Implement automatic paging table deallocation
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user