[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