[PATCH 2/2] gpu: nova-core: use kernel lossless integer conversion module

From: Alexandre Courbot

Date: Mon Jul 27 2026 - 06:26:22 EST


The `kernel` crate now features a copy of our lossless integer
conversion routines. Switch to the kernel version and remove our own.

Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
---
drivers/gpu/nova-core/falcon.rs | 10 +-
drivers/gpu/nova-core/falcon/fsp.rs | 2 +-
drivers/gpu/nova-core/fb.rs | 2 +-
drivers/gpu/nova-core/fb/hal/gb100.rs | 6 +-
drivers/gpu/nova-core/firmware.rs | 8 +-
drivers/gpu/nova-core/firmware/booter.rs | 10 +-
drivers/gpu/nova-core/firmware/fwsec.rs | 2 +-
drivers/gpu/nova-core/firmware/fwsec/bootloader.rs | 2 +-
drivers/gpu/nova-core/firmware/gsp.rs | 2 +-
drivers/gpu/nova-core/firmware/riscv.rs | 6 +-
drivers/gpu/nova-core/fsp.rs | 2 +-
drivers/gpu/nova-core/gsp.rs | 2 +-
drivers/gpu/nova-core/gsp/cmdq.rs | 4 +-
drivers/gpu/nova-core/gsp/fw.rs | 8 +-
drivers/gpu/nova-core/gsp/sequencer.rs | 2 +-
drivers/gpu/nova-core/num.rs | 211 ---------------------
drivers/gpu/nova-core/vbios.rs | 2 +-
17 files changed, 35 insertions(+), 246 deletions(-)

diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
index 94c7696a6493..3133c6e2f229 100644
--- a/drivers/gpu/nova-core/falcon.rs
+++ b/drivers/gpu/nova-core/falcon.rs
@@ -23,6 +23,10 @@
},
Io,
},
+ num::{
+ self,
+ FromSafeCast, //
+ },
prelude::*,
sync::aref::ARef,
time::Delta,
@@ -33,11 +37,7 @@
driver::Bar0,
falcon::hal::LoadMethod,
gpu::Chipset,
- num::{
- self,
- FromSafeCast, //
- },
- regs,
+ regs, //
};

pub(crate) mod fsp;
diff --git a/drivers/gpu/nova-core/falcon/fsp.rs b/drivers/gpu/nova-core/falcon/fsp.rs
index 52cdb84ef0e8..aad919c8471d 100644
--- a/drivers/gpu/nova-core/falcon/fsp.rs
+++ b/drivers/gpu/nova-core/falcon/fsp.rs
@@ -16,6 +16,7 @@
},
Io, //
},
+ num,
prelude::*,
time::Delta,
};
@@ -28,7 +29,6 @@
PFalcon2Base,
PFalconBase, //
},
- num,
regs, //
};

diff --git a/drivers/gpu/nova-core/fb.rs b/drivers/gpu/nova-core/fb.rs
index 725e428154cf..a635be13d0d0 100644
--- a/drivers/gpu/nova-core/fb.rs
+++ b/drivers/gpu/nova-core/fb.rs
@@ -10,6 +10,7 @@
dma::CoherentHandle,
fmt,
io::Io,
+ num::FromSafeCast,
prelude::*,
ptr::{
Alignable,
@@ -23,7 +24,6 @@
firmware::gsp::GspFirmware,
gpu::Chipset,
gsp,
- num::FromSafeCast,
regs, //
};

diff --git a/drivers/gpu/nova-core/fb/hal/gb100.rs b/drivers/gpu/nova-core/fb/hal/gb100.rs
index 6e0eba101ca1..91461433c5d0 100644
--- a/drivers/gpu/nova-core/fb/hal/gb100.rs
+++ b/drivers/gpu/nova-core/fb/hal/gb100.rs
@@ -11,7 +11,10 @@
},
Io, //
},
- num::Bounded,
+ num::{
+ usize_into_u32,
+ Bounded, //
+ },
prelude::*,
ptr::{
const_align_up,
@@ -23,7 +26,6 @@
use crate::{
driver::Bar0,
fb::hal::FbHal,
- num::usize_into_u32,
regs, //
};

diff --git a/drivers/gpu/nova-core/firmware.rs b/drivers/gpu/nova-core/firmware.rs
index 1e89390209f5..03571251b490 100644
--- a/drivers/gpu/nova-core/firmware.rs
+++ b/drivers/gpu/nova-core/firmware.rs
@@ -10,6 +10,10 @@
use kernel::{
device,
firmware,
+ num::{
+ FromSafeCast,
+ IntoSafeCast, //
+ },
prelude::*,
str::CString,
transmute::FromBytes, //
@@ -21,10 +25,6 @@
FalconFirmware, //
},
gpu,
- num::{
- FromSafeCast,
- IntoSafeCast, //
- },
};

