public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] rust: io: convert `PhysAddr` type alias to newtype
@ 2026-05-04  4:57 Albab Hasan
  2026-05-04 22:08 ` Danilo Krummrich
  0 siblings, 1 reply; 3+ messages in thread
From: Albab Hasan @ 2026-05-04  4:57 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Albab Hasan, Danilo Krummrich, Alice Ryhl, Daniel Almeida,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Trevor Gross, Robin Murphy, rust-for-linux,
	linux-kernel

Makes `PhysAddr` a newtype wrapper around `bindings::phys_addr_t`.
This restricts what operations are possible with physical address
values, helping prevent mistakes such as mixing them with other
integer quantities.

Arithmetic operations are intentionally not provided; none of the
current users perform address arithmetic in Rust.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1204
Signed-off-by: Albab Hasan <albabhasan276@gmail.com>
---
 rust/kernel/devres.rs        |  4 +--
 rust/kernel/io.rs            | 52 ++++++++++++++++++++++++++++++++----
 rust/kernel/io/resource.rs   |  6 ++---
 rust/kernel/iommu/pgtable.rs |  2 +-
 4 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index 6afe196be42c..0de69157877b 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -72,10 +72,10 @@
 ///     ///
 ///     /// [`paddr`, `paddr` + `SIZE`) must be a valid MMIO region that is mappable into the CPUs
 ///     /// virtual address space.
-///     unsafe fn new(paddr: usize) -> Result<Self>{
+///     unsafe fn new(paddr: PhysAddr) -> Result<Self>{
 ///         // SAFETY: By the safety requirements of this function [`paddr`, `paddr` + `SIZE`) is
 ///         // valid for `ioremap`.
-///         let addr = unsafe { bindings::ioremap(paddr as PhysAddr, SIZE) };
+///         let addr = unsafe { bindings::ioremap(paddr.into(), SIZE) };
 ///         if addr.is_null() {
 ///             return Err(ENOMEM);
 ///         }
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index e5fba6bf6db0..7c35537edf43 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -4,6 +4,8 @@
 //!
 //! C header: [`include/asm-generic/io.h`](srctree/include/asm-generic/io.h)
 
+use core::num::TryFromIntError;
+
 use crate::{
     bindings,
     prelude::*, //
@@ -17,9 +19,48 @@
 
 /// Physical address type.
 ///
-/// This is a type alias to either `u32` or `u64` depending on the config option
+/// This is a transparent wrapper around 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 PhysAddr = bindings::phys_addr_t;
+///
+/// # Examples
+///
+/// ```
+/// use kernel::{bindings, io::PhysAddr};
+///
+/// let raw: bindings::phys_addr_t = 0x1000;
+/// let paddr = PhysAddr::from(raw);
+/// let raw2: bindings::phys_addr_t = paddr.into();
+/// assert_eq!(raw, raw2);
+///
+/// let size = usize::try_from(paddr).unwrap();
+/// assert_eq!(size, 0x1000);
+/// ```
+#[repr(transparent)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
+pub struct PhysAddr(bindings::phys_addr_t);
+
+impl From<bindings::phys_addr_t> for PhysAddr {
+    #[inline]
+    fn from(value: bindings::phys_addr_t) -> Self {
+        Self(value)
+    }
+}
+
+impl From<PhysAddr> for bindings::phys_addr_t {
+    #[inline]
+    fn from(value: PhysAddr) -> Self {
+        value.0
+    }
+}
+
+impl TryFrom<PhysAddr> for usize {
+    type Error = TryFromIntError;
+
+    #[inline]
+    fn try_from(value: PhysAddr) -> Result<Self, Self::Error> {
+        usize::try_from(value.0)
+    }
+}
 
 /// Resource Size type.
 ///
@@ -97,10 +138,10 @@ pub fn maxsize(&self) -> usize {
 ///     ///
 ///     /// [`paddr`, `paddr` + `SIZE`) must be a valid MMIO region that is mappable into the CPUs
 ///     /// virtual address space.
-///     unsafe fn new(paddr: usize) -> Result<Self>{
+///     unsafe fn new(paddr: PhysAddr) -> Result<Self>{
 ///         // SAFETY: By the safety requirements of this function [`paddr`, `paddr` + `SIZE`) is
 ///         // valid for `ioremap`.
-///         let addr = unsafe { bindings::ioremap(paddr as PhysAddr, SIZE) };
+///         let addr = unsafe { bindings::ioremap(paddr.into(), SIZE) };
 ///         if addr.is_null() {
 ///             return Err(ENOMEM);
 ///         }
@@ -127,7 +168,8 @@ pub fn maxsize(&self) -> usize {
 ///
 ///# fn no_run() -> Result<(), Error> {
 /// // SAFETY: Invalid usage for example purposes.
-/// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? };
+/// let addr = PhysAddr::from(0xBAAAAAAD as bindings::phys_addr_t);
+/// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(addr)? };
 /// iomem.write32(0x42, 0x0);
 /// assert!(iomem.try_write32(0x42, 0x0).is_ok());
 /// assert!(iomem.try_write32(0x42, 0x4).is_err());
diff --git a/rust/kernel/io/resource.rs b/rust/kernel/io/resource.rs
index b7ac9faf141d..d703c7317980 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.into(), size) };
     }
 }
 
