From 387b558fec9f8b0d3e0a4d48b5912301c1477bdd Mon Sep 17 00:00:00 2001 From: lutong Date: Fri, 7 Nov 2025 11:44:25 +0800 Subject: [PATCH] KVM: arm64: Deactivate the spurious vtimer interrupt virt inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/none CVE: NA Reference: https://gitee.com/openeuler/kernel/issues/ID7470 ------------------------------------------- when hypervisor receives a vtimer interrupt but ISTATUS is 0, kvm_timer_update_irq will not be executed to inject this interrupt into the VM. Since EOImode is 1 and the timer interrupt has IRQD_FORWARDED_TO_VCPU flag, hypervisor will not write ICC_DIR_EL1 to deactivate the interrupt. This interrupt remains in active state, blocking subsequent interrupt from being process. Fixes: 9e01dc76be6a ("KVM: arm/arm64: arch_timer: Assign the phys timer on VHE systems") Signed-off-by: Kunkun Jiang Signed-off-by: Jia Qingtong Signed-off-by: Chengfei Huang Signed-off-by: Lutong --- --- arch/arm64/kvm/arch_timer.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 807873a72f89..42eeec7b9454 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -309,6 +309,14 @@ static void soft_timer_cancel(struct hrtimer *hrt) hrtimer_cancel(hrt); } +static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) +{ + int r; + + r = irq_set_irqchip_state(ctx->host_timer_irq, IRQCHIP_STATE_ACTIVE, active); + WARN_ON(r); +} + static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) { struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)dev_id; @@ -333,6 +341,8 @@ static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) if (kvm_timer_should_fire(ctx)) kvm_timer_update_irq(vcpu, true, ctx); + else + set_timer_irq_phys_active(ctx, false); if (userspace_irqchip(vcpu->kvm) && !static_branch_unlikely(&has_gic_active_state)) @@ -747,13 +757,6 @@ static void timer_restore_state(struct arch_timer_context *ctx) local_irq_restore(flags); } -static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, bool active) -{ - int r; - r = irq_set_irqchip_state(ctx->host_timer_irq, IRQCHIP_STATE_ACTIVE, active); - WARN_ON(r); -} - #ifdef CONFIG_VIRT_VTIMER_IRQ_BYPASS static void kvm_vtimer_mbigen_auto_clr_set(struct kvm_vcpu *vcpu, bool set) { -- Gitee