qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [QEMU-PPC] [PATCH V4 1/6] target/ppc/kvm: Add cap_ppc_saf


From: David Gibson
Subject: Re: [Qemu-ppc] [QEMU-PPC] [PATCH V4 1/6] target/ppc/kvm: Add cap_ppc_safe_[cache/bounds_check/indirect_branch]
Date: Thu, 18 Jan 2018 16:06:16 +1100
User-agent: Mutt/1.9.1 (2017-09-22)

On Mon, Jan 15, 2018 at 05:58:37PM +1100, Suraj Jitindar Singh wrote:
> Add three new kvm capabilities used to represent the level of host support
> for three corresponding workarounds.
> 
> Host support for each of the capabilities is queried through the
> new ioctl KVM_PPC_GET_CPU_CHAR which returns four uint64 quantities. The
> first two, character and behaviour, represent the available
> characteristics of the cpu and the behaviour of the cpu respectively.
> The second two, c_mask and b_mask, represent the mask of known bits for
> the character and beheviour dwords respectively.
> 
> Signed-off-by: Suraj Jitindar Singh <address@hidden>

Reviewed-by: David Gibson <address@hidden>

Waiting for the kernel part to go in before merging, though.

> ---
> 
> V3 -> V4:
> - Move kvmppc_get_cpu_characteristics() function implementation to fix
>   compilation on some targets.
> 
> ---
>  include/hw/ppc/spapr.h          | 12 +++++++++
>  linux-headers/asm-powerpc/kvm.h |  8 ++++++
>  linux-headers/linux/kvm.h       |  3 +++
>  target/ppc/kvm.c                | 58 
> +++++++++++++++++++++++++++++++++++++++++
>  target/ppc/kvm_ppc.h            | 18 +++++++++++++
>  5 files changed, 99 insertions(+)
> 
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 0f5628f22e..eded0ea57d 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -295,6 +295,18 @@ struct sPAPRMachineState {
>  #define H_DABRX_KERNEL     (1ULL<<(63-62))
>  #define H_DABRX_USER       (1ULL<<(63-63))
>  
> +/* Values for KVM_PPC_GET_CPU_CHAR & H_GET_CPU_CHARACTERISTICS */
> +#define H_CPU_CHAR_SPEC_BAR_ORI31               PPC_BIT(0)
> +#define H_CPU_CHAR_BCCTRL_SERIALISED            PPC_BIT(1)
> +#define H_CPU_CHAR_L1D_FLUSH_ORI30              PPC_BIT(2)
> +#define H_CPU_CHAR_L1D_FLUSH_TRIG2              PPC_BIT(3)
> +#define H_CPU_CHAR_L1D_THREAD_PRIV              PPC_BIT(4)
> +#define H_CPU_CHAR_HON_BRANCH_HINTS             PPC_BIT(5)
> +#define H_CPU_CHAR_THR_RECONF_TRIG              PPC_BIT(6)
> +#define H_CPU_BEHAV_FAVOUR_SECURITY             PPC_BIT(0)
> +#define H_CPU_BEHAV_L1D_FLUSH_PR                PPC_BIT(1)
> +#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR           PPC_BIT(2)
> +
>  /* Each control block has to be on a 4K boundary */
>  #define H_CB_ALIGNMENT     4096
>  
> diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
> index 61d6049f4c..5d2cb26848 100644
> --- a/linux-headers/asm-powerpc/kvm.h
> +++ b/linux-headers/asm-powerpc/kvm.h
> @@ -443,6 +443,14 @@ struct kvm_ppc_rmmu_info {
>       __u32   ap_encodings[8];
>  };
>  
> +/* For KVM_PPC_GET_CPU_CHAR */
> +struct kvm_ppc_cpu_char {
> +        __u64   character;      /* characteristics of the CPU */
> +        __u64   behaviour;      /* recommended software behaviour */
> +        __u64   c_mask;         /* valid bits in character */
> +        __u64   b_mask;         /* valid bits in behaviour */
> +};
> +
>  /* Per-vcpu XICS interrupt controller state */
>  #define KVM_REG_PPC_ICP_STATE        (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
>  
> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
> index ce6c2f11f4..c35f1bd363 100644
> --- a/linux-headers/linux/kvm.h
> +++ b/linux-headers/linux/kvm.h
> @@ -932,6 +932,7 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_HYPERV_SYNIC2 148
>  #define KVM_CAP_HYPERV_VP_INDEX 149
>  #define KVM_CAP_S390_AIS_MIGRATION 150
> +#define KVM_CAP_PPC_GET_CPU_CHAR 151
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  
> @@ -1261,6 +1262,8 @@ struct kvm_s390_ucas_mapping {
>  #define KVM_PPC_CONFIGURE_V3_MMU  _IOW(KVMIO,  0xaf, struct 
> kvm_ppc_mmuv3_cfg)
>  /* Available with KVM_CAP_PPC_RADIX_MMU */
>  #define KVM_PPC_GET_RMMU_INFO          _IOW(KVMIO,  0xb0, struct 
> kvm_ppc_rmmu_info)
> +/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
> +#define KVM_PPC_GET_CPU_CHAR      _IOR(KVMIO,  0xb1, struct kvm_ppc_cpu_char)
>  
>  /* ioctl for vm fd */
>  #define KVM_CREATE_DEVICE      _IOWR(KVMIO,  0xe0, struct kvm_create_device)
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 914be687e7..b16f731522 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -89,6 +89,9 @@ static int cap_mmu_radix;
>  static int cap_mmu_hash_v3;
>  static int cap_resize_hpt;
>  static int cap_ppc_pvr_compat;
> +static int cap_ppc_safe_cache;
> +static int cap_ppc_safe_bounds_check;
> +static int cap_ppc_safe_indirect_branch;
>  
>  static uint32_t debug_inst_opcode;
>  
> @@ -121,6 +124,7 @@ static bool kvmppc_is_pr(KVMState *ks)
>  }
>  
>  static int kvm_ppc_register_host_cpu_type(MachineState *ms);
> +static void kvmppc_get_cpu_characteristics(KVMState *s);
>  
>  int kvm_arch_init(MachineState *ms, KVMState *s)
>  {
> @@ -147,6 +151,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
>      cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
>      cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
>      cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
> +    kvmppc_get_cpu_characteristics(s);
>      /*
>       * Note: setting it to false because there is not such capability
>       * in KVM at this moment.
> @@ -2456,6 +2461,59 @@ bool kvmppc_has_cap_mmu_hash_v3(void)
>      return cap_mmu_hash_v3;
>  }
>  
> +static void kvmppc_get_cpu_characteristics(KVMState *s)
> +{
> +    struct kvm_ppc_cpu_char c;
> +    int ret;
> +
> +    /* Assume broken */
> +    cap_ppc_safe_cache = 0;
> +    cap_ppc_safe_bounds_check = 0;
> +    cap_ppc_safe_indirect_branch = 0;
> +
> +    ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR);
> +    if (!ret) {
> +        return;
> +    }
> +    ret = kvm_vm_ioctl(s, KVM_PPC_GET_CPU_CHAR, &c);
> +    if (ret < 0) {
> +        return;
> +    }
> +    /* Parse and set cap_ppc_safe_cache */
> +    if (~c.behaviour & c.b_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
> +        cap_ppc_safe_cache = 2;
> +    } else if ((c.character & c.c_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
> +               (c.character & c.c_mask & (H_CPU_CHAR_L1D_FLUSH_ORI30 |
> +                                          H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
> +        cap_ppc_safe_cache = 1;
> +    }
> +    /* Parse and set cap_ppc_safe_bounds_check */
> +    if (~c.behaviour & c.b_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
> +        cap_ppc_safe_bounds_check = 2;
> +    } else if (c.character & c.c_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
> +        cap_ppc_safe_bounds_check = 1;
> +    }
> +    /* Parse and set cap_ppc_safe_indirect_branch */
> +    if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) {
> +        cap_ppc_safe_indirect_branch = 2;
> +    }
> +}
> +
> +int kvmppc_get_cap_safe_cache(void)
> +{
> +    return cap_ppc_safe_cache;
> +}
> +
> +int kvmppc_get_cap_safe_bounds_check(void)
> +{
> +    return cap_ppc_safe_bounds_check;
> +}
> +
> +int kvmppc_get_cap_safe_indirect_branch(void)
> +{
> +    return cap_ppc_safe_indirect_branch;
> +}
> +
>  PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
>  {
>      uint32_t host_pvr = mfpvr();
> diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
> index ecb55493cc..39830baa77 100644
> --- a/target/ppc/kvm_ppc.h
> +++ b/target/ppc/kvm_ppc.h
> @@ -59,6 +59,9 @@ bool kvmppc_has_cap_fixup_hcalls(void);
>  bool kvmppc_has_cap_htm(void);
>  bool kvmppc_has_cap_mmu_radix(void);
>  bool kvmppc_has_cap_mmu_hash_v3(void);
> +int kvmppc_get_cap_safe_cache(void);
> +int kvmppc_get_cap_safe_bounds_check(void);
> +int kvmppc_get_cap_safe_indirect_branch(void);
>  int kvmppc_enable_hwrng(void);
>  int kvmppc_put_books_sregs(PowerPCCPU *cpu);
>  PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
> @@ -290,6 +293,21 @@ static inline bool kvmppc_has_cap_mmu_hash_v3(void)
>      return false;
>  }
>  
> +static inline int kvmppc_get_cap_safe_cache(void)
> +{
> +    return 0;
> +}
> +
> +static inline int kvmppc_get_cap_safe_bounds_check(void)
> +{
> +    return 0;
> +}
> +
> +static inline int kvmppc_get_cap_safe_indirect_branch(void)
> +{
> +    return 0;
> +}
> +
>  static inline int kvmppc_enable_hwrng(void)
>  {
>      return -1;

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]