vmm: take exclusive mem_segs_lock in vm_cleanup()

The consumers of vm_cleanup() are vm_reinit() and vm_destroy().

The vm_reinit() call path is, here vmmdev_ioctl() takes mem_segs_lock:
    vmmdev_ioctl()
    vm_reinit()
    vm_cleanup(destroy=false)

The call path for vm_destroy() is (mem_segs_lock not taken):
    sysctl_vmm_destroy()
    vmmdev_destroy()
    vm_destroy()
    vm_cleanup(destroy=true)

Fix this by taking mem_segs_lock in vm_cleanup() when destroy == true.

Reviewed by:	corvink, markj, jhb
Fixes:  67b69e76e8 ("vmm: Use an sx lock to protect the memory map.")
Differential Revision:	https://reviews.freebsd.org/D38071
This commit is contained in:
Robert Wing 2023-01-20 11:10:53 +00:00
parent ccf32a68f8
commit c668e8173a

View File

@ -651,6 +651,9 @@ vm_cleanup(struct vm *vm, bool destroy)
struct mem_map *mm;
int i;
if (destroy)
vm_xlock_memsegs(vm);
ppt_unassign_all(vm);
if (vm->iommu != NULL)
@ -690,6 +693,7 @@ vm_cleanup(struct vm *vm, bool destroy)
if (destroy) {
for (i = 0; i < VM_MAX_MEMSEGS; i++)
vm_free_memseg(vm, i);
vm_unlock_memsegs(vm);
vmmops_vmspace_free(vm->vmspace);
vm->vmspace = NULL;