|
|
4401709 |
From: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
4401709 |
Subject: x86/spec-ctrl: Mitigations for LazyFPU
|
|
|
4401709 |
|
|
|
4401709 |
Intel Core processors since at least Nehalem speculate past #NM, which is the
|
|
|
4401709 |
mechanism by which lazy FPU context switching is implemented.
|
|
|
4401709 |
|
|
|
4401709 |
On affected processors, Xen must use fully eager FPU context switching to
|
|
|
4401709 |
prevent guests from being able to read FPU state (SSE/AVX/etc) from previously
|
|
|
4401709 |
scheduled vcpus.
|
|
|
4401709 |
|
|
|
4401709 |
This is part of XSA-267 / CVE-2018-3665
|
|
|
4401709 |
|
|
|
4401709 |
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
4401709 |
Reviewed-by: Jan Beulich <jbeulich@suse.com>
|
|
|
4401709 |
|
|
|
4401709 |
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
|
|
|
4401709 |
index 6300f69..52ed051 100644
|
|
|
4401709 |
--- a/docs/misc/xen-command-line.markdown
|
|
|
4401709 |
+++ b/docs/misc/xen-command-line.markdown
|
|
|
4401709 |
@@ -1635,7 +1635,7 @@ false disable the quirk workaround, which is also the default.
|
|
|
4401709 |
|
|
|
4401709 |
### spec-ctrl (x86)
|
|
|
4401709 |
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>,
|
|
|
4401709 |
-> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd}=<bool> ]`
|
|
|
4401709 |
+> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu}=<bool> ]`
|
|
|
4401709 |
|
|
|
4401709 |
Controls for speculative execution sidechannel mitigations. By default, Xen
|
|
|
4401709 |
will pick the most appropriate mitigations based on compiled in support,
|
|
|
4401709 |
@@ -1685,6 +1685,11 @@ hardware, this is a global option applied at boot, and not virtualised for
|
|
|
4401709 |
guest use. On Intel hardware, the feature is virtualised for guests,
|
|
|
4401709 |
independently of Xen's choice of setting.
|
|
|
4401709 |
|
|
|
4401709 |
+On all hardware, the `eager-fpu=` option can be used to force or prevent Xen
|
|
|
4401709 |
+from using fully eager FPU context switches. This is currently implemented as
|
|
|
4401709 |
+a global control. By default, Xen will choose to use fully eager context
|
|
|
4401709 |
+switches on hardware believed to speculate past #NM exceptions.
|
|
|
4401709 |
+
|
|
|
4401709 |
### sync\_console
|
|
|
4401709 |
> `= <boolean>`
|
|
|
4401709 |
|
|
|
4401709 |
diff --git a/xen/arch/x86/i387.c b/xen/arch/x86/i387.c
|
|
|
4401709 |
index 1da31af..c3fda87 100644
|
|
|
4401709 |
--- a/xen/arch/x86/i387.c
|
|
|
4401709 |
+++ b/xen/arch/x86/i387.c
|
|
|
4401709 |
@@ -15,6 +15,7 @@
|
|
|
4401709 |
#include <asm/i387.h>
|
|
|
4401709 |
#include <asm/xstate.h>
|
|
|
4401709 |
#include <asm/asm_defns.h>
|
|
|
4401709 |
+#include <asm/spec_ctrl.h>
|
|
|
4401709 |
|
|
|
4401709 |
/*******************************/
|
|
|
4401709 |
/* FPU Restore Functions */
|
|
|
4401709 |
@@ -307,6 +308,8 @@ int vcpu_init_fpu(struct vcpu *v)
|
|
|
4401709 |
{
|
|
|
4401709 |
int rc;
|
|
|
4401709 |
|
|
|
4401709 |
+ v->arch.fully_eager_fpu = opt_eager_fpu;
|
|
|
4401709 |
+
|
|
|
4401709 |
if ( (rc = xstate_alloc_save_area(v)) != 0 )
|
|
|
4401709 |
return rc;
|
|
|
4401709 |
|
|
|
4401709 |
diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c
|
|
|
4401709 |
index 8077000..ada4aac 100644
|
|
|
4401709 |
--- a/xen/arch/x86/spec_ctrl.c
|
|
|
4401709 |
+++ b/xen/arch/x86/spec_ctrl.c
|
|
|
4401709 |
@@ -44,6 +44,7 @@ static enum ind_thunk {
|
|
|
4401709 |
static int8_t __initdata opt_ibrs = -1;
|
|
|
4401709 |
bool __read_mostly opt_ibpb = true;
|
|
|
4401709 |
bool __read_mostly opt_ssbd = false;
|
|
|
4401709 |
+int8_t __read_mostly opt_eager_fpu = -1;
|
|
|
4401709 |
|
|
|
4401709 |
bool __initdata bsp_delay_spec_ctrl;
|
|
|
4401709 |
uint8_t __read_mostly default_xen_spec_ctrl;
|
|
|
4401709 |
@@ -114,6 +115,7 @@ static int __init parse_spec_ctrl(char *s)
|
|
|
4401709 |
opt_thunk = THUNK_JMP;
|
|
|
4401709 |
opt_ibrs = 0;
|
|
|
4401709 |
opt_ibpb = false;
|
|
|
4401709 |
+ opt_eager_fpu = 0;
|
|
|
4401709 |
}
|
|
|
4401709 |
else if ( val > 0 )
|
|
|
4401709 |
rc = -EINVAL;
|
|
|
4401709 |
@@ -167,6 +169,8 @@ static int __init parse_spec_ctrl(char *s)
|
|
|
4401709 |
opt_ibpb = val;
|
|
|
4401709 |
else if ( (val = parse_boolean("ssbd", s, ss)) >= 0 )
|
|
|
4401709 |
opt_ssbd = val;
|
|
|
4401709 |
+ else if ( (val = parse_boolean("eager-fpu", s, ss)) >= 0 )
|
|
|
4401709 |
+ opt_eager_fpu = val;
|
|
|
4401709 |
else
|
|
|
4401709 |
rc = -EINVAL;
|
|
|
4401709 |
|
|
|
4401709 |
@@ -223,15 +227,19 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
|
|
|
4401709 |
* Alternatives blocks for protecting against and/or virtualising
|
|
|
4401709 |
* mitigation support for guests.
|
|
|
4401709 |
*/
|
|
|
4401709 |
- printk(" Support for VMs: PV:%s%s%s, HVM:%s%s%s\n",
|
|
|
4401709 |
+ printk(" Support for VMs: PV:%s%s%s%s, HVM:%s%s%s%s\n",
|
|
|
4401709 |
(boot_cpu_has(X86_FEATURE_SC_MSR_PV) ||
|
|
|
4401709 |
- boot_cpu_has(X86_FEATURE_SC_RSB_PV)) ? "" : " None",
|
|
|
4401709 |
+ boot_cpu_has(X86_FEATURE_SC_RSB_PV) ||
|
|
|
4401709 |
+ opt_eager_fpu) ? "" : " None",
|
|
|
4401709 |
boot_cpu_has(X86_FEATURE_SC_MSR_PV) ? " MSR_SPEC_CTRL" : "",
|
|
|
4401709 |
boot_cpu_has(X86_FEATURE_SC_RSB_PV) ? " RSB" : "",
|
|
|
4401709 |
+ opt_eager_fpu ? " EAGER_FPU" : "",
|
|
|
4401709 |
(boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ||
|
|
|
4401709 |
- boot_cpu_has(X86_FEATURE_SC_RSB_HVM)) ? "" : " None",
|
|
|
4401709 |
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ||
|
|
|
4401709 |
+ opt_eager_fpu) ? "" : " None",
|
|
|
4401709 |
boot_cpu_has(X86_FEATURE_SC_MSR_HVM) ? " MSR_SPEC_CTRL" : "",
|
|
|
4401709 |
- boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "");
|
|
|
4401709 |
+ boot_cpu_has(X86_FEATURE_SC_RSB_HVM) ? " RSB" : "",
|
|
|
4401709 |
+ opt_eager_fpu ? " EAGER_FPU" : "");
|
|
|
4401709 |
|
|
|
4401709 |
printk("XPTI: %s\n",
|
|
|
4401709 |
boot_cpu_has(X86_FEATURE_NO_XPTI) ? "disabled" : "enabled");
|
|
|
4401709 |
@@ -321,6 +329,82 @@ static bool __init retpoline_safe(uint64_t caps)
|
|
|
4401709 |
}
|
|
|
4401709 |
}
|
|
|
4401709 |
|
|
|
4401709 |
+/* Calculate whether this CPU speculates past #NM */
|
|
|
4401709 |
+static bool __init should_use_eager_fpu(void)
|
|
|
4401709 |
+{
|
|
|
4401709 |
+ /*
|
|
|
4401709 |
+ * Assume all unrecognised processors are ok. This is only known to
|
|
|
4401709 |
+ * affect Intel Family 6 processors.
|
|
|
4401709 |
+ */
|
|
|
4401709 |
+ if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
|
|
|
4401709 |
+ boot_cpu_data.x86 != 6 )
|
|
|
4401709 |
+ return false;
|
|
|
4401709 |
+
|
|
|
4401709 |
+ switch ( boot_cpu_data.x86_model )
|
|
|
4401709 |
+ {
|
|
|
4401709 |
+ /*
|
|
|
4401709 |
+ * Core processors since at least Nehalem are vulnerable.
|
|
|
4401709 |
+ */
|
|
|
4401709 |
+ case 0x1e: /* Nehalem */
|
|
|
4401709 |
+ case 0x1f: /* Auburndale / Havendale */
|
|
|
4401709 |
+ case 0x1a: /* Nehalem EP */
|
|
|
4401709 |
+ case 0x2e: /* Nehalem EX */
|
|
|
4401709 |
+ case 0x25: /* Westmere */
|
|
|
4401709 |
+ case 0x2c: /* Westmere EP */
|
|
|
4401709 |
+ case 0x2f: /* Westmere EX */
|
|
|
4401709 |
+ case 0x2a: /* SandyBridge */
|
|
|
4401709 |
+ case 0x2d: /* SandyBridge EP/EX */
|
|
|
4401709 |
+ case 0x3a: /* IvyBridge */
|
|
|
4401709 |
+ case 0x3e: /* IvyBridge EP/EX */
|
|
|
4401709 |
+ case 0x3c: /* Haswell */
|
|
|
4401709 |
+ case 0x3f: /* Haswell EX/EP */
|
|
|
4401709 |
+ case 0x45: /* Haswell D */
|
|
|
4401709 |
+ case 0x46: /* Haswell H */
|
|
|
4401709 |
+ case 0x3d: /* Broadwell */
|
|
|
4401709 |
+ case 0x47: /* Broadwell H */
|
|
|
4401709 |
+ case 0x4f: /* Broadwell EP/EX */
|
|
|
4401709 |
+ case 0x56: /* Broadwell D */
|
|
|
4401709 |
+ case 0x4e: /* Skylake M */
|
|
|
4401709 |
+ case 0x55: /* Skylake X */
|
|
|
4401709 |
+ case 0x5e: /* Skylake D */
|
|
|
4401709 |
+ case 0x66: /* Cannonlake */
|
|
|
4401709 |
+ case 0x67: /* Cannonlake? */
|
|
|
4401709 |
+ case 0x8e: /* Kabylake M */
|
|
|
4401709 |
+ case 0x9e: /* Kabylake D */
|
|
|
4401709 |
+ return true;
|
|
|
4401709 |
+
|
|
|
4401709 |
+ /*
|
|
|
4401709 |
+ * Atom processors are not vulnerable.
|
|
|
4401709 |
+ */
|
|
|
4401709 |
+ case 0x1c: /* Pineview */
|
|
|
4401709 |
+ case 0x26: /* Lincroft */
|
|
|
4401709 |
+ case 0x27: /* Penwell */
|
|
|
4401709 |
+ case 0x35: /* Cloverview */
|
|
|
4401709 |
+ case 0x36: /* Cedarview */
|
|
|
4401709 |
+ case 0x37: /* Baytrail / Valleyview (Silvermont) */
|
|
|
4401709 |
+ case 0x4d: /* Avaton / Rangely (Silvermont) */
|
|
|
4401709 |
+ case 0x4c: /* Cherrytrail / Brasswell */
|
|
|
4401709 |
+ case 0x4a: /* Merrifield */
|
|
|
4401709 |
+ case 0x5a: /* Moorefield */
|
|
|
4401709 |
+ case 0x5c: /* Goldmont */
|
|
|
4401709 |
+ case 0x5f: /* Denverton */
|
|
|
4401709 |
+ case 0x7a: /* Gemini Lake */
|
|
|
4401709 |
+ return false;
|
|
|
4401709 |
+
|
|
|
4401709 |
+ /*
|
|
|
4401709 |
+ * Knights processors are not vulnerable.
|
|
|
4401709 |
+ */
|
|
|
4401709 |
+ case 0x57: /* Knights Landing */
|
|
|
4401709 |
+ case 0x85: /* Knights Mill */
|
|
|
4401709 |
+ return false;
|
|
|
4401709 |
+
|
|
|
4401709 |
+ default:
|
|
|
4401709 |
+ printk("Unrecognised CPU model %#x - assuming vulnerable to LazyFPU\n",
|
|
|
4401709 |
+ boot_cpu_data.x86_model);
|
|
|
4401709 |
+ return true;
|
|
|
4401709 |
+ }
|
|
|
4401709 |
+}
|
|
|
4401709 |
+
|
|
|
4401709 |
void __init init_speculation_mitigations(void)
|
|
|
4401709 |
{
|
|
|
4401709 |
enum ind_thunk thunk = THUNK_DEFAULT;
|
|
|
4401709 |
@@ -519,6 +603,10 @@ void __init init_speculation_mitigations(void)
|
|
|
4401709 |
if ( !boot_cpu_has(X86_FEATURE_IBRSB) && !boot_cpu_has(X86_FEATURE_IBPB) )
|
|
|
4401709 |
opt_ibpb = false;
|
|
|
4401709 |
|
|
|
4401709 |
+ /* Check whether Eager FPU should be enabled by default. */
|
|
|
4401709 |
+ if ( opt_eager_fpu == -1 )
|
|
|
4401709 |
+ opt_eager_fpu = should_use_eager_fpu();
|
|
|
4401709 |
+
|
|
|
4401709 |
/* (Re)init BSP state now that default_spec_ctrl_flags has been calculated. */
|
|
|
4401709 |
init_shadow_spec_ctrl_state();
|
|
|
4401709 |
|
|
|
4401709 |
diff --git a/xen/include/asm-x86/spec_ctrl.h b/xen/include/asm-x86/spec_ctrl.h
|
|
|
4401709 |
index 91bed1b..5b40afb 100644
|
|
|
4401709 |
--- a/xen/include/asm-x86/spec_ctrl.h
|
|
|
4401709 |
+++ b/xen/include/asm-x86/spec_ctrl.h
|
|
|
4401709 |
@@ -28,6 +28,7 @@ void init_speculation_mitigations(void);
|
|
|
4401709 |
|
|
|
4401709 |
extern bool opt_ibpb;
|
|
|
4401709 |
extern bool opt_ssbd;
|
|
|
4401709 |
+extern int8_t opt_eager_fpu;
|
|
|
4401709 |
|
|
|
4401709 |
extern bool bsp_delay_spec_ctrl;
|
|
|
4401709 |
extern uint8_t default_xen_spec_ctrl;
|