pub(crate) mod booter;
diff --git a/drivers/gpu/nova-core/firmware/booter.rs b/drivers/gpu/nova-core/firmware/booter.rs
index d9313ac361af..0645677dcc30 100644
--- a/drivers/gpu/nova-core/firmware/booter.rs
+++ b/drivers/gpu/nova-core/firmware/booter.rs
@@ -10,6 +10,10 @@
use kernel::{
device,
dma::Coherent,
+ num::{
+ FromSafeCast,
+ IntoSafeCast, //
+ },
prelude::*,
transmute::FromBytes, //
};
@@ -31,11 +35,7 @@
Signed,
Unsigned, //
},
- gpu::Chipset,
- num::{
- FromSafeCast,
- IntoSafeCast, //
- },
+ gpu::Chipset, //
};

/// Local convenience function to return a copy of `S` by reinterpreting the bytes starting at
diff --git a/drivers/gpu/nova-core/firmware/fwsec.rs b/drivers/gpu/nova-core/firmware/fwsec.rs
index 199ae2adb664..e856eb698300 100644
--- a/drivers/gpu/nova-core/firmware/fwsec.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec.rs
@@ -19,6 +19,7 @@
self,
Device, //
},
+ num::FromSafeCast,
prelude::*,
transmute::{
AsBytes,
@@ -43,7 +44,6 @@
Signed,
Unsigned, //
},
- num::FromSafeCast,
vbios::Vbios,
};

diff --git a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
index 039920dc340b..7d82c0ca33a5 100644
--- a/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
+++ b/drivers/gpu/nova-core/firmware/fwsec/bootloader.rs
@@ -17,6 +17,7 @@
register::WithBase, //
Io,
},
+ num::FromSafeCast,
prelude::*,
ptr::{
Alignable,
@@ -51,7 +52,6 @@
FIRMWARE_VERSION, //
},
gpu::Chipset,
- num::FromSafeCast,
regs,
};

diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs
index 99a302bae567..87ed9d4ede08 100644
--- a/drivers/gpu/nova-core/firmware/gsp.rs
+++ b/drivers/gpu/nova-core/firmware/gsp.rs
@@ -8,6 +8,7 @@
DataDirection,
DmaAddress, //
},
+ num::FromSafeCast,
prelude::*,
scatterlist::{
Owned,
@@ -25,7 +26,6 @@
Chipset, //
},
gsp::GSP_PAGE_SIZE,
- num::FromSafeCast,
};

/// GSP firmware with 3-level radix page tables for the GSP bootloader.
diff --git a/drivers/gpu/nova-core/firmware/riscv.rs b/drivers/gpu/nova-core/firmware/riscv.rs
index 2afa7f36404e..572c2815a053 100644
--- a/drivers/gpu/nova-core/firmware/riscv.rs
+++ b/drivers/gpu/nova-core/firmware/riscv.rs
@@ -7,14 +7,12 @@
device,
dma::Coherent,
firmware::Firmware,
+ num::FromSafeCast,
prelude::*,
transmute::FromBytes, //
};

-use crate::{
- firmware::BinFirmware,
- num::FromSafeCast, //
-};
+use crate::firmware::BinFirmware;

/// Descriptor for microcode running on a RISC-V core.
#[repr(C)]
diff --git a/drivers/gpu/nova-core/fsp.rs b/drivers/gpu/nova-core/fsp.rs
index 8fc243c66e35..ae529652b3eb 100644
--- a/drivers/gpu/nova-core/fsp.rs
+++ b/drivers/gpu/nova-core/fsp.rs
@@ -11,6 +11,7 @@
device,
dma::Coherent,
io::poll::read_poll_timeout,
+ num,
prelude::*,
ptr::{
Alignable,
@@ -42,7 +43,6 @@
NvdmHeader,
NvdmType, //
},
- num,
regs, //
};

diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 69175ca3315c..75f7bfe50976 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -11,6 +11,7 @@
CoherentBox,
DmaAddress, //
},
+ num,
pci,
prelude::*,
transmute::{
@@ -36,7 +37,6 @@
GspArgumentsPadded,
LibosMemoryRegionInitArgument, //
},
- num,
};

pub(crate) const GSP_PAGE_SHIFT: usize = 12;
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 070de0731e95..513542ed7924 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -16,6 +16,7 @@
Io, //
},
new_mutex,
+ num,
prelude::*,
ptr,
sync::{
@@ -26,7 +27,7 @@
transmute::{
AsBytes,
FromBytes, //
- },
+ }, //
};

use continuation::{
@@ -50,7 +51,6 @@
GSP_PAGE_SHIFT,
GSP_PAGE_SIZE, //
},
- num,
regs,
sbuffer::SBufferIter, //
};
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 4db0cfa4dc4d..755015a2eff1 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -11,6 +11,10 @@

