From 32f4c9ae512c8ec950db35ab7ff5a558728c68cc Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Wed, 10 Mar 2021 22:42:20 +0800 Subject: [PATCH 2583/2944] x86/cpu/intel: Detect SGX support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit to #32051961 commit 224ab3527f89f69ae57dc53555826667ac46a3cc upstream. Kernel support for SGX is ultimately decided by the state of the launch control bits in the feature control MSR (MSR_IA32_FEAT_CTL). If the hardware supports SGX, but neglects to support flexible launch control, the kernel will not enable SGX. Enable SGX at feature control MSR initialization and update the associated X86_FEATURE flags accordingly. Disable X86_FEATURE_SGX (and all derivatives) if the kernel is not able to establish itself as the authority over SGX Launch Control. All checks are performed for each logical CPU (not just boot CPU) in order to verify that MSR_IA32_FEATURE_CONTROL is correctly configured on all CPUs. All SGX code in this series expects the same configuration from all CPUs. This differs from VMX where X86_FEATURE_VMX is intentionally cleared only for the current CPU so that KVM can provide additional information if KVM fails to load like which CPU doesn't support VMX. There’s not much the kernel or an administrator can do to fix the situation, so SGX neglects to convey additional details about these kinds of failures if they occur. Signed-off-by: Sean Christopherson Co-developed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen Signed-off-by: Borislav Petkov Acked-by: Jethro Beekman Link: https://lkml.kernel.org/r/20201112220135.165028-8-jarkko@kernel.org [GuoRui.Yu: Removed VMX related code, only for SGX.] Signed-off-by: GuoRui.Yu Reviewed-by: Jia Zhang --- arch/x86/kernel/cpu/feat_ctl.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c index e143c3f..221f4a9 100644 --- a/arch/x86/kernel/cpu/feat_ctl.c +++ b/arch/x86/kernel/cpu/feat_ctl.c @@ -5,15 +5,32 @@ #include #include +static void clear_sgx_caps(void) +{ + setup_clear_cpu_cap(X86_FEATURE_SGX); + setup_clear_cpu_cap(X86_FEATURE_SGX_LC); +} + void init_ia32_feat_ctl(struct cpuinfo_x86 *c) { + bool enable_sgx; u64 msr; - if (rdmsrl_safe(MSR_IA32_FEATURE_CONTROL, &msr)) + if (rdmsrl_safe(MSR_IA32_FEATURE_CONTROL, &msr)) { + clear_sgx_caps(); return; + } + + /* + * Enable SGX if and only if the kernel supports SGX and Launch Control + * is supported, i.e. disable SGX if the LE hash MSRs can't be written. + */ + enable_sgx = cpu_has(c, X86_FEATURE_SGX) && + cpu_has(c, X86_FEATURE_SGX_LC) && + IS_ENABLED(CONFIG_X86_SGX); if (msr & FEATURE_CONTROL_LOCKED) - return; + goto update_sgx; /* * Ignore whatever value BIOS left in the MSR to avoid enabling random @@ -21,5 +38,16 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) */ msr = FEATURE_CONTROL_LOCKED; + if (enable_sgx) + msr |= FEAT_CTL_SGX_ENABLED | FEAT_CTL_SGX_LC_ENABLED; + wrmsrl(MSR_IA32_FEATURE_CONTROL, msr); + +update_sgx: + if (!(msr & FEAT_CTL_SGX_ENABLED) || + !(msr & FEAT_CTL_SGX_LC_ENABLED) || !enable_sgx) { + if (enable_sgx) + pr_err_once("SGX disabled by BIOS\n"); + clear_sgx_caps(); + } } -- 1.8.3.1