diff --git a/Kernel/Arch/aarch64/PageDirectory.cpp b/Kernel/Arch/aarch64/PageDirectory.cpp index 1067061282..69c25d1eaf 100644 --- a/Kernel/Arch/aarch64/PageDirectory.cpp +++ b/Kernel/Arch/aarch64/PageDirectory.cpp @@ -62,10 +62,12 @@ UNMAP_AFTER_INIT NonnullLockRefPtr PageDirectory::must_create_ker return adopt_lock_ref_if_nonnull(new (nothrow) PageDirectory).release_nonnull(); } -ErrorOr> PageDirectory::try_create_for_userspace() +ErrorOr> PageDirectory::try_create_for_userspace(Process& process) { auto directory = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) PageDirectory)); + directory->m_process = &process; + directory->m_root_table = TRY(MM.allocate_physical_page()); directory->m_directory_table = TRY(MM.allocate_physical_page()); diff --git a/Kernel/Arch/aarch64/PageDirectory.h b/Kernel/Arch/aarch64/PageDirectory.h index 15f02d760d..079f444ddc 100644 --- a/Kernel/Arch/aarch64/PageDirectory.h +++ b/Kernel/Arch/aarch64/PageDirectory.h @@ -179,7 +179,7 @@ class PageDirectory final : public AtomicRefCounted { friend class MemoryManager; public: - static ErrorOr> try_create_for_userspace(); + static ErrorOr> try_create_for_userspace(Process&); static NonnullLockRefPtr must_create_kernel_page_directory(); static LockRefPtr find_current(); @@ -197,10 +197,7 @@ public: return m_root_table; } - AddressSpace* address_space() { return m_space; } - AddressSpace const* address_space() const { return m_space; } - - void set_space(Badge, AddressSpace& space) { m_space = &space; } + Process* process() { return m_process; } RecursiveSpinlock& get_lock() { return m_lock; } @@ -212,7 +209,7 @@ private: static void register_page_directory(PageDirectory* directory); static void deregister_page_directory(PageDirectory* directory); - AddressSpace* m_space { nullptr }; + Process* m_process { nullptr }; RefPtr m_root_table; RefPtr m_directory_table; RefPtr m_directory_pages[512]; diff --git a/Kernel/Arch/x86_64/PageDirectory.cpp b/Kernel/Arch/x86_64/PageDirectory.cpp index f7cc16d992..e1459dee62 100644 --- a/Kernel/Arch/x86_64/PageDirectory.cpp +++ b/Kernel/Arch/x86_64/PageDirectory.cpp @@ -61,10 +61,12 @@ UNMAP_AFTER_INIT NonnullLockRefPtr PageDirectory::must_create_ker return adopt_lock_ref_if_nonnull(new (nothrow) PageDirectory).release_nonnull(); } -ErrorOr> PageDirectory::try_create_for_userspace() +ErrorOr> PageDirectory::try_create_for_userspace(Process& process) { auto directory = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) PageDirectory)); + directory->m_process = &process; + directory->m_pml4t = TRY(MM.allocate_physical_page()); directory->m_directory_table = TRY(MM.allocate_physical_page()); diff --git a/Kernel/Arch/x86_64/PageDirectory.h b/Kernel/Arch/x86_64/PageDirectory.h index 2035846d95..f45b88e249 100644 --- a/Kernel/Arch/x86_64/PageDirectory.h +++ b/Kernel/Arch/x86_64/PageDirectory.h @@ -162,7 +162,7 @@ class PageDirectory final : public AtomicRefCounted { friend class MemoryManager; public: - static ErrorOr> try_create_for_userspace(); + static ErrorOr> try_create_for_userspace(Process& process); static NonnullLockRefPtr must_create_kernel_page_directory(); static LockRefPtr find_current(); @@ -180,10 +180,7 @@ public: return m_pml4t; } - AddressSpace* address_space() { return m_space; } - AddressSpace const* address_space() const { return m_space; } - - void set_space(Badge, AddressSpace& space) { m_space = &space; } + Process* process() { return m_process; } RecursiveSpinlock& get_lock() { return m_lock; } @@ -195,7 +192,7 @@ private: static void register_page_directory(PageDirectory* directory); static void deregister_page_directory(PageDirectory* directory); - AddressSpace* m_space { nullptr }; + Process* m_process { nullptr }; RefPtr m_pml4t; RefPtr m_directory_table; RefPtr m_directory_pages[512]; diff --git a/Kernel/Memory/AddressSpace.cpp b/Kernel/Memory/AddressSpace.cpp index fd02923461..2c9e42bd30 100644 --- a/Kernel/Memory/AddressSpace.cpp +++ b/Kernel/Memory/AddressSpace.cpp @@ -19,9 +19,9 @@ namespace Kernel::Memory { -ErrorOr> AddressSpace::try_create(AddressSpace const* parent) +ErrorOr> AddressSpace::try_create(Process& process, AddressSpace const* parent) { - auto page_directory = TRY(PageDirectory::try_create_for_userspace()); + auto page_directory = TRY(PageDirectory::try_create_for_userspace(process)); VirtualRange total_range = [&]() -> VirtualRange { if (parent) @@ -33,9 +33,7 @@ ErrorOr> AddressSpace::try_create(AddressSpace const return VirtualRange(VirtualAddress { base }, userspace_range_ceiling - base); }(); - auto space = TRY(adopt_nonnull_own_or_enomem(new (nothrow) AddressSpace(move(page_directory), total_range))); - space->page_directory().set_space({}, *space); - return space; + return adopt_nonnull_own_or_enomem(new (nothrow) AddressSpace(move(page_directory), total_range)); } AddressSpace::AddressSpace(NonnullLockRefPtr page_directory, VirtualRange total_range) diff --git a/Kernel/Memory/AddressSpace.h b/Kernel/Memory/AddressSpace.h index 6f14aac8b9..5e0597025a 100644 --- a/Kernel/Memory/AddressSpace.h +++ b/Kernel/Memory/AddressSpace.h @@ -21,7 +21,7 @@ namespace Kernel::Memory { class AddressSpace { public: - static ErrorOr> try_create(AddressSpace const* parent); + static ErrorOr> try_create(Process&, AddressSpace const* parent); ~AddressSpace(); PageDirectory& page_directory() { return *m_page_directory; } diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 6d1c59908c..ff041a2356 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -722,8 +722,11 @@ Region* MemoryManager::find_region_from_vaddr(VirtualAddress vaddr) auto page_directory = PageDirectory::find_current(); if (!page_directory) return nullptr; - VERIFY(page_directory->address_space()); - return find_user_region_from_vaddr(*page_directory->address_space(), vaddr); + auto* process = page_directory->process(); + VERIFY(process); + return process->address_space().with([&](auto& space) { + return find_user_region_from_vaddr(*space, vaddr); + }); } PageFaultResponse MemoryManager::handle_page_fault(PageFault const& fault) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 1c38430aeb..a6f28c0a3a 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -286,20 +286,22 @@ void Process::unprotect_data() ErrorOr Process::create(NonnullOwnPtr name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, Process* fork_parent) { - OwnPtr new_address_space; - if (fork_parent) { - TRY(fork_parent->address_space().with([&](auto& parent_address_space) -> ErrorOr { - new_address_space = TRY(Memory::AddressSpace::try_create(parent_address_space.ptr())); - return {}; - })); - } else { - new_address_space = TRY(Memory::AddressSpace::try_create(nullptr)); - } auto unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) }; auto exec_unveil_tree = UnveilNode { TRY(KString::try_create("/"sv)), UnveilMetadata(TRY(KString::try_create("/"sv))) }; auto credentials = TRY(Credentials::create(uid, gid, uid, gid, uid, gid, {}, fork_parent ? fork_parent->sid() : 0, fork_parent ? fork_parent->pgid() : 0)); auto process = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) Process(move(name), move(credentials), ppid, is_kernel_process, move(current_directory), move(executable), tty, move(unveil_tree), move(exec_unveil_tree)))); + + OwnPtr new_address_space; + if (fork_parent) { + TRY(fork_parent->address_space().with([&](auto& parent_address_space) -> ErrorOr { + new_address_space = TRY(Memory::AddressSpace::try_create(*process, parent_address_space.ptr())); + return {}; + })); + } else { + new_address_space = TRY(Memory::AddressSpace::try_create(*process, nullptr)); + } + auto first_thread = TRY(process->attach_resources(new_address_space.release_nonnull(), fork_parent)); return ProcessAndFirstThread { move(process), move(first_thread) }; diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 15d0b5dfa0..10a91bfb50 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -488,7 +488,7 @@ ErrorOr Process::do_exec(NonnullRefPtr main_program_d auto new_process_name = TRY(KString::try_create(last_part)); auto new_main_thread_name = TRY(new_process_name->try_clone()); - auto allocated_space = TRY(Memory::AddressSpace::try_create(nullptr)); + auto allocated_space = TRY(Memory::AddressSpace::try_create(*this, nullptr)); OwnPtr old_space; auto& new_space = m_space.with([&](auto& space) -> Memory::AddressSpace& { old_space = move(space);