pub struct Mmu { /* private fields */ }Expand description
A sparse, page-granular guest address space.
Unmapped pages are simply absent, so a 64-bit address space costs only what the guest actually touches.
Implementations§
Source§impl Mmu
impl Mmu
pub fn new() -> Self
Sourcepub fn resident_pages(&self) -> usize
pub fn resident_pages(&self) -> usize
Number of pages currently backed by memory. Mostly a test and telemetry hook — it is the honest measure of an MMU’s footprint.
pub fn check_uninit(&self) -> bool
Sourcepub fn set_check_uninit(&mut self, enabled: bool)
pub fn set_check_uninit(&mut self, enabled: bool)
Makes a read of a byte without perm::INIT fault.
pub fn watchpoints_armed(&self) -> bool
Sourcepub fn set_watchpoints_armed(&mut self, armed: bool)
pub fn set_watchpoints_armed(&mut self, armed: bool)
Makes perm::READ_WATCH and perm::WRITE_WATCH bytes fault.
Sourcepub fn tlb_ptr(&mut self) -> *mut u8
pub fn tlb_ptr(&mut self) -> *mut u8
The table compiled code indexes, as a raw pointer.
Valid for as long as this MMU is neither moved nor mutated; a caller takes it immediately before entering compiled code.
Sourcepub fn flush_tlb(&mut self)
pub fn flush_tlb(&mut self)
Drops every cached translation. Called for any change to which pages exist or where they live.
Sourcepub fn cache_translation(&mut self, addr: u64) -> bool
pub fn cache_translation(&mut self, addr: u64) -> bool
Caches the page holding addr so compiled code can reach it directly,
reporting whether it now can.
Only the page’s residence is cached. Permissions are left to the caller — compiled code reads them from the page itself — so this says nothing about whether any particular access is allowed.
Sourcepub fn map(
&mut self,
addr: u64,
len: u64,
permissions: Perm,
) -> Result<(), MemFault>
pub fn map( &mut self, addr: u64, len: u64, permissions: Perm, ) -> Result<(), MemFault>
Maps len bytes at addr with permissions, zero-filling the range.
Follows MAP_FIXED semantics: an already-mapped range is replaced rather
than refused. perm::MAP is added implicitly — a mapped byte is mapped
regardless of what the caller asked for.
Sourcepub fn unmap(&mut self, addr: u64, len: u64) -> Result<(), MemFault>
pub fn unmap(&mut self, addr: u64, len: u64) -> Result<(), MemFault>
Unmaps len bytes at addr, discarding contents and permissions.
A page whose every byte becomes unmapped is dropped outright, so map/unmap churn does not leak pages.
Sourcepub fn protect(
&mut self,
addr: u64,
len: u64,
permissions: Perm,
) -> Result<(), MemFault>
pub fn protect( &mut self, addr: u64, len: u64, permissions: Perm, ) -> Result<(), MemFault>
Changes the permissions of an already-mapped range, preserving contents.
perm::INIT is preserved rather than taken from permissions:
initializedness is a property of the bytes, and mprotect does not
scribble on them. Unmapped bytes in the range fault, matching mprotect.
Sourcepub fn permissions(&self, addr: u64) -> Perm
pub fn permissions(&self, addr: u64) -> Perm
Returns the permissions of a single byte, or perm::NONE if unmapped.
Sourcepub fn read(&self, addr: u64, out: &mut [u8]) -> Result<(), MemFault>
pub fn read(&self, addr: u64, out: &mut [u8]) -> Result<(), MemFault>
Reads out.len() bytes into out, requiring perm::READ.
Sourcepub fn read_code(&self, addr: u64, out: &mut [u8]) -> Result<(), MemFault>
pub fn read_code(&self, addr: u64, out: &mut [u8]) -> Result<(), MemFault>
Reads instruction bytes, requiring perm::EXEC.
The decoder calls this rather than read so that jumping
into a non-executable page faults at the fetch, the way it does on
hardware, instead of silently decoding data as code.
Sourcepub fn write(&mut self, addr: u64, bytes: &[u8]) -> Result<(), MemFault>
pub fn write(&mut self, addr: u64, bytes: &[u8]) -> Result<(), MemFault>
Writes bytes at addr, requiring perm::WRITE and marking the
written bytes initialized.
Sourcepub fn write_unchecked(&mut self, addr: u64, bytes: &[u8], permissions: Perm)
pub fn write_unchecked(&mut self, addr: u64, bytes: &[u8], permissions: Perm)
Writes bytes ignoring permissions, mapping any absent pages.
This is the loader and harness entry point — seeding a guest image or a fixture is not a guest access and must not be refused by the permissions it is itself installing. Never reachable from emulated code.
Sourcepub fn snapshot(&self) -> MmuSnapshot
pub fn snapshot(&self) -> MmuSnapshot
Captures the full contents of the address space.
Deliberately a deep copy: correctness first, and a copy-on-write or dirty-page scheme is a drop-in replacement behind this same pair of methods once snapshot cost shows up in a profile.
Sourcepub fn restore(&mut self, snapshot: &MmuSnapshot)
pub fn restore(&mut self, snapshot: &MmuSnapshot)
Restores a snapshot, discarding every change made since it was taken.
Trait Implementations§
Source§impl Clone for Mmu
Cloning an MMU produces one with an empty TranslationCache.
impl Clone for Mmu
Cloning an MMU produces one with an empty TranslationCache.
A cached entry names a host address inside this MMU’s pages, which the clone does not own. Copying one across would hand compiled code running on the clone a pointer into the original’s memory.