]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86: Drop pending_smi vs. INIT_RECEIVED check when setting MP_STATE
authorSean Christopherson <seanjc@google.com>
Thu, 5 Jun 2025 19:50:15 +0000 (12:50 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:07:59 +0000 (13:07 -0700)
Allow userspace to set a vCPU's mp_state to INIT_RECEIVED in conjunction
with a pending SMI, as rejecting that combination could result in KVM
disallowing reflecting the output from KVM_GET_VCPU_EVENTS back into KVM
via KVM_SET_VCPU_EVENTS.

At the time the check was added, smi_pending could only be set in the
context of KVM_RUN, with the vCPU in the RUNNABLE state.  I.e. it was
impossible for KVM to save vCPU state such that userspace could see a
pending SMI for a vCPU in WFS.

That no longer holds true now that KVM processes requested SMIs during
KVM_GET_VCPU_EVENTS, e.g. if a vCPU receives an SMI while in WFS, and
then userspace saves vCPU state.

Note, this may partially re-open the user-triggerable WARN that was mostly
closed by commit 28bf28887976 ("KVM: x86: fix user triggerable warning in
kvm_apic_accept_events()"), but that WARN can already be triggered in
several other ways, e.g. if userspace stuffs VMXON=1 after putting the
vCPU into WFS.  That issue will be addressed in an upcoming commit, in a
more robust fashion (hopefully).

Fixes: 1f7becf1b7e2 ("KVM: x86: get smi pending status correctly")
Link: https://lore.kernel.org/r/20250605195018.539901-2-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/x86.c

index 7227696c75e695d4fecd14787de04624c9d208f3..f183951a8ea8b60842e8b0281d43fd99217a264f 100644 (file)
@@ -11916,10 +11916,9 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
        /*
         * Pending INITs are reported using KVM_SET_VCPU_EVENTS, disallow
         * forcing the guest into INIT/SIPI if those events are supposed to be
-        * blocked.  KVM prioritizes SMI over INIT, so reject INIT/SIPI state
-        * if an SMI is pending as well.
+        * blocked.
         */
-       if ((!kvm_apic_init_sipi_allowed(vcpu) || vcpu->arch.smi_pending) &&
+       if (!kvm_apic_init_sipi_allowed(vcpu) &&
            (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED ||
             mp_state->mp_state == KVM_MP_STATE_INIT_RECEIVED))
                goto out;