KVM: LAPIC: Also cancel preemption timer when disarm LAPIC timer
authorWanpeng Li <wanpengli@tencent.com>
Tue, 24 Mar 2020 06:32:10 +0000 (14:32 +0800)
committerPaolo Bonzini <pbonzini@redhat.com>
Tue, 24 Mar 2020 11:25:20 +0000 (07:25 -0400)
The timer is disarmed when switching between TSC deadline and other modes,
we should set everything to disarmed state, however, LAPIC timer can be
emulated by preemption timer, it still works if vmx->hv_deadline_timer is
not -1. This patch also cancels preemption timer when disarm LAPIC timer.

Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
Message-Id: <1585031530-19823-1-git-send-email-wanpengli@tencent.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/lapic.c

index 929511e01960e833d6b320bc784e92de40269314..7356a56e6282f192e5e8c8630ce1a5b2065bdcb5 100644 (file)
@@ -1445,6 +1445,8 @@ static void limit_periodic_timer_frequency(struct kvm_lapic *apic)
        }
 }
 
+static void cancel_hv_timer(struct kvm_lapic *apic);
+
 static void apic_update_lvtt(struct kvm_lapic *apic)
 {
        u32 timer_mode = kvm_lapic_get_reg(apic, APIC_LVTT) &
@@ -1454,6 +1456,10 @@ static void apic_update_lvtt(struct kvm_lapic *apic)
                if (apic_lvtt_tscdeadline(apic) != (timer_mode ==
                                APIC_LVT_TIMER_TSCDEADLINE)) {
                        hrtimer_cancel(&apic->lapic_timer.timer);
+                       preempt_disable();
+                       if (apic->lapic_timer.hv_timer_in_use)
+                               cancel_hv_timer(apic);
+                       preempt_enable();
                        kvm_lapic_set_reg(apic, APIC_TMICT, 0);
                        apic->lapic_timer.period = 0;
                        apic->lapic_timer.tscdeadline = 0;