summaryrefslogtreecommitdiff
path: root/rust/kernel/io
diff options
context:
space:
mode:
authorGary Guo <gary@garyguo.net>2026-07-06 13:44:16 +0100
committerDanilo Krummrich <dakr@kernel.org>2026-07-11 17:59:31 +0200
commit6461c5776bf0f546cfeaf2a72f1a2f7de27bfe0d (patch)
tree07c347b6aaf47b881be7173943a026a4a2c1c11b /rust/kernel/io
parent65f6abf9fa81617c8455a28b5f07269d883d080a (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.rs20
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,
{