Merge tag 'drm-xe-fixes-2024-04-18' of https://gitlab.freedesktop.org/drm/xe/kernel...
authorDave Airlie <airlied@redhat.com>
Fri, 19 Apr 2024 00:40:04 +0000 (10:40 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 19 Apr 2024 00:40:47 +0000 (10:40 +1000)
- Fix bo leak on error path during fb init
- Fix use-after-free due to order vm is put and destroyed

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Lucas De Marchi <lucas.demarchi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/xjguifyantaibyrnymuiotxws6akiexi6r7tqyieqxgquovubc@kkrtbe24hjjr
drivers/gpu/drm/xe/display/intel_fb_bo.c
drivers/gpu/drm/xe/xe_vm.c

index b21da7b745a5e7cd6b3e34e4fb8d42a45b2b6466..a9c1f9885c6bb4d2727cbce81d5be93cb9458a38 100644 (file)
@@ -31,7 +31,7 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
 
        ret = ttm_bo_reserve(&bo->ttm, true, false, NULL);
        if (ret)
-               return ret;
+               goto err;
 
        if (!(bo->flags & XE_BO_SCANOUT_BIT)) {
                /*
@@ -42,12 +42,16 @@ int intel_fb_bo_framebuffer_init(struct intel_framebuffer *intel_fb,
                 */
                if (XE_IOCTL_DBG(i915, !list_empty(&bo->ttm.base.gpuva.list))) {
                        ttm_bo_unreserve(&bo->ttm);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto err;
                }
                bo->flags |= XE_BO_SCANOUT_BIT;
        }
        ttm_bo_unreserve(&bo->ttm);
+       return 0;
 
+err:
+       xe_bo_put(bo);
        return ret;
 }
 
index 62d1ef8867a84351ae7444d63113d8867dfbb0c5..3d4c8f342e215ed39263ba5c4c01079072dfcbbd 100644 (file)
@@ -1577,6 +1577,16 @@ void xe_vm_close_and_put(struct xe_vm *vm)
                xe->usm.num_vm_in_fault_mode--;
        else if (!(vm->flags & XE_VM_FLAG_MIGRATION))
                xe->usm.num_vm_in_non_fault_mode--;
+
+       if (vm->usm.asid) {
+               void *lookup;
+
+               xe_assert(xe, xe->info.has_asid);
+               xe_assert(xe, !(vm->flags & XE_VM_FLAG_MIGRATION));
+
+               lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
+               xe_assert(xe, lookup == vm);
+       }
        mutex_unlock(&xe->usm.lock);
 
        for_each_tile(tile, xe, id)
@@ -1592,24 +1602,15 @@ static void vm_destroy_work_func(struct work_struct *w)
        struct xe_device *xe = vm->xe;
        struct xe_tile *tile;
        u8 id;
-       void *lookup;
 
        /* xe_vm_close_and_put was not called? */
        xe_assert(xe, !vm->size);
 
        mutex_destroy(&vm->snap_mutex);
 
-       if (!(vm->flags & XE_VM_FLAG_MIGRATION)) {
+       if (!(vm->flags & XE_VM_FLAG_MIGRATION))
                xe_device_mem_access_put(xe);
 
-               if (xe->info.has_asid && vm->usm.asid) {
-                       mutex_lock(&xe->usm.lock);
-                       lookup = xa_erase(&xe->usm.asid_to_vm, vm->usm.asid);
-                       xe_assert(xe, lookup == vm);
-                       mutex_unlock(&xe->usm.lock);
-               }
-       }
-
        for_each_tile(tile, xe, id)
                XE_WARN_ON(vm->pt_root[id]);