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

Eliot Courtney <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,dev.linux.lists.driver-core,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]>
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(-)

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