LazyPager

Struct LazyPager 

Source
pub struct LazyPager {}
Expand description

The LazyPager structure implements lazy paging, where memory pages are mapped only when accessed (on page fault), instead of during mmap calls.

Implementations§

Source§

impl LazyPager

Source

pub fn do_copy_on_write( &mut self, page_table: &mut PageTable, reason: &PageFaultReason, ) -> Result<(), KernelError>

Handles a copy-on-write (COW) page fault by creating a private copy of the faulted page.

This method is invoked when a process attempts to write to a page that is currently shared and marked read-only as part of a copy-on-write mapping. It ensures that the faulting process receives its own writable copy of the page while preserving the original contents for other processes that may still share the original page.

§Steps:
  1. Find write-protected page table entry with PageTable::walk_mut.
  2. Allocates a new page and copies the contents of the original page into it.
  3. Updates the page table to point to the new page with write permissions.
  4. Invalidates the TLB entry for the faulting address to ensure the CPU reloads the mapping.
§Parameters
  • page_table: The faulting process’s page table.
  • reason: Information about the page fault, including the faulting address and access type.
Source

pub fn write_protect_ptes( mm_struct: &mut MmStruct<LazyPager>, ) -> Result<MmStruct<LazyPager>, KernelError>

Applies write-protection to all user-accessible pages in the memory layout.

This method is called during fork to prepare the address space for copy-on-write semantics. It traverses the entire virtual memory layout, identifies writable mappings, and rewrites their page table entries (PTEs) as read-only. This allows parent and child processes to safely share physical memory until one performs a write, at which point a private copy is created.

After modifying the page tables, stale entries in the Translation Lookaside Buffer (TLB) are invalidated to ensure that the CPU observes the new permissions by calling tlb_shutdown.

§Parameters
  • mm_struct: The current process’s memory layout, including its LazyPager state.
§Returns
  • A new MmStruct representing the forked child process, with updated page table mappings.
Source§

impl LazyPager

Source

pub fn do_lazy_load( &mut self, page_table: &mut PageTable, reason: &PageFaultReason, ) -> Result<(), KernelError>

Handles a page fault by performing lazy loading of the faulting page.

This method is invoked when a page fault occurs due to demand paging— that is, when a program accesses a virtual address that is validly mapped but not yet backed by a physical page. This function allocates and installs the corresponding page into the page table on demand.

The kernel may initialize the page from a file (if the mapping was file-backed) or zero-fill it (if anonymous). The newly loaded page must also be mapped with the correct permissions, as defined at the time of the original mmap.

§Parameters
  • page_table: The page table of the faulting process.
  • reason: The PageFaultReason that describes the faulting reason.

This must indicate a demand paging fault.

§Returns
  • Ok(()) if the page was successfully loaded and mapped.
  • Err(KernelError): If the faulting address is invalid, out of bounds, or if page allocation fails.
Source

pub fn handle_page_fault( &mut self, page_table: &mut PageTable, reason: &PageFaultReason, ) -> Result<(), KernelError>

Handles a page fault by allocating a physical page and updating the page table.

This function is called when a process accesses a lazily mapped page that has not been allocated yet. The function must:

  1. Identify the faulting virtual address from PageFaultReason.
  2. Check if the address was previously recorded in mmap metadata.
  3. Allocate a new physical page.
  4. Update the page table with the new mapping.
  5. Invalidate the TLB entry to ensure memory consistency.
§Arguments
  • page_table: Mutable reference to the page table.
  • reason: The cause of the page fault, including the faulting address.

If the faulting address was not mapped via mmap, the system should trigger a segmentation fault, resulting process exit.

Trait Implementations§

Source§

impl Clone for LazyPager

Source§

fn clone(&self) -> LazyPager

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Pager for LazyPager

Source§

fn new() -> Self

Creates a new instance of LazyPager.

This constructor initializes an empty LazyPager struct.

Source§

fn mmap( &mut self, _page_table: &mut PageTable, addr: Va, size: usize, prot: Permission, file: Option<&RegularFile>, offset: usize, ) -> Result<usize, KernelError>

Memory map function (mmap) for lazy paging.

This function creates the metadata for memory mappings, and delegate the real mappings on page fault.

Returns an address for the mapped area.

Source§

fn munmap( &mut self, page_table: &mut PageTable, addr: Va, ) -> Result<usize, KernelError>

Memory unmap function (munmap) for lazy paging.

This function would unmap a previously mapped memory region, releasing any associated resources.

§Returns
Source§

fn get_user_page( &mut self, page_table: &mut PageTable, addr: Va, ) -> Option<(PageRef<'_>, Permission)>

Find a mapped page at the given virtual address. If the page for addr is not loaded, load it and then returns.

This function searches for a memory page mapped at addr and, if found, returns a tuple of PageRef to the page and its corresponding Permission flags.

§Parameters
  • addr: The virtual address (Va) of the page to find.
§Returns
  • Some(([PageRef], [Permission])): If the page is found.
  • None: If no mapped page is found at addr.
Source§

fn access_ok(&self, va: Va, is_write: bool) -> bool

Checks whether access to the given virtual address is permitted.

This function verifies that a virtual address va is part of a valid memory mapping and that the requested access type (read or write) is allowed by the page’s protection flags. Note that this does not trigger the demand paging.

Auto Trait Implementations§

§

impl Freeze for LazyPager

§

impl RefUnwindSafe for LazyPager

§

impl Send for LazyPager

§

impl Sync for LazyPager

§

impl Unpin for LazyPager

§

impl UnwindSafe for LazyPager

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.