From: Sean Christopherson Date: Mon, 24 Feb 2025 23:55:41 +0000 (-0800) Subject: KVM: x86: Fold guts of kvm_arch_sync_events() into kvm_arch_pre_destroy_vm() X-Git-Tag: v6.15-rc1~195^2~1^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fd21732682e20f1eefe73abbf6fc866b6bc51e9e;p=thirdparty%2Fkernel%2Flinux.git KVM: x86: Fold guts of kvm_arch_sync_events() into kvm_arch_pre_destroy_vm() Fold the guts of kvm_arch_sync_events() into kvm_arch_pre_destroy_vm(), as the kvmclock and PIT background workers only need to be stopped before destroying vCPUs (to avoid accessing vCPUs as they are being freed); it's a-ok for them to be running while the VM is visible on the global vm_list. Note, the PIT also needs to be stopped before IRQ routing is freed (because KVM's IRQ routing is garbage and assumes there is always non-NULL routing). Opportunistically add comments to explain why KVM stops/frees certain assets early. Signed-off-by: Sean Christopherson Message-ID: <20250224235542.2562848-7-seanjc@google.com> Signed-off-by: Paolo Bonzini --- diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2b74e8b1df678..650ef1ae02119 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -12759,9 +12759,7 @@ out: void kvm_arch_sync_events(struct kvm *kvm) { - cancel_delayed_work_sync(&kvm->arch.kvmclock_sync_work); - cancel_delayed_work_sync(&kvm->arch.kvmclock_update_work); - kvm_free_pit(kvm); + } /** @@ -12842,6 +12840,17 @@ EXPORT_SYMBOL_GPL(__x86_set_memory_region); void kvm_arch_pre_destroy_vm(struct kvm *kvm) { + /* + * Stop all background workers and kthreads before destroying vCPUs, as + * iterating over vCPUs in a different task while vCPUs are being freed + * is unsafe, i.e. will lead to use-after-free. The PIT also needs to + * be stopped before IRQ routing is freed. + */ + cancel_delayed_work_sync(&kvm->arch.kvmclock_sync_work); + cancel_delayed_work_sync(&kvm->arch.kvmclock_update_work); + + kvm_free_pit(kvm); + kvm_mmu_pre_destroy_vm(kvm); }