From c3dacb290690524f6d68dbd4297112e9799c9221 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 4 Jul 2019 17:43:08 -0700 Subject: [PATCH] Fix mis-flagged page table entries --- src/kernel/memory_bootstrap.cpp | 28 +++++++++++++++++++++++++--- src/kernel/page_manager.cpp | 13 +++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/kernel/memory_bootstrap.cpp b/src/kernel/memory_bootstrap.cpp index 4b1eac2..0b54c1b 100644 --- a/src/kernel/memory_bootstrap.cpp +++ b/src/kernel/memory_bootstrap.cpp @@ -186,9 +186,31 @@ memory_initialize(uint16_t scratch_pages, const void *memory_map, size_t map_len page_table *id_pml4 = &tables[0]; page_table *id_pdp = &tables[1]; + + // Flags: 0 0 0 0 1 1 0 0 0 0 0 1 1 = 0x0183 + // | IGN | | | | | | | | +- Present + // | | | | | | | | +--- Writeable + // | | | | | | | +----- Supervisor only + // | | | | | | +------- PWT (determining memory type for page) + // | | | | | +---------- PCD (determining memory type for page) + // | | | | +------------ Accessed flag (not accessed yet) + // | | | +-------------- Dirty (not dirtied yet) + // | | +---------------- Page size (1GiB page) + // | +------------------- Global + // +---------------------------- PAT (determining memory type for page) for (int i=0; i<512; ++i) - id_pdp->entries[i] = (static_cast(i) << 30) | 0x18b; - id_pml4->entries[511] = reinterpret_cast(id_pdp) | 0x10b; + id_pdp->entries[i] = (static_cast(i) << 30) | 0x0183; + + // Flags: 0 0 0 0 0 0 0 0 0 0 1 1 = 0x0003 + // IGNORED | | | | | | | +- Present + // | | | | | | +--- Writeable + // | | | | | +----- Supervisor only + // | | | | +------- PWT (determining memory type for pdpt) + // | | | +---------- PCD (determining memory type for pdpt) + // | | +------------ Accessed flag (not accessed yet) + // | +-------------- Ignored + // +---------------- Reserved 0 + id_pml4->entries[511] = reinterpret_cast(id_pdp) | 0x003; // Make sure the page table is finished updating before we write to memory __sync_synchronize(); @@ -218,7 +240,7 @@ memory_initialize(uint16_t scratch_pages, const void *memory_map, size_t map_len pml4 = kutil::offset_pointer(pml4, page_offset); kutil::memset(pml4, 0, sizeof(page_table)); - pml4->entries[511] = reinterpret_cast(id_pdp) | 0x10b; + pml4->entries[511] = reinterpret_cast(id_pdp) | 0x003; bootstrap.page_in_kernel(*pm, pml4); diff --git a/src/kernel/page_manager.cpp b/src/kernel/page_manager.cpp index efa7120..9be0a3e 100644 --- a/src/kernel/page_manager.cpp +++ b/src/kernel/page_manager.cpp @@ -17,6 +17,13 @@ using memory::page_mappable; page_manager g_page_manager(g_frame_allocator); extern kutil::vm_space g_kspace; +// NB: in 4KiB page table entries, bit 7 isn't pagesize but PAT. Currently this +// doesn't matter, becasue in the default PAT table, both 000 and 100 are WB. +constexpr uint64_t sys_page_flags = 0x183; // global, pagesize, write, present +constexpr uint64_t sys_table_flags = 0x003; // write, present +constexpr uint64_t user_page_flags = 0x087; // pagesize, user, write, present +constexpr uint64_t user_table_flags = 0x007; // user, write, present + static uintptr_t pt_to_phys(page_table *pt) { @@ -335,7 +342,7 @@ page_manager::check_needs_page(page_table *table, unsigned index, bool user) page_table *new_table = get_table_page(); for (int i=0; i<512; ++i) new_table->entries[i] = 0; - table->entries[index] = pt_to_phys(new_table) | (user ? 0xf : 0xb); + table->entries[index] = pt_to_phys(new_table) | (user ? user_table_flags : sys_table_flags); } void @@ -349,9 +356,7 @@ page_manager::page_in(page_table *pml4, uintptr_t phys_addr, uintptr_t virt_addr page_table_indices idx{virt_addr}; page_table *tables[4] = {pml4, nullptr, nullptr, nullptr}; - uint64_t flags = user ? - 0x00f: // writethru, user, write, present - 0x10b; // global, writethru, write, present + uint64_t flags = user ? user_table_flags : sys_table_flags; for (; idx[0] < 512; idx[0] += 1) { check_needs_page(tables[0], idx[0], user);