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
impl MappedPages
sourcepub const fn empty() -> MappedPages
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.
sourcepub fn flags(&self) -> PteFlagsArch
pub fn flags(&self) -> PteFlagsArch
Returns the flags that describe this MappedPages
page table permissions.
sourcepub fn merge(
&mut self,
mp: MappedPages
) -> Result<(), (&'static str, MappedPages)>
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 thisMappedPages
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.
sourcepub fn split(
self,
at_page: Page
) -> Result<(MappedPages, MappedPages), MappedPages>
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 returnedMappedPages
object will be empty. - If
at_page == self.pages.end + 1
, the second returnedMappedPages
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.
sourcepub fn deep_copy<F: Into<PteFlagsArch>>(
&self,
active_table_mapper: &mut Mapper,
new_flags: Option<F>
) -> Result<MappedPages, &'static str>
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.
sourcepub fn remap<F: Into<PteFlagsArch>>(
&mut self,
active_table_mapper: &mut Mapper,
new_flags: F
) -> Result<(), &'static str>
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.
sourcepub fn unmap_into_parts(
self,
active_table_mapper: &mut Mapper
) -> Result<(AllocatedPages, Option<AllocatedFrames>), Self>
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.
sourcepub fn as_type<T: FromBytes>(
&self,
byte_offset: usize
) -> Result<&T, &'static str>
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.
- This offset must be properly aligned with respect to the alignment requirements
of type
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.
sourcepub fn as_type_mut<T: FromBytes>(
&mut self,
byte_offset: usize
) -> Result<&mut T, &'static str>
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.
sourcepub fn as_slice<T: FromBytes>(
&self,
byte_offset: usize,
length: usize
) -> Result<&[T], &'static str>
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.
- This offset must be properly aligned with respect to the alignment requirements
of type
length
: the length of the slice, i.e., the number of elements of typeT
in the slice. Thus, the slice’s address bounds will span the range frombyte_offset
(inclusive) tobyte_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.
sourcepub fn as_slice_mut<T: FromBytes>(
&mut self,
byte_offset: usize,
length: usize
) -> Result<&mut [T], &'static str>
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.
sourcepub fn into_borrowed<T: FromBytes>(
self,
byte_offset: usize
) -> Result<BorrowedMappedPages<T, Immutable>, (MappedPages, &'static str)>
pub fn into_borrowed<T: FromBytes>( self, byte_offset: usize ) -> Result<BorrowedMappedPages<T, Immutable>, (MappedPages, &'static str)>
A convenience function for BorrowedMappedPages::from()
.
sourcepub fn into_borrowed_mut<T: FromBytes>(
self,
byte_offset: usize
) -> Result<BorrowedMappedPages<T, Mutable>, (MappedPages, &'static str)>
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()
.
sourcepub fn into_borrowed_slice<T: FromBytes>(
self,
byte_offset: usize,
length: usize
) -> Result<BorrowedSliceMappedPages<T, Immutable>, (MappedPages, &'static str)>
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()
.
sourcepub fn into_borrowed_slice_mut<T: FromBytes>(
self,
byte_offset: usize,
length: usize
) -> Result<BorrowedSliceMappedPages<T, Mutable>, (MappedPages, &'static str)>
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
pub fn start_address(&self) -> VirtualAddress
Returns the starting VirtualAddress
in this range of pages.
pub fn size_in_bytes(&self) -> usize
pub fn size_in_bytes(&self) -> usize
Returns the size in bytes of this range of pages.
pub fn size_in_pages(&self) -> usize
pub fn size_in_pages(&self) -> usize
Returns the size in number of pages of this range of pages.
pub fn range(&self) -> &PageRange<P>
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>
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>
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
.