From bcc6ddfb6bd2417ccd8358f64356c1f27026ddee Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 20 May 2019 04:46:29 +0200 Subject: [PATCH] Kernel: Let PageDirectory own the associated RangeAllocator. Since we transition to a new PageDirectory on exec(), we need a matching RangeAllocator to go with the new directory. Instead of juggling this in Process and MemoryManager, simply attach the RangeAllocator to the PageDirectory instead. Fixes #61. --- Kernel/Process.cpp | 14 +++++--------- Kernel/Process.h | 1 - Kernel/VM/MemoryManager.cpp | 3 +-- Kernel/VM/MemoryManager.h | 3 --- Kernel/VM/PageDirectory.cpp | 5 +++++ Kernel/VM/PageDirectory.h | 6 +++++- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 9866a5d087..cae1d20648 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -75,8 +75,8 @@ Range Process::allocate_range(LinearAddress laddr, size_t size) laddr.mask(PAGE_MASK); size = PAGE_ROUND_UP(size); if (laddr.is_null()) - return m_range_allocator.allocate_anywhere(size); - return m_range_allocator.allocate_specific(laddr, size); + return page_directory().range_allocator().allocate_anywhere(size); + return page_directory().range_allocator().allocate_specific(laddr, size); } Region* Process::allocate_region(LinearAddress laddr, size_t size, String&& name, bool is_readable, bool is_writable, bool commit) @@ -117,7 +117,7 @@ bool Process::deallocate_region(Region& region) InterruptDisabler disabler; for (int i = 0; i < m_regions.size(); ++i) { if (m_regions[i] == ®ion) { - m_range_allocator.deallocate({ region.laddr(), region.size() }); + page_directory().range_allocator().deallocate({ region.laddr(), region.size() }); MM.unmap_region(region); m_regions.remove(i); return true; @@ -313,7 +313,7 @@ int Process::do_exec(String path, Vector arguments, Vector envir dword entry_eip = 0; // FIXME: Is there a race here? auto old_page_directory = move(m_page_directory); - m_page_directory = PageDirectory::create(); + m_page_directory = PageDirectory::create_for_userspace(); #ifdef MM_DEBUG dbgprintf("Process %u exec: PD=%x created\n", pid(), m_page_directory.ptr()); #endif @@ -542,9 +542,6 @@ Process* Process::create_kernel_process(String&& name, void (*e)()) return process; } -static const dword userspace_range_base = 0x01000000; -static const dword kernelspace_range_base = 0xc0000000; - Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring, RetainPtr&& cwd, RetainPtr&& executable, TTY* tty, Process* fork_parent) : m_name(move(name)) , m_pid(next_pid++) // FIXME: RACE: This variable looks racy! @@ -557,11 +554,10 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring , m_executable(move(executable)) , m_tty(tty) , m_ppid(ppid) - , m_range_allocator(LinearAddress(userspace_range_base), kernelspace_range_base - userspace_range_base) { dbgprintf("Process: New process PID=%u with name=%s\n", m_pid, m_name.characters()); - m_page_directory = PageDirectory::create(); + m_page_directory = PageDirectory::create_for_userspace(); #ifdef MM_DEBUG dbgprintf("Process %u ctor: PD=%x created\n", pid(), m_page_directory.ptr()); #endif diff --git a/Kernel/Process.h b/Kernel/Process.h index 7f2f1b5a91..f0f6fb246f 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -331,7 +331,6 @@ private: RetainPtr m_tracer; OwnPtr m_elf_loader; - RangeAllocator m_range_allocator; Lock m_big_lock { "Process" }; }; diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index b26cca4c09..1f3c328dd7 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -20,7 +20,6 @@ MemoryManager& MM } MemoryManager::MemoryManager() - : m_range_allocator(LinearAddress(0xc0000000), 0x3f000000) { // FIXME: This is not the best way to do memory map detection. // Rewrite to use BIOS int 15,e820 once we have VM86 support. @@ -402,7 +401,7 @@ RetainPtr MemoryManager::allocate_kernel_region(size_t size, String&& na InterruptDisabler disabler; ASSERT(!(size % PAGE_SIZE)); - auto range = m_range_allocator.allocate_anywhere(size); + auto range = kernel_page_directory().range_allocator().allocate_anywhere(size); ASSERT(range.is_valid()); auto region = adopt(*new Region(range, move(name), true, true, false)); MM.map_region_at_address(*m_kernel_page_directory, *region, range.base(), false); diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index dde0bc2195..3615826fb3 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -217,8 +216,6 @@ private: HashTable m_user_regions; HashTable m_kernel_regions; - RangeAllocator m_range_allocator; - size_t m_ram_size { 0 }; bool m_quickmap_in_use { false }; }; diff --git a/Kernel/VM/PageDirectory.cpp b/Kernel/VM/PageDirectory.cpp index d5c10c189a..c3f5070ce3 100644 --- a/Kernel/VM/PageDirectory.cpp +++ b/Kernel/VM/PageDirectory.cpp @@ -3,12 +3,17 @@ #include #include +static const dword userspace_range_base = 0x01000000; +static const dword kernelspace_range_base = 0xc0000000; + PageDirectory::PageDirectory(PhysicalAddress paddr) + : m_range_allocator(LinearAddress(0xc0000000), 0x3f000000) { m_directory_page = PhysicalPage::create_eternal(paddr, true); } PageDirectory::PageDirectory() + : m_range_allocator(LinearAddress(userspace_range_base), kernelspace_range_base - userspace_range_base) { MM.populate_page_directory(*this); } diff --git a/Kernel/VM/PageDirectory.h b/Kernel/VM/PageDirectory.h index ba655178b2..2937eab520 100644 --- a/Kernel/VM/PageDirectory.h +++ b/Kernel/VM/PageDirectory.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -8,7 +9,7 @@ class PageDirectory : public Retainable { friend class MemoryManager; public: - static Retained create() { return adopt(*new PageDirectory); } + static Retained create_for_userspace() { return adopt(*new PageDirectory); } static Retained create_at_fixed_address(PhysicalAddress paddr) { return adopt(*new PageDirectory(paddr)); } ~PageDirectory(); @@ -17,10 +18,13 @@ public: void flush(LinearAddress); + RangeAllocator& range_allocator() { return m_range_allocator; } + private: PageDirectory(); explicit PageDirectory(PhysicalAddress); + RangeAllocator m_range_allocator; RetainPtr m_directory_page; HashMap> m_physical_pages; };