public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Onur Özkan" <work@onurozkan.dev>
To: x@2005.tr
Cc: "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>,
	"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: Re: [PATCH] rust: io: use newtype for PhysAddr
Date: Sun,  3 May 2026 21:28:26 +0300	[thread overview]
Message-ID: <20260503182827.21492-1-work@onurozkan.dev> (raw)
In-Reply-To: <20260503103050.200526-1-x@2005.tr>

On Sun, 03 May 2026 13:30:50 +0300
x@2005.tr wrote:

> 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)]

Copy and Clone seem never used, please drop them (also see [1]).

[1]: https://rust-for-linux.zulipchat.com/#narrow/channel/509436-Nova/topic/clone.2Fcopy.20additions

Regards,
Onur

> +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
> 

  parent reply	other threads:[~2026-05-03 18:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-03 10:30 [PATCH] rust: io: use newtype for PhysAddr x
2026-05-03 10:43 ` Greg Kroah-Hartman
2026-05-03 18:28 ` Onur Özkan [this message]
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=20260503182827.21492-1-work@onurozkan.dev \
    --to=work@onurozkan.dev \
    --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 \
    --cc=x@2005.tr \
    /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