From 57482136ae25c624a2d9c19e12e6558027155f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sun, 24 Dec 2017 01:59:35 +0100 Subject: [PATCH] VMM - get_page fails if PTE not present --- src/kernel/memory/vmm.c | 20 +++++++++++++++----- src/kernel/memory/vmm.tt | 35 ++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c index 775771e..5282bf7 100644 --- a/src/kernel/memory/vmm.c +++ b/src/kernel/memory/vmm.c @@ -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; } diff --git a/src/kernel/memory/vmm.tt b/src/kernel/memory/vmm.tt index 07ae68e..ef52590 100644 --- a/src/kernel/memory/vmm.tt +++ b/src/kernel/memory/vmm.tt @@ -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); +}