RE: [PATCH] drm/amdgpu: fix NULL pointer deref in amdgpu_vm_handle_moved for BO-less mappings

"Zhang, Jesse(Jie)" <[email protected]> Tue, 28 Jul 2026 07:32:51 +0000
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <DM4PR12MB515250C99F5D181D66A2C932E3CB2@DM4PR12MB5152.namprd12.prod.outlook.com>
AMD General

> -----Original Message-----
> From: Zhou, Bob <[email protected]>
> Sent: Tuesday, July 28, 2026 2:33 PM
> To: Zhang, Jesse(Jie) <[email protected]>; [email protected]
> Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
> <[email protected]>; Zhang, Jesse(Jie) <[email protected]>
> Subject: RE: [PATCH] drm/amdgpu: fix NULL pointer deref in
> amdgpu_vm_handle_moved for BO-less mappings
>
> AMD General
>
> since the new bo && guard already ensures bo is non-NULL (and equals bo_va-
> >base.bo), use bo directly instead of bo_va->base.bo - e.g.
> drm_gem_is_imported(&bo->tbo.base).
Good catch, thanks.
You're right: after the new NULL guard, using bo_va->base.bo is redundant.
I'll switch those uses to the local bo pointer (no functional change) and fold it into v2.

Thanks
Jesse
>
> Regards,
> Bob
>
> -----Original Message-----
> From: amd-gfx <[email protected]> On Behalf Of Jesse
> Zhang
> Sent: Tuesday, July 28, 2026 9:46 AM
> To: [email protected]
> Cc: Deucher, Alexander <[email protected]>; Koenig, Christian
> <[email protected]>; Zhang, Jesse(Jie) <[email protected]>
> Subject: [PATCH] drm/amdgpu: fix NULL pointer deref in
> amdgpu_vm_handle_moved for BO-less mappings
>
> The individual.needs_update loop in amdgpu_vm_handle_moved() unconditionally
> dereferenced bo_va->base.bo (to read its reservation object, ttm_tt and to test for a
> DMABuf import). However bo_va->base.bo can legitimately be NULL for
> PRT/sparse mappings - amdgpu_vm_bo_update() already handles a NULL bo via
> its "else if (!bo)" PRT path. When such a bo_va reaches the moved list (e.g. the
> userq eviction restore worker running amdgpu_vm_handle_moved() while a user
> queue is being torn down during a GPU reset), the NULL deref crashes the kernel:
>
>   BUG: kernel NULL pointer dereference, address: 0000000000000158
>   #PF: supervisor read access in kernel mode
>   Oops: 0000 [#1] SMP NOPTI
>   Workqueue: events amdgpu_userq_restore_worker [amdgpu]
>   RIP: 0010:amdgpu_vm_handle_moved+0x17a/0x200 [amdgpu]
>   Call Trace:
>    <TASK>
>    amdgpu_userq_vm_validate_and_restore_queue+0x2ce/0x920 [amdgpu]
>    amdgpu_userq_restore_worker+0xce/0x210 [amdgpu]
>    process_scheduled_works+0xa6/0x460
>    worker_thread+0x13c/0x290
>    kthread+0xfb/0x140
>    ret_from_fork+0x1b6/0x2b0
>    ret_from_fork_asm+0x1a/0x30
>    </TASK>
>
> The faulting instruction is "mov rax,[rdx+0x158]" with rdx (bo) == 0 and
> CR2 == 0x158, i.e. reading bo->tbo.base.resv off a NULL bo.
>
> Guard the BO-less case: skip the reservation dance and the DMABuf-import check
> when bo is NULL, and let amdgpu_vm_bo_update() take its existing PRT path.
>
> Signed-off-by: Jesse Zhang <[email protected]>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 12 +++++++++---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index aac8ace9d7a6..fbb76c32bff9 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -1631,11 +1631,17 @@ int amdgpu_vm_handle_moved(struct
> amdgpu_device *adev,
>                 bo_va = list_first_entry(&vm->individual.needs_update,
>                                          typeof(*bo_va), base.vm_status);
>                 bo = bo_va->base.bo;
> -               resv = bo->tbo.base.resv;
> +               resv = bo ? bo->tbo.base.resv : NULL;
>                 spin_unlock(&vm->individual_lock);
>
> +               /* PRT/sparse mappings have no BO to reserve; just update the
> +                * page tables (amdgpu_vm_bo_update() handles a NULL bo).
> +                */
> +               if (!bo) {
> +                       clear = false;
> +                       unlock = false;
>                 /* Try to reserve the BO to avoid clearing its ptes */
> -               if (!adev->debug_vm && !amdgpu_ttm_tt_get_usermm(bo->tbo.ttm) &&
> +               } else if (!adev->debug_vm &&
> +!amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)
> +&&
>                     dma_resv_trylock(resv)) {
>                         clear = false;
>                         unlock = true;
> @@ -1659,7 +1665,7 @@ int amdgpu_vm_handle_moved(struct amdgpu_device
> *adev,
>                 /* Remember evicted DMABuf imports in compute VMs for later
>                  * validation
>                  */
> -               if (vm->is_compute_context &&
> +               if (bo && vm->is_compute_context &&
>                     drm_gem_is_imported(&bo_va->base.bo->tbo.base) &&
>                     (!bo_va->base.bo->tbo.resource ||
>                      bo_va->base.bo->tbo.resource->mem_type == TTM_PL_SYSTEM))
> --
> 2.49.0
>