KVM: x86: latch INITs while in system management mode
Do not process INITs immediately while in system management mode, keep it instead in apic->pending_events. Tell userspace if an INIT is pending when they issue GET_VCPU_EVENTS, and similarly handle the new field in SET_VCPU_EVENTS. Note that the same treatment should be done while in VMX non-root mode. Reviewed-by: Radim Krčmář <rkrcmar@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
64d6067057
commit
cd7764fe9f
|
@ -2057,8 +2057,19 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
|
|||
if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
|
||||
return;
|
||||
|
||||
pe = xchg(&apic->pending_events, 0);
|
||||
/*
|
||||
* INITs are latched while in SMM. Because an SMM CPU cannot
|
||||
* be in KVM_MP_STATE_INIT_RECEIVED state, just eat SIPIs
|
||||
* and delay processing of INIT until the next RSM.
|
||||
*/
|
||||
if (is_smm(vcpu)) {
|
||||
WARN_ON_ONCE(vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED);
|
||||
if (test_bit(KVM_APIC_SIPI, &apic->pending_events))
|
||||
clear_bit(KVM_APIC_SIPI, &apic->pending_events);
|
||||
return;
|
||||
}
|
||||
|
||||
pe = xchg(&apic->pending_events, 0);
|
||||
if (test_bit(KVM_APIC_INIT, &pe)) {
|
||||
kvm_lapic_reset(vcpu, true);
|
||||
kvm_vcpu_reset(vcpu, true);
|
||||
|
|
|
@ -5482,6 +5482,9 @@ static void kvm_smm_changed(struct kvm_vcpu *vcpu)
|
|||
if (unlikely(vcpu->arch.smi_pending)) {
|
||||
kvm_make_request(KVM_REQ_SMI, vcpu);
|
||||
vcpu->arch.smi_pending = 0;
|
||||
} else {
|
||||
/* Process a latched INIT, if any. */
|
||||
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue