[PATCH 1/5] KVM: arm64: Grab KVM MMU write lock in kvm_arch_flush_shadow_all()
Bibo Mao
maobibo at loongson.cn
Wed May 6 18:40:10 PDT 2026
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
More information about the linux-arm-kernel
mailing list