Struct memory::MappedPages

source ·
pub struct MappedPages { /* private fields */ }
Expand description

Represents a contiguous range of virtual memory pages that are currently mapped. A MappedPages object can only have a single range of contiguous pages, not multiple disjoint ranges. This does not guarantee that its pages are mapped to frames that are contiguous in physical memory.

This object also represents ownership of those pages; if this object falls out of scope, it will be dropped, and the pages will be unmapped and then also de-allocated. Thus, it ensures memory safety by guaranteeing that this object must be held in order to access data stored in these mapped pages, much like a guard type.

Implementations§

source§

impl MappedPages

source

pub const fn empty() -> MappedPages

Returns an empty MappedPages object that performs no allocation or mapping actions. Can be used as a placeholder, but will not permit any real usage.

source

pub fn flags(&self) -> PteFlagsArch

Returns the flags that describe this MappedPages page table permissions.

source

pub fn merge( &mut self, mp: MappedPages ) -> Result<(), (&'static str, MappedPages)>

Merges the given MappedPages object mp into this MappedPages object (self).

For example, if you have the following MappedPages objects:

  • this mapping, with a page range including one page at 0x2000
  • mp, with a page range including two pages at 0x3000 and 0x4000 Then this MappedPages object will be updated to cover three pages from [0x2000:0x4000] inclusive.

In addition, the MappedPages objects must have the same flags and page table root frame (i.e., they must have all been mapped using the same set of page tables).

If an error occurs, such as the mappings not being contiguous or having different flags, then a tuple including an error message and the original mp will be returned, which prevents the mp from being dropped.

Note

No remapping actions or page reallocations will occur on either a failure or a success.

source

pub fn split( self, at_page: Page ) -> Result<(MappedPages, MappedPages), MappedPages>

Splits this MappedPages into two separate MappedPages objects:

  • [beginning : at_page - 1]
  • [at_page : end]

This function follows the behavior of core::slice::split_at(), thus, either one of the returned MappedPages objects may be empty.

  • If at_page == self.pages.start, the first returned MappedPages object will be empty.
  • If at_page == self.pages.end + 1, the second returned MappedPages object will be empty.

Returns an Err containing this MappedPages (self) if at_page is not within its bounds.

Note

No remapping actions or page reallocations will occur on either a failure or a success.

source

pub fn deep_copy<F: Into<PteFlagsArch>>( &self, active_table_mapper: &mut Mapper, new_flags: Option<F> ) -> Result<MappedPages, &'static str>

Creates a deep copy of this MappedPages memory region, by duplicating not only the virtual memory mapping but also the underlying physical memory frames.

The caller can optionally specify new flags for the duplicated mapping, otherwise, the same flags as the existing MappedPages will be used. This is useful for when you want to modify contents in the new pages, since it avoids extra remap() operations.

Returns a new MappedPages object with the same in-memory contents as this object, but at a completely new memory region.

source

pub fn remap<F: Into<PteFlagsArch>>( &mut self, active_table_mapper: &mut Mapper, new_flags: F ) -> Result<(), &'static str>

Change the mapping flags of this MappedPages’s page table entries.

Note that attempting to change certain “reserved” flags will have no effect. For example, the EXCLUSIVE flag cannot be changed beause arbitrarily setting it would violate safety.

source

pub fn unmap_into_parts( self, active_table_mapper: &mut Mapper ) -> Result<(AllocatedPages, Option<AllocatedFrames>), Self>

Consumes and unmaps this MappedPages object without auto-deallocating its AllocatedPages and AllocatedFrames, allowing the caller to continue using them directly, e.g., reusing them for a future mapping. This removes the need to attempt to to reallocate those same pages or frames on a separate code path.

Note that only the first contiguous range of AllocatedFrames will be returned, if any were unmapped. All other non-contiguous ranges will be auto-dropped and deallocated. This is due to how frame deallocation works.

source

pub fn as_type<T: FromBytes>( &self, byte_offset: usize ) -> Result<&T, &'static str>

Reinterprets this MappedPages’s underlying memory region as a struct of the given type T, i.e., overlays a struct on top of this mapped memory region.

Requirements

The type T must implement the FromBytes trait, which is similar to the requirements of a “plain old data” type, in that it cannot contain Rust references (& or &mut). This makes sense because there is no valid way to reinterpret a region of untyped memory as a Rust reference. In addition, if we did permit that, a Rust reference created from unchecked memory contents could never be valid, safe, or sound, as it could allow random memory access (just like with an arbitrary pointer dereference) that could break isolation.

To satisfy this condition, you can use #[derive(FromBytes)] on your struct type T, which will only compile correctly if the struct can be validly constructed from “untyped” memory, i.e., an array of bytes.

Arguments
  • byte_offset: the offset (in number of bytes) from the beginning of the memory region at which the struct is located (where it should start).
    • This offset must be properly aligned with respect to the alignment requirements of type T, otherwise an error will be returned.

Returns a reference to the new struct (&T) that is formed from the underlying memory region, with a lifetime dependent upon the lifetime of this MappedPages object. This ensures safety by guaranteeing that the returned struct reference cannot be used after this MappedPages object is dropped and unmapped.

source

pub fn as_type_mut<T: FromBytes>( &mut self, byte_offset: usize ) -> Result<&mut T, &'static str>

Same as MappedPages::as_type(), but returns a mutable reference to the type T.

Thus, it also checks that the underlying mapping is writable.

source

pub fn as_slice<T: FromBytes>( &self, byte_offset: usize, length: usize ) -> Result<&[T], &'static str>

Reinterprets this MappedPages’s underlying memory region as &[T], a length-element slice of type T.

It has similar requirements and behavior as MappedPages::as_type().

Arguments
  • byte_offset: the offset (in number of bytes) into the memory region at which the slice should start.
    • This offset must be properly aligned with respect to the alignment requirements of type T, otherwise an error will be returned.
  • length: the length of the slice, i.e., the number of elements of type T in the slice. Thus, the slice’s address bounds will span the range from byte_offset (inclusive) to byte_offset + (size_of::<T>() * length) (exclusive).

Returns a reference to the new slice that is formed from the underlying memory region, with a lifetime dependent upon the lifetime of this MappedPages object. This ensures safety by guaranteeing that the returned slice cannot be used after this MappedPages object is dropped and unmapped.

source

pub fn as_slice_mut<T: FromBytes>( &mut self, byte_offset: usize, length: usize ) -> Result<&mut [T], &'static str>

Same as MappedPages::as_slice(), but returns a mutable slice.

Thus, it checks that the underlying mapping is writable.

source

pub fn into_borrowed<T: FromBytes>( self, byte_offset: usize ) -> Result<BorrowedMappedPages<T, Immutable>, (MappedPages, &'static str)>

A convenience function for BorrowedMappedPages::from().

source

pub fn into_borrowed_mut<T: FromBytes>( self, byte_offset: usize ) -> Result<BorrowedMappedPages<T, Mutable>, (MappedPages, &'static str)>

A convenience function for BorrowedMappedPages::from_mut().

source

pub fn into_borrowed_slice<T: FromBytes>( self, byte_offset: usize, length: usize ) -> Result<BorrowedSliceMappedPages<T, Immutable>, (MappedPages, &'static str)>

A convenience function for BorrowedSliceMappedPages::from().

source

pub fn into_borrowed_slice_mut<T: FromBytes>( self, byte_offset: usize, length: usize ) -> Result<BorrowedSliceMappedPages<T, Mutable>, (MappedPages, &'static str)>

A convenience function for BorrowedSliceMappedPages::from_mut().

Methods from Deref<Target = AllocatedPages>§

pub fn start_address(&self) -> VirtualAddress

Returns the starting VirtualAddress in this range of pages.

pub fn size_in_bytes(&self) -> usize

Returns the size in bytes of this range of pages.

pub fn size_in_pages(&self) -> usize

Returns the size in number of pages of this range of pages.

pub fn start(&self) -> &Page<P>

Returns the starting Page in this range of pages.

pub fn end(&self) -> &Page<P>

Returns the ending Page (inclusive) in this range of pages.

pub fn range(&self) -> &PageRange<P>

Returns a reference to the inner PageRange, which is cloneable/iterable.

pub fn offset_of_address(&self, addr: VirtualAddress) -> Option<usize>

Returns the offset of the given VirtualAddress within this range of pages, i.e., addr - self.start_address().

If the given addr is not covered by this range of pages, this returns None.

Examples

If the range covers addresses 0x2000 to 0x4000, then offset_of_address(0x3500) would return Some(0x1500).

pub fn address_at_offset(&self, offset: usize) -> Option<VirtualAddress>

Returns the VirtualAddress at the given offset into this range of pages, i.e., self.start_address() + offset.

If the given offset is not within this range of pages, this returns None.

Examples

If the range covers addresses 0x2000 through 0x3FFF, then address_at_offset(0x1500) would return Some(0x3500), and address_at_offset(0x2000) would return None.

Trait Implementations§

source§

impl Debug for MappedPages

source§

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

Formats the value using the given formatter. Read more
source§

impl Deref for MappedPages

§

type Target = AllocatedPages<Page4K>

The resulting type after dereferencing.
source§

fn deref(&self) -> &AllocatedPages

Dereferences the value.
source§

impl Drop for MappedPages

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere 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, U> TryFrom<U> for Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.