Skip to content

Commit 0d92e4a

Browse files
author
Marc Zyngier
committed
KVM: arm64: Disassociate vcpus from redistributor region on teardown
When tearing down a redistributor region, make sure we don't have any dangling pointer to that region stored in a vcpu. Fixes: e5a3563 ("kvm: arm64: vgic-v3: Introduce vgic_v3_free_redist_region()") Reported-by: Alexander Potapenko <glider@google.com> Reviewed-by: Oliver Upton <oliver.upton@linux.dev> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20240605175637.1635653-1-maz@kernel.org Cc: stable@vger.kernel.org
1 parent afb91f5 commit 0d92e4a

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
391391

392392
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
393393
list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list)
394-
vgic_v3_free_redist_region(rdreg);
394+
vgic_v3_free_redist_region(kvm, rdreg);
395395
INIT_LIST_HEAD(&dist->rd_regions);
396396
} else {
397397
dist->vgic_cpu_base = VGIC_ADDR_UNDEF;

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,8 +919,19 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index,
919919
return ret;
920920
}
921921

922-
void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg)
922+
void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg)
923923
{
924+
struct kvm_vcpu *vcpu;
925+
unsigned long c;
926+
927+
lockdep_assert_held(&kvm->arch.config_lock);
928+
929+
/* Garbage collect the region */
930+
kvm_for_each_vcpu(c, vcpu, kvm) {
931+
if (vcpu->arch.vgic_cpu.rdreg == rdreg)
932+
vcpu->arch.vgic_cpu.rdreg = NULL;
933+
}
934+
924935
list_del(&rdreg->list);
925936
kfree(rdreg);
926937
}
@@ -945,7 +956,7 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count)
945956

946957
mutex_lock(&kvm->arch.config_lock);
947958
rdreg = vgic_v3_rdist_region_from_index(kvm, index);
948-
vgic_v3_free_redist_region(rdreg);
959+
vgic_v3_free_redist_region(kvm, rdreg);
949960
mutex_unlock(&kvm->arch.config_lock);
950961
return ret;
951962
}

arch/arm64/kvm/vgic/vgic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg)
316316

317317
struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm,
318318
u32 index);
319-
void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg);
319+
void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg);
320320

321321
bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
322322

0 commit comments

Comments
 (0)