Skip to content

Add CUDA GPU coredump support to nvproxy#13644

Open
luiscape wants to merge 1 commit into
google:masterfrom
luiscape:luis/gpucoredump-support
Open

Add CUDA GPU coredump support to nvproxy#13644
luiscape wants to merge 1 commit into
google:masterfrom
luiscape:luis/gpucoredump-support

Conversation

@luiscape

@luiscape luiscape commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Adds the five missing ioctls required to generate CUDA GPU coredumps using CUDA_ENABLE_COREDUMP_ON_EXCEPTION=1, all on the GT200_DEBUGGER class.

All the new ioctls simple pass-through controls except DEBUG_READ_MEMORY. They are gated on compute,utility, consistent with the existing NV83DE debug controls (SET_EXCEPTION_MASK, READ_ALL_SM_ERROR_STATES, CLEAR_ALL_SM_ERROR_STATES).

Coredump generation additionally uses NV2080_CTRL_CMD_GPU_EXEC_REG_OPS (already supported), so the feature requires running with --nvproxy-allowed-driver-capabilities=all,profiling.

In order for this to work, I added a ctrlDebugReadMemory handler that translates the embedded Buffer pointer in NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS by substituting a sentry-allocated buffer of the requested Length before invoking the host driver and copying the result back out to the application, mirroring the driver's own embedded-pointer copy logic in embedded_param_copy.c (which disables the RMAPI_PARAM_COPY_MAX_PARAMS_SIZE cap for this control).

Tested on an A10G with a faulting Triton kernel: the generated .nvcudmp matches native (runc) byte-for-byte in size, and cuda-gdb fully decodes it (CUDA Exception: Warp Illegal Address, faulting PC/kernel/warp/lane and backtrace). Without this change, coredump generation silently produces an empty dump (No exception was found on any device).

Assisted-by: Claude

Comment thread pkg/sentry/devices/nvproxy/frontend_unsafe.go
Adds the five missing `ioctls` required to generate [CUDA GPU coredumps](https://docs.nvidia.com/cuda/cuda-gdb/index.html#gpu-core-dump-support) (`CUDA_ENABLE_COREDUMP_ON_EXCEPTION=1`) under nvproxy, all on the `GT200_DEBUGGER` (`0x83de`) class:

- `NV83DE_CTRL_CMD_DEBUG_SET_MODE_MMU_DEBUG` (`0x83de0307`) control command — enables MMU debug mode during exception handling.
- `NV83DE_CTRL_CMD_DEBUG_READ_MEMORY` (`0x83de0315`) control command, with its `NV83DE_CTRL_DEBUG_READ_MEMORY_PARAMS` struct — reads a block of memory from the debugged context into an embedded pointer (`buffer`), which requires a custom handler. Note that the driver passes `RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK` for this control (see `src/nvidia/src/kernel/rmapi/embedded_param_copy.c`), so unlike most embedded pointers the buffer is *not* bounded by `RMAPI_PARAM_COPY_MAX_PARAMS_SIZE`; the handler mirrors this.
- `NV83DE_CTRL_CMD_DEBUG_SUSPEND_CONTEXT` (`0x83de0317`) control command — suspends the faulting SM context so its state can be captured.
- `NV83DE_CTRL_CMD_DEBUG_RESUME_CONTEXT` (`0x83de0318`) control command — resumes the context after capture. No params.
- `NV83DE_CTRL_CMD_DEBUG_SET_MODE_ERRBAR_DEBUG` (`0x83de031f`) control command — enables error-barrier debug mode (Volta+), a prerequisite for capturing SM exception state.

All are simple pass-through controls except `DEBUG_READ_MEMORY`. They are gated on `compute,utility`, consistent with the existing `NV83DE` debug controls (`SET_EXCEPTION_MASK`, `READ_ALL_SM_ERROR_STATES`, `CLEAR_ALL_SM_ERROR_STATES`).

Coredump generation additionally uses `NV2080_CTRL_CMD_GPU_EXEC_REG_OPS` (already supported), so the feature requires running with `--nvproxy-allowed-driver-capabilities=all,profiling`.

Tested on an A10G with a faulting Triton kernel: the generated `.nvcudmp` matches native (runc) byte-for-byte in size, and `cuda-gdb` fully decodes it (`CUDA Exception: Warp Illegal Address`, faulting PC/kernel/warp/lane and backtrace). Without this change, coredump generation silently produces an empty dump (`No exception was found on any device`).
@luiscape luiscape force-pushed the luis/gpucoredump-support branch from f41356e to ea001c0 Compare July 10, 2026 15:24
@luiscape luiscape requested a review from EtiennePerot July 10, 2026 15:28
// debugReadMemoryMaxLength bounds the size of the sentry buffer allocated to
// proxy a single NV83DE_CTRL_CMD_DEBUG_READ_MEMORY request, preventing a
// malicious application from forcing an arbitrarily large (up to ^uint32(0)
// bytes) sentry allocation. The driver itself does not impose a limit below

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sentry allocation and also host kernel allocation, since the driver too is not bounding this allocation.

Comment on lines +205 to +208
// note that the driver passes RMAPI_PARAM_COPY_FLAGS_DISABLE_MAX_SIZE_CHECK
// for this control, so Buffer's size is not limited by
// RMAPI_PARAM_COPY_MAX_PARAMS_SIZE, and the driver allocates a kernel buffer
// of the same size that we allocate here.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stale comment?

// NV_ERR_NO_MEMORY; see
// src/nvidia/src/kernel/rmapi/param_copy.c:rmapiParamsAcquire().
fi.ctx.Warningf("nvproxy: NV83DE_CTRL_CMD_DEBUG_READ_MEMORY length %d exceeds limit %d", ctrlParams.Length, uint32(debugReadMemoryMaxLength))
return 0, frontendFailWithStatus(fi, ioctlParams, nvgpu.NV_ERR_NO_MEMORY)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the requested length exceeds the limit, the driver generally returns NV_ERR_INVALID_ARGUMENT: https://github.com/NVIDIA/open-gpu-kernel-modules/blob/452cec62d827034798072827d3866d1881662b77/src/nvidia/src/kernel/rmapi/param_copy.c#L91

I suspect NV_ERR_NO_MEMORY is reserved for when the GPU genuinely runs out of memory.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But there's no limit specified in this call, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants