Re: [PATCH 1/8] rust: io: generalize `MmioRaw` to pointer to arbitrary type

Gary Guo
2026-03-26T14:31:39Z

On Thu Mar 26, 2026 at 12:53 PM GMT, Andreas Hindborg wrote:
> "Gary Guo" <gary@kernel.org> writes:
>
>> From: Gary Guo <gary@garyguo.net>
>>
>> Conceptually, `MmioRaw` is just `__iomem *`, so it should work for any
>> types. The existing use case where it represents a region of compile-time
>> known minimum size and run-time known actual size is moved to a custom
>> dynamic-sized type `Region<SIZE>` instead. The `maxsize` method is also
>> renamed to `size` to reflect that it is the actual size (not a bound) of
>> the region.
>>
>> Signed-off-by: Gary Guo <gary@garyguo.net>
>> ---
>> rust/kernel/devres.rs | 7 ++--
>> rust/kernel/io.rs | 84 +++++++++++++++++++++++++++++++++----------
>> rust/kernel/io/mem.rs | 4 +--
>> rust/kernel/pci/io.rs | 4 +--
>> 4 files changed, 74 insertions(+), 25 deletions(-)
>>
>> diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
>> index 9e5f93aed20c..65a4082122af 100644
>> --- a/rust/kernel/devres.rs
>> +++ b/rust/kernel/devres.rs
>> @@ -71,14 +71,15 @@ struct Inner<T> {
>> /// IoKnownSize,
>> /// Mmio,
>> /// MmioRaw,
>> -/// PhysAddr, //
>> +/// PhysAddr,
>> +/// Region, //
>> /// },
>> /// prelude::*,
>> /// };
>> /// use core::ops::Deref;
>> ///
>> /// // See also [`pci::Bar`] for a real example.
>> -/// struct IoMem<const SIZE: usize>(MmioRaw<SIZE>);
>> +/// struct IoMem<const SIZE: usize>(MmioRaw<Region<SIZE>>);
>> ///
>> /// impl<const SIZE: usize> IoMem<SIZE> {
>> /// /// # Safety
>> @@ -93,7 +94,7 @@ struct Inner<T> {
>> /// return Err(ENOMEM);
>> /// }
>> ///
>> -/// Ok(IoMem(MmioRaw::new(addr as usize, SIZE)?))
>> +/// Ok(IoMem(MmioRaw::new_region(addr as usize, SIZE)?))
>
> Should this be `addr.addr()` ?

This (and other occurence) are all existing use of casts introduced probably
before we enabled strict provenance APIs. These should be fixed separately.

>
>> /// }
>> /// }
>> ///
>> diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
>> index fcc7678fd9e3..d7f2145fa9b9 100644
>> --- a/rust/kernel/io.rs
>> +++ b/rust/kernel/io.rs
>> @@ -6,7 +6,8 @@
>>
>> use crate::{
>> bindings,
>> - prelude::*, //
>> + prelude::*,
>> + ptr::KnownSize, //
>> };
>>
>> pub mod mem;
>> @@ -31,39 +32,85 @@
>> /// `CONFIG_PHYS_ADDR_T_64BIT`, and it can be a u64 even on 32-bit architectures.
>> pub type ResourceSize = bindings::resource_size_t;
>>
>> +/// Untyped I/O region.
>> +///
>> +/// This type can be used when an I/O region without known type information has a compile-time known
>> +/// minimum size (and a runtime known actual size).
>> +///
>> +/// The `SIZE` generic parameter indicate the minimum size of the region.
>> +#[repr(transparent)]
>> +pub struct Region<const SIZE: usize = 0> {
>> + inner: [u8],
>> +}
>> +
>> +impl<const SIZE: usize> KnownSize for Region<SIZE> {
>> + #[inline(always)]
>> + fn size(p: *const Self) -> usize {
>> + (p as *const [u8]).len()
>
> Is `as` the only way to cast fat pointers?

Yes. There's no way currently stable way to guarantee a matching metadata with
traits.

Best,
Gary

>
>> + }
>> +}
>> +