cryptospore / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-target-ppc-spapr-Add-workaround-option-to-SPAPR_CAP_.patch

b38b0f
From c1bd7825b1cbe0ff34be196effc7a18992cce269 Mon Sep 17 00:00:00 2001
b38b0f
From: Sam Bobroff <sbobroff@redhat.com>
b38b0f
Date: Thu, 29 Aug 2019 05:53:35 +0100
b38b0f
Subject: [PATCH 02/10] target/ppc/spapr: Add workaround option to
b38b0f
 SPAPR_CAP_IBS
b38b0f
b38b0f
RH-Author: Sam Bobroff <sbobroff@redhat.com>
b38b0f
Message-id: <67946d77e95afc19f2afc5f8dfa4e89335dbb58d.1567057498.git.sbobroff@redhat.com>
b38b0f
Patchwork-id: 90188
b38b0f
O-Subject: [RHEL8.1 qemu-kvm BZ1744415 PATCH 1/2] target/ppc/spapr: Add workaround option to SPAPR_CAP_IBS
b38b0f
Bugzilla: 1744415
b38b0f
RH-Acked-by: David Gibson <dgibson@redhat.com>
b38b0f
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
b38b0f
RH-Acked-by: Thomas Huth <thuth@redhat.com>
b38b0f
b38b0f
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
b38b0f
b38b0f
The spapr_cap SPAPR_CAP_IBS is used to indicate the level of capability
b38b0f
for mitigations for indirect branch speculation. Currently the available
b38b0f
values are broken (default), fixed-ibs (fixed by serialising indirect
b38b0f
branches) and fixed-ccd (fixed by diabling the count cache).
b38b0f
b38b0f
Introduce a new value for this capability denoted workaround, meaning that
b38b0f
software can work around the issue by flushing the count cache on
b38b0f
context switch. This option is available if the hypervisor sets the
b38b0f
H_CPU_BEHAV_FLUSH_COUNT_CACHE flag in the cpu behaviours returned from
b38b0f
the KVM_PPC_GET_CPU_CHAR ioctl.
b38b0f
b38b0f
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
b38b0f
Message-Id: <20190301031912.28809-1-sjitindarsingh@gmail.com>
b38b0f
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
b38b0f
(cherry picked from commit 399b2896d4948a1ec0278d896ea3a561df768d64)
b38b0f
b38b0f
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1744415
b38b0f
Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=23229146
b38b0f
Signed-off-by: Sam Bobroff <sbobroff@redhat.com>
b38b0f
Testing: Start QEMU with -M cap-ibs=workaround, check guest dmesg
b38b0f
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
b38b0f
---
b38b0f
 hw/ppc/spapr_caps.c    | 21 ++++++++++-----------
b38b0f
 hw/ppc/spapr_hcall.c   |  5 +++++
b38b0f
 include/hw/ppc/spapr.h |  7 +++++++
b38b0f
 target/ppc/kvm.c       |  8 +++++++-
b38b0f
 4 files changed, 29 insertions(+), 12 deletions(-)
b38b0f
b38b0f
diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c
b38b0f
index 86a7947..dfc8cce 100644
b38b0f
--- a/hw/ppc/spapr_caps.c
b38b0f
+++ b/hw/ppc/spapr_caps.c
b38b0f
@@ -236,11 +236,13 @@ static void cap_safe_bounds_check_apply(sPAPRMachineState *spapr, uint8_t val,
b38b0f
 }
b38b0f
 
b38b0f
 sPAPRCapPossible cap_ibs_possible = {
b38b0f
-    .num = 4,
b38b0f
+    .num = 5,
b38b0f
     /* Note workaround only maintained for compatibility */
b38b0f
-    .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd"},
b38b0f
-    .help = "broken - no protection, fixed-ibs - indirect branch serialisation,"
b38b0f
-            " fixed-ccd - cache count disabled",
b38b0f
+    .vals = {"broken", "workaround", "fixed-ibs", "fixed-ccd", "fixed-na"},
b38b0f
+    .help = "broken - no protection, workaround - count cache flush"
b38b0f
+            ", fixed-ibs - indirect branch serialisation,"
b38b0f
+            " fixed-ccd - cache count disabled,"
b38b0f
+            " fixed-na - fixed in hardware (no longer applicable)",
b38b0f
 };
b38b0f
 
b38b0f
 static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
