Skip to content

Commit ff60c8d

Browse files
committed
drm/panthor: Keep a ref to the VM at the panthor_kernel_bo level
Avoids use-after-free situations when panthor_fw_unplug() is called and the kernel BO was mapped to the FW VM. Signed-off-by: Boris Brezillon <[email protected]> Reviewed-by: Steven Price <[email protected]> Reviewed-by: Liviu Dudau <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 2b2a26b commit ff60c8d

File tree

5 files changed

+22
-17
lines changed

5 files changed

+22
-17
lines changed

drivers/gpu/drm/panthor/panthor_fw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ panthor_fw_alloc_queue_iface_mem(struct panthor_device *ptdev,
453453

454454
ret = panthor_kernel_bo_vmap(mem);
455455
if (ret) {
456-
panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), mem);
456+
panthor_kernel_bo_destroy(mem);
457457
return ERR_PTR(ret);
458458
}
459459

@@ -1134,7 +1134,7 @@ void panthor_fw_unplug(struct panthor_device *ptdev)
11341134
panthor_fw_stop(ptdev);
11351135

11361136
list_for_each_entry(section, &ptdev->fw->sections, node)
1137-
panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), section->mem);
1137+
panthor_kernel_bo_destroy(section->mem);
11381138

11391139
/* We intentionally don't call panthor_vm_idle() and let
11401140
* panthor_mmu_unplug() release the AS we acquired with

drivers/gpu/drm/panthor/panthor_gem.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@ static void panthor_gem_free_object(struct drm_gem_object *obj)
2626

2727
/**
2828
* panthor_kernel_bo_destroy() - Destroy a kernel buffer object
29-
* @vm: The VM this BO was mapped to.
3029
* @bo: Kernel buffer object to destroy. If NULL or an ERR_PTR(), the destruction
3130
* is skipped.
3231
*/
33-
void panthor_kernel_bo_destroy(struct panthor_vm *vm,
34-
struct panthor_kernel_bo *bo)
32+
void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
3533
{
34+
struct panthor_vm *vm;
3635
int ret;
3736

3837
if (IS_ERR_OR_NULL(bo))
3938
return;
4039

40+
vm = bo->vm;
4141
panthor_kernel_bo_vunmap(bo);
4242

4343
if (drm_WARN_ON(bo->obj->dev,
@@ -53,6 +53,7 @@ void panthor_kernel_bo_destroy(struct panthor_vm *vm,
5353
drm_gem_object_put(bo->obj);
5454

5555
out_free_bo:
56+
panthor_vm_put(vm);
5657
kfree(bo);
5758
}
5859

@@ -106,6 +107,7 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
106107
if (ret)
107108
goto err_free_va;
108109

110+
kbo->vm = panthor_vm_get(vm);
109111
bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm);
110112
drm_gem_object_get(bo->exclusive_vm_root_gem);
111113
bo->base.base.resv = bo->exclusive_vm_root_gem->resv;

drivers/gpu/drm/panthor/panthor_gem.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ struct panthor_kernel_bo {
6161
*/
6262
struct drm_gem_object *obj;
6363

64+
/**
65+
* @vm: VM this private buffer is attached to.
66+
*/
67+
struct panthor_vm *vm;
68+
6469
/**
6570
* @va_node: VA space allocated to this GEM.
6671
*/
@@ -136,7 +141,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
136141
size_t size, u32 bo_flags, u32 vm_map_flags,
137142
u64 gpu_va);
138143

139-
void panthor_kernel_bo_destroy(struct panthor_vm *vm,
140-
struct panthor_kernel_bo *bo);
144+
void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo);
141145

142146
#endif /* __PANTHOR_GEM_H__ */

drivers/gpu/drm/panthor/panthor_heap.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ static void panthor_free_heap_chunk(struct panthor_vm *vm,
127127
heap->chunk_count--;
128128
mutex_unlock(&heap->lock);
129129

130-
panthor_kernel_bo_destroy(vm, chunk->bo);
130+
panthor_kernel_bo_destroy(chunk->bo);
131131
kfree(chunk);
132132
}
133133

@@ -183,7 +183,7 @@ static int panthor_alloc_heap_chunk(struct panthor_device *ptdev,
183183
return 0;
184184

185185
err_destroy_bo:
186-
panthor_kernel_bo_destroy(vm, chunk->bo);
186+
panthor_kernel_bo_destroy(chunk->bo);
187187

188188
err_free_chunk:
189189
kfree(chunk);
@@ -395,7 +395,7 @@ int panthor_heap_return_chunk(struct panthor_heap_pool *pool,
395395
mutex_unlock(&heap->lock);
396396

397397
if (removed) {
398-
panthor_kernel_bo_destroy(pool->vm, chunk->bo);
398+
panthor_kernel_bo_destroy(chunk->bo);
399399
kfree(chunk);
400400
ret = 0;
401401
} else {
@@ -595,7 +595,7 @@ void panthor_heap_pool_destroy(struct panthor_heap_pool *pool)
595595
drm_WARN_ON(&pool->ptdev->base, panthor_heap_destroy_locked(pool, i));
596596

597597
if (!IS_ERR_OR_NULL(pool->gpu_contexts))
598-
panthor_kernel_bo_destroy(pool->vm, pool->gpu_contexts);
598+
panthor_kernel_bo_destroy(pool->gpu_contexts);
599599

600600
/* Reflects the fact the pool has been destroyed. */
601601
pool->vm = NULL;

drivers/gpu/drm/panthor/panthor_sched.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,8 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue *
826826

827827
panthor_queue_put_syncwait_obj(queue);
828828

829-
panthor_kernel_bo_destroy(group->vm, queue->ringbuf);
830-
panthor_kernel_bo_destroy(panthor_fw_vm(group->ptdev), queue->iface.mem);
829+
panthor_kernel_bo_destroy(queue->ringbuf);
830+
panthor_kernel_bo_destroy(queue->iface.mem);
831831

832832
kfree(queue);
833833
}
@@ -837,15 +837,14 @@ static void group_release_work(struct work_struct *work)
837837
struct panthor_group *group = container_of(work,
838838
struct panthor_group,
839839
release_work);
840-
struct panthor_device *ptdev = group->ptdev;
841840
u32 i;
842841

843842
for (i = 0; i < group->queue_count; i++)
844843
group_free_queue(group, group->queues[i]);
845844

846-
panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->suspend_buf);
847-
panthor_kernel_bo_destroy(panthor_fw_vm(ptdev), group->protm_suspend_buf);
848-
panthor_kernel_bo_destroy(group->vm, group->syncobjs);
845+
panthor_kernel_bo_destroy(group->suspend_buf);
846+
panthor_kernel_bo_destroy(group->protm_suspend_buf);
847+
panthor_kernel_bo_destroy(group->syncobjs);
849848

850849
panthor_vm_put(group->vm);
851850
kfree(group);

0 commit comments

Comments
 (0)