diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index de8c9847..ee7b5320 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -12,7 +12,7 @@ set(SOURCES src/memory/MemoryManager.cpp src/memory/Heap.cpp src/memory/KernelVM.cpp - src/memory/UserVM.cpp + src/memory/AddressSpace.cpp src/memory/MemoryMap.cpp src/boot/Init.cpp src/arch/Serial.cpp diff --git a/kernel/src/memory/UserVM.cpp b/kernel/src/memory/AddressSpace.cpp similarity index 85% rename from kernel/src/memory/UserVM.cpp rename to kernel/src/memory/AddressSpace.cpp index bfb13450..d750c766 100644 --- a/kernel/src/memory/UserVM.cpp +++ b/kernel/src/memory/AddressSpace.cpp @@ -1,4 +1,4 @@ -#include "memory/UserVM.h" +#include "memory/AddressSpace.h" #include "Log.h" #include "arch/MMU.h" #include "memory/Heap.h" @@ -8,9 +8,9 @@ static constexpr u64 VM_START = ARCH_PAGE_SIZE; static constexpr u64 VM_END = 0x0000800000000000; -Result> UserVM::try_create() +Result> AddressSpace::try_create() { - OwnedPtr ptr = TRY(make_owned()); + OwnedPtr ptr = TRY(make_owned()); TRY(ptr->create_null_region()); TRY(ptr->create_default_region()); @@ -20,7 +20,7 @@ Result> UserVM::try_create() return move(ptr); } -Result UserVM::create_null_region() +Result AddressSpace::create_null_region() { // Create a small region at the start of the address space to prevent anyone from mapping page 0. auto* region = TRY(make()); @@ -33,7 +33,7 @@ Result UserVM::create_null_region() return {}; } -Result UserVM::create_default_region() +Result AddressSpace::create_default_region() { // Create a free region covering the rest of the address space. auto* region = TRY(make()); @@ -45,9 +45,9 @@ Result UserVM::create_default_region() return {}; } -Result> UserVM::clone() +Result> AddressSpace::clone() { - OwnedPtr ptr = TRY(make_owned()); + OwnedPtr ptr = TRY(make_owned()); for (const auto* region : m_regions) { @@ -61,11 +61,11 @@ Result> UserVM::clone() return move(ptr); } -UserVM::UserVM() +AddressSpace::AddressSpace() { } -UserVM& UserVM::operator=(UserVM&& other) +AddressSpace& AddressSpace::operator=(AddressSpace&& other) { if (&other == this) return *this; @@ -78,7 +78,7 @@ UserVM& UserVM::operator=(UserVM&& other) return *this; } -Result UserVM::alloc_region(usize count, bool persistent) +Result AddressSpace::alloc_region(usize count, bool persistent) { for (auto* region = m_regions.expect_last(); region; region = m_regions.previous(region).value_or(nullptr)) { @@ -108,7 +108,7 @@ Result UserVM::alloc_region(usize count, bool persistent) return err(ENOMEM); } -Result UserVM::set_region(u64 address, usize count, bool used, bool persistent) +Result AddressSpace::set_region(u64 address, usize count, bool used, bool persistent) { if (address >= VM_END) return err(EINVAL); @@ -171,7 +171,7 @@ Result UserVM::set_region(u64 address, usize count, bool used, bool persis return true; } -void UserVM::merge_contiguous_regions(VMRegion* a, VMRegion* b) +void AddressSpace::merge_contiguous_regions(VMRegion* a, VMRegion* b) { a->end = b->end; a->count += b->count; @@ -179,7 +179,7 @@ void UserVM::merge_contiguous_regions(VMRegion* a, VMRegion* b) delete b; } -void UserVM::try_merge_region_with_neighbors(VMRegion* region) +void AddressSpace::try_merge_region_with_neighbors(VMRegion* region) { auto prev = m_regions.previous(region); if (prev.has_value() && (*prev)->used == region->used && (*prev)->persistent == region->persistent) @@ -195,7 +195,7 @@ void UserVM::try_merge_region_with_neighbors(VMRegion* region) } } -Result UserVM::split_region(VMRegion* parent, u64 boundary) +Result AddressSpace::split_region(VMRegion* parent, u64 boundary) { auto* region = TRY(make()); @@ -212,7 +212,7 @@ Result UserVM::split_region(VMRegion* parent, u64 boundary) return region; } -UserVM::~UserVM() +AddressSpace::~AddressSpace() { m_regions.consume([](VMRegion* region) { delete region; }); MMU::delete_userspace_page_directory(m_directory); diff --git a/kernel/src/memory/UserVM.h b/kernel/src/memory/AddressSpace.h similarity index 84% rename from kernel/src/memory/UserVM.h rename to kernel/src/memory/AddressSpace.h index 08550c89..e096a41e 100644 --- a/kernel/src/memory/UserVM.h +++ b/kernel/src/memory/AddressSpace.h @@ -14,13 +14,13 @@ class VMRegion : LinkedListNode bool persistent { false }; }; -class UserVM +class AddressSpace { public: - UserVM(); - ~UserVM(); + AddressSpace(); + ~AddressSpace(); - UserVM& operator=(UserVM&& other); + AddressSpace& operator=(AddressSpace&& other); Result alloc_region(usize count, bool persistent = false); @@ -34,9 +34,9 @@ class UserVM return set_region(address, count, false, false); } - static Result> try_create(); + static Result> try_create(); - Result> clone(); + Result> clone(); PageDirectory* page_directory() const { @@ -50,6 +50,7 @@ class UserVM void try_merge_region_with_neighbors(VMRegion* region); void merge_contiguous_regions(VMRegion* a, VMRegion* b); Result split_region(VMRegion* parent, u64 boundary); + LinkedList m_regions; PageDirectory* m_directory; }; diff --git a/kernel/src/sys/mmap.cpp b/kernel/src/sys/mmap.cpp index f6516d20..8f02b278 100644 --- a/kernel/src/sys/mmap.cpp +++ b/kernel/src/sys/mmap.cpp @@ -37,12 +37,12 @@ Result sys_mmap(Registers*, SyscallArgs args) Thread* current = Scheduler::current(); u64 address; - if (!addr) address = TRY(current->vm_allocator->alloc_region(get_blocks_from_size(len, ARCH_PAGE_SIZE))); + if (!addr) address = TRY(current->address_space->alloc_region(get_blocks_from_size(len, ARCH_PAGE_SIZE))); else { // FIXME: We should be more flexible if MAP_FIXED was not specified. address = align_down((u64)addr); - if (!TRY(current->vm_allocator->test_and_alloc_region(address, get_blocks_from_size(len, ARCH_PAGE_SIZE)))) + if (!TRY(current->address_space->test_and_alloc_region(address, get_blocks_from_size(len, ARCH_PAGE_SIZE)))) return err(ENOMEM); } @@ -69,7 +69,7 @@ Result sys_munmap(Registers*, SyscallArgs args) Thread* current = Scheduler::current(); - bool ok = TRY(current->vm_allocator->free_region(address, get_blocks_from_size(size, ARCH_PAGE_SIZE))); + bool ok = TRY(current->address_space->free_region(address, get_blocks_from_size(size, ARCH_PAGE_SIZE))); // POSIX says munmap should silently do nothing if the memory was not already mapped. if (!ok) return 0; diff --git a/kernel/src/thread/ELF.cpp b/kernel/src/thread/ELF.cpp index 4d4fdb65..f7e9e1f8 100644 --- a/kernel/src/thread/ELF.cpp +++ b/kernel/src/thread/ELF.cpp @@ -25,7 +25,7 @@ static bool can_write_segment(u32 flags) namespace ELFLoader { - Result load(SharedPtr inode, UserVM* vm) + Result load(SharedPtr inode, AddressSpace* space) { Elf64_Ehdr elf_header; usize nread = TRY(inode->read((u8*)&elf_header, 0, sizeof elf_header)); @@ -102,7 +102,7 @@ namespace ELFLoader if (can_write_segment(program_header.p_flags)) flags |= MMU::ReadWrite; if (can_execute_segment(program_header.p_flags)) flags &= ~MMU::NoExecute; - if (!TRY(vm->test_and_alloc_region( + if (!TRY(space->test_and_alloc_region( base_vaddr, get_blocks_from_size(program_header.p_memsz + vaddr_diff, ARCH_PAGE_SIZE), true))) return err(ENOMEM); diff --git a/kernel/src/thread/ELF.h b/kernel/src/thread/ELF.h index 21103e43..c4045b5f 100644 --- a/kernel/src/thread/ELF.h +++ b/kernel/src/thread/ELF.h @@ -1,6 +1,6 @@ #pragma once #include "fs/VFS.h" -#include "memory/UserVM.h" +#include "memory/AddressSpace.h" #include #define ELFMAG "\177ELF" @@ -54,5 +54,5 @@ struct ELFData namespace ELFLoader { - Result load(SharedPtr inode, UserVM* vm); + Result load(SharedPtr inode, AddressSpace* space); }; diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index 309d2d6b..6e979095 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -2,7 +2,7 @@ #include "arch/MMU.h" #include "fs/VFS.h" -#include "memory/UserVM.h" +#include "memory/AddressSpace.h" #include #include #include @@ -70,7 +70,7 @@ struct Thread : public LinkedListNode Stack stack; Stack kernel_stack; - OwnedPtr vm_allocator; + OwnedPtr address_space; Option fd_table[FD_MAX] = {}; Result allocate_fd(int min); @@ -99,7 +99,7 @@ struct Thread : public LinkedListNode PageDirectory* self_directory() const { - return vm_allocator->page_directory(); + return address_space->page_directory(); } PageDirectory* active_directory { nullptr }; diff --git a/kernel/src/thread/ThreadImage.cpp b/kernel/src/thread/ThreadImage.cpp index 744145b2..2e9ca57c 100644 --- a/kernel/src/thread/ThreadImage.cpp +++ b/kernel/src/thread/ThreadImage.cpp @@ -7,11 +7,11 @@ static constexpr usize DEFAULT_USER_STACK_PAGES = 6; static constexpr usize DEFAULT_USER_STACK_SIZE = DEFAULT_USER_STACK_PAGES * ARCH_PAGE_SIZE; -static Result create_stacks(Stack& user_stack, Stack& kernel_stack, UserVM* vm) +static Result create_stacks(Stack& user_stack, Stack& kernel_stack, AddressSpace* space) { const u64 THREAD_STACK_BASE = 0x10000; - if (!TRY(vm->test_and_alloc_region(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES, true))) return err(ENOMEM); + if (!TRY(space->test_and_alloc_region(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES, true))) return err(ENOMEM); TRY(MemoryManager::alloc_at_zeroed(THREAD_STACK_BASE, DEFAULT_USER_STACK_PAGES, MMU::ReadWrite | MMU::NoExecute | MMU::User)); @@ -32,26 +32,26 @@ Result> ThreadImage::try_load_from_elf(SharedPtr()); - auto vm_allocator = TRY(UserVM::try_create()); + auto address_space = TRY(AddressSpace::try_create()); auto old_directory = MMU::get_page_directory(); - MMU::switch_page_directory(vm_allocator->page_directory()); + MMU::switch_page_directory(address_space->page_directory()); auto guard = make_scope_guard([=] { MMU::switch_page_directory(old_directory); }); - const ELFData data = TRY(ELFLoader::load(inode, vm_allocator.ptr())); + const ELFData data = TRY(ELFLoader::load(inode, address_space.ptr())); Stack user_stack; Stack kernel_stack; - TRY(create_stacks(user_stack, kernel_stack, vm_allocator.ptr())); + TRY(create_stacks(user_stack, kernel_stack, address_space.ptr())); guard.deactivate(); image->m_kernel_stack = kernel_stack; image->m_user_stack = user_stack; image->m_loaded_image_data = data; - image->m_vm_allocator = move(vm_allocator); + image->m_address_space = move(address_space); image->m_sp = user_stack.top(); return image; @@ -61,7 +61,7 @@ Result> ThreadImage::clone_from_thread(Thread* parent) { auto image = TRY(make_owned()); - auto vm_allocator = TRY(parent->vm_allocator->clone()); + auto address_space = TRY(parent->address_space->clone()); const ELFData data = { .entry = parent->ip() }; @@ -71,7 +71,7 @@ Result> ThreadImage::clone_from_thread(Thread* parent) image->m_kernel_stack = kernel_stack; image->m_user_stack = parent->stack; image->m_loaded_image_data = data; - image->m_vm_allocator = move(vm_allocator); + image->m_address_space = move(address_space); image->m_sp = parent->sp(); return image; @@ -115,7 +115,7 @@ void ThreadImage::apply(Thread* thread) thread->stack = m_user_stack; thread->set_sp(align_down<16>(m_sp)); - thread->active_directory = m_vm_allocator->page_directory(); + thread->active_directory = m_address_space->page_directory(); - thread->vm_allocator = move(m_vm_allocator); + thread->address_space = move(m_address_space); } diff --git a/kernel/src/thread/ThreadImage.h b/kernel/src/thread/ThreadImage.h index 498fbe40..f6f7fbad 100644 --- a/kernel/src/thread/ThreadImage.h +++ b/kernel/src/thread/ThreadImage.h @@ -4,7 +4,7 @@ #include "arch/CPU.h" #include "arch/MMU.h" #include "fs/VFS.h" -#include "memory/UserVM.h" +#include "memory/AddressSpace.h" #include "thread/Thread.h" #include #include @@ -28,7 +28,7 @@ class ThreadImage void apply(Thread* thread); private: - OwnedPtr m_vm_allocator; + OwnedPtr m_address_space; Stack m_user_stack; Stack m_kernel_stack; ELFData m_loaded_image_data;