diff --git a/Kernel/Interrupts/APIC.cpp b/Kernel/Interrupts/APIC.cpp index cd7f04f068..a2bfa0dd8e 100644 --- a/Kernel/Interrupts/APIC.cpp +++ b/Kernel/Interrupts/APIC.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -274,6 +275,19 @@ UNMAP_AFTER_INIT bool APIC::init_bsp() return true; } +UNMAP_AFTER_INIT static NonnullOwnPtr create_identity_mapped_region(PhysicalAddress paddr, size_t size) +{ + auto vmobject = Memory::AnonymousVMObject::try_create_for_physical_range(paddr, size); + VERIFY(vmobject); + auto region = MM.allocate_kernel_region_with_vmobject( + Memory::VirtualRange { VirtualAddress { static_cast(paddr.get()) }, size }, + vmobject.release_nonnull(), + {}, + Memory::Region::Access::Read | Memory::Region::Access::Write | Memory::Region::Access::Execute); + VERIFY(region); + return region.release_nonnull(); +} + UNMAP_AFTER_INIT void APIC::do_boot_aps() { VERIFY(m_processor_enabled_cnt > 1); @@ -283,7 +297,7 @@ UNMAP_AFTER_INIT void APIC::do_boot_aps() // Also account for the data appended to: // * aps_to_enable u32 values for ap_cpu_init_stacks // * aps_to_enable u32 values for ap_cpu_init_processor_info_array - auto apic_startup_region = MM.allocate_kernel_region_identity(PhysicalAddress(0x8000), Memory::page_round_up(apic_ap_start_size + (2 * aps_to_enable * sizeof(u32))), {}, Memory::Region::Access::Read | Memory::Region::Access::Write | Memory::Region::Access::Execute); + auto apic_startup_region = create_identity_mapped_region(PhysicalAddress(0x8000), Memory::page_round_up(apic_ap_start_size + (2 * aps_to_enable * sizeof(u32)))); memcpy(apic_startup_region->vaddr().as_ptr(), reinterpret_cast(apic_ap_start), apic_ap_start_size); // Allocate enough stacks for all APs @@ -362,6 +376,10 @@ UNMAP_AFTER_INIT void APIC::do_boot_aps() } dbgln_if(APIC_DEBUG, "APIC: {} processors are initialized and running", m_processor_enabled_cnt); + + // NOTE: Since this region is identity-mapped, we have to unmap it manually to prevent the virtual + // address range from leaking into the general virtual range allocator. + apic_startup_region->unmap(Memory::Region::ShouldDeallocateVirtualMemoryVirtualRange::No); } UNMAP_AFTER_INIT void APIC::boot_aps() diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index 0b5f5f12a2..e117aed54c 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -733,19 +733,6 @@ OwnPtr MemoryManager::allocate_kernel_region(PhysicalAddress paddr, size return allocate_kernel_region_with_vmobject(range.value(), *vm_object, name, access, cacheable); } -OwnPtr MemoryManager::allocate_kernel_region_identity(PhysicalAddress paddr, size_t size, StringView name, Region::Access access, Region::Cacheable cacheable) -{ - auto vm_object = AnonymousVMObject::try_create_for_physical_range(paddr, size); - if (!vm_object) - return {}; - VERIFY(!(size % PAGE_SIZE)); - ScopedSpinLock lock(s_mm_lock); - auto range = kernel_page_directory().identity_range_allocator().allocate_specific(VirtualAddress(paddr.get()), size); - if (!range.has_value()) - return {}; - return allocate_kernel_region_with_vmobject(range.value(), *vm_object, name, access, cacheable); -} - OwnPtr MemoryManager::allocate_kernel_region_with_vmobject(VirtualRange const& range, VMObject& vmobject, StringView name, Region::Access access, Region::Cacheable cacheable) { ScopedSpinLock lock(s_mm_lock); diff --git a/Kernel/Memory/MemoryManager.h b/Kernel/Memory/MemoryManager.h index 5070b6706e..bc2bbd312b 100644 --- a/Kernel/Memory/MemoryManager.h +++ b/Kernel/Memory/MemoryManager.h @@ -183,7 +183,6 @@ public: OwnPtr allocate_contiguous_kernel_region(size_t, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes); OwnPtr allocate_kernel_region(size_t, StringView name, Region::Access access, AllocationStrategy strategy = AllocationStrategy::Reserve, Region::Cacheable = Region::Cacheable::Yes); OwnPtr allocate_kernel_region(PhysicalAddress, size_t, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes); - OwnPtr allocate_kernel_region_identity(PhysicalAddress, size_t, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes); OwnPtr allocate_kernel_region_with_vmobject(VMObject&, size_t, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes); OwnPtr allocate_kernel_region_with_vmobject(VirtualRange const&, VMObject&, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes); diff --git a/Kernel/Memory/PageDirectory.cpp b/Kernel/Memory/PageDirectory.cpp index 6aca487b3e..4d8cf94e88 100644 --- a/Kernel/Memory/PageDirectory.cpp +++ b/Kernel/Memory/PageDirectory.cpp @@ -38,7 +38,6 @@ UNMAP_AFTER_INIT NonnullRefPtr PageDirectory::must_create_kernel_ // make sure this starts in a new page directory to make MemoryManager::initialize_physical_pages() happy FlatPtr start_of_range = ((FlatPtr)end_of_kernel_image & ~(FlatPtr)0x1fffff) + 0x200000; directory->m_range_allocator.initialize_with_range(VirtualAddress(start_of_range), KERNEL_PD_END - start_of_range); - directory->m_identity_range_allocator.initialize_with_range(VirtualAddress(FlatPtr(0x00000000)), 0x00200000); return directory; } diff --git a/Kernel/Memory/PageDirectory.h b/Kernel/Memory/PageDirectory.h index 98d3d94cf4..b50a2867b0 100644 --- a/Kernel/Memory/PageDirectory.h +++ b/Kernel/Memory/PageDirectory.h @@ -39,8 +39,6 @@ public: VirtualRangeAllocator& range_allocator() { return m_range_allocator; } VirtualRangeAllocator const& range_allocator() const { return m_range_allocator; } - VirtualRangeAllocator& identity_range_allocator() { return m_identity_range_allocator; } - AddressSpace* address_space() { return m_space; } const AddressSpace* address_space() const { return m_space; } @@ -53,7 +51,6 @@ private: AddressSpace* m_space { nullptr }; VirtualRangeAllocator m_range_allocator; - VirtualRangeAllocator m_identity_range_allocator; #if ARCH(X86_64) RefPtr m_pml4t; #endif diff --git a/Kernel/Memory/Region.cpp b/Kernel/Memory/Region.cpp index 07f16d7a93..a5b5758b94 100644 --- a/Kernel/Memory/Region.cpp +++ b/Kernel/Memory/Region.cpp @@ -247,10 +247,7 @@ void Region::unmap(ShouldDeallocateVirtualMemoryVirtualRange deallocate_range) } MM.flush_tlb(m_page_directory, vaddr(), page_count()); if (deallocate_range == ShouldDeallocateVirtualMemoryVirtualRange::Yes) { - if (m_page_directory->range_allocator().contains(range())) - m_page_directory->range_allocator().deallocate(range()); - else - m_page_directory->identity_range_allocator().deallocate(range()); + m_page_directory->range_allocator().deallocate(range()); } m_page_directory = nullptr; }