diff options
author | Radim Krčmář <rkrcmar@redhat.com> | 2018-03-01 09:24:25 -0500 |
---|---|---|
committer | Radim Krčmář <rkrcmar@redhat.com> | 2018-03-01 16:32:45 -0500 |
commit | b7e31be385584afe7f073130e8e570d53c95f7fe (patch) | |
tree | f14381b2f2593fbf6b2bae27a67c9a9605bc5a67 | |
parent | 518e7b94817abed94becfe6a44f1ece0d4745afe (diff) |
KVM: x86: fix vcpu initialization with userspace lapic
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>
-rw-r--r-- | arch/x86/kvm/lapic.c | 10 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 3 |
2 files changed, 6 insertions, 7 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index cc5fe7a50dde..391dda8d43b7 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -2002,14 +2002,13 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
2002 | 2002 | ||
2003 | void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) | 2003 | void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) |
2004 | { | 2004 | { |
2005 | struct kvm_lapic *apic; | 2005 | struct kvm_lapic *apic = vcpu->arch.apic; |
2006 | int i; | 2006 | int i; |
2007 | 2007 | ||
2008 | apic_debug("%s\n", __func__); | 2008 | if (!apic) |
2009 | return; | ||
2009 | 2010 | ||
2010 | ASSERT(vcpu); | 2011 | apic_debug("%s\n", __func__); |
2011 | apic = vcpu->arch.apic; | ||
2012 | ASSERT(apic != NULL); | ||
2013 | 2012 | ||
2014 | /* Stop the timer in case it's a reset to an active apic */ | 2013 | /* Stop the timer in case it's a reset to an active apic */ |
2015 | hrtimer_cancel(&apic->lapic_timer.timer); | 2014 | hrtimer_cancel(&apic->lapic_timer.timer); |
@@ -2568,7 +2567,6 @@ void kvm_apic_accept_events(struct kvm_vcpu *vcpu) | |||
2568 | 2567 | ||
2569 | pe = xchg(&apic->pending_events, 0); | 2568 | pe = xchg(&apic->pending_events, 0); |
2570 | if (test_bit(KVM_APIC_INIT, &pe)) { | 2569 | if (test_bit(KVM_APIC_INIT, &pe)) { |
2571 | kvm_lapic_reset(vcpu, true); | ||
2572 | kvm_vcpu_reset(vcpu, true); | 2570 | kvm_vcpu_reset(vcpu, true); |
2573 | if (kvm_vcpu_is_bsp(apic->vcpu)) | 2571 | if (kvm_vcpu_is_bsp(apic->vcpu)) |
2574 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | 2572 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 11649d290b93..18b5ca7a3197 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -8060,7 +8060,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
8060 | kvm_vcpu_mtrr_init(vcpu); | 8060 | kvm_vcpu_mtrr_init(vcpu); |
8061 | vcpu_load(vcpu); | 8061 | vcpu_load(vcpu); |
8062 | kvm_vcpu_reset(vcpu, false); | 8062 | kvm_vcpu_reset(vcpu, false); |
8063 | kvm_lapic_reset(vcpu, false); | ||
8064 | kvm_mmu_setup(vcpu); | 8063 | kvm_mmu_setup(vcpu); |
8065 | vcpu_put(vcpu); | 8064 | vcpu_put(vcpu); |
8066 | return 0; | 8065 | return 0; |
@@ -8103,6 +8102,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
8103 | 8102 | ||
8104 | void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) | 8103 | void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) |
8105 | { | 8104 | { |
8105 | kvm_lapic_reset(vcpu, init_event); | ||
8106 | |||
8106 | vcpu->arch.hflags = 0; | 8107 | vcpu->arch.hflags = 0; |
8107 | 8108 | ||
8108 | vcpu->arch.smi_pending = 0; | 8109 | vcpu->arch.smi_pending = 0; |