Skip to content

Commit

Permalink
KVM: arm64: vgic: Force vcpu vgic teardown on vcpu destroy
Browse files Browse the repository at this point in the history
commit 02e3858 upstream.

When failing to create a vcpu because (for example) it has a
duplicate vcpu_id, we destroy the vcpu. Amusingly, this leaves
the redistributor registered with the KVM_MMIO bus.

This is no good, and we should properly clean the mess. Force
a teardown of the vgic vcpu interface, including the RD device
before returning to the caller.

Cc: stable@vger.kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20231207151201.3028710-4-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Marc Zyngier authored and Greg Kroah-Hartman committed Jan 1, 2024
1 parent 05d47e2 commit e13ce00
Showing 4 changed files with 7 additions and 3 deletions.
2 changes: 1 addition & 1 deletion arch/arm64/kvm/arm.c
Original file line number Diff line number Diff line change
@@ -407,7 +407,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
kvm_timer_vcpu_terminate(vcpu);
kvm_pmu_vcpu_destroy(vcpu);

kvm_vgic_vcpu_destroy(vcpu);
kvm_arm_vcpu_destroy(vcpu);
}

5 changes: 4 additions & 1 deletion arch/arm64/kvm/vgic/vgic-init.c
Original file line number Diff line number Diff line change
@@ -379,7 +379,10 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
vgic_flush_pending_lpis(vcpu);

INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
vgic_unregister_redist_iodev(vcpu);
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
}
}

void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
2 changes: 1 addition & 1 deletion arch/arm64/kvm/vgic/vgic-mmio-v3.c
Original file line number Diff line number Diff line change
@@ -820,7 +820,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
return ret;
}

static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
{
struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev;

1 change: 1 addition & 0 deletions arch/arm64/kvm/vgic/vgic.h
Original file line number Diff line number Diff line change
@@ -241,6 +241,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq);
int vgic_v3_save_pending_tables(struct kvm *kvm);
int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count);
int vgic_register_redist_iodev(struct kvm_vcpu *vcpu);
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu);
bool vgic_v3_check_base(struct kvm *kvm);

void vgic_v3_load(struct kvm_vcpu *vcpu);

0 comments on commit e13ce00

Please sign in to comment.