Skip to content

Commit d90a7a0

Browse files
Jiri KosinaKAGA-KOKO
authored andcommitted
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
1 parent fee0aed commit d90a7a0

File tree

5 files changed

+165
-19
lines changed

5 files changed

+165
-19
lines changed

Documentation/ABI/testing/sysfs-devices-system-cpu

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ What: /sys/devices/system/cpu/vulnerabilities
476476
/sys/devices/system/cpu/vulnerabilities/spectre_v1
477477
/sys/devices/system/cpu/vulnerabilities/spectre_v2
478478
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
479+
/sys/devices/system/cpu/vulnerabilities/l1tf
479480
Date: January 2018
480481
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
481482
Description: Information about CPU vulnerabilities
@@ -488,6 +489,9 @@ Description: Information about CPU vulnerabilities
488489
"Vulnerable" CPU is affected and no mitigation in effect
489490
"Mitigation: $M" CPU is affected and mitigation $M is in effect
490491

492+
Details about the l1tf file can be found in
493+
Documentation/admin-guide/l1tf.rst
494+
491495
What: /sys/devices/system/cpu/smt
492496
/sys/devices/system/cpu/smt/active
493497
/sys/devices/system/cpu/smt/control

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,12 +1946,6 @@
19461946
[KVM,ARM] Allow use of GICv4 for direct injection of
19471947
LPIs.
19481948

1949-
kvm-intel.nosmt=[KVM,Intel] If the L1TF CPU bug is present (CVE-2018-3620)
1950-
and the system has SMT (aka Hyper-Threading) enabled then
1951-
don't allow guests to be created.
1952-
1953-
Default is 0 (allow guests to be created).
1954-
19551949
kvm-intel.ept= [KVM,Intel] Disable extended page tables
19561950
(virtualized MMU) support on capable Intel chips.
19571951
Default is 1 (enabled)
@@ -1989,6 +1983,68 @@
19891983
feature (tagged TLBs) on capable Intel chips.
19901984
Default is 1 (enabled)
19911985

1986+
l1tf= [X86] Control mitigation of the L1TF vulnerability on
1987+
affected CPUs
1988+
1989+
The kernel PTE inversion protection is unconditionally
1990+
enabled and cannot be disabled.
1991+
1992+
full
1993+
Provides all available mitigations for the
1994+
L1TF vulnerability. Disables SMT and
1995+
enables all mitigations in the
1996+
hypervisors, i.e. unconditional L1D flush.
1997+
1998+
SMT control and L1D flush control via the
1999+
sysfs interface is still possible after
2000+
boot. Hypervisors will issue a warning
2001+
when the first VM is started in a
2002+
potentially insecure configuration,
2003+
i.e. SMT enabled or L1D flush disabled.
2004+
2005+
full,force
2006+
Same as 'full', but disables SMT and L1D
2007+
flush runtime control. Implies the
2008+
'nosmt=force' command line option.
2009+
(i.e. sysfs control of SMT is disabled.)
2010+
2011+
flush
2012+
Leaves SMT enabled and enables the default
2013+
hypervisor mitigation, i.e. conditional
2014+
L1D flush.
2015+
2016+
SMT control and L1D flush control via the
2017+
sysfs interface is still possible after
2018+
boot. Hypervisors will issue a warning
2019+
when the first VM is started in a
2020+
potentially insecure configuration,
2021+
i.e. SMT enabled or L1D flush disabled.
2022+
2023+
flush,nosmt
2024+
2025+
Disables SMT and enables the default
2026+
hypervisor mitigation.
2027+
2028+
SMT control and L1D flush control via the
2029+
sysfs interface is still possible after
2030+
boot. Hypervisors will issue a warning
2031+
when the first VM is started in a
2032+
potentially insecure configuration,
2033+
i.e. SMT enabled or L1D flush disabled.
2034+
2035+
flush,nowarn
2036+
Same as 'flush', but hypervisors will not
2037+
warn when a VM is started in a potentially
2038+
insecure configuration.
2039+
2040+
off
2041+
Disables hypervisor mitigations and doesn't
2042+
emit any warnings.
2043+
2044+
Default is 'flush'.
2045+
2046+
For details see: Documentation/admin-guide/l1tf.rst
2047+
19922048
l2cr= [PPC]
19932049

