Message ID | a6c0b0d2632a6c603e68d9bdc81f564290ff04ad.1610935432.git.kai.huang@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM SGX virtualization support | expand |
On 1/17/21 7:27 PM, Kai Huang wrote: > - enable_sgx = cpu_has(c, X86_FEATURE_SGX) && > - cpu_has(c, X86_FEATURE_SGX_LC) && > - IS_ENABLED(CONFIG_X86_SGX); > + enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX) && > + cpu_has(c, X86_FEATURE_SGX1) && > + IS_ENABLED(CONFIG_X86_SGX) && > + cpu_has(c, X86_FEATURE_SGX_LC); > + enable_sgx_virt = cpu_has(c, X86_FEATURE_SGX) && > + cpu_has(c, X86_FEATURE_SGX1) && > + IS_ENABLED(CONFIG_X86_SGX) && > + IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) && > + enable_vmx; Would it be too much to ask that the SGX/SGX1 checks not be duplicated? Perhaps: enable_sgx_any = cpu_feature_enabled(CONFIG_X86_SGX) && cpu_feature_enabled(CONFIG_X86_SGX1); enable_sgx_driver = enable_sgx_any && cpu_has(c, X86_FEATURE_SGX_LC); enable_sgx_virt = enable_sgx_any && enable_vmx && IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just CONFIG_X86_SGX_VIRT?
On Wed, Jan 20, 2021, Dave Hansen wrote: > BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just > CONFIG_X86_SGX_VIRT? Mmm, bacon. I used the full "virtualization" to avoid any possible confusion with virtual memory. The existing sgx_get_epc_virt_addr() in particular gave me pause. I agree it's long and not consistent since other code in this series uses "virt". My thinking was that most shortand versions, e.g. virt_epc, would be used only in contexts that are already fairly obvious to be KVM/virtualization related, whereas the porcine Kconfig would help establish that context.
On 1/20/21 2:36 PM, Sean Christopherson wrote: > On Wed, Jan 20, 2021, Dave Hansen wrote: >> BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just >> CONFIG_X86_SGX_VIRT? > Mmm, bacon. I used the full "virtualization" to avoid any possible confusion > with virtual memory. The existing sgx_get_epc_virt_addr() in particular gave me > pause. > > I agree it's long and not consistent since other code in this series uses "virt". > My thinking was that most shortand versions, e.g. virt_epc, would be used only > in contexts that are already fairly obvious to be KVM/virtualization related, > whereas the porcine Kconfig would help establish that context. Not a big deal either way. I agree that "virt" can be confusing. Considering that: +config X86_SGX_VIRTUALIZATION + depends on ... KVM_INTEL Calling it X86_SGX_KVM doesn't seem horrible either.
On Wed, 20 Jan 2021 15:27:27 -0800 Dave Hansen wrote: > On 1/20/21 2:36 PM, Sean Christopherson wrote: > > On Wed, Jan 20, 2021, Dave Hansen wrote: > >> BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just > >> CONFIG_X86_SGX_VIRT? > > Mmm, bacon. I used the full "virtualization" to avoid any possible confusion > > with virtual memory. The existing sgx_get_epc_virt_addr() in particular gave me > > pause. > > > > I agree it's long and not consistent since other code in this series uses "virt". > > My thinking was that most shortand versions, e.g. virt_epc, would be used only > > in contexts that are already fairly obvious to be KVM/virtualization related, > > whereas the porcine Kconfig would help establish that context. > > Not a big deal either way. I agree that "virt" can be confusing. > > Considering that: > > +config X86_SGX_VIRTUALIZATION > + depends on ... KVM_INTEL It is already in patch 3: Introduce virtual EPC for use by KVM guests: +config X86_SGX_VIRTUALIZATION + bool "Software Guard eXtensions (SGX) Virtualization" + depends on X86_SGX && KVM_INTEL > > Calling it X86_SGX_KVM doesn't seem horrible either.
On Wed, 20 Jan 2021 13:02:15 -0800 Dave Hansen wrote: > On 1/17/21 7:27 PM, Kai Huang wrote: > > - enable_sgx = cpu_has(c, X86_FEATURE_SGX) && > > - cpu_has(c, X86_FEATURE_SGX_LC) && > > - IS_ENABLED(CONFIG_X86_SGX); > > + enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX) && > > + cpu_has(c, X86_FEATURE_SGX1) && > > + IS_ENABLED(CONFIG_X86_SGX) && > > + cpu_has(c, X86_FEATURE_SGX_LC); > > + enable_sgx_virt = cpu_has(c, X86_FEATURE_SGX) && > > + cpu_has(c, X86_FEATURE_SGX1) && > > + IS_ENABLED(CONFIG_X86_SGX) && > > + IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) && > > + enable_vmx; > > Would it be too much to ask that the SGX/SGX1 checks not be duplicated? > Perhaps: > > enable_sgx_any = cpu_feature_enabled(CONFIG_X86_SGX) && > cpu_feature_enabled(CONFIG_X86_SGX1); > > enable_sgx_driver = enable_sgx_any && > cpu_has(c, X86_FEATURE_SGX_LC); > > enable_sgx_virt = enable_sgx_any && > enable_vmx && > IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) > I am happy to do it. Thanks.
On 1/20/21 3:48 PM, Kai Huang wrote: >> Not a big deal either way. I agree that "virt" can be confusing. >> >> Considering that: >> >> +config X86_SGX_VIRTUALIZATION >> + depends on ... KVM_INTEL > It is already in patch 3: Introduce virtual EPC for use by KVM guests: > > +config X86_SGX_VIRTUALIZATION > + bool "Software Guard eXtensions (SGX) Virtualization" > + depends on X86_SGX && KVM_INTEL Right, I'm suggesting that patch 3 should call it: X86_SGX_KVM instead of: X86_SGX_VIRTUALIZATION
On Wed, Jan 20, 2021 at 01:02:15PM -0800, Dave Hansen wrote: > On 1/17/21 7:27 PM, Kai Huang wrote: > > - enable_sgx = cpu_has(c, X86_FEATURE_SGX) && > > - cpu_has(c, X86_FEATURE_SGX_LC) && > > - IS_ENABLED(CONFIG_X86_SGX); > > + enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX) && > > + cpu_has(c, X86_FEATURE_SGX1) && > > + IS_ENABLED(CONFIG_X86_SGX) && > > + cpu_has(c, X86_FEATURE_SGX_LC); > > + enable_sgx_virt = cpu_has(c, X86_FEATURE_SGX) && > > + cpu_has(c, X86_FEATURE_SGX1) && > > + IS_ENABLED(CONFIG_X86_SGX) && > > + IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) && > > + enable_vmx; > > Would it be too much to ask that the SGX/SGX1 checks not be duplicated? > Perhaps: > > enable_sgx_any = cpu_feature_enabled(CONFIG_X86_SGX) && > cpu_feature_enabled(CONFIG_X86_SGX1); > > enable_sgx_driver = enable_sgx_any && > cpu_has(c, X86_FEATURE_SGX_LC); > > enable_sgx_virt = enable_sgx_any && > enable_vmx && > IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) > > BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just > CONFIG_X86_SGX_VIRT? If my /dev/sgx_vepc naming gets acceptance, then IMHO the best name ought to be CONFIG_X86_VEPC. /Jarkko
On Wed, Jan 20, 2021 at 03:27:27PM -0800, Dave Hansen wrote: > On 1/20/21 2:36 PM, Sean Christopherson wrote: > > On Wed, Jan 20, 2021, Dave Hansen wrote: > >> BTW, CONFIG_X86_SGX_VIRTUALIZATION is a pretty porky name. Maybe just > >> CONFIG_X86_SGX_VIRT? > > Mmm, bacon. I used the full "virtualization" to avoid any possible confusion > > with virtual memory. The existing sgx_get_epc_virt_addr() in particular gave me > > pause. > > > > I agree it's long and not consistent since other code in this series uses "virt". > > My thinking was that most shortand versions, e.g. virt_epc, would be used only > > in contexts that are already fairly obvious to be KVM/virtualization related, > > whereas the porcine Kconfig would help establish that context. > > Not a big deal either way. I agree that "virt" can be confusing. > > Considering that: > > +config X86_SGX_VIRTUALIZATION > + depends on ... KVM_INTEL > > Calling it X86_SGX_KVM doesn't seem horrible either. This is something that I could cope just as well as with my proposal as this is KVM tied feature. /Jarkko
On Wed, 20 Jan 2021 15:51:44 -0800 Dave Hansen wrote: > On 1/20/21 3:48 PM, Kai Huang wrote: > >> Not a big deal either way. I agree that "virt" can be confusing. > >> > >> Considering that: > >> > >> +config X86_SGX_VIRTUALIZATION > >> + depends on ... KVM_INTEL > > It is already in patch 3: Introduce virtual EPC for use by KVM guests: > > > > +config X86_SGX_VIRTUALIZATION > > + bool "Software Guard eXtensions (SGX) Virtualization" > > + depends on X86_SGX && KVM_INTEL > > Right, I'm suggesting that patch 3 should call it: > > X86_SGX_KVM > > instead of: > > X86_SGX_VIRTUALIZATION In case we want to change to X86_SGX_KVM, is it more reasonable to put it to arch/x86/kvm/Kconfig (maybe change to X86_KVM_SGX)? Jarkko also mentioned X86_SGX_VEPC, in which case still putting it to arch/x86/Kconfig looks a better fit. Sean, Paolo, Do you have comment here?
On Thu, Jan 21, 2021 at 02:53:23PM +1300, Kai Huang wrote: > On Wed, 20 Jan 2021 15:51:44 -0800 Dave Hansen wrote: > > On 1/20/21 3:48 PM, Kai Huang wrote: > > >> Not a big deal either way. I agree that "virt" can be confusing. > > >> > > >> Considering that: > > >> > > >> +config X86_SGX_VIRTUALIZATION > > >> + depends on ... KVM_INTEL > > > It is already in patch 3: Introduce virtual EPC for use by KVM guests: > > > > > > +config X86_SGX_VIRTUALIZATION > > > + bool "Software Guard eXtensions (SGX) Virtualization" > > > + depends on X86_SGX && KVM_INTEL > > > > Right, I'm suggesting that patch 3 should call it: > > > > X86_SGX_KVM > > > > instead of: > > > > X86_SGX_VIRTUALIZATION > > In case we want to change to X86_SGX_KVM, is it more reasonable to put it to > arch/x86/kvm/Kconfig (maybe change to X86_KVM_SGX)? > > Jarkko also mentioned X86_SGX_VEPC, in which case still putting it to > arch/x86/Kconfig looks a better fit. I disagree with myself on that now :-) I think the other suggestions are better. I'm only pursuing 'vepc' for the device name because it follows the pattern used in the other devices. > > Sean, Paolo, > > Do you have comment here? /Jarkko
diff --git a/arch/x86/kernel/cpu/feat_ctl.c b/arch/x86/kernel/cpu/feat_ctl.c index 7937a315f8cf..7bd8c57c62fa 100644 --- a/arch/x86/kernel/cpu/feat_ctl.c +++ b/arch/x86/kernel/cpu/feat_ctl.c @@ -98,6 +98,11 @@ static void clear_sgx_caps(void) setup_clear_cpu_cap(X86_FEATURE_SGX); } +static void clear_sgx_lc(void) +{ + setup_clear_cpu_cap(X86_FEATURE_SGX_LC); +} + static int __init nosgx(char *str) { clear_sgx_caps(); @@ -110,7 +115,7 @@ early_param("nosgx", nosgx); void init_ia32_feat_ctl(struct cpuinfo_x86 *c) { bool tboot = tboot_enabled(); - bool enable_sgx; + bool enable_vmx, enable_sgx_virt, enable_sgx_driver; u64 msr; if (rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr)) { @@ -119,13 +124,24 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) return; } + enable_vmx = cpu_has(c, X86_FEATURE_VMX) && + IS_ENABLED(CONFIG_KVM_INTEL); + /* - * 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 if and only if the kernel supports SGX. Require Launch + * Control support if SGX virtualization is *not* supported, i.e. + * disable SGX if the LE hash MSRs can't be written and SGX can't be + * exposed to a KVM guest (which might support non-LC configurations). */ - enable_sgx = cpu_has(c, X86_FEATURE_SGX) && - cpu_has(c, X86_FEATURE_SGX_LC) && - IS_ENABLED(CONFIG_X86_SGX); + enable_sgx_driver = cpu_has(c, X86_FEATURE_SGX) && + cpu_has(c, X86_FEATURE_SGX1) && + IS_ENABLED(CONFIG_X86_SGX) && + cpu_has(c, X86_FEATURE_SGX_LC); + enable_sgx_virt = cpu_has(c, X86_FEATURE_SGX) && + cpu_has(c, X86_FEATURE_SGX1) && + IS_ENABLED(CONFIG_X86_SGX) && + IS_ENABLED(CONFIG_X86_SGX_VIRTUALIZATION) && + enable_vmx; if (msr & FEAT_CTL_LOCKED) goto update_caps; @@ -141,15 +157,18 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) * 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)) { + if (enable_vmx) { msr |= FEAT_CTL_VMX_ENABLED_OUTSIDE_SMX; if (tboot) msr |= FEAT_CTL_VMX_ENABLED_INSIDE_SMX; } - if (enable_sgx) - msr |= FEAT_CTL_SGX_ENABLED | FEAT_CTL_SGX_LC_ENABLED; + if (enable_sgx_driver || enable_sgx_virt) { + msr |= FEAT_CTL_SGX_ENABLED; + if (enable_sgx_driver) + msr |= FEAT_CTL_SGX_LC_ENABLED; + } wrmsrl(MSR_IA32_FEAT_CTL, msr); @@ -172,10 +191,29 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c) } 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"); + if (!(msr & FEAT_CTL_SGX_ENABLED)) { + if (enable_sgx_driver || enable_sgx_virt) + pr_err_once("SGX disabled by BIOS.\n"); clear_sgx_caps(); + return; + } + + /* + * VMX feature bit may be cleared due to being disabled in BIOS, + * in which case SGX virtualization cannot be supported either. + */ + if (!cpu_has(c, X86_FEATURE_VMX) && enable_sgx_virt) { + pr_err_once("SGX virtualization disabled due to lack of VMX.\n"); + enable_sgx_virt = 0; + } + + if (!(msr & FEAT_CTL_SGX_LC_ENABLED) && enable_sgx_driver) { + if (!enable_sgx_virt) { + pr_err_once("SGX Launch Control is locked. Disable SGX.\n"); + clear_sgx_caps(); + } else { + pr_err_once("SGX Launch Control is locked. Support SGX virtualization only.\n"); + clear_sgx_lc(); + } } }