* [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure
@ 2026-03-25 12:13 Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
` (9 more replies)
0 siblings, 10 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add the infrastructure for sending RM control RPCs. This is needed e.g.
for channel allocation.
This series adds:
- `NV_STATUS` bindings and wrapping `NvStatus` enum (used by RM control
RPCs)
- The necessary bindings for the RM control RPCs.
- `RmControlMsgFunction` to identify individual control commands, like
`MsgFunction` for GSP commands.
- `SBufferIter::read_to_vec` (using KVVec) for reading large RPC payloads
- A typed `RmControl` command that can send RM control commands.
- One usage of `RmControl`: the `FaultMethodBufferSize`
RPC. This is useful for channel allocation later.
Each new RM control command can be added by extending
`RmControlMsgFunction`, adding the bindings and wrappers for their
parameters, and writing a type-safe wrapper to send and receive the
reply for the RM control rpc, using `RmControl`.
This series applies on latest drm-rust-next with the listed
pre-requisites.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
Changes in v3:
- Remove `send_rm_control` in favour of a typed `RmControl`
- Print out fault method buffer size at gsp boot
- Remove Reviewed-by and Tested-by on some patches that have changed
substantively.
- Link to v2: https://lore.kernel.org/r/20260318-rmcontrol-v2-0-9a9fa6f1c4c3@nvidia.com
Changes in v2:
- Introduce typed Handle<T> for RM objects.
- Improve naming
- Improve doc comments
- Change SBufferIter to always use KVVec
- flush_into_kvec -> read_to_vec
- Rebased on latest cmdq locking
- Link to v1: https://lore.kernel.org/r/20260227-rmcontrol-v1-0-86648e4869f9@nvidia.com
---
Eliot Courtney (9):
gpu: nova-core: gsp: add NV_STATUS error code bindings
gpu: nova-core: gsp: add NvStatus enum for RM control errors
gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles
gpu: nova-core: gsp: add RM control RPC structure binding
gpu: nova-core: gsp: add types for RM control RPCs
gpu: nova-core: use KVVec for SBufferIter flush
gpu: nova-core: gsp: add RM control command infrastructure
gpu: nova-core: gsp: add CE fault method buffer size bindings
gpu: nova-core: gsp: add FaultMethodBufferSize RM control command
drivers/gpu/nova-core/gsp.rs | 1 +
drivers/gpu/nova-core/gsp/boot.rs | 11 +
drivers/gpu/nova-core/gsp/commands.rs | 62 ++++
drivers/gpu/nova-core/gsp/fw.rs | 402 ++++++++++++++++++++++
drivers/gpu/nova-core/gsp/fw/commands.rs | 19 +-
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 161 +++++++++
drivers/gpu/nova-core/gsp/fw/rm.rs | 106 ++++++
drivers/gpu/nova-core/gsp/rm.rs | 3 +
drivers/gpu/nova-core/gsp/rm/commands.rs | 167 +++++++++
drivers/gpu/nova-core/gsp/sequencer.rs | 4 +-
drivers/gpu/nova-core/sbuffer.rs | 6 +-
11 files changed, 936 insertions(+), 6 deletions(-)
---
base-commit: dff8302ca1d0e773c90dbeeb05e759f995c95482
change-id: 20260225-rmcontrol-bd8a06fc3a0d
Best regards,
--
Eliot Courtney <ecourtney@nvidia.com>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-04-05 19:55 ` John Hubbard
2026-03-25 12:13 ` [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
` (8 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add bindgen generated constants for NV_STATUS. This is used for RM
control messages.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 144 ++++++++++++++++++++++
1 file changed, 144 insertions(+)
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index 334e8be5fde8..dd37a7fd58c6 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -379,6 +379,150 @@ pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS {
pub __bindgen_padding_0: [u8; 4usize],
pub fbRegion: [NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; 16usize],
}
+pub const NV_OK: _bindgen_ty_4 = 0;
+pub const NV_ERR_GENERIC: _bindgen_ty_4 = 65535;
+pub const NV_ERR_BROKEN_FB: _bindgen_ty_4 = 1;
+pub const NV_ERR_BUFFER_TOO_SMALL: _bindgen_ty_4 = 2;
+pub const NV_ERR_BUSY_RETRY: _bindgen_ty_4 = 3;
+pub const NV_ERR_CALLBACK_NOT_SCHEDULED: _bindgen_ty_4 = 4;
+pub const NV_ERR_CARD_NOT_PRESENT: _bindgen_ty_4 = 5;
+pub const NV_ERR_CYCLE_DETECTED: _bindgen_ty_4 = 6;
+pub const NV_ERR_DMA_IN_USE: _bindgen_ty_4 = 7;
+pub const NV_ERR_DMA_MEM_NOT_LOCKED: _bindgen_ty_4 = 8;
+pub const NV_ERR_DMA_MEM_NOT_UNLOCKED: _bindgen_ty_4 = 9;
+pub const NV_ERR_DUAL_LINK_INUSE: _bindgen_ty_4 = 10;
+pub const NV_ERR_ECC_ERROR: _bindgen_ty_4 = 11;
+pub const NV_ERR_FIFO_BAD_ACCESS: _bindgen_ty_4 = 12;
+pub const NV_ERR_FREQ_NOT_SUPPORTED: _bindgen_ty_4 = 13;
+pub const NV_ERR_GPU_DMA_NOT_INITIALIZED: _bindgen_ty_4 = 14;
+pub const NV_ERR_GPU_IS_LOST: _bindgen_ty_4 = 15;
+pub const NV_ERR_GPU_IN_FULLCHIP_RESET: _bindgen_ty_4 = 16;
+pub const NV_ERR_GPU_NOT_FULL_POWER: _bindgen_ty_4 = 17;
+pub const NV_ERR_GPU_UUID_NOT_FOUND: _bindgen_ty_4 = 18;
+pub const NV_ERR_HOT_SWITCH: _bindgen_ty_4 = 19;
+pub const NV_ERR_I2C_ERROR: _bindgen_ty_4 = 20;
+pub const NV_ERR_I2C_SPEED_TOO_HIGH: _bindgen_ty_4 = 21;
+pub const NV_ERR_ILLEGAL_ACTION: _bindgen_ty_4 = 22;
+pub const NV_ERR_IN_USE: _bindgen_ty_4 = 23;
+pub const NV_ERR_INFLATE_COMPRESSED_DATA_FAILED: _bindgen_ty_4 = 24;
+pub const NV_ERR_INSERT_DUPLICATE_NAME: _bindgen_ty_4 = 25;
+pub const NV_ERR_INSUFFICIENT_RESOURCES: _bindgen_ty_4 = 26;
+pub const NV_ERR_INSUFFICIENT_PERMISSIONS: _bindgen_ty_4 = 27;
+pub const NV_ERR_INSUFFICIENT_POWER: _bindgen_ty_4 = 28;
+pub const NV_ERR_INVALID_ACCESS_TYPE: _bindgen_ty_4 = 29;
+pub const NV_ERR_INVALID_ADDRESS: _bindgen_ty_4 = 30;
+pub const NV_ERR_INVALID_ARGUMENT: _bindgen_ty_4 = 31;
+pub const NV_ERR_INVALID_BASE: _bindgen_ty_4 = 32;
+pub const NV_ERR_INVALID_CHANNEL: _bindgen_ty_4 = 33;
+pub const NV_ERR_INVALID_CLASS: _bindgen_ty_4 = 34;
+pub const NV_ERR_INVALID_CLIENT: _bindgen_ty_4 = 35;
+pub const NV_ERR_INVALID_COMMAND: _bindgen_ty_4 = 36;
+pub const NV_ERR_INVALID_DATA: _bindgen_ty_4 = 37;
+pub const NV_ERR_INVALID_DEVICE: _bindgen_ty_4 = 38;
+pub const NV_ERR_INVALID_DMA_SPECIFIER: _bindgen_ty_4 = 39;
+pub const NV_ERR_INVALID_EVENT: _bindgen_ty_4 = 40;
+pub const NV_ERR_INVALID_FLAGS: _bindgen_ty_4 = 41;
+pub const NV_ERR_INVALID_FUNCTION: _bindgen_ty_4 = 42;
+pub const NV_ERR_INVALID_HEAP: _bindgen_ty_4 = 43;
+pub const NV_ERR_INVALID_INDEX: _bindgen_ty_4 = 44;
+pub const NV_ERR_INVALID_IRQ_LEVEL: _bindgen_ty_4 = 45;
+pub const NV_ERR_INVALID_LIMIT: _bindgen_ty_4 = 46;
+pub const NV_ERR_INVALID_LOCK_STATE: _bindgen_ty_4 = 47;
+pub const NV_ERR_INVALID_METHOD: _bindgen_ty_4 = 48;
+pub const NV_ERR_INVALID_OBJECT: _bindgen_ty_4 = 49;
+pub const NV_ERR_INVALID_OBJECT_BUFFER: _bindgen_ty_4 = 50;
+pub const NV_ERR_INVALID_OBJECT_HANDLE: _bindgen_ty_4 = 51;
+pub const NV_ERR_INVALID_OBJECT_NEW: _bindgen_ty_4 = 52;
+pub const NV_ERR_INVALID_OBJECT_OLD: _bindgen_ty_4 = 53;
+pub const NV_ERR_INVALID_OBJECT_PARENT: _bindgen_ty_4 = 54;
+pub const NV_ERR_INVALID_OFFSET: _bindgen_ty_4 = 55;
+pub const NV_ERR_INVALID_OPERATION: _bindgen_ty_4 = 56;
+pub const NV_ERR_INVALID_OWNER: _bindgen_ty_4 = 57;
+pub const NV_ERR_INVALID_PARAM_STRUCT: _bindgen_ty_4 = 58;
+pub const NV_ERR_INVALID_PARAMETER: _bindgen_ty_4 = 59;
+pub const NV_ERR_INVALID_PATH: _bindgen_ty_4 = 60;
+pub const NV_ERR_INVALID_POINTER: _bindgen_ty_4 = 61;
+pub const NV_ERR_INVALID_REGISTRY_KEY: _bindgen_ty_4 = 62;
+pub const NV_ERR_INVALID_REQUEST: _bindgen_ty_4 = 63;
+pub const NV_ERR_INVALID_STATE: _bindgen_ty_4 = 64;
+pub const NV_ERR_INVALID_STRING_LENGTH: _bindgen_ty_4 = 65;
+pub const NV_ERR_INVALID_READ: _bindgen_ty_4 = 66;
+pub const NV_ERR_INVALID_WRITE: _bindgen_ty_4 = 67;
+pub const NV_ERR_INVALID_XLATE: _bindgen_ty_4 = 68;
+pub const NV_ERR_IRQ_NOT_FIRING: _bindgen_ty_4 = 69;
+pub const NV_ERR_IRQ_EDGE_TRIGGERED: _bindgen_ty_4 = 70;
+pub const NV_ERR_MEMORY_TRAINING_FAILED: _bindgen_ty_4 = 71;
+pub const NV_ERR_MISMATCHED_SLAVE: _bindgen_ty_4 = 72;
+pub const NV_ERR_MISMATCHED_TARGET: _bindgen_ty_4 = 73;
+pub const NV_ERR_MISSING_TABLE_ENTRY: _bindgen_ty_4 = 74;
+pub const NV_ERR_MODULE_LOAD_FAILED: _bindgen_ty_4 = 75;
+pub const NV_ERR_MORE_DATA_AVAILABLE: _bindgen_ty_4 = 76;
+pub const NV_ERR_MORE_PROCESSING_REQUIRED: _bindgen_ty_4 = 77;
+pub const NV_ERR_MULTIPLE_MEMORY_TYPES: _bindgen_ty_4 = 78;
+pub const NV_ERR_NO_FREE_FIFOS: _bindgen_ty_4 = 79;
+pub const NV_ERR_NO_INTR_PENDING: _bindgen_ty_4 = 80;
+pub const NV_ERR_NO_MEMORY: _bindgen_ty_4 = 81;
+pub const NV_ERR_NO_SUCH_DOMAIN: _bindgen_ty_4 = 82;
+pub const NV_ERR_NO_VALID_PATH: _bindgen_ty_4 = 83;
+pub const NV_ERR_NOT_COMPATIBLE: _bindgen_ty_4 = 84;
+pub const NV_ERR_NOT_READY: _bindgen_ty_4 = 85;
+pub const NV_ERR_NOT_SUPPORTED: _bindgen_ty_4 = 86;
+pub const NV_ERR_OBJECT_NOT_FOUND: _bindgen_ty_4 = 87;
+pub const NV_ERR_OBJECT_TYPE_MISMATCH: _bindgen_ty_4 = 88;
+pub const NV_ERR_OPERATING_SYSTEM: _bindgen_ty_4 = 89;
+pub const NV_ERR_OTHER_DEVICE_FOUND: _bindgen_ty_4 = 90;
+pub const NV_ERR_OUT_OF_RANGE: _bindgen_ty_4 = 91;
+pub const NV_ERR_OVERLAPPING_UVM_COMMIT: _bindgen_ty_4 = 92;
+pub const NV_ERR_PAGE_TABLE_NOT_AVAIL: _bindgen_ty_4 = 93;
+pub const NV_ERR_PID_NOT_FOUND: _bindgen_ty_4 = 94;
+pub const NV_ERR_PROTECTION_FAULT: _bindgen_ty_4 = 95;
+pub const NV_ERR_RC_ERROR: _bindgen_ty_4 = 96;
+pub const NV_ERR_REJECTED_VBIOS: _bindgen_ty_4 = 97;
+pub const NV_ERR_RESET_REQUIRED: _bindgen_ty_4 = 98;
+pub const NV_ERR_STATE_IN_USE: _bindgen_ty_4 = 99;
+pub const NV_ERR_SIGNAL_PENDING: _bindgen_ty_4 = 100;
+pub const NV_ERR_TIMEOUT: _bindgen_ty_4 = 101;
+pub const NV_ERR_TIMEOUT_RETRY: _bindgen_ty_4 = 102;
+pub const NV_ERR_TOO_MANY_PRIMARIES: _bindgen_ty_4 = 103;
+pub const NV_ERR_UVM_ADDRESS_IN_USE: _bindgen_ty_4 = 104;
+pub const NV_ERR_MAX_SESSION_LIMIT_REACHED: _bindgen_ty_4 = 105;
+pub const NV_ERR_LIB_RM_VERSION_MISMATCH: _bindgen_ty_4 = 106;
+pub const NV_ERR_PRIV_SEC_VIOLATION: _bindgen_ty_4 = 107;
+pub const NV_ERR_GPU_IN_DEBUG_MODE: _bindgen_ty_4 = 108;
+pub const NV_ERR_FEATURE_NOT_ENABLED: _bindgen_ty_4 = 109;
+pub const NV_ERR_RESOURCE_LOST: _bindgen_ty_4 = 110;
+pub const NV_ERR_PMU_NOT_READY: _bindgen_ty_4 = 111;
+pub const NV_ERR_FLCN_ERROR: _bindgen_ty_4 = 112;
+pub const NV_ERR_FATAL_ERROR: _bindgen_ty_4 = 113;
+pub const NV_ERR_MEMORY_ERROR: _bindgen_ty_4 = 114;
+pub const NV_ERR_INVALID_LICENSE: _bindgen_ty_4 = 115;
+pub const NV_ERR_NVLINK_INIT_ERROR: _bindgen_ty_4 = 116;
+pub const NV_ERR_NVLINK_MINION_ERROR: _bindgen_ty_4 = 117;
+pub const NV_ERR_NVLINK_CLOCK_ERROR: _bindgen_ty_4 = 118;
+pub const NV_ERR_NVLINK_TRAINING_ERROR: _bindgen_ty_4 = 119;
+pub const NV_ERR_NVLINK_CONFIGURATION_ERROR: _bindgen_ty_4 = 120;
+pub const NV_ERR_RISCV_ERROR: _bindgen_ty_4 = 121;
+pub const NV_ERR_FABRIC_MANAGER_NOT_PRESENT: _bindgen_ty_4 = 122;
+pub const NV_ERR_ALREADY_SIGNALLED: _bindgen_ty_4 = 123;
+pub const NV_ERR_QUEUE_TASK_SLOT_NOT_AVAILABLE: _bindgen_ty_4 = 124;
+pub const NV_ERR_KEY_ROTATION_IN_PROGRESS: _bindgen_ty_4 = 125;
+pub const NV_ERR_TEST_ONLY_CODE_NOT_ENABLED: _bindgen_ty_4 = 126;
+pub const NV_ERR_SECURE_BOOT_FAILED: _bindgen_ty_4 = 127;
+pub const NV_ERR_INSUFFICIENT_ZBC_ENTRY: _bindgen_ty_4 = 128;
+pub const NV_ERR_NVLINK_FABRIC_NOT_READY: _bindgen_ty_4 = 129;
+pub const NV_ERR_NVLINK_FABRIC_FAILURE: _bindgen_ty_4 = 130;
+pub const NV_ERR_GPU_MEMORY_ONLINING_FAILURE: _bindgen_ty_4 = 131;
+pub const NV_ERR_REDUCTION_MANAGER_NOT_AVAILABLE: _bindgen_ty_4 = 132;
+pub const NV_ERR_RESOURCE_RETIREMENT_ERROR: _bindgen_ty_4 = 134;
+pub const NV_WARN_HOT_SWITCH: _bindgen_ty_4 = 65537;
+pub const NV_WARN_INCORRECT_PERFMON_DATA: _bindgen_ty_4 = 65538;
+pub const NV_WARN_MISMATCHED_SLAVE: _bindgen_ty_4 = 65539;
+pub const NV_WARN_MISMATCHED_TARGET: _bindgen_ty_4 = 65540;
+pub const NV_WARN_MORE_PROCESSING_REQUIRED: _bindgen_ty_4 = 65541;
+pub const NV_WARN_NOTHING_TO_DO: _bindgen_ty_4 = 65542;
+pub const NV_WARN_NULL_OBJECT: _bindgen_ty_4 = 65543;
+pub const NV_WARN_OUT_OF_RANGE: _bindgen_ty_4 = 65544;
+pub type _bindgen_ty_4 = ffi::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone, MaybeZeroable)]
pub struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-04-05 20:05 ` John Hubbard
2026-03-25 12:13 ` [PATCH v3 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles Eliot Courtney
` (7 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add NvStatus enum that wraps the raw NV_STATUS u32 codes returned by RM
control RPCs.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/fw.rs | 401 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 401 insertions(+)
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 0c8a74f0e8ac..cb4bda253193 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -97,6 +97,407 @@ pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &Coherent<GspMem>, count: u32) {
pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =
num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX);
+/// Status code returned by GSP-RM RPCs.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub(crate) enum NvStatus {
+ Ok,
+ AlreadySignalled,
+ BrokenFb,
+ BufferTooSmall,
+ BusyRetry,
+ CallbackNotScheduled,
+ CardNotPresent,
+ CycleDetected,
+ DmaInUse,
+ DmaMemNotLocked,
+ DmaMemNotUnlocked,
+ DualLinkInuse,
+ EccError,
+ FabricManagerNotPresent,
+ FatalError,
+ FeatureNotEnabled,
+ FifoBadAccess,
+ FlcnError,
+ FreqNotSupported,
+ Generic,
+ GpuDmaNotInitialized,
+ GpuInDebugMode,
+ GpuInFullchipReset,
+ GpuIsLost,
+ GpuMemoryOnliningFailure,
+ GpuNotFullPower,
+ GpuUuidNotFound,
+ HotSwitch,
+ I2cError,
+ I2cSpeedTooHigh,
+ IllegalAction,
+ InUse,
+ InflateCompressedDataFailed,
+ InsertDuplicateName,
+ InsufficientPermissions,
+ InsufficientPower,
+ InsufficientResources,
+ InsufficientZbcEntry,
+ InvalidAccessType,
+ InvalidAddress,
+ InvalidArgument,
+ InvalidBase,
+ InvalidChannel,
+ InvalidClass,
+ InvalidClient,
+ InvalidCommand,
+ InvalidData,
+ InvalidDevice,
+ InvalidDmaSpecifier,
+ InvalidEvent,
+ InvalidFlags,
+ InvalidFunction,
+ InvalidHeap,
+ InvalidIndex,
+ InvalidIrqLevel,
+ InvalidLicense,
+ InvalidLimit,
+ InvalidLockState,
+ InvalidMethod,
+ InvalidObject,
+ InvalidObjectBuffer,
+ InvalidObjectHandle,
+ InvalidObjectNew,
+ InvalidObjectOld,
+ InvalidObjectParent,
+ InvalidOffset,
+ InvalidOperation,
+ InvalidOwner,
+ InvalidParamStruct,
+ InvalidParameter,
+ InvalidPath,
+ InvalidPointer,
+ InvalidRead,
+ InvalidRegistryKey,
+ InvalidRequest,
+ InvalidState,
+ InvalidStringLength,
+ InvalidWrite,
+ InvalidXlate,
+ IrqEdgeTriggered,
+ IrqNotFiring,
+ KeyRotationInProgress,
+ LibRmVersionMismatch,
+ MaxSessionLimitReached,
+ MemoryError,
+ MemoryTrainingFailed,
+ MismatchedSlave,
+ MismatchedTarget,
+ MissingTableEntry,
+ ModuleLoadFailed,
+ MoreDataAvailable,
+ MoreProcessingRequired,
+ MultipleMemoryTypes,
+ NoFreeFifos,
+ NoIntrPending,
+ NoMemory,
+ NoSuchDomain,
+ NoValidPath,
+ NotCompatible,
+ NotReady,
+ NotSupported,
+ NvlinkClockError,
+ NvlinkConfigurationError,
+ NvlinkFabricFailure,
+ NvlinkFabricNotReady,
+ NvlinkInitError,
+ NvlinkMinionError,
+ NvlinkTrainingError,
+ ObjectNotFound,
+ ObjectTypeMismatch,
+ OperatingSystem,
+ OtherDeviceFound,
+ OutOfRange,
+ OverlappingUvmCommit,
+ PageTableNotAvail,
+ PidNotFound,
+ PmuNotReady,
+ PrivSecViolation,
+ ProtectionFault,
+ QueueTaskSlotNotAvailable,
+ RcError,
+ ReductionManagerNotAvailable,
+ RejectedVbios,
+ ResetRequired,
+ ResourceLost,
+ ResourceRetirementError,
+ RiscvError,
+ SecureBootFailed,
+ SignalPending,
+ StateInUse,
+ TestOnlyCodeNotEnabled,
+ Timeout,
+ TimeoutRetry,
+ TooManyPrimaries,
+ UvmAddressInUse,
+ Unknown(u32),
+}
+
+impl From<NvStatus> for Result {
+ fn from(status: NvStatus) -> Self {
+ match status {
+ NvStatus::Ok => Ok(()),
+
+ NvStatus::BufferTooSmall | NvStatus::MoreDataAvailable => Err(EMSGSIZE),
+
+ NvStatus::BusyRetry
+ | NvStatus::DmaInUse
+ | NvStatus::DualLinkInuse
+ | NvStatus::GpuInFullchipReset
+ | NvStatus::InUse
+ | NvStatus::KeyRotationInProgress
+ | NvStatus::NotReady
+ | NvStatus::NvlinkFabricNotReady
+ | NvStatus::PmuNotReady
+ | NvStatus::StateInUse
+ | NvStatus::UvmAddressInUse => Err(EBUSY),
+
+ NvStatus::CardNotPresent
+ | NvStatus::FabricManagerNotPresent
+ | NvStatus::InvalidDevice
+ | NvStatus::ReductionManagerNotAvailable => Err(ENODEV),
+
+ NvStatus::FeatureNotEnabled
+ | NvStatus::FreqNotSupported
+ | NvStatus::NotSupported
+ | NvStatus::TestOnlyCodeNotEnabled => Err(ENOTSUPP),
+
+ NvStatus::GpuUuidNotFound
+ | NvStatus::MissingTableEntry
+ | NvStatus::NoSuchDomain
+ | NvStatus::NoValidPath
+ | NvStatus::ObjectNotFound => Err(ENOENT),
+
+ NvStatus::I2cSpeedTooHigh
+ | NvStatus::InvalidAccessType
+ | NvStatus::InvalidArgument
+ | NvStatus::InvalidBase
+ | NvStatus::InvalidChannel
+ | NvStatus::InvalidClass
+ | NvStatus::InvalidClient
+ | NvStatus::InvalidCommand
+ | NvStatus::InvalidData
+ | NvStatus::InvalidDmaSpecifier
+ | NvStatus::InvalidEvent
+ | NvStatus::InvalidFlags
+ | NvStatus::InvalidFunction
+ | NvStatus::InvalidHeap
+ | NvStatus::InvalidIndex
+ | NvStatus::InvalidIrqLevel
+ | NvStatus::InvalidLimit
+ | NvStatus::InvalidLockState
+ | NvStatus::InvalidMethod
+ | NvStatus::InvalidObject
+ | NvStatus::InvalidObjectBuffer
+ | NvStatus::InvalidObjectHandle
+ | NvStatus::InvalidObjectNew
+ | NvStatus::InvalidObjectOld
+ | NvStatus::InvalidObjectParent
+ | NvStatus::InvalidOffset
+ | NvStatus::InvalidOperation
+ | NvStatus::InvalidOwner
+ | NvStatus::InvalidParamStruct
+ | NvStatus::InvalidParameter
+ | NvStatus::InvalidPath
+ | NvStatus::InvalidRegistryKey
+ | NvStatus::InvalidRequest
+ | NvStatus::InvalidState
+ | NvStatus::InvalidStringLength
+ | NvStatus::InvalidXlate
+ | NvStatus::LibRmVersionMismatch
+ | NvStatus::MismatchedSlave
+ | NvStatus::MismatchedTarget
+ | NvStatus::MultipleMemoryTypes
+ | NvStatus::NotCompatible
+ | NvStatus::ObjectTypeMismatch
+ | NvStatus::OverlappingUvmCommit
+ | NvStatus::RejectedVbios => Err(EINVAL),
+
+ NvStatus::IllegalAction => Err(EPERM),
+
+ NvStatus::InsertDuplicateName => Err(EEXIST),
+
+ NvStatus::InsufficientPermissions
+ | NvStatus::InvalidLicense
+ | NvStatus::PrivSecViolation => Err(EACCES),
+
+ NvStatus::InsufficientResources | NvStatus::NoMemory | NvStatus::PageTableNotAvail => {
+ Err(ENOMEM)
+ }
+
+ NvStatus::InsufficientZbcEntry
+ | NvStatus::MaxSessionLimitReached
+ | NvStatus::NoFreeFifos
+ | NvStatus::QueueTaskSlotNotAvailable
+ | NvStatus::TooManyPrimaries => Err(ENOSPC),
+
+ NvStatus::InvalidAddress | NvStatus::InvalidPointer | NvStatus::ProtectionFault => {
+ Err(EFAULT)
+ }
+
+ NvStatus::MoreProcessingRequired | NvStatus::TimeoutRetry => Err(EAGAIN),
+
+ NvStatus::OutOfRange => Err(ERANGE),
+
+ NvStatus::PidNotFound => Err(ESRCH),
+
+ NvStatus::SignalPending => Err(EINTR),
+
+ NvStatus::Timeout => Err(ETIMEDOUT),
+
+ _ => Err(EIO),
+ }
+ }
+}
+
+impl From<u32> for NvStatus {
+ fn from(value: u32) -> Self {
+ match value {
+ bindings::NV_OK => Self::Ok,
+ bindings::NV_ERR_ALREADY_SIGNALLED => Self::AlreadySignalled,
+ bindings::NV_ERR_BROKEN_FB => Self::BrokenFb,
+ bindings::NV_ERR_BUFFER_TOO_SMALL => Self::BufferTooSmall,
+ bindings::NV_ERR_BUSY_RETRY => Self::BusyRetry,
+ bindings::NV_ERR_CALLBACK_NOT_SCHEDULED => Self::CallbackNotScheduled,
+ bindings::NV_ERR_CARD_NOT_PRESENT => Self::CardNotPresent,
+ bindings::NV_ERR_CYCLE_DETECTED => Self::CycleDetected,
+ bindings::NV_ERR_DMA_IN_USE => Self::DmaInUse,
+ bindings::NV_ERR_DMA_MEM_NOT_LOCKED => Self::DmaMemNotLocked,
+ bindings::NV_ERR_DMA_MEM_NOT_UNLOCKED => Self::DmaMemNotUnlocked,
+ bindings::NV_ERR_DUAL_LINK_INUSE => Self::DualLinkInuse,
+ bindings::NV_ERR_ECC_ERROR => Self::EccError,
+ bindings::NV_ERR_FABRIC_MANAGER_NOT_PRESENT => Self::FabricManagerNotPresent,
+ bindings::NV_ERR_FATAL_ERROR => Self::FatalError,
+ bindings::NV_ERR_FEATURE_NOT_ENABLED => Self::FeatureNotEnabled,
+ bindings::NV_ERR_FIFO_BAD_ACCESS => Self::FifoBadAccess,
+ bindings::NV_ERR_FLCN_ERROR => Self::FlcnError,
+ bindings::NV_ERR_FREQ_NOT_SUPPORTED => Self::FreqNotSupported,
+ bindings::NV_ERR_GENERIC => Self::Generic,
+ bindings::NV_ERR_GPU_DMA_NOT_INITIALIZED => Self::GpuDmaNotInitialized,
+ bindings::NV_ERR_GPU_IN_DEBUG_MODE => Self::GpuInDebugMode,
+ bindings::NV_ERR_GPU_IN_FULLCHIP_RESET => Self::GpuInFullchipReset,
+ bindings::NV_ERR_GPU_IS_LOST => Self::GpuIsLost,
+ bindings::NV_ERR_GPU_MEMORY_ONLINING_FAILURE => Self::GpuMemoryOnliningFailure,
+ bindings::NV_ERR_GPU_NOT_FULL_POWER => Self::GpuNotFullPower,
+ bindings::NV_ERR_GPU_UUID_NOT_FOUND => Self::GpuUuidNotFound,
+ bindings::NV_ERR_HOT_SWITCH => Self::HotSwitch,
+ bindings::NV_ERR_I2C_ERROR => Self::I2cError,
+ bindings::NV_ERR_I2C_SPEED_TOO_HIGH => Self::I2cSpeedTooHigh,
+ bindings::NV_ERR_ILLEGAL_ACTION => Self::IllegalAction,
+ bindings::NV_ERR_IN_USE => Self::InUse,
+ bindings::NV_ERR_INFLATE_COMPRESSED_DATA_FAILED => Self::InflateCompressedDataFailed,
+ bindings::NV_ERR_INSERT_DUPLICATE_NAME => Self::InsertDuplicateName,
+ bindings::NV_ERR_INSUFFICIENT_PERMISSIONS => Self::InsufficientPermissions,
+ bindings::NV_ERR_INSUFFICIENT_POWER => Self::InsufficientPower,
+ bindings::NV_ERR_INSUFFICIENT_RESOURCES => Self::InsufficientResources,
+ bindings::NV_ERR_INSUFFICIENT_ZBC_ENTRY => Self::InsufficientZbcEntry,
+ bindings::NV_ERR_INVALID_ACCESS_TYPE => Self::InvalidAccessType,
+ bindings::NV_ERR_INVALID_ADDRESS => Self::InvalidAddress,
+ bindings::NV_ERR_INVALID_ARGUMENT => Self::InvalidArgument,
+ bindings::NV_ERR_INVALID_BASE => Self::InvalidBase,
+ bindings::NV_ERR_INVALID_CHANNEL => Self::InvalidChannel,
+ bindings::NV_ERR_INVALID_CLASS => Self::InvalidClass,
+ bindings::NV_ERR_INVALID_CLIENT => Self::InvalidClient,
+ bindings::NV_ERR_INVALID_COMMAND => Self::InvalidCommand,
+ bindings::NV_ERR_INVALID_DATA => Self::InvalidData,
+ bindings::NV_ERR_INVALID_DEVICE => Self::InvalidDevice,
+ bindings::NV_ERR_INVALID_DMA_SPECIFIER => Self::InvalidDmaSpecifier,
+ bindings::NV_ERR_INVALID_EVENT => Self::InvalidEvent,
+ bindings::NV_ERR_INVALID_FLAGS => Self::InvalidFlags,
+ bindings::NV_ERR_INVALID_FUNCTION => Self::InvalidFunction,
+ bindings::NV_ERR_INVALID_HEAP => Self::InvalidHeap,
+ bindings::NV_ERR_INVALID_INDEX => Self::InvalidIndex,
+ bindings::NV_ERR_INVALID_IRQ_LEVEL => Self::InvalidIrqLevel,
+ bindings::NV_ERR_INVALID_LICENSE => Self::InvalidLicense,
+ bindings::NV_ERR_INVALID_LIMIT => Self::InvalidLimit,
+ bindings::NV_ERR_INVALID_LOCK_STATE => Self::InvalidLockState,
+ bindings::NV_ERR_INVALID_METHOD => Self::InvalidMethod,
+ bindings::NV_ERR_INVALID_OBJECT => Self::InvalidObject,
+ bindings::NV_ERR_INVALID_OBJECT_BUFFER => Self::InvalidObjectBuffer,
+ bindings::NV_ERR_INVALID_OBJECT_HANDLE => Self::InvalidObjectHandle,
+ bindings::NV_ERR_INVALID_OBJECT_NEW => Self::InvalidObjectNew,
+ bindings::NV_ERR_INVALID_OBJECT_OLD => Self::InvalidObjectOld,
+ bindings::NV_ERR_INVALID_OBJECT_PARENT => Self::InvalidObjectParent,
+ bindings::NV_ERR_INVALID_OFFSET => Self::InvalidOffset,
+ bindings::NV_ERR_INVALID_OPERATION => Self::InvalidOperation,
+ bindings::NV_ERR_INVALID_OWNER => Self::InvalidOwner,
+ bindings::NV_ERR_INVALID_PARAM_STRUCT => Self::InvalidParamStruct,
+ bindings::NV_ERR_INVALID_PARAMETER => Self::InvalidParameter,
+ bindings::NV_ERR_INVALID_PATH => Self::InvalidPath,
+ bindings::NV_ERR_INVALID_POINTER => Self::InvalidPointer,
+ bindings::NV_ERR_INVALID_READ => Self::InvalidRead,
+ bindings::NV_ERR_INVALID_REGISTRY_KEY => Self::InvalidRegistryKey,
+ bindings::NV_ERR_INVALID_REQUEST => Self::InvalidRequest,
+ bindings::NV_ERR_INVALID_STATE => Self::InvalidState,
+ bindings::NV_ERR_INVALID_STRING_LENGTH => Self::InvalidStringLength,
+ bindings::NV_ERR_INVALID_WRITE => Self::InvalidWrite,
+ bindings::NV_ERR_INVALID_XLATE => Self::InvalidXlate,
+ bindings::NV_ERR_IRQ_EDGE_TRIGGERED => Self::IrqEdgeTriggered,
+ bindings::NV_ERR_IRQ_NOT_FIRING => Self::IrqNotFiring,
+ bindings::NV_ERR_KEY_ROTATION_IN_PROGRESS => Self::KeyRotationInProgress,
+ bindings::NV_ERR_LIB_RM_VERSION_MISMATCH => Self::LibRmVersionMismatch,
+ bindings::NV_ERR_MAX_SESSION_LIMIT_REACHED => Self::MaxSessionLimitReached,
+ bindings::NV_ERR_MEMORY_ERROR => Self::MemoryError,
+ bindings::NV_ERR_MEMORY_TRAINING_FAILED => Self::MemoryTrainingFailed,
+ bindings::NV_ERR_MISMATCHED_SLAVE => Self::MismatchedSlave,
+ bindings::NV_ERR_MISMATCHED_TARGET => Self::MismatchedTarget,
+ bindings::NV_ERR_MISSING_TABLE_ENTRY => Self::MissingTableEntry,
+ bindings::NV_ERR_MODULE_LOAD_FAILED => Self::ModuleLoadFailed,
+ bindings::NV_ERR_MORE_DATA_AVAILABLE => Self::MoreDataAvailable,
+ bindings::NV_ERR_MORE_PROCESSING_REQUIRED => Self::MoreProcessingRequired,
+ bindings::NV_ERR_MULTIPLE_MEMORY_TYPES => Self::MultipleMemoryTypes,
+ bindings::NV_ERR_NO_FREE_FIFOS => Self::NoFreeFifos,
+ bindings::NV_ERR_NO_INTR_PENDING => Self::NoIntrPending,
+ bindings::NV_ERR_NO_MEMORY => Self::NoMemory,
+ bindings::NV_ERR_NO_SUCH_DOMAIN => Self::NoSuchDomain,
+ bindings::NV_ERR_NO_VALID_PATH => Self::NoValidPath,
+ bindings::NV_ERR_NOT_COMPATIBLE => Self::NotCompatible,
+ bindings::NV_ERR_NOT_READY => Self::NotReady,
+ bindings::NV_ERR_NOT_SUPPORTED => Self::NotSupported,
+ bindings::NV_ERR_NVLINK_CLOCK_ERROR => Self::NvlinkClockError,
+ bindings::NV_ERR_NVLINK_CONFIGURATION_ERROR => Self::NvlinkConfigurationError,
+ bindings::NV_ERR_NVLINK_FABRIC_FAILURE => Self::NvlinkFabricFailure,
+ bindings::NV_ERR_NVLINK_FABRIC_NOT_READY => Self::NvlinkFabricNotReady,
+ bindings::NV_ERR_NVLINK_INIT_ERROR => Self::NvlinkInitError,
+ bindings::NV_ERR_NVLINK_MINION_ERROR => Self::NvlinkMinionError,
+ bindings::NV_ERR_NVLINK_TRAINING_ERROR => Self::NvlinkTrainingError,
+ bindings::NV_ERR_OBJECT_NOT_FOUND => Self::ObjectNotFound,
+ bindings::NV_ERR_OBJECT_TYPE_MISMATCH => Self::ObjectTypeMismatch,
+ bindings::NV_ERR_OPERATING_SYSTEM => Self::OperatingSystem,
+ bindings::NV_ERR_OTHER_DEVICE_FOUND => Self::OtherDeviceFound,
+ bindings::NV_ERR_OUT_OF_RANGE => Self::OutOfRange,
+ bindings::NV_ERR_OVERLAPPING_UVM_COMMIT => Self::OverlappingUvmCommit,
+ bindings::NV_ERR_PAGE_TABLE_NOT_AVAIL => Self::PageTableNotAvail,
+ bindings::NV_ERR_PID_NOT_FOUND => Self::PidNotFound,
+ bindings::NV_ERR_PMU_NOT_READY => Self::PmuNotReady,
+ bindings::NV_ERR_PRIV_SEC_VIOLATION => Self::PrivSecViolation,
+ bindings::NV_ERR_PROTECTION_FAULT => Self::ProtectionFault,
+ bindings::NV_ERR_QUEUE_TASK_SLOT_NOT_AVAILABLE => Self::QueueTaskSlotNotAvailable,
+ bindings::NV_ERR_RC_ERROR => Self::RcError,
+ bindings::NV_ERR_REDUCTION_MANAGER_NOT_AVAILABLE => Self::ReductionManagerNotAvailable,
+ bindings::NV_ERR_REJECTED_VBIOS => Self::RejectedVbios,
+ bindings::NV_ERR_RESET_REQUIRED => Self::ResetRequired,
+ bindings::NV_ERR_RESOURCE_LOST => Self::ResourceLost,
+ bindings::NV_ERR_RESOURCE_RETIREMENT_ERROR => Self::ResourceRetirementError,
+ bindings::NV_ERR_RISCV_ERROR => Self::RiscvError,
+ bindings::NV_ERR_SECURE_BOOT_FAILED => Self::SecureBootFailed,
+ bindings::NV_ERR_SIGNAL_PENDING => Self::SignalPending,
+ bindings::NV_ERR_STATE_IN_USE => Self::StateInUse,
+ bindings::NV_ERR_TEST_ONLY_CODE_NOT_ENABLED => Self::TestOnlyCodeNotEnabled,
+ bindings::NV_ERR_TIMEOUT => Self::Timeout,
+ bindings::NV_ERR_TIMEOUT_RETRY => Self::TimeoutRetry,
+ bindings::NV_ERR_TOO_MANY_PRIMARIES => Self::TooManyPrimaries,
+ bindings::NV_ERR_UVM_ADDRESS_IN_USE => Self::UvmAddressInUse,
+ other => Self::Unknown(other),
+ }
+ }
+}
+
/// Empty type to group methods related to heap parameters for running the GSP firmware.
enum GspFwHeapParams {}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
` (6 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Expose the `hInternalClient` and `hInternalSubdevice` handles. These are
needed for RM control calls.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/commands.rs | 65 ++++++++++++++++++++++++++++++++
drivers/gpu/nova-core/gsp/fw/commands.rs | 19 +++++++++-
2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index c89c7b57a751..f3566f3ea6a7 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -4,6 +4,7 @@
array,
convert::Infallible,
ffi::FromBytesUntilNulError,
+ marker::PhantomData,
str::Utf8Error, //
};
@@ -34,6 +35,54 @@
sbuffer::SBufferIter,
};
+/// Marker type for a GSP-RM client handle.
+///
+/// A client handle identifies a client which provides a namespace for RM objects. Lookup of objects
+/// happens within the client namespace.
+pub(crate) struct Client;
+
+/// Marker type for a GSP-RM device handle.
+///
+/// A device handle identifies a logical GPU device instance under a client. In multi-GPU
+/// configurations it can represent a grouped or logical device.
+#[expect(dead_code)]
+pub(crate) struct Device;
+
+/// Marker type for a GSP-RM subdevice handle.
+///
+/// A subdevice handle identifies a child of a device that selects one specific GPU within that
+/// device.
+pub(crate) struct Subdevice;
+
+/// A typed GSP-RM object handle.
+///
+/// These handles form a tree structure with different types of RM objects, with client at the root.
+/// An RM object is anything identified by a valid handle. For example, the tree may look like
+/// Client -> Device -> Subdevice, where there may be multiple devices under each client, and
+/// multiple subdevices under each device.
+#[derive(Debug)]
+pub(crate) struct Handle<T>(u32, PhantomData<T>);
+
+impl<T> Clone for Handle<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+impl<T> Copy for Handle<T> {}
+
+impl<T> Handle<T> {
+ /// Creates a new handle from a raw value.
+ pub(crate) fn new(raw: u32) -> Self {
+ Self(raw, PhantomData)
+ }
+
+ /// Returns the raw handle value.
+ #[expect(dead_code)]
+ pub(crate) fn as_raw(self) -> u32 {
+ self.0
+ }
+}
+
/// The `GspSetSystemInfo` command.
pub(crate) struct SetSystemInfo<'a> {
pdev: &'a pci::Device<device::Bound>,
@@ -192,6 +241,8 @@ fn init(&self) -> impl Init<Self::Command, Self::InitError> {
/// The reply from the GSP to the [`GetGspInfo`] command.
pub(crate) struct GetGspStaticInfoReply {
gpu_name: [u8; 64],
+ client: Handle<Client>,
+ subdevice: Handle<Subdevice>,
}
impl MessageFromGsp for GetGspStaticInfoReply {
@@ -205,6 +256,8 @@ fn read(
) -> Result<Self, Self::InitError> {
Ok(GetGspStaticInfoReply {
gpu_name: msg.gpu_name_str(),
+ client: msg.client(),
+ subdevice: msg.subdevice(),
})
}
}
@@ -231,6 +284,18 @@ pub(crate) fn gpu_name(&self) -> core::result::Result<&str, GpuNameError> {
.to_str()
.map_err(GpuNameError::InvalidUtf8)
}
+
+ /// Returns the client handle allocated by GSP-RM.
+ #[expect(dead_code)]
+ pub(crate) fn client(&self) -> Handle<Client> {
+ self.client
+ }
+
+ /// Returns the subdevice handle allocated by GSP-RM.
+ #[expect(dead_code)]
+ pub(crate) fn subdevice(&self) -> Handle<Subdevice> {
+ self.subdevice
+ }
}
/// Send the [`GetGspInfo`] command and awaits for its reply.
diff --git a/drivers/gpu/nova-core/gsp/fw/commands.rs b/drivers/gpu/nova-core/gsp/fw/commands.rs
index db46276430be..9fce6ffefbce 100644
--- a/drivers/gpu/nova-core/gsp/fw/commands.rs
+++ b/drivers/gpu/nova-core/gsp/fw/commands.rs
@@ -10,7 +10,14 @@
}, //
};
-use crate::gsp::GSP_PAGE_SIZE;
+use crate::gsp::{
+ commands::{
+ Client,
+ Handle,
+ Subdevice, //
+ },
+ GSP_PAGE_SIZE, //
+};
use super::bindings;
@@ -121,6 +128,16 @@ impl GspStaticConfigInfo {
pub(crate) fn gpu_name_str(&self) -> [u8; 64] {
self.0.gpuNameString
}
+
+ /// Returns the client handle allocated by GSP-RM.
+ pub(crate) fn client(&self) -> Handle<Client> {
+ Handle::new(self.0.hInternalClient)
+ }
+
+ /// Returns the subdevice handle allocated by GSP-RM.
+ pub(crate) fn subdevice(&self) -> Handle<Subdevice> {
+ Handle::new(self.0.hInternalSubdevice)
+ }
}
// SAFETY: Padding is explicit and will not contain uninitialized data.
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 4/9] gpu: nova-core: gsp: add RM control RPC structure binding
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (2 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
` (5 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add the bindgen rpc_gsp_rm_control_v03_00 structure. This is the
structure for sending RM control commands.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index dd37a7fd58c6..05e205e6dc58 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -1025,6 +1025,17 @@ fn default() -> Self {
}
#[repr(C)]
#[derive(Debug, Default, MaybeZeroable)]
+pub struct rpc_gsp_rm_control_v03_00 {
+ pub hClient: u32_,
+ pub hObject: u32_,
+ pub cmd: u32_,
+ pub status: u32_,
+ pub paramsSize: u32_,
+ pub flags: u32_,
+ pub params: __IncompleteArrayField<u8_>,
+}
+#[repr(C)]
+#[derive(Debug, Default, MaybeZeroable)]
pub struct rpc_run_cpu_sequencer_v17_00 {
pub bufferSizeDWord: u32_,
pub cmdIndex: u32_,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 5/9] gpu: nova-core: gsp: add types for RM control RPCs
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (3 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
` (4 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add `RmControlMsgFunction` which mirrors `MsgFunction` in fw.rs. This
denotes the type of RM control RPC. For now it contains a single
discriminant only (which will be used later), which is needed to prevent
compile errors when using an otherwise empty enum.
Add `GspRmControl` which wraps the RM control RPC structure from the
bindings.
Reviewed-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/commands.rs | 1 -
drivers/gpu/nova-core/gsp/fw.rs | 1 +
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 1 +
drivers/gpu/nova-core/gsp/fw/rm.rs | 88 +++++++++++++++++++++++
4 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index f3566f3ea6a7..8c9599aa227b 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -77,7 +77,6 @@ pub(crate) fn new(raw: u32) -> Self {
}
/// Returns the raw handle value.
- #[expect(dead_code)]
pub(crate) fn as_raw(self) -> u32 {
self.0
}
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index cb4bda253193..bee7169fd4ae 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -2,6 +2,7 @@
pub(crate) mod commands;
mod r570_144;
+pub(crate) mod rm;
// Alias to avoid repeating the version number with every use.
use r570_144 as bindings;
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index 05e205e6dc58..ece31cc32f5b 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -44,6 +44,7 @@ fn fmt(&self, fmt: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
pub const GSP_FW_WPR_META_MAGIC: i64 = -2577556379034558285;
pub const REGISTRY_TABLE_ENTRY_TYPE_DWORD: u32 = 1;
pub const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: u32 = 65536;
+pub const NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE: u32 = 545270280;
pub type __u8 = ffi::c_uchar;
pub type __u16 = ffi::c_ushort;
pub type __u32 = ffi::c_uint;
diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
new file mode 100644
index 000000000000..4a4f97d88ecf
--- /dev/null
+++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+ prelude::*,
+ transmute::{
+ AsBytes,
+ FromBytes, //
+ }, //
+};
+
+use crate::gsp::commands::{
+ Client,
+ Handle, //
+};
+
+use super::{
+ bindings,
+ NvStatus, //
+};
+
+/// Command code for RM control RPCs sent using [`MsgFunction::GspRmControl`].
+#[derive(Copy, Clone, Debug, PartialEq)]
+#[repr(u32)]
+pub(crate) enum RmControlMsgFunction {
+ /// Get the CE fault method buffer size.
+ CeGetFaultMethodBufferSize = bindings::NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE,
+}
+
+// TODO[FPRI]: replace with 'FromPrimitive'.
+impl TryFrom<u32> for RmControlMsgFunction {
+ type Error = kernel::error::Error;
+
+ fn try_from(value: u32) -> Result<Self> {
+ match value {
+ bindings::NV2080_CTRL_CMD_CE_GET_FAULT_METHOD_BUFFER_SIZE => {
+ Ok(Self::CeGetFaultMethodBufferSize)
+ }
+ _ => Err(EINVAL),
+ }
+ }
+}
+
+impl From<RmControlMsgFunction> for u32 {
+ fn from(value: RmControlMsgFunction) -> Self {
+ // CAST: `RmControlMsgFunction` is `repr(u32)` and can thus be cast losslessly.
+ value as u32
+ }
+}
+
+/// RM control message element structure.
+#[repr(transparent)]
+pub(crate) struct GspRmControl {
+ inner: bindings::rpc_gsp_rm_control_v03_00,
+}
+
+#[expect(dead_code)]
+impl GspRmControl {
+ /// Creates a new RM control command.
+ pub(crate) fn new<T>(
+ client: Handle<Client>,
+ object: Handle<T>,
+ cmd: RmControlMsgFunction,
+ params_size: u32,
+ ) -> Self {
+ Self {
+ inner: bindings::rpc_gsp_rm_control_v03_00 {
+ hClient: client.as_raw(),
+ hObject: object.as_raw(),
+ cmd: u32::from(cmd),
+ status: 0,
+ paramsSize: params_size,
+ flags: 0,
+ params: Default::default(),
+ },
+ }
+ }
+
+ /// Returns the status from the RM control response.
+ pub(crate) fn status(&self) -> NvStatus {
+ NvStatus::from(self.inner.status)
+ }
+}
+
+// SAFETY: This struct only contains integer types for which all bit patterns are valid.
+unsafe impl FromBytes for GspRmControl {}
+
+// SAFETY: This struct contains no padding.
+unsafe impl AsBytes for GspRmControl {}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 6/9] gpu: nova-core: use KVVec for SBufferIter flush
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (4 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (3 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Change flush_into_kvec to return KVVec instead of KVec. KVVec uses
vmalloc for large allocations, which is appropriate since RPC reply
payloads can be large (>=20 KiB).
Update GspSequence to use KVVec accordingly.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/sequencer.rs | 4 ++--
drivers/gpu/nova-core/sbuffer.rs | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs
index 474e4c8021db..c8f587d2d57b 100644
--- a/drivers/gpu/nova-core/gsp/sequencer.rs
+++ b/drivers/gpu/nova-core/gsp/sequencer.rs
@@ -42,7 +42,7 @@ struct GspSequence {
/// Current command index for error reporting.
cmd_index: u32,
/// Command data buffer containing the sequence of commands.
- cmd_data: KVec<u8>,
+ cmd_data: KVVec<u8>,
}
impl MessageFromGsp for GspSequence {
@@ -54,7 +54,7 @@ fn read(
msg: &Self::Message,
sbuffer: &mut SBufferIter<array::IntoIter<&[u8], 2>>,
) -> Result<Self, Self::InitError> {
- let cmd_data = sbuffer.flush_into_kvec(GFP_KERNEL)?;
+ let cmd_data = sbuffer.read_to_vec(GFP_KERNEL)?;
Ok(GspSequence {
cmd_index: msg.cmd_index(),
cmd_data,
diff --git a/drivers/gpu/nova-core/sbuffer.rs b/drivers/gpu/nova-core/sbuffer.rs
index 3a41d224c77a..ae2facdcbdd4 100644
--- a/drivers/gpu/nova-core/sbuffer.rs
+++ b/drivers/gpu/nova-core/sbuffer.rs
@@ -162,11 +162,11 @@ pub(crate) fn read_exact(&mut self, mut dst: &mut [u8]) -> Result {
Ok(())
}
- /// Read all the remaining data into a [`KVec`].
+ /// Read all the remaining data into a [`KVVec`].
///
/// `self` will be empty after this operation.
- pub(crate) fn flush_into_kvec(&mut self, flags: kernel::alloc::Flags) -> Result<KVec<u8>> {
- let mut buf = KVec::<u8>::new();
+ pub(crate) fn read_to_vec(&mut self, flags: kernel::alloc::Flags) -> Result<KVVec<u8>> {
+ let mut buf = KVVec::<u8>::new();
if let Some(slice) = core::mem::take(&mut self.cur_slice) {
buf.extend_from_slice(slice, flags)?;
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (5 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings Eliot Courtney
` (2 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add `RawRmControl` which implements CommandToGsp for sending RM control
RPCs. Add `RmControlReply` which implements MessageFromGsp for getting
the reply back. Add the `RmControlCommand` trait for defining an RM
control message.
Add `RmControl` which sends an RM control RPC via the command queue
using the above structures.
This gives a generic way to send each RM control RPC. Each new RM
control RPC can be added by extending RmControlMsgFunction, adding its
bindings wrappers and writing an implementation of `RmControlCommand`
that can be sent using `RmControl`.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp.rs | 1 +
drivers/gpu/nova-core/gsp/fw/rm.rs | 1 -
drivers/gpu/nova-core/gsp/rm.rs | 3 +
drivers/gpu/nova-core/gsp/rm/commands.rs | 141 +++++++++++++++++++++++++++++++
4 files changed, 145 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 04e3976127cc..09d6e673aa65 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -21,6 +21,7 @@
pub(crate) mod cmdq;
pub(crate) mod commands;
mod fw;
+pub(crate) mod rm;
mod sequencer;
pub(crate) use fw::{
diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
index 4a4f97d88ecf..1c6e8b4c4865 100644
--- a/drivers/gpu/nova-core/gsp/fw/rm.rs
+++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
@@ -53,7 +53,6 @@ pub(crate) struct GspRmControl {
inner: bindings::rpc_gsp_rm_control_v03_00,
}
-#[expect(dead_code)]
impl GspRmControl {
/// Creates a new RM control command.
pub(crate) fn new<T>(
diff --git a/drivers/gpu/nova-core/gsp/rm.rs b/drivers/gpu/nova-core/gsp/rm.rs
new file mode 100644
index 000000000000..10e879a3e842
--- /dev/null
+++ b/drivers/gpu/nova-core/gsp/rm.rs
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+
+pub(crate) mod commands;
diff --git a/drivers/gpu/nova-core/gsp/rm/commands.rs b/drivers/gpu/nova-core/gsp/rm/commands.rs
new file mode 100644
index 000000000000..8845ca0a0225
--- /dev/null
+++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use core::array;
+
+use kernel::prelude::*;
+
+use crate::{
+ driver::Bar0,
+ gsp::{
+ cmdq::{
+ Cmdq,
+ CommandToGsp,
+ MessageFromGsp, //
+ },
+ commands::{
+ Client,
+ Handle, //
+ },
+ fw::{
+ rm::*,
+ MsgFunction,
+ NvStatus, //
+ },
+ },
+ sbuffer::SBufferIter, //
+};
+
+/// Wraps a [`RmControl`] command to provide the infrastructure for sending it on the command queue.
+struct RawRmControl<'a, T>(&'a RmControl<T>)
+where
+ T: RmControlCommand;
+
+impl<'a, T: RmControlCommand> CommandToGsp for RawRmControl<'a, T> {
+ const FUNCTION: MsgFunction = MsgFunction::GspRmControl;
+ type Command = GspRmControl;
+ type Reply = RmControlReply;
+ type InitError = Error;
+
+ fn init(&self) -> impl Init<Self::Command, Self::InitError> {
+ let params_size: u32 = T::LEN.try_into()?;
+ Ok(GspRmControl::new(
+ self.0.client,
+ self.0.object,
+ T::FUNCTION,
+ params_size,
+ ))
+ }
+
+ fn variable_payload_len(&self) -> usize {
+ T::LEN
+ }
+
+ fn init_variable_payload(
+ &self,
+ dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>,
+ ) -> Result {
+ self.0.cmd.write_payload(dst)
+ }
+}
+
+/// Command for sending an RM control message to the GSP.
+///
+/// RM control messages are used to query or control RM objects (see [`Handle`] for more info on RM
+/// objects). It takes a client handle and an RM object handle identifying the target of the
+/// message, within the given client.
+pub(crate) struct RmControl<T>
+where
+ T: RmControlCommand,
+{
+ /// The client handle under which `object` is allocated.
+ client: Handle<Client>,
+ /// The RM object handle to query or control.
+ object: Handle<T::Target>,
+ /// The specific RM control command to send.
+ cmd: T,
+}
+
+#[expect(unused)]
+impl<T: RmControlCommand> RmControl<T> {
+ /// Creates a new RM control command.
+ pub(crate) fn new(client: Handle<Client>, object: Handle<T::Target>, cmd: T) -> Self {
+ Self {
+ client,
+ object,
+ cmd,
+ }
+ }
+
+ /// Sends an RM control command, checks the reply status, and returns the reply.
+ pub(crate) fn send(self, cmdq: &Cmdq, bar: &Bar0) -> Result<T::Reply> {
+ let reply = cmdq.send_command(bar, RawRmControl(&self))?;
+
+ Result::from(reply.status)?;
+
+ self.cmd.parse_reply(&reply.params)
+ }
+}
+
+/// Response from an RM control message.
+struct RmControlReply {
+ status: NvStatus,
+ params: KVVec<u8>,
+}
+
+impl MessageFromGsp for RmControlReply {
+ const FUNCTION: MsgFunction = MsgFunction::GspRmControl;
+ type Message = GspRmControl;
+ type InitError = Error;
+
+ fn read(
+ msg: &Self::Message,
+ sbuffer: &mut SBufferIter<array::IntoIter<&[u8], 2>>,
+ ) -> Result<Self, Self::InitError> {
+ Ok(RmControlReply {
+ status: msg.status(),
+ params: sbuffer.read_to_vec(GFP_KERNEL)?,
+ })
+ }
+}
+
+/// Trait for RM control commands that can be sent using [`RmControl`].
+pub(crate) trait RmControlCommand {
+ /// The specific RM control message kind to send.
+ const FUNCTION: RmControlMsgFunction;
+
+ /// Length of the command-specific payload to send with the RM control message.
+ const LEN: usize;
+
+ /// The type of the reply after parsing the raw bytes from the RM control reply message.
+ type Reply;
+
+ /// The type of the RM object that this command targets.
+ type Target;
+
+ /// Writes the payload of the command into `dst`.
+ fn write_payload(&self, dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>) -> Result;
+
+ /// Parses the reply bytes from an RM control reply message into the command-specific
+ /// reply type.
+ fn parse_reply(&self, params: &[u8]) -> Result<Self::Reply>;
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (6 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command Eliot Courtney
2026-04-05 19:48 ` [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure John Hubbard
9 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add the bindings for CE fault method buffer size RM control RPC. This
will be needed for channel allocation and is also a simple way to
demonstrate the usage of the RM control infrastructure for now.
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
index ece31cc32f5b..354ee2cfa295 100644
--- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
+++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
@@ -1025,6 +1025,11 @@ fn default() -> Self {
}
}
#[repr(C)]
+#[derive(Debug, Default, Copy, Clone, MaybeZeroable)]
+pub struct NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS {
+ pub size: u32_,
+}
+#[repr(C)]
#[derive(Debug, Default, MaybeZeroable)]
pub struct rpc_gsp_rm_control_v03_00 {
pub hClient: u32_,
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (7 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings Eliot Courtney
@ 2026-03-25 12:13 ` Eliot Courtney
2026-04-05 20:12 ` John Hubbard
2026-04-05 19:48 ` [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure John Hubbard
9 siblings, 1 reply; 18+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter
Cc: John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Eliot Courtney
Add `CeGetFaultMethodBufferSizeParams` which wraps the bindings.
Add `FaultMethodBufferSize` RM control command which returns the fault
method buffer size we should use. This is needed for channel allocation.
Finally, print out the fault method buffer size on GSP boot.
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/boot.rs | 11 +++++++++++
drivers/gpu/nova-core/gsp/commands.rs | 2 --
drivers/gpu/nova-core/gsp/fw/rm.rs | 25 ++++++++++++++++++++---
drivers/gpu/nova-core/gsp/rm/commands.rs | 34 ++++++++++++++++++++++++++++----
4 files changed, 63 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index e55210ebb6d1..8a4ad4c6ea98 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -33,6 +33,10 @@
gpu::Chipset,
gsp::{
commands,
+ rm::commands::{
+ FaultMethodBufferSize,
+ RmControl, //
+ },
sequencer::{
GspSequencer,
GspSequencerParams, //
@@ -232,6 +236,13 @@ pub(crate) fn boot(
Err(e) => dev_warn!(pdev, "GPU name unavailable: {:?}\n", e),
}
+ match RmControl::new(info.client(), info.subdevice(), FaultMethodBufferSize)
+ .send(&self.cmdq, bar)
+ {
+ Ok(size) => dev_info!(pdev, "Fault method buffer size: {} bytes\n", size),
+ Err(e) => dev_warn!(pdev, "Failed to get fault method buffer size: {:?}\n", e),
+ }
+
Ok(())
}
}
diff --git a/drivers/gpu/nova-core/gsp/commands.rs b/drivers/gpu/nova-core/gsp/commands.rs
index 8c9599aa227b..56655bade9ab 100644
--- a/drivers/gpu/nova-core/gsp/commands.rs
+++ b/drivers/gpu/nova-core/gsp/commands.rs
@@ -285,13 +285,11 @@ pub(crate) fn gpu_name(&self) -> core::result::Result<&str, GpuNameError> {
}
/// Returns the client handle allocated by GSP-RM.
- #[expect(dead_code)]
pub(crate) fn client(&self) -> Handle<Client> {
self.client
}
/// Returns the subdevice handle allocated by GSP-RM.
- #[expect(dead_code)]
pub(crate) fn subdevice(&self) -> Handle<Subdevice> {
self.subdevice
}
diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
index 1c6e8b4c4865..73913541d9d4 100644
--- a/drivers/gpu/nova-core/gsp/fw/rm.rs
+++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
@@ -8,9 +8,12 @@
}, //
};
-use crate::gsp::commands::{
- Client,
- Handle, //
+use crate::{
+ gsp::commands::{
+ Client,
+ Handle, //
+ },
+ num, //
};
use super::{
@@ -85,3 +88,19 @@ unsafe impl FromBytes for GspRmControl {}
// SAFETY: This struct contains no padding.
unsafe impl AsBytes for GspRmControl {}
+
+/// Wrapper for [`bindings::NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS`].
+#[repr(transparent)]
+pub(crate) struct CeGetFaultMethodBufferSizeParams(
+ bindings::NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS,
+);
+
+impl CeGetFaultMethodBufferSizeParams {
+ /// Returns the CE fault method buffer size in bytes.
+ pub(crate) fn size(&self) -> usize {
+ num::u32_as_usize(self.0.size)
+ }
+}
+
+// SAFETY: This struct only contains integer types for which all bit patterns are valid.
+unsafe impl FromBytes for CeGetFaultMethodBufferSizeParams {}
diff --git a/drivers/gpu/nova-core/gsp/rm/commands.rs b/drivers/gpu/nova-core/gsp/rm/commands.rs
index 8845ca0a0225..de290f4845f4 100644
--- a/drivers/gpu/nova-core/gsp/rm/commands.rs
+++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
@@ -1,8 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
-use core::array;
+use core::{
+ array,
+ mem::size_of, //
+};
-use kernel::prelude::*;
+use kernel::{
+ prelude::*,
+ transmute::FromBytes, //
+};
use crate::{
driver::Bar0,
@@ -14,7 +20,8 @@
},
commands::{
Client,
- Handle, //
+ Handle,
+ Subdevice, //
},
fw::{
rm::*,
@@ -75,7 +82,6 @@ pub(crate) struct RmControl<T>
cmd: T,
}
-#[expect(unused)]
impl<T: RmControlCommand> RmControl<T> {
/// Creates a new RM control command.
pub(crate) fn new(client: Handle<Client>, object: Handle<T::Target>, cmd: T) -> Self {
@@ -139,3 +145,23 @@ pub(crate) trait RmControlCommand {
/// reply type.
fn parse_reply(&self, params: &[u8]) -> Result<Self::Reply>;
}
+
+/// RM control command for querying the fault method buffer size. This is required for setting up
+/// channels.
+pub(crate) struct FaultMethodBufferSize;
+
+impl RmControlCommand for FaultMethodBufferSize {
+ const FUNCTION: RmControlMsgFunction = RmControlMsgFunction::CeGetFaultMethodBufferSize;
+ const LEN: usize = size_of::<CeGetFaultMethodBufferSizeParams>();
+ type Reply = usize;
+ type Target = Subdevice;
+
+ fn write_payload(&self, dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>) -> Result {
+ dst.write_all(&[0u8; Self::LEN])
+ }
+
+ fn parse_reply(&self, params: &[u8]) -> Result<Self::Reply> {
+ let reply = CeGetFaultMethodBufferSizeParams::from_bytes(params).ok_or(EINVAL)?;
+ Ok(reply.size())
+ }
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (8 preceding siblings ...)
2026-03-25 12:13 ` [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command Eliot Courtney
@ 2026-04-05 19:48 ` John Hubbard
2026-04-06 2:29 ` Eliot Courtney
9 siblings, 1 reply; 18+ messages in thread
From: John Hubbard @ 2026-04-05 19:48 UTC (permalink / raw)
To: Eliot Courtney, Danilo Krummrich, Alice Ryhl, Alexandre Courbot,
David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On 3/25/26 5:13 AM, Eliot Courtney wrote:
> Add the infrastructure for sending RM control RPCs. This is needed e.g.
> for channel allocation.
>
> This series adds:
> - `NV_STATUS` bindings and wrapping `NvStatus` enum (used by RM control
> RPCs)
> - The necessary bindings for the RM control RPCs.
> - `RmControlMsgFunction` to identify individual control commands, like
> `MsgFunction` for GSP commands.
> - `SBufferIter::read_to_vec` (using KVVec) for reading large RPC payloads
> - A typed `RmControl` command that can send RM control commands.
> - One usage of `RmControl`: the `FaultMethodBufferSize`
> RPC. This is useful for channel allocation later.
>
> Each new RM control command can be added by extending
> `RmControlMsgFunction`, adding the bindings and wrappers for their
> parameters, and writing a type-safe wrapper to send and receive the
> reply for the RM control rpc, using `RmControl`.
>
> This series applies on latest drm-rust-next with the listed
> pre-requisites.
Hi Eliot,
Nice clean series, I appreciate the work that went into making
it easily reviewable!
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings
2026-03-25 12:13 ` [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
@ 2026-04-05 19:55 ` John Hubbard
2026-04-06 8:54 ` Eliot Courtney
0 siblings, 1 reply; 18+ messages in thread
From: John Hubbard @ 2026-04-05 19:55 UTC (permalink / raw)
To: Eliot Courtney, Danilo Krummrich, Alice Ryhl, Alexandre Courbot,
David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On 3/25/26 5:13 AM, Eliot Courtney wrote:
> Add bindgen generated constants for NV_STATUS. This is used for RM
> control messages.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
> ---
> drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 144 ++++++++++++++++++++++
> 1 file changed, 144 insertions(+)
>
> diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> index 334e8be5fde8..dd37a7fd58c6 100644
> --- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> +++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
> @@ -379,6 +379,150 @@ pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS {
> pub __bindgen_padding_0: [u8; 4usize],
> pub fbRegion: [NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; 16usize],
> }
> +pub const NV_OK: _bindgen_ty_4 = 0;
> +pub const NV_ERR_GENERIC: _bindgen_ty_4 = 65535;
...
> +pub const NV_ERR_RESOURCE_RETIREMENT_ERROR: _bindgen_ty_4 = 134;
> +pub const NV_WARN_HOT_SWITCH: _bindgen_ty_4 = 65537;
> +pub const NV_WARN_INCORRECT_PERFMON_DATA: _bindgen_ty_4 = 65538;
If we go with pulling these ERR_ and WARN_ items in directly
from GSP-RM, then we should also update Alistair's bindgen
helper, or my fork of it:
https://github.com/apopple-nvidia/nova-gsp-binding-generator/commits/main/
https://github.com/johnhubbard/nova-gsp-binding-generator/commits/main
However, the deeper problem is that the C headers define these as
#defines, so bindgen emits pub const u32 items. The hand-written
NvStatus enum in patch 2 has no compile-time relationship to them. When
Open RM adds a new code, the Rust enum silently absorbs it into
Unknown(u32) -> Err(EIO) with no compiler diagnostic.
Which brings us back to a feature that Alex Courbot and Danilo have been
asking for, and I've been treating as "nice to have, maybe next month"
for apparently too long. And that is, generating Rust bindings directly
from the GSP-RM build system.
I think it's time, yes?
> +pub const NV_WARN_MISMATCHED_SLAVE: _bindgen_ty_4 = 65539;
> +pub const NV_WARN_MISMATCHED_TARGET: _bindgen_ty_4 = 65540;
> +pub const NV_WARN_MORE_PROCESSING_REQUIRED: _bindgen_ty_4 = 65541;
> +pub const NV_WARN_NOTHING_TO_DO: _bindgen_ty_4 = 65542;
> +pub const NV_WARN_NULL_OBJECT: _bindgen_ty_4 = 65543;
> +pub const NV_WARN_OUT_OF_RANGE: _bindgen_ty_4 = 65544;
> +pub type _bindgen_ty_4 = ffi::c_uint;
> #[repr(C)]
> #[derive(Debug, Copy, Clone, MaybeZeroable)]
> pub struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
>
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors
2026-03-25 12:13 ` [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
@ 2026-04-05 20:05 ` John Hubbard
2026-04-06 12:09 ` Eliot Courtney
0 siblings, 1 reply; 18+ messages in thread
From: John Hubbard @ 2026-04-05 20:05 UTC (permalink / raw)
To: Eliot Courtney, Danilo Krummrich, Alice Ryhl, Alexandre Courbot,
David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On 3/25/26 5:13 AM, Eliot Courtney wrote:
> Add NvStatus enum that wraps the raw NV_STATUS u32 codes returned by RM
> control RPCs.
>
> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
> ---
> drivers/gpu/nova-core/gsp/fw.rs | 401 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 401 insertions(+)
>
> diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
> index 0c8a74f0e8ac..cb4bda253193 100644
> --- a/drivers/gpu/nova-core/gsp/fw.rs
> +++ b/drivers/gpu/nova-core/gsp/fw.rs
> @@ -97,6 +97,407 @@ pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &Coherent<GspMem>, count: u32) {
> pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =
> num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX);
>
> +/// Status code returned by GSP-RM RPCs.
> +#[derive(Copy, Clone, Debug, PartialEq, Eq)]
> +pub(crate) enum NvStatus {
> + Ok,
As mentioned in my respose to patch 1, these are hand-written and won't
automatically pick up anything new from bindgen(1).
If for some reason we don't go directly to generating Rust bindings from
GSP-RM builds, then we could somewhat mitigate the problem with a
declarative macro that generates the enum, the From<u32> impl, and the
From<NvStatus> for Result impl from a single table.
That would at least prevent internal drift between the three, but it
still would not detect new binding constants.
It would also add yet another macro, sigh.
> + AlreadySignalled,
> + BrokenFb,
...
> + Unknown(u32),
> +}
> +
> +impl From<NvStatus> for Result {
> + fn from(status: NvStatus) -> Self {
This discards the NvStatus variant. The caller sees only a kernel errno.
We need to retain the rich RM error codes for debugging. For example,
a caller that gets Err(ENODEV) cannot tell whether RM returned
CardNotPresent, InvalidDevice, FabricManagerNotPresent, or
ReductionManagerNotAvailable. Something like:
fn send(self, ...) -> Result<T::Reply, NvStatus>
would let the caller log or match on the original status, and convert
to errno only when propagating upward.
> + match status {
> + NvStatus::Ok => Ok(()),
...
> +
> + NvStatus::Timeout => Err(ETIMEDOUT),
> +
> + _ => Err(EIO),
This will cause failures for NV_WARN_* items, which is a problem.
RM warnings should not be converted into errors.
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command
2026-03-25 12:13 ` [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command Eliot Courtney
@ 2026-04-05 20:12 ` John Hubbard
2026-04-06 2:30 ` Eliot Courtney
0 siblings, 1 reply; 18+ messages in thread
From: John Hubbard @ 2026-04-05 20:12 UTC (permalink / raw)
To: Eliot Courtney, Danilo Krummrich, Alice Ryhl, Alexandre Courbot,
David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On 3/25/26 5:13 AM, Eliot Courtney wrote:
...
> Err(e) => dev_warn!(pdev, "GPU name unavailable: {:?}\n", e),
> }
>
> + match RmControl::new(info.client(), info.subdevice(), FaultMethodBufferSize)
> + .send(&self.cmdq, bar)
> + {
> + Ok(size) => dev_info!(pdev, "Fault method buffer size: {} bytes\n", size),
> + Err(e) => dev_warn!(pdev, "Failed to get fault method buffer size: {:?}\n", e),
We are in Gsp::boot(). Errors here should be fatal.
So there are a couple of options: either don't invoke a non-critical RM
control during boot(), or else if it is critical, then call it from a
more appropriate place.
thanks,
--
John Hubbard
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-04-05 19:48 ` [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure John Hubbard
@ 2026-04-06 2:29 ` Eliot Courtney
0 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-04-06 2:29 UTC (permalink / raw)
To: John Hubbard, Eliot Courtney, Danilo Krummrich, Alice Ryhl,
Alexandre Courbot, David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On Mon Apr 6, 2026 at 4:48 AM JST, John Hubbard wrote:
> On 3/25/26 5:13 AM, Eliot Courtney wrote:
>> Add the infrastructure for sending RM control RPCs. This is needed e.g.
>> for channel allocation.
>>
>> This series adds:
>> - `NV_STATUS` bindings and wrapping `NvStatus` enum (used by RM control
>> RPCs)
>> - The necessary bindings for the RM control RPCs.
>> - `RmControlMsgFunction` to identify individual control commands, like
>> `MsgFunction` for GSP commands.
>> - `SBufferIter::read_to_vec` (using KVVec) for reading large RPC payloads
>> - A typed `RmControl` command that can send RM control commands.
>> - One usage of `RmControl`: the `FaultMethodBufferSize`
>> RPC. This is useful for channel allocation later.
>>
>> Each new RM control command can be added by extending
>> `RmControlMsgFunction`, adding the bindings and wrappers for their
>> parameters, and writing a type-safe wrapper to send and receive the
>> reply for the RM control rpc, using `RmControl`.
>>
>> This series applies on latest drm-rust-next with the listed
>> pre-requisites.
>
> Hi Eliot,
>
> Nice clean series, I appreciate the work that went into making
> it easily reviewable!
>
>
> thanks,
Thanks a lot John, and thanks for the reviews.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command
2026-04-05 20:12 ` John Hubbard
@ 2026-04-06 2:30 ` Eliot Courtney
0 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-04-06 2:30 UTC (permalink / raw)
To: John Hubbard, Eliot Courtney, Danilo Krummrich, Alice Ryhl,
Alexandre Courbot, David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On Mon Apr 6, 2026 at 5:12 AM JST, John Hubbard wrote:
> On 3/25/26 5:13 AM, Eliot Courtney wrote:
> ...
>> Err(e) => dev_warn!(pdev, "GPU name unavailable: {:?}\n", e),
>> }
>>
>> + match RmControl::new(info.client(), info.subdevice(), FaultMethodBufferSize)
>> + .send(&self.cmdq, bar)
>> + {
>> + Ok(size) => dev_info!(pdev, "Fault method buffer size: {} bytes\n", size),
>> + Err(e) => dev_warn!(pdev, "Failed to get fault method buffer size: {:?}\n", e),
>
> We are in Gsp::boot(). Errors here should be fatal.
>
> So there are a couple of options: either don't invoke a non-critical RM
> control during boot(), or else if it is critical, then call it from a
> more appropriate place.
>
> thanks,
We should change the code right before this which does the same thing (ignoring
errors) to print out general GPU info then, IMO.
I think it would be fine to drop this patch as well, it mostly exists
just to show how the RM control infra is called.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings
2026-04-05 19:55 ` John Hubbard
@ 2026-04-06 8:54 ` Eliot Courtney
0 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-04-06 8:54 UTC (permalink / raw)
To: John Hubbard, Eliot Courtney, Danilo Krummrich, Alice Ryhl,
Alexandre Courbot, David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On Mon Apr 6, 2026 at 4:55 AM JST, John Hubbard wrote:
> On 3/25/26 5:13 AM, Eliot Courtney wrote:
>> Add bindgen generated constants for NV_STATUS. This is used for RM
>> control messages.
>>
>> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs | 144 ++++++++++++++++++++++
>> 1 file changed, 144 insertions(+)
>>
>> diff --git a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
>> index 334e8be5fde8..dd37a7fd58c6 100644
>> --- a/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
>> +++ b/drivers/gpu/nova-core/gsp/fw/r570_144/bindings.rs
>> @@ -379,6 +379,150 @@ pub struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS {
>> pub __bindgen_padding_0: [u8; 4usize],
>> pub fbRegion: [NV2080_CTRL_CMD_FB_GET_FB_REGION_FB_REGION_INFO; 16usize],
>> }
>> +pub const NV_OK: _bindgen_ty_4 = 0;
>> +pub const NV_ERR_GENERIC: _bindgen_ty_4 = 65535;
> ...
>> +pub const NV_ERR_RESOURCE_RETIREMENT_ERROR: _bindgen_ty_4 = 134;
>> +pub const NV_WARN_HOT_SWITCH: _bindgen_ty_4 = 65537;
>> +pub const NV_WARN_INCORRECT_PERFMON_DATA: _bindgen_ty_4 = 65538;
>
> If we go with pulling these ERR_ and WARN_ items in directly
> from GSP-RM, then we should also update Alistair's bindgen
> helper, or my fork of it:
>
> https://github.com/apopple-nvidia/nova-gsp-binding-generator/commits/main/
> https://github.com/johnhubbard/nova-gsp-binding-generator/commits/main
Yep, I have local changes to these which I will send. These bindings
updates were all generated based on Alistair's bindgen helper.
> However, the deeper problem is that the C headers define these as
> #defines, so bindgen emits pub const u32 items. The hand-written
> NvStatus enum in patch 2 has no compile-time relationship to them. When
> Open RM adds a new code, the Rust enum silently absorbs it into
> Unknown(u32) -> Err(EIO) with no compiler diagnostic.
Yes, this is unfortunate, although we still need to manually think about
the mapping at some point.
One thing I can try is to remove the Unknown(u32) variant here and use
TryFrom (which we will end up using with FromPrimitive later) - then
at least we will get errors if a new discriminant is added.
>
> Which brings us back to a feature that Alex Courbot and Danilo have been
> asking for, and I've been treating as "nice to have, maybe next month"
> for apparently too long. And that is, generating Rust bindings directly
> from the GSP-RM build system.
Sounds good to me as long as we can generate this mapping at the same
time and have it fail if a new one is added.
> I think it's time, yes?
What would this look like / any agreement on what the shape of this
would look like yet?
>
>> +pub const NV_WARN_MISMATCHED_SLAVE: _bindgen_ty_4 = 65539;
>> +pub const NV_WARN_MISMATCHED_TARGET: _bindgen_ty_4 = 65540;
>> +pub const NV_WARN_MORE_PROCESSING_REQUIRED: _bindgen_ty_4 = 65541;
>> +pub const NV_WARN_NOTHING_TO_DO: _bindgen_ty_4 = 65542;
>> +pub const NV_WARN_NULL_OBJECT: _bindgen_ty_4 = 65543;
>> +pub const NV_WARN_OUT_OF_RANGE: _bindgen_ty_4 = 65544;
>> +pub type _bindgen_ty_4 = ffi::c_uint;
>> #[repr(C)]
>> #[derive(Debug, Copy, Clone, MaybeZeroable)]
>> pub struct NV2080_CTRL_GPU_GET_GID_INFO_PARAMS {
>>
>
> thanks,
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors
2026-04-05 20:05 ` John Hubbard
@ 2026-04-06 12:09 ` Eliot Courtney
0 siblings, 0 replies; 18+ messages in thread
From: Eliot Courtney @ 2026-04-06 12:09 UTC (permalink / raw)
To: John Hubbard, Eliot Courtney, Danilo Krummrich, Alice Ryhl,
Alexandre Courbot, David Airlie, Simona Vetter
Cc: Alistair Popple, Joel Fernandes, Timur Tabi, rust-for-linux,
dri-devel, linux-kernel
On Mon Apr 6, 2026 at 5:05 AM JST, John Hubbard wrote:
> On 3/25/26 5:13 AM, Eliot Courtney wrote:
>> Add NvStatus enum that wraps the raw NV_STATUS u32 codes returned by RM
>> control RPCs.
>>
>> Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
>> ---
>> drivers/gpu/nova-core/gsp/fw.rs | 401 ++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 401 insertions(+)
>>
>> diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
>> index 0c8a74f0e8ac..cb4bda253193 100644
>> --- a/drivers/gpu/nova-core/gsp/fw.rs
>> +++ b/drivers/gpu/nova-core/gsp/fw.rs
>> @@ -97,6 +97,407 @@ pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &Coherent<GspMem>, count: u32) {
>> pub(crate) const GSP_MSG_QUEUE_ELEMENT_SIZE_MAX: usize =
>> num::u32_as_usize(bindings::GSP_MSG_QUEUE_ELEMENT_SIZE_MAX);
>>
>> +/// Status code returned by GSP-RM RPCs.
>> +#[derive(Copy, Clone, Debug, PartialEq, Eq)]
>> +pub(crate) enum NvStatus {
>> + Ok,
>
> As mentioned in my respose to patch 1, these are hand-written and won't
> automatically pick up anything new from bindgen(1).
>
> If for some reason we don't go directly to generating Rust bindings from
> GSP-RM builds, then we could somewhat mitigate the problem with a
> declarative macro that generates the enum, the From<u32> impl, and the
> From<NvStatus> for Result impl from a single table.
>
> That would at least prevent internal drift between the three, but it
> still would not detect new binding constants.
>
> It would also add yet another macro, sigh.
Yeah I feel we have a lot of macros. But, at least for From<u32> we can
use FromPrimitive once that is ready (see my other email, maybe better
for me to switch it to TryFrom and get rid of Unknown). As for the
mapping, we have to think about it manually somewhere, so either it's
here in a From<> impl, or it's in the bindings generator or upstream of
that.
>
>> + AlreadySignalled,
>> + BrokenFb,
> ...
>> + Unknown(u32),
>> +}
>> +
>> +impl From<NvStatus> for Result {
>> + fn from(status: NvStatus) -> Self {
>
> This discards the NvStatus variant. The caller sees only a kernel errno.
> We need to retain the rich RM error codes for debugging. For example,
> a caller that gets Err(ENODEV) cannot tell whether RM returned
> CardNotPresent, InvalidDevice, FabricManagerNotPresent, or
> ReductionManagerNotAvailable. Something like:
>
> fn send(self, ...) -> Result<T::Reply, NvStatus>
>
> would let the caller log or match on the original status, and convert
> to errno only when propagating upward.
SGTM, let me push NvStatus handling a bit up the caller chain then.
I was thinking it might be nice to not carry the openrm naming, and
instead call it e.g. GspMsgRmStatus.
But, I don't think we should use it as is as the error variant of
Result, because it contains 'Ok'. A better shape might be:
GspMsgRmStatus {Ok, Warning(GspMsgRmWarning), Error(GspMsgRmError)}
Another issue is that RmControl::send needs to also propagate the
kernel::error::Error from calling the cmdq. So we would need a wrapping
enum, e.g. enum GspRpcError {Transport(Error), Rm(GspMsgRmError)}. The
(currently unchecked) rpc_result field that comes back from GSP messages
can contain NV_STATUS values (as well as some other ones), so
probably Cmdq should be returning this too.
So if we are fine to just log warnings instead of surfacing them to the
caller, we could do:
fn send(...) -> Result<T::Reply, GspRpcError>
WDYT?
If we go this direction, I might create another patch series for
defining GspRpcError and adding support to Cmdq for returning that,
based on the RPC header's `rpc_result`, since we need to pass that
through here for RM control.
>
>> + match status {
>> + NvStatus::Ok => Ok(()),
> ...
>> +
>> + NvStatus::Timeout => Err(ETIMEDOUT),
>> +
>> + _ => Err(EIO),
>
> This will cause failures for NV_WARN_* items, which is a problem.
> RM warnings should not be converted into errors.
Do you reckon we will want to do anything other than just log the
warning?
>
> thanks,
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-04-06 12:09 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-25 12:13 [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
2026-04-05 19:55 ` John Hubbard
2026-04-06 8:54 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
2026-04-05 20:05 ` John Hubbard
2026-04-06 12:09 ` Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings Eliot Courtney
2026-03-25 12:13 ` [PATCH v3 9/9] gpu: nova-core: gsp: add FaultMethodBufferSize RM control command Eliot Courtney
2026-04-05 20:12 ` John Hubbard
2026-04-06 2:30 ` Eliot Courtney
2026-04-05 19:48 ` [PATCH v3 0/9] gpu: nova-core: gsp: add RM control command infrastructure John Hubbard
2026-04-06 2:29 ` Eliot Courtney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox