[PATCH 2/2] gpu: nova-core: use FromSafeCast wherever possible

From: Alexandre Courbot

Date: Fri Aug 28 2026 - 01:34:31 EST


`FromSafeCast` should be preferred to the `*_as_*` family of functions
when it can be used (i.e. in non-const contexts), as it requires a
single import to perform all valid conversions.

After this patch, the only remaining references to the `casts` module
are those done in const context, which means the `casts` import can be
removed once these are converted to use the `cv!` macro.

Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
---
drivers/gpu/nova-core/falcon/fsp.rs | 4 ++--
drivers/gpu/nova-core/firmware/tlv.rs | 4 ++--
drivers/gpu/nova-core/gsp.rs | 4 ++--
drivers/gpu/nova-core/gsp/cmdq.rs | 19 +++++++++++--------
drivers/gpu/nova-core/gsp/fw.rs | 8 ++++----
5 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/falcon/fsp.rs
index 2470ac511c98..ece95b1ea8cb 100644
--- a/drivers/gpu/nova-core/falcon/fsp.rs
+++ b/drivers/gpu/nova-core/falcon/fsp.rs
@@ -16,7 +16,7 @@
},
Io, //
},
- num::casts,
+ num::casts::FromSafeCast,
prelude::*,
sizes::SZ_1K,
time::Delta,
@@ -165,7 +165,7 @@ pub(crate) fn recv_msg(&mut self) -> Result<KVec<u8>> {
Delta::from_millis(10),
Delta::from_millis(FSP_MSG_TIMEOUT_MS),
)
- .map(casts::u32_as_usize)?;
+ .map(usize::from_safe_cast)?;

// Don't blindly allocate more than the maximum we expect from FSP.
if msg_size > FSP_EMEM_CHANNEL_0_SIZE {
diff --git a/drivers/gpu/nova-core/firmware/tlv.rs b/drivers/gpu/nova-core/firmware/tlv.rs
index 6653c10e3e0a..7dff8871e338 100644
--- a/drivers/gpu/nova-core/firmware/tlv.rs
+++ b/drivers/gpu/nova-core/firmware/tlv.rs
@@ -5,7 +5,7 @@
device,
firmware,
num::casts::{
- self,
+ FromSafeCast,
IntoSafeCast, //
},
prelude::*,
@@ -52,7 +52,7 @@ fn parse(hdr: &[u8]) -> Option<Self> {
return None;
}
let len_arr = <[u8; 4]>::try_from(hdr.get(4..Self::SIZE)?).ok()?;
- let length = casts::u32_as_usize(u32::from_le_bytes(len_arr));
+ let length = usize::from_safe_cast(u32::from_le_bytes(len_arr));
Some(Self { tag, length })
}
}
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index fc8648de84c2..0f5275dcb41c 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -17,7 +17,7 @@
io_write,
Io, //
},
- num::casts,
+ num::casts::FromSafeCast,
pci,
prelude::*, //
};
@@ -92,7 +92,7 @@ fn init(view: CoherentView<'_, Self>, start: DmaAddress) -> Result<()> {
for i in 0..NUM_PAGES {
io_write!(view, .0[build: i],
start
- .checked_add(casts::usize_as_u64(i) << GSP_PAGE_SHIFT)
+ .checked_add(u64::from_safe_cast(i) << GSP_PAGE_SHIFT)
.ok_or(EOVERFLOW)?
);
}
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index f85fde09aa6e..658d0a9b2cfb 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -23,7 +23,10 @@
Io, //
},
new_mutex,
- num::casts,
+ num::casts::{
+ self,
+ FromSafeCast, //
+ },
prelude::*,
ptr,
sync::{
@@ -289,10 +292,10 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
unsafe {
(
core::slice::from_raw_parts_mut(
- data.add(casts::u32_as_usize(tx)),
- casts::u32_as_usize(tail_end - tx),
+ data.add(usize::from_safe_cast(tx)),
+ usize::from_safe_cast(tail_end - tx),
),
- core::slice::from_raw_parts_mut(data, casts::u32_as_usize(wrap_end)),
+ core::slice::from_raw_parts_mut(data, usize::from_safe_cast(wrap_end)),
)
}
}
@@ -307,7 +310,7 @@ fn driver_write_area_size(&self) -> usize {
// `cpu_write_ptr`. The minimum value case is where `rx == 0` and `tx == MSGQ_NUM_PAGES -
// 1`, which gives `0 + MSGQ_NUM_PAGES - (MSGQ_NUM_PAGES - 1) - 1 == 0`.
let slots = (rx + MSGQ_NUM_PAGES - tx - 1) % MSGQ_NUM_PAGES;
- casts::u32_as_usize(slots) * GSP_PAGE_SIZE
+ usize::from_safe_cast(slots) * GSP_PAGE_SIZE
}

/// Returns the region of the GSP message queue that the driver is currently allowed to read
@@ -343,10 +346,10 @@ fn driver_write_area_size(&self) -> usize {
unsafe {
(
core::slice::from_raw_parts(
- data.add(casts::u32_as_usize(rx)),
- casts::u32_as_usize(tail_end - rx),
+ data.add(usize::from_safe_cast(rx)),
+ usize::from_safe_cast(tail_end - rx),
),
- core::slice::from_raw_parts(data, casts::u32_as_usize(wrap_end)),
+ core::slice::from_raw_parts(data, usize::from_safe_cast(wrap_end)),
)
}
}
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 88f083ff1f13..61064b6a251b 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -681,7 +681,7 @@ fn id8(name: &str) -> u64 {
let init_inner = init!(bindings::LibosMemoryRegionInitArgument {
id8: id8(name),
pa: obj.dma_address(),
- size: casts::usize_as_u64(obj.size()),
+ size: u64::from_safe_cast(obj.size()),
kind: casts::u32_into_u8::<
{ bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS },
>(),
@@ -851,7 +851,7 @@ pub(crate) fn set_checksum(&mut self, checksum: u32) {
/// Returns the length of the message's payload.
pub(crate) fn payload_length(&self) -> usize {
// `rpc.length` includes the length of the RPC message header.
- casts::u32_as_usize(self.inner.rpc.length)
+ usize::from_safe_cast(self.inner.rpc.length)
.saturating_sub(size_of::<bindings::rpc_message_header_v>())
}

@@ -948,8 +948,8 @@ fn new(cmdq: &Cmdq) -> impl Init<Self> + '_ {
init!(MessageQueueInitArguments {
sharedMemPhysAddr: cmdq.dma_addr,
pageTableEntryCount: casts::usize_into_u32::<{ Cmdq::NUM_PTES }>(),
- cmdQueueOffset: casts::usize_as_u64(Cmdq::CMDQ_OFFSET),
- statQueueOffset: casts::usize_as_u64(Cmdq::STATQ_OFFSET),
+ cmdQueueOffset: u64::from_safe_cast(Cmdq::CMDQ_OFFSET),
+ statQueueOffset: u64::from_safe_cast(Cmdq::STATQ_OFFSET),
..Zeroable::init_zeroed()
})
}

--
2.55.0