Fix virtual_memory::drop_table freeing each mapping frame multiple times

This commit is contained in:
pjht 2024-07-07 08:06:15 -05:00
parent a98324c3b4
commit e2d248b609
Signed by: pjht
GPG Key ID: 7B5F6AFBEC7EE78E

View File

@ -1,6 +1,6 @@
mod holes; mod holes;
use crate::{bootinfo::BOOTINFO, dbg, physical_memory::PHYSICAL_MEMORY, println}; use crate::{bootinfo::BOOTINFO, physical_memory::PHYSICAL_MEMORY};
use alloc::alloc::{AllocError, Allocator, Layout}; use alloc::alloc::{AllocError, Allocator, Layout};
use core::{fmt, ops::Deref, ptr::NonNull, slice}; use core::{fmt, ops::Deref, ptr::NonNull, slice};
use replace_with::replace_with_or_abort; use replace_with::replace_with_or_abort;
@ -44,7 +44,7 @@ pub enum PagingError {
PageAlreadyMapped, PageAlreadyMapped,
PagesAlreadyMapped, PagesAlreadyMapped,
PageNotMapped, PageNotMapped,
InvalidFrameAddress(PhysAddr), InvalidFrameAddress(#[allow(dead_code)] PhysAddr),
} }
impl From<MapToError<Size4KiB>> for PagingError { impl From<MapToError<Size4KiB>> for PagingError {
@ -474,6 +474,7 @@ impl Drop for AddressSpace {
} }
fn drop_table(table: &PageTable, level: u8) { fn drop_table(table: &PageTable, level: u8) {
if level > 2 {
for (i, entry) in table.iter().enumerate() { for (i, entry) in table.iter().enumerate() {
if level == 4 && i >= 256 { if level == 4 && i >= 256 {
continue; continue;
@ -481,7 +482,6 @@ fn drop_table(table: &PageTable, level: u8) {
if entry.flags().contains(PageTableFlags::PRESENT) if entry.flags().contains(PageTableFlags::PRESENT)
&& !entry.flags().contains(PageTableFlags::HUGE_PAGE) && !entry.flags().contains(PageTableFlags::HUGE_PAGE)
{ {
if level > 2 {
// SAFETY: The present flag is set on the entry, which means the child frame must // SAFETY: The present flag is set on the entry, which means the child frame must
// contain a valid page table, so making a reference to it must be ok. // contain a valid page table, so making a reference to it must be ok.
// Unwrap: from_start_address requires it's input to be 4KiB aligned (have none of its lower 12 bits // Unwrap: from_start_address requires it's input to be 4KiB aligned (have none of its lower 12 bits
@ -493,18 +493,13 @@ fn drop_table(table: &PageTable, level: u8) {
level - 1, level - 1,
); );
} }
let phys_addr = match ACTIVE_SPACE.lock().translate(VirtAddr::from_ptr(table)) { }
TranslateResult::Mapped { frame, .. } => frame.start_address(), }
_ => panic!("Refrence must point to mapped page!"), let phys_addr = ACTIVE_SPACE.lock().translate_addr(VirtAddr::from_ptr(table)).unwrap();
};
unsafe { unsafe {
PHYSICAL_MEMORY PHYSICAL_MEMORY.lock().deallocate_frame(PhysFrame::from_start_address(phys_addr).unwrap());
.lock()
.deallocate_frame(PhysFrame::from_start_address(phys_addr).unwrap());
}; };
} }
}
}
impl Translate for AddressSpace { impl Translate for AddressSpace {
fn translate(&self, addr: VirtAddr) -> TranslateResult { fn translate(&self, addr: VirtAddr) -> TranslateResult {