diff options
author | Andreas Kling <awesomekling@gmail.com> | 2020-01-17 22:02:10 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2020-01-17 22:34:36 +0100 |
commit | 59b584d983a19710edaa2532b0a15c6b1ef328b2 (patch) | |
tree | f4524b95f6e6af5af05c8450f81abcbe10f7b600 | |
parent | 545ec578b327c243cab1c8551c6a293ac51c5a2d (diff) | |
download | serenity-59b584d983a19710edaa2532b0a15c6b1ef328b2.zip |
Kernel: Tidy up the lowest part of the address space
After MemoryManager initialization, we now only leave the lowest 1MB
of memory identity-mapped. The very first (null) page is not present.
All other pages are RW but not X. Supervisor only.
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 43 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.h | 3 |
2 files changed, 38 insertions, 8 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 2fe6ee363c..0400eef2a0 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -45,10 +45,6 @@ void MemoryManager::initialize_paging() dbgprintf("MM: Kernel page directory @ %p\n", kernel_page_directory().cr3()); #endif - // Disable execution from 0MB through 2MB (BIOS data, legacy things, ...) - if (g_cpu_supports_nx) - quickmap_pd(kernel_page_directory(), 0)[0].set_execute_disabled(true); - #if 0 // Disable writing to the kernel text and rodata segments. extern u32 start_of_kernel_text; @@ -138,11 +134,41 @@ void MemoryManager::initialize_paging() "movl %%eax, %%cr0\n" :: : "%eax", "memory"); + setup_low_1mb(); + #ifdef MM_DEBUG dbgprintf("MM: Paging initialized.\n"); #endif } +void MemoryManager::setup_low_1mb() +{ + m_low_page_table = allocate_supervisor_physical_page(); + + auto* pd_zero = quickmap_pd(kernel_page_directory(), 0); + pd_zero[1].set_present(false); + pd_zero[2].set_present(false); + pd_zero[3].set_present(false); + + auto& pde_zero = pd_zero[0]; + pde_zero.set_page_table_base(m_low_page_table->paddr().get()); + pde_zero.set_present(true); + pde_zero.set_huge(false); + pde_zero.set_writable(true); + pde_zero.set_user_allowed(false); + if (g_cpu_supports_nx) + pde_zero.set_execute_disabled(true); + + for (u32 offset = 0; offset < (2 * MB); offset += PAGE_SIZE) { + auto& page_table_page = m_low_page_table; + auto& pte = quickmap_pt(page_table_page->paddr())[offset / PAGE_SIZE]; + pte.set_physical_page_base(offset); + pte.set_user_allowed(false); + pte.set_present(offset != 0); + pte.set_writable(offset < (1 * MB)); + } +} + void MemoryManager::parse_memory_map() { RefPtr<PhysicalRegion> region; @@ -218,7 +244,6 @@ void MemoryManager::parse_memory_map() for (auto& region : m_user_physical_regions) m_user_physical_pages += region.finalize_capacity(); - } PageTableEntry& MemoryManager::ensure_pte(PageDirectory& page_directory, VirtualAddress vaddr) @@ -591,7 +616,9 @@ PageDirectoryEntry* MemoryManager::quickmap_pd(PageDirectory& directory, size_t auto& pte = boot_pd3_pde1023_pt[4]; auto pd_paddr = directory.m_directory_pages[pdpt_index]->paddr(); if (pte.physical_page_base() != pd_paddr.as_ptr()) { - //dbgprintf("quickmap_pd: Mapping P%p at 0xffe04000 in pte @ %p\n", directory.m_directory_pages[pdpt_index]->paddr().as_ptr(), &pte); +#ifdef MM_DEBUG + dbgprintf("quickmap_pd: Mapping P%p at 0xffe04000 in pte @ %p\n", directory.m_directory_pages[pdpt_index]->paddr().as_ptr(), &pte); +#endif pte.set_physical_page_base(pd_paddr.get()); pte.set_present(true); pte.set_writable(true); @@ -605,7 +632,9 @@ PageTableEntry* MemoryManager::quickmap_pt(PhysicalAddress pt_paddr) { auto& pte = boot_pd3_pde1023_pt[8]; if (pte.physical_page_base() != pt_paddr.as_ptr()) { - //dbgprintf("quickmap_pt: Mapping P%p at 0xffe08000 in pte @ %p\n", pt_paddr.as_ptr(), &pte); +#ifdef MM_DEBUG + dbgprintf("quickmap_pt: Mapping P%p at 0xffe08000 in pte @ %p\n", pt_paddr.as_ptr(), &pte); +#endif pte.set_physical_page_base(pt_paddr.get()); pte.set_present(true); pte.set_writable(true); diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index 002bc6aebb..363867502d 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -122,6 +122,7 @@ private: void detect_cpu_features(); void initialize_paging(); + void setup_low_1mb(); void parse_memory_map(); void flush_entire_tlb(); void flush_tlb(VirtualAddress); @@ -147,7 +148,7 @@ private: PageTableEntry& ensure_pte(PageDirectory&, VirtualAddress); RefPtr<PageDirectory> m_kernel_page_directory; - PageTableEntry* m_low_page_tables[4] { nullptr }; + RefPtr<PhysicalPage> m_low_page_table; VirtualAddress m_quickmap_addr; |