# Commit 9df52a25e0e95a0b9971aa2fc26c5c6a5cbdf4ef
# Date 2018-05-21 14:20:06 +0100
# Author Andrew Cooper <andrew.cooper3@citrix.com>
# Committer Andrew Cooper <andrew.cooper3@citrix.com>
x86/Intel: Mitigations for GPZ SP4 - Speculative Store Bypass

To combat GPZ SP4 "Speculative Store Bypass", Intel have extended their
speculative sidechannel mitigations specification as follows:

 * A feature bit to indicate that Speculative Store Bypass Disable is
   supported.
 * A new bit in MSR_SPEC_CTRL which, when set, disables memory disambiguation
   in the pipeline.
 * A new bit in MSR_ARCH_CAPABILITIES, which will be set in future hardware,
   indicating that the hardware is not susceptible to Speculative Store Bypass
   sidechannels.

For contemporary processors, this interface will be implemented via a
microcode update.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>

--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -335,9 +335,10 @@ accounting for hardware capabilities as 
 
 Currently accepted:
 
-The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb` are used by
-default if avaiable.  They can be ignored, e.g. `no-ibrsb`, at which point Xen
-won't use them itself, and won't offer them to guests.
+The Speculation Control hardware features `ibrsb`, `stibp`, `ibpb`, `ssbd` are
+used by default if available and applicable.  They can be ignored,
+e.g. `no-ibrsb`, at which point Xen won't use them itself, and won't offer
+them to guests.
 
 ### cpuid\_mask\_cpu (AMD only)
 > `= fam_0f_rev_c | fam_0f_rev_d | fam_0f_rev_e | fam_0f_rev_f | fam_0f_rev_g | fam_10_rev_b | fam_10_rev_c | fam_11_rev_b`
@@ -895,7 +896,7 @@ protect itself, and Xen's ability to vir
   respectively.
 * `msr-sc=` offers control over Xen's support for manipulating MSR\_SPEC\_CTRL
   on entry and exit.  These blocks are necessary to virtualise support for
-  guests and if disabled, guests will be unable to use IBRS/STIBP/etc.
+  guests and if disabled, guests will be unable to use IBRS/STIBP/SSBD/etc.
 * `rsb=` offers control over whether to overwrite the Return Stack Buffer /
   Return Address Stack on entry to Xen.
 
@@ -917,7 +918,8 @@ prediction barriers on vcpu context swit
 On hardware supporting SSBD (Speculative Store Bypass Disable), the `ssbd=`
 option can be used to force or prevent Xen using the feature itself.  On AMD
 hardware, this is a global option applied at boot, and not virtualised for
-guest use.
+guest use.  On Intel hardware, the feature is virtualised for guests,
+independently of Xen's choice of setting.
 
 ### sync\_console
 > `= <boolean>`
--- a/tools/libxc/xc_cpufeature.h
+++ b/tools/libxc/xc_cpufeature.h
@@ -144,5 +144,6 @@
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (edx) */
 #define X86_FEATURE_IBRSB       26 /* IBRS and IBPB support (used by Intel) */
 #define X86_FEATURE_STIBP       27 /* STIBP */
+#define X86_FEATURE_SSBD        31 /* MSR_SPEC_CTRL.SSBD available */
 
 #endif /* __LIBXC_CPUFEATURE_H */
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -373,7 +373,8 @@ static void xc_cpuid_hvm_policy(
                         bitmaskof(X86_FEATURE_RTM)  |
                         bitmaskof(X86_FEATURE_FSGSBASE));
             regs[3] &= (bitmaskof(X86_FEATURE_IBRSB) |
-                        bitmaskof(X86_FEATURE_STIBP));
+                        bitmaskof(X86_FEATURE_STIBP) |
+                        bitmaskof(X86_FEATURE_SSBD));
         } else
             regs[1] = regs[3] = 0;
         regs[0] = regs[2] = 0;
@@ -510,7 +511,8 @@ static void xc_cpuid_pv_policy(
                         bitmaskof(X86_FEATURE_RTM)  |
                         bitmaskof(X86_FEATURE_FSGSBASE));
             regs[3] &= (bitmaskof(X86_FEATURE_IBRSB) |
-                        bitmaskof(X86_FEATURE_STIBP));
+                        bitmaskof(X86_FEATURE_STIBP) |
+                        bitmaskof(X86_FEATURE_SSBD));
         }
         else
             regs[1] = regs[3] = 0;
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -148,6 +148,7 @@ int libxl_cpuid_parse_config(libxl_cpuid
         {"fpu",          0x00000001, NA, CPUID_REG_EDX,  0,  1},
         {"ibrsb",        0x00000007,  0, CPUID_REG_EDX, 26,  1},
         {"stibp",        0x00000007,  0, CPUID_REG_EDX, 27,  1},
+        {"ssbd",         0x00000007,  0, CPUID_REG_EDX, 31,  1},
         {"topoext",      0x80000001, NA, CPUID_REG_ECX, 22,  1},
         {"tbm",          0x80000001, NA, CPUID_REG_ECX, 21,  1},
         {"nodeid",       0x80000001, NA, CPUID_REG_ECX, 19,  1},
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -60,6 +60,7 @@
 #include <asm/hvm/nestedhvm.h>
 #include <asm/mtrr.h>
 #include <asm/apic.h>
+#include <asm/spec_ctrl.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <public/version.h>
@@ -3004,7 +3005,8 @@ void hvm_cpuid(unsigned int input, unsig
         if ( count == 0 )
         {
             if ( !opt_msr_sc_hvm )
-                *edx &= ~cpufeat_mask(X86_FEATURE_IBRSB);
+                *edx &= ~(cpufeat_mask(X86_FEATURE_IBRSB) |
+                          cpufeat_mask(X86_FEATURE_SSBD));
 
             /*
              * Override STIBP to match IBRS.  Guests can safely use STIBP
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -128,6 +128,11 @@ static int __init parse_xen_cpuid(const 
             if ( !val )
                 setup_clear_cpu_cap(X86_FEATURE_STIBP);
         }
+        else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
+        {
+            if ( !val )
+                setup_clear_cpu_cap(X86_FEATURE_SSBD);
+        }
         else
             rc = -EINVAL;
 
--- a/xen/arch/x86/spec_ctrl.c
+++ b/xen/arch/x86/spec_ctrl.c
@@ -158,9 +158,10 @@ static void __init print_details(enum in
     printk("Speculative mitigation facilities:\n");
 
     /* Hardware features which pertain to speculative mitigations. */
-    printk("  Hardware features:%s%s%s\n",
+    printk("  Hardware features:%s%s%s%s\n",
            (_7d0 & cpufeat_mask(X86_FEATURE_IBRSB)) ? " IBRS/IBPB" : "",
            (_7d0 & cpufeat_mask(X86_FEATURE_STIBP)) ? " STIBP"     : "",
+           (_7d0 & cpufeat_mask(X86_FEATURE_SSBD))  ? " SSBD"      : "",
            (e8b  & cpufeat_mask(X86_FEATURE_IBPB))  ? " IBPB"      : "");
 
     /* Compiled-in support which pertains to BTI mitigations. */
@@ -169,11 +170,14 @@ static void __init print_details(enum in
 #endif
 
     /* Settings for Xen's protection, irrespective of guests. */
-    printk("  Xen settings: BTI-Thunk %s, SPEC_CTRL: %s, Other:%s\n",
+    printk("  Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s\n",
            thunk == THUNK_NONE      ? "N/A" :
            thunk == THUNK_RETPOLINE ? "RETPOLINE" : "?",
            default_xen_spec_ctrl < 0 ? "" :
            default_xen_spec_ctrl & SPEC_CTRL_IBRS ? " IBRS+" : " IBRS-",
+           default_xen_spec_ctrl < 0 || !boot_cpu_has(X86_FEATURE_SSBD)
+                                                     ? "" :
+           (default_xen_spec_ctrl & SPEC_CTRL_SSBD)  ? " SSBD+" : " SSBD-",
            opt_ibpb                 ? " IBPB"  : "");
 
     printk("  Support for VMs: PV:%s%s%s, HVM:%s%s%s\n",
@@ -213,6 +217,10 @@ void __init init_speculation_mitigations
     if ( boot_cpu_has(X86_FEATURE_IBRSB) )
         default_xen_spec_ctrl = ibrs ? SPEC_CTRL_IBRS : 0;
 
+    /* If we have SSBD available, see whether we should use it. */
+    if ( boot_cpu_has(X86_FEATURE_SSBD) && opt_ssbd )
+        default_xen_spec_ctrl |= SPEC_CTRL_SSBD;
+
     if ( default_xen_spec_ctrl < 0 )
        opt_msr_sc_pv = opt_msr_sc_hvm = 0;
 
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -71,6 +71,7 @@
 #include <asm/apic.h>
 #include <asm/mc146818rtc.h>
 #include <asm/hpet.h>
+#include <asm/spec_ctrl.h>
 #include <public/arch-x86/cpuid.h>
 #include <xsm/xsm.h>
 
@@ -822,7 +823,8 @@ static void pv_cpuid(struct cpu_user_reg
             if ( (uint32_t)regs->ecx == 0 )
             {
                 if ( !opt_msr_sc_pv )
-                    d &= ~cpufeat_mask(X86_FEATURE_IBRSB);
+                    d &= ~(cpufeat_mask(X86_FEATURE_IBRSB) |
+                           cpufeat_mask(X86_FEATURE_SSBD));
 
                 /*
                  * Override STIBP to match IBRS.  Guests can safely use STIBP
@@ -911,7 +913,8 @@ static void pv_cpuid(struct cpu_user_reg
                   cpufeat_mask(X86_FEATURE_FSGSBASE));
 
             if ( opt_msr_sc_pv )
-                d &= cpufeat_mask(X86_FEATURE_IBRSB);
+                d &= cpufeat_mask(X86_FEATURE_IBRSB) |
+                     cpufeat_mask(X86_FEATURE_SSBD);
             else
                 d = 0;
 
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -167,6 +167,7 @@
 /* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
 #define X86_FEATURE_IBRSB	(9*32+26) /* IBRS and IBPB support (used by Intel) */
 #define X86_FEATURE_STIBP	(9*32+27) /* STIBP */
+#define X86_FEATURE_SSBD	(9*32+31) /* MSR_SPEC_CTRL.SSBD available */
 
 #define cpu_has(c, bit)		test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)	test_bit(bit, boot_cpu_data.x86_capability)
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -35,6 +35,7 @@
 #define MSR_SPEC_CTRL			0x00000048
 #define SPEC_CTRL_IBRS			(_AC(1, UL) << 0)
 #define SPEC_CTRL_STIBP			(_AC(1, UL) << 1)
+#define SPEC_CTRL_SSBD			(_AC(1, UL) << 2)
 
 #define MSR_PRED_CMD			0x00000049
 #define PRED_CMD_IBPB			(_AC(1, UL) << 0)
