Add two new VM ioctl operations:
  AMDGPU_VM_OP_SET_L2_TRAP   (op = 3)
  AMDGPU_VM_OP_CLEAR_L2_TRAP (op = 4)

The second-level trap handler is a per-VM setting. All shader waves
executing under this VMID share the same handler regardless of queue
type. GFX and compute queues from the same process share the same VMID
so one SET_L2_TRAP covers all queue types for this DRM file.

The TRAP ioctl and its associated structures are removed entirely; the
ioctl number was never part of a released kernel.

Both TBA and TMA buffers MUST be allocated with
AMDGPU_GEM_CREATE_VM_ALWAYS_VALID. The GPU jumps to TBA automatically on
a hardware exception without any software job submission.

Signed-off-by: Srinivasan Shanmugam <[email protected]>
Cc: Christian König <[email protected]>
Cc: Alex Deucher <[email protected]>
Cc: Felix Kuehling <[email protected]>
Cc: Lijo Lazar <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c |  26 ++++++
 include/uapi/drm/amdgpu_drm.h          | 112 ++++++++++++++++++++-----
 2 files changed, 118 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index d981915ac2f4..562139dc23ae 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2911,6 +2911,32 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, 
struct drm_file *filp)
        case AMDGPU_VM_OP_UNRESERVE_VMID:
                amdgpu_vmid_free_reserved(adev, vm, AMDGPU_GFXHUB(0));
                break;
