This series adds support for a userspace second-level trap handler on
render-node user queues (UQs), equivalent to what KFD already provides
for compute workloads via the HSA trap handler ABI.

When a GPU shader hits an exception, the hardware jumps to the
first-level CWSR trap handler. The first-level handler checks two slots
in the per-VM TMA buffer for a second-level handler address and
forwards the trap to userspace if one is installed.

The second-level handler is a per-VM (per-process) 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 that DRM file
descriptor. This is confirmed to work for GFX9 and later hardware.

Two new VM ioctl operations are added:
  AMDGPU_VM_OP_SET_L2_TRAP   (op = 3)
  AMDGPU_VM_OP_CLEAR_L2_TRAP (op = 4)

Both TBA and TMA buffers MUST be allocated with VM_ALWAYS_VALID. The
GPU jumps to TBA on hardware exception without any software submission,
so the kernel cannot track these BOs in a job's used-buffer list. An
evicted BO leaves a stale page table entry, causing a GPU page fault on
the next shader exception.

Changes in v2:
  - Move SET_L2_TRAP from the old TRAP ioctl (never released to
    upstream) into the VM ioctl as a per-VM property. The TRAP ioctl
    and its associated structures are removed entirely (Patch 1).
  - Add VM_ALWAYS_VALID validation in amdgpu_trap_validate_user_addr().
    SET_L2_TRAP returns -EINVAL if TBA or TMA BO does not have this
    flag. Without it, eviction leaves a stale page table entry
    (Natalie Vock).
  - Clarify in kdoc: SET_L2_TRAP is per-VM (per-process). No conflict
    between processes on user queue VMIDs. kq_tma_bo is CWSR scratch
    for the first-level handler only. SET_L2_TRAP for kernel queue
    VMIDs is not supported in this series (Lijo Lazar).
  - Replace void *tma_cpu_addr with struct iosys_map tma_map. On dGPUs
    the TMA BO may be placed in VRAM and accessed via MMIO (PCI BAR);
    raw pointer dereferences are unsafe there.
  - Add evict-flush-write-restore sequence in SET_L2_TRAP. Writing TBA
    and TMA as two separate stores creates a race window where a
    trapping wave reads a mismatched pair.
  - Evict user queues in amdgpu_trap_free() at file close to prevent
    waves from trapping into a freed TMA BO.
  - Intercept GEM_VA UNMAP and CLEAR to disable the handler when TBA
    or TMA is unmapped without calling CLEAR_L2_TRAP first (Patch 3).

RFC v1: https://patchwork.freedesktop.org/series/172489/

Srinivasan Shanmugam (3):
  drm/amdgpu/uapi: Add second-level trap handler ops to VM ioctl
  drm/amdgpu: Add VM ioctl handlers for second-level trap handler
  drm/amdgpu: Disable L2 trap handler when its VA range is unmapped

 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c       |   1 -
 .../drm/amd/amdgpu/amdgpu_eviction_fence.c    |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c       |  22 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c       |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_trap.c      | 298 ++++++++++++------
 drivers/gpu/drm/amd/amdgpu/amdgpu_trap.h      |  63 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c     |  16 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h     |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c        |  25 ++
 include/uapi/drm/amdgpu_drm.h                 |  98 ++++--
 10 files changed, 402 insertions(+), 134 deletions(-)

-- 
2.34.1

Reply via email to