19942050
l3cr= [PPC]

arch/x86/include/asm/processor.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -982,4 +982,16 @@ bool xen_set_default_idle(void);
982982
void stop_this_cpu(void *dummy);
983983
void df_debug(struct pt_regs *regs, long error_code);
984984
void microcode_check(void);
985+
986+
enum l1tf_mitigations {
987+
L1TF_MITIGATION_OFF,
988+
L1TF_MITIGATION_FLUSH_NOWARN,
989+
L1TF_MITIGATION_FLUSH,
990+
L1TF_MITIGATION_FLUSH_NOSMT,
991+
L1TF_MITIGATION_FULL,
992+
L1TF_MITIGATION_FULL_FORCE
993+
};
994+
995+
extern enum l1tf_mitigations l1tf_mitigation;
996+
985997
#endif /* _ASM_X86_PROCESSOR_H */

arch/x86/kernel/cpu/bugs.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,11 @@ void x86_spec_ctrl_setup_ap(void)
665665
#undef pr_fmt
666666
#define pr_fmt(fmt) "L1TF: " fmt
667667

668+
/* Default mitigation for L1TF-affected CPUs */
669+
enum l1tf_mitigations l1tf_mitigation __ro_after_init = L1TF_MITIGATION_FLUSH;
668670
#if IS_ENABLED(CONFIG_KVM_INTEL)
671+
EXPORT_SYMBOL_GPL(l1tf_mitigation);
672+
669673
enum vmx_l1d_flush_state l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
670674
EXPORT_SYMBOL_GPL(l1tf_vmx_mitigation);
671675
#endif
@@ -677,6 +681,20 @@ static void __init l1tf_select_mitigation(void)
677681
if (!boot_cpu_has_bug(X86_BUG_L1TF))
678682
return;
679683

684+
switch (l1tf_mitigation) {
685+
case L1TF_MITIGATION_OFF:
686+
case L1TF_MITIGATION_FLUSH_NOWARN:
687+
case L1TF_MITIGATION_FLUSH:
688+
break;
689+
case L1TF_MITIGATION_FLUSH_NOSMT:
690+
case L1TF_MITIGATION_FULL:
691+
cpu_smt_disable(false);
692+
break;
693+
case L1TF_MITIGATION_FULL_FORCE:
694+
cpu_smt_disable(true);
695+
break;
696+
}
697+
680698
#if CONFIG_PGTABLE_LEVELS == 2
681699
pr_warn("Kernel not compiled for PAE. No mitigation for L1TF\n");
682700
return;
@@ -695,6 +713,32 @@ static void __init l1tf_select_mitigation(void)
695713

696714
setup_force_cpu_cap(X86_FEATURE_L1TF_PTEINV);
697715
}
716+
717+
static int __init l1tf_cmdline(char *str)
718+
{
719+
if (!boot_cpu_has_bug(X86_BUG_L1TF))
720+
return 0;
721+
722+
if (!str)
723+
return -EINVAL;
724+
725+
if (!strcmp(str, "off"))
726+
l1tf_mitigation = L1TF_MITIGATION_OFF;
727+
else if (!strcmp(str, "flush,nowarn"))
728+
l1tf_mitigation = L1TF_MITIGATION_FLUSH_NOWARN;
729+
else if (!strcmp(str, "flush"))
730+
l1tf_mitigation = L1TF_MITIGATION_FLUSH;
731+
else if (!strcmp(str, "flush,nosmt"))
732+
l1tf_mitigation = L1TF_MITIGATION_FLUSH_NOSMT;
733+
else if (!strcmp(str, "full"))
734+
l1tf_mitigation = L1TF_MITIGATION_FULL;
735+
else if (!strcmp(str, "full,force"))
736+
l1tf_mitigation = L1TF_MITIGATION_FULL_FORCE;
737+
738+
return 0;
739+
}
740+
early_param("l1tf", l1tf_cmdline);
741+
698742
#undef pr_fmt
699743

700744
#ifdef CONFIG_SYSFS

arch/x86/kvm/vmx.c

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,6 @@ static const struct x86_cpu_id vmx_cpu_id[] = {
7171
};
7272
MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id);
7373

