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 <[email protected]>
>> ---
>>  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.
>
>>      }
>>  }
>>  

Reply via email to