xe_assert(vm->xe, xe_vma_vm(vma) == vm);
        lockdep_assert_held(&vm->lock);
 
+       mutex_lock(&vm->snap_mutex);
        err = drm_gpuva_insert(&vm->gpuvm, &vma->gpuva);
+       mutex_unlock(&vm->snap_mutex);
        XE_WARN_ON(err);        /* Shouldn't be possible */
 
        return err;
        xe_assert(vm->xe, xe_vma_vm(vma) == vm);
        lockdep_assert_held(&vm->lock);
 
+       mutex_lock(&vm->snap_mutex);
        drm_gpuva_remove(&vma->gpuva);
+       mutex_unlock(&vm->snap_mutex);
        if (vm->usm.last_fault_vma == vma)
                vm->usm.last_fault_vma = NULL;
 }
        vm->flags = flags;
 
        init_rwsem(&vm->lock);
+       mutex_init(&vm->snap_mutex);
 
        INIT_LIST_HEAD(&vm->rebind_list);
 
        return ERR_PTR(err);
 
 err_no_resv:
+       mutex_destroy(&vm->snap_mutex);
        for_each_tile(tile, xe, id)
                xe_range_fence_tree_fini(&vm->rftree[id]);
        kfree(vm);
 
        up_write(&vm->lock);
 
+       mutex_destroy(&vm->snap_mutex);
+
        mutex_lock(&xe->usm.lock);
        if (vm->flags & XE_VM_FLAG_FAULT_MODE)
                xe->usm.num_vm_in_fault_mode--;
 
         * VM
         */
        struct rw_semaphore lock;
+       /**
+        * @snap_mutex: Mutex used to guard insertions and removals from gpuva,
+        * so we can take a snapshot safely from devcoredump.
+        */
+       struct mutex snap_mutex;
 
        /**
         * @rebind_list: list of VMAs that need rebinding. Protected by the