Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

KVM: arm64: GICv2: Handle LR overflow when EOImode==0

Similarly to the GICv3 version, handle the EOIcount-driven deactivation
by walking the overflow list.

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-38-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>

authored by

Marc Zyngier and committed by
Oliver Upton
281c6c06 78ffc284

+27
+27
arch/arm64/kvm/vgic/vgic-v2.c
··· 100 100 vgic_put_irq(vcpu->kvm, irq); 101 101 } 102 102 103 + static u32 vgic_v2_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq); 104 + 103 105 /* 104 106 * transfer the content of the LRs back into the corresponding ap_list: 105 107 * - active bit is transferred as is ··· 113 111 { 114 112 struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; 115 113 struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; 114 + u32 eoicount = FIELD_GET(GICH_HCR_EOICOUNT, cpuif->vgic_hcr); 115 + struct vgic_irq *irq; 116 116 117 117 DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); 118 118 119 119 for (int lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++) 120 120 vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]); 121 + 122 + /* See the GICv3 equivalent for the EOIcount handling rationale */ 123 + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { 124 + u32 lr; 125 + 126 + if (!eoicount) { 127 + break; 128 + } else { 129 + guard(raw_spinlock)(&irq->irq_lock); 130 + 131 + if (!(likely(vgic_target_oracle(irq) == vcpu) && 132 + irq->active)) 133 + continue; 134 + 135 + lr = vgic_v2_compute_lr(vcpu, irq) & ~GICH_LR_ACTIVE_BIT; 136 + } 137 + 138 + if (lr & GICH_LR_HW) 139 + writel_relaxed(FIELD_GET(GICH_LR_PHYSID_CPUID, lr), 140 + kvm_vgic_global_state.gicc_base + GIC_CPU_DEACTIVATE); 141 + vgic_v2_fold_lr(vcpu, lr); 142 + eoicount--; 143 + } 121 144 122 145 cpuif->used_lrs = 0; 123 146 }