pub struct LinearMap { /* private fields */ }Expand description
Manages a level 1 page table using linear mapping, where every virtual address is either unmapped or mapped to an IPA with a fixed offset.
This assumes that the same linear mapping is used both for the page table being managed, and for code that is managing it.
Implementations§
Source§impl LinearMap
impl LinearMap
Sourcepub fn new(
asid: usize,
rootlevel: usize,
offset: isize,
translation_regime: TranslationRegime,
va_range: VaRange,
) -> Self
pub fn new( asid: usize, rootlevel: usize, offset: isize, translation_regime: TranslationRegime, va_range: VaRange, ) -> Self
Creates a new identity-mapping page table with the given ASID, root level and offset, for use in the given TTBR.
This will map any virtual address va which is added to the table to the physical address
va + offset.
The offset must be a multiple of PAGE_SIZE; if not this will panic.
Sourcepub fn size(&self) -> usize
pub fn size(&self) -> usize
Returns the size in bytes of the virtual address space which can be mapped in this page table.
This is a function of the chosen root level.
Sourcepub unsafe fn activate(&mut self) -> usize
pub unsafe fn activate(&mut self) -> usize
Activates the page table by programming the physical address of the root page table into
TTBRn_ELx, along with the provided ASID. The previous value of TTBRn_ELx is returned so
that it may later be restored by passing it to deactivate.
In test builds or builds that do not target aarch64, the TTBR0_EL1 access is omitted.
§Safety
The caller must ensure that the page table doesn’t unmap any memory which the program is using, or introduce aliases which break Rust’s aliasing rules. The page table must not be dropped as long as its mappings are required, as it will automatically be deactivated when it is dropped.
Sourcepub unsafe fn deactivate(&mut self, previous_ttbr: usize)
pub unsafe fn deactivate(&mut self, previous_ttbr: usize)
Deactivates the page table, by setting TTBRn_ELx to the provided value, and invalidating
the TLB for this page table’s configured ASID. The provided TTBR value should be the value
returned by the preceding activate call.
In test builds or builds that do not target aarch64, the TTBR0_EL1 access is omitted.
§Safety
The caller must ensure that the previous page table which this is switching back to doesn’t unmap any memory which the program is using.
Sourcepub fn map_range(
&mut self,
range: &MemoryRegion,
flags: Attributes,
) -> Result<(), MapError>
pub fn map_range( &mut self, range: &MemoryRegion, flags: Attributes, ) -> Result<(), MapError>
Maps the given range of virtual addresses to the corresponding physical addresses with the given flags.
This should generally only be called while the page table is not active. In particular, any
change that may require break-before-make per the architecture must be made while the page
table is inactive. Mapping a previously unmapped memory range may be done while the page
table is active. This function writes block and page entries, but only maps them if flags
contains Attributes::VALID, otherwise the entries remain invalid.
§Errors
Returns MapError::InvalidVirtualAddress if adding the configured offset to any virtual
address within the range would result in overflow.
Returns MapError::RegionBackwards if the range is backwards.
Returns MapError::AddressRange if the largest address in the range is greater than the
largest virtual address covered by the page table given its root level.
Returns MapError::InvalidFlags if the flags argument has unsupported attributes set.
Returns [`MapError::BreakBeforeMakeViolation’] if the range intersects with live mappings, and modifying those would violate architectural break-before-make (BBM) requirements.
Sourcepub fn map_range_with_constraints(
&mut self,
range: &MemoryRegion,
flags: Attributes,
constraints: Constraints,
) -> Result<(), MapError>
pub fn map_range_with_constraints( &mut self, range: &MemoryRegion, flags: Attributes, constraints: Constraints, ) -> Result<(), MapError>
Maps the given range of virtual addresses to the corresponding physical addresses with the given flags, taking the given constraints into account.
This should generally only be called while the page table is not active. In particular, any
change that may require break-before-make per the architecture must be made while the page
table is inactive. Mapping a previously unmapped memory range may be done while the page
table is active. This function writes block and page entries, but only maps them if flags
contains Attributes::VALID, otherwise the entries remain invalid.
§Errors
Returns MapError::InvalidVirtualAddress if adding the configured offset to any virtual
address within the range would result in overflow.
Returns MapError::RegionBackwards if the range is backwards.
Returns MapError::AddressRange if the largest address in the range is greater than the
largest virtual address covered by the page table given its root level.
Returns MapError::InvalidFlags if the flags argument has unsupported attributes set.
Returns [`MapError::BreakBeforeMakeViolation’] if the range intersects with live mappings, and modifying those would violate architectural break-before-make (BBM) requirements.
Sourcepub fn modify_range<F>(
&mut self,
range: &MemoryRegion,
f: &F,
) -> Result<(), MapError>
pub fn modify_range<F>( &mut self, range: &MemoryRegion, f: &F, ) -> Result<(), MapError>
Applies the provided updater function to the page table descriptors covering a given memory range.
This may involve splitting block entries if the provided range is not currently mapped
down to its precise boundaries. For visiting all the descriptors covering a memory range
without potential splitting (and no descriptor updates), use
walk_range instead.
The updater function receives the following arguments:
- The virtual address range mapped by each page table descriptor. A new descriptor will have been allocated before the invocation of the updater function if a page table split was needed.
- A mutable reference to the page table descriptor that permits modifications.
- The level of a translation table the descriptor belongs to.
The updater function should return:
Okto continue updating the remaining entries.Errto signal an error and stop updating the remaining entries.
This should generally only be called while the page table is not active. In particular, any change that may require break-before-make per the architecture must be made while the page table is inactive. Mapping a previously unmapped memory range may be done while the page table is active.
§Errors
Returns MapError::PteUpdateFault if the updater function returns an error.
Returns MapError::RegionBackwards if the range is backwards.
Returns MapError::AddressRange if the largest address in the range is greater than the
largest virtual address covered by the page table given its root level.
Returns [`MapError::BreakBeforeMakeViolation’] if the range intersects with live mappings, and modifying those would violate architectural break-before-make (BBM) requirements.
Sourcepub fn walk_range<F>(
&self,
range: &MemoryRegion,
f: &mut F,
) -> Result<(), MapError>
pub fn walk_range<F>( &self, range: &MemoryRegion, f: &mut F, ) -> Result<(), MapError>
Applies the provided callback function to the page table descriptors covering a given memory range.
The callback function receives the following arguments:
- The range covered by the current step in the walk. This is always a subrange of
rangeeven when the descriptor covers a region that exceeds it. - The page table descriptor itself.
- The level of a translation table the descriptor belongs to.
The callback function should return:
Okto continue visiting the remaining entries.Errto signal an error and stop visiting the remaining entries.
§Errors
Returns MapError::PteUpdateFault if the callback function returns an error.
Returns MapError::RegionBackwards if the range is backwards.
Returns MapError::AddressRange if the largest address in the range is greater than the
largest virtual address covered by the page table given its root level.
Sourcepub fn root_address(&self) -> PhysicalAddress
pub fn root_address(&self) -> PhysicalAddress
Returns the physical address of the root table.
This may be used to activate the page table by setting the appropriate TTBRn_ELx if you wish
to do so yourself rather than by calling activate. Make sure to call
mark_active after doing so.
Sourcepub fn mark_active(&mut self)
pub fn mark_active(&mut self)
Marks the page table as active.
This should be called if the page table is manually activated by calling
root_address and setting some TTBR with it. This will cause
map_range and modify_range to perform extra
checks to avoid violating break-before-make requirements.
It is called automatically by activate.
Sourcepub fn mark_inactive(&mut self)
pub fn mark_inactive(&mut self)
Marks the page table as inactive.
This may be called after manually disabling the use of the page table, such as by setting the relevant TTBR to a different address.
It is called automatically by deactivate.