Commit e447212
KVM: x86: Unload MMUs during vCPU destruction, not before
When destroying a VM, unload a vCPU's MMUs as part of normal vCPU freeing,
instead of as a separate prepratory action. Unloading MMUs ahead of time
is a holdover from commit 7b53aa5 ("KVM: Fix vcpu freeing for guest
smp"), which "fixed" a rather egregious flaw where KVM would attempt to
free *all* MMU pages when destroying a vCPU.
At the time, KVM would spin on all MMU pages in a VM when free a single
vCPU, and so would hang due to the way KVM pins and zaps root pages
(roots are invalidated but not freed if they are pinned by a vCPU).
static void free_mmu_pages(struct kvm_vcpu *vcpu)
{
struct kvm_mmu_page *page;
while (!list_empty(&vcpu->kvm->active_mmu_pages)) {
page = container_of(vcpu->kvm->active_mmu_pages.next,
struct kvm_mmu_page, link);
kvm_mmu_zap_page(vcpu->kvm, page);
}
free_page((unsigned long)vcpu->mmu.pae_root);
}
Now that KVM doesn't try to free all MMU pages when destroying a single
vCPU, there's no need to unpin roots prior to destroying a vCPU.
Note! While KVM mostly destroys all MMUs before calling
kvm_arch_destroy_vm() (see commit f00be0c ("KVM: MMU: do not free
active mmu pages in free_mmu_pages()")), unpinning MMU roots during vCPU
destruction will unfortunately trigger remote TLB flushes, i.e. will try
to send requests to all vCPUs.
Happily, thanks to commit 27592ae ("KVM: Move wiping of the kvm->vcpus
array to common code"), that's a non-issue as freed vCPUs are naturally
skipped by xa_for_each_range(), i.e. by kvm_for_each_vcpu(). Prior to that
commit, KVM x86 rather stupidly freed vCPUs one-by-one, and _then_
nullified them, one-by-one. I.e. triggering a VM-wide request would hit a
use-after-free.
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20250224235542.2562848-6-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>1 parent ed8f966 commit e447212
1 file changed
+3
-12
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12361 | 12361 | | |
12362 | 12362 | | |
12363 | 12363 | | |
| 12364 | + | |
| 12365 | + | |
| 12366 | + | |
12364 | 12367 | | |
12365 | 12368 | | |
12366 | 12369 | | |
| |||
12754 | 12757 | | |
12755 | 12758 | | |
12756 | 12759 | | |
12757 | | - | |
12758 | | - | |
12759 | | - | |
12760 | | - | |
12761 | | - | |
12762 | | - | |
12763 | | - | |
12764 | | - | |
12765 | | - | |
12766 | | - | |
12767 | | - | |
12768 | 12760 | | |
12769 | 12761 | | |
12770 | 12762 | | |
| |||
12869 | 12861 | | |
12870 | 12862 | | |
12871 | 12863 | | |
12872 | | - | |
12873 | 12864 | | |
12874 | 12865 | | |
12875 | 12866 | | |
| |||
0 commit comments