VMM - free_page does not unset P2 entry if P1 is not empty

This commit is contained in:
Thomas Lovén 2018-01-03 14:16:02 +01:00
parent 96a877c95b
commit ce937c8088
2 changed files with 28 additions and 10 deletions

View File

@ -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_page(void *P4, uintptr_t addr, int free)
{ {
(void)free;
if(!page_exists(P4, addr)) if(!page_exists(P4, addr))
return; return;
union PTE *pt;
if(P2e(P4, addr).huge)
{
P2e(P4, addr).value = 0;
if(!free) return;
} else {
P1e(P4, addr).value = 0; P1e(P4, addr).value = 0;
if(!free) return; if(!free) return;
union PTE *pt;
pt = PT(P2e(P4, addr).value); pt = PT(P2e(P4, addr).value);
for(int i = 0; i < ENTRIES_PER_PT; i++) for(int i = 0; i < ENTRIES_PER_PT; i++)
if(pt[i].value) if(pt[i].value)
return; return;
pmm_free(MASK_FLAGS(P2e(P4, addr).value)); pmm_free(MASK_FLAGS(P2e(P4, addr).value));
P2e(P4, addr).value = 0; P2e(P4, addr).value = 0;
}
pt = PT(P3e(P4, addr).value); pt = PT(P3e(P4, addr).value);
for(int i = 0; i < ENTRIES_PER_PT; i++) for(int i = 0; i < ENTRIES_PER_PT; i++)

View File

@ -196,6 +196,17 @@ TEST(free_page_does_not_unset_P2_entry_if_P1_is_not_empty)
ASSERT_NEQ_PTR(p2[3], 0); 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}; uintptr_t freed[] = {0,0,0,0,0};
void pmm_free(uintptr_t page) void pmm_free(uintptr_t page)