Skip to content

Commit 7a57c09

Browse files
Sean Christophersonbonzini
authored andcommitted
KVM: VMX: Condition ENCLS-exiting enabling on CPU support for SGX1
Enable ENCLS-exiting (and thus set vmcs.ENCLS_EXITING_BITMAP) only if the CPU supports SGX1. Per Intel's SDM, all ENCLS leafs #UD if SGX1 is not supported[*], i.e. intercepting ENCLS to inject a #UD is unnecessary. Avoiding ENCLS-exiting even when it is reported as supported by the CPU works around a reported issue where SGX is "hard" disabled after an S3 suspend/resume cycle, i.e. CPUID.0x7.SGX=0 and the VMCS field/control are enumerated as unsupported. While the root cause of the S3 issue is unknown, it's definitely _not_ a KVM (or kernel) bug, i.e. this is a workaround for what is most likely a hardware or firmware issue. As a bonus side effect, KVM saves a VMWRITE when first preparing vmcs01 and vmcs02. Note, SGX must be disabled in BIOS to take advantage of this workaround [*] The additional ENCLS CPUID check on SGX1 exists so that SGX can be globally "soft" disabled post-reset, e.g. if #MC bits in MCi_CTL are cleared. Soft disabled meaning disabling SGX without clearing the primary CPUID bit (in leaf 0x7) and without poking into non-SGX CPU paths, e.g. for the VMCS controls. Fixes: 0b665d3 ("KVM: vmx: Inject #UD for SGX ENCLS instruction in guest") Reported-by: Toni Spets <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent a754acc commit 7a57c09

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

arch/x86/kvm/vmx/vmx.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,6 +2338,17 @@ static void hardware_disable(void)
23382338
kvm_cpu_vmxoff();
23392339
}
23402340

2341+
/*
2342+
* There is no X86_FEATURE for SGX yet, but anyway we need to query CPUID
2343+
* directly instead of going through cpu_has(), to ensure KVM is trapping
2344+
* ENCLS whenever it's supported in hardware. It does not matter whether
2345+
* the host OS supports or has enabled SGX.
2346+
*/
2347+
static bool cpu_has_sgx(void)
2348+
{
2349+
return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0));
2350+
}
2351+
23412352
static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt,
23422353
u32 msr, u32 *result)
23432354
{
@@ -2418,8 +2429,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf,
24182429
SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE |
24192430
SECONDARY_EXEC_PT_USE_GPA |
24202431
SECONDARY_EXEC_PT_CONCEAL_VMX |
2421-
SECONDARY_EXEC_ENABLE_VMFUNC |
2422-
SECONDARY_EXEC_ENCLS_EXITING;
2432+
SECONDARY_EXEC_ENABLE_VMFUNC;
2433+
if (cpu_has_sgx())
2434+
opt2 |= SECONDARY_EXEC_ENCLS_EXITING;
24232435
if (adjust_vmx_controls(min2, opt2,
24242436
MSR_IA32_VMX_PROCBASED_CTLS2,
24252437
&_cpu_based_2nd_exec_control) < 0)

0 commit comments

Comments
 (0)