diff mbox series

[v2,1/2] KVM: LAPIC: Disarm LAPIC timer includes pending timer around TSC deadline switch

Message ID 1652236710-36524-1-git-send-email-wanpengli@tencent.com (mailing list archive)
State New, archived
Headers show
Series [v2,1/2] KVM: LAPIC: Disarm LAPIC timer includes pending timer around TSC deadline switch | expand

Commit Message

Wanpeng Li May 11, 2022, 2:38 a.m. UTC
From: Wanpeng Li <wanpengli@tencent.com>

The timer is disarmed when switching between TSC deadline and other modes, 
however, the pending timer is still in-flight, so let's accurately set 
everything to a disarmed state, this patch does it by clearing pending
when canceling the timer.

Fixes: 4427593258 (KVM: x86: thoroughly disarm LAPIC timer around TSC deadline switch)
Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
---
v1 -> v2:
 * clear pending in cancel_apic_timer

 arch/x86/kvm/lapic.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Paolo Bonzini May 11, 2022, 1:53 p.m. UTC | #1
On 5/11/22 04:38, Wanpeng Li wrote:
> 
> Fixes: 4427593258 (KVM: x86: thoroughly disarm LAPIC timer around TSC deadline switch)
> Signed-off-by: Wanpeng Li<wanpengli@tencent.com>
> ---

Please write a testcase for this.

Paolo
Wanpeng Li May 12, 2022, 8:23 a.m. UTC | #2
On Wed, 11 May 2022 at 21:54, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> On 5/11/22 04:38, Wanpeng Li wrote:
> >
> > Fixes: 4427593258 (KVM: x86: thoroughly disarm LAPIC timer around TSC deadline switch)
> > Signed-off-by: Wanpeng Li<wanpengli@tencent.com>
> > ---
>
> Please write a testcase for this.

Something like this, however, it is not easy to catch the pending
timer in this scenario.

diff --git a/x86/apic.c b/x86/apic.c
index 23508ad..108c1c8 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -22,7 +22,7 @@ static void test_lapic_existence(void)
 #define TSC_DEADLINE_TIMER_VECTOR 0xef
 #define BROADCAST_VECTOR 0xcf

-static int tdt_count;
+static int volatile tdt_count;

 static void tsc_deadline_timer_isr(isr_regs_t *regs)
 {
@@ -672,6 +672,18 @@ static void test_apic_change_mode(void)
        /* now tmcct == 0 and tmict != 0 */
        apic_change_mode(APIC_LVT_TIMER_PERIODIC);
        report(!apic_read(APIC_TMCCT), "TMCCT should stay at zero");
+
+       handle_irq(TSC_DEADLINE_TIMER_VECTOR, tsc_deadline_timer_isr);
+       irq_enable();
+
+       apic_write(APIC_LVTT, APIC_LVT_TIMER_ONESHOT |
+               APIC_LVT_TIMER_VECTOR);
+        /* Divider == 1 */
+       apic_write(APIC_TDCR, 0x0000000b);
+
+       apic_write(APIC_TMICT, 0x999999);
+       enable_tsc_deadline_timer();
+       while(tdt_count == 1);
 }

 #define KVM_HC_SEND_IPI 10
Wanpeng Li May 19, 2022, 8:50 a.m. UTC | #3
ping,
On Wed, 11 May 2022 at 10:39, Wanpeng Li <kernellwp@gmail.com> wrote:
>
> From: Wanpeng Li <wanpengli@tencent.com>
>
> The timer is disarmed when switching between TSC deadline and other modes,
> however, the pending timer is still in-flight, so let's accurately set
> everything to a disarmed state, this patch does it by clearing pending
> when canceling the timer.
>
> Fixes: 4427593258 (KVM: x86: thoroughly disarm LAPIC timer around TSC deadline switch)
> Signed-off-by: Wanpeng Li <wanpengli@tencent.com>
> ---
> v1 -> v2:
>  * clear pending in cancel_apic_timer
>
>  arch/x86/kvm/lapic.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 66b0eb0bda94..6268880c8eed 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -1548,6 +1548,7 @@ static void cancel_apic_timer(struct kvm_lapic *apic)
>         if (apic->lapic_timer.hv_timer_in_use)
>                 cancel_hv_timer(apic);
>         preempt_enable();
> +       atomic_set(&apic->lapic_timer.pending, 0);
>  }
>
>  static void apic_update_lvtt(struct kvm_lapic *apic)
> --
> 2.25.1
>
diff mbox series

Patch

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 66b0eb0bda94..6268880c8eed 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1548,6 +1548,7 @@  static void cancel_apic_timer(struct kvm_lapic *apic)
 	if (apic->lapic_timer.hv_timer_in_use)
 		cancel_hv_timer(apic);
 	preempt_enable();
+	atomic_set(&apic->lapic_timer.pending, 0);
 }
 
 static void apic_update_lvtt(struct kvm_lapic *apic)