]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: timer: Kill the per-timer irq level cache
authorMarc Zyngier <maz@kernel.org>
Wed, 20 May 2026 10:01:57 +0000 (11:01 +0100)
committerMarc Zyngier <maz@kernel.org>
Thu, 21 May 2026 07:08:49 +0000 (08:08 +0100)
The timer code makes use of a per-timer irq level cache, which
looks like a very minor optimisation to avoid taking a lock upon
updating the GIC view of the interrupt when it is unchanged from
the previous state.

This is coming in the way of more important correctness issues,
so get rid of the cache, which simplifies a couple of minor things.

Reviewed-by: Oliver Upton <oupton@kernel.org>
Link: https://patch.msgid.link/20260520100200.543845-4-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/arch_timer.c
include/kvm/arm_arch_timer.h

index 7236dd6a99e67b50e6e5c73fb07e3d1e8ce2f2c1..c3b8257888e89583330c4ffdfe53e144628ad70a 100644 (file)
@@ -453,9 +453,8 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 {
        kvm_timer_update_status(timer_ctx, new_level);
 
-       timer_ctx->irq.level = new_level;
        trace_kvm_timer_update_irq(vcpu->vcpu_id, timer_irq(timer_ctx),
-                                  timer_ctx->irq.level);
+                                  new_level);
 
        if (userspace_irqchip(vcpu->kvm))
                return;
@@ -473,7 +472,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 
        kvm_vgic_inject_irq(vcpu->kvm, vcpu,
                            timer_irq(timer_ctx),
-                           timer_ctx->irq.level,
+                           new_level,
                            timer_ctx);
 }
 
@@ -484,10 +483,7 @@ static void timer_emulate(struct arch_timer_context *ctx)
 
        trace_kvm_timer_emulate(ctx, pending);
 
-       if (pending != ctx->irq.level)
-               kvm_timer_update_irq(timer_context_to_vcpu(ctx), pending, ctx);
-
-       kvm_timer_update_status(ctx, pending);
+       kvm_timer_update_irq(timer_context_to_vcpu(ctx), pending, ctx);
 
        /*
         * If the timer is pending, we don't need to have a soft timer
@@ -684,6 +680,7 @@ static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, boo
 static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
 {
        struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctx);
+       bool pending = kvm_timer_pending(ctx);
        bool phys_active = false;
 
        /*
@@ -692,12 +689,12 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
         * this point and the register restoration, we'll take the
         * interrupt anyway.
         */
-       kvm_timer_update_irq(vcpu, kvm_timer_pending(ctx), ctx);
+       kvm_timer_update_irq(vcpu, pending, ctx);
 
        if (irqchip_in_kernel(vcpu->kvm))
                phys_active = kvm_vgic_map_is_active(vcpu, timer_irq(ctx));
 
-       phys_active |= ctx->irq.level;
+       phys_active |= pending;
        phys_active |= vgic_is_v5(vcpu->kvm);
 
        set_timer_irq_phys_active(ctx, phys_active);
@@ -706,6 +703,7 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
 static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
 {
        struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
+       bool pending = kvm_timer_pending(vtimer);
 
        /*
         * Update the timer output so that it is likely to match the
@@ -713,7 +711,7 @@ static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
         * this point and the register restoration, we'll take the
         * interrupt anyway.
         */
-       kvm_timer_update_irq(vcpu, kvm_timer_pending(vtimer), vtimer);
+       kvm_timer_update_irq(vcpu, pending, vtimer);
 
        /*
         * When using a userspace irqchip with the architected timers and a
@@ -725,7 +723,7 @@ static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
         * being de-asserted, we unmask the interrupt again so that we exit
         * from the guest when the timer fires.
         */
-       if (vtimer->irq.level)
+       if (pending)
                disable_percpu_irq(host_vtimer_irq);
        else
                enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags);
index 9e4076eebd29fcc02d1507d0161878a6b90b2fac..15a4f97f8105156d0691c41625dba4f4cd304c91 100644 (file)
@@ -66,11 +66,6 @@ struct arch_timer_context {
         */
        bool                            loaded;
 
-       /* Output level of the timer IRQ */
-       struct {
-               bool                    level;
-       } irq;
-
        /* Who am I? */
        enum kvm_arch_timers            timer_id;