x86/spec-ctrl: Introduce an option to control L1D_FLUSH for HVM HAP guests

This mitigation requires up-to-date microcode, and is enabled by default on
affected hardware if available, and is used for HVM guests

The default for SMT/Hyperthreading is far more complicated to reason about,
not least because we don't know if the user is going to want to run any HVM
guests to begin with.  If a explicit default isn't given, nag the user to
perform a risk assessment and choose an explicit default, and leave other
configuration to the toolstack.

This is part of XSA-273 / CVE-2018-3620.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2018-08-14 16:56:47 +01:00
1 parent fd9823faf9
commit 3bd36952da
4 files changed
+50 -3

No files matched your search

+8 -1
View File
@@ -1825,7 +1825,8 @@ By default SSBD will be mitigated at runtime (i.e `ssbd=runtime`).
### spec-ctrl (x86)
> `= List of [ <bool>, xen=<bool>, {pv,hvm,msr-sc,rsb}=<bool>,
> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu}=<bool> ]`
> bti-thunk=retpoline|lfence|jmp, {ibrs,ibpb,ssbd,eager-fpu,
> l1d-flush}=<bool> ]`
Controls for speculative execution sidechannel mitigations. By default, Xen
will pick the most appropriate mitigations based on compiled in support,
@@ -1880,6 +1881,12 @@ from using fully eager FPU context switches. This is currently implemented as
a global control. By default, Xen will choose to use fully eager context
switches on hardware believed to speculate past #NM exceptions.
On hardware supporting L1D_FLUSH, the `l1d-flush=` option can be used to force
or prevent Xen from issuing an L1 data cache flush on each VMEntry.
Irrespective of Xen's setting, the feature is virtualised for HVM guests to
use. By default, Xen will enable this mitigation on hardware believed to be
vulnerable to L1TF.
### sync\_console
> `= <boolean>`
+5
View File
@@ -38,6 +38,7 @@
#include <asm/flushtlb.h>
#include <asm/monitor.h>
#include <asm/shadow.h>
#include <asm/spec_ctrl.h>
#include <asm/tboot.h>
#include <asm/apic.h>
@@ -1269,6 +1270,10 @@ static int construct_vmcs(struct vcpu *v)
vmx_vlapic_msr_changed(v);
if ( opt_l1d_flush && paging_mode_hap(d) )
rc = vmx_add_msr(v, MSR_FLUSH_CMD, FLUSH_CMD_L1D,
VMX_MSR_GUEST_LOADONLY);
out:
vmx_vmcs_exit(v);
+36 -2
View File
@@ -19,11 +19,13 @@
#include <xen/errno.h>
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/warning.h>
#include <asm/microcode.h>
#include <asm/msr.h>
#include <asm/processor.h>
#include <asm/pv/shim.h>
#include <asm/setup.h>
#include <asm/spec_ctrl.h>
#include <asm/spec_ctrl_asm.h>
@@ -46,6 +48,7 @@ static int8_t __initdata opt_ibrs = -1;
bool __read_mostly opt_ibpb = true;
bool __read_mostly opt_ssbd = false;
int8_t __read_mostly opt_eager_fpu = -1;
int8_t __read_mostly opt_l1d_flush = -1;
bool __initdata bsp_delay_spec_ctrl;
uint8_t __read_mostly default_xen_spec_ctrl;
@@ -139,6 +142,7 @@ static int __init parse_spec_ctrl(const char *s)
opt_ibrs = 0;
opt_ibpb = false;
opt_ssbd = false;
opt_l1d_flush = 0;
}
else if ( val > 0 )
rc = -EINVAL;
@@ -194,6 +198,8 @@ static int __init parse_spec_ctrl(const char *s)
opt_ssbd = val;
else if ( (val = parse_boolean("eager-fpu", s, ss)) >= 0 )
opt_eager_fpu = val;
else if ( (val = parse_boolean("l1d-flush", s, ss)) >= 0 )
opt_l1d_flush = val;
else
rc = -EINVAL;
@@ -290,7 +296,7 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
"\n");
/* Settings for Xen's protection, irrespective of guests. */
printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s\n",
printk(" Xen settings: BTI-Thunk %s, SPEC_CTRL: %s%s, Other:%s%s\n",
thunk == THUNK_NONE ? "N/A" :
thunk == THUNK_RETPOLINE ? "RETPOLINE" :
thunk == THUNK_LFENCE ? "LFENCE" :
@@ -299,7 +305,8 @@ static void __init print_details(enum ind_thunk thunk, uint64_t caps)
(default_xen_spec_ctrl & SPEC_CTRL_IBRS) ? "IBRS+" : "IBRS-",
!boot_cpu_has(X86_FEATURE_SSBD) ? "" :
(default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-",
opt_ibpb ? " IBPB" : "");
opt_ibpb ? " IBPB" : "",
opt_l1d_flush ? " L1D_FLUSH" : "");
/* L1TF diagnostics, printed if vulnerable or PV shadowing is in use. */
if ( cpu_has_bug_l1tf || opt_pv_l1tf )
@@ -871,6 +878,33 @@ void __init init_speculation_mitigations(void)
opt_pv_l1tf = OPT_PV_L1TF_DOMU;
}
/*
* By default, enable L1D_FLUSH on L1TF-vulnerable hardware, unless
* instructed to skip the flush on vmentry by our outer hypervisor.
*/
if ( !boot_cpu_has(X86_FEATURE_L1D_FLUSH) )
opt_l1d_flush = 0;
else if ( opt_l1d_flush == -1 )
opt_l1d_flush = cpu_has_bug_l1tf && !(caps & ARCH_CAPS_SKIP_L1DFL);
/*
* We do not disable HT by default on affected hardware.
*
* Firstly, if the user intends to use exclusively PV, or HVM shadow
* guests, HT isn't a concern and should remain fully enabled. Secondly,
* safety for HVM HAP guests can be arranged by the toolstack with core
* parking, pinning or cpupool configurations, including mixed setups.
*
* However, if we are on affected hardware, with HT enabled, and the user
* hasn't explicitly chosen whether to use HT or not, nag them to do so.
*/
if ( opt_smt == -1 && cpu_has_bug_l1tf && !pv_shim &&
boot_cpu_data.x86_num_siblings > 1 )
warning_add(
"Booted on L1TF-vulnerable hardware with SMT/Hyperthreading\n"
"enabled. Please assess your configuration and choose an\n"
"explicit 'smt=<bool>' setting. See XSA-273.\n");
print_details(thunk, caps);
/*
+1
View File
@@ -29,6 +29,7 @@ void init_speculation_mitigations(void);
extern bool opt_ibpb;
extern bool opt_ssbd;
extern int8_t opt_eager_fpu;
extern int8_t opt_l1d_flush;
extern bool bsp_delay_spec_ctrl;
extern uint8_t default_xen_spec_ctrl;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.