From ce937c808841b40f23e898e9aa71071860b6068a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Wed, 3 Jan 2018 14:16:02 +0100 Subject: [PATCH] VMM - free_page does not unset P2 entry if P1 is not empty --- src/kernel/memory/vmm.c | 27 +++++++++++++++++---------- src/kernel/memory/vmm.tt | 11 +++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c index 6acfd13..4ba7afc 100644 --- a/src/kernel/memory/vmm.c +++ b/src/kernel/memory/vmm.c @@ -98,21 +98,28 @@ int touch_page(void *P4, uintptr_t addr, uint16_t flags) void free_page(void *P4, uintptr_t addr, int free) { - (void)free; if(!page_exists(P4, addr)) return; - P1e(P4, addr).value = 0; - - if(!free) return; union PTE *pt; - pt = PT(P2e(P4, addr).value); - for(int i = 0; i < ENTRIES_PER_PT; i++) - if(pt[i].value) - return; - pmm_free(MASK_FLAGS(P2e(P4, addr).value)); - P2e(P4, addr).value = 0; + if(P2e(P4, addr).huge) + { + P2e(P4, addr).value = 0; + + if(!free) return; + } else { + P1e(P4, addr).value = 0; + + if(!free) return; + + pt = PT(P2e(P4, addr).value); + for(int i = 0; i < ENTRIES_PER_PT; i++) + if(pt[i].value) + return; + pmm_free(MASK_FLAGS(P2e(P4, addr).value)); + P2e(P4, addr).value = 0; + } pt = PT(P3e(P4, addr).value); for(int i = 0; i < ENTRIES_PER_PT; i++) diff --git a/src/kernel/memory/vmm.tt b/src/kernel/memory/vmm.tt index b3e729b..b08f308 100644 --- a/src/kernel/memory/vmm.tt +++ b/src/kernel/memory/vmm.tt @@ -196,6 +196,17 @@ TEST(free_page_does_not_unset_P2_entry_if_P1_is_not_empty) ASSERT_NEQ_PTR(p2[3], 0); } +TEST(free_page_does_not_stop_if_P2_pointed_page_is_not_empty) +{ + BUILD_PT(1,2,3); + p2[3] |= PAGE_HUGE; + p1[4] = PAGE_PRESENT; + p1[0] = PAGE_PRESENT; + + free_page(p4, ADDR1234, 1); + + ASSERT_EQ_PTR(p2[3], 0); +} uintptr_t freed[] = {0,0,0,0,0}; void pmm_free(uintptr_t page)