Background
----------
When a GPU shader crashes or hits an exception, the hardware
automatically jumps to a trap handler. There are two levels:

  First-level  — always active, managed by the kernel (CWSR)
  Second-level — optional, installed by userspace (RADV, ROCm)

The second-level handler lets userspace debuggers catch GPU crashes
and inspect what went wrong.

Problem
-------
The existing second-level trap handler support (merged earlier) only
works for user queues. RADV on GFX9 and GFX10 hardware (Vega, Navi,
Steam Deck) uses kernel queues — not user queues — because user queues
are not supported on those GPUs. This means RADV has no way to install
a second-level trap handler for shader debugging on those platforms.

Root cause: the SQ_SHADER_TMA register for kernel queue VMIDs was
never programmed by the driver, so there was nowhere to store the
second-level handler address.

Solution
--------
This series fixes the problem in three steps:

Patch 1 — Infrastructure
  - Allocate a small per-VM TMA buffer (kq_tma_bo) at VM creation time,
    the same way page tables are allocated.
  - Map it read-only into the GPU VM at a fixed address
    (AMDGPU_VA_RESERVED_TRAP_START).
  - Program SQ_SHADER_TMA for all kernel queue VMIDs to point to this
    fixed address. Because each VM has its own buffer at the same
    address, per-process isolation comes from the page tables — not
    from reprogramming the register per job.

Patch 2 — Hardware register programming (GFX10/11/12)
  - Implement the actual register writes (SQ_SHADER_TBA/TMA) for all
    supported GPU generations via SRBM select.
  - GFX10 uses mm-prefixed registers, GFX11/12 use reg-prefixed.
  - GFX12.1 has multiple XCC instances and iterates over all of them.
  - Called at boot and on GPU resume.

Patch 3 — Wire up SET_L2_TRAP and CLEAR_L2_TRAP
  - When userspace calls SET_L2_TRAP, write the second-level handler
    address into both the user queue TMA and the new kernel queue TMA.
  - When userspace calls CLEAR_L2_TRAP, zero both.
  - No new ioctl needed — RADV uses the same SET_L2_TRAP ioctl that
    user queues already use.

Design decisions
----------------
  - kq_tma_bo is per-VM, not device-level. One BO per process,
    same model as page tables.
  - Fixed VA (AMDGPU_VA_RESERVED_TRAP_START) in every VM's address
    space. Same register value for all VMIDs — isolation via page tables.
  - GPU sees it as read-only. Kernel CPU updates it via CPU mapping
    when SET_L2_TRAP is called.
  - Lifecycle matches page tables: allocated at VM init, freed at
    VM fini.
        
Only compilation tested.

Srinivasan Shanmugam (3):
  drm/amdgpu: Add per-VM kernel queue first-level trap handler
    infrastructure
  drm/amdgpu: Implement kernel VMID SQ_SHADER_TBA/TMA programming for
    GFX10/11/12
  drm/amdgpu: Extend second-level trap handler to kernel queues

 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h     |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_trap.c    | 107 ++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_trap.h    |   7 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c      |   9 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h      |  13 +++
 drivers/gpu/drm/amd/amdgpu/gfxhub_v11_5_0.c |  38 +++++++
 drivers/gpu/drm/amd/amdgpu/gfxhub_v12_0.c   |  38 +++++++
 drivers/gpu/drm/amd/amdgpu/gfxhub_v12_1.c   |  36 +++++++
 drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c    |  38 +++++++
 drivers/gpu/drm/amd/amdgpu/gfxhub_v3_0.c    |  33 ++++++
 10 files changed, 320 insertions(+)

-- 
2.34.1

Reply via email to