Implement automatic paging table deallocation

This commit is contained in:
2026-01-04 21:26:11 +01:00
parent bba36ef057
commit b1579e4ac1

View File

@@ -77,6 +77,14 @@ static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool
return (uint64_t*)((uintptr_t)hhdm->offset + (uintptr_t)paddr);
}
static bool amd64_mm_is_table_empty (uint64_t* table) {
for (size_t i = 0; i < 512; i++) {
if (table[i] & AMD64_PG_PRESENT)
return false;
}
return true;
}
/// Convert generic memory management subsystem flags into AMD64-specific flags
static uint64_t amd64_mm_resolve_flags (uint32_t generic) {
uint64_t flags = 0;
@@ -171,8 +179,28 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr, uint32_t flags) {
uint64_t* pte = &pml1[pg_index.pml1];
*pte &= ~AMD64_PG_PRESENT;
do_reload = true;
if ((*pte) & AMD64_PG_PRESENT) {
*pte = 0;
do_reload = true;
}
if (amd64_mm_is_table_empty (pml1)) {
uintptr_t pml1_phys = pml2[pg_index.pml2] & ~0xFFFULL;
pmm_free (pml1_phys, 1);
pml2[pg_index.pml2] = 0;
if (amd64_mm_is_table_empty (pml2)) {
uintptr_t pml2_phys = pml3[pg_index.pml3] & ~0xFFFULL;
pmm_free (pml2_phys, 1);
pml3[pg_index.pml3] = 0;
if (amd64_mm_is_table_empty (pml3)) {
uintptr_t pml3_phys = pml4[pg_index.pml4] & ~0xFFFULL;
pmm_free (pml3_phys, 1);
pml4[pg_index.pml4] = 0;
}
}
}
done:
if (do_reload && (flags & MM_PD_RELOAD))