i686: free translation tables
This commit is contained in:
parent
c907fe032a
commit
ce8ccf4af9
@ -64,6 +64,16 @@ impl KernelTableManager for KernelTableManagerImpl {
|
||||
.expect("Invalid virtual address")
|
||||
.into_u64()
|
||||
}
|
||||
|
||||
unsafe fn unmap_physical_address(virt: usize) {
|
||||
if virt < KERNEL_VIRT_OFFSET {
|
||||
panic!("Invalid 'virtualized' address: {:#x}", virt);
|
||||
}
|
||||
let virt = virt - KERNEL_VIRT_OFFSET;
|
||||
if virt >= fixed::FIXED_MAP_COUNT << L0::SHIFT {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets up fixed MMU translation tables.
|
||||
|
@ -5,14 +5,16 @@ use libk_mm_interface::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
pointer::PhysicalRefMut,
|
||||
process::ProcessAddressSpaceManager,
|
||||
table::{EntryLevel, EntryLevelExt, MapAttributes, NextPageTable, TableAllocator},
|
||||
table::{
|
||||
EntryLevel, EntryLevelDrop, EntryLevelExt, MapAttributes, NextPageTable, TableAllocator,
|
||||
},
|
||||
};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
use crate::{mem::flush_tlb_entry, KernelTableManagerImpl};
|
||||
|
||||
use super::{
|
||||
fixed::clone_kernel_tables,
|
||||
fixed::{clone_kernel_tables, KERNEL_SPLIT_L0},
|
||||
table::{PageEntry, PageTable, L0, L3},
|
||||
};
|
||||
|
||||
@ -46,9 +48,7 @@ impl<TA: TableAllocator> ProcessAddressSpaceManager<TA> for ProcessAddressSpaceI
|
||||
}
|
||||
|
||||
unsafe fn clear(&mut self) {
|
||||
// TODO
|
||||
// self.l0
|
||||
// .drop_range::<TA>(0..((Self::UPPER_LIMIT_PFN * L3::SIZE).page_index::<L0>()));
|
||||
self.l0.drop_range::<TA>(0..KERNEL_SPLIT_L0);
|
||||
}
|
||||
|
||||
fn translate(&self, address: usize) -> Result<(PhysicalAddress, MapAttributes), Error> {
|
||||
@ -123,3 +123,15 @@ impl<TA: TableAllocator> ProcessAddressSpaceImpl<TA> {
|
||||
Some((page, l3[l3i].attributes().into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<TA: TableAllocator> Drop for ProcessAddressSpaceImpl<TA> {
|
||||
fn drop(&mut self) {
|
||||
// SAFETY: with safe usage of the ProcessAddressSpaceImpl, clearing and dropping
|
||||
// is safe, no one refers to the memory
|
||||
unsafe {
|
||||
self.clear();
|
||||
let l0_phys = self.l0.as_physical_address();
|
||||
TA::free_page_table(l0_phys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
use core::{
|
||||
marker::PhantomData,
|
||||
ops::{Index, IndexMut},
|
||||
ops::{Index, IndexMut, Range},
|
||||
};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use libk_mm_interface::{
|
||||
address::{AsPhysicalAddress, PhysicalAddress},
|
||||
pointer::{PhysicalRef, PhysicalRefMut},
|
||||
table::{EntryLevel, MapAttributes, NextPageTable, NonTerminalEntryLevel, TableAllocator},
|
||||
table::{
|
||||
EntryLevel, EntryLevelDrop, MapAttributes, NextPageTable, NonTerminalEntryLevel,
|
||||
TableAllocator,
|
||||
},
|
||||
};
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
@ -132,6 +135,16 @@ impl<L: EntryLevel> PageTable<L> {
|
||||
|
||||
Ok(table)
|
||||
}
|
||||
|
||||
/// Recursively clears and deallocates the translation table.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The caller must ensure the table is no longer in use and is not referenced anymore.
|
||||
pub unsafe fn free<TA: TableAllocator>(this: PhysicalRefMut<Self, KernelTableManagerImpl>) {
|
||||
let physical = this.as_physical_address();
|
||||
TA::free_page_table(physical);
|
||||
}
|
||||
}
|
||||
|
||||
impl NextPageTable for PageTable<L0> {
|
||||
@ -184,6 +197,39 @@ impl<L: EntryLevel> IndexMut<usize> for PageTable<L> {
|
||||
}
|
||||
}
|
||||
|
||||
impl EntryLevelDrop for PageTable<L3> {
|
||||
const FULL_RANGE: Range<usize> = 0..1024;
|
||||
|
||||
unsafe fn drop_range<TA: TableAllocator>(&mut self, _range: Range<usize>) {}
|
||||
}
|
||||
|
||||
impl EntryLevelDrop for PageTable<L0> {
|
||||
const FULL_RANGE: Range<usize> = 0..1024;
|
||||
|
||||
unsafe fn drop_range<TA: TableAllocator>(&mut self, range: Range<usize>) {
|
||||
for index in range {
|
||||
let entry = self[index];
|
||||
|
||||
if let Some(table) = entry.as_table() {
|
||||
let mut table_ref: PhysicalRefMut<PageTable<L3>, KernelTableManagerImpl> =
|
||||
PhysicalRefMut::map(table);
|
||||
|
||||
table_ref.drop_all::<TA>();
|
||||
|
||||
TA::free_page_table(table);
|
||||
} else if entry.is_present() {
|
||||
// Memory must've been cleared beforehand, so no non-table entries must be present
|
||||
panic!(
|
||||
"Expected a table containing only tables, got table[{}] = {:#x?}",
|
||||
index, entry.0
|
||||
);
|
||||
}
|
||||
|
||||
self[index] = PageEntry::INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MapAttributes> for PageAttributes {
|
||||
fn from(value: MapAttributes) -> Self {
|
||||
let mut res = PageAttributes::WRITABLE;
|
||||
|
@ -66,14 +66,15 @@ pub fn load_kernel_symbol_table<P: AsRef<Path>>(
|
||||
let mut map = DefaultHashTable::new();
|
||||
|
||||
loop {
|
||||
let mut len = [0; size_of::<usize>()];
|
||||
let mut len = [0; size_of::<u32>()];
|
||||
let mut value = [0; size_of::<u64>()];
|
||||
|
||||
if symbol_file.read(&mut len)? != len.len() {
|
||||
break;
|
||||
}
|
||||
let len = u32::from_le_bytes(len) as usize;
|
||||
symbol_file.read_exact(&mut string_buffer[..len])?;
|
||||
let name = core::str::from_utf8(&string_buffer[..len]).unwrap();
|
||||
let mut value = [0; size_of::<u64>()];
|
||||
symbol_file.read_exact(&mut value)?;
|
||||
let value = u64::from_le_bytes(value).try_into().unwrap();
|
||||
map.insert(name.into(), value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user