mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
KVM: arm64: GICv3: Add GICv2 SGI handling to deactivation primitive
The GICv2 SGIs require additional handling for deactivation, as they are effectively multiple interrrupts muxed into one. Make sure we check for the source CPU when deactivating. 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-30-maz@kernel.org Signed-off-by: Oliver Upton <oupton@kernel.org>
This commit is contained in:
committed by
Oliver Upton
parent
cd4f6ee99b
commit
295b692165
@@ -176,11 +176,20 @@ void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val)
|
||||
{
|
||||
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
|
||||
struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3;
|
||||
u32 model = vcpu->kvm->arch.vgic.vgic_model;
|
||||
struct kvm_vcpu *target_vcpu = NULL;
|
||||
bool mmio = false, is_v2_sgi;
|
||||
struct vgic_irq *irq;
|
||||
unsigned long flags;
|
||||
bool mmio = false;
|
||||
u64 lr = 0;
|
||||
u8 cpuid;
|
||||
|
||||
/* Snapshot CPUID, and remove it from the INTID */
|
||||
cpuid = FIELD_GET(GENMASK_ULL(12, 10), val);
|
||||
val &= ~GENMASK_ULL(12, 10);
|
||||
|
||||
is_v2_sgi = (model == KVM_DEV_TYPE_ARM_VGIC_V2 &&
|
||||
val < VGIC_NR_SGIS);
|
||||
|
||||
/*
|
||||
* We only deal with DIR when EOIMode==1, and only for SGI,
|
||||
@@ -216,6 +225,9 @@ void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val)
|
||||
* - Or the irq is active, but not in an LR, and we can
|
||||
* directly deactivate it by building a pseudo-LR, fold it,
|
||||
* and queue a request to prune the resulting ap_list,
|
||||
*
|
||||
* Special care must be taken to match the source CPUID when
|
||||
* deactivating a GICv2 SGI.
|
||||
*/
|
||||
scoped_guard(raw_spinlock, &irq->irq_lock) {
|
||||
target_vcpu = irq->vcpu;
|
||||
@@ -233,6 +245,12 @@ void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val)
|
||||
goto put;
|
||||
}
|
||||
|
||||
/* GICv2 SGI: check that the cpuid matches */
|
||||
if (is_v2_sgi && irq->active_source != cpuid) {
|
||||
target_vcpu = NULL;
|
||||
goto put;
|
||||
}
|
||||
|
||||
/* (with a Dalek voice) DEACTIVATE!!!! */
|
||||
lr = vgic_v3_compute_lr(vcpu, irq) & ~ICH_LR_ACTIVE_BIT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user