On 8/28/2026 9:11 PM, Christian König wrote:
On 8/28/26 11:53, Zhu Lingshan wrote:
The GFX11 user queue private fault woker loads
the relevnt user queue from the userq doorbell xarray.
However it does not hold the spin_lock of the xarray
when walking the xarray, and does not increase the
kref of the user queue, so it races with queue
destruction path and may run into an use-after-free
userq problem.

This commit fixes this UAF problem by utilizing
amdgpu_lookup_queue_by_doorbell helper, which
properly hoding the xarray spin lock and the kref
of the user queue.

Signed-off-by: Zhu Lingshan <lingshan.zhu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a447562977ab..a063f86a8847 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -6733,9 +6733,12 @@ static void gfx_v11_0_userq_priv_fault_work(struct work_struct *work)
 
 		doorbell = (db_ctrl & CP_RB_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK) >>
 			   CP_RB_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT;
-		q = xa_load(&adev->userq_doorbell_xa, doorbell);
-		if (q)
+		q = amdgpu_lookup_queue_by_doorbell(&adev->userq_doorbell_xa,
+						    doorbell);
+		if (q) {
 			amdgpu_userq_start_hang_detect_work(q);
+			amdgpu_userq_put(q);
+		}
This must just lock the XA irqsave, this code has been suggested like that before and been removed because it doesn't work correctly.\
The xa spin lock is held in the helper amdgpu_lookup_queue_by_doorbell().

Please see patch 1:

38 +amdgpu_lookup_queue_by_doorbell(struct xarray *xa, u32 doorbell)
 39 +{
 40 +       struct amdgpu_usermode_queue *queue;
 41 +       unsigned long flags;
 42 +
 43 +       xa_lock_irqsave(xa, flags);



Thanks
Lingshan

Please check the git history before suggesting bringing back a buggy approach.

Christian.

 	}
 }