Message ID | 20200716135303.276442-7-jarkko.sakkinen@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Intel SGX foundations | expand |
On Thursday, 2020-07-16 at 16:52:45 +03, Jarkko Sakkinen wrote: > From: Sean Christopherson <sean.j.christopherson@intel.com> > > Configure SGX as part of feature control MSR initialization and update > the associated X86_FEATURE flags accordingly. Because the kernel will > require the LE hash MSRs to be writable when running native enclaves, > disable X86_FEATURE_SGX (and all derivatives) if SGX Launch Control is > not (or cannot) be fully enabled via feature control MSR. > > The check is done for every CPU, not just BSP, in order to verify that > MSR_IA32_FEATURE_CONTROL is correctly configured on all CPUs. The other > parts of the kernel, like the enclave driver, expect the same > configuration from all CPUs. > > Note, unlike VMX, clear the X86_FEATURE_SGX* flags for all CPUs if any > CPU lacks SGX support as the kernel expects SGX to be available on all > CPUs. X86_FEATURE_VMX is intentionally cleared only for the current CPU > so that KVM can provide additional information if KVM fails to load, > e.g. print which CPU doesn't support VMX. KVM/VMX requires additional > per-CPU enabling, e.g. to set CR4.VMXE and do VMXON, and so already has > the necessary infrastructure to do per-CPU checks. SGX on the other > hand doesn't require additional enabling, so clearing the feature flags > on all CPUs means the SGX subsystem doesn't need to manually do support > checks on a per-CPU basis. > > Acked-by: Jethro Beekman <jethro@fortanix.com> > Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> > Co-developed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> > --- > arch/x86/kernel/cpu/feat_ctl.c | 32 +++++++++++++++++++++++++++++++- > 1 file changed, 31 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c > index 29a3bedabd06..c3afcd2e4342 100644 > --- a/arch/x86/kernel/cpu/feat_ctl.c > +++ b/arch/x86/kernel/cpu/feat_ctl.c > @@ -93,16 +93,35 @@ static void init_vmx_capabilities(struct cpuinfo_x86 *c) > } > #endif /* CONFIG_X86_VMX_FEATURE_NAMES */ > > +static void clear_sgx_caps(void) > +{ > + setup_clear_cpu_cap(X86_FEATURE_SGX); > + setup_clear_cpu_cap(X86_FEATURE_SGX_LC); > + setup_clear_cpu_cap(X86_FEATURE_SGX1); > + setup_clear_cpu_cap(X86_FEATURE_SGX2); > +} > + > void init_ia32_feat_ctl(struct cpuinfo_x86 *c) > { > bool tboot = tboot_enabled(); > + bool enable_sgx; > u64 msr; > > if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr)) { > clear_cpu_cap(c, X86_FEATURE_VMX); > + 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_SGX1) && > + cpu_has(c, X86_FEATURE_SGX_LC) && > + IS_ENABLED(CONFIG_INTEL_SGX); > + > if (msr & FEAT_CTL_LOCKED) > goto update_caps; > > @@ -124,13 +143,16 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) > msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX; > } > > + if (enable_sgx) > + msr |= FEAT_CTL_SGX_ENABLED | FEAT_CTL_SGX_LC_ENABLED; > + > wrmsrl(MSR_IA32_FEAT_CTL, msr); > > update_caps: > set_cpu_cap(c, X86_FEATURE_MSR_IA32_FEAT_CTL); > > if (!cpu_has(c, X86_FEATURE_VMX)) > - return; > + goto update_sgx; > > if ( (tboot && !(msr & FEAT_CTL_VMX_ENABLED_INSIDE_SMX)) || > (!tboot && !(msr & FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) { > @@ -143,4 +165,12 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) > init_vmx_capabilities(c); > #endif > } > + > +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(); > + } > } > -- > 2.25.1
diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c index 29a3bedabd06..c3afcd2e4342 100644 --- a/arch/x86/kernel/cpu/feat_ctl.c +++ b/arch/x86/kernel/cpu/feat_ctl.c @@ -93,16 +93,35 @@ static void init_vmx_capabilities(struct cpuinfo_x86 *c) } #endif /* CONFIG_X86_VMX_FEATURE_NAMES */ +static void clear_sgx_caps(void) +{ + setup_clear_cpu_cap(X86_FEATURE_SGX); + setup_clear_cpu_cap(X86_FEATURE_SGX_LC); + setup_clear_cpu_cap(X86_FEATURE_SGX1); + setup_clear_cpu_cap(X86_FEATURE_SGX2); +} + void init_ia32_feat_ctl(struct cpuinfo_x86 *c) { bool tboot = tboot_enabled(); + bool enable_sgx; u64 msr; if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr)) { clear_cpu_cap(c, X86_FEATURE_VMX); + 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_SGX1) && + cpu_has(c, X86_FEATURE_SGX_LC) && + IS_ENABLED(CONFIG_INTEL_SGX); + if (msr & FEAT_CTL_LOCKED) goto update_caps; @@ -124,13 +143,16 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX; } + if (enable_sgx) + msr |= FEAT_CTL_SGX_ENABLED | FEAT_CTL_SGX_LC_ENABLED; + wrmsrl(MSR_IA32_FEAT_CTL, msr); update_caps: set_cpu_cap(c, X86_FEATURE_MSR_IA32_FEAT_CTL); if (!cpu_has(c, X86_FEATURE_VMX)) - return; + goto update_sgx; if ( (tboot && !(msr & FEAT_CTL_VMX_ENABLED_INSIDE_SMX)) || (!tboot && !(msr & FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX))) { @@ -143,4 +165,12 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) init_vmx_capabilities(c); #endif } + +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(); + } }