[PATCH v2 1/2] rust: mm: add VmaRef range query helpers

liujinlong <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
From: liujinlong <[email protected]>

Add helpers on VmaRef to query the virtual address span and test
address membership:

  range()               - returns core::ops::Range<usize> covering
                          [vm_start, vm_end), giving callers access
                          to all standard Range methods (len(),
                          contains(), iteration, etc.)
  contains_range()      - sub-range membership, returns false
                          on overflow
  is_page_aligned()     - PAGE_SIZE alignment for one address
  is_page_aligned_range() - PAGE_SIZE alignment for addr and size

is_page_aligned() and is_page_aligned_range() are associated
functions rather than methods, since they do not reference any VMA
state.  They live here instead of a separate utility module to
keep the page-alignment helpers close to the range-checking code
that often uses them.

Signed-off-by: liujinlong <[email protected]>
---
 rust/kernel/mm/virt.rs | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
index 63eb730b0b05..c11fb4c089bd 100644
--- a/rust/kernel/mm/virt.rs
+++ b/rust/kernel/mm/virt.rs
@@ -18,7 +18,7 @@
     bindings,
     error::{code::EINVAL, to_result, Result},
     mm::MmWithUser,
-    page::Page,
+    page::{Page, PAGE_SIZE},
     types::Opaque,
 };
 
@@ -92,6 +92,36 @@ pub fn end(&self) -> usize {
         unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_end }
     }
 
+    /// Return the virtual address range `[vm_start, vm_end)` of this
+    /// VMA as a [`Range<usize>`], giving callers access to all the
+    /// standard range methods (`len()`, `contains()`, iteration, etc.).
+    #[inline]
+    pub fn range(&self) -> core::ops::Range<usize> {
+        self.start()..self.end()
+    }
+
+    /// True if `[addr, addr + size)` lies in `[vm_start, vm_end)`;
+    /// returns false on overflow.
+    #[inline]
+    pub fn contains_range(&self, addr: usize, size: usize) -> bool {
+        let Some(end) = addr.checked_add(size) else {
+            return false;
+        };
+        self.start() <= addr && end <= self.end()
+    }
+
+    /// True if `addr` is `PAGE_SIZE`-aligned.
+    #[inline]
+    pub fn is_page_aligned(addr: usize) -> bool {
+        addr % PAGE_SIZE == 0
+    }
+
+    /// True if `addr` and `size` are both page-aligned.
+    #[inline]
+    pub fn is_page_aligned_range(addr: usize, size: usize) -> bool {
+        Self::is_page_aligned(addr) && Self::is_page_aligned(size)
+    }
+
     /// Zap pages in the given page range.
     ///
     /// This clears page table mappings for the range at the leaf level, leaving all other page
-- 
2.25.1
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.