b38b0f
@@ -248,15 +250,11 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr,
b38b0f
 {
b38b0f
     uint8_t kvm_val = kvmppc_get_cap_safe_indirect_branch();
b38b0f
 
b38b0f
-    if (val == SPAPR_CAP_WORKAROUND) { /* Can only be Broken or Fixed */
b38b0f
-        error_setg(errp,
b38b0f
-"Requested safe indirect branch capability level \"workaround\" not valid, try cap-ibs=%s",
b38b0f
-                   cap_ibs_possible.vals[kvm_val]);
b38b0f
-    } else if (tcg_enabled() && val) {
b38b0f
+    if (tcg_enabled() && val) {
b38b0f
         /* TODO - for now only allow broken for TCG */
b38b0f
         error_setg(errp,
b38b0f
 "Requested safe indirect branch capability level not supported by tcg, try a different value for cap-ibs");
b38b0f
-    } else if (kvm_enabled() && val && (val != kvm_val)) {
b38b0f
+    } else if (kvm_enabled() && (val > kvm_val)) {
b38b0f
         error_setg(errp,
b38b0f
 "Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s",
b38b0f
                    cap_ibs_possible.vals[kvm_val]);
b38b0f
@@ -338,7 +336,8 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = {
b38b0f
     [SPAPR_CAP_IBS] = {
b38b0f
         .name = "ibs",
b38b0f
         .description =
b38b0f
-            "Indirect Branch Speculation (broken, fixed-ibs, fixed-ccd)",
b38b0f
+            "Indirect Branch Speculation (broken, workaround, fixed-ibs,"
b38b0f
+            "fixed-ccd, fixed-na)",
b38b0f
         .index = SPAPR_CAP_IBS,
b38b0f
         .get = spapr_cap_get_string,
b38b0f
         .set = spapr_cap_set_string,
b38b0f
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
b38b0f
index 16bccdd..01c4215 100644
b38b0f
--- a/hw/ppc/spapr_hcall.c
b38b0f
+++ b/hw/ppc/spapr_hcall.c
b38b0f
@@ -1705,12 +1705,17 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
b38b0f
     }
b38b0f
 
b38b0f
     switch (safe_indirect_branch) {
b38b0f
+    case SPAPR_CAP_FIXED_NA:
b38b0f
+        break;
b38b0f
     case SPAPR_CAP_FIXED_CCD:
b38b0f
         characteristics |= H_CPU_CHAR_CACHE_COUNT_DIS;
b38b0f
         break;
b38b0f
     case SPAPR_CAP_FIXED_IBS:
b38b0f
         characteristics |= H_CPU_CHAR_BCCTRL_SERIALISED;
b38b0f
         break;
b38b0f
+    case SPAPR_CAP_WORKAROUND:
b38b0f
+        behaviour |= H_CPU_BEHAV_FLUSH_COUNT_CACHE;
b38b0f
+        break;
b38b0f
     default: /* broken */
b38b0f
         assert(safe_indirect_branch == SPAPR_CAP_BROKEN);
b38b0f
         break;
b38b0f
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
b38b0f
index 72cfa49..8bb95bb 100644
b38b0f
--- a/include/hw/ppc/spapr.h
b38b0f
+++ b/include/hw/ppc/spapr.h
b38b0f
@@ -77,12 +77,17 @@ typedef enum {
b38b0f
 /* Bool Caps */
b38b0f
 #define SPAPR_CAP_OFF                   0x00
b38b0f
 #define SPAPR_CAP_ON                    0x01
b38b0f
+
b38b0f
 /* Custom Caps */
b38b0f
+
b38b0f
+/* Generic */
b38b0f
 #define SPAPR_CAP_BROKEN                0x00
b38b0f
 #define SPAPR_CAP_WORKAROUND            0x01
b38b0f
 #define SPAPR_CAP_FIXED                 0x02
b38b0f
+/* SPAPR_CAP_IBS (cap-ibs) */
b38b0f
 #define SPAPR_CAP_FIXED_IBS             0x02
b38b0f
 #define SPAPR_CAP_FIXED_CCD             0x03
b38b0f
+#define SPAPR_CAP_FIXED_NA              0x10 /* Lets leave a bit of a gap... */
b38b0f
 
b38b0f
 typedef struct sPAPRCapabilities sPAPRCapabilities;
b38b0f
 struct sPAPRCapabilities {
b38b0f
@@ -322,9 +327,11 @@ struct sPAPRMachineState {
b38b0f
 #define H_CPU_CHAR_HON_BRANCH_HINTS             PPC_BIT(5)
b38b0f
 #define H_CPU_CHAR_THR_RECONF_TRIG              PPC_BIT(6)
b38b0f
 #define H_CPU_CHAR_CACHE_COUNT_DIS              PPC_BIT(7)
b38b0f
+#define H_CPU_CHAR_BCCTR_FLUSH_ASSIST           PPC_BIT(9)
b38b0f
 #define H_CPU_BEHAV_FAVOUR_SECURITY             PPC_BIT(0)
b38b0f
 #define H_CPU_BEHAV_L1D_FLUSH_PR                PPC_BIT(1)
b38b0f
 #define H_CPU_BEHAV_BNDS_CHK_SPEC_BAR           PPC_BIT(2)
b38b0f
+#define H_CPU_BEHAV_FLUSH_COUNT_CACHE           PPC_BIT(5)
b38b0f
 
b38b0f
 /* Each control block has to be on a 4K boundary */
b38b0f
 #define H_CB_ALIGNMENT     4096
b38b0f
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
b38b0f
index b9858fa..0e94cfc 100644
b38b0f
--- a/target/ppc/kvm.c
b38b0f
+++ b/target/ppc/kvm.c
b38b0f
@@ -2511,7 +2511,13 @@ static int parse_cap_ppc_safe_bounds_check(struct kvm_ppc_cpu_char c)
b38b0f
 
b38b0f
 static int parse_cap_ppc_safe_indirect_branch(struct kvm_ppc_cpu_char c)
b38b0f
 {
b38b0f
-    if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
b38b0f
+    if ((~c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) &&
b38b0f
+        (~c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) &&
b38b0f
+        (~c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED)) {
b38b0f
+        return SPAPR_CAP_FIXED_NA;
b38b0f
+    } else if (c.behaviour & c.behaviour_mask & H_CPU_BEHAV_FLUSH_COUNT_CACHE) {
b38b0f
+        return SPAPR_CAP_WORKAROUND;
b38b0f
+    } else if (c.character & c.character_mask & H_CPU_CHAR_CACHE_COUNT_DIS) {
b38b0f
         return  SPAPR_CAP_FIXED_CCD;
b38b0f
     } else if (c.character & c.character_mask & H_CPU_CHAR_BCCTRL_SERIALISED) {
b38b0f
         return SPAPR_CAP_FIXED_IBS;
b38b0f
-- 
b38b0f
1.8.3.1
b38b0f