diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-04 10:41:21 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-06-04 16:01:51 +0200 |
commit | cd7764fe9f73530b20a0f2310fa753af635fabb3 (patch) | |
tree | 4a82128e03604182b8501d4df46dbd2cee880db8 /arch/x86/kvm/lapic.c | |
parent | 64d6067057d9658acb8675afcfba549abdb7fc16 (diff) | |
download | op-kernel-dev-cd7764fe9f73530b20a0f2310fa753af635fabb3.zip op-kernel-dev-cd7764fe9f73530b20a0f2310fa753af635fabb3.tar.gz |
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>
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index b8e47e2..beeef05 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -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); |