x86/bugs, kvm: Introduce boot-time control of L1TF mitigations
Introduce the 'l1tf=' kernel command line option to allow for boot-time switching of mitigation that is used on processors affected by L1TF. The possible values are: full Provides all available mitigations for the L1TF vulnerability. Disables SMT and enables all mitigations in the hypervisors. SMT control via /sys/devices/system/cpu/smt/control is still possible after boot. Hypervisors will issue a warning when the first VM is started in a potentially insecure configuration, i.e. SMT enabled or L1D flush disabled. full,force Same as 'full', but disables SMT control. Implies the 'nosmt=force' command line option. sysfs control of SMT and the hypervisor flush control is disabled. flush Leaves SMT enabled and enables the conditional hypervisor mitigation. Hypervisors will issue a warning when the first VM is started in a potentially insecure configuration, i.e. SMT enabled or L1D flush disabled. flush,nosmt Disables SMT and enables the conditional hypervisor mitigation. SMT control via /sys/devices/system/cpu/smt/control is still possible after boot. If SMT is reenabled or flushing disabled at runtime hypervisors will issue a warning. flush,nowarn Same as 'flush', but hypervisors will not warn when a VM is started in a potentially insecure configuration. off Disables hypervisor mitigations and doesn't emit any warnings. Default is 'flush'. Let KVM adhere to these semantics, which means: - 'lt1f=full,force' : Performe L1D flushes. No runtime control possible. - 'l1tf=full' - 'l1tf-flush' - 'l1tf=flush,nosmt' : Perform L1D flushes and warn on VM start if SMT has been runtime enabled or L1D flushing has been run-time enabled - 'l1tf=flush,nowarn' : Perform L1D flushes and no warnings are emitted. - 'l1tf=off' : L1D flushes are not performed and no warnings are emitted. KVM can always override the L1D flushing behavior using its 'vmentry_l1d_flush' module parameter except when lt1f=full,force is set. This makes KVM's private 'nosmt' option redundant, and as it is a bit non-systematic anyway (this is something to control globally, not on hypervisor level), remove that option. Add the missing Documentation entry for the l1tf vulnerability sysfs file while at it. Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Jiri Kosina <jkosina@suse.cz> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lkml.kernel.org/r/20180713142323.202758176@linutronix.de
This commit is contained in:

committed by
Thomas Gleixner

orang tua
fee0aede6f
melakukan
d90a7a0ec8
@@ -71,9 +71,6 @@ static const struct x86_cpu_id vmx_cpu_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id);
|
||||
|
||||
static bool __read_mostly nosmt;
|
||||
module_param(nosmt, bool, S_IRUGO);
|
||||
|
||||
static bool __read_mostly enable_vpid = 1;
|
||||
module_param_named(vpid, enable_vpid, bool, 0444);
|
||||
|
||||
@@ -215,15 +212,31 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
|
||||
{
|
||||
struct page *page;
|
||||
|
||||
/* If set to 'auto' select 'cond' */
|
||||
if (l1tf == VMENTER_L1D_FLUSH_AUTO)
|
||||
l1tf = VMENTER_L1D_FLUSH_COND;
|
||||
|
||||
if (!enable_ept) {
|
||||
l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If set to auto use the default l1tf mitigation method */
|
||||
if (l1tf == VMENTER_L1D_FLUSH_AUTO) {
|
||||
switch (l1tf_mitigation) {
|
||||
case L1TF_MITIGATION_OFF:
|
||||
l1tf = VMENTER_L1D_FLUSH_NEVER;
|
||||
break;
|
||||
case L1TF_MITIGATION_FLUSH_NOWARN:
|
||||
case L1TF_MITIGATION_FLUSH:
|
||||
case L1TF_MITIGATION_FLUSH_NOSMT:
|
||||
l1tf = VMENTER_L1D_FLUSH_COND;
|
||||
break;
|
||||
case L1TF_MITIGATION_FULL:
|
||||
case L1TF_MITIGATION_FULL_FORCE:
|
||||
l1tf = VMENTER_L1D_FLUSH_ALWAYS;
|
||||
break;
|
||||
}
|
||||
} else if (l1tf_mitigation == L1TF_MITIGATION_FULL_FORCE) {
|
||||
l1tf = VMENTER_L1D_FLUSH_ALWAYS;
|
||||
}
|
||||
|
||||
if (l1tf != VMENTER_L1D_FLUSH_NEVER && !vmx_l1d_flush_pages &&
|
||||
!boot_cpu_has(X86_FEATURE_FLUSH_L1D)) {
|
||||
page = alloc_pages(GFP_KERNEL, L1D_CACHE_ORDER);
|
||||
@@ -10571,19 +10584,36 @@ free_vcpu:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
#define L1TF_MSG "SMT enabled with L1TF CPU bug present. Refer to CVE-2018-3620 for details.\n"
|
||||
#define L1TF_MSG_SMT "L1TF CPU bug present and SMT on, data leak possible. See CVE-2018-3646 and https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html for details.\n"
|
||||
#define L1TF_MSG_L1D "L1TF CPU bug present and virtualization mitigation disabled, data leak possible. See CVE-2018-3646 and https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html for details.\n"
|
||||
|
||||
static int vmx_vm_init(struct kvm *kvm)
|
||||
{
|
||||
if (!ple_gap)
|
||||
kvm->arch.pause_in_guest = true;
|
||||
|
||||
if (boot_cpu_has(X86_BUG_L1TF) && cpu_smt_control == CPU_SMT_ENABLED) {
|
||||
if (nosmt) {
|
||||
pr_err(L1TF_MSG);
|
||||
return -EOPNOTSUPP;
|
||||
if (boot_cpu_has(X86_BUG_L1TF) && enable_ept) {
|
||||
switch (l1tf_mitigation) {
|
||||
case L1TF_MITIGATION_OFF:
|
||||
case L1TF_MITIGATION_FLUSH_NOWARN:
|
||||
/* 'I explicitly don't care' is set */
|
||||
break;
|
||||
case L1TF_MITIGATION_FLUSH:
|
||||
case L1TF_MITIGATION_FLUSH_NOSMT:
|
||||
case L1TF_MITIGATION_FULL:
|
||||
/*
|
||||
* Warn upon starting the first VM in a potentially
|
||||
* insecure environment.
|
||||
*/
|
||||
if (cpu_smt_control == CPU_SMT_ENABLED)
|
||||
pr_warn_once(L1TF_MSG_SMT);
|
||||
if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_NEVER)
|
||||
pr_warn_once(L1TF_MSG_L1D);
|
||||
break;
|
||||
case L1TF_MITIGATION_FULL_FORCE:
|
||||
/* Flush is enforced */
|
||||
break;
|
||||
}
|
||||
pr_warn(L1TF_MSG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user