rmm: Couple of minor cleanups

This commit is contained in:
bjorn3
2026-03-28 22:35:26 +01:00
parent 3593c53146
commit d02312055e
2 changed files with 49 additions and 74 deletions
+46 -50
View File
@@ -13,7 +13,7 @@ pub struct PageMapper<A, F> {
}
impl<A: Arch, F: FrameAllocator> PageMapper<A, F> {
pub unsafe fn new(table_kind: TableKind, table_addr: PhysicalAddress, allocator: F) -> Self {
unsafe fn new(table_kind: TableKind, table_addr: PhysicalAddress, allocator: F) -> Self {
Self {
table_kind,
table_addr,
@@ -128,25 +128,24 @@ impl<A: Arch, F: FrameAllocator> PageMapper<A, F> {
//TODO: check for overwriting entry
table.set_entry(i, entry);
return Some(PageFlush::new(virt));
} else {
let next_opt = table.next(i);
let next = match next_opt {
Some(some) => some,
None => {
let next_phys = self.allocator.allocate_one()?;
//TODO: correct flags?
let flags = A::ENTRY_FLAG_DEFAULT_TABLE
| if virt.kind() == TableKind::User {
A::ENTRY_FLAG_TABLE_USER
} else {
0
};
table.set_entry(i, PageEntry::new(next_phys.data(), flags));
table.next(i)?
}
};
table = next;
}
let next = match table.next(i) {
Some(some) => some,
None => {
let next_phys = self.allocator.allocate_one()?;
//TODO: correct flags?
let flags = A::ENTRY_FLAG_DEFAULT_TABLE
| if virt.kind() == TableKind::User {
A::ENTRY_FLAG_TABLE_USER
} else {
0
};
table.set_entry(i, PageEntry::new(next_phys.data(), flags));
table.next(i)?
}
};
table = next;
}
}
}
@@ -166,14 +165,12 @@ impl<A: Arch, F: FrameAllocator> PageMapper<A, F> {
f: impl FnOnce(&mut PageTable<A>, usize) -> T,
) -> Option<T> {
let mut table = self.table();
unsafe {
loop {
let i = table.index_of(virt)?;
if table.level() == 0 {
return Some(f(&mut table, i));
} else {
table = table.next(i)?;
}
loop {
let i = table.index_of(virt)?;
if table.level() == 0 {
return Some(f(&mut table, i));
} else {
table = unsafe { table.next(i)? };
}
}
}
@@ -223,30 +220,29 @@ unsafe fn unmap_phys_inner<A: Arch>(
table.set_entry(i, PageEntry::new(0, 0));
let entry = entry_opt?;
Some((entry.address().ok()?, entry.flags()))
} else {
let mut subtable = table.next(i)?;
let res =
unmap_phys_inner(virt, &mut subtable, initial_level, unmap_parents, allocator)?;
//TODO: This is a bad idea for architectures where the kernel mappings are done in the process tables,
// as these mappings may become out of sync
if unmap_parents {
// TODO: Use a counter? This would reduce the remaining number of available bits, but could be
// faster (benchmark is needed).
let is_still_populated = (0..A::PAGE_ENTRIES)
.map(|j| subtable.entry(j).expect("must be within bounds"))
.any(|e| e.present());
if !is_still_populated {
allocator.free_one(subtable.phys());
table.set_entry(i, PageEntry::new(0, 0));
}
}
Some(res)
return Some((entry.address().ok()?, entry.flags()));
}
let mut subtable = table.next(i)?;
let res = unmap_phys_inner(virt, &mut subtable, initial_level, unmap_parents, allocator)?;
//TODO: This is a bad idea for architectures where the kernel mappings are done in the process tables,
// as these mappings may become out of sync
if unmap_parents {
// TODO: Use a counter? This would reduce the remaining number of available bits, but could be
// faster (benchmark is needed).
let is_still_populated = (0..A::PAGE_ENTRIES)
.map(|j| subtable.entry(j).expect("must be within bounds"))
.any(|e| e.present());
if !is_still_populated {
allocator.free_one(subtable.phys());
table.set_entry(i, PageEntry::new(0, 0));
}
}
Some(res)
}
}
impl<A, F: core::fmt::Debug> core::fmt::Debug for PageMapper<A, F> {
+3 -24
View File
@@ -1,7 +1,7 @@
use core::marker::PhantomData;
use super::PageEntry;
use crate::{Arch, PhysicalAddress, TableKind, VirtualAddress};
use crate::{Arch, PhysicalAddress, VirtualAddress};
pub struct PageTable<A> {
base: VirtualAddress,
@@ -20,16 +20,6 @@ impl<A: Arch> PageTable<A> {
}
}
pub unsafe fn top(table_kind: TableKind) -> Self {
unsafe {
Self::new(
VirtualAddress::new(0),
A::table(table_kind),
A::PAGE_LEVELS - 1,
)
}
}
pub fn base(&self) -> VirtualAddress {
self.base
}
@@ -43,18 +33,7 @@ impl<A: Arch> PageTable<A> {
}
pub unsafe fn virt(&self) -> VirtualAddress {
unsafe {
A::phys_to_virt(self.phys)
// Recursive mapping
// let mut addr = 0xFFFF_FFFF_FFFF_F000;
// for level in (self.level + 1 .. A::PAGE_LEVELS).rev() {
// let index = (self.base.0 >> (level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT)) & A::PAGE_ENTRY_MASK;
// addr <<= A::PAGE_ENTRY_SHIFT;
// addr |= index << A::PAGE_SHIFT;
// }
// VirtualAddress::new(addr)
}
unsafe { A::phys_to_virt(self.phys) }
}
pub fn entry_base(&self, i: usize) -> Option<VirtualAddress> {
@@ -91,7 +70,7 @@ impl<A: Arch> PageTable<A> {
}
}
pub unsafe fn index_of(&self, address: VirtualAddress) -> Option<usize> {
pub fn index_of(&self, address: VirtualAddress) -> Option<usize> {
// Canonicalize address first
let address = VirtualAddress::new(address.data() & A::PAGE_ADDRESS_MASK);
let level_shift = self.level * A::PAGE_ENTRY_SHIFT + A::PAGE_SHIFT;