mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-18 15:19:38 +02:00
KVM: arm64: Disassociate vcpus from redistributor region on teardown
commit0d92e4a7ff
upstream. When tearing down a redistributor region, make sure we don't have any dangling pointer to that region stored in a vcpu. Fixes:e5a3563546
("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 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a937ef951b
commit
48bb62859d
|
@ -355,7 +355,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
|
||||||
|
|
||||||
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
|
if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
|
||||||
list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list)
|
list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list)
|
||||||
vgic_v3_free_redist_region(rdreg);
|
vgic_v3_free_redist_region(kvm, rdreg);
|
||||||
INIT_LIST_HEAD(&dist->rd_regions);
|
INIT_LIST_HEAD(&dist->rd_regions);
|
||||||
} else {
|
} else {
|
||||||
dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
|
dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
|
||||||
|
|
|
@ -942,8 +942,19 @@ free:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg)
|
void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg)
|
||||||
{
|
{
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
unsigned long c;
|
||||||
|
|
||||||
|
lockdep_assert_held(&kvm->arch.config_lock);
|
||||||
|
|
||||||
|
/* Garbage collect the region */
|
||||||
|
kvm_for_each_vcpu(c, vcpu, kvm) {
|
||||||
|
if (vcpu->arch.vgic_cpu.rdreg == rdreg)
|
||||||
|
vcpu->arch.vgic_cpu.rdreg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
list_del(&rdreg->list);
|
list_del(&rdreg->list);
|
||||||
kfree(rdreg);
|
kfree(rdreg);
|
||||||
}
|
}
|
||||||
|
@ -968,7 +979,7 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count)
|
||||||
|
|
||||||
mutex_lock(&kvm->arch.config_lock);
|
mutex_lock(&kvm->arch.config_lock);
|
||||||
rdreg = vgic_v3_rdist_region_from_index(kvm, index);
|
rdreg = vgic_v3_rdist_region_from_index(kvm, index);
|
||||||
vgic_v3_free_redist_region(rdreg);
|
vgic_v3_free_redist_region(kvm, rdreg);
|
||||||
mutex_unlock(&kvm->arch.config_lock);
|
mutex_unlock(&kvm->arch.config_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg)
|
||||||
|
|
||||||
struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm,
|
struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm,
|
||||||
u32 index);
|
u32 index);
|
||||||
void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg);
|
void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg);
|
||||||
|
|
||||||
bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
|
bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user