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
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.
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.
© 2016 - 2026 Red Hat, Inc.