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

Reply via email to