From 6fb87c786f1982b560d6476f78810ba88a7cc941 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Wed, 6 Aug 2025 08:50:55 +0000 Subject: [PATCH] map 2MiB --- nel_os_kernel/src/vmm/x86_64/intel/ept.rs | 86 ++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/nel_os_kernel/src/vmm/x86_64/intel/ept.rs b/nel_os_kernel/src/vmm/x86_64/intel/ept.rs index 91c45de..a3b7c28 100644 --- a/nel_os_kernel/src/vmm/x86_64/intel/ept.rs +++ b/nel_os_kernel/src/vmm/x86_64/intel/ept.rs @@ -1,7 +1,6 @@ use modular_bitfield::{ bitfield, prelude::{B3, B53}, - Specifier, }; use x86_64::{ structures::paging::{FrameAllocator, PhysFrame, Size4KiB}, @@ -18,12 +17,95 @@ impl EPT { .allocate_frame() .ok_or("Failed to allocate EPT root table frame")?; + Self::init_table(&root_table_frame); + Ok(Self { root_table: root_table_frame, }) } - fn init_table(frame: &PhysFrame) {} + fn init_table(frame: &PhysFrame) { + let table_ptr = frame.start_address().as_u64(); + let entries = unsafe { &mut *(table_ptr as *mut [EntryBase; 512]) }; + + for entry in entries { + entry.set_read(false); + entry.set_write(false); + entry.set_exec_super(false); + entry.set_map_memory(false); + entry.set_typ(0); + } + } + + pub fn map_2m( + &mut self, + gpa: u64, + hpa: u64, + allocator: &mut impl FrameAllocator, + ) -> Result<(), &'static str> { + let lv4_index = (gpa >> 39) & 0x1FF; + let lv3_index = (gpa >> 30) & 0x1FF; + let lv2_index = (gpa >> 21) & 0x1FF; + + let lv4_table = Self::frame_to_table_ptr(&self.root_table); + let lv4_entry = &mut lv4_table[lv4_index as usize]; + + let lv3_table = if !lv4_entry.is_present() { + let frame = allocator + .allocate_frame() + .ok_or("Failed to allocate LV3 frame")?; + let table_ptr = Self::frame_to_table_ptr(&frame); + lv4_entry.set_phys(frame.start_address().as_u64() >> 12); + lv4_entry.set_map_memory(false); + lv4_entry.set_typ(0); + lv4_entry.set_read(true); + lv4_entry.set_write(true); + lv4_entry.set_exec_super(true); + + table_ptr + } else { + let frame = PhysFrame::from_start_address(PhysAddr::new(lv4_entry.phys() << 12)) + .map_err(|_| "Invalid LV4 frame address")?; + Self::frame_to_table_ptr(&frame) + }; + + let lv3_entry = &mut lv3_table[lv3_index as usize]; + + let lv2_table = if !lv3_entry.is_present() { + let frame = allocator + .allocate_frame() + .ok_or("Failed to allocate LV2 frame")?; + let table_ptr = Self::frame_to_table_ptr(&frame); + lv3_entry.set_phys(frame.start_address().as_u64() >> 12); + lv3_entry.set_map_memory(false); + lv3_entry.set_typ(0); + lv3_entry.set_read(true); + lv3_entry.set_write(true); + lv3_entry.set_exec_super(true); + + table_ptr + } else { + let frame = PhysFrame::from_start_address(PhysAddr::new(lv3_entry.phys() << 12)) + .map_err(|_| "Invalid LV3 frame address")?; + Self::frame_to_table_ptr(&frame) + }; + + let lv2_entry = &mut lv2_table[lv2_index as usize]; + lv2_entry.set_phys(hpa >> 12); + lv2_entry.set_map_memory(true); + lv2_entry.set_typ(0); + lv2_entry.set_read(true); + lv2_entry.set_write(true); + lv2_entry.set_exec_super(true); + + Ok(()) + } + + fn frame_to_table_ptr(frame: &PhysFrame) -> &'static mut [EntryBase; 512] { + let table_ptr = frame.start_address().as_u64(); + + unsafe { &mut *(table_ptr as *mut [EntryBase; 512]) } + } } #[bitfield]