@@ -113,7 +113,7 @@ pub fn request_region(
         let region = unsafe {
             bindings::__request_region(
                 self.0.get(),
-                start,
+                start.into(),
                 size,
                 name.as_char_ptr(),
                 flags.0 as c_int,
@@ -137,7 +137,7 @@ pub fn size(&self) -> ResourceSize {
     pub fn start(&self) -> PhysAddr {
         let inner = self.0.get();
         // SAFETY: Safe as per the invariants of `Resource`.
-        unsafe { (*inner).start }
+        unsafe { (*inner).start }.into()
     }
 
     /// Returns the name of the resource.
diff --git a/rust/kernel/iommu/pgtable.rs b/rust/kernel/iommu/pgtable.rs
index c88e38fd938a..1d75c09c47bb 100644
--- a/rust/kernel/iommu/pgtable.rs
+++ b/rust/kernel/iommu/pgtable.rs
@@ -182,7 +182,7 @@ pub unsafe fn map_pages(
             (map_pages)(
                 self.raw_ops(),
                 iova,
-                paddr,
+                paddr.into(),
                 pgsize,
                 pgcount,
                 prot as i32,
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] rust: io: convert `PhysAddr` type alias to newtype
  2026-05-04  4:57 [PATCH] rust: io: convert `PhysAddr` type alias to newtype Albab Hasan
@ 2026-05-04 22:08 ` Danilo Krummrich
  2026-05-05  9:17   ` Albab Hasan
  0 siblings, 1 reply; 3+ messages in thread
From: Danilo Krummrich @ 2026-05-04 22:08 UTC (permalink / raw)
  To: Albab Hasan
  Cc: Miguel Ojeda, Alice Ryhl, Daniel Almeida, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, Robin Murphy, rust-for-linux, linux-kernel

Hi Albab,

On Mon May 4, 2026 at 6:57 AM CEST, Albab Hasan wrote:
> Makes `PhysAddr` a newtype wrapper around `bindings::phys_addr_t`.
> This restricts what operations are possible with physical address
> values, helping prevent mistakes such as mixing them with other
> integer quantities.
>
> Arithmetic operations are intentionally not provided; none of the
> current users perform address arithmetic in Rust.
>
> Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> Link: https://github.com/Rust-for-Linux/linux/issues/1204
> Signed-off-by: Albab Hasan <albabhasan276@gmail.com>

Thanks for the patch; a similar patch [1] has already been submitted slightly
before this one.

May I suggest picking up another issue and / or help reviewing the other patch
in [1]?

Thanks,
Danilo

[1] https://lore.kernel.org/driver-core/20260503103050.200526-1-x@2005.tr/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] rust: io: convert `PhysAddr` type alias to newtype
  2026-05-04 22:08 ` Danilo Krummrich
@ 2026-05-05  9:17   ` Albab Hasan
  0 siblings, 0 replies; 3+ messages in thread
From: Albab Hasan @ 2026-05-05  9:17 UTC (permalink / raw)
  To: Danilo Krummrich
  Cc: Miguel Ojeda, Alice Ryhl, Daniel Almeida, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg,
	Trevor Gross, Robin Murphy, rust-for-linux, linux-kernel

Thanks for pointing it out. I'm extremely sorry. i always seem to miss
previously submitted patches.

I'll take on another issue and take a look at the other patch.

Thanks

On Tue, 5 May 2026 at 04:08, Danilo Krummrich <dakr@kernel.org> wrote:
>
> Hi Albab,
>
> On Mon May 4, 2026 at 6:57 AM CEST, Albab Hasan wrote:
> > Makes `PhysAddr` a newtype wrapper around `bindings::phys_addr_t`.
> > This restricts what operations are possible with physical address
> > values, helping prevent mistakes such as mixing them with other
> > integer quantities.
> >
> > Arithmetic operations are intentionally not provided; none of the
> > current users perform address arithmetic in Rust.
> >
> > Suggested-by: Miguel Ojeda <ojeda@kernel.org>
> > Link: https://github.com/Rust-for-Linux/linux/issues/1204
> > Signed-off-by: Albab Hasan <albabhasan276@gmail.com>
>
> Thanks for the patch; a similar patch [1] has already been submitted slightly
> before this one.
>
> May I suggest picking up another issue and / or help reviewing the other patch
> in [1]?
>
> Thanks,
> Danilo
>
> [1] https://lore.kernel.org/driver-core/20260503103050.200526-1-x@2005.tr/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-05  9:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-04  4:57 [PATCH] rust: io: convert `PhysAddr` type alias to newtype Albab Hasan
2026-05-04 22:08 ` Danilo Krummrich
2026-05-05  9:17   ` Albab Hasan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox