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 { union PTE {
uint64_t value; uint64_t value;
struct { 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) uintptr_t vmm_get_page(void *P4, uintptr_t addr)
{ {
if(P4 if(P4
&& P4e(P4, addr).value && P4e(P4, addr).present
&& P3e(P4, addr).value && P3e(P4, addr).present
&& P2e(P4, addr).value && P2e(P4, addr).present
&& P1e(P4, addr).present
) )
return MASK_FLAGS(P1e(P4, addr).value); return MASK_FLAGS(P1e(P4, addr).value);
else else
return 0; return -1;
} }

View File

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