VMM -- Know what? Let's ignore huge pages for simplicity
This commit is contained in:
parent
ae2de799f3
commit
cb09833ebc
@ -24,7 +24,7 @@ void memory_init()
|
|||||||
uint64_t page = vmm_get_page(kernel_P4, addr);
|
uint64_t page = vmm_get_page(kernel_P4, addr);
|
||||||
if(!PAGE_EXIST(page) || !(page & PAGE_PRESENT))
|
if(!PAGE_EXIST(page) || !(page & PAGE_PRESENT))
|
||||||
{
|
{
|
||||||
uint16_t flags = PAGE_GLOBAL | PAGE_HUGE | PAGE_WRITE;
|
uint16_t flags = PAGE_GLOBAL | PAGE_WRITE;
|
||||||
vmm_set_page(kernel_P4, addr, p, flags | PAGE_PRESENT, 1);
|
vmm_set_page(kernel_P4, addr, p, flags | PAGE_PRESENT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,6 @@ uint64_t vmm_get_page(uint64_t P4, uint64_t addr)
|
|||||||
{
|
{
|
||||||
if(page_exists(P4, addr))
|
if(page_exists(P4, addr))
|
||||||
{
|
{
|
||||||
if(P2E.huge)
|
|
||||||
return P2E.value;
|
|
||||||
return P1E.value;
|
return P1E.value;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -48,22 +46,6 @@ uint64_t vmm_get_page(uint64_t P4, uint64_t addr)
|
|||||||
|
|
||||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags, int touch)
|
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags, int touch)
|
||||||
{
|
{
|
||||||
if(flags & PAGE_HUGE)
|
|
||||||
{
|
|
||||||
if(!(P4 && P4E.present && P3E.present))
|
|
||||||
{
|
|
||||||
if(!touch)
|
|
||||||
return -1;
|
|
||||||
touch_page(P4, addr, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't overwrite a non-huge page with a huge one
|
|
||||||
if(P2E.present && !P2E.huge)
|
|
||||||
return -1;
|
|
||||||
P2E.value = page | flags;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!page_exists(P4, addr))
|
if(!page_exists(P4, addr))
|
||||||
{
|
{
|
||||||
if(!touch)
|
if(!touch)
|
||||||
@ -79,9 +61,6 @@ int touch_page(uint64_t P4, uint64_t addr, uint16_t flags)
|
|||||||
{
|
{
|
||||||
if(!P4) return -1;
|
if(!P4) return -1;
|
||||||
|
|
||||||
int huge=(flags & PAGE_HUGE)?1:0;
|
|
||||||
flags ^= PAGE_HUGE*huge;
|
|
||||||
|
|
||||||
if((!P4E.present) && (!(P4E.value = pmm_calloc())))
|
if((!P4E.present) && (!(P4E.value = pmm_calloc())))
|
||||||
return -1;
|
return -1;
|
||||||
P4E.value |= flags | PAGE_PRESENT;
|
P4E.value |= flags | PAGE_PRESENT;
|
||||||
@ -90,8 +69,6 @@ int touch_page(uint64_t P4, uint64_t addr, uint16_t flags)
|
|||||||
return -1;
|
return -1;
|
||||||
P3E.value |= flags | PAGE_PRESENT;
|
P3E.value |= flags | PAGE_PRESENT;
|
||||||
|
|
||||||
if(huge) return 0;
|
|
||||||
|
|
||||||
if((!P2E.present) && (!(P2E.value = pmm_calloc())))
|
if((!P2E.present) && (!(P2E.value = pmm_calloc())))
|
||||||
return -1;
|
return -1;
|
||||||
P2E.value |= flags | PAGE_PRESENT;
|
P2E.value |= flags | PAGE_PRESENT;
|
||||||
@ -106,25 +83,17 @@ void free_page(uint64_t P4, uint64_t addr, int free)
|
|||||||
|
|
||||||
union PTE *pt;
|
union PTE *pt;
|
||||||
|
|
||||||
if(P2E.huge)
|
P1E.value = 0;
|
||||||
{
|
|
||||||
P2E.value = 0;
|
|
||||||
|
|
||||||
if(!free)
|
if(!free)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pt = PT(P2E.value);
|
||||||
|
for(int i = 0; i < ENTRIES_PER_PT; i++)
|
||||||
|
if(pt[i].value)
|
||||||
return;
|
return;
|
||||||
} else {
|
pmm_free(MASK_FLAGS(P2E.value));
|
||||||
P1E.value = 0;
|
P2E.value = 0;
|
||||||
|
|
||||||
if(!free)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pt = PT(P2E.value);
|
|
||||||
for(int i = 0; i < ENTRIES_PER_PT; i++)
|
|
||||||
if(pt[i].value)
|
|
||||||
return;
|
|
||||||
pmm_free(MASK_FLAGS(P2E.value));
|
|
||||||
P2E.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pt = PT(P3E.value);
|
pt = PT(P3E.value);
|
||||||
for(int i = 0; i < ENTRIES_PER_PT; i++)
|
for(int i = 0; i < ENTRIES_PER_PT; i++)
|
||||||
|
@ -68,15 +68,6 @@ TEST(get_page_fails_if_PTE_not_present)
|
|||||||
|
|
||||||
ASSERT_EQ_PTR(ret, -1);
|
ASSERT_EQ_PTR(ret, -1);
|
||||||
}
|
}
|
||||||
TEST(get_page_gets_2mb_pages)
|
|
||||||
{
|
|
||||||
p4[1] = (uint64_t)p3; p4[1] |= PAGE_PRESENT;
|
|
||||||
p3[2] = (uint64_t)p2; p3[2] |= PAGE_PRESENT;
|
|
||||||
p2[3] = 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT;
|
|
||||||
|
|
||||||
uint64_t ret = vmm_get_page(P4, ADDR1234);
|
|
||||||
ASSERT_EQ_PTR(ret, 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(set_page_sets_page)
|
TEST(set_page_sets_page)
|
||||||
{
|
{
|
||||||
@ -121,23 +112,6 @@ TEST(set_page_makes_P3_if_PT_missing_but_touch_flag_is_set)
|
|||||||
|
|
||||||
ASSERT_EQ_INT(p3[0] & PAGE_PRESENT, PAGE_PRESENT);
|
ASSERT_EQ_INT(p3[0] & PAGE_PRESENT, PAGE_PRESENT);
|
||||||
}
|
}
|
||||||
TEST(set_page_sets_2mb_pages)
|
|
||||||
{
|
|
||||||
p4[1] = (uint64_t)p3; p4[1] |= PAGE_PRESENT;
|
|
||||||
p3[2] = (uint64_t)p2; p3[2] |= PAGE_PRESENT;
|
|
||||||
|
|
||||||
vmm_set_page(P4, (1UL<<39)+(2UL<<30)+(3UL<<21), 0x1234567890A00000, PAGE_HUGE | PAGE_PRESENT, 0);
|
|
||||||
|
|
||||||
ASSERT_EQ_PTR(p2[3], 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT);
|
|
||||||
}
|
|
||||||
TEST(set_page_does_not_overwrite_4kb_pages_with_2mb)
|
|
||||||
{
|
|
||||||
BUILD_PT(0,0,0);
|
|
||||||
|
|
||||||
int retval = vmm_set_page(P4, 0, 0, PAGE_HUGE | PAGE_PRESENT, 0);
|
|
||||||
|
|
||||||
ASSERT_NEQ_INT(retval, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t pmm_calloc()
|
uint64_t pmm_calloc()
|
||||||
{
|
{
|
||||||
@ -177,11 +151,6 @@ TEST(touch_page_fails_if_out_of_pages)
|
|||||||
int retval = touch_page(P4, 0, 0);
|
int retval = touch_page(P4, 0, 0);
|
||||||
ASSERT_NEQ_INT(retval, 0);
|
ASSERT_NEQ_INT(retval, 0);
|
||||||
}
|
}
|
||||||
TEST(touch_page_stops_at_P2_for_huge_pages)
|
|
||||||
{
|
|
||||||
touch_page(P4, 0, PAGE_HUGE);
|
|
||||||
ASSERT_EQ_PTR(p2[0], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(free_page_unsets_page)
|
TEST(free_page_unsets_page)
|
||||||
{
|
{
|
||||||
@ -220,17 +189,6 @@ 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t freed[] = {0,0,0,0,0};
|
uint64_t freed[] = {0,0,0,0,0};
|
||||||
void pmm_free(uint64_t page)
|
void pmm_free(uint64_t page)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user