Blame SOURCES/kvm-target-ppc-kvm-Add-cap_ppc_safe_-cache-bounds_check-.patch

4a2fec
From e8388e92e3bb6dbdd69ada6d7939e06e15875eeb Mon Sep 17 00:00:00 2001
4a2fec
From: Suraj Jitindar Singh <sursingh@redhat.com>
4a2fec
Date: Tue, 13 Feb 2018 04:12:23 +0100
4a2fec
Subject: [PATCH 06/15] target/ppc/kvm: Add
4a2fec
 cap_ppc_safe_[cache/bounds_check/indirect_branch]
4a2fec
4a2fec
RH-Author: Suraj Jitindar Singh <sursingh@redhat.com>
4a2fec
Message-id: <1518495150-24134-3-git-send-email-sursingh@redhat.com>
4a2fec
Patchwork-id: 78984
4a2fec
O-Subject: [RHEL7.5 qemu-kvm-rhev PATCH 2/9] target/ppc/kvm: Add cap_ppc_safe_[cache/bounds_check/indirect_branch]
4a2fec
Bugzilla: 1532050
4a2fec
RH-Acked-by: David Gibson <dgibson@redhat.com>
4a2fec
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
4a2fec
RH-Acked-by: Thomas Huth <thuth@redhat.com>
4a2fec
4a2fec
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
4a2fec
4a2fec
Add three new kvm capabilities used to represent the level of host support
4a2fec
for three corresponding workarounds.
4a2fec
4a2fec
Host support for each of the capabilities is queried through the
4a2fec
new ioctl KVM_PPC_GET_CPU_CHAR which returns four uint64 quantities. The
4a2fec
first two, character and behaviour, represent the available
4a2fec
characteristics of the cpu and the behaviour of the cpu respectively.
4a2fec
The second two, c_mask and b_mask, represent the mask of known bits for
4a2fec
the character and beheviour dwords respectively.
4a2fec
4a2fec
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
4a2fec
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
4a2fec
[dwg: Correct some compile errors due to name change in final kernel
4a2fec
 patch version]
4a2fec
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
4a2fec
4a2fec
(cherry picked from commit 8acc2ae5e91681ceda3ff4cf946ebf163f6012e9)
4a2fec
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
4a2fec
4a2fec
Conflicts:
4a2fec
	target/ppc/kvm.c
4a2fec
4a2fec
Minor massage required due to lack of commit downstream:
4a2fec
2e9c10eb (ppc: spapr: use generic cpu_model parsing)
4a2fec
4a2fec
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1532050
4a2fec
4a2fec
Signed-off-by: Suraj Jitindar Singh <sursingh@redhat.com>
4a2fec
---
4a2fec
 include/hw/ppc/spapr.h | 12 +++++++++++
4a2fec
 target/ppc/kvm.c       | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
4a2fec
 target/ppc/kvm_ppc.h   | 18 ++++++++++++++++
4a2fec
 3 files changed, 88 insertions(+)
4a2fec
4a2fec
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
4a2fec
index 7156a70..6090f3d 100644
4a2fec
--- a/include/hw/ppc/spapr.h
4a2fec
+++ b/include/hw/ppc/spapr.h
4a2fec
@@ -297,6 +297,18 @@ struct sPAPRMachineState {
4a2fec
 #define H_DABRX_KERNEL     (1ULL<<(63-62))
4a2fec
 #define H_DABRX_USER       (1ULL<<(63-63))
4a2fec
 
4a2fec
+/* Values for KVM_PPC_GET_CPU_CHAR & H_GET_CPU_CHARACTERISTICS */
4a2fec
+#define H_CPU_CHAR_SPEC_BAR_ORI31               PPC_BIT(0)
4a2fec
+#define H_CPU_CHAR_BCCTRL_SERIALISED            PPC_BIT(1)
4a2fec
+#define H_CPU_CHAR_L1D_FLUSH_ORI30              PPC_BIT(2)
4a2fec
+#define H_CPU_CHAR_L1D_FLUSH_TRIG2              PPC_BIT(3)
4a2fec
+#define H_CPU_CHAR_L1D_THREAD_PRIV              PPC_BIT(4)
4a2fec
+#define H_CPU_CHAR_HON_BRANCH_HINTS             PPC_BIT(5)
4a2fec
+#define H_CPU_CHAR_THR_RECONF_TRIG              PPC_BIT(6)
4a2fec
+#define H_CPU_BEHAV_FAVOUR_SECURITY             PPC_BIT(0)
4a2fec
+#define H_CPU_BEHAV_L1D_FLUSH_PR                PPC_BIT(1)
4a2fec
+#define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR           PPC_BIT(2)
4a2fec
+
4a2fec
 /* Each control block has to be on a 4K boundary */
4a2fec
 #define H_CB_ALIGNMENT     4096
4a2fec
 
4a2fec
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
4a2fec
index ce7e2ec..7a7bc3b 100644
4a2fec
--- a/target/ppc/kvm.c
4a2fec
+++ b/target/ppc/kvm.c
4a2fec
@@ -92,6 +92,9 @@ static int cap_mmu_radix;
4a2fec
 static int cap_mmu_hash_v3;
4a2fec
 static int cap_resize_hpt;
4a2fec
 static int cap_ppc_pvr_compat;
4a2fec
+static int cap_ppc_safe_cache;
4a2fec
+static int cap_ppc_safe_bounds_check;
4a2fec
+static int cap_ppc_safe_indirect_branch;
4a2fec
 
4a2fec
 static uint32_t debug_inst_opcode;
4a2fec
 
4a2fec
@@ -124,6 +127,7 @@ static bool kvmppc_is_pr(KVMState *ks)
4a2fec
 }
4a2fec
 
