Skip to main content

RecursivePageTable

Struct RecursivePageTable 

pub struct RecursivePageTable<'a> {
    p4: &'a mut PageTable,
    recursive_index: PageTableIndex,
}
Expand description

A recursive page table is a last level page table with an entry mapped to the table itself.

This recursive mapping allows accessing all page tables in the hierarchy:

  • To access the level 4 page table, we “loop“ (i.e. follow the recursively mapped entry) four times.
  • To access a level 3 page table, we “loop” three times and then use the level 4 index.
  • To access a level 2 page table, we “loop” two times, then use the level 4 index, then the level 3 index.
  • To access a level 1 page table, we “loop” once, then use the level 4 index, then the level 3 index, then the level 2 index.

This struct implements the Mapper trait.

The page table flags PRESENT and WRITABLE are always set for higher level page table entries, even if not specified, because the design of the recursive page table requires it.

Fields§

§p4: &'a mut PageTable§recursive_index: PageTableIndex

Implementations§

§

impl<'a> RecursivePageTable<'a>

pub fn new( table: &'a mut PageTable, ) -> Result<RecursivePageTable<'a>, InvalidPageTable>

Creates a new RecursivePageTable from the passed level 4 PageTable.

The page table must be recursively mapped, that means:

  • The page table must have one recursive entry, i.e. an entry that points to the table itself.
    • The reference must use that “loop”, i.e. be of the form 0o_xxx_xxx_xxx_xxx_0000 where xxx is the recursive entry.
  • The page table must be active, i.e. the CR3 register must contain its physical address.

Otherwise Err(()) is returned.

§Safety

Note that creating a PageTable with recursive index 511 is unsound because allocating the last byte of the address space can lead to pointer overflows and undefined behavior. For more details, see the discussions on Zulip and in the unsafe-code-guidelines repo.

pub unsafe fn new_unchecked( table: &'a mut PageTable, recursive_index: PageTableIndex, ) -> RecursivePageTable<'a>

Creates a new RecursivePageTable without performing any checks.

§Safety

The given page table must be a level 4 page table that is active in the CPU (i.e. loaded in the CR3 register). The recursive_index parameter must be the index of the recursively mapped entry of that page table.

pub fn level_4_table(&self) -> &PageTable

Returns an immutable reference to the wrapped level 4 PageTable instance.

pub fn level_4_table_mut(&mut self) -> &mut PageTable

Returns a mutable reference to the wrapped level 4 PageTable instance.

Trait Implementations§

§

impl CleanUp for RecursivePageTable<'_>

§

unsafe fn clean_up<D>(&mut self, frame_deallocator: &mut D)

Remove all empty P1-P3 tables Read more
§

unsafe fn clean_up_addr_range<D>( &mut self, range: PageRangeInclusive, frame_deallocator: &mut D, )

Remove all empty P1-P3 tables in a certain range Read more
§

impl<'a> Debug for RecursivePageTable<'a>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Mapper<Size1GiB> for RecursivePageTable<'_>

§

unsafe fn map_to_with_table_flags<A>( &mut self, page: Page<Size1GiB>, frame: PhysFrame<Size1GiB>, flags: PageTableFlags, parent_table_flags: PageTableFlags, allocator: &mut A, ) -> Result<MapperFlush<Size1GiB>, MapToError<Size1GiB>>

Creates a new mapping in the page table. Read more
§

fn unmap( &mut self, page: Page<Size1GiB>, ) -> Result<(PhysFrame<Size1GiB>, MapperFlush<Size1GiB>), UnmapError>

Removes a mapping from the page table and returns the frame that used to be mapped. Read more
§

unsafe fn update_flags( &mut self, page: Page<Size1GiB>, flags: PageTableFlags, ) -> Result<MapperFlush<Size1GiB>, FlagUpdateError>

Updates the flags of an existing mapping. Read more
§

unsafe fn set_flags_p4_entry( &mut self, page: Page<Size1GiB>, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page level 4 table entry Read more
§

unsafe fn set_flags_p3_entry( &mut self, _page: Page<Size1GiB>, _flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 3 entry Read more
§

unsafe fn set_flags_p2_entry( &mut self, _page: Page<Size1GiB>, _flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 2 entry Read more
§

fn translate_page( &self, page: Page<Size1GiB>, ) -> Result<PhysFrame<Size1GiB>, TranslateError>

Return the frame that the specified page is mapped to. Read more
§

unsafe fn map_to<A>( &mut self, page: Page<S>, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized, A: FrameAllocator<Size4KiB> + ?Sized,

Creates a new mapping in the page table. Read more
§

unsafe fn identity_map<A>( &mut self, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized + Mapper<S>, A: FrameAllocator<Size4KiB> + ?Sized, S: PageSize,

Maps the given frame to the virtual page with the same address. Read more
§

impl Mapper<Size2MiB> for RecursivePageTable<'_>

§

unsafe fn map_to_with_table_flags<A>( &mut self, page: Page<Size2MiB>, frame: PhysFrame<Size2MiB>, flags: PageTableFlags, parent_table_flags: PageTableFlags, allocator: &mut A, ) -> Result<MapperFlush<Size2MiB>, MapToError<Size2MiB>>

Creates a new mapping in the page table. Read more
§

fn unmap( &mut self, page: Page<Size2MiB>, ) -> Result<(PhysFrame<Size2MiB>, MapperFlush<Size2MiB>), UnmapError>

Removes a mapping from the page table and returns the frame that used to be mapped. Read more
§

unsafe fn update_flags( &mut self, page: Page<Size2MiB>, flags: PageTableFlags, ) -> Result<MapperFlush<Size2MiB>, FlagUpdateError>

Updates the flags of an existing mapping. Read more
§

unsafe fn set_flags_p4_entry( &mut self, page: Page<Size2MiB>, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page level 4 table entry Read more
§

unsafe fn set_flags_p3_entry( &mut self, page: Page<Size2MiB>, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 3 entry Read more
§

unsafe fn set_flags_p2_entry( &mut self, _page: Page<Size2MiB>, _flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 2 entry Read more
§

fn translate_page( &self, page: Page<Size2MiB>, ) -> Result<PhysFrame<Size2MiB>, TranslateError>

Return the frame that the specified page is mapped to. Read more
§

unsafe fn map_to<A>( &mut self, page: Page<S>, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized, A: FrameAllocator<Size4KiB> + ?Sized,

Creates a new mapping in the page table. Read more
§

unsafe fn identity_map<A>( &mut self, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized + Mapper<S>, A: FrameAllocator<Size4KiB> + ?Sized, S: PageSize,

Maps the given frame to the virtual page with the same address. Read more
§

impl Mapper<Size4KiB> for RecursivePageTable<'_>

§

unsafe fn map_to_with_table_flags<A>( &mut self, page: Page, frame: PhysFrame, flags: PageTableFlags, parent_table_flags: PageTableFlags, allocator: &mut A, ) -> Result<MapperFlush<Size4KiB>, MapToError<Size4KiB>>

Creates a new mapping in the page table. Read more
§

fn unmap( &mut self, page: Page, ) -> Result<(PhysFrame, MapperFlush<Size4KiB>), UnmapError>

Removes a mapping from the page table and returns the frame that used to be mapped. Read more
§

unsafe fn update_flags( &mut self, page: Page, flags: PageTableFlags, ) -> Result<MapperFlush<Size4KiB>, FlagUpdateError>

Updates the flags of an existing mapping. Read more
§

unsafe fn set_flags_p4_entry( &mut self, page: Page, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page level 4 table entry Read more
§

unsafe fn set_flags_p3_entry( &mut self, page: Page, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 3 entry Read more
§

unsafe fn set_flags_p2_entry( &mut self, page: Page, flags: PageTableFlags, ) -> Result<MapperFlushAll, FlagUpdateError>

Set the flags of an existing page table level 2 entry Read more
§

fn translate_page(&self, page: Page) -> Result<PhysFrame, TranslateError>

Return the frame that the specified page is mapped to. Read more
§

unsafe fn map_to<A>( &mut self, page: Page<S>, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized, A: FrameAllocator<Size4KiB> + ?Sized,

Creates a new mapping in the page table. Read more
§

unsafe fn identity_map<A>( &mut self, frame: PhysFrame<S>, flags: PageTableFlags, frame_allocator: &mut A, ) -> Result<MapperFlush<S>, MapToError<S>>
where Self: Sized + Mapper<S>, A: FrameAllocator<Size4KiB> + ?Sized, S: PageSize,

Maps the given frame to the virtual page with the same address. Read more
§

impl Translate for RecursivePageTable<'_>

§

fn translate(&self, addr: VirtAddr) -> TranslateResult

Return the frame that the given virtual address is mapped to and the offset within that frame. Read more
§

fn translate_addr(&self, addr: VirtAddr) -> Option<PhysAddr>

Translates the given virtual address to the physical address that it maps to. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> MapperAllSizes for T

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.