Re: [PATCH 1/5] KVM: arm64: Grab KVM MMU write lock in kvm_arch_flush_shadow_all()

From: Bibo Mao

Date: Wed May 06 2026 - 21:43:36 EST




On 2026/5/6 下午9:55, Sean Christopherson wrote:
On Wed, May 06, 2026, Bibo Mao wrote:
On 2026/5/5 上午6:42, James Houghton wrote:
kvm_arch_flush_shadow_all() may sometimes be called on the same `kvm`
concurrently in the event that the KVM's `mm` is __mmput() at the
same time that last reference to the KVM is being dropped.

T1 T2
KVM_CREATE_VM
Get VM file from T1
close VM
exit_mm() close VM

T1: exit_mm() -> kvm_mmu_notifier_release() -> kvm_flush_shadow_all(),
with only the KVM srcu read lock held.

T2: kvm_vm_release() ---> mmu_notifier_unregister() ->
kvm_mmu_notifier_release() -> kvm_flush_shadow_all(),
again, with only the KVM srcu read lock held.
By looking through the code, kvm_arch_destroy_vm() will free PGD page only,
page table walking is executing in deleting memslot or exit_mm().

With normal code, life cycle of VM is something like this:

Not necessarily. Abruptly closing the VM, as described below, is also "normal"
(though likely uncommon).

KVM_CREATE_VM
Create_VCPUs
Create memslots
Destroy_VCPUs

This is incorrect. KVM doesn't provide any way for userspace to destroy vCPUs.
Userspace can fully release every vCPU fd, but the vCPU object within KVM stays
alive (and indirectly reachable) until the VM is destroyed.
yes, that is so. For users, there is vCPU fd release interface. As for vCPU object release, it is kind of internal implementation in KVM.

Destroy memslots
close VM
exit_mm()

Note, exit_mm() may or may not be called. E.g. there are VMMs that will destroy
a VM and start a new one (perhaps even the same conceptual virtual machine) in
the same process / mm_struct / address space.

And there is kvm_get_kvm()/kvm_put_kvm() function call with creating/destroy
vCPUs, however no such operations with memslot operation. Is it possible
that VM is destroyed without removing memslots, such as the following
operation.
KVM_CREATE_VM
Create memslots
close VM
exit_mm()

Yep. KVM cannot make any assumptions when it comes to userspace-initiated
operations. Even a VMM that super strictly follows the first approach may exit
abruptly, without destroying memslots, e.g. if it's OOM-killed.
oh, I see. If so, the implementation about kvm_arch_destroy_vm() on Loongarch is problematic, it needs consider this kind of abnormal VM destroy, take page table walk and free page tables. I had thought that memslots create/destroy should call kvm_get_kvm()/kvm_put_kvm() :(

Regards
Bibo Mao