diff options
author | Thomas Hellström <[email protected]> | 2023-05-25 09:41:44 +0200 |
---|---|---|
committer | Rodrigo Vivi <[email protected]> | 2023-12-21 11:35:04 -0500 |
commit | 5835dc7fa6e419627e23015c7dbde120a77ce738 (patch) | |
tree | 144c5308795c01c64f40ee44edf4d72f1b6dd5c6 | |
parent | a201c6ee37d63e7c0a2973fb7790e94211b7fa83 (diff) |
drm/xe: Fix vm refcount races
Fix a race in xe_vm_lookup() where the vm could disappear after
the lookup mutex unlock but before the get. The xe_vm_get() call
must be inside the lookup mutex.
Also fix a vm close race where multiple callers could potentially
succeed in calling xe_vm_close_and_put().
Reported-by: Oded Gabbay <[email protected]>
Link: https://lists.freedesktop.org/archives/intel-xe/2023-May/004704.html
Signed-off-by: Thomas Hellström <[email protected]>
Reviewed-by: Matthew Brost <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Signed-off-by: Rodrigo Vivi <[email protected]>
-rw-r--r-- | drivers/gpu/drm/xe/xe_vm.c | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 06ebc1cfc4f7..bd143acbde0e 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1533,10 +1533,9 @@ struct xe_vm *xe_vm_lookup(struct xe_file *xef, u32 id) mutex_lock(&xef->vm.lock); vm = xa_load(&xef->vm.xa, id); - mutex_unlock(&xef->vm.lock); - if (vm) xe_vm_get(vm); + mutex_unlock(&xef->vm.lock); return vm; } @@ -2011,27 +2010,26 @@ int xe_vm_destroy_ioctl(struct drm_device *dev, void *data, struct xe_file *xef = to_xe_file(file); struct drm_xe_vm_destroy *args = data; struct xe_vm *vm; + int err = 0; if (XE_IOCTL_ERR(xe, args->pad) || XE_IOCTL_ERR(xe, args->reserved[0] || args->reserved[1])) return -EINVAL; - vm = xe_vm_lookup(xef, args->vm_id); - if (XE_IOCTL_ERR(xe, !vm)) - return -ENOENT; - xe_vm_put(vm); - - /* FIXME: Extend this check to non-compute mode VMs */ - if (XE_IOCTL_ERR(xe, vm->preempt.num_engines)) - return -EBUSY; - mutex_lock(&xef->vm.lock); - xa_erase(&xef->vm.xa, args->vm_id); + vm = xa_load(&xef->vm.xa, args->vm_id); + if (XE_IOCTL_ERR(xe, !vm)) + err = -ENOENT; + else if (XE_IOCTL_ERR(xe, vm->preempt.num_engines)) + err = -EBUSY; + else + xa_erase(&xef->vm.xa, args->vm_id); mutex_unlock(&xef->vm.lock); - xe_vm_close_and_put(vm); + if (!err) + xe_vm_close_and_put(vm); - return 0; + return err; } static const u32 region_to_mem_type[] = { |