VMM -- Touch and set page in one operation
This commit is contained in:
parent
df0df93da7
commit
9bc1abceff
@ -41,7 +41,7 @@ uint64_t pmm_calloc();
|
||||
|
||||
uint64_t vmm_get_page(uint64_t P4, uint64_t addr);
|
||||
#define PAGE_EXIST(p) ((p) != (uint64_t)-1)
|
||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags);
|
||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags, int touch);
|
||||
int touch_page(uint64_t P4, uint64_t addr, uint16_t flags);
|
||||
void free_page(uint64_t P4, uint64_t addr, int free);
|
||||
|
||||
|
@ -25,8 +25,7 @@ void memory_init()
|
||||
if(!PAGE_EXIST(page) || !(page & PAGE_PRESENT))
|
||||
{
|
||||
uint16_t flags = PAGE_GLOBAL | PAGE_HUGE | PAGE_WRITE;
|
||||
touch_page(kernel_P4, addr, flags);
|
||||
vmm_set_page(kernel_P4, addr, p, flags | PAGE_PRESENT);
|
||||
vmm_set_page(kernel_P4, addr, p, flags | PAGE_PRESENT, 1);
|
||||
}
|
||||
|
||||
if(type == MMAP_FREE)
|
||||
|
@ -47,7 +47,7 @@ uint64_t vmm_get_page(uint64_t P4, uint64_t addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags)
|
||||
int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags, int touch)
|
||||
{
|
||||
if(flags & PAGE_HUGE)
|
||||
{
|
||||
@ -55,7 +55,12 @@ int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags)
|
||||
&& P4e(P4, addr).present
|
||||
&& P3e(P4, addr).present
|
||||
))
|
||||
{
|
||||
if(touch)
|
||||
touch_page(P4, addr, flags);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if(P2e(P4, addr).present && !P2e(P4,addr).huge)
|
||||
return -1;
|
||||
P2e(P4, addr).value = page | flags;
|
||||
@ -63,7 +68,12 @@ int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags)
|
||||
}
|
||||
|
||||
if(!page_exists(P4, addr))
|
||||
{
|
||||
if(touch)
|
||||
touch_page(P4, addr, flags);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
P1e(P4, addr).value = page | flags;
|
||||
return 0;
|
||||
|
@ -82,7 +82,7 @@ TEST(set_page_sets_page)
|
||||
{
|
||||
BUILD_PT(0,0,0);
|
||||
|
||||
vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT);
|
||||
vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT, 0);
|
||||
|
||||
ASSERT_EQ_PTR(p1[0], 0x1234567890ABC000 | PAGE_PRESENT);
|
||||
}
|
||||
@ -90,7 +90,7 @@ TEST(set_page_returns_success_if_working)
|
||||
{
|
||||
BUILD_PT(0,0,0);
|
||||
|
||||
int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT);
|
||||
int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT, 0);
|
||||
|
||||
ASSERT_EQ_INT(retval, 0);
|
||||
}
|
||||
@ -99,16 +99,34 @@ TEST(set_page_fails_if_PT_missing)
|
||||
BUILD_PT(0,0,0);
|
||||
p3[0] = (uint64_t)p2;
|
||||
|
||||
int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT);
|
||||
int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT, 0);
|
||||
|
||||
ASSERT_NEQ_INT(retval, 0);
|
||||
}
|
||||
TEST(set_page_does_not_fail_if_PT_missing_but_touch_flag_is_set)
|
||||
{
|
||||
BUILD_PT(0,0,0);
|
||||
p3[0] = (uint64_t)p2;
|
||||
|
||||
int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT, 1);
|
||||
|
||||
ASSERT_EQ_INT(retval, 0);
|
||||
}
|
||||
TEST(set_page_makes_P3_if_PT_missing_but_touch_flag_is_set)
|
||||
{
|
||||
BUILD_PT(0,0,0);
|
||||
p3[0] = (uint64_t)p2;
|
||||
|
||||
vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT, 1);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
@ -116,7 +134,7 @@ 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);
|
||||
int retval = vmm_set_page(P4, 0, 0, PAGE_HUGE | PAGE_PRESENT, 0);
|
||||
|
||||
ASSERT_NEQ_INT(retval, 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user