diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c index c26049e..87b9058 100644 --- a/src/kernel/memory/vmm.c +++ b/src/kernel/memory/vmm.c @@ -82,4 +82,24 @@ void free_page(void *P4, uintptr_t addr, int free) )) return; P1e(P4, addr).value = 0; + + union PTE *pt; + + pt = PT(P2e(P4, addr).value); + for(int i = 0; i < ENTRIES_PER_PT; i++) + if(pt[i].value) + return; + P2e(P4, addr).value = 0; + + pt = PT(P3e(P4, addr).value); + for(int i = 0; i < ENTRIES_PER_PT; i++) + if(pt[i].value) + return; + P3e(P4, addr).value = 0; + + pt = PT(P4e(P4, addr).value); + for(int i = 0; i < ENTRIES_PER_PT; i++) + if(pt[i].value) + return; + P4e(P4, addr).value = 0; } diff --git a/src/kernel/memory/vmm.tt b/src/kernel/memory/vmm.tt index 29284c5..d8a9ffa 100644 --- a/src/kernel/memory/vmm.tt +++ b/src/kernel/memory/vmm.tt @@ -137,3 +137,12 @@ TEST(free_page_unsets_page) ASSERT_EQ_PTR(p1[4], 0); } +TEST(free_page_unsets_P2_entry_if_P1_is_empty) +{ + BUILD_PT(1,2,3); + p1[4] = PAGE_PRESENT; + + free_page(p4, ADDR1234, 1); + + ASSERT_EQ_PTR(p2[3], 0); +}