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:
Родитель
64d6067057
Коммит
cd7764fe9f
|
@ -2057,8 +2057,19 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
|
||||||
if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
|
if (!kvm_vcpu_has_lapic(vcpu) || !apic->pending_events)
|
||||||
return;
|
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)) {
|
if (test_bit(KVM_APIC_INIT, &pe)) {
|
||||||
kvm_lapic_reset(vcpu, true);
|
kvm_lapic_reset(vcpu, true);
|
||||||
kvm_vcpu_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)) {
|
if (unlikely(vcpu->arch.smi_pending)) {
|
||||||
kvm_make_request(KVM_REQ_SMI, vcpu);
|
kvm_make_request(KVM_REQ_SMI, vcpu);
|
||||||
vcpu->arch.smi_pending = 0;
|
vcpu->arch.smi_pending = 0;
|
||||||
|
} else {
|
||||||
|
/* Process a latched INIT, if any. */
|
||||||
|
kvm_make_request(KVM_REQ_EVENT, vcpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче