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

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