mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86/spec-ctrl: Support BHI_DIS_S in order to mitigate BHI
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>
(cherry picked from commit 62a1106415)
This commit is contained in:
1 parent
cf630e30dc
commit
028ef76307
4 files changed
+48
-2
No files matched your search
@@ -2263,7 +2263,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,
|
||||
@@ -2342,6 +2343,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.
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <asm/event.h>
|
||||
#include <asm/mce.h>
|
||||
#include <asm/monitor.h>
|
||||
#include <asm/spec_ctrl.h>
|
||||
#include <public/arch-x86/cpuid.h>
|
||||
|
||||
static bool_t __initdata opt_force_ept;
|
||||
@@ -781,6 +782,22 @@ static void 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);
|
||||
|
||||
@@ -58,6 +58,7 @@ static int8_t __initdata opt_ibrs = -1;
|
||||
int8_t __initdata opt_stibp = -1;
|
||||
bool __read_mostly opt_ssbd;
|
||||
int8_t __initdata opt_psfd = -1;
|
||||
int8_t __read_mostly opt_bhi_dis_s = -1;
|
||||
|
||||
int8_t __read_mostly opt_ibpb_ctxt_switch = -1;
|
||||
int8_t __read_mostly opt_eager_fpu = -1;
|
||||
@@ -274,6 +275,8 @@ static int __init 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 )
|
||||
@@ -508,7 +511,7 @@ static void __init print_details(enum ind_thunk thunk)
|
||||
"\n");
|
||||
|
||||
/* Settings for Xen's protection, irrespective of guests. */
|
||||
printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s%s%s, Other:%s%s%s%s%s%s%s\n",
|
||||
printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s%s%s%s%s, Other:%s%s%s%s%s%s%s\n",
|
||||
thunk == THUNK_NONE ? "N/A" :
|
||||
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
|
||||
thunk == THUNK_LFENCE ? "LFENCE" :
|
||||
@@ -525,6 +528,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 ? "" :
|
||||
@@ -1572,6 +1577,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);
|
||||
@@ -2111,6 +2131,8 @@ void __init init_speculation_mitigations(void)
|
||||
|
||||
gds_calculations();
|
||||
|
||||
bhi_calculations();
|
||||
|
||||
print_details(thunk);
|
||||
|
||||
/*
|
||||
|
||||
@@ -89,6 +89,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;
|
||||
|
||||
|
||||