amdgpu_userq_evict_all() dereferenced queue->fw_obj.obj->vm_bo->vm to
reach the process VM when bumping the queue eviction counter. The fw_obj
is a kernel-allocated, GTT-pinned firmware/MQD buffer object that is
never added to the process VM, so its vm_bo is always NULL. On the first
eviction of any user queue, this faulted:
BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 2941.106372] Workqueue: events amdgpu_eviction_fence_suspend_worker [amdgpu]
[ 2941.106585] RIP: 0010:amdgpu_userq_evict+0xc7/0x140 [amdgpu]
[ 2941.106729] Code: ff ff ff ff 48 c7 45 d8 00 00 00 00 e8 92 5b 02 f7 49 89
c4 48 85 c0 74 62 45 31 ed 49 8b 44 24 78 31 f6 48 8b 80 60 02 00 00 <48> 8b 38
e8 c1 b8 ce ff 4c 89 e7 e8 19 db ff ff b9 08 00 00 00 48
[ 2941.106739] RSP: 0018:ffffd4bd485fbdc0 EFLAGS: 00010246
[ 2941.106743] RAX: 0000000000000000 RBX: ffff8e5bd3358cb0 RCX: 0000000000000000
[ 2941.106747] RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffffd4bd485fbd58
[ 2941.106751] RBP: ffffd4bd485fbde8 R08: ffff8e5bdd888000 R09: ffffd4bd485fbb38
[ 2941.106755] R10: 0000000000000001 R11: 0000000000000001 R12: ffff8e5bd2820c00
[ 2941.106759] R13: 0000000000000000 R14: ffff8e5bd9cf7360 R15: ffff8e5bd3358cb0
[ 2941.106764] FS: 0000000000000000(0000) GS:ffff8e5f342c9000(0000)
knlGS:0000000000000000
[ 2941.106769] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2941.106773] CR2: 0000000000000000 CR3: 000000001d840000 CR4: 0000000000750ef0
[ 2941.106778] PKRU: 55555554
[ 2941.106780] Call Trace:
[ 2941.106783] <TASK>
[ 2941.106787] amdgpu_eviction_fence_suspend_worker+0xd8/0x160 [amdgpu]
[ 2941.106898] process_scheduled_works+0xa6/0x420
[ 2941.106904] worker_thread+0x12a/0x270
[ 2941.106907] kthread+0x10d/0x230
[ 2941.106911] ? __pfx_worker_thread+0x10/0x10
[ 2941.106915] ? __pfx_kthread+0x10/0x10
[ 2941.106918] ret_from_fork+0x17c/0x1f0
[ 2941.106922] ? __pfx_kthread+0x10/0x10
[ 2941.106926] ret_from_fork_asm+0x1a/0x30
[ 2941.106931] </TASK>
The queue already carries a direct pointer to its VM in queue->vm, which
is the value the counter helper actually wants. Use it instead of walking
through the fw_obj BO.
Fixes: 4c131aa02bc4 ("drm/amdgpu: Add profiling counters in fdinfo")
Signed-off-by: Jesse Zhang <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index d5316e7bbb48..cf915ec8926c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -1358,7 +1358,7 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr)
amdgpu_userq_detect_and_reset_queues(uq_mgr);
/* Try to unmap all the queues in this process ctx */
xa_for_each(&uq_mgr->userq_xa, queue_id, queue) {
-
amdgpu_vm_increment_process_counter(queue->fw_obj.obj->vm_bo->vm,
AMDGPU_VM_QUEUE_EVICTION_COUNTER);
+ amdgpu_vm_increment_process_counter(queue->vm,
AMDGPU_VM_QUEUE_EVICTION_COUNTER);
r = amdgpu_userq_preempt_helper(queue);
if (r)
--
2.49.0