Skip to content

Commit

Permalink
Mem: Fix issues with page tables and impl invlpg
Browse files Browse the repository at this point in the history
  • Loading branch information
corigan01 committed Jan 20, 2025
1 parent 8d90a45 commit fd33038
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 30 deletions.
1 change: 1 addition & 0 deletions crates/mem/src/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ macro_rules! make_addr {

impl<A: AlignmentTo> $ident<A> {
/// Force a value as an addr.
#[inline]
pub const unsafe fn new_unchecked(value: usize) -> Self {
Self {
addr: value,
Expand Down
1 change: 1 addition & 0 deletions crates/mem/src/page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl<S: PagingStructureSize> VirtPage<S> {
}

/// Get the address that this page represents.
#[inline]
pub const fn addr(&self) -> VirtAddr {
// We know this is safe because we are of this alignment
unsafe { VirtAddr::new_unchecked(self.id * S::N_BYTES) }
Expand Down
38 changes: 36 additions & 2 deletions crates/mem/src/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,13 @@ impl Clone for Virt2PhysMapping {
/// Flush this page from the TLB
#[inline]
pub unsafe fn flush_tlb(page: VirtPage) {
todo!()
unsafe {
core::arch::asm!(
"invlpg [rax]",
in("rax") page.addr().addr(),
options(nostack)
)
}
}

/// Returns the indexes into the page tables that would give this virtual address.
Expand Down Expand Up @@ -351,7 +357,7 @@ impl Virt2PhysMapping {
let page_entry = lower.table.get(lvl1_index);

// Make sure we don't override unless we are told to
if entry.is_present_set() && !options.is_overwrite_set() {
if page_entry.is_present_set() && !options.is_overwrite_set() {
return Some(PageCorrelationError::PageAlreadyMapped);
}

Expand Down Expand Up @@ -982,6 +988,34 @@ impl SafePageMapLvl1 {
}

impl core::fmt::Debug for Virt2PhysMapping {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mapping_lock = self.mapping.read();

let Some(_) = mapping_lock.as_ref() else {
writeln!(f, "Virt2PhysMapping ?? (Empty)")?;
return Ok(());
};

write!(f, "Virt2PhysMapping (",)?;

if self.is_loaded() {
write!(f, "Current")?;
} else {
write!(
f,
"Not Loaded, refs={}",
self.mapping
.read()
.as_ref()
.map(|inner| Arc::strong_count(inner))
.unwrap_or(0)
)?;
}
writeln!(f, ")")
}
}

impl core::fmt::Display for Virt2PhysMapping {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mapping_lock = self.mapping.read();

Expand Down
46 changes: 18 additions & 28 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,36 +101,26 @@ fn main(kbh: &KernelBootHeader) {
);
mem::pmm::set_physical_memory_manager(pmm);

logln!("Attached virt2phys provider!");
init_virt2phys_provider();

let new_tables = Virt2PhysMapping::empty();
new_tables
.correlate_page(
mem::page::VirtPage::new(10),
PhysPage::new(1),
VmOptions::none()
.set_no_tlb_flush_flag(true)
.set_increase_perm_flag(true),
mem::paging::VmPermissions::none()
.set_read_flag(true)
.set_write_flag(true)
.set_exec_flag(true),
)
.unwrap();
new_tables
.correlate_page(
mem::page::VirtPage::new(51224),
PhysPage::new(2),
VmOptions::none()
.set_no_tlb_flush_flag(true)
.set_increase_perm_flag(true),
mem::paging::VmPermissions::none()
.set_read_flag(true)
.set_write_flag(true)
.set_exec_flag(true)
.set_user_flag(true),
)
.unwrap();
logln!("Page tables:\n{new_tables:#?}");
for i in 0..1024 {
new_tables
.correlate_page(
mem::page::VirtPage::new(10 + i),
PhysPage::new(1 + i),
VmOptions::none()
.set_no_tlb_flush_flag(false)
.set_increase_perm_flag(true),
mem::paging::VmPermissions::none()
.set_read_flag(true)
.set_write_flag(true)
.set_exec_flag(true),
)
.unwrap();
}
// logln!("Page tables:\n{new_tables:#?}");

logln!("Init VirtMemoryManager");
let kernel_process = unsafe { VmProcess::new_from_bootloader() };
Expand Down

0 comments on commit fd33038

Please sign in to comment.