+       case AMDGPU_VM_OP_SET_L2_TRAP:
+               /*
+                * Install or replace the per-VM second-level trap handler.
+                * Applies to all shader waves under this VMID regardless of
+                * queue type.
+                */
+               if (!vm->trap_obj)
+                       return -EOPNOTSUPP;
+               return amdgpu_trap_vm_set_l2_trap(adev, vm,
+                                                 &fpriv->userq_mgr,
+                                                 vm->trap_obj,
+                                                 args->in.l2trap.tba_va,
+                                                 args->in.l2trap.tba_sz,
+                                                 args->in.l2trap.tma_va,
+                                                 args->in.l2trap.tma_sz);
+       case AMDGPU_VM_OP_CLEAR_L2_TRAP:
+               /*
+                * Disable the per-VM second-level trap handler.
+                * Waits for VM idle, evicts queues, flushes TLB, clears
+                * the handler descriptor.
+                */
+               if (!vm->trap_obj)
+                       return -EOPNOTSUPP;
+               return amdgpu_trap_vm_clear_l2_trap(adev, vm,
+                                                   &fpriv->userq_mgr,
+                                                   vm->trap_obj);
        default:
                return -EINVAL;
        }
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 4785cf48da17..24a08e4f0f36 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -632,10 +632,102 @@ struct drm_amdgpu_userq_wait {
 #define AMDGPU_VM_OP_RESERVE_VMID      1
 #define AMDGPU_VM_OP_UNRESERVE_VMID    2
 
+/**
+ * AMDGPU_VM_OP_SET_L2_TRAP - install or replace the second-level trap
+ *   handler for all GFX and compute queues belonging to this VM.
+ *
+ * The second-level trap handler is a per-VM setting. All shader waves
+ * executing under this VMID share the same handler regardless of queue
+ * type. GFX and compute queues from the same process share the same VMID
+ * so one SET_L2_TRAP covers all queue types for this DRM file.
+ *
+ * IMPORTANT: Both TBA and TMA buffers MUST be allocated with the
+ * AMDGPU_GEM_CREATE_VM_ALWAYS_VALID flag. The GPU jumps to TBA
+ * automatically on a hardware exception without any software job
+ * submission, so the kernel cannot track TBA/TMA in a job's used-buffer
+ * list. Without VM_ALWAYS_VALID the BO can be evicted and the page
+ * table entry becomes stale, causing a GPU page fault or memory
+ * corruption when the next shader exception fires.
+ *
+ * The TBA range must contain the handler executable code.
+ * The TMA range is the handler scratch memory buffer.
+ * Both ranges must be non-empty and fully mapped in the GPU virtual
+ * address space of this DRM file descriptor.
+ *
+ * For user queues, all active queues are evicted and the GPU TLB is
+ * flushed before the descriptor is written, then queues are restored.
+ * This prevents a trapping wave from observing a partially-written
+ * TBA/TMA pair during the update window.
+ *
+ * For kernel queues, the VM is drained via amdgpu_vm_wait_idle() before
+ * eviction and the descriptor write. This ensures no kernel-queue wave
+ * is active while TBA and TMA are being updated.
+ *
+ * Userspace should keep both mappings alive until
+ * AMDGPU_VM_OP_CLEAR_L2_TRAP succeeds. If either mapping is removed
+ * while the handler is active, the kernel waits for the VM to be idle,
+ * evicts all user queues, flushes the GPU TLB, clears the handler, and
+ * allows the unmap to proceed. UNMAP never returns an error for this
+ * condition. Queues whose trap handler VA was removed are not restarted.
+ *
+ * Returns:
+ *  0             on success;
+ *  -EOPNOTSUPP   if the first-level CWSR handler is unavailable;
+ *  -EINVAL       if TBA/TMA is invalid, not mapped, or not allocated
+ *                with AMDGPU_GEM_CREATE_VM_ALWAYS_VALID;
+ *  -ETIMEDOUT    if the VM did not become idle within the wait timeout;
+ *  negative errno if the VM reservation fails.
+ */
+#define AMDGPU_VM_OP_SET_L2_TRAP       3
+
+/**
+ * AMDGPU_VM_OP_CLEAR_L2_TRAP - disable the second-level trap handler.
+ *
+ * For user queues, all active queues are evicted and the GPU TLB is
+ * flushed before TBA is zeroed to ensure no wave is executing inside
+ * the handler at the time of the clear.
+ *
+ * For kernel queues, the VM is drained via amdgpu_vm_wait_idle() before
+ * eviction and the clear. This ensures no kernel-queue wave is active
+ * while the descriptor is being zeroed.
+ *
+ * The l2trap input members are ignored for this operation.
+ *
+ * After this operation succeeds userspace may safely remove the TBA
+ * and TMA mappings.
+ *
+ * Returns:
+ *  0             on success;
+ *  -EOPNOTSUPP   if the first-level CWSR handler is unavailable;
+ *  negative errno if the VM reservation fails.
+ */
+#define AMDGPU_VM_OP_CLEAR_L2_TRAP     4
+
 struct drm_amdgpu_vm_in {
        /** AMDGPU_VM_OP_* */
        __u32   op;
        __u32   flags;
+       union {
+               struct {
+                       /** GPU VA of second-level trap handler code buffer */
+                       __u64 tba_va;
+                       /** TBA buffer size in bytes */
+                       __u32 tba_sz;
+                       /** Explicit padding; tma_va starts at offset 24 */
+                       __u32 _pad;
+                       /** GPU VA of second-level trap handler scratch buffer 
*/
+                       __u64 tma_va;
+                       /** TMA buffer size in bytes */
+                       __u32 tma_sz;
+                       /** Padding to fix total union size at 32 bytes */
+                       __u32 _pad2;
+               } l2trap;
+               /**
+                * Padding; keeps the union at a fixed 32-byte size for
+                * future ops. Zero-initialise for RESERVE/UNRESERVE_VMID.
+                */
+               __u64 _pad[4];
+       };
 };
 
 struct drm_amdgpu_vm_out {
@@ -1745,27 +1837,7 @@ struct drm_amdgpu_info_cwsr {
        __u32 min_save_area_size;
 };
 
-/* cwsr ioctl */
-#define AMDGPU_TRAP_OP_SET_L2_TRAP 1
-
-struct drm_amdgpu_trap_in {
-       /* AMDGPU_TRAP_OP_* */
-       __u32 op;
-       struct {
-               /* Level 2 trap handler base address */
-               __u64 tba_va;
-               /* Level 2 trap handler buffer size (in bytes) */
-               __u32 tba_sz;
-               /* Level 2 trap memory buffer address */
-               __u64 tma_va;
-               /* Level 2 trap memory buffer size (in bytes) */
-               __u32 tma_sz;
-       } l2trap;
-};
 
-union drm_amdgpu_trap {
-       struct drm_amdgpu_trap_in in;
-};
 /*
  * Supported GPU families
  */
-- 
2.34.1

Reply via email to