Re: [PATCH 2/8] rust: io: generalize `Mmio` to arbitrary type

Gary Guo
2026-03-26T14:32:49Z

On Thu Mar 26, 2026 at 1:04 PM GMT, Andreas Hindborg wrote:
> "Gary Guo" <gary@kernel.org> writes:
>
>> From: Gary Guo <gary@garyguo.net>
>>
>> Currently, `io::Mmio` always represent an untyped region of a compile-time
>> known minimum size, which is roughly equivalent to `void __iomem*` (but
>> with bound checks). However, it is useful to also be to represent I/O
>> memory of a specific type, e.g. `u32 __iomem*` or `struct foo __iomem*`.
>>
>> Thus, make `Mmio` generic on arbitrary `T`, where `T` is a sized type, or a
>> DST that implements `KnownSize`. Similar to the `MmioRaw` change, the
>> existing behaviour is preserved in the form of `Mmio<Region<SIZE>>`. This
>> change brings the MMIO closer to the DMA coherent allocation types that we
>> have, which is already typed.
>>
>> To be able to implement `IoKnownSize`, add a `MIN_SIZE` constant to
>> `KnownSize` trait to represent compile-time known minimum size of a
>> specific type.
>>
>> Signed-off-by: Gary Guo <gary@garyguo.net>
>> ---
>> rust/kernel/devres.rs | 2 +-
>> rust/kernel/io.rs | 63 ++++++++++++++++++++++----------------
>> rust/kernel/io/mem.rs | 4 +--
>> rust/kernel/io/poll.rs | 6 ++--
>> rust/kernel/io/register.rs | 19 +++++++-----
>> rust/kernel/pci/io.rs | 2 +-
>> rust/kernel/ptr.rs | 7 +++++
>> 7 files changed, 64 insertions(+), 39 deletions(-)
>>
>> diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
>> index 65a4082122af..3e22c63efb98 100644
>> --- a/rust/kernel/devres.rs
>> +++ b/rust/kernel/devres.rs
>> @@ -106,7 +106,7 @@ struct Inner<T> {
>> /// }
>> ///
>> /// impl<const SIZE: usize> Deref for IoMem<SIZE> {
>> -/// type Target = Mmio<SIZE>;
>> +/// type Target = Mmio<Region<SIZE>>;
>> ///
>> /// fn deref(&self) -> &Self::Target {
>> /// // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
>> diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
>> index d7f2145fa9b9..5a26b1e7e533 100644
>> --- a/rust/kernel/io.rs
>> +++ b/rust/kernel/io.rs
>> @@ -44,6 +44,8 @@ pub struct Region<const SIZE: usize = 0> {
>> }
>>
>> impl<const SIZE: usize> KnownSize for Region<SIZE> {
>> + const MIN_SIZE: usize = SIZE;
>> +
>> #[inline(always)]
>> fn size(p: *const Self) -> usize {
>> (p as *const [u8]).len()
>> @@ -169,7 +171,7 @@ pub fn size(&self) -> usize {
>> /// }
>> ///
>> /// impl<const SIZE: usize> Deref for IoMem<SIZE> {
>> -/// type Target = Mmio<SIZE>;
>> +/// type Target = Mmio<Region<SIZE>>;
>> ///
>> /// fn deref(&self) -> &Self::Target {
>> /// // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
>> @@ -187,7 +189,7 @@ pub fn size(&self) -> usize {
>> /// # }
>> /// ```
>> #[repr(transparent)]
>> -pub struct Mmio<const SIZE: usize = 0>(MmioRaw<Region<SIZE>>);
>> +pub struct Mmio<T: ?Sized>(MmioRaw<T>);
>
> Why not have the `KnownSize` bound here? I think that would be more clear.
>

There's no need to put bounds on structs unless you need them for `Drop` or use
of assoc types.

Best,
Gary

>
> Best regards,
> Andreas Hindborg