summaryrefslogtreecommitdiff
path: root/rust/kernel/mm.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/kernel/mm.rs')
-rw-r--r--rust/kernel/mm.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
index eda7a479cff7..f1689ccb3740 100644
--- a/rust/kernel/mm.rs
+++ b/rust/kernel/mm.rs
@@ -18,6 +18,8 @@ use crate::{
};
use core::{ops::Deref, ptr::NonNull};
+pub mod virt;
+
/// A wrapper for the kernel's `struct mm_struct`.
///
/// This represents the address space of a userspace process, so each process has one `Mm`
@@ -201,6 +203,27 @@ pub struct MmapReadGuard<'a> {
_nts: NotThreadSafe,
}
+impl<'a> MmapReadGuard<'a> {
+ /// Look up a vma at the given address.
+ #[inline]
+ pub fn vma_lookup(&self, vma_addr: usize) -> Option<&virt::VmaRef> {
+ // SAFETY: By the type invariants we hold the mmap read guard, so we can safely call this
+ // method. Any value is okay for `vma_addr`.
+ let vma = unsafe { bindings::vma_lookup(self.mm.as_raw(), vma_addr) };
+
+ if vma.is_null() {
+ None
+ } else {
+ // SAFETY: We just checked that a vma was found, so the pointer references a valid vma.
+ //
+ // Furthermore, the returned vma is still under the protection of the read lock guard
+ // and can be used while the mmap read lock is still held. That the vma is not used
+ // after the MmapReadGuard gets dropped is enforced by the borrow-checker.
+ unsafe { Some(virt::VmaRef::from_raw(vma)) }
+ }
+ }
+}
+
impl Drop for MmapReadGuard<'_> {
#[inline]
fn drop(&mut self) {