diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2023-04-04 21:06:14 +0300 |
---|---|---|
committer | Idan Horowitz <idan.horowitz@gmail.com> | 2023-04-06 20:30:03 +0300 |
commit | 003989e1b07d801f6b6e18d32c803db746a32c73 (patch) | |
tree | fe8c581c58658810becf4b7c286dc76cd3ac0ba0 | |
parent | 65641187ffb15e3512fcf9c260c02287f83b5d09 (diff) | |
download | serenity-003989e1b07d801f6b6e18d32c803db746a32c73.zip |
Kernel: Store a pointer to the owner process in PageDirectory
This replaces the previous owning address space pointer. This commit
should not change any of the existing functionality, but it lays down
the groundwork needed to let us properly access the region table under
the address space spinlock during page fault handling.
-rw-r--r-- | Kernel/Arch/aarch64/PageDirectory.cpp | 4 | ||||
-rw-r--r-- | Kernel/Arch/aarch64/PageDirectory.h | 9 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/PageDirectory.cpp | 4 | ||||
-rw-r--r-- | Kernel/Arch/x86_64/PageDirectory.h | 9 | ||||
-rw-r--r-- | Kernel/Memory/AddressSpace.cpp | 8 | ||||
-rw-r--r-- | Kernel/Memory/AddressSpace.h | 2 | ||||
-rw-r--r-- | Kernel/Memory/MemoryManager.cpp | 7 | ||||
-rw-r--r-- | Kernel/Process.cpp | 14 | ||||
-rw-r--r-- | Kernel/Syscalls/execve.cpp | 2 |
9 files changed, 30 insertions, 29 deletions
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> PageDirectory::must_create_ker return adopt_lock_ref_if_nonnull(new (nothrow) PageDirectory).release_nonnull(); } -ErrorOr<NonnullLockRefPtr<PageDirectory>> PageDirectory::try_create_for_userspace() +ErrorOr<NonnullLockRefPtr<PageDirectory>> 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<PageDirectory> { friend class MemoryManager; public: - static ErrorOr<NonnullLockRefPtr<PageDirectory>> try_create_for_userspace(); + static ErrorOr<NonnullLockRefPtr<PageDirectory>> try_create_for_userspace(Process&); static NonnullLockRefPtr<PageDirectory> must_create_kernel_page_directory(); static LockRefPtr<PageDirectory> 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>, AddressSpace& space) { m_space = &space; } + Process* process() { return m_process; } RecursiveSpinlock<LockRank::None>& 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<PhysicalPage> m_root_table; RefPtr<PhysicalPage> m_directory_table; RefPtr<PhysicalPage> 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> PageDirectory::must_create_ker return adopt_lock_ref_if_nonnull(new (nothrow) PageDirectory).release_nonnull(); } -ErrorOr<NonnullLockRefPtr<PageDirectory>> PageDirectory::try_create_for_userspace() +ErrorOr<NonnullLockRefPtr<PageDirectory>> 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<PageDirectory> { friend class MemoryManager; public: - static ErrorOr<NonnullLockRefPtr<PageDirectory>> try_create_for_userspace(); + static ErrorOr<NonnullLockRefPtr<PageDirectory>> try_create_for_userspace(Process& process); static NonnullLockRefPtr<PageDirectory> must_create_kernel_page_directory(); static LockRefPtr<PageDirectory> 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>, AddressSpace& space) { m_space = &space; } + Process* process() { return m_process; } RecursiveSpinlock<LockRank::None>& 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<PhysicalPage> m_pml4t; RefPtr<PhysicalPage> m_directory_table; RefPtr<PhysicalPage> 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<NonnullOwnPtr<AddressSpace>> AddressSpace::try_create(AddressSpace const* parent) +ErrorOr<NonnullOwnPtr<AddressSpace>> 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<NonnullOwnPtr<AddressSpace>> 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<PageDirectory> 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<NonnullOwnPtr<AddressSpace>> try_create(AddressSpace const* parent); + static ErrorOr<NonnullOwnPtr<AddressSpace>> 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::ProcessAndFirstThread> Process::create(NonnullOwnPtr<KString> name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr<Custody> current_directory, RefPtr<Custody> executable, RefPtr<TTY> tty, Process* fork_parent) { + 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<Memory::AddressSpace> new_address_space; if (fork_parent) { TRY(fork_parent->address_space().with([&](auto& parent_address_space) -> ErrorOr<void> { - new_address_space = TRY(Memory::AddressSpace::try_create(parent_address_space.ptr())); + new_address_space = TRY(Memory::AddressSpace::try_create(*process, parent_address_space.ptr())); return {}; })); } else { - new_address_space = TRY(Memory::AddressSpace::try_create(nullptr)); + new_address_space = TRY(Memory::AddressSpace::try_create(*process, 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)))); 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<void> Process::do_exec(NonnullRefPtr<OpenFileDescription> 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<Memory::AddressSpace> old_space; auto& new_space = m_space.with([&](auto& space) -> Memory::AddressSpace& { old_space = move(space); |