Skip to content

Commit a487f67

Browse files
committed
KVM: x86: Query X86_FEATURE_MWAIT iff userspace owns the CPUID feature bit
Rework MONITOR/MWAIT emulation to query X86_FEATURE_MWAIT if and only if the MISC_ENABLE_NO_MWAIT quirk is enabled, in which case MWAIT is not a dynamic, KVM-controlled CPUID feature. KVM's funky ABI for that quirk is to emulate MONITOR/MWAIT as nops if userspace sets MWAIT in guest CPUID. For the case where KVM owns the MWAIT feature bit, check MISC_ENABLES itself, i.e. check the actual control, not its reflection in guest CPUID. Avoiding consumption of dynamic CPUID features will allow KVM to defer runtime CPUID updates until kvm_emulate_cpuid(), i.e. until the updates become visible to the guest. Alternatively, KVM could play other games with runtime CPUID updates, e.g. by precisely specifying which feature bits to update, but doing so adds non-trivial complexity and doesn't solve the underlying issue of unnecessary updates causing meaningful overhead for nested virtualization roundtrips. Link: https://lore.kernel.org/r/20241211013302.1347853-5-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 7e9f735 commit a487f67

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

arch/x86/kvm/x86.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2080,10 +2080,20 @@ EXPORT_SYMBOL_GPL(kvm_handle_invalid_op);
20802080

20812081
static int kvm_emulate_monitor_mwait(struct kvm_vcpu *vcpu, const char *insn)
20822082
{
2083-
if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS) &&
2084-
!guest_cpu_cap_has(vcpu, X86_FEATURE_MWAIT))
2083+
bool enabled;
2084+
2085+
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS))
2086+
goto emulate_as_nop;
2087+
2088+
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT))
2089+
enabled = guest_cpu_cap_has(vcpu, X86_FEATURE_MWAIT);
2090+
else
2091+
enabled = vcpu->arch.ia32_misc_enable_msr & MSR_IA32_MISC_ENABLE_MWAIT;
2092+
2093+
if (!enabled)
20852094
return kvm_handle_invalid_op(vcpu);
20862095

2096+
emulate_as_nop:
20872097
pr_warn_once("%s instruction emulated as NOP!\n", insn);
20882098
return kvm_emulate_as_nop(vcpu);
20892099
}

0 commit comments

Comments
 (0)