74-
static bool __read_mostly nosmt;
75-
module_param(nosmt, bool, S_IRUGO);
76-
7774
static bool __read_mostly enable_vpid = 1;
7875
module_param_named(vpid, enable_vpid, bool, 0444);
7976

@@ -215,15 +212,31 @@ static int vmx_setup_l1d_flush(enum vmx_l1d_flush_state l1tf)
215212
{
216213
struct page *page;
217214

218-
/* If set to 'auto' select 'cond' */
219-
if (l1tf == VMENTER_L1D_FLUSH_AUTO)
220-
l1tf = VMENTER_L1D_FLUSH_COND;
221-
222215
if (!enable_ept) {
223216
l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED;
224217
return 0;
225218
}
226219

220+
/* If set to auto use the default l1tf mitigation method */
221+
if (l1tf == VMENTER_L1D_FLUSH_AUTO) {
222+
switch (l1tf_mitigation) {
223+
case L1TF_MITIGATION_OFF:
224+
l1tf = VMENTER_L1D_FLUSH_NEVER;
225+
break;
226+
case L1TF_MITIGATION_FLUSH_NOWARN:
227+
case L1TF_MITIGATION_FLUSH:
228+
case L1TF_MITIGATION_FLUSH_NOSMT:
229+
l1tf = VMENTER_L1D_FLUSH_COND;
230+
break;
231+
case L1TF_MITIGATION_FULL:
232+
case L1TF_MITIGATION_FULL_FORCE:
233+
l1tf = VMENTER_L1D_FLUSH_ALWAYS;
234+
break;
235+
}
236+
} else if (l1tf_mitigation == L1TF_MITIGATION_FULL_FORCE) {
237+
l1tf = VMENTER_L1D_FLUSH_ALWAYS;
238+
}
239+
227240
if (l1tf != VMENTER_L1D_FLUSH_NEVER && !vmx_l1d_flush_pages &&
228241
!boot_cpu_has(X86_FEATURE_FLUSH_L1D)) {
229242
page = alloc_pages(GFP_KERNEL, L1D_CACHE_ORDER);
@@ -10571,19 +10584,36 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
1057110584
return ERR_PTR(err);
1057210585
}
1057310586

10574-
#define L1TF_MSG "SMT enabled with L1TF CPU bug present. Refer to CVE-2018-3620 for details.\n"
10587+
#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"
10588+
#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"
1057510589

1057610590
static int vmx_vm_init(struct kvm *kvm)
1057710591
{
1057810592
if (!ple_gap)
1057910593
kvm->arch.pause_in_guest = true;
1058010594

10581-
if (boot_cpu_has(X86_BUG_L1TF) && cpu_smt_control == CPU_SMT_ENABLED) {
10582-
if (nosmt) {
10583-
pr_err(L1TF_MSG);
10584-
return -EOPNOTSUPP;
10595+
if (boot_cpu_has(X86_BUG_L1TF) && enable_ept) {
10596+
switch (l1tf_mitigation) {
10597+
case L1TF_MITIGATION_OFF:
10598+
case L1TF_MITIGATION_FLUSH_NOWARN:
10599+
/* 'I explicitly don't care' is set */
10600+
break;
10601+
case L1TF_MITIGATION_FLUSH:
10602+
case L1TF_MITIGATION_FLUSH_NOSMT:
10603+
case L1TF_MITIGATION_FULL:
10604+
/*
10605+
* Warn upon starting the first VM in a potentially
10606+
* insecure environment.
10607+
*/
10608+
if (cpu_smt_control == CPU_SMT_ENABLED)
10609+
pr_warn_once(L1TF_MSG_SMT);
10610+
if (l1tf_vmx_mitigation == VMENTER_L1D_FLUSH_NEVER)
10611+
pr_warn_once(L1TF_MSG_L1D);
10612+
break;
10613+
case L1TF_MITIGATION_FULL_FORCE:
10614+
/* Flush is enforced */
10615+
break;
1058510616
}
10586-
pr_warn(L1TF_MSG);
1058710617
}
1058810618
return 0;
1058910619
}

0 commit comments

Comments
 (0)