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.
This commit is contained in:
Andreas Kling 2022-04-05 12:07:45 +02:00
parent da7ea2556e
commit cfb61cbd54
Notes: sideshowbarker 2024-07-17 14:25:21 +09:00
4 changed files with 25 additions and 15 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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;
}
}

View file

@ -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);