Skip to content

Commit 80469f5

Browse files
committed
fix(x86_64/paging): use identity-mapped page tables
1 parent 854b756 commit 80469f5

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

src/arch/x86_64/paging.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ use core::fmt::Debug;
22
use core::ptr;
33

44
use log::warn;
5+
use x86_64::VirtAddr;
6+
use x86_64::registers::control::Cr3;
57
use x86_64::structures::paging::mapper::CleanUp;
68
use x86_64::structures::paging::{
7-
Mapper, Page, PageSize, PageTableFlags, PhysFrame, RecursivePageTable,
9+
Mapper, OffsetPageTable, Page, PageSize, PageTable, PageTableFlags, PhysFrame,
810
};
911

1012
use super::physicalmem::PhysAlloc;
1113

1214
pub fn map<S>(virtual_address: usize, physical_address: usize, count: usize, flags: PageTableFlags)
1315
where
1416
S: PageSize + Debug,
15-
RecursivePageTable<'static>: Mapper<S>,
17+
for<'a> OffsetPageTable<'a>: Mapper<S>,
1618
{
1719
let pages = {
1820
let start = Page::<S>::containing_address(x86_64::VirtAddr::new(virtual_address as u64));
@@ -38,7 +40,7 @@ where
3840
);
3941

4042
let flags = flags | PageTableFlags::PRESENT;
41-
let mut table = unsafe { recursive_page_table() };
43+
let mut table = unsafe { identity_mapped_page_table() };
4244

4345
for (page, frame) in pages.zip(frames) {
4446
unsafe {
@@ -58,7 +60,7 @@ pub fn map_range<S>(
5860
mut flags: PageTableFlags,
5961
) where
6062
S: PageSize + Debug,
61-
RecursivePageTable<'static>: Mapper<S>,
63+
for<'a> OffsetPageTable<'a>: Mapper<S>,
6264
{
6365
let first_page = Page::<S>::containing_address(x86_64::VirtAddr::new(virtual_start as u64));
6466
let first_frame = PhysFrame::containing_address(x86_64::PhysAddr::new(phys_start as u64));
@@ -71,7 +73,7 @@ pub fn map_range<S>(
7173
to_end = last_frame.start_address()
7274
);
7375
flags |= PageTableFlags::PRESENT;
74-
let mut table = unsafe { recursive_page_table() };
76+
let mut table = unsafe { identity_mapped_page_table() };
7577
let page_range = core::iter::successors(Some(first_page), |page| Some(*page + 1u64));
7678
let frame_range = PhysFrame::<S>::range(first_frame, last_frame);
7779
for (page, frame) in core::iter::zip(page_range, frame_range) {
@@ -85,16 +87,16 @@ pub fn map_range<S>(
8587
}
8688

8789
pub fn clean_up() {
88-
let mut table = unsafe { recursive_page_table() };
90+
let mut table = unsafe { identity_mapped_page_table() };
8991

9092
unsafe { table.clean_up(&mut PhysAlloc) }
9193
}
9294

93-
unsafe fn recursive_page_table() -> RecursivePageTable<'static> {
94-
let level_4_table_addr = 0xFFFF_FFFF_FFFF_F000_usize;
95-
let level_4_table_ptr = ptr::with_exposed_provenance_mut(level_4_table_addr);
96-
unsafe {
97-
let level_4_table = &mut *(level_4_table_ptr);
98-
RecursivePageTable::new(level_4_table).unwrap()
99-
}
95+
unsafe fn identity_mapped_page_table() -> OffsetPageTable<'static> {
96+
let level_4_table_addr = Cr3::read().0.start_address().as_u64();
97+
let level_4_table_addr = usize::try_from(level_4_table_addr).unwrap();
98+
let level_4_table_ptr = ptr::with_exposed_provenance_mut::<PageTable>(level_4_table_addr);
99+
let level_4_table = unsafe { level_4_table_ptr.as_mut().unwrap() };
100+
let phys_offset = VirtAddr::new(0x0);
101+
unsafe { OffsetPageTable::new(level_4_table, phys_offset) }
100102
}

0 commit comments

Comments
 (0)