From: x@2005.tr
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Danilo Krummrich <dakr@kernel.org>,
Miguel Ojeda <ojeda@kernel.org>,
Daniel Almeida <daniel.almeida@collabora.com>,
Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>
Cc: "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>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Robin Murphy" <robin.murphy@arm.com>,
driver-core@lists.linux.dev, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org, iommu@lists.linux.dev
Subject: [PATCH] rust: io: use newtype for PhysAddr
Date: Sun, 3 May 2026 13:30:50 +0300 [thread overview]
Message-ID: <20260503103050.200526-1-x@2005.tr> (raw)
From: Favilances Noir <favilances@proton.me>
From: Favilances Noir <favilances@proton.me>
Currently, `PhysAddr` is a type alias for `phys_addr_t`. This means
that physical addresses can be mixed with unrelated integer values
without Rust noticing.
Use a transparent newtype for `PhysAddr` instead, and update the
affected call sites to perform explicit raw conversions at the FFI
boundary.
This keeps the existing `phys_addr_t` representation while making
physical addresses distinct in Rust type checking.
Signed-off-by: Favilances Noir <favilances@proton.me>
---
rust/kernel/devres.rs | 8 +++++---
rust/kernel/io.rs | 30 ++++++++++++++++++++++++------
rust/kernel/io/mem.rs | 4 ++--
rust/kernel/io/resource.rs | 6 +++---
rust/kernel/iommu/pgtable.rs | 2 +-
5 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index 9e5f93aed20c..beb3723d2519 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -85,10 +85,10 @@ struct Inner<T> {
/// ///
/// /// [`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_raw(), SIZE) };
/// if addr.is_null() {
/// return Err(ENOMEM);
/// }
@@ -114,7 +114,9 @@ struct Inner<T> {
/// }
/// # fn no_run(dev: &Device<Bound>) -> Result<(), Error> {
/// // SAFETY: Invalid usage for example purposes.
-/// let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? };
+/// let iomem = unsafe {
+/// IoMem::<{ core::mem::size_of::<u32>() }>::new(PhysAddr::from_raw(0xBAAAAAAD))?
+/// };
/// let devres = Devres::new(dev, iomem)?;
///
/// let res = devres.try_access().ok_or(ENXIO)?;
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index fcc7678fd9e3..2d55ee93caae 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -21,9 +21,25 @@
/// Physical address 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 PhysAddr = bindings::phys_addr_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.
+#[repr(transparent)]
+#[derive(Clone, Copy)]
+pub struct PhysAddr(bindings::phys_addr_t);
+
+impl PhysAddr {
+ /// Creates a physical address from the raw C type.
+ #[inline]
+ pub const fn from_raw(value: bindings::phys_addr_t) -> Self {
+ Self(value)
+ }
+
+ /// Turns this physical address into the raw C type.
+ #[inline]
+ pub const fn into_raw(self) -> bindings::phys_addr_t {
+ self.0
+ }
+}
/// Resource Size type.
///
@@ -101,10 +117,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_raw(), SIZE) };
/// if addr.is_null() {
/// return Err(ENOMEM);
/// }
@@ -131,7 +147,9 @@ 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 iomem = unsafe {
+/// IoMem::<{ core::mem::size_of::<u32>() }>::new(PhysAddr::from_raw(0xBAAAAAAD))?
+/// };
/// 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/mem.rs b/rust/kernel/io/mem.rs
index 7dc78d547f7a..f21f9038b297 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -254,12 +254,12 @@ fn ioremap(resource: &Resource) -> Result<Self> {
// SAFETY:
// - `res_start` and `size` are read from a presumably valid `struct resource`.
// - `size` is known not to be zero at this point.
- unsafe { bindings::ioremap_np(res_start, size) }
+ unsafe { bindings::ioremap_np(res_start.into_raw(), size) }
} else {
// SAFETY:
// - `res_start` and `size` are read from a presumably valid `struct resource`.
// - `size` is known not to be zero at this point.
- unsafe { bindings::ioremap(res_start, size) }
+ unsafe { bindings::ioremap(res_start.into_raw(), size) }
};
if addr.is_null() {
diff --git a/rust/kernel/io/resource.rs b/rust/kernel/io/resource.rs
index b7ac9faf141d..5dda1061db68 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_raw(), size) };
}
}
@@ -113,7 +113,7 @@ pub fn request_region(
let region = unsafe {
bindings::__request_region(
self.0.get(),
- start,
+ start.into_raw(),
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 }
+ PhysAddr::from_raw(unsafe { (*inner).start })
}
/// Returns the name of the resource.
diff --git a/rust/kernel/iommu/pgtable.rs b/rust/kernel/iommu/pgtable.rs
index c88e38fd938a..ae724ca1e8ad 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_raw(),
pgsize,
pgcount,
prot as i32,
--
2.54.0
next reply other threads:[~2026-05-03 10:37 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-03 10:30 x [this message]
2026-05-03 10:43 ` [PATCH] rust: io: use newtype for PhysAddr Greg Kroah-Hartman
2026-05-03 18:28 ` Onur Özkan
2026-05-03 18:45 ` Danilo Krummrich
2026-05-03 18:52 ` Onur Özkan
2026-05-04 11:14 ` [PATCH v2] " x
2026-05-04 22:04 ` Danilo Krummrich
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=20260503103050.200526-1-x@2005.tr \
--to=x@2005.tr \
--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=driver-core@lists.linux.dev \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=robin.murphy@arm.com \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=will@kernel.org \
/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