* [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype
@ 2026-09-27 18:11 Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 1/2] rust: scatterlist: return u32 from SGEntry::dma_len() Lorenzo Delgado
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Lorenzo Delgado @ 2026-09-27 18:11 UTC (permalink / raw)
To: Daniel Almeida, Alice Ryhl, Danilo Krummrich, David Airlie,
Simona Vetter, Abdiel Janulgue, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Alexandre Courbot,
Onur Özkan
Cc: Lorenzo Delgado, dri-devel, linux-kernel, driver-core, rust-for-linux
This turns ResourceSize from a type alias into a #[repr(transparent)]
newtype, so that every conversion at the FFI boundary is explicit.
The first patch changes SGEntry::dma_len() to return u32. The length of
a DMA segment is an unsigned int on the C side, so it was never a
ResourceSize. Doing that first means the newtype patch no longer has to
touch tyr or nova-core.
Note that Alexandre's nova_num series [1] rewrites the dma_len() line in
nova-core's gsp.rs to usize::from_safe_cast_arch(), which takes a u64.
With patch 1 applied, that line needs usize::from_safe_cast() instead,
and the FromSafeCastArch import goes away. The two series apply on top
of each other without conflicts, so this only shows up as a build
error. I can rebase on top of nova_num if it lands first.
[1] https://lore.kernel.org/r/20260828-nova_num-v1-0-e21f17ba4127@nvidia.com
Signed-off-by: Lorenzo Delgado <lnsdev@proton.me>
---
Changes in v4:
- New patch 1: return u32 from SGEntry::dma_len(), as suggested by
Danilo.
- Patch 2 no longer touches scatterlist.rs, tyr or nova-core.
- Drop FromSafeCastArch<ResourceSize> for usize. Its only user was the
dma_len() conversion in nova-core.
- Link to v3: https://patch.msgid.link/20260920-resource-size-newtype-v3-1-9451444e83bb@proton.me
Changes in v3:
- Rebase on rust-next (v7.3-rc4).
- Implement FromSafeCastArch<ResourceSize> for usize in the kernel
crate, next to the type, now that the lossless casts live in
kernel::num::casts. Drop the impl from nova-core's num.rs, and switch
gsp.rs to usize::from_safe_cast_arch(), the same line the nova-core
conversion to kernel::num uses.
- Convert the dma_len() user in tyr, added since v2. Without it, tyr
fails to build on 32-bit ARM without LPAE.
- Link to v2: https://lore.kernel.org/r/20260719200945.687904-1-lnsdev@proton.me
- Link to v1: https://lore.kernel.org/r/20260712113602.389060-1-lnsdev@proton.me
---
Lorenzo Delgado (2):
rust: scatterlist: return u32 from SGEntry::dma_len()
rust: io: convert ResourceSize into a transparent newtype
drivers/gpu/drm/tyr/vm.rs | 1 -
rust/kernel/io.rs | 74 ++++++++++++++++++++++++++++++++++++++++++----
rust/kernel/io/resource.rs | 6 ++--
rust/kernel/scatterlist.rs | 9 ++----
4 files changed, 75 insertions(+), 15 deletions(-)
---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20260920-resource-size-newtype-63a82d4f2cdb
Best regards,
--
Lorenzo Delgado <lnsdev@proton.me>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v4 1/2] rust: scatterlist: return u32 from SGEntry::dma_len()
2026-09-27 18:11 [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
@ 2026-09-27 18:11 ` Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 2/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
2026-10-01 22:15 ` [PATCH v4 0/2] " Danilo Krummrich
2 siblings, 0 replies; 4+ messages in thread
From: Lorenzo Delgado @ 2026-09-27 18:11 UTC (permalink / raw)
To: Daniel Almeida, Alice Ryhl, Danilo Krummrich, David Airlie,
Simona Vetter, Abdiel Janulgue, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Alexandre Courbot,
Onur Özkan
Cc: Lorenzo Delgado, dri-devel, linux-kernel, driver-core, rust-for-linux
`SGEntry::dma_len()` returns `ResourceSize`, but the length of a DMA
segment is not the size of a resource. The C side stores it as an
`unsigned int` (`dma_length` in `struct scatterlist`), the helper
returns `unsigned int`, and a single segment is bounded by the
device's `max_segment_size`, which is an `unsigned int` as well. The
method only widens the value to `resource_size_t`.
Return `u32`, which is what the binding already produces, and drop the
`.into()` along with its `clippy::useless_conversion` allow.
tyr widens the length to `u64`, which is now a real conversion on
every architecture, so drop its `useless_conversion` allow too.
nova-core converts it to `usize` through `FromSafeCast`, which already
covers `u32`, so it needs no change.
Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/DLNPXJ4WPH4L.2MBUGV1TAESYY@kernel.org
Signed-off-by: Lorenzo Delgado <lnsdev@proton.me>
---
drivers/gpu/drm/tyr/vm.rs | 1 -
rust/kernel/scatterlist.rs | 9 +++------
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/tyr/vm.rs b/drivers/gpu/drm/tyr/vm.rs
index c5e307b1e241..1dd11b2b1253 100644
--- a/drivers/gpu/drm/tyr/vm.rs
+++ b/drivers/gpu/drm/tyr/vm.rs
@@ -644,7 +644,6 @@ fn sm_step_map<'op>(
// Expressly convert to u64 to work with arm 32-bit builds.
#[allow(clippy::useless_conversion)]
let mut paddr = u64::from(sgt_entry.dma_address());
- #[allow(clippy::useless_conversion)]
let mut sgt_entry_length = u64::from(sgt_entry.dma_len());
if bytes_left_to_map == 0 {
diff --git a/rust/kernel/scatterlist.rs b/rust/kernel/scatterlist.rs
index b83c468b5c63..f37bf29fdbca 100644
--- a/rust/kernel/scatterlist.rs
+++ b/rust/kernel/scatterlist.rs
@@ -34,9 +34,7 @@
bindings,
device::{Bound, Device},
devres::Devres,
- dma, error,
- io::ResourceSize,
- page,
+ dma, error, page,
prelude::*,
sync::aref::ARef,
types::Opaque,
@@ -90,10 +88,9 @@ pub fn dma_address(&self) -> dma::DmaAddress {
/// Returns the length of this SG entry in bytes.
#[inline]
- pub fn dma_len(&self) -> ResourceSize {
- #[allow(clippy::useless_conversion)]
+ pub fn dma_len(&self) -> u32 {
// SAFETY: `self.as_raw()` is a valid pointer to a `struct scatterlist`.
- unsafe { bindings::sg_dma_len(self.as_raw()) }.into()
+ unsafe { bindings::sg_dma_len(self.as_raw()) }
}
}
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v4 2/2] rust: io: convert ResourceSize into a transparent newtype
2026-09-27 18:11 [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 1/2] rust: scatterlist: return u32 from SGEntry::dma_len() Lorenzo Delgado
@ 2026-09-27 18:11 ` Lorenzo Delgado
2026-10-01 22:15 ` [PATCH v4 0/2] " Danilo Krummrich
2 siblings, 0 replies; 4+ messages in thread
From: Lorenzo Delgado @ 2026-09-27 18:11 UTC (permalink / raw)
To: Daniel Almeida, Alice Ryhl, Danilo Krummrich, David Airlie,
Simona Vetter, Abdiel Janulgue, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Alexandre Courbot,
Onur Özkan
Cc: Lorenzo Delgado, dri-devel, linux-kernel, driver-core, rust-for-linux
`ResourceSize` is a bare type alias for `resource_size_t`, so it
inherits every integer operation and `as` cast. That allows operations
that make no sense for the size of a hardware resource, such as mixing
it with unrelated integers or truncating it with a cast.
Wrap it in a `#[repr(transparent)]` newtype so each conversion at a
boundary is explicit. The representation is unchanged, so this is
ABI-identical; only the spelling at the FFI boundary changes. Provide
`from_raw`/`into_raw`, `From` in both directions, and a fallible
`TryFrom<ResourceSize> for usize`, since `resource_size_t` can be wider
than `usize` on 32-bit.
Update the producer, `Resource::size`, and its consumers in `Region`
and `request_region`.
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1203
Signed-off-by: Lorenzo Delgado <lnsdev@proton.me>
---
rust/kernel/io.rs | 74 ++++++++++++++++++++++++++++++++++++++++++----
rust/kernel/io/resource.rs | 6 ++--
2 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index 5ce9fd129068..09b0586acf1a 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -6,11 +6,13 @@
use core::{
marker::PhantomData,
- mem::MaybeUninit, //
+ mem::MaybeUninit,
+ num::TryFromIntError, //
};
use crate::{
bindings,
+ fmt,
prelude::*,
ptr::{
Alignment,
@@ -35,11 +37,73 @@
/// `CONFIG_PHYS_ADDR_T_64BIT`, and it can be a u64 even on 32-bit architectures.
pub type PhysAddr = bindings::phys_addr_t;
-/// Resource Size type.
+/// Resource size type.
///
-/// This is a type alias to either `u32` or `u64` depending on the config option
-/// `CONFIG_PHYS_ADDR_T_64BIT`, and it can be a u64 even on 32-bit architectures.
-pub type ResourceSize = bindings::resource_size_t;
+/// This wraps either `u32` or `u64` depending on the config option
+/// `CONFIG_PHYS_ADDR_T_64BIT`, and it can be a `u64` even on 32-bit architectures.
+///
+/// # Examples
+///
+/// ```
+/// use kernel::io::ResourceSize;
+///
+/// let size = ResourceSize::from_raw(0x1000);
+/// assert_eq!(size.into_raw(), 0x1000);
+///
+/// // Round-trips through the raw C type.
+/// let raw: kernel::bindings::resource_size_t = size.into();
+/// assert_eq!(ResourceSize::from(raw), size);
+///
+/// // Fallible conversion to `usize` (can truncate on 32-bit).
+/// assert_eq!(usize::try_from(size)?, 0x1000);
+/// # Ok::<(), core::num::TryFromIntError>(())
+/// ```
+#[repr(transparent)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct ResourceSize(bindings::resource_size_t);
+
+impl ResourceSize {
+ /// Creates a resource size from the raw C type.
+ #[inline]
+ pub const fn from_raw(value: bindings::resource_size_t) -> Self {
+ Self(value)
+ }
+
+ /// Turns this resource size into the raw C type.
+ #[inline]
+ pub const fn into_raw(self) -> bindings::resource_size_t {
+ self.0
+ }
+}
+
+impl fmt::Debug for ResourceSize {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:#x}", self.0)
+ }
+}
+
+impl From<bindings::resource_size_t> for ResourceSize {
+ #[inline]
+ fn from(value: bindings::resource_size_t) -> Self {
+ Self::from_raw(value)
+ }
+}
+
+impl From<ResourceSize> for bindings::resource_size_t {
+ #[inline]
+ fn from(value: ResourceSize) -> Self {
+ value.into_raw()
+ }
+}
+
+impl TryFrom<ResourceSize> for usize {
+ type Error = TryFromIntError;
+
+ #[inline]
+ fn try_from(value: ResourceSize) -> Result<Self, Self::Error> {
+ Self::try_from(value.into_raw())
+ }
+}
/// Untyped I/O region.
///
diff --git a/rust/kernel/io/resource.rs b/rust/kernel/io/resource.rs
index 17b0c174cfc5..a33a416b289a 100644
--- a/rust/kernel/io/resource.rs
+++ b/rust/kernel/io/resource.rs
@@ -58,7 +58,7 @@ fn drop(&mut self) {
};
// SAFETY: Safe as per the invariant of `Region`.
- unsafe { release_fn(start, size) };
+ unsafe { release_fn(start, size.into_raw()) };
}
}
@@ -114,7 +114,7 @@ pub fn request_region(
bindings::__request_region(
self.0.get(),
start,
- size,
+ size.into_raw(),
name.as_char_ptr(),
flags.0 as c_int,
)
@@ -130,7 +130,7 @@ pub fn request_region(
pub fn size(&self) -> ResourceSize {
let inner = self.0.get();
// SAFETY: Safe as per the invariants of `Resource`.
- unsafe { bindings::resource_size(inner) }
+ ResourceSize::from_raw(unsafe { bindings::resource_size(inner) })
}
/// Returns the start address of the resource.
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype
2026-09-27 18:11 [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 1/2] rust: scatterlist: return u32 from SGEntry::dma_len() Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 2/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
@ 2026-10-01 22:15 ` Danilo Krummrich
2 siblings, 0 replies; 4+ messages in thread
From: Danilo Krummrich @ 2026-10-01 22:15 UTC (permalink / raw)
To: Lorenzo Delgado
Cc: Daniel Almeida, Alice Ryhl, Danilo Krummrich, David Airlie,
Simona Vetter, Abdiel Janulgue, Robin Murphy, Andreas Hindborg,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Trevor Gross, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, dri-devel, linux-kernel, driver-core,
rust-for-linux
On Sun, 27 Sep 2026 18:11:31 +0000, Lorenzo Delgado wrote:
> [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype
Applied, thanks!
Branch: driver-core-testing
Tree: git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core.git
[1/2] rust: scatterlist: return u32 from SGEntry::dma_len()
commit: 2581f023a5a6
[2/2] rust: io: convert ResourceSize into a transparent newtype
commit: 7db73c69c831
The patches will appear in the next linux-next integration (typically within 24
hours on weekdays).
The patches are in the driver-core-testing branch and will be promoted to
driver-core-next after validation.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-01 22:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-27 18:11 [PATCH v4 0/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 1/2] rust: scatterlist: return u32 from SGEntry::dma_len() Lorenzo Delgado
2026-09-27 18:11 ` [PATCH v4 2/2] rust: io: convert ResourceSize into a transparent newtype Lorenzo Delgado
2026-10-01 22:15 ` [PATCH v4 0/2] " Danilo Krummrich
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®