From: Albab Hasan <albabhasan276@gmail.com>
To: Miguel Ojeda <ojeda@kernel.org>
Cc: "Albab Hasan" <albabhasan276@gmail.com>,
"Danilo Krummrich" <dakr@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Trevor Gross" <tmgross@umich.edu>,
"Robin Murphy" <robin.murphy@arm.com>,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] rust: io: convert `PhysAddr` type alias to newtype
Date: Mon, 4 May 2026 10:57:03 +0600 [thread overview]
Message-ID: <20260504045714.59248-1-albabhasan276@gmail.com> (raw)
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
next reply other threads:[~2026-05-04 4:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-04 4:57 Albab Hasan [this message]
2026-05-04 22:08 ` [PATCH] rust: io: convert `PhysAddr` type alias to newtype Danilo Krummrich
2026-05-05 9:17 ` Albab Hasan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260504045714.59248-1-albabhasan276@gmail.com \
--to=albabhasan276@gmail.com \
--cc=a.hindborg@kernel.org \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=robin.murphy@arm.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox