/* * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace Kernel::Memory { enum class RandomizeVirtualAddress { No, Yes, }; // RegionTree represents a virtual address space. // It is used by MemoryManager for kernel VM and by AddressSpace for user VM. // Regions are stored in an intrusive data structure and there are no allocations when interacting with it. class RegionTree { AK_MAKE_NONCOPYABLE(RegionTree); AK_MAKE_NONMOVABLE(RegionTree); public: explicit RegionTree(VirtualRange total_range) : m_total_range(total_range) { } ~RegionTree(); auto& regions() { return m_regions; } auto const& regions() const { return m_regions; } VirtualRange total_range() const { return m_total_range; } ErrorOr> allocate_unbacked_anywhere(size_t size, size_t alignment = PAGE_SIZE); ErrorOr place_anywhere(Region&, RandomizeVirtualAddress, size_t size, size_t alignment = PAGE_SIZE); ErrorOr place_specifically(Region&, VirtualRange const&); ErrorOr> create_identity_mapped_region(PhysicalAddress, size_t); void delete_all_regions_assuming_they_are_unmapped(); private: ErrorOr allocate_range_anywhere(size_t size, size_t alignment = PAGE_SIZE); ErrorOr allocate_range_specific(VirtualAddress base, size_t size); ErrorOr allocate_range_randomized(size_t size, size_t alignment = PAGE_SIZE); Spinlock m_lock; IntrusiveRedBlackTree<&Region::m_tree_node> m_regions; VirtualRange const m_total_range; }; }