-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mm/pagetable: use self map to implement virt_to_phys
It is possible to insert a reference to the current page table into the page table itself, creating a recursive "self-map". This permits access to any PTE in the address space by taking advantage of the hierarchical property of page tables, using the CPU's own page table walker to obtain the PTE contents. This change inserts a self-map entry into every page table, and reimplements `virt_to_phys()` to use the self map so that it is possible to translate any VA to a PA without requiring either the VA or the PA to be within the bounds of any known address range. Signed-off-by: Jon Lange <[email protected]>
- Loading branch information
1 parent
4069528
commit 45ff857
Showing
4 changed files
with
113 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
// Author: Joerg Roedel <[email protected]> | ||
|
||
use crate::address::{PhysAddr, VirtAddr}; | ||
use crate::mm::pagetable::PageTable; | ||
use crate::utils::immut_after_init::ImmutAfterInitCell; | ||
|
||
#[derive(Debug, Copy, Clone)] | ||
|
@@ -38,16 +39,6 @@ impl FixedAddressMappingRange { | |
} | ||
} | ||
} | ||
|
||
#[cfg(target_os = "none")] | ||
fn virt_to_phys(&self, vaddr: VirtAddr) -> Option<PhysAddr> { | ||
if (vaddr < self.virt_start) || (vaddr >= self.virt_end) { | ||
None | ||
} else { | ||
let offset: usize = vaddr - self.virt_start; | ||
Some(self.phys_start + offset) | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Copy, Clone)] | ||
|
@@ -74,16 +65,12 @@ pub fn init_kernel_mapping_info( | |
|
||
#[cfg(target_os = "none")] | ||
pub fn virt_to_phys(vaddr: VirtAddr) -> PhysAddr { | ||
if let Some(addr) = FIXED_MAPPING.kernel_mapping.virt_to_phys(vaddr) { | ||
return addr; | ||
} | ||
if let Some(ref mapping) = FIXED_MAPPING.heap_mapping { | ||
if let Some(addr) = mapping.virt_to_phys(vaddr) { | ||
return addr; | ||
match PageTable::virt_to_phys(vaddr) { | ||
Some(paddr) => paddr, | ||
None => { | ||
panic!("Invalid virtual address {:#018x}", vaddr); | ||
} | ||
} | ||
|
||
panic!("Invalid virtual address {:#018x}", vaddr); | ||
} | ||
|
||
#[cfg(target_os = "none")] | ||
|
@@ -203,6 +190,11 @@ pub const SVSM_PERTASK_END: VirtAddr = SVSM_PERTASK_BASE.const_add(SIZE_LEVEL3); | |
/// Kernel stack for a task | ||
pub const SVSM_PERTASK_STACK_BASE: VirtAddr = SVSM_PERTASK_BASE; | ||
|
||
/// Page table self-map level 3 index | ||
pub const PGTABLE_LVL3_IDX_PTE_SELFMAP: usize = 493; | ||
|
||
pub const SVSM_PTE_BASE: VirtAddr = virt_from_idx(PGTABLE_LVL3_IDX_PTE_SELFMAP); | ||
|
||
// | ||
// User-space mapping constants | ||
// | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters