Re: [PATCH v4 09/20] rust: io: use view types instead of addresses for `Io`

From: Gary Guo

Date: Sun Jun 21 2026 - 11:41:30 EST


On Sun Jun 21, 2026 at 10:17 AM BST, Alexandre Courbot wrote:
> On Tue Jun 16, 2026 at 11:50 PM JST, Gary Guo wrote:
>> I think this could be solved by adding `U: FromBytes + IntoBytes`? We're only
>> using it form primitives anyway.
>>
>> Technically, even without the bound, nothing can cause any breakage anyway,
>> given even after the full series to do things with the view you'd need to use
>> `copy_read`/`copy_write` which themselves carry the `FromBytes`/`IntoBytes`
>> bound.
>
> I should have provided an example - here is a minimal one showing the
> issue. I have put this module into nova-core and it builds just fine:
>
> #[allow(dead_code)]
> mod foo {
> use kernel::io::{Io, IoLoc, Mmio};
> use kernel::prelude::*;
>
> #[repr(C)]
> struct Regs {
> status: u64,
> }
>
> fn io_addr_abuse(regs: Mmio<'_, Regs>) -> Result<u32> {
> let high_half: Mmio<'_, u32> = regs.io_addr::<u32>(4)?;
>
> Ok(high_half.read_val())
> }
> }
>
> As you can see, this lets a 32-bit access be done on the upper half of a
> 64-bit register, which sounds like it should not be allowed? Similarly
> one could change register types, and so on. This might not be "unsafe"
> in the sense that it is still aligned and in bounds, but it lets the
> structure set by the type system be bypassed. It could also potentially
> be a violation of the hardware contract if the access width is relevant
> for this particular address.

I see no reason to prevent any of the case, this can be done by `try_cast()` API
as well. If we need to take access width restriction and other restrictions into
consideration, then a lot of API cannot be exposed at all. E.g. it is not okay
to add `copy_read`/`copy_write` like the patch 19, because it uses
memcpy_from/toio which is possibility doing byte-width access.

in my opinion think people should be able to type casting without reaching out
to `unsafe` if it's not UB. Similar to the logic on why we have `zerocopy` that
allows casting between to types, these are "bypassing the typesystem" as well!

>
> The same thing can be achieved using `IoLoc`:
>
> struct HighHalfOfStatus;
>
> impl IoLoc<Regs, u32> for HighHalfOfStatus {
> type IoType = u32;
>
> fn offset(self) -> usize {
> 4
> }
> }
>
> fn ioloc_abuse(regs: Mmio<'_, Regs>) -> Result<u32> {
> Ok(regs.read(HighHalfOfStatus))
> }

This can also be done just by adding another `register!()`.

Given that `Io` is currently completely untyped, I think we shouldn't attempt to
immediately make `Io` super restrictive in one go. We can revisit if it turns
out to be a problem.

Best,
Gary