summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2023-04-04 21:06:14 +0300
committerIdan Horowitz <idan.horowitz@gmail.com>2023-04-06 20:30:03 +0300
commit003989e1b07d801f6b6e18d32c803db746a32c73 (patch)
treefe8c581c58658810becf4b7c286dc76cd3ac0ba0
parent65641187ffb15e3512fcf9c260c02287f83b5d09 (diff)
downloadserenity-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.cpp4
-rw-r--r--Kernel/Arch/aarch64/PageDirectory.h9
-rw-r--r--Kernel/Arch/x86_64/PageDirectory.cpp4
-rw-r--r--Kernel/Arch/x86_64/PageDirectory.h9
-rw-r--r--Kernel/Memory/AddressSpace.cpp8
-rw-r--r--Kernel/Memory/AddressSpace.h2
-rw-r--r--Kernel/Memory/MemoryManager.cpp7
-rw-r--r--Kernel/Process.cpp14
-rw-r--r--Kernel/Syscalls/execve.cpp2
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);