Commit 1db2a6e1 authored by Sean Christopherson's avatar Sean Christopherson Committed by Borislav Petkov

x86/intel: Initialize IA32_FEAT_CTL MSR at boot

Opportunistically initialize IA32_FEAT_CTL to enable VMX when the MSR is
left unlocked by BIOS.  Configuring feature control at boot time paves
the way for similar enabling of other features, e.g. Software Guard
Extensions (SGX).

Temporarily leave equivalent KVM code in place in order to avoid
introducing a regression on Centaur and Zhaoxin CPUs, e.g. removing
KVM's code would leave the MSR unlocked on those CPUs and would break
existing functionality if people are loading kvm_intel on Centaur and/or
Zhaoxin.  Defer enablement of the boot-time configuration on Centaur and
Zhaoxin to future patches to aid bisection.

Note, Local Machine Check Exceptions (LMCE) are also supported by the
kernel and enabled via feature control, but the kernel currently uses
LMCE if and only if the feature is explicitly enabled by BIOS.  Keep
the current behavior to avoid introducing bugs, future patches can opt
in to opportunistic enabling if it's deemed desirable to do so.

Always lock IA32_FEAT_CTL if it exists, even if the CPU doesn't support
VMX, so that other existing and future kernel code that queries the MSR
can assume it's locked.

Start from a clean slate when constructing the value to write to
IA32_FEAT_CTL, i.e. ignore whatever value BIOS left in the MSR so as not
to enable random features or fault on the WRMSR.
Suggested-by: default avatarBorislav Petkov <bp@suse.de>
Signed-off-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20191221044513.21680-5-sean.j.christopherson@intel.com
parent f6505c88
...@@ -387,6 +387,10 @@ config X86_DEBUGCTLMSR ...@@ -387,6 +387,10 @@ config X86_DEBUGCTLMSR
def_bool y def_bool y
depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486SX || M486) && !UML depends on !(MK6 || MWINCHIPC6 || MWINCHIP3D || MCYRIXIII || M586MMX || M586TSC || M586 || M486SX || M486) && !UML
config IA32_FEAT_CTL
def_bool y
depends on CPU_SUP_INTEL
menuconfig PROCESSOR_SELECT menuconfig PROCESSOR_SELECT
bool "Supported processor vendors" if EXPERT bool "Supported processor vendors" if EXPERT
---help--- ---help---
......
...@@ -29,6 +29,7 @@ obj-y += umwait.o ...@@ -29,6 +29,7 @@ obj-y += umwait.o
obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
obj-$(CONFIG_IA32_FEAT_CTL) += feat_ctl.o
ifdef CONFIG_CPU_SUP_INTEL ifdef CONFIG_CPU_SUP_INTEL
obj-y += intel.o intel_pconfig.o tsx.o obj-y += intel.o intel_pconfig.o tsx.o
obj-$(CONFIG_PM) += intel_epb.o obj-$(CONFIG_PM) += intel_epb.o
......
...@@ -80,4 +80,8 @@ extern void x86_spec_ctrl_setup_ap(void); ...@@ -80,4 +80,8 @@ extern void x86_spec_ctrl_setup_ap(void);
extern u64 x86_read_arch_cap_msr(void); extern u64 x86_read_arch_cap_msr(void);
#ifdef CONFIG_IA32_FEAT_CTL
void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
#endif
#endif /* ARCH_X86_CPU_H */ #endif /* ARCH_X86_CPU_H */
// SPDX-License-Identifier: GPL-2.0
#include <linux/tboot.h>
#include <asm/cpufeature.h>
#include <asm/msr-index.h>
#include <asm/processor.h>
void init_ia32_feat_ctl(struct cpuinfo_x86 *c)
{
u64 msr;
if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr))
return;
if (msr & FEAT_CTL_LOCKED)
return;
/*
* Ignore whatever value BIOS left in the MSR to avoid enabling random
* features or faulting on the WRMSR.
*/
msr = FEAT_CTL_LOCKED;
/*
* Enable VMX if and only if the kernel may do VMXON at some point,
* i.e. KVM is enabled, to avoid unnecessarily adding an attack vector
* for the kernel, e.g. using VMX to hide malicious code.
*/
if (cpu_has(c, X86_FEATURE_VMX) && IS_ENABLED(CONFIG_KVM_INTEL)) {
msr |= FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX;
if (tboot_enabled())
msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX;
}
wrmsrl(MSR_IA32_FEAT_CTL, msr);
}
...@@ -755,6 +755,8 @@ static void init_intel(struct cpuinfo_x86 *c) ...@@ -755,6 +755,8 @@ static void init_intel(struct cpuinfo_x86 *c)
/* Work around errata */ /* Work around errata */
srat_detect_node(c); srat_detect_node(c);
init_ia32_feat_ctl(c);
if (cpu_has(c, X86_FEATURE_VMX)) if (cpu_has(c, X86_FEATURE_VMX))
detect_vmx_virtcap(c); detect_vmx_virtcap(c);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment