diff --git a/src/memory/paging.rs b/src/memory/paging.rs index e78a398..ea4651d 100644 --- a/src/memory/paging.rs +++ b/src/memory/paging.rs @@ -12,12 +12,21 @@ //! //! ## Page Table Hierarchy (4-level paging) //! +//! We use simplified level-based naming (PML4/PML3/PML2/PML1) rather than +//! the x86 architectural names for clarity: +//! //! ```text -//! PML4 (Page Map Level 4) - 512 entries, each covers 512 GB -//! └─► PDPT (Page Dir Ptr) - 512 entries, each covers 1 GB -//! └─► PD (Page Dir) - 512 entries, each covers 2 MB -//! └─► PT (Page Table) - 512 entries, each covers 4 KB +//! PML4 (Page Map Level 4) - 512 entries, each covers 512 GB [x86: PML4] +//! └─► PML3 - 512 entries, each covers 1 GB [x86: PDPT] +//! └─► PML2 - 512 entries, each covers 2 MB [x86: PD] +//! └─► PML1 - 512 entries, each covers 4 KB [x86: PT] //! ``` +//! +//! Correspondence to x86 terminology: +//! - PML4 = Page Map Level 4 (same) +//! - PML3 = Page Directory Pointer Table (PDPT) +//! - PML2 = Page Directory (PD) +//! - PML1 = Page Table (PT) use core::fmt; use crate::memory::frame::{Frame, PhysAddr, allocate_frame, FrameAllocatorError}; @@ -47,7 +56,7 @@ pub mod flags { pub const ACCESSED: u64 = 1 << 5; /// Page has been written to (set by CPU) pub const DIRTY: u64 = 1 << 6; - /// Huge page (2MB in PD, 1GB in PDPT) + /// Huge page (2MB in PML2, 1GB in PML3) pub const HUGE_PAGE: u64 = 1 << 7; /// Global page (not flushed on CR3 change) pub const GLOBAL: u64 = 1 << 8; @@ -183,21 +192,21 @@ impl VirtAddr { ((self.0 >> 39) & 0x1FF) as usize } - /// Get the PDPT index (bits 30-38) + /// Get the PML3 index (bits 30-38) #[inline] - pub const fn pdpt_index(self) -> usize { + pub const fn pml3_index(self) -> usize { ((self.0 >> 30) & 0x1FF) as usize } - /// Get the PD index (bits 21-29) + /// Get the PML2 index (bits 21-29) #[inline] - pub const fn pd_index(self) -> usize { + pub const fn pml2_index(self) -> usize { ((self.0 >> 21) & 0x1FF) as usize } - /// Get the PT index (bits 12-20) + /// Get the PML1 index (bits 12-20) #[inline] - pub const fn pt_index(self) -> usize { + pub const fn pml1_index(self) -> usize { ((self.0 >> 12) & 0x1FF) as usize } @@ -230,11 +239,11 @@ impl fmt::LowerHex for VirtAddr { /// Page size variants #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum PageSize { - /// 4 KB page (standard) + /// 4 KB page (standard, via PML1 entry) Small, - /// 2 MB page (huge page via PD entry) + /// 2 MB page (huge page via PML2 entry) Large, - /// 1 GB page (huge page via PDPT entry) + /// 1 GB page (huge page via PML3 entry) Huge, } @@ -283,69 +292,69 @@ pub fn pml4_entry_addr(pml4_idx: usize) -> *mut PageTableEntry { (PML4_BASE + (pml4_idx as u64) * 8) as *mut PageTableEntry } -/// Calculate the virtual address to access a PDPT entry via recursive mapping +/// Calculate the virtual address to access a PML3 entry via recursive mapping /// -/// Formula: 0xFFFFFF7FBFC00000 + (pml4_idx * 0x1000) + (pdpt_idx * 8) +/// Formula: 0xFFFFFF7FBFC00000 + (pml4_idx * 0x1000) + (pml3_idx * 8) #[inline] -pub fn pdpt_entry_addr(pml4_idx: usize, pdpt_idx: usize) -> *mut PageTableEntry { - const PDPT_BASE: u64 = 0xFFFF_FF7F_BFC0_0000; - (PDPT_BASE + (pml4_idx as u64) * 0x1000 + (pdpt_idx as u64) * 8) as *mut PageTableEntry +pub fn pml3_entry_addr(pml4_idx: usize, pml3_idx: usize) -> *mut PageTableEntry { + const PML3_BASE: u64 = 0xFFFF_FF7F_BFC0_0000; + (PML3_BASE + (pml4_idx as u64) * 0x1000 + (pml3_idx as u64) * 8) as *mut PageTableEntry } -/// Calculate the virtual address to access a PD entry via recursive mapping +/// Calculate the virtual address to access a PML2 entry via recursive mapping /// -/// Formula: 0xFFFFFF7F80000000 + (pml4_idx * 0x200000) + (pdpt_idx * 0x1000) + (pd_idx * 8) +/// Formula: 0xFFFFFF7F80000000 + (pml4_idx * 0x200000) + (pml3_idx * 0x1000) + (pml2_idx * 8) #[inline] -pub fn pd_entry_addr(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize) -> *mut PageTableEntry { - const PD_BASE: u64 = 0xFFFF_FF7F_8000_0000; - (PD_BASE +pub fn pml2_entry_addr(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize) -> *mut PageTableEntry { + const PML2_BASE: u64 = 0xFFFF_FF7F_8000_0000; + (PML2_BASE + (pml4_idx as u64) * 0x20_0000 - + (pdpt_idx as u64) * 0x1000 - + (pd_idx as u64) * 8) as *mut PageTableEntry + + (pml3_idx as u64) * 0x1000 + + (pml2_idx as u64) * 8) as *mut PageTableEntry } -/// Calculate the virtual address to access a PT entry via recursive mapping +/// Calculate the virtual address to access a PML1 entry via recursive mapping /// -/// Formula: 0xFFFFFF0000000000 + (pml4_idx * 0x40000000) + (pdpt_idx * 0x200000) -/// + (pd_idx * 0x1000) + (pt_idx * 8) +/// Formula: 0xFFFFFF0000000000 + (pml4_idx * 0x40000000) + (pml3_idx * 0x200000) +/// + (pml2_idx * 0x1000) + (pml1_idx * 8) #[inline] -pub fn pt_entry_addr(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, pt_idx: usize) -> *mut PageTableEntry { - const PT_BASE: u64 = 0xFFFF_FF00_0000_0000; - (PT_BASE +pub fn pml1_entry_addr(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize, pml1_idx: usize) -> *mut PageTableEntry { + const PML1_BASE: u64 = 0xFFFF_FF00_0000_0000; + (PML1_BASE + (pml4_idx as u64) * 0x4000_0000 - + (pdpt_idx as u64) * 0x20_0000 - + (pd_idx as u64) * 0x1000 - + (pt_idx as u64) * 8) as *mut PageTableEntry + + (pml3_idx as u64) * 0x20_0000 + + (pml2_idx as u64) * 0x1000 + + (pml1_idx as u64) * 8) as *mut PageTableEntry } -/// Calculate the virtual address of a PDPT page via recursive mapping +/// Calculate the virtual address of a PML3 table via recursive mapping /// -/// After PML4[pml4_idx] is set, this address accesses the entire PDPT page. +/// After PML4[pml4_idx] is set, this address accesses the entire PML3 table. #[inline] -fn pdpt_table_addr(pml4_idx: usize) -> *mut u64 { - const PDPT_BASE: u64 = 0xFFFF_FF7F_BFC0_0000; - (PDPT_BASE + (pml4_idx as u64) * 0x1000) as *mut u64 +fn pml3_table_addr(pml4_idx: usize) -> *mut u64 { + const PML3_BASE: u64 = 0xFFFF_FF7F_BFC0_0000; + (PML3_BASE + (pml4_idx as u64) * 0x1000) as *mut u64 } -/// Calculate the virtual address of a PD page via recursive mapping +/// Calculate the virtual address of a PML2 table via recursive mapping /// -/// After PDPT[pml4_idx][pdpt_idx] is set, this address accesses the entire PD page. +/// After PML3[pml4_idx][pml3_idx] is set, this address accesses the entire PML2 table. #[inline] -fn pd_table_addr(pml4_idx: usize, pdpt_idx: usize) -> *mut u64 { - const PD_BASE: u64 = 0xFFFF_FF7F_8000_0000; - (PD_BASE + (pml4_idx as u64) * 0x20_0000 + (pdpt_idx as u64) * 0x1000) as *mut u64 +fn pml2_table_addr(pml4_idx: usize, pml3_idx: usize) -> *mut u64 { + const PML2_BASE: u64 = 0xFFFF_FF7F_8000_0000; + (PML2_BASE + (pml4_idx as u64) * 0x20_0000 + (pml3_idx as u64) * 0x1000) as *mut u64 } -/// Calculate the virtual address of a PT page via recursive mapping +/// Calculate the virtual address of a PML1 table via recursive mapping /// -/// After PD[pml4_idx][pdpt_idx][pd_idx] is set, this address accesses the entire PT page. +/// After PML2[pml4_idx][pml3_idx][pml2_idx] is set, this address accesses the entire PML1 table. #[inline] -fn pt_table_addr(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize) -> *mut u64 { - const PT_BASE: u64 = 0xFFFF_FF00_0000_0000; - (PT_BASE +fn pml1_table_addr(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize) -> *mut u64 { + const PML1_BASE: u64 = 0xFFFF_FF00_0000_0000; + (PML1_BASE + (pml4_idx as u64) * 0x4000_0000 - + (pdpt_idx as u64) * 0x20_0000 - + (pd_idx as u64) * 0x1000) as *mut u64 + + (pml3_idx as u64) * 0x20_0000 + + (pml2_idx as u64) * 0x1000) as *mut u64 } // ============================================================================ @@ -367,40 +376,40 @@ pub fn write_pml4(pml4_idx: usize, entry: PageTableEntry) { } } -/// Read a PDPT entry (requires PML4 entry to be present) +/// Read a PML3 entry (requires PML4 entry to be present) #[inline] -pub fn read_pdpt(pml4_idx: usize, pdpt_idx: usize) -> PageTableEntry { - unsafe { *pdpt_entry_addr(pml4_idx, pdpt_idx) } +pub fn read_pml3(pml4_idx: usize, pml3_idx: usize) -> PageTableEntry { + unsafe { *pml3_entry_addr(pml4_idx, pml3_idx) } } -/// Write a PDPT entry +/// Write a PML3 entry #[inline] -pub fn write_pdpt(pml4_idx: usize, pdpt_idx: usize, entry: PageTableEntry) { - unsafe { *pdpt_entry_addr(pml4_idx, pdpt_idx) = entry; } +pub fn write_pml3(pml4_idx: usize, pml3_idx: usize, entry: PageTableEntry) { + unsafe { *pml3_entry_addr(pml4_idx, pml3_idx) = entry; } } -/// Read a PD entry (requires PML4 and PDPT entries to be present) +/// Read a PML2 entry (requires PML4 and PML3 entries to be present) #[inline] -pub fn read_pd(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize) -> PageTableEntry { - unsafe { *pd_entry_addr(pml4_idx, pdpt_idx, pd_idx) } +pub fn read_pml2(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize) -> PageTableEntry { + unsafe { *pml2_entry_addr(pml4_idx, pml3_idx, pml2_idx) } } -/// Write a PD entry +/// Write a PML2 entry #[inline] -pub fn write_pd(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, entry: PageTableEntry) { - unsafe { *pd_entry_addr(pml4_idx, pdpt_idx, pd_idx) = entry; } +pub fn write_pml2(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize, entry: PageTableEntry) { + unsafe { *pml2_entry_addr(pml4_idx, pml3_idx, pml2_idx) = entry; } } -/// Read a PT entry (requires PML4, PDPT, and PD entries to be present) +/// Read a PML1 entry (requires PML4, PML3, and PML2 entries to be present) #[inline] -pub fn read_pt(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, pt_idx: usize) -> PageTableEntry { - unsafe { *pt_entry_addr(pml4_idx, pdpt_idx, pd_idx, pt_idx) } +pub fn read_pml1(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize, pml1_idx: usize) -> PageTableEntry { + unsafe { *pml1_entry_addr(pml4_idx, pml3_idx, pml2_idx, pml1_idx) } } -/// Write a PT entry +/// Write a PML1 entry #[inline] -pub fn write_pt(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, pt_idx: usize, entry: PageTableEntry) { - unsafe { *pt_entry_addr(pml4_idx, pdpt_idx, pd_idx, pt_idx) = entry; } +pub fn write_pml1(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize, pml1_idx: usize, entry: PageTableEntry) { + unsafe { *pml1_entry_addr(pml4_idx, pml3_idx, pml2_idx, pml1_idx) = entry; } } // ============================================================================ @@ -443,14 +452,14 @@ pub fn remove_identity_mapping() { // Page Table Creation and Mapping // ============================================================================ -/// Ensure a PML4 entry exists, creating a PDPT if necessary +/// Ensure a PML4 entry exists, creating a PML3 table if necessary fn ensure_pml4_entry(pml4_idx: usize, page_flags: u64) -> Result<(), PagingError> { let entry = read_pml4(pml4_idx); if !entry.is_present() { let frame = allocate_frame()?; let phys = frame.start_address(); - // Link the new PDPT into the PML4 first + // Link the new PML3 into the PML4 first // For user pages, the USER bit must be set in all intermediate entries let mut table_flags = flags::PRESENT | flags::WRITABLE; if page_flags & flags::USER != 0 { @@ -459,12 +468,12 @@ fn ensure_pml4_entry(pml4_idx: usize, page_flags: u64) -> Result<(), PagingError let new_entry = PageTableEntry::new(phys, table_flags); write_pml4(pml4_idx, new_entry); - // Flush TLB so we can access the new PDPT via recursive mapping + // Flush TLB so we can access the new PML3 via recursive mapping flush_tlb(); // Zero the new page table via recursive mapping - // Now that PML4[pml4_idx] is set, pdpt_table_addr gives us access - zero_page_table(pdpt_table_addr(pml4_idx)); + // Now that PML4[pml4_idx] is set, pml3_table_addr gives us access + zero_page_table(pml3_table_addr(pml4_idx)); } else if page_flags & flags::USER != 0 && !entry.is_user() { // Existing entry needs USER bit added let mut updated = entry; @@ -474,11 +483,11 @@ fn ensure_pml4_entry(pml4_idx: usize, page_flags: u64) -> Result<(), PagingError Ok(()) } -/// Ensure a PDPT entry exists, creating a PD if necessary -fn ensure_pdpt_entry(pml4_idx: usize, pdpt_idx: usize, page_flags: u64) -> Result<(), PagingError> { +/// Ensure a PML3 entry exists, creating a PML2 table if necessary +fn ensure_pml3_entry(pml4_idx: usize, pml3_idx: usize, page_flags: u64) -> Result<(), PagingError> { ensure_pml4_entry(pml4_idx, page_flags)?; - let entry = read_pdpt(pml4_idx, pdpt_idx); + let entry = read_pml3(pml4_idx, pml3_idx); if entry.is_huge() { return Err(PagingError::HugePageConflict); } @@ -486,34 +495,34 @@ fn ensure_pdpt_entry(pml4_idx: usize, pdpt_idx: usize, page_flags: u64) -> Resul let frame = allocate_frame()?; let phys = frame.start_address(); - // Link the new PD into the PDPT first + // Link the new PML2 into the PML3 first // For user pages, the USER bit must be set in all intermediate entries let mut table_flags = flags::PRESENT | flags::WRITABLE; if page_flags & flags::USER != 0 { table_flags |= flags::USER; } let new_entry = PageTableEntry::new(phys, table_flags); - write_pdpt(pml4_idx, pdpt_idx, new_entry); + write_pml3(pml4_idx, pml3_idx, new_entry); - // Flush TLB so we can access the new PD via recursive mapping + // Flush TLB so we can access the new PML2 via recursive mapping flush_tlb(); // Zero the new page table via recursive mapping - zero_page_table(pd_table_addr(pml4_idx, pdpt_idx)); + zero_page_table(pml2_table_addr(pml4_idx, pml3_idx)); } else if page_flags & flags::USER != 0 && !entry.is_user() { // Existing entry needs USER bit added let mut updated = entry; updated.set_flags(entry.flags() | flags::USER); - write_pdpt(pml4_idx, pdpt_idx, updated); + write_pml3(pml4_idx, pml3_idx, updated); } Ok(()) } -/// Ensure a PD entry exists, creating a PT if necessary -fn ensure_pd_entry(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, page_flags: u64) -> Result<(), PagingError> { - ensure_pdpt_entry(pml4_idx, pdpt_idx, page_flags)?; +/// Ensure a PML2 entry exists, creating a PML1 table if necessary +fn ensure_pml2_entry(pml4_idx: usize, pml3_idx: usize, pml2_idx: usize, page_flags: u64) -> Result<(), PagingError> { + ensure_pml3_entry(pml4_idx, pml3_idx, page_flags)?; - let entry = read_pd(pml4_idx, pdpt_idx, pd_idx); + let entry = read_pml2(pml4_idx, pml3_idx, pml2_idx); if entry.is_huge() { return Err(PagingError::HugePageConflict); } @@ -521,25 +530,25 @@ fn ensure_pd_entry(pml4_idx: usize, pdpt_idx: usize, pd_idx: usize, page_flags: let frame = allocate_frame()?; let phys = frame.start_address(); - // Link the new PT into the PD first + // Link the new PML1 into the PML2 first // For user pages, the USER bit must be set in all intermediate entries let mut table_flags = flags::PRESENT | flags::WRITABLE; if page_flags & flags::USER != 0 { table_flags |= flags::USER; } let new_entry = PageTableEntry::new(phys, table_flags); - write_pd(pml4_idx, pdpt_idx, pd_idx, new_entry); + write_pml2(pml4_idx, pml3_idx, pml2_idx, new_entry); - // Flush TLB so we can access the new PT via recursive mapping + // Flush TLB so we can access the new PML1 via recursive mapping flush_tlb(); // Zero the new page table via recursive mapping - zero_page_table(pt_table_addr(pml4_idx, pdpt_idx, pd_idx)); + zero_page_table(pml1_table_addr(pml4_idx, pml3_idx, pml2_idx)); } else if page_flags & flags::USER != 0 && !entry.is_user() { // Existing entry needs USER bit added let mut updated = entry; updated.set_flags(entry.flags() | flags::USER); - write_pd(pml4_idx, pdpt_idx, pd_idx, updated); + write_pml2(pml4_idx, pml3_idx, pml2_idx, updated); } Ok(()) } @@ -563,22 +572,22 @@ pub fn map_4kb(virt: VirtAddr, phys: PhysAddr, flags: u64) -> Result<(), PagingE } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); - let pd_idx = virt.pd_index(); - let pt_idx = virt.pt_index(); + let pml3_idx = virt.pml3_index(); + let pml2_idx = virt.pml2_index(); + let pml1_idx = virt.pml1_index(); // Ensure all parent tables exist - ensure_pd_entry(pml4_idx, pdpt_idx, pd_idx, flags)?; + ensure_pml2_entry(pml4_idx, pml3_idx, pml2_idx, flags)?; // Check if already mapped - let existing = read_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx); + let existing = read_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx); if existing.is_present() { return Err(PagingError::AlreadyMapped); } // Create the mapping let entry = PageTableEntry::new(phys, flags | flags::PRESENT); - write_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx, entry); + write_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx, entry); // Invalidate TLB for this address invalidate_page(virt); @@ -598,21 +607,21 @@ pub fn map_2mb(virt: VirtAddr, phys: PhysAddr, flags: u64) -> Result<(), PagingE } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); - let pd_idx = virt.pd_index(); + let pml3_idx = virt.pml3_index(); + let pml2_idx = virt.pml2_index(); - // Ensure PML4 and PDPT entries exist - ensure_pdpt_entry(pml4_idx, pdpt_idx, flags)?; + // Ensure PML4 and PML3 entries exist + ensure_pml3_entry(pml4_idx, pml3_idx, flags)?; // Check if already mapped - let existing = read_pd(pml4_idx, pdpt_idx, pd_idx); + let existing = read_pml2(pml4_idx, pml3_idx, pml2_idx); if existing.is_present() { return Err(PagingError::AlreadyMapped); } // Create the huge page mapping let entry = PageTableEntry::new(phys, flags | flags::PRESENT | flags::HUGE_PAGE); - write_pd(pml4_idx, pdpt_idx, pd_idx, entry); + write_pml2(pml4_idx, pml3_idx, pml2_idx, entry); // Invalidate TLB invalidate_page(virt); @@ -632,20 +641,20 @@ pub fn map_1gb(virt: VirtAddr, phys: PhysAddr, flags: u64) -> Result<(), PagingE } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); + let pml3_idx = virt.pml3_index(); // Ensure PML4 entry exists ensure_pml4_entry(pml4_idx, flags)?; // Check if already mapped - let existing = read_pdpt(pml4_idx, pdpt_idx); + let existing = read_pml3(pml4_idx, pml3_idx); if existing.is_present() { return Err(PagingError::AlreadyMapped); } // Create the huge page mapping let entry = PageTableEntry::new(phys, flags | flags::PRESENT | flags::HUGE_PAGE); - write_pdpt(pml4_idx, pdpt_idx, entry); + write_pml3(pml4_idx, pml3_idx, entry); // Invalidate TLB invalidate_page(virt); @@ -660,9 +669,9 @@ pub fn unmap_4kb(virt: VirtAddr) -> Result { } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); - let pd_idx = virt.pd_index(); - let pt_idx = virt.pt_index(); + let pml3_idx = virt.pml3_index(); + let pml2_idx = virt.pml2_index(); + let pml1_idx = virt.pml1_index(); // Walk the page table hierarchy let pml4_entry = read_pml4(pml4_idx); @@ -670,31 +679,31 @@ pub fn unmap_4kb(virt: VirtAddr) -> Result { return Err(PagingError::NotMapped); } - let pdpt_entry = read_pdpt(pml4_idx, pdpt_idx); - if !pdpt_entry.is_present() { + let pml3_entry = read_pml3(pml4_idx, pml3_idx); + if !pml3_entry.is_present() { return Err(PagingError::NotMapped); } - if pdpt_entry.is_huge() { + if pml3_entry.is_huge() { return Err(PagingError::HugePageConflict); } - let pd_entry = read_pd(pml4_idx, pdpt_idx, pd_idx); - if !pd_entry.is_present() { + let pml2_entry = read_pml2(pml4_idx, pml3_idx, pml2_idx); + if !pml2_entry.is_present() { return Err(PagingError::NotMapped); } - if pd_entry.is_huge() { + if pml2_entry.is_huge() { return Err(PagingError::HugePageConflict); } - let pt_entry = read_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx); - if !pt_entry.is_present() { + let pml1_entry = read_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx); + if !pml1_entry.is_present() { return Err(PagingError::NotMapped); } - let frame = pt_entry.frame(); + let frame = pml1_entry.frame(); // Clear the entry - write_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx, PageTableEntry::empty()); + write_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx, PageTableEntry::empty()); // Invalidate TLB invalidate_page(virt); @@ -709,9 +718,9 @@ pub fn translate(virt: VirtAddr) -> Option { } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); - let pd_idx = virt.pd_index(); - let pt_idx = virt.pt_index(); + let pml3_idx = virt.pml3_index(); + let pml2_idx = virt.pml2_index(); + let pml1_idx = virt.pml1_index(); let offset = virt.page_offset(); // Walk the page table hierarchy @@ -720,35 +729,35 @@ pub fn translate(virt: VirtAddr) -> Option { return None; } - let pdpt_entry = read_pdpt(pml4_idx, pdpt_idx); - if !pdpt_entry.is_present() { + let pml3_entry = read_pml3(pml4_idx, pml3_idx); + if !pml3_entry.is_present() { return None; } - if pdpt_entry.is_huge() { + if pml3_entry.is_huge() { // 1GB page - let base = pdpt_entry.addr().as_u64(); + let base = pml3_entry.addr().as_u64(); let page_offset = virt.as_u64() & 0x3FFFFFFF; // Lower 30 bits return Some(PhysAddr::new(base + page_offset)); } - let pd_entry = read_pd(pml4_idx, pdpt_idx, pd_idx); - if !pd_entry.is_present() { + let pml2_entry = read_pml2(pml4_idx, pml3_idx, pml2_idx); + if !pml2_entry.is_present() { return None; } - if pd_entry.is_huge() { + if pml2_entry.is_huge() { // 2MB page - let base = pd_entry.addr().as_u64(); + let base = pml2_entry.addr().as_u64(); let page_offset = virt.as_u64() & 0x1FFFFF; // Lower 21 bits return Some(PhysAddr::new(base + page_offset)); } - let pt_entry = read_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx); - if !pt_entry.is_present() { + let pml1_entry = read_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx); + if !pml1_entry.is_present() { return None; } // 4KB page - let base = pt_entry.addr().as_u64(); + let base = pml1_entry.addr().as_u64(); Some(PhysAddr::new(base + offset as u64)) } @@ -759,35 +768,35 @@ pub fn get_mapping_info(virt: VirtAddr) -> Option<(PhysAddr, PageSize, u64)> { } let pml4_idx = virt.pml4_index(); - let pdpt_idx = virt.pdpt_index(); - let pd_idx = virt.pd_index(); - let pt_idx = virt.pt_index(); + let pml3_idx = virt.pml3_index(); + let pml2_idx = virt.pml2_index(); + let pml1_idx = virt.pml1_index(); let pml4_entry = read_pml4(pml4_idx); if !pml4_entry.is_present() { return None; } - let pdpt_entry = read_pdpt(pml4_idx, pdpt_idx); - if !pdpt_entry.is_present() { + let pml3_entry = read_pml3(pml4_idx, pml3_idx); + if !pml3_entry.is_present() { return None; } - if pdpt_entry.is_huge() { - return Some((pdpt_entry.addr(), PageSize::Huge, pdpt_entry.flags())); + if pml3_entry.is_huge() { + return Some((pml3_entry.addr(), PageSize::Huge, pml3_entry.flags())); } - let pd_entry = read_pd(pml4_idx, pdpt_idx, pd_idx); - if !pd_entry.is_present() { + let pml2_entry = read_pml2(pml4_idx, pml3_idx, pml2_idx); + if !pml2_entry.is_present() { return None; } - if pd_entry.is_huge() { - return Some((pd_entry.addr(), PageSize::Large, pd_entry.flags())); + if pml2_entry.is_huge() { + return Some((pml2_entry.addr(), PageSize::Large, pml2_entry.flags())); } - let pt_entry = read_pt(pml4_idx, pdpt_idx, pd_idx, pt_idx); - if !pt_entry.is_present() { + let pml1_entry = read_pml1(pml4_idx, pml3_idx, pml2_idx, pml1_idx); + if !pml1_entry.is_present() { return None; } - Some((pt_entry.addr(), PageSize::Small, pt_entry.flags())) + Some((pml1_entry.addr(), PageSize::Small, pml1_entry.flags())) }