Re: [PATCH 01/12] rust: io: add Region::try_subregion

"Gary Guo" <[email protected]> Wed, 05 Aug 2026 11:43:08 +0100
Newsgroups gmane.linux.kernel,gmane.linux.kernel.rust,gmane.comp.video.dri.devel,gmane.linux.documentation
Message-ID <[email protected]>
On Wed Aug 5, 2026 at 6:44 AM BST, Eliot Courtney wrote:
> Add a helper to get a subregion of an IO view fallibly.
>
> Signed-off-by: Eliot Courtney <[email protected]>
> ---
>  rust/kernel/io.rs | 31 ++++++++++++++++++++++++++++++-
>  1 file changed, 30 insertions(+), 1 deletion(-)

Looks like the case where you need this don't actually require a `Region`
(dynamically sized type) but rather a fixed size window?

In that case the next version of
https://lore.kernel.org/rust-for-linux/[email protected]/
will contain what you need.

Best,
Gary

>
> 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> {