kernel_alloc/
vmm.rs

1//! Minimal Virtual Memory Manager (VMM) for the kernel.
2//!
3//! This VMM provides basic map/unmap/query operations for a single address space.
4//! It uses the `AddressSpace` abstraction from kernel-vmem, and FrameAlloc/PhysMapper
5//! implementations from kernel-alloc.
6//!
7//! # Example
8//! ```ignore
9//! use kernel_alloc::{frame_alloc::BitmapFrameAlloc, phys_mapper::HhdmPhysMapper, vmm::Vmm};
10//! let mut pmm = BitmapFrameAlloc::new();
11//! let mapper = HhdmPhysMapper;
12//! let mut vmm = Vmm::new(&mapper, &mut pmm);
13//! // Map, unmap, query...
14//! ```
15
16use kernel_vmem::VirtualMemoryPageBits;
17use kernel_vmem::address_space::AddressSpaceMapRegionError;
18use kernel_vmem::addresses::{PhysicalAddress, VirtualAddress};
19use kernel_vmem::{AddressSpace, FrameAlloc, PhysMapper};
20
21/// Minimal kernel virtual memory manager.
22pub struct Vmm<'m, M: PhysMapper, A: FrameAlloc> {
23    aspace: AddressSpace<'m, M>,
24    alloc: &'m mut A,
25}
26
27impl<'m, M: PhysMapper, A: FrameAlloc> Vmm<'m, M, A> {
28    /// # Safety
29    /// - Must run at CPL0 with paging enabled.
30    /// - Assumes CR3 points at a valid PML4 frame.
31    pub unsafe fn from_current(mapper: &'m M, alloc: &'m mut A) -> Self {
32        let aspace = unsafe { AddressSpace::from_current(mapper) };
33        Self { aspace, alloc }
34    }
35
36    /// # Errors
37    /// Allocation fails, e.g. due to OOM.
38    pub fn map_region(
39        &mut self,
40        va: VirtualAddress,
41        pa: PhysicalAddress,
42        len: u64,
43        nonleaf: VirtualMemoryPageBits,
44        leaf: VirtualMemoryPageBits,
45    ) -> Result<(), AddressSpaceMapRegionError> {
46        self.aspace
47            .map_region(self.alloc, va, pa, len, nonleaf, leaf)
48    }
49
50    pub fn unmap_region(&mut self, va: VirtualAddress, len: u64) {
51        self.aspace.unmap_region(va, len);
52    }
53
54    #[must_use]
55    pub fn query(&self, va: VirtualAddress) -> Option<PhysicalAddress> {
56        self.aspace.query(va)
57    }
58}