On Thursday, 2020-07-16 at 16:52:45 +03, Jarkko Sakkinen wrote:
> From: Sean Christopherson <sean.j.christopher...@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 <jet...@fortanix.com>
> Signed-off-by: Sean Christopherson <sean.j.christopher...@intel.com>
> Co-developed-by: Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>
> Signed-off-by: Jarkko Sakkinen <jarkko.sakki...@linux.intel.com>

Reviewed-by: Darren Kenny <darren.ke...@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

Reply via email to