]> xenbits.xensource.com Git - people/aperard/xen-unstable.git/commitdiff
x86/spec-ctrl: Support BHI_DIS_S in order to mitigate BHI
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 26 Mar 2024 19:01:37 +0000 (19:01 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 9 Apr 2024 15:37:30 +0000 (16:37 +0100)
Introduce a "bhi-dis-s" boolean to match the other options we have for
MSR_SPEC_CTRL values.  Also introduce bhi_calculations().

Use BHI_DIS_S whenever possible.

Guests which are levelled to be migration compatible with older CPUs can't see
BHI_DIS_S, and Xen must fill in the difference to make the guest safe.  Use
the virt MSR_SPEC_CTRL infrastructure to force BHI_DIS_S behind the guest's
back.

This is part of XSA-456 / CVE-2024-2201.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
docs/misc/xen-command-line.pandoc
xen/arch/x86/hvm/vmx/vmx.c
xen/arch/x86/include/asm/spec_ctrl.h
xen/arch/x86/spec_ctrl.c

index 14cafb462a9a8cf65e9fd5781dce4f56957ce9e8..b87e7ebc35ebf5bd0dada92fd785a2947b8a232e 100644 (file)
@@ -2377,7 +2377,8 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).
 >              {msr-sc,rsb,verw,ibpb-entry}=<bool>|{pv,hvm}=<bool>,
 >              bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,psfd,
 >              eager-fpu,l1d-flush,branch-harden,srb-lock,
->              unpriv-mmio,gds-mit,div-scrub,lock-harden}=<bool> ]`
+>              unpriv-mmio,gds-mit,div-scrub,lock-harden,
+>              bhi-dis-s}=<bool> ]`
 
 Controls for speculative execution sidechannel mitigations.  By default, Xen
 will pick the most appropriate mitigations based on compiled in support,
@@ -2458,6 +2459,11 @@ option can be used to force or prevent Xen using the feature itself.  By
 default, Xen will not use PSFD.  PSFD is implied by SSBD, and SSBD is off by
 default.
 
+On hardware supporting BHI_DIS_S (Branch History Injection Disable
+Supervisor), the `bhi-dis-s=` option can be used to force or prevent Xen using
+the feature itself.  By default Xen will use BHI_DIS_S on hardware susceptible
+to Branch History Injection.
+
 On hardware supporting IBPB (Indirect Branch Prediction Barrier), the `ibpb=`
 option can be used to force (the default) or prevent Xen from issuing branch
 prediction barriers on vcpu context switches.
index c886331006266ed8eee56dd3ef4cf864bfcfe6ac..0935762378433fcad5081439c6db8f7af8a2d7a2 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/mce.h>
 #include <asm/monitor.h>
 #include <asm/prot-key.h>
+#include <asm/spec_ctrl.h>
 #include <public/arch-x86/cpuid.h>
 
 static bool __initdata opt_force_ept;
@@ -842,6 +843,22 @@ static void cf_check vmx_cpuid_policy_changed(struct vcpu *v)
             vmx_del_msr(v, MSR_SPEC_CTRL, VMX_MSR_GUEST);
     }
 
+    if ( cpu_has_vmx_virt_spec_ctrl )
+    {
+        /*
+         * If we're on BHI_DIS_S capable hardware, the short loop sequence is
+         * not sufficient to mitigate Native-BHI.  If the VM can't see it
+         * (i.e. it's levelled with older hardware), force it behind the
+         * guests back for safey.
+         *
+         * Because there's not a real Host/Guest split of the MSR_SPEC_CTRL
+         * value, this only works as expected when Xen is using BHI_DIS_S too.
+         */
+        bool force_bhi_dis_s = opt_bhi_dis_s && !cp->feat.bhi_ctrl;
+
+        __vmwrite(SPEC_CTRL_MASK, force_bhi_dis_s ? SPEC_CTRL_BHI_DIS_S : 0);
+    }
+
     /* MSR_PRED_CMD is safe to pass through if the guest knows about it. */
     if ( cp->feat.ibrsb || cp->extd.ibpb )
         vmx_clear_msr_intercept(v, MSR_PRED_CMD,  VMX_MSR_RW);
