From 8a6d79d3077685e1280e1c7de9238b9cb24b9d28 Mon Sep 17 00:00:00 2001 From: Qiang Ma Date: Tue, 26 May 2026 15:55:44 +0800 Subject: [PATCH] RISC-V: KVM: Fix timer state restore The KVM_REG_RISCV_TIMER_REG(state) one-reg write passes the value written by userspace to kvm_riscv_vcpu_timer_next_event() when re-enabling the timer. That value is the timer state, KVM_RISCV_TIMER_STATE_ON, not the timer compare value. During migration or state restore, userspace restores the compare register separately, which stores the target cycle in t->next_cycles. Re-arming the timer with the state value schedules the next event at cycle 1 instead of the restored compare value, causing the virtual timer to fire too early. Use the restored compare value from t->next_cycles when turning the timer back on. Fixes: 3a9f66cb25e1 ("RISC-V: KVM: Add timer functionality") Signed-off-by: Qiang Ma Signed-off-by: Linux RISC-V bot --- arch/riscv/kvm/vcpu_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c index 9817ff80282160..ae53133c7ab035 100644 --- a/arch/riscv/kvm/vcpu_timer.c +++ b/arch/riscv/kvm/vcpu_timer.c @@ -231,7 +231,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu, break; case KVM_REG_RISCV_TIMER_REG(state): if (reg_val == KVM_RISCV_TIMER_STATE_ON) - ret = kvm_riscv_vcpu_timer_next_event(vcpu, reg_val); + ret = kvm_riscv_vcpu_timer_next_event(vcpu, t->next_cycles); else ret = kvm_riscv_vcpu_timer_cancel(t); break;