]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: Add tracking of vgic_irq being present in a LR
authorMarc Zyngier <maz@kernel.org>
Thu, 20 Nov 2025 17:24:58 +0000 (17:24 +0000)
committerOliver Upton <oupton@kernel.org>
Mon, 24 Nov 2025 22:29:12 +0000 (14:29 -0800)
We currently cannot identify whether an interrupt is queued into
a LR. It wasn't needed until now, but that's about to change.

Add yet another flag to track that state.

Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Link: https://msgid.link/20251120172540.2267180-9-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
arch/arm64/kvm/vgic/vgic-v2.c
arch/arm64/kvm/vgic/vgic-v3.c
include/kvm/arm_vgic.h

index 441efef80d609bd68a9e19b45647543dc8144795..74efacba38d42299397cac162feb3a0a41b79e72 100644 (file)
@@ -101,6 +101,8 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
                /* Handle resampling for mapped interrupts if required */
                vgic_irq_handle_resampling(irq, deactivated, val & GICH_LR_PENDING_BIT);
 
+               irq->on_lr = false;
+
                raw_spin_unlock(&irq->irq_lock);
                vgic_put_irq(vcpu->kvm, irq);
        }
@@ -124,6 +126,8 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        u32 val = irq->intid;
        bool allow_pending = true;
 
+       WARN_ON(irq->on_lr);
+
        if (irq->active) {
                val |= GICH_LR_ACTIVE_BIT;
                if (vgic_irq_is_sgi(irq->intid))
@@ -194,6 +198,8 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        /* The GICv2 LR only holds five bits of priority. */
        val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT;
 
+       irq->on_lr = true;
+
        vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val;
 }
 
index 1b6c3071ec80f2d5a817a656b2494fd7f522cf84..e3f4b27e0225fe5025d43e66f17d29d9d92ba59b 100644 (file)
@@ -97,6 +97,8 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
                /* Handle resampling for mapped interrupts if required */
                vgic_irq_handle_resampling(irq, deactivated, val & ICH_LR_PENDING_BIT);
 
+               irq->on_lr = false;
+
                raw_spin_unlock(&irq->irq_lock);
                vgic_put_irq(vcpu->kvm, irq);
        }
@@ -111,6 +113,8 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        u64 val = irq->intid;
        bool allow_pending = true, is_v2_sgi;
 
+       WARN_ON(irq->on_lr);
+
        is_v2_sgi = (vgic_irq_is_sgi(irq->intid) &&
                     model == KVM_DEV_TYPE_ARM_VGIC_V2);
 
@@ -185,6 +189,8 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
        val |= (u64)irq->priority << ICH_LR_PRIORITY_SHIFT;
 
        vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[lr] = val;
+
+       irq->on_lr = true;
 }
 
 void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr)
index e84a1bc5cf172a095b3a28957c17b41111494cb7..ec349c5a4a8b6bd06cd6499828c4eafee4a8d943 100644 (file)
@@ -149,6 +149,7 @@ struct vgic_irq {
        bool enabled:1;
        bool active:1;
        bool hw:1;                      /* Tied to HW IRQ */
+       bool on_lr:1;                   /* Present in a CPU LR */
        refcount_t refcount;            /* Used for LPIs */
        u32 hwintid;                    /* HW INTID number */
        unsigned int host_irq;          /* linux irq corresponding to hwintid */