index 95dd081f303568e1382f63b9f5a86cad75565492..b2d2c258421df80d64d73794a0cda48cb4e2855b 100644 (file)
@@ -77,6 +77,7 @@ static always_inline void spec_ctrl_new_guest_context(void)
 
 extern int8_t opt_ibpb_ctxt_switch;
 extern bool opt_ssbd;
+extern int8_t opt_bhi_dis_s;
 extern int8_t opt_eager_fpu;
 extern int8_t opt_l1d_flush;
 
index ed52ce3cc5b09f84e8a21be01ebe6c74d1af34fa..a5096ab4fb6b78d86fea1b186c2f77a034fb3353 100644 (file)
@@ -47,6 +47,7 @@ static int8_t __initdata opt_ibrs = -1;
 static int8_t __initdata opt_stibp = -1;
 bool __ro_after_init opt_ssbd;
 static int8_t __initdata opt_psfd = -1;
+int8_t __ro_after_init opt_bhi_dis_s = -1;
 
 int8_t __ro_after_init opt_ibpb_ctxt_switch = -1;
 int8_t __ro_after_init opt_eager_fpu = -1;
@@ -269,6 +270,8 @@ static int __init cf_check parse_spec_ctrl(const char *s)
             opt_ssbd = val;
         else if ( (val = parse_boolean("psfd", s, ss)) >= 0 )
             opt_psfd = val;
+        else if ( (val = parse_boolean("bhi-dis-s", s, ss)) >= 0 )
+            opt_bhi_dis_s = val;
 
         /* Misc settings. */
         else if ( (val = parse_boolean("ibpb", s, ss)) >= 0 )
@@ -524,7 +527,7 @@ static void __init print_details(enum ind_thunk thunk)
                "\n");
 
     /* Settings for Xen's protection, irrespective of guests. */
-    printk("  Xen settings: %s%sSPEC_CTRL: %s%s%s%s%s, Other:%s%s%s%s%s%s%s\n",
+    printk("  Xen settings: %s%sSPEC_CTRL: %s%s%s%s%s%s, Other:%s%s%s%s%s%s%s\n",
            thunk != THUNK_NONE      ? "BTI-Thunk: " : "",
            thunk == THUNK_NONE      ? "" :
            thunk == THUNK_RETPOLINE ? "RETPOLINE, " :
@@ -542,6 +545,8 @@ static void __init print_details(enum ind_thunk thunk)
            (!boot_cpu_has(X86_FEATURE_PSFD) &&
             !boot_cpu_has(X86_FEATURE_INTEL_PSFD))   ? "" :
            (default_xen_spec_ctrl & SPEC_CTRL_PSFD)  ? " PSFD+" : " PSFD-",
+           !boot_cpu_has(X86_FEATURE_BHI_CTRL)       ? "" :
+           (default_xen_spec_ctrl & SPEC_CTRL_BHI_DIS_S) ? " BHI_DIS_S+" : " BHI_DIS_S-",
            !(caps & ARCH_CAPS_TSX_CTRL)              ? "" :
            (opt_tsx & 1)                             ? " TSX+" : " TSX-",
            !cpu_has_srbds_ctrl                       ? "" :
@@ -1596,6 +1601,21 @@ static void __init gds_calculations(void)
     }
 }
 
+/*
+ * https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html
+ */
+static void __init bhi_calculations(void)
+{
+    if ( opt_bhi_dis_s == -1 )
+        opt_bhi_dis_s = !boot_cpu_has(X86_FEATURE_BHI_NO);
+
+    if ( !boot_cpu_has(X86_FEATURE_BHI_CTRL) )
+        opt_bhi_dis_s = false;
+
+    if ( opt_bhi_dis_s )
+        default_xen_spec_ctrl |= SPEC_CTRL_BHI_DIS_S;
+}
+
 void spec_ctrl_init_domain(struct domain *d)
 {
     bool pv = is_pv_domain(d);
@@ -2140,6 +2160,8 @@ void __init init_speculation_mitigations(void)
 
     gds_calculations();
 
+    bhi_calculations();
+
     print_details(thunk);
 
     /*