From 6f342db5c24a69ffd8160f687d091bb419957789 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Sun, 27 Apr 2025 09:12:19 +0000 Subject: [PATCH] add EPT --- src/lib.rs | 1 + src/main.rs | 6 +++- src/memory.rs | 4 +++ src/vmm/ept.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 20539c4..2725a9a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ #![feature(abi_x86_interrupt)] #![feature(alloc_error_handler)] #![feature(naked_functions)] +#![feature(generic_const_exprs)] #![test_runner(crate::test_runner)] #![reexport_test_harness_main = "test_main"] diff --git a/src/main.rs b/src/main.rs index d3ec8f7..aff8d86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ #![feature(custom_test_frameworks)] #![feature(new_zeroed_alloc)] #![feature(naked_functions)] +#![feature(generic_const_exprs)] #![test_runner(nel_os::test_runner)] #![reexport_test_harness_main = "test_main"] #![allow(unreachable_code)] @@ -10,7 +11,7 @@ extern crate alloc; use bootloader::{entry_point, BootInfo}; -use core::panic::PanicInfo; +use core::{panic::PanicInfo, sync::atomic::Ordering}; use nel_os::{ allocator, info, memory::{self, BootInfoFrameAllocator}, @@ -43,6 +44,9 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { nel_os::init(); let phys_mem_offset = VirtAddr::new(boot_info.physical_memory_offset); + + memory::PHYSICAL_MEMORY_OFFSET.store(phys_mem_offset.as_u64(), Ordering::Relaxed); + let mut mapper = unsafe { memory::init(phys_mem_offset) }; let mut frame_allocator = unsafe { BootInfoFrameAllocator::init(&boot_info.memory_map) }; diff --git a/src/memory.rs b/src/memory.rs index 64e7549..f23224b 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,9 +1,13 @@ +use core::sync::atomic::AtomicU64; + use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; use x86_64::{ structures::paging::{FrameAllocator, OffsetPageTable, PageTable, PhysFrame, Size4KiB}, PhysAddr, VirtAddr, }; +pub static PHYSICAL_MEMORY_OFFSET: AtomicU64 = AtomicU64::new(0); + pub struct BootInfoFrameAllocator { memory_map: &'static MemoryMap, next: usize, diff --git a/src/vmm/ept.rs b/src/vmm/ept.rs index 1827b96..9710570 100644 --- a/src/vmm/ept.rs +++ b/src/vmm/ept.rs @@ -1,6 +1,61 @@ +use core::sync::atomic::Ordering; + use bitfield::bitfield; use x86_64::PhysAddr; +use crate::memory; + +pub enum Assert {} + +pub trait IsTrue {} + +impl IsTrue for Assert {} + +pub struct TableEntry { + pub entry: EntryBase, +} + +impl TableEntry { + pub fn new_map_table(table: TableEntry) -> Self + where + Assert<{ LEVEL > L }>: IsTrue, + Assert<{ L > 0 }>: IsTrue, + Assert<{ LEVEL < 5 }>: IsTrue, + { + let mut entry = EntryBase::default(); + entry.set_map_memory(false); + entry.set_typ(0); + entry.set_phys( + (&table as *const _ as u64 + memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed)) + >> 12, + ); + + Self { entry } + } + + pub fn new_map_page(phys: u64) -> Self + where + Assert<{ L < 4 }>: IsTrue, + Assert<{ L > 0 }>: IsTrue, + { + let mut entry = EntryBase::default(); + entry.set_read(true); + entry.set_write(true); + entry.set_exec_super(true); + entry.set_exec_user(true); + entry.set_map_memory(true); + entry.set_typ(0); + entry.set_phys((phys + memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed)) >> 12); + + Self { entry } + } +} + +pub type Lv4Entry = TableEntry<4>; +pub type Lv3Entry = TableEntry<3>; +pub type Lv2Entry = TableEntry<2>; +pub type Lv1Entry = TableEntry<1>; + bitfield! { pub struct EntryBase(u64); impl Debug; @@ -25,6 +80,22 @@ impl EntryBase { pub fn address(&self) -> PhysAddr { PhysAddr::new(self.phys() << 12) } - - pub fn new_map_table() {} +} + +impl Default for EntryBase { + fn default() -> Self { + let mut entry = EntryBase(0); + entry.set_read(true); + entry.set_write(true); + entry.set_exec_super(true); + entry.set_typ(0); + entry.set_ignore_pat(false); + entry.set_map_memory(false); + entry.set_accessed(false); + entry.set_dirty(false); + entry.set_exec_user(true); + entry.set_phys(0); + + entry + } }