* [PATCH v2 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
@ 2026-03-18 7:13 ` Eliot Courtney
2026-03-20 4:10 ` Alistair Popple
2026-03-18 7:13 ` [PATCH v2 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
` (7 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7: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] 21+ messages in thread* Re: [PATCH v2 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings
2026-03-18 7:13 ` [PATCH v2 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
@ 2026-03-20 4:10 ` Alistair Popple
0 siblings, 0 replies; 21+ messages in thread
From: Alistair Popple @ 2026-03-20 4:10 UTC (permalink / raw)
To: Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter, John Hubbard, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
The sooner bindgen goes away the better, but for now can you make sure to send a
pull request to https://github.com/apopple-nvidia/nova-gsp-binding-generator so
everyone can regenerate these if needed? Thanks!
- Alistair
On 2026-03-18 at 18:13 +1100, Eliot Courtney <ecourtney@nvidia.com> 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_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 [flat|nested] 21+ messages in thread
* [PATCH v2 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-18 7:13 ` [PATCH v2 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
@ 2026-03-18 7:13 ` Eliot Courtney
2026-03-18 7:13 ` [PATCH v2 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles Eliot Courtney
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7: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 a061131b5412..37831034ec3e 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -112,6 +112,407 @@ pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &CoherentAllocation<GspMem>, cou
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] 21+ messages in thread* [PATCH v2 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
2026-03-18 7:13 ` [PATCH v2 1/9] gpu: nova-core: gsp: add NV_STATUS error code bindings Eliot Courtney
2026-03-18 7:13 ` [PATCH v2 2/9] gpu: nova-core: gsp: add NvStatus enum for RM control errors Eliot Courtney
@ 2026-03-18 7:13 ` Eliot Courtney
2026-03-18 7:14 ` [PATCH v2 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7: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] 21+ messages in thread* [PATCH v2 4/9] gpu: nova-core: gsp: add RM control RPC structure binding
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (2 preceding siblings ...)
2026-03-18 7:13 ` [PATCH v2 3/9] gpu: nova-core: gsp: expose GSP-RM internal client and subdevice handles Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-20 4:19 ` Alistair Popple
2026-03-18 7:14 ` [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
` (4 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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] 21+ messages in thread* Re: [PATCH v2 4/9] gpu: nova-core: gsp: add RM control RPC structure binding
2026-03-18 7:14 ` [PATCH v2 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
@ 2026-03-20 4:19 ` Alistair Popple
0 siblings, 0 replies; 21+ messages in thread
From: Alistair Popple @ 2026-03-20 4:19 UTC (permalink / raw)
To: Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter, John Hubbard, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
Same comment as for patch 1, although feel free to do it all as one pull
request/commit.
On 2026-03-18 at 18:14 +1100, Eliot Courtney <ecourtney@nvidia.com> wrote...
> 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 [flat|nested] 21+ messages in thread
* [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (3 preceding siblings ...)
2026-03-18 7:14 ` [PATCH v2 4/9] gpu: nova-core: gsp: add RM control RPC structure binding Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-20 4:26 ` Alistair Popple
2026-03-18 7:14 ` [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
` (3 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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.
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 37831034ec3e..8cbe90ce8271 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] 21+ messages in thread* Re: [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs
2026-03-18 7:14 ` [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
@ 2026-03-20 4:26 ` Alistair Popple
0 siblings, 0 replies; 21+ messages in thread
From: Alistair Popple @ 2026-03-20 4:26 UTC (permalink / raw)
To: Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter, John Hubbard, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
On 2026-03-18 at 18:14 +1100, Eliot Courtney <ecourtney@nvidia.com> wrote...
> 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.
>
> 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 37831034ec3e..8cbe90ce8271 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;
I'm sure you can guess my comment here based on my comments for patch 1 and 4 :-)
I wonder if it would be better to just add all the bindings in one patch at the
start of the series?
Everything else here looked sensible to me and my limited experience though, so:
Reviewed-by: Alistair Popple <apopple@nvidia.com>
> 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 [flat|nested] 21+ messages in thread
* [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (4 preceding siblings ...)
2026-03-18 7:14 ` [PATCH v2 5/9] gpu: nova-core: gsp: add types for RM control RPCs Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-20 4:32 ` Alistair Popple
2026-03-18 7:14 ` [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (2 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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] 21+ messages in thread* Re: [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush
2026-03-18 7:14 ` [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
@ 2026-03-20 4:32 ` Alistair Popple
2026-03-25 7:43 ` Eliot Courtney
0 siblings, 1 reply; 21+ messages in thread
From: Alistair Popple @ 2026-03-20 4:32 UTC (permalink / raw)
To: Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter, John Hubbard, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
On 2026-03-18 at 18:14 +1100, Eliot Courtney <ecourtney@nvidia.com> wrote...
> 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).
Out of curiosity do you know if there is any upper limit on payload size?
And is there any concern about performance of vmalloc() vs. kmalloc() for RPC
messages?
> 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 [flat|nested] 21+ messages in thread* Re: [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush
2026-03-20 4:32 ` Alistair Popple
@ 2026-03-25 7:43 ` Eliot Courtney
0 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-25 7:43 UTC (permalink / raw)
To: Alistair Popple, Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, Alexandre Courbot, David Airlie,
Simona Vetter, John Hubbard, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
On Fri Mar 20, 2026 at 1:32 PM JST, Alistair Popple wrote:
> On 2026-03-18 at 18:14 +1100, Eliot Courtney <ecourtney@nvidia.com> wrote...
>> 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).
>
> Out of curiosity do you know if there is any upper limit on payload size?
IIRC the largest one I saw in openrm was a few hundred KiB.
Theoretically, the largest complete payload you could have in a single
message is ~64 KiB since we don't support continuation records on the
receive path.
>
> And is there any concern about performance of vmalloc() vs. kmalloc() for RPC
> messages?
`KVVec` uses `KVmalloc` which tries `Kmalloc` first. Most of the time,
`Kmalloc` should work. So this shouldn't regress performance really in
the common case, and it's required for the longer RPCs.
>
>> 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 [flat|nested] 21+ messages in thread
* [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (5 preceding siblings ...)
2026-03-18 7:14 ` [PATCH v2 6/9] gpu: nova-core: use KVVec for SBufferIter flush Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-18 12:35 ` Danilo Krummrich
2026-03-18 7:14 ` [PATCH v2 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings Eliot Courtney
2026-03-18 7:14 ` [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command Eliot Courtney
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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, Zhi Wang
Add `RmControl` which implements CommandToGsp for sending RM control
RPCs.
Add `RmControlReply` which implements MessageFromGsp for getting the
reply back.
Add `send_rm_control` 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 and adding
its bindings wrappers and writing a helper function to send it via
`send_rm_control`.
Tested-by: Zhi Wang <zhiw@nvidia.com>
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 | 118 +++++++++++++++++++++++++++++++
4 files changed, 122 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 72f173726f87..14c734c53e7c 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -17,6 +17,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..5a3ac7bd415a
--- /dev/null
+++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use core::{
+ array,
+ convert::Infallible, //
+};
+
+use kernel::prelude::*;
+
+use crate::{
+ driver::Bar0,
+ gsp::{
+ cmdq::{
+ Cmdq,
+ CommandToGsp,
+ MessageFromGsp, //
+ },
+ commands::{
+ Client,
+ Handle, //
+ },
+ fw::{
+ rm::*,
+ MsgFunction,
+ NvStatus, //
+ },
+ },
+ sbuffer::SBufferIter,
+};
+
+/// 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.
+struct RmControl<'a, T> {
+ /// The client handle under which `object` is allocated.
+ client: Handle<Client>,
+ /// The RM object handle to query or control.
+ object: Handle<T>,
+ /// The specific control message to send.
+ cmd: RmControlMsgFunction,
+ /// The raw parameter bytes to send with the control message. Interpretation of these bytes is
+ /// specific to the control message being sent.
+ params: &'a [u8],
+}
+
+impl<'a, T> RmControl<'a, T> {
+ /// Creates a new RM control command.
+ #[expect(dead_code)]
+ fn new(
+ client: Handle<Client>,
+ object: Handle<T>,
+ cmd: RmControlMsgFunction,
+ params: &'a [u8],
+ ) -> Self {
+ Self {
+ client,
+ object,
+ cmd,
+ params,
+ }
+ }
+}
+
+impl<T> CommandToGsp for RmControl<'_, T> {
+ const FUNCTION: MsgFunction = MsgFunction::GspRmControl;
+ type Command = GspRmControl;
+ type Reply = RmControlReply;
+ type InitError = Infallible;
+
+ fn init(&self) -> impl Init<Self::Command, Self::InitError> {
+ GspRmControl::new(self.client, self.object, self.cmd, self.params.len() as u32)
+ }
+
+ fn variable_payload_len(&self) -> usize {
+ self.params.len()
+ }
+
+ fn init_variable_payload(
+ &self,
+ dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>,
+ ) -> Result {
+ dst.write_all(self.params)
+ }
+}
+
+/// Response from an RM control message.
+pub(crate) 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)?,
+ })
+ }
+}
+
+/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
+#[expect(dead_code)]
+fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
+ let reply = cmdq.send_command(bar, cmd)?;
+
+ Result::from(reply.status)?;
+
+ Ok(reply.params)
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-18 7:14 ` [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
@ 2026-03-18 12:35 ` Danilo Krummrich
2026-03-19 1:06 ` Eliot Courtney
0 siblings, 1 reply; 21+ messages in thread
From: Danilo Krummrich @ 2026-03-18 12:35 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alice Ryhl, Alexandre Courbot, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Zhi Wang
On Wed Mar 18, 2026 at 8:14 AM CET, Eliot Courtney wrote:
> Add `RmControl` which implements CommandToGsp for sending RM control
> RPCs.
>
> Add `RmControlReply` which implements MessageFromGsp for getting the
> reply back.
>
> Add `send_rm_control` 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 and adding
> its bindings wrappers and writing a helper function to send it via
> `send_rm_control`.
>
> Tested-by: Zhi Wang <zhiw@nvidia.com>
> 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 | 118 +++++++++++++++++++++++++++++++
> 4 files changed, 122 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
> index 72f173726f87..14c734c53e7c 100644
> --- a/drivers/gpu/nova-core/gsp.rs
> +++ b/drivers/gpu/nova-core/gsp.rs
> @@ -17,6 +17,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..5a3ac7bd415a
> --- /dev/null
> +++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
> @@ -0,0 +1,118 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +use core::{
> + array,
> + convert::Infallible, //
> +};
> +
> +use kernel::prelude::*;
> +
> +use crate::{
> + driver::Bar0,
> + gsp::{
> + cmdq::{
> + Cmdq,
> + CommandToGsp,
> + MessageFromGsp, //
> + },
> + commands::{
> + Client,
> + Handle, //
> + },
> + fw::{
> + rm::*,
> + MsgFunction,
> + NvStatus, //
> + },
> + },
> + sbuffer::SBufferIter,
> +};
> +
> +/// 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.
> +struct RmControl<'a, T> {
> + /// The client handle under which `object` is allocated.
> + client: Handle<Client>,
> + /// The RM object handle to query or control.
> + object: Handle<T>,
> + /// The specific control message to send.
> + cmd: RmControlMsgFunction,
> + /// The raw parameter bytes to send with the control message. Interpretation of these bytes is
> + /// specific to the control message being sent.
> + params: &'a [u8],
> +}
> +
> +impl<'a, T> RmControl<'a, T> {
> + /// Creates a new RM control command.
> + #[expect(dead_code)]
> + fn new(
> + client: Handle<Client>,
> + object: Handle<T>,
> + cmd: RmControlMsgFunction,
> + params: &'a [u8],
> + ) -> Self {
> + Self {
> + client,
> + object,
> + cmd,
> + params,
> + }
> + }
> +}
> +
> +impl<T> CommandToGsp for RmControl<'_, T> {
> + const FUNCTION: MsgFunction = MsgFunction::GspRmControl;
> + type Command = GspRmControl;
> + type Reply = RmControlReply;
> + type InitError = Infallible;
> +
> + fn init(&self) -> impl Init<Self::Command, Self::InitError> {
> + GspRmControl::new(self.client, self.object, self.cmd, self.params.len() as u32)
> + }
> +
> + fn variable_payload_len(&self) -> usize {
> + self.params.len()
> + }
> +
> + fn init_variable_payload(
> + &self,
> + dst: &mut SBufferIter<array::IntoIter<&mut [u8], 2>>,
> + ) -> Result {
> + dst.write_all(self.params)
> + }
> +}
> +
> +/// Response from an RM control message.
> +pub(crate) 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)?,
> + })
> + }
> +}
> +
> +/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
> +#[expect(dead_code)]
> +fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
> + let reply = cmdq.send_command(bar, cmd)?;
> +
> + Result::from(reply.status)?;
> +
> + Ok(reply.params)
> +}
It still feels wrong to me for this to be a standalone function.
It should either be a method of Cmdq, or it should be a method of RmControl,
that takes self by value, i.e. either Cmdq::send_rm_ctrl() or RmControl::send().
Please choose one of those options.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-18 12:35 ` Danilo Krummrich
@ 2026-03-19 1:06 ` Eliot Courtney
2026-03-20 14:42 ` Alexandre Courbot
0 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-19 1:06 UTC (permalink / raw)
To: Danilo Krummrich, Eliot Courtney
Cc: Alice Ryhl, Alexandre Courbot, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Zhi Wang
On Wed Mar 18, 2026 at 9:35 PM JST, Danilo Krummrich wrote:
>> +/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
>> +#[expect(dead_code)]
>> +fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
>> + let reply = cmdq.send_command(bar, cmd)?;
>> +
>> + Result::from(reply.status)?;
>> +
>> + Ok(reply.params)
>> +}
>
> It still feels wrong to me for this to be a standalone function.
>
> It should either be a method of Cmdq, or it should be a method of RmControl,
> that takes self by value, i.e. either Cmdq::send_rm_ctrl() or RmControl::send().
>
> Please choose one of those options.
RmControl::send() seems good to me, will do that one.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-19 1:06 ` Eliot Courtney
@ 2026-03-20 14:42 ` Alexandre Courbot
2026-03-25 3:28 ` Eliot Courtney
0 siblings, 1 reply; 21+ messages in thread
From: Alexandre Courbot @ 2026-03-20 14:42 UTC (permalink / raw)
To: Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Zhi Wang
On Thu Mar 19, 2026 at 10:06 AM JST, Eliot Courtney wrote:
> On Wed Mar 18, 2026 at 9:35 PM JST, Danilo Krummrich wrote:
>>> +/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
>>> +#[expect(dead_code)]
>>> +fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
>>> + let reply = cmdq.send_command(bar, cmd)?;
>>> +
>>> + Result::from(reply.status)?;
>>> +
>>> + Ok(reply.params)
>>> +}
>>
>> It still feels wrong to me for this to be a standalone function.
>>
>> It should either be a method of Cmdq, or it should be a method of RmControl,
>> that takes self by value, i.e. either Cmdq::send_rm_ctrl() or RmControl::send().
>>
>> Please choose one of those options.
>
> RmControl::send() seems good to me, will do that one.
Honestly if we can just extend `Cmdq` with a RM-dedicated impl block in
`rm.rs` and make these regular `Cmdq` methods, why are we jumping
through hoops?
RM commands are one kind of command, I don't see why they need to be
sent through an associated function that takes a `Cmdq` as the first
argument anyway.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure
2026-03-20 14:42 ` Alexandre Courbot
@ 2026-03-25 3:28 ` Eliot Courtney
0 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-25 3:28 UTC (permalink / raw)
To: Alexandre Courbot, Eliot Courtney
Cc: Danilo Krummrich, Alice Ryhl, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel, Zhi Wang
On Fri Mar 20, 2026 at 11:42 PM JST, Alexandre Courbot wrote:
> On Thu Mar 19, 2026 at 10:06 AM JST, Eliot Courtney wrote:
>> On Wed Mar 18, 2026 at 9:35 PM JST, Danilo Krummrich wrote:
>>>> +/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
>>>> +#[expect(dead_code)]
>>>> +fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
>>>> + let reply = cmdq.send_command(bar, cmd)?;
>>>> +
>>>> + Result::from(reply.status)?;
>>>> +
>>>> + Ok(reply.params)
>>>> +}
>>>
>>> It still feels wrong to me for this to be a standalone function.
>>>
>>> It should either be a method of Cmdq, or it should be a method of RmControl,
>>> that takes self by value, i.e. either Cmdq::send_rm_ctrl() or RmControl::send().
>>>
>>> Please choose one of those options.
>>
>> RmControl::send() seems good to me, will do that one.
>
> Honestly if we can just extend `Cmdq` with a RM-dedicated impl block in
> `rm.rs` and make these regular `Cmdq` methods, why are we jumping
> through hoops?
>
> RM commands are one kind of command, I don't see why they need to be
> sent through an associated function that takes a `Cmdq` as the first
> argument anyway.
I posted my reason for not wanting to do this here[1]. But TLDR is that
these RM control commands are built on top of the Cmdq transport. They
don't need visibility into the Cmdq implementation; they're at a higher
level of abstraction. But let me think if there is a nicer way to do all
of this.
[1]: https://lore.kernel.org/all/DH46ZI0CRRKZ.1UZTS1TIWPRTQ@nvidia.com/
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (6 preceding siblings ...)
2026-03-18 7:14 ` [PATCH v2 7/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-18 7:14 ` [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command Eliot Courtney
8 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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 `send_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] 21+ messages in thread* [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
2026-03-18 7:13 [PATCH v2 0/9] gpu: nova-core: gsp: add RM control command infrastructure Eliot Courtney
` (7 preceding siblings ...)
2026-03-18 7:14 ` [PATCH v2 8/9] gpu: nova-core: gsp: add CE fault method buffer size bindings Eliot Courtney
@ 2026-03-18 7:14 ` Eliot Courtney
2026-03-20 13:27 ` Danilo Krummrich
8 siblings, 1 reply; 21+ messages in thread
From: Eliot Courtney @ 2026-03-18 7:14 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 `get_ce_fault_method_buffer_size` which sends the RM control RPC
and returns the buffer size. This is needed for channel allocation.
Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
drivers/gpu/nova-core/gsp/fw/rm.rs | 16 +++++++++++++
drivers/gpu/nova-core/gsp/rm/commands.rs | 39 ++++++++++++++++++++++++++++----
2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
index 1c6e8b4c4865..561f358ec4f1 100644
--- a/drivers/gpu/nova-core/gsp/fw/rm.rs
+++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
@@ -85,3 +85,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) -> u32 {
+ 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 5a3ac7bd415a..05a8cfae385c 100644
--- a/drivers/gpu/nova-core/gsp/rm/commands.rs
+++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
@@ -2,10 +2,14 @@
use core::{
array,
- convert::Infallible, //
+ convert::Infallible,
+ mem::size_of, //
};
-use kernel::prelude::*;
+use kernel::{
+ prelude::*,
+ transmute::FromBytes, //
+};
use crate::{
driver::Bar0,
@@ -17,7 +21,8 @@
},
commands::{
Client,
- Handle, //
+ Handle,
+ Subdevice, //
},
fw::{
rm::*,
@@ -47,7 +52,6 @@ struct RmControl<'a, T> {
impl<'a, T> RmControl<'a, T> {
/// Creates a new RM control command.
- #[expect(dead_code)]
fn new(
client: Handle<Client>,
object: Handle<T>,
@@ -108,7 +112,6 @@ fn read(
}
/// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
-#[expect(dead_code)]
fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
let reply = cmdq.send_command(bar, cmd)?;
@@ -116,3 +119,29 @@ fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<
Ok(reply.params)
}
+
+/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
+///
+/// Returns the CE fault method buffer size in bytes.
+#[expect(dead_code)]
+pub(crate) fn get_ce_fault_method_buffer_size(
+ cmdq: &Cmdq,
+ bar: &Bar0,
+ client: Handle<Client>,
+ subdevice: Handle<Subdevice>,
+) -> Result<u32> {
+ // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
+ let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
+
+ let cmd = RmControl::new(
+ client,
+ subdevice,
+ RmControlMsgFunction::CeGetFaultMethodBufferSize,
+ &req,
+ );
+ let reply = send_rm_control(cmdq, bar, cmd)?;
+
+ let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
+
+ Ok(params.size())
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 21+ messages in thread* Re: [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
2026-03-18 7:14 ` [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command Eliot Courtney
@ 2026-03-20 13:27 ` Danilo Krummrich
2026-03-25 12:13 ` Eliot Courtney
0 siblings, 1 reply; 21+ messages in thread
From: Danilo Krummrich @ 2026-03-20 13:27 UTC (permalink / raw)
To: Eliot Courtney
Cc: Alice Ryhl, Alexandre Courbot, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
On Wed Mar 18, 2026 at 8:14 AM CET, Eliot Courtney wrote:
> +/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
> +///
> +/// Returns the CE fault method buffer size in bytes.
> +#[expect(dead_code)]
> +pub(crate) fn get_ce_fault_method_buffer_size(
> + cmdq: &Cmdq,
> + bar: &Bar0,
> + client: Handle<Client>,
> + subdevice: Handle<Subdevice>,
> +) -> Result<u32> {
> + // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
> + let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
> +
> + let cmd = RmControl::new(
> + client,
> + subdevice,
> + RmControlMsgFunction::CeGetFaultMethodBufferSize,
> + &req,
> + );
> + let reply = send_rm_control(cmdq, bar, cmd)?;
> +
> + let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
> +
> + Ok(params.size())
> +}
This is similar to send_rm_control(), I think RmControl should be generic over
the control message type, so you could just write something along the lines of:
RmControl::<CeGetFaultMethodBufferSize>::new(...).send();
Admittedly, CeGetFaultMethodBufferSize is a bit long, but that's GSP naming and
get_ce_fault_method_buffer_size() isn't shorter anyway.
(Btw. please try to avoid building functions named get_*() or *_get(), though
I'm aware that it is part of the struct name in this case. Yet another reason
not to solve this with a helper function. :)
Alternatively, you could also consider a builder pattern approach.
^ permalink raw reply [flat|nested] 21+ messages in thread* Re: [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
2026-03-20 13:27 ` Danilo Krummrich
@ 2026-03-25 12:13 ` Eliot Courtney
0 siblings, 0 replies; 21+ messages in thread
From: Eliot Courtney @ 2026-03-25 12:13 UTC (permalink / raw)
To: Danilo Krummrich, Eliot Courtney
Cc: Alice Ryhl, Alexandre Courbot, David Airlie, Simona Vetter,
John Hubbard, Alistair Popple, Joel Fernandes, Timur Tabi,
rust-for-linux, dri-devel, linux-kernel
On Fri Mar 20, 2026 at 10:27 PM JST, Danilo Krummrich wrote:
> On Wed Mar 18, 2026 at 8:14 AM CET, Eliot Courtney wrote:
>> +/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
>> +///
>> +/// Returns the CE fault method buffer size in bytes.
>> +#[expect(dead_code)]
>> +pub(crate) fn get_ce_fault_method_buffer_size(
>> + cmdq: &Cmdq,
>> + bar: &Bar0,
>> + client: Handle<Client>,
>> + subdevice: Handle<Subdevice>,
>> +) -> Result<u32> {
>> + // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
>> + let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
>> +
>> + let cmd = RmControl::new(
>> + client,
>> + subdevice,
>> + RmControlMsgFunction::CeGetFaultMethodBufferSize,
>> + &req,
>> + );
>> + let reply = send_rm_control(cmdq, bar, cmd)?;
>> +
>> + let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
>> +
>> + Ok(params.size())
>> +}
>
> This is similar to send_rm_control(), I think RmControl should be generic over
> the control message type, so you could just write something along the lines of:
>
> RmControl::<CeGetFaultMethodBufferSize>::new(...).send();
>
> Admittedly, CeGetFaultMethodBufferSize is a bit long, but that's GSP naming and
> get_ce_fault_method_buffer_size() isn't shorter anyway.
>
> (Btw. please try to avoid building functions named get_*() or *_get(), though
> I'm aware that it is part of the struct name in this case. Yet another reason
> not to solve this with a helper function. :)
>
> Alternatively, you could also consider a builder pattern approach.
I agree with this, and after thinking about it I also think we should
get rid of the other helper type methods like `get_gsp_info`. I was
trying to make this consistent with the existing way it's done (the
helper methods) but it does look increasingly bad.
^ permalink raw reply [flat|nested] 21+ messages in thread