use kernel::{
dma::Coherent,
+ num::{
+ self,
+ FromSafeCast, //
+ },
prelude::*,
ptr::{
Alignable,
@@ -38,10 +42,6 @@
cmdq::Cmdq, //
GSP_PAGE_SIZE,
},
- num::{
- self,
- FromSafeCast, //
- },
};

// TODO: Replace with `IoView` projections once available.
diff --git a/drivers/gpu/nova-core/gsp/sequencer.rs b/drivers/gpu/nova-core/gsp/sequencer.rs
index e0850d21adca..2ee84178628f 100644
--- a/drivers/gpu/nova-core/gsp/sequencer.rs
+++ b/drivers/gpu/nova-core/gsp/sequencer.rs
@@ -10,6 +10,7 @@
poll::read_poll_timeout,
Io, //
},
+ num::FromSafeCast,
prelude::*,
time::{
delay::fsleep,
@@ -32,7 +33,6 @@
},
fw,
},
- num::FromSafeCast,
sbuffer::SBufferIter,
};

diff --git a/drivers/gpu/nova-core/num.rs b/drivers/gpu/nova-core/num.rs
index 6eb174d136ab..3921ef6f238e 100644
--- a/drivers/gpu/nova-core/num.rs
+++ b/drivers/gpu/nova-core/num.rs
@@ -5,217 +5,6 @@
//! This is essentially a staging module for code to mature until it can be moved to the `kernel`
//! crate.

