KVM: x86: fix vcpu initialization with userspace lapic
authorRadim Krčmář <rkrcmar@redhat.com>
Thu, 1 Mar 2018 14:24:25 +0000 (15:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Mar 2018 06:41:25 +0000 (22:41 -0800)
commit b7e31be385584afe7f073130e8e570d53c95f7fe upstream.

Moving the code around broke this rare configuration.
Use this opportunity to finally call lapic reset from vcpu reset.

Reported-by: syzbot+fb7a33a4b6c35007a72b@syzkaller.appspotmail.com
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Fixes: 0b2e9904c159 ("KVM: x86: move LAPIC initialization after VMCS creation")
Cc: stable@vger.kernel.org
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/lapic.c
arch/x86/kvm/x86.c

index 5f59a567f2469bebe58013a7aeaaa5cfcf38e464..8cfdb6484fd05fa5e58bd46afe6dca2450c7b07c 100644 (file)
@@ -1944,14 +1944,13 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
 
 void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
 {
-       struct kvm_lapic *apic;
+       struct kvm_lapic *apic = vcpu->arch.apic;
        int i;
 
-       apic_debug("%s\n", __func__);
+       if (!apic)
+               return;
 
-       ASSERT(vcpu);
-       apic = vcpu->arch.apic;
-       ASSERT(apic != NULL);
+       apic_debug("%s\n", __func__);
 
        /* Stop the timer in case it's a reset to an active apic */
        hrtimer_cancel(&apic->lapic_timer.timer);
@@ -2510,7 +2509,6 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu)
 
        pe = xchg(&apic->pending_events, 0);
        if (test_bit(KVM_APIC_INIT, &pe)) {
-               kvm_lapic_reset(vcpu, true);
                kvm_vcpu_reset(vcpu, true);
                if (kvm_vcpu_is_bsp(apic->vcpu))
                        vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
index 64d2e692aeb73e467f7414d01609204928d699c8..7ab26f88ec0553edb050bcab24395c89681f2353 100644 (file)
@@ -7779,7 +7779,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
        if (r)
                return r;
        kvm_vcpu_reset(vcpu, false);
-       kvm_lapic_reset(vcpu, false);
        kvm_mmu_setup(vcpu);
        vcpu_put(vcpu);
        return r;
@@ -7822,6 +7821,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 
 void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
 {
+       kvm_lapic_reset(vcpu, init_event);
+
        vcpu->arch.hflags = 0;
 
        vcpu->arch.smi_pending = 0;