VMM - get_page fails if PTE not present

This commit is contained in:
Thomas Lovén 2017-12-24 01:59:35 +01:00
parent d32e93b72b
commit 57482136ae
2 changed files with 41 additions and 14 deletions

View File

@ -6,7 +6,16 @@
union PTE {
uint64_t value;
struct {
uintptr_t flags:12;
uintptr_t present:1;
uintptr_t write:1;
uintptr_t user:1;
uintptr_t write_through:1;
uintptr_t nocache:1;
uintptr_t accessed:1;
uintptr_t dirty:1;
uintptr_t huge:1;
uintptr_t global:1;
uintptr_t flags:3;
};
};
@ -19,11 +28,12 @@ union PTE {
uintptr_t vmm_get_page(void *P4, uintptr_t addr)
{
if(P4
&& P4e(P4, addr).value
&& P3e(P4, addr).value
&& P2e(P4, addr).value
&& P4e(P4, addr).present
&& P3e(P4, addr).present
&& P2e(P4, addr).present
&& P1e(P4, addr).present
)
return MASK_FLAGS(P1e(P4, addr).value);
else
return 0;
return -1;
}

View File

@ -22,9 +22,12 @@ AFTER()
TEST(get_page_returns_correct_address)
{
p4[0] = (uintptr_t)p3;
p4[0] |= PAGE_PRESENT;
p3[0] = (uintptr_t)p2;
p3[0] |= PAGE_PRESENT;
p2[0] = (uintptr_t)p1;
p1[0] = 0x1234567890ABC000;
p2[0] |= PAGE_PRESENT;
p1[0] = 0x1234567890ABC000 | PAGE_PRESENT;
uintptr_t ret = vmm_get_page(p4, 0);
@ -33,12 +36,12 @@ TEST(get_page_returns_correct_address)
TEST(get_page_ignores_flags)
{
p4[0] = (uintptr_t)p3;
p4[0] |= 0x123;
p4[0] |= PAGE_PRESENT;
p3[0] = (uintptr_t)p2;
p3[0] |= 0x456;
p3[0] |= PAGE_PRESENT;
p2[0] = (uintptr_t)p1;
p2[0] |= 0x789;
p1[0] = 0x1234567890ABCDEF;
p2[0] |= PAGE_PRESENT;
p1[0] = 0x1234567890ABC000 | PAGE_PRESENT;
uintptr_t ret = vmm_get_page(p4, 0);
@ -47,14 +50,28 @@ TEST(get_page_ignores_flags)
TEST(get_page_works_for_different_address)
{
p4[1] = (uintptr_t)p3;
p4[1] |= 0x123;
p4[1] |= PAGE_PRESENT;
p3[2] = (uintptr_t)p2;
p3[2] |= 0x456;
p3[2] |= PAGE_PRESENT;
p2[3] = (uintptr_t)p1;
p2[3] |= 0x789;
p1[4] = 0x34567890ABCDEF12;
p2[3] |= PAGE_PRESENT;
p1[4] = 0x34567890ABCDE000 | PAGE_PRESENT;
uintptr_t ret = vmm_get_page(p4, (1UL<<39)+(2UL<<30)+(3UL<<21)+(4UL<<12));
ASSERT_EQ_PTR(ret, 0x34567890ABCDE000);
}
TEST(get_page_fails_if_PTE_not_present)
{
p4[0] = (uintptr_t)p3;
p4[0] |= PAGE_PRESENT;
p3[0] = (uintptr_t)p2;
p3[0] |= PAGE_PRESENT;
p2[0] = (uintptr_t)p1;
p2[0] |= 0;
p1[0] = 0x1234567890ABC000 | PAGE_PRESENT;
uintptr_t ret = vmm_get_page(p4, 0);
ASSERT_EQ_PTR(ret, -1);
}