4a2fec
 static int kvm_ppc_register_host_cpu_type(void);
4a2fec
+static void kvmppc_get_cpu_characteristics(KVMState *s);
4a2fec
 
4a2fec
 int kvm_arch_init(MachineState *ms, KVMState *s)
4a2fec
 {
4a2fec
@@ -150,6 +154,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
4a2fec
     cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
4a2fec
     cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
4a2fec
     cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT);
4a2fec
+    kvmppc_get_cpu_characteristics(s);
4a2fec
     /*
4a2fec
      * Note: setting it to false because there is not such capability
4a2fec
      * in KVM at this moment.
4a2fec
@@ -2473,6 +2478,59 @@ bool kvmppc_has_cap_mmu_hash_v3(void)
4a2fec
     return cap_mmu_hash_v3;
4a2fec
 }
4a2fec
 
4a2fec
+static void kvmppc_get_cpu_characteristics(KVMState *s)
4a2fec
+{
4a2fec
+    struct kvm_ppc_cpu_char c;
4a2fec
+    int ret;
4a2fec
+
4a2fec
+    /* Assume broken */
4a2fec
+    cap_ppc_safe_cache = 0;
4a2fec
+    cap_ppc_safe_bounds_check = 0;
4a2fec
+    cap_ppc_safe_indirect_branch = 0;
4a2fec
+
4a2fec
+    ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR);
4a2fec
+    if (!ret) {
4a2fec
+        return;
4a2fec
+    }
4a2fec
+    ret = kvm_vm_ioctl(s, KVM_PPC_GET_CPU_CHAR, &c);
4a2fec
+    if (ret < 0) {
4a2fec
+        return;
4a2fec
+    }
4a2fec
+    /* Parse and set cap_ppc_safe_cache */
4a2fec
+    if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_L1D_FLUSH_PR) {
4a2fec
+        cap_ppc_safe_cache = 2;
4a2fec
+    } else if ((c.character & c.character_mask & H_CPU_CHAR_L1D_THREAD_PRIV) &&
4a2fec
+               (c.character & c.character_mask
4a2fec
+                & (H_CPU_CHAR_L1D_FLUSH_ORI30 | H_CPU_CHAR_L1D_FLUSH_TRIG2))) {
4a2fec
+        cap_ppc_safe_cache = 1;
4a2fec
+    }
4a2fec
+    /* Parse and set cap_ppc_safe_bounds_check */
4a2fec
+    if (~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_BNDS_CHK_SPEC_BAR) {
4a2fec
+        cap_ppc_safe_bounds_check = 2;
4a2fec
+    } else if (c.character & c.character_mask & H_CPU_CHAR_SPEC_BAR_ORI31) {
4a2fec
+        cap_ppc_safe_bounds_check = 1;
4a2fec
+    }
4a2fec
+    /* Parse and set cap_ppc_safe_indirect_branch */
4a2fec
+    if (c.character & H_CPU_CHAR_BCCTRL_SERIALISED) {
4a2fec
+        cap_ppc_safe_indirect_branch = 2;
4a2fec
+    }
4a2fec
+}
4a2fec
+
4a2fec
+int kvmppc_get_cap_safe_cache(void)
4a2fec
+{
4a2fec
+    return cap_ppc_safe_cache;
4a2fec
+}
4a2fec
+
4a2fec
+int kvmppc_get_cap_safe_bounds_check(void)
4a2fec
+{
4a2fec
+    return cap_ppc_safe_bounds_check;
4a2fec
+}
4a2fec
+
4a2fec
+int kvmppc_get_cap_safe_indirect_branch(void)
4a2fec
+{
4a2fec
+    return cap_ppc_safe_indirect_branch;
4a2fec
+}
4a2fec
+
4a2fec
 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
4a2fec
 {
4a2fec
     uint32_t host_pvr = mfpvr();
4a2fec
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
4a2fec
index e6711fc..9da92a9 100644
4a2fec
--- a/target/ppc/kvm_ppc.h
4a2fec
+++ b/target/ppc/kvm_ppc.h
4a2fec
@@ -62,6 +62,9 @@ bool kvmppc_has_cap_fixup_hcalls(void);
4a2fec
 bool kvmppc_has_cap_htm(void);
4a2fec
 bool kvmppc_has_cap_mmu_radix(void);
4a2fec
 bool kvmppc_has_cap_mmu_hash_v3(void);
4a2fec
+int kvmppc_get_cap_safe_cache(void);
4a2fec
+int kvmppc_get_cap_safe_bounds_check(void);
4a2fec
+int kvmppc_get_cap_safe_indirect_branch(void);
4a2fec
 int kvmppc_enable_hwrng(void);
4a2fec
 int kvmppc_put_books_sregs(PowerPCCPU *cpu);
4a2fec
 PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
4a2fec
@@ -299,6 +302,21 @@ static inline bool kvmppc_has_cap_mmu_hash_v3(void)
4a2fec
     return false;
4a2fec
 }
4a2fec
 
4a2fec
+static inline int kvmppc_get_cap_safe_cache(void)
4a2fec
+{
4a2fec
+    return 0;
4a2fec
+}
4a2fec
+
4a2fec
+static inline int kvmppc_get_cap_safe_bounds_check(void)
4a2fec
+{
4a2fec
+    return 0;
4a2fec
+}
4a2fec
+
4a2fec
+static inline int kvmppc_get_cap_safe_indirect_branch(void)
4a2fec
+{
4a2fec
+    return 0;
4a2fec
+}
4a2fec
+
4a2fec
 static inline int kvmppc_enable_hwrng(void)
4a2fec
 {
4a2fec
     return -1;
4a2fec
-- 
4a2fec
1.8.3.1
4a2fec