diff options
author | Andreas Kling <kling@serenityos.org> | 2022-04-05 12:07:45 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-05 12:23:47 +0200 |
commit | cfb61cbd5407681e2712bdde75d05e1831315062 (patch) | |
tree | c0d9061de0234c19f937d8dfea2a3997c5d72422 /Kernel/Memory | |
parent | da7ea2556e2dc2b027609feec35204b12693afd4 (diff) | |
download | serenity-cfb61cbd5407681e2712bdde75d05e1831315062.zip |
Kernel: Add RegionTree::find_region_containing(address or range)
Let's encapsulate looking up regions so clients don't have to dig into
RegionTree internals.
Diffstat (limited to 'Kernel/Memory')
-rw-r--r-- | Kernel/Memory/AddressSpace.cpp | 7 | ||||
-rw-r--r-- | Kernel/Memory/MemoryManager.cpp | 12 | ||||
-rw-r--r-- | Kernel/Memory/RegionTree.cpp | 18 | ||||
-rw-r--r-- | Kernel/Memory/RegionTree.h | 3 |
4 files changed, 25 insertions, 15 deletions
diff --git a/Kernel/Memory/AddressSpace.cpp b/Kernel/Memory/AddressSpace.cpp index 5e84decbdd..50cd70eb73 100644 --- a/Kernel/Memory/AddressSpace.cpp +++ b/Kernel/Memory/AddressSpace.cpp @@ -250,12 +250,7 @@ Region* AddressSpace::find_region_from_range(VirtualRange const& range) Region* AddressSpace::find_region_containing(VirtualRange const& range) { - SpinlockLocker lock(m_lock); - SpinlockLocker tree_locker(m_region_tree.get_lock()); - auto* candidate = m_region_tree.regions().find_largest_not_above(range.base().get()); - if (!candidate) - return nullptr; - return (*candidate).range().contains(range) ? candidate : nullptr; + return m_region_tree.find_region_containing(range); } ErrorOr<Vector<Region*>> AddressSpace::find_regions_intersecting(VirtualRange const& range) diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 9384fa6a98..2934655b75 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -658,18 +658,12 @@ UNMAP_AFTER_INIT void MemoryManager::initialize(u32 cpu) } } -Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress vaddr) +Region* MemoryManager::kernel_region_from_vaddr(VirtualAddress address) { - if (is_user_address(vaddr)) + if (is_user_address(address)) return nullptr; - SpinlockLocker lock(s_mm_lock); - SpinlockLocker tree_locker(MM.m_region_tree.get_lock()); - - auto* region = MM.m_region_tree.regions().find_largest_not_above(vaddr.get()); - if (!region || !region->contains(vaddr)) - return nullptr; - return region; + return MM.region_tree().find_region_containing(address); } Region* MemoryManager::find_user_region_from_vaddr_no_lock(AddressSpace& space, VirtualAddress vaddr) diff --git a/Kernel/Memory/RegionTree.cpp b/Kernel/Memory/RegionTree.cpp index ed0baa952c..5736a56aa1 100644 --- a/Kernel/Memory/RegionTree.cpp +++ b/Kernel/Memory/RegionTree.cpp @@ -170,4 +170,22 @@ bool RegionTree::remove(Region& region) return m_regions.remove(region.range().base().get()); } +Region* RegionTree::find_region_containing(VirtualAddress address) +{ + SpinlockLocker locker(m_lock); + auto* region = m_regions.find_largest_not_above(address.get()); + if (!region || !region->contains(address)) + return nullptr; + return region; +} + +Region* RegionTree::find_region_containing(VirtualRange range) +{ + SpinlockLocker lock(m_lock); + auto* region = m_regions.find_largest_not_above(range.base().get()); + if (!region || !region->contains(range)) + return nullptr; + return region; +} + } diff --git a/Kernel/Memory/RegionTree.h b/Kernel/Memory/RegionTree.h index d55b52affb..339fc6fd3c 100644 --- a/Kernel/Memory/RegionTree.h +++ b/Kernel/Memory/RegionTree.h @@ -54,6 +54,9 @@ public: bool remove(Region&); + Region* find_region_containing(VirtualAddress); + Region* find_region_containing(VirtualRange); + private: ErrorOr<VirtualRange> allocate_range_anywhere(size_t size, size_t alignment = PAGE_SIZE); ErrorOr<VirtualRange> allocate_range_specific(VirtualAddress base, size_t size); |