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

"Gary Guo" <[email protected]>
Newsgroups dev.linux.lists.driver-core,dev.linux.lists.nova-gpu,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux
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> {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.