summaryrefslogtreecommitdiff
path: root/Kernel/Memory
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-04-05 12:07:45 +0200
committerAndreas Kling <kling@serenityos.org>2022-04-05 12:23:47 +0200
commitcfb61cbd5407681e2712bdde75d05e1831315062 (patch)
treec0d9061de0234c19f937d8dfea2a3997c5d72422 /Kernel/Memory
parentda7ea2556e2dc2b027609feec35204b12693afd4 (diff)
downloadserenity-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.cpp7
-rw-r--r--Kernel/Memory/MemoryManager.cpp12
-rw-r--r--Kernel/Memory/RegionTree.cpp18
-rw-r--r--Kernel/Memory/RegionTree.h3
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);