[PATCH 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:

  len(), is_empty()       - byte span and zero-length check
  contains()              - single-address membership in
                           [vm_start, vm_end)
  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 | 41 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/rust/kernel/mm/virt.rs b/rust/kernel/mm/virt.rs
index 63eb730b0b05..5fdc3c616ef3 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,45 @@ pub fn end(&self) -> usize {
         unsafe { (*self.as_ptr()).__bindgen_anon_1.__bindgen_anon_1.vm_end }
     }
 
+    /// Size in bytes (`vm_end - vm_start`).
+    #[inline]
+    pub fn len(&self) -> usize {
+        self.end() - self.start()
+    }
+
+    /// True if `vm_start == vm_end`.
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.start() == self.end()
+    }
+
+    /// True if `addr` lies in `[vm_start, vm_end)`.
+    #[inline]
+    pub fn contains(&self, addr: usize) -> bool {
+        self.start() <= addr && addr < self.end()
+    }
+
+    /// True if `[addr, addr + size)` lies in `[vm_start, vm_end)`; 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.