mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
KVM: arm64: GICv2: Extract LR computing primitive
Split vgic_v2_populate_lr() into two helpers, so that we have another primitive that computes the LR from a vgic_irq, but doesn't update anything in the shadow structure. 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-19-maz@kernel.org Signed-off-by: Oliver Upton <oupton@kernel.org>
This commit is contained in:
committed by
Oliver Upton
parent
3aa9a50c20
commit
0660bc4a2b
@@ -107,18 +107,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu)
|
||||
cpuif->used_lrs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates the particular LR with the state of a given IRQ:
|
||||
* - for an edge sensitive IRQ the pending state is cleared in struct vgic_irq
|
||||
* - for a level sensitive IRQ the pending state value is unchanged;
|
||||
* it is dictated directly by the input level
|
||||
*
|
||||
* If @irq describes an SGI with multiple sources, we choose the
|
||||
* lowest-numbered source VCPU and clear that bit in the source bitmap.
|
||||
*
|
||||
* The irq_lock must be held by the caller.
|
||||
*/
|
||||
void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
|
||||
static u32 vgic_v2_compute_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq)
|
||||
{
|
||||
u32 val = irq->intid;
|
||||
bool allow_pending = true;
|
||||
@@ -164,22 +153,52 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
|
||||
if (allow_pending && irq_is_pending(irq)) {
|
||||
val |= GICH_LR_PENDING_BIT;
|
||||
|
||||
if (vgic_irq_is_sgi(irq->intid)) {
|
||||
u32 src = ffs(irq->source);
|
||||
|
||||
if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
|
||||
irq->intid))
|
||||
return 0;
|
||||
|
||||
val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
|
||||
if (irq->source & ~BIT(src - 1))
|
||||
val |= GICH_LR_EOI;
|
||||
}
|
||||
}
|
||||
|
||||
/* The GICv2 LR only holds five bits of priority. */
|
||||
val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates the particular LR with the state of a given IRQ:
|
||||
* - for an edge sensitive IRQ the pending state is cleared in struct vgic_irq
|
||||
* - for a level sensitive IRQ the pending state value is unchanged;
|
||||
* it is dictated directly by the input level
|
||||
*
|
||||
* If @irq describes an SGI with multiple sources, we choose the
|
||||
* lowest-numbered source VCPU and clear that bit in the source bitmap.
|
||||
*
|
||||
* The irq_lock must be held by the caller.
|
||||
*/
|
||||
void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
|
||||
{
|
||||
u32 val = vgic_v2_compute_lr(vcpu, irq);
|
||||
|
||||
vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val;
|
||||
|
||||
if (val & GICH_LR_PENDING_BIT) {
|
||||
if (irq->config == VGIC_CONFIG_EDGE)
|
||||
irq->pending_latch = false;
|
||||
|
||||
if (vgic_irq_is_sgi(irq->intid)) {
|
||||
u32 src = ffs(irq->source);
|
||||
|
||||
if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
|
||||
irq->intid))
|
||||
return;
|
||||
|
||||
val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
|
||||
irq->source &= ~(1 << (src - 1));
|
||||
if (irq->source) {
|
||||
irq->source &= ~BIT(src - 1);
|
||||
if (irq->source)
|
||||
irq->pending_latch = true;
|
||||
val |= GICH_LR_EOI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,8 +215,6 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
|
||||
val |= (irq->priority >> 3) << GICH_LR_PRIORITY_SHIFT;
|
||||
|
||||
irq->on_lr = true;
|
||||
|
||||
vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = val;
|
||||
}
|
||||
|
||||
void vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr)
|
||||
|
||||
Reference in New Issue
Block a user