Skip to content

Commit 3243b93

Browse files
committed
KVM: VMX: Treat UMIP as emulated if and only if the host doesn't have UMIP
Advertise UMIP as emulated if and only if the host doesn't natively support UMIP, otherwise vmx_umip_emulated() is misleading when the host _does_ support UMIP. Of the four users of vmx_umip_emulated(), two already check for native support, and the logic in vmx_set_cpu_caps() is relevant if and only if UMIP isn't natively supported as UMIP is set in KVM's caps by kvm_set_cpu_caps() when UMIP is present in hardware. That leaves KVM's stuffing of X86_CR4_UMIP into the default cr4_fixed1 value enumerated for nested VMX. In that case, checking for (lack of) host support is actually a bug fix of sorts, as enumerating UMIP support based solely on descriptor table exiting works only because KVM doesn't sanity check MSR_IA32_VMX_CR4_FIXED1. E.g. if a (very theoretical) host supported UMIP in hardware but didn't allow UMIP+VMX, KVM would advertise UMIP but not actually emulate UMIP. Of course, KVM would explode long before it could run a nested VM on said theoretical CPU, as KVM doesn't modify host CR4 when enabling VMX, i.e. would load an "illegal" value into vmcs.HOST_CR4. Reported-by: Robert Hoo <robert.hu@intel.com> Link: https://lore.kernel.org/all/20230310125718.1442088-2-robert.hu@intel.com Link: https://lore.kernel.org/r/20230413231914.1482782-2-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 82dc11b commit 3243b93

3 files changed

Lines changed: 4 additions & 5 deletions

File tree

arch/x86/kvm/vmx/capabilities.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ static inline bool cpu_has_vmx_ept(void)
152152

153153
static inline bool vmx_umip_emulated(void)
154154
{
155-
return vmcs_config.cpu_based_2nd_exec_ctrl &
156-
SECONDARY_EXEC_DESC;
155+
return !boot_cpu_has(X86_FEATURE_UMIP) &&
156+
(vmcs_config.cpu_based_2nd_exec_ctrl & SECONDARY_EXEC_DESC);
157157
}
158158

159159
static inline bool cpu_has_vmx_rdtscp(void)

arch/x86/kvm/vmx/nested.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,8 +2328,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
23282328
* Preset *DT exiting when emulating UMIP, so that vmx_set_cr4()
23292329
* will not have to rewrite the controls just for this bit.
23302330
*/
2331-
if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated() &&
2332-
(vmcs12->guest_cr4 & X86_CR4_UMIP))
2331+
if (vmx_umip_emulated() && (vmcs12->guest_cr4 & X86_CR4_UMIP))
23332332
exec_control |= SECONDARY_EXEC_DESC;
23342333

23352334
if (exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3404,7 +3404,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
34043404
else
34053405
hw_cr4 |= KVM_PMODE_VM_CR4_ALWAYS_ON;
34063406

3407-
if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated()) {
3407+
if (vmx_umip_emulated()) {
34083408
if (cr4 & X86_CR4_UMIP) {
34093409
secondary_exec_controls_setbit(vmx, SECONDARY_EXEC_DESC);
34103410
hw_cr4 &= ~X86_CR4_UMIP;

0 commit comments

Comments
 (0)