diff options
| author | Gary Guo <gary@garyguo.net> | 2026-07-06 13:44:16 +0100 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2026-07-11 17:59:31 +0200 |
| commit | 6461c5776bf0f546cfeaf2a72f1a2f7de27bfe0d (patch) | |
| tree | 07c347b6aaf47b881be7173943a026a4a2c1c11b /rust/kernel/io | |
| parent | 65f6abf9fa81617c8455a28b5f07269d883d080a (diff) | |
rust: io: restrict untyped IO access and `register!` to `Region`
Currently the `Io` trait exposes a bunch of untyped IO accesses, but if the
`Io` region itself is typed, then it might be weird to have
let io: Mmio<u32> = /* ... */;
io.read8(1);
while not unsound, it is surely strange. Thus, restrict the untyped methods
and also the register macro to `Region` type only.
Implement it by adding a generic type to `IoLoc` indicating allowed base
types. This also paves the way to add typed register blocks in the future;
for example, we could use this mechanism to block driver A's `register!()`
generated macro from being used on driver B's MMIO. The same mechanism
could be used for relative IO registers. These are future opportunities,
and for now restrict everything to require `IoLoc<Region<SIZE>, _>`.
Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/rust-for-linux/DHLB3RO3OSF5.2R7F27U99BKLN@nvidia.com/
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Link: https://patch.msgid.link/20260706-io_projection-v6-3-72cd5d055d54@garyguo.net
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'rust/kernel/io')
| -rw-r--r-- | rust/kernel/io/register.rs | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs index f924c7c7c1db..3122b17098ee 100644 --- a/rust/kernel/io/register.rs +++ b/rust/kernel/io/register.rs @@ -113,6 +113,8 @@ use crate::{ io::IoLoc, // }; +use super::Region; + /// Trait implemented by all registers. pub trait Register: Sized { /// Backing primitive type of the register. @@ -129,7 +131,7 @@ pub trait FixedRegister: Register {} /// Allows `()` to be used as the `location` parameter of [`Io::write`](super::Io::write) when /// passing a [`FixedRegister`] value. -impl<T> IoLoc<T> for () +impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for () where T: FixedRegister, { @@ -143,7 +145,7 @@ where /// A [`FixedRegister`] carries its location in its type. Thus `FixedRegister` values can be used /// as an [`IoLoc`]. -impl<T> IoLoc<T> for T +impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for T where T: FixedRegister, { @@ -168,7 +170,7 @@ impl<T: FixedRegister> FixedRegisterLoc<T> { } } -impl<T> IoLoc<T> for FixedRegisterLoc<T> +impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for FixedRegisterLoc<T> where T: FixedRegister, { @@ -239,7 +241,7 @@ where } } -impl<T, B> IoLoc<T> for RelativeRegisterLoc<T, B> +impl<const SIZE: usize, T, B> IoLoc<Region<SIZE>, T> for RelativeRegisterLoc<T, B> where T: RelativeRegister, B: RegisterBase<T::BaseFamily> + ?Sized, @@ -283,7 +285,7 @@ impl<T: RegisterArray> RegisterArrayLoc<T> { } } -impl<T> IoLoc<T> for RegisterArrayLoc<T> +impl<const SIZE: usize, T> IoLoc<Region<SIZE>, T> for RegisterArrayLoc<T> where T: RegisterArray, { @@ -370,7 +372,7 @@ where } } -impl<T, B> IoLoc<T> for RelativeRegisterArrayLoc<T, B> +impl<const SIZE: usize, T, B> IoLoc<Region<SIZE>, T> for RelativeRegisterArrayLoc<T, B> where T: RelativeRegisterArray, B: RegisterBase<T::BaseFamily> + ?Sized, @@ -387,18 +389,18 @@ where /// which to write it. /// /// Implementors can be used with [`Io::write_reg`](super::Io::write_reg). -pub trait LocatedRegister { +pub trait LocatedRegister<Base: ?Sized> { /// Register value to write. type Value: Register; /// Full location information at which to write the value. - type Location: IoLoc<Self::Value>; + type Location: IoLoc<Base, Self::Value>; /// Consumes `self` and returns a `(location, value)` tuple describing a valid I/O write /// operation. fn into_io_op(self) -> (Self::Location, Self::Value); } -impl<T> LocatedRegister for T +impl<const SIZE: usize, T> LocatedRegister<Region<SIZE>> for T where T: FixedRegister, { |
