Add validation in amdgpu_gem_va_ioctl to reject VA mapping operations for buffers allocated with AMDGPU_GEM_DOMAIN_MMIO_REMAP domain.
This fixes a kernel NULL pointer dereference that occurs when user-space attempts to create VA mappings for MMIO_REMAP buffers. The MMIO_REMAP domain lacks proper scatter-gather table setup required for VA operations, causing the kernel to crash when accessing ttm->sg->sgl in amdgpu_ttm_tt_pde_flags. The crash manifests as: [ 228.188527] amdgpu_gem_create_ioctl[513] allocation mmio domain ########### [ 228.188537] BUG: kernel NULL pointer dereference, address: 0000000000000030 [ 228.188541] #PF: supervisor read access in kernel mode [ 228.188543] #PF: error_code(0x0000) - not-present page [ 228.188546] Oops: Oops: 0000 [#1] SMP NOPTI [ 228.188556] RIP: 0010:amdgpu_ttm_tt_pde_flags+0x2b/0x60 [amdgpu] [ 228.188673] RSP: 0018:ffff986f04563998 EFLAGS: 00010246 [ 228.188686] Call Trace: [ 228.188691] amdgpu_ttm_tt_pte_flags+0x21/0x50 [amdgpu] [ 228.188783] amdgpu_vm_bo_update+0x105/0x710 [amdgpu] [ 228.188887] amdgpu_gem_va_ioctl+0x77f/0x800 [amdgpu] The crash occurs because the instruction at amdgpu_ttm_tt_pde_flags+0x2b attempts to read from offset 0x30 of a NULL pointer (rdi=0x0000000000000000). By explicitly rejecting VA mapping for MMIO_REMAP domain at the ioctl entry point, we prevent the crash and provide clear feedback to user-space that this memory domain is not supported for VA operations. Signed-off-by: Jesse Zhang <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 10e21d2d9b52..1b09d6b9af58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -867,6 +867,20 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, uint64_t vm_size; int r = 0; + /* Check for invalid memory domains */ + if (args->operation != AMDGPU_VA_OP_CLEAR && + !(args->flags & AMDGPU_VM_PAGE_PRT)) { + gobj = drm_gem_object_lookup(filp, args->handle); + if (gobj == NULL) + return -ENOENT; + abo = gem_to_amdgpu_bo(gobj); + if (abo && (abo->preferred_domains & AMDGPU_GEM_DOMAIN_MMIO_REMAP)) { + drm_gem_object_put(gobj); + dev_info(adev->dev, "MMIO_REMAP domain not supported for VA mapping\n"); + return -EINVAL; + } + } + if (args->va_address < AMDGPU_VA_RESERVED_BOTTOM) { dev_dbg(dev->dev, "va_address 0x%llx is in reserved area 0x%llx\n", -- 2.49.0
