mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
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>
This commit is contained in:
parent
78ffc28456
commit
281c6c06e2
|
|
@ -100,6 +100,8 @@ static void vgic_v2_fold_lr(struct kvm_vcpu *vcpu, u32 val)
|
||||||
vgic_put_irq(vcpu->kvm, irq);
|
vgic_put_irq(vcpu->kvm, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 vgic_v2_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transfer the content of the LRs back into the corresponding ap_list:
|
* transfer the content of the LRs back into the corresponding ap_list:
|
||||||
* - active bit is transferred as is
|
* - active bit is transferred as is
|
||||||
|
|
@ -111,12 +113,37 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
|
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
|
||||||
struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2;
|
struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2;
|
||||||
|
u32 eoicount = FIELD_GET(GICH_HCR_EOICOUNT, cpuif->vgic_hcr);
|
||||||
|
struct vgic_irq *irq;
|
||||||
|
|
||||||
DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
|
DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
|
||||||
|
|
||||||
for (int lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++)
|
for (int lr = 0; lr < vgic_cpu->vgic_v2.used_lrs; lr++)
|
||||||
vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]);
|
vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]);
|
||||||
|
|
||||||
|
/* See the GICv3 equivalent for the EOIcount handling rationale */
|
||||||
|
list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) {
|
||||||
|
u32 lr;
|
||||||
|
|
||||||
|
if (!eoicount) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
guard(raw_spinlock)(&irq->irq_lock);
|
||||||
|
|
||||||
|
if (!(likely(vgic_target_oracle(irq) == vcpu) &&
|
||||||
|
irq->active))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lr = vgic_v2_compute_lr(vcpu, irq) & ~GICH_LR_ACTIVE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lr & GICH_LR_HW)
|
||||||
|
writel_relaxed(FIELD_GET(GICH_LR_PHYSID_CPUID, lr),
|
||||||
|
kvm_vgic_global_state.gicc_base + GIC_CPU_DEACTIVATE);
|
||||||
|
vgic_v2_fold_lr(vcpu, lr);
|
||||||
|
eoicount--;
|
||||||
|
}
|
||||||
|
|
||||||
cpuif->used_lrs = 0;
|
cpuif->used_lrs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user