Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <seanjc@google.com>
Message-ID: <20250224235542.2562848-7-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Sean Christopherson and committed by
Paolo Bonzini
fd217326 e4472125

+12 -3
+12 -3
arch/x86/kvm/x86.c
··· 12759 12759 12760 12760 void kvm_arch_sync_events(struct kvm *kvm) 12761 12761 { 12762 - cancel_delayed_work_sync(&kvm->arch.kvmclock_sync_work); 12763 - cancel_delayed_work_sync(&kvm->arch.kvmclock_update_work); 12764 - kvm_free_pit(kvm); 12762 + 12765 12763 } 12766 12764 12767 12765 /** ··· 12840 12842 12841 12843 void kvm_arch_pre_destroy_vm(struct kvm *kvm) 12842 12844 { 12845 + /* 12846 + * Stop all background workers and kthreads before destroying vCPUs, as 12847 + * iterating over vCPUs in a different task while vCPUs are being freed 12848 + * is unsafe, i.e. will lead to use-after-free. The PIT also needs to 12849 + * be stopped before IRQ routing is freed. 12850 + */ 12851 + cancel_delayed_work_sync(&kvm->arch.kvmclock_sync_work); 12852 + cancel_delayed_work_sync(&kvm->arch.kvmclock_update_work); 12853 + 12854 + kvm_free_pit(kvm); 12855 + 12843 12856 kvm_mmu_pre_destroy_vm(kvm); 12844 12857 } 12845 12858