-use kernel::{
- macros::paste,
- prelude::*, //
-};
-
-/// Implements safe `as` conversion functions from a given type into a series of target types.
-///
-/// These functions can be used in place of `as`, with the guarantee that they will be lossless.
-macro_rules! impl_safe_as {
- ($from:ty as { $($into:ty),* }) => {
- $(
- paste! {
- #[doc = ::core::concat!(
- "Losslessly converts a [`",
- ::core::stringify!($from),
- "`] into a [`",
- ::core::stringify!($into),
- "`].")]
- ///
- /// This conversion is allowed as it is always lossless. Prefer this over the `as`
- /// keyword to ensure no lossy casts are performed.
- ///
- /// This is for use from a `const` context. For non `const` use, prefer the
- /// [`FromSafeCast`] and [`IntoSafeCast`] traits.
- ///
- /// # Examples
- ///
- /// ```
- /// use crate::num;
- ///
- #[doc = ::core::concat!(
- "assert_eq!(num::",
- ::core::stringify!($from),
- "_as_",
- ::core::stringify!($into),
- "(1",
- ::core::stringify!($from),
- "), 1",
- ::core::stringify!($into),
- ");")]
- /// ```
- #[allow(unused)]
- #[inline(always)]
- pub(crate) const fn [<$from _as_ $into>](value: $from) -> $into {
- ::kernel::build_assert::static_assert!(size_of::<$into>() >= size_of::<$from>());
-
- value as $into
- }
- }
- )*
- };
-}
-
-impl_safe_as!(u8 as { u16, u32, u64, usize });
-impl_safe_as!(u16 as { u32, u64, usize });
-impl_safe_as!(u32 as { u64, usize } );
-// `u64` and `usize` have the same size on 64-bit platforms.
-#[cfg(CONFIG_64BIT)]
-impl_safe_as!(u64 as { usize } );
-
-// A `usize` fits into a `u64` on 32 and 64-bit platforms.
-#[cfg(any(CONFIG_32BIT, CONFIG_64BIT))]
-impl_safe_as!(usize as { u64 });
-
-// A `usize` fits into a `u32` on 32-bit platforms.
-#[cfg(CONFIG_32BIT)]
-impl_safe_as!(usize as { u32 });
-
-/// Extension trait providing guaranteed lossless cast to `Self` from `T`.
-///
-/// The standard library's `From` implementations do not cover conversions that are not portable or
-/// future-proof. For instance, even though it is safe today, `From<usize>` is not implemented for
-/// [`u64`] because of the possibility to support larger-than-64bit architectures in the future.
-///
-/// The workaround is to either deal with the error handling of [`TryFrom`] for an operation that
-/// technically cannot fail, or to use the `as` keyword, which can silently strip data if the
-/// destination type is smaller than the source.
-///
-/// Both options are hardly acceptable for the kernel. It is also a much more architecture
-/// dependent environment, supporting only 32 and 64 bit architectures, with some modules
-/// explicitly depending on a specific bus width that could greatly benefit from infallible
-/// conversion operations.
-///
-/// Thus this extension trait that provides, for the architecture the kernel is built for, safe
-/// conversion between types for which such cast is lossless.
-///
-/// In other words, this trait is implemented if, for the current build target and with `t: T`, the
-/// `t as Self` operation is completely lossless.
-///
-/// Prefer this over the `as` keyword to ensure no lossy casts are performed.
-///
-/// If you need to perform a conversion in `const` context, use [`u64_as_usize`], [`u32_as_usize`],
-/// [`usize_as_u64`], etc.
-///
-/// # Examples
-///
-/// ```
-/// use crate::num::FromSafeCast;
-///
-/// assert_eq!(usize::from_safe_cast(0xf00u32), 0xf00u32 as usize);
-/// ```
-pub(crate) trait FromSafeCast<T> {
- /// Create a `Self` from `value`. This operation is guaranteed to be lossless.
- fn from_safe_cast(value: T) -> Self;
-}
-
-impl FromSafeCast<usize> for u64 {
- fn from_safe_cast(value: usize) -> Self {
- usize_as_u64(value)
- }
-}
-
-#[cfg(CONFIG_32BIT)]
-impl FromSafeCast<usize> for u32 {
- fn from_safe_cast(value: usize) -> Self {
- usize_as_u32(value)
- }
-}
-
-impl FromSafeCast<u32> for usize {
- fn from_safe_cast(value: u32) -> Self {
- u32_as_usize(value)
- }
-}
-
-#[cfg(CONFIG_64BIT)]
-impl FromSafeCast<u64> for usize {
- fn from_safe_cast(value: u64) -> Self {
- u64_as_usize(value)
- }
-}
-
-/// Counterpart to the [`FromSafeCast`] trait, i.e. this trait is to [`FromSafeCast`] what [`Into`]
-/// is to [`From`].
-///
-/// See the documentation of [`FromSafeCast`] for the motivation.
-///
-/// # Examples
-///
-/// ```
-/// use crate::num::IntoSafeCast;
-///
-/// assert_eq!(0xf00u32.into_safe_cast(), 0xf00u32 as usize);
-/// ```
-pub(crate) trait IntoSafeCast<T> {
- /// Convert `self` into a `T`. This operation is guaranteed to be lossless.
- fn into_safe_cast(self) -> T;
-}
-
-/// Reverse operation for types implementing [`FromSafeCast`].
-impl<S, T> IntoSafeCast<T> for S
-where
- T: FromSafeCast<S>,
-{
- fn into_safe_cast(self) -> T {
- T::from_safe_cast(self)
- }
-}
-
-/// Implements lossless conversion of a constant from a larger type into a smaller one.
-macro_rules! impl_const_into {
- ($from:ty => { $($into:ty),* }) => {
- $(
- paste! {
- #[doc = ::core::concat!(
- "Performs a build-time safe conversion of a [`",
- ::core::stringify!($from),
- "`] constant value into a [`",
- ::core::stringify!($into),
- "`].")]
- ///
- /// This checks at compile-time that the conversion is lossless, and triggers a build
- /// error if it isn't.
- ///
- /// # Examples
- ///
- /// ```
- /// use crate::num;
- ///
- /// // Succeeds because the value of the source fits into the destination's type.
- #[doc = ::core::concat!(
- "assert_eq!(num::",
- ::core::stringify!($from),
- "_into_",
- ::core::stringify!($into),
- "::<1",
- ::core::stringify!($from),
- ">(), 1",
- ::core::stringify!($into),
- ");")]
- /// ```
- #[allow(unused)]
- pub(crate) const fn [<$from _into_ $into>]<const N: $from>() -> $into {
- // Make sure that the target type is smaller than the source one.
- static_assert!($from::BITS >= $into::BITS);
- // CAST: we statically enforced above that `$from` is larger than `$into`, so the
- // `as` conversion will be lossless.
- build_assert!(N >= $into::MIN as $from && N <= $into::MAX as $from);
-
- N as $into
- }
- }
- )*
- };
-}
-
-impl_const_into!(usize => { u8, u16, u32 });
-impl_const_into!(u64 => { u8, u16, u32 });
-impl_const_into!(u32 => { u8, u16 });
-impl_const_into!(u16 => { u8 });
-
/// Creates an enum type associated to a [`Bounded`](kernel::num::Bounded), with a [`From`]
/// conversion to the associated `Bounded` and either a [`TryFrom`] or `From` conversion from the
/// associated `Bounded`.
diff --git a/drivers/gpu/nova-core/vbios.rs b/drivers/gpu/nova-core/vbios.rs
index c6e6bfcd6a1f..9bce9a4b2286 100644
--- a/drivers/gpu/nova-core/vbios.rs
+++ b/drivers/gpu/nova-core/vbios.rs
@@ -5,6 +5,7 @@
use kernel::{
device,
io::Io,
+ num::FromSafeCast,
prelude::*,
ptr::{
Alignable,
@@ -26,7 +27,6 @@
FalconUCodeDescV2,
FalconUCodeDescV3, //
},
- num::FromSafeCast,
};

/// BIOS Image Type from PCI Data Structure code_type field.

--
2.55.0