[PATCH 3/3] LoongArch: KVM: Move unconditional delay in timer clear scenery

From: Bibo Mao

Date: Tue Apr 14 2026 - 03:28:30 EST


When timer interrupt arrives in guest kernel, guest kernel clears
the timer interrupt and program timer with the next incoming event.

During this stage, timer tick is -1 and timer interrupt status is
disabled in ESTAT register. KVM hypervisor need write zero with timer
tick register and wait timer interrupt injection from HW side, and
then clear timer interrupt.

So there is 2 cycle delay in KVM hypervisor to emulate such scenery,
and the delay is unnecessary if there is no need to clear timer
interrupt.

Here move 2 timer cycle delay in timer clear scenery and add timer
estat checking after delay, and set max timer expire value if timer
interrupt does not arrive still.

Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx>
---
arch/loongarch/kvm/timer.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/loongarch/kvm/timer.c b/arch/loongarch/kvm/timer.c
index 29c2aaba63c3..c83f72a7c746 100644
--- a/arch/loongarch/kvm/timer.c
+++ b/arch/loongarch/kvm/timer.c
@@ -96,15 +96,27 @@ void kvm_restore_timer(struct kvm_vcpu *vcpu)
* and set CSR TVAL with -1
*/
write_gcsr_timertick(0);
- __delay(2); /* Wait cycles until timer interrupt injected */

/*
* Writing CSR_TINTCLR_TI to LOONGARCH_CSR_TINTCLR will clear
* timer interrupt, and CSR TVAL keeps unchanged with -1, it
* avoids spurious timer interrupt
*/
- if (!(estat & CPU_TIMER))
+ if (!(estat & CPU_TIMER)) {
+ __delay(2); /* Wait cycles until timer interrupt injected */
+
+ /*
+ * Fail to restore timer with timer tick == -1 and
+ * timer interrupt disabled.
+ *
+ * Write timer tick with max value, timer will go
+ * down from max tick value
+ */
+ estat = kvm_read_hw_gcsr(LOONGARCH_CSR_ESTAT);
+ if (!(estat & CPU_TIMER))
+ write_gcsr_timertick(CSR_TCFG_VAL);
gcsr_write(CSR_TINTCLR_TI, LOONGARCH_CSR_TINTCLR);
+ }
return;
}

--
2.39.3