diff options
Diffstat (limited to 'Kernel/VM')
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 35 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.h | 13 | ||||
-rw-r--r-- | Kernel/VM/Region.cpp | 26 | ||||
-rw-r--r-- | Kernel/VM/Region.h | 20 | ||||
-rw-r--r-- | Kernel/VM/Space.cpp | 6 |
5 files changed, 44 insertions, 56 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 436f8e76cd..7e329ef4a6 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -454,7 +454,7 @@ PageFaultResponse MemoryManager::handle_page_fault(const PageFault& fault) return region->handle_fault(fault, lock); } -OwnPtr<Region> MemoryManager::allocate_contiguous_kernel_region(size_t size, const StringView& name, u8 access, size_t physical_alignment, bool user_accessible, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_contiguous_kernel_region(size_t size, String name, u8 access, size_t physical_alignment, Region::Cacheable cacheable) { ASSERT(!(size % PAGE_SIZE)); ScopedSpinLock lock(s_mm_lock); @@ -462,10 +462,10 @@ OwnPtr<Region> MemoryManager::allocate_contiguous_kernel_region(size_t size, con if (!range.has_value()) return {}; auto vmobject = ContiguousVMObject::create_with_size(size, physical_alignment); - return allocate_kernel_region_with_vmobject(range.value(), vmobject, name, access, user_accessible, cacheable); + return allocate_kernel_region_with_vmobject(range.value(), vmobject, move(name), access, cacheable); } -OwnPtr<Region> MemoryManager::allocate_kernel_region(size_t size, const StringView& name, u8 access, bool user_accessible, AllocationStrategy strategy, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_kernel_region(size_t size, String name, u8 access, AllocationStrategy strategy, Region::Cacheable cacheable) { ASSERT(!(size % PAGE_SIZE)); ScopedSpinLock lock(s_mm_lock); @@ -475,10 +475,10 @@ OwnPtr<Region> MemoryManager::allocate_kernel_region(size_t size, const StringVi auto vmobject = AnonymousVMObject::create_with_size(size, strategy); if (!vmobject) return {}; - return allocate_kernel_region_with_vmobject(range.value(), vmobject.release_nonnull(), name, access, user_accessible, cacheable); + return allocate_kernel_region_with_vmobject(range.value(), vmobject.release_nonnull(), move(name), access, cacheable); } -OwnPtr<Region> MemoryManager::allocate_kernel_region(PhysicalAddress paddr, size_t size, const StringView& name, u8 access, bool user_accessible, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_kernel_region(PhysicalAddress paddr, size_t size, String name, u8 access, Region::Cacheable cacheable) { ASSERT(!(size % PAGE_SIZE)); ScopedSpinLock lock(s_mm_lock); @@ -488,10 +488,10 @@ OwnPtr<Region> MemoryManager::allocate_kernel_region(PhysicalAddress paddr, size auto vmobject = AnonymousVMObject::create_for_physical_range(paddr, size); if (!vmobject) return {}; - return allocate_kernel_region_with_vmobject(range.value(), *vmobject, name, access, user_accessible, cacheable); + return allocate_kernel_region_with_vmobject(range.value(), *vmobject, move(name), access, cacheable); } -OwnPtr<Region> MemoryManager::allocate_kernel_region_identity(PhysicalAddress paddr, size_t size, const StringView& name, u8 access, bool user_accessible, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_kernel_region_identity(PhysicalAddress paddr, size_t size, String name, u8 access, Region::Cacheable cacheable) { ASSERT(!(size % PAGE_SIZE)); ScopedSpinLock lock(s_mm_lock); @@ -501,35 +501,26 @@ OwnPtr<Region> MemoryManager::allocate_kernel_region_identity(PhysicalAddress pa auto vmobject = AnonymousVMObject::create_for_physical_range(paddr, size); if (!vmobject) return {}; - return allocate_kernel_region_with_vmobject(range.value(), *vmobject, name, access, user_accessible, cacheable); + return allocate_kernel_region_with_vmobject(range.value(), *vmobject, move(name), access, cacheable); } -OwnPtr<Region> MemoryManager::allocate_user_accessible_kernel_region(size_t size, const StringView& name, u8 access, bool cacheable) -{ - return allocate_kernel_region(size, name, access, true, AllocationStrategy::Reserve, cacheable); -} - -OwnPtr<Region> MemoryManager::allocate_kernel_region_with_vmobject(const Range& range, VMObject& vmobject, const StringView& name, u8 access, bool user_accessible, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_kernel_region_with_vmobject(const Range& range, VMObject& vmobject, String name, u8 access, Region::Cacheable cacheable) { ScopedSpinLock lock(s_mm_lock); - OwnPtr<Region> region; - if (user_accessible) - region = Region::create_user_accessible(nullptr, range, vmobject, 0, name, access, cacheable, false); - else - region = Region::create_kernel_only(range, vmobject, 0, name, access, cacheable); + auto region = Region::create_kernel_only(range, vmobject, 0, move(name), access, cacheable); if (region) region->map(kernel_page_directory()); return region; } -OwnPtr<Region> MemoryManager::allocate_kernel_region_with_vmobject(VMObject& vmobject, size_t size, const StringView& name, u8 access, bool user_accessible, bool cacheable) +OwnPtr<Region> MemoryManager::allocate_kernel_region_with_vmobject(VMObject& vmobject, size_t size, String name, u8 access, Region::Cacheable cacheable) { ASSERT(!(size % PAGE_SIZE)); ScopedSpinLock lock(s_mm_lock); auto range = kernel_page_directory().range_allocator().allocate_anywhere(size); if (!range.has_value()) return {}; - return allocate_kernel_region_with_vmobject(range.value(), vmobject, name, access, user_accessible, cacheable); + return allocate_kernel_region_with_vmobject(range.value(), vmobject, move(name), access, cacheable); } bool MemoryManager::commit_user_physical_pages(size_t page_count) @@ -843,7 +834,7 @@ bool MemoryManager::validate_user_stack(const Process& process, VirtualAddress v return false; ScopedSpinLock lock(s_mm_lock); auto* region = user_region_from_vaddr(const_cast<Process&>(process).space(), vaddr); - return region && region->is_user_accessible() && region->is_stack(); + return region && region->is_user() && region->is_stack(); } void MemoryManager::register_vmobject(VMObject& vmobject) diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h index 7780ca0e75..53a4cc03a5 100644 --- a/Kernel/VM/MemoryManager.h +++ b/Kernel/VM/MemoryManager.h @@ -145,13 +145,12 @@ public: void deallocate_user_physical_page(const PhysicalPage&); void deallocate_supervisor_physical_page(const PhysicalPage&); - OwnPtr<Region> allocate_contiguous_kernel_region(size_t, const StringView& name, u8 access, size_t physical_alignment = PAGE_SIZE, bool user_accessible = false, bool cacheable = true); - OwnPtr<Region> allocate_kernel_region(size_t, const StringView& name, u8 access, bool user_accessible = false, AllocationStrategy strategy = AllocationStrategy::Reserve, bool cacheable = true); - OwnPtr<Region> allocate_kernel_region(PhysicalAddress, size_t, const StringView& name, u8 access, bool user_accessible = false, bool cacheable = true); - OwnPtr<Region> allocate_kernel_region_identity(PhysicalAddress, size_t, const StringView& name, u8 access, bool user_accessible = false, bool cacheable = true); - OwnPtr<Region> allocate_kernel_region_with_vmobject(VMObject&, size_t, const StringView& name, u8 access, bool user_accessible = false, bool cacheable = true); - OwnPtr<Region> allocate_kernel_region_with_vmobject(const Range&, VMObject&, const StringView& name, u8 access, bool user_accessible = false, bool cacheable = true); - OwnPtr<Region> allocate_user_accessible_kernel_region(size_t, const StringView& name, u8 access, bool cacheable = true); + OwnPtr<Region> allocate_contiguous_kernel_region(size_t, String name, u8 access, size_t physical_alignment = PAGE_SIZE, Region::Cacheable = Region::Cacheable::Yes); + OwnPtr<Region> allocate_kernel_region(size_t, String name, u8 access, AllocationStrategy strategy = AllocationStrategy::Reserve, Region::Cacheable = Region::Cacheable::Yes); + OwnPtr<Region> allocate_kernel_region(PhysicalAddress, size_t, String name, u8 access, Region::Cacheable = Region::Cacheable::Yes); + OwnPtr<Region> allocate_kernel_region_identity(PhysicalAddress, size_t, String name, u8 access, Region::Cacheable = Region::Cacheable::Yes); + OwnPtr<Region> allocate_kernel_region_with_vmobject(VMObject&, size_t, String name, u8 access, Region::Cacheable = Region::Cacheable::Yes); + OwnPtr<Region> allocate_kernel_region_with_vmobject(const Range&, VMObject&, String name, u8 access, Region::Cacheable = Region::Cacheable::Yes); unsigned user_physical_pages() const { return m_user_physical_pages; } unsigned user_physical_pages_used() const { return m_user_physical_pages_used; } diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp index b24101ada1..87032b992f 100644 --- a/Kernel/VM/Region.cpp +++ b/Kernel/VM/Region.cpp @@ -38,16 +38,15 @@ namespace Kernel { -Region::Region(const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const String& name, u8 access, bool cacheable, bool kernel, bool shared) +Region::Region(const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, String name, u8 access, Cacheable cacheable, bool shared) : PurgeablePageRanges(vmobject) , m_range(range) , m_offset_in_vmobject(offset_in_vmobject) , m_vmobject(move(vmobject)) - , m_name(name) + , m_name(move(name)) , m_access(access | ((access & 0x7) << 4)) , m_shared(shared) - , m_cacheable(cacheable) - , m_kernel(kernel) + , m_cacheable(cacheable == Cacheable::Yes) { ASSERT(m_range.base().is_page_aligned()); ASSERT(m_range.size()); @@ -104,7 +103,7 @@ OwnPtr<Region> Region::clone(Process& new_owner) // Create a new region backed by the same VMObject. auto region = Region::create_user_accessible( - &new_owner, m_range, m_vmobject, m_offset_in_vmobject, m_name, m_access, m_cacheable, m_shared); + &new_owner, m_range, m_vmobject, m_offset_in_vmobject, m_name, m_access, m_cacheable ? Cacheable::Yes : Cacheable::No, m_shared); if (m_vmobject->is_anonymous()) region->copy_purgeable_page_ranges(*this); region->set_mmap(m_mmap); @@ -123,7 +122,7 @@ OwnPtr<Region> Region::clone(Process& new_owner) // Set up a COW region. The parent (this) region becomes COW as well! remap(); auto clone_region = Region::create_user_accessible( - &new_owner, m_range, vmobject_clone.release_nonnull(), m_offset_in_vmobject, m_name, m_access, m_cacheable, m_shared); + &new_owner, m_range, vmobject_clone.release_nonnull(), m_offset_in_vmobject, m_name, m_access, m_cacheable ? Cacheable::Yes : Cacheable::No, m_shared); if (m_vmobject->is_anonymous()) clone_region->copy_purgeable_page_ranges(*this); if (m_stack) { @@ -228,20 +227,17 @@ size_t Region::amount_shared() const return bytes; } -NonnullOwnPtr<Region> Region::create_user_accessible(Process* owner, const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable, bool shared) +NonnullOwnPtr<Region> Region::create_user_accessible(Process* owner, const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, String name, u8 access, Cacheable cacheable, bool shared) { - auto region = make<Region>(range, move(vmobject), offset_in_vmobject, name, access, cacheable, false, shared); + auto region = make<Region>(range, move(vmobject), offset_in_vmobject, move(name), access, cacheable, shared); if (owner) region->m_owner = owner->make_weak_ptr(); - region->m_user_accessible = true; return region; } -NonnullOwnPtr<Region> Region::create_kernel_only(const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable) +NonnullOwnPtr<Region> Region::create_kernel_only(const Range& range, NonnullRefPtr<VMObject> vmobject, size_t offset_in_vmobject, String name, u8 access, Cacheable cacheable) { - auto region = make<Region>(range, move(vmobject), offset_in_vmobject, name, access, cacheable, true, false); - region->m_user_accessible = false; - return region; + return make<Region>(range, move(vmobject), offset_in_vmobject, move(name), access, cacheable, false); } bool Region::should_cow(size_t page_index) const @@ -278,7 +274,7 @@ bool Region::map_individual_page_impl(size_t page_index) pte->set_writable(is_writable()); if (Processor::current().has_feature(CPUFeature::NX)) pte->set_execute_disabled(!is_executable()); - pte->set_user_allowed(is_user_accessible()); + pte->set_user_allowed(page_vaddr.get() >= 0x00800000 && is_user_address(page_vaddr)); } return true; } @@ -388,7 +384,7 @@ bool Region::map(PageDirectory& page_directory) ScopedSpinLock page_lock(page_directory.get_lock()); // FIXME: Find a better place for this sanity check(?) - if (is_user_accessible() && !is_shared()) { + if (is_user() && !is_shared()) { ASSERT(!vmobject().is_shared_inode()); } diff --git a/Kernel/VM/Region.h b/Kernel/VM/Region.h index ab04e6b491..0fba189157 100644 --- a/Kernel/VM/Region.h +++ b/Kernel/VM/Region.h @@ -59,8 +59,13 @@ public: HasBeenExecutable = 64, }; - static NonnullOwnPtr<Region> create_user_accessible(Process*, const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable, bool shared); - static NonnullOwnPtr<Region> create_kernel_only(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable = true); + enum class Cacheable { + No = 0, + Yes, + }; + + static NonnullOwnPtr<Region> create_user_accessible(Process*, const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, String name, u8 access, Cacheable, bool shared); + static NonnullOwnPtr<Region> create_kernel_only(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, String name, u8 access, Cacheable = Cacheable::Yes); ~Region(); @@ -79,8 +84,7 @@ public: const String& name() const { return m_name; } unsigned access() const { return m_access; } - void set_name(const String& name) { m_name = name; } - void set_name(String&& name) { m_name = move(name); } + void set_name(String name) { m_name = move(name); } const VMObject& vmobject() const { return *m_vmobject; } VMObject& vmobject() { return *m_vmobject; } @@ -95,8 +99,8 @@ public: bool is_mmap() const { return m_mmap; } void set_mmap(bool mmap) { m_mmap = mmap; } - bool is_user_accessible() const { return m_user_accessible; } - bool is_kernel() const { return m_kernel || vaddr().get() >= 0xc0000000; } + bool is_user() const { return !is_kernel(); } + bool is_kernel() const { return vaddr().get() < 0x00800000 || vaddr().get() >= 0xc0000000; } PageFaultResponse handle_fault(const PageFault&, ScopedSpinLock<RecursiveSpinLock>&); @@ -225,7 +229,7 @@ public: Region* m_prev { nullptr }; // NOTE: These are public so we can make<> them. - Region(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const String&, u8 access, bool cacheable, bool kernel, bool shared); + Region(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, String, u8 access, Cacheable, bool shared); bool remap_vmobject_page_range(size_t page_index, size_t page_count); @@ -272,11 +276,9 @@ private: String m_name; u8 m_access { 0 }; bool m_shared : 1 { false }; - bool m_user_accessible : 1 { false }; bool m_cacheable : 1 { false }; bool m_stack : 1 { false }; bool m_mmap : 1 { false }; - bool m_kernel : 1 { false }; bool m_syscall_region : 1 { false }; WeakPtr<Process> m_owner; }; diff --git a/Kernel/VM/Space.cpp b/Kernel/VM/Space.cpp index 9bb77f9173..5cb7e28d2e 100644 --- a/Kernel/VM/Space.cpp +++ b/Kernel/VM/Space.cpp @@ -66,7 +66,7 @@ Optional<Range> Space::allocate_range(VirtualAddress vaddr, size_t size, size_t Region& Space::allocate_split_region(const Region& source_region, const Range& range, size_t offset_in_vmobject) { auto& region = add_region(Region::create_user_accessible( - m_process, range, source_region.vmobject(), offset_in_vmobject, source_region.name(), source_region.access(), source_region.is_cacheable(), source_region.is_shared())); + m_process, range, source_region.vmobject(), offset_in_vmobject, source_region.name(), source_region.access(), source_region.is_cacheable() ? Region::Cacheable::Yes : Region::Cacheable::No, source_region.is_shared())); region.set_syscall_region(source_region.is_syscall_region()); region.set_mmap(source_region.is_mmap()); region.set_stack(source_region.is_stack()); @@ -84,7 +84,7 @@ KResultOr<Region*> Space::allocate_region(const Range& range, const String& name auto vmobject = AnonymousVMObject::create_with_size(range.size(), strategy); if (!vmobject) return ENOMEM; - auto region = Region::create_user_accessible(m_process, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot), true, false); + auto region = Region::create_user_accessible(m_process, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot), Region::Cacheable::Yes, false); if (!region->map(page_directory())) return ENOMEM; return &add_region(move(region)); @@ -107,7 +107,7 @@ KResultOr<Region*> Space::allocate_region_with_vmobject(const Range& range, Nonn return EINVAL; } offset_in_vmobject &= PAGE_MASK; - auto& region = add_region(Region::create_user_accessible(m_process, range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot), true, shared)); + auto& region = add_region(Region::create_user_accessible(m_process, range, move(vmobject), offset_in_vmobject, name, prot_to_region_access_flags(prot), Region::Cacheable::Yes, shared)); if (!region.map(page_directory())) { // FIXME: What is an appropriate error code here, really? return ENOMEM; |