[PATCH 01/12] rust: io: add Region::try_subregion
From: Eliot Courtney
Date: Wed Aug 05 2026 - 01:46:27 EST
Add a helper to get a subregion of an IO view fallibly.
Signed-off-by: Eliot Courtney <ecourtney@xxxxxxxxxx>
---
rust/kernel/io.rs | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index 95f46bb75f9e..85fbdcc50c8f 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -6,7 +6,8 @@
use core::{
marker::PhantomData,
- mem::MaybeUninit, //
+ mem::MaybeUninit,
+ ops::Range, //
};
use crate::{
@@ -80,6 +81,34 @@ pub fn ptr_try_from_raw_parts_mut(base: *mut u8, size: usize) -> Result<*mut Sel
Ok(Self::ptr_from_raw_parts_mut(base, size))
}
+
+ /// Try to create a subregion of `io` at the given range.
+ ///
+ /// Runtime checks that `range` is within this region, is at least as large as the given new
+ /// minimum size `NEW_SIZE`, and that [`Region`]'s alignment requirements are satisfied.
+ #[inline]
+ pub fn try_subregion<'a, const NEW_SIZE: usize, IO>(
+ io: IO,
+ range: Range<usize>,
+ ) -> Result<<IO::Backend as IoBackend>::View<'a, Region<NEW_SIZE>>>
+ where
+ IO: IoBase<'a, Target = Self>,
+ {
+ let view = io.as_view();
+ let ptr = IO::Backend::as_ptr(view);
+
+ let size = KnownSize::size(ptr);
+ if range.start > size || range.end > size {
+ return Err(EINVAL);
+ }
+ let region = Region::ptr_try_from_raw_parts_mut(
+ ptr.cast::<u8>().wrapping_add(range.start),
+ range.len(),
+ )?;
+
+ // SAFETY: We have checked bounds and alignment, so this is a valid projection.
+ Ok(unsafe { IO::Backend::project_view(view, region) })
+ }
}
impl<const SIZE: usize> KnownSize for Region<SIZE> {
--
2.55.0