[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