From 2ff9db02452eaac3242f9b7ac500c6684b07959f Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 11 Feb 2022 12:20:26 +0100 Subject: [PATCH] Kernel: Make contiguous VM objects use "user physical pages" by default If someone specifically wants contiguous memory in the low-physical- address-for-DMA range ("super pages"), they can use the allocate_dma_buffer_pages() helper. --- Kernel/Memory/AnonymousVMObject.cpp | 2 +- Kernel/Memory/MemoryManager.cpp | 22 ++++++++++++++++++++++ Kernel/Memory/MemoryManager.h | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Kernel/Memory/AnonymousVMObject.cpp b/Kernel/Memory/AnonymousVMObject.cpp index 925a023e655..38c5cf9e443 100644 --- a/Kernel/Memory/AnonymousVMObject.cpp +++ b/Kernel/Memory/AnonymousVMObject.cpp @@ -82,7 +82,7 @@ ErrorOr> AnonymousVMObject::try_create_with_siz ErrorOr> AnonymousVMObject::try_create_physically_contiguous_with_size(size_t size) { - auto contiguous_physical_pages = TRY(MM.allocate_contiguous_supervisor_physical_pages(size)); + auto contiguous_physical_pages = TRY(MM.allocate_contiguous_user_physical_pages(size)); auto new_physical_pages = TRY(FixedArray>::try_create(contiguous_physical_pages.span())); diff --git a/Kernel/Memory/MemoryManager.cpp b/Kernel/Memory/MemoryManager.cpp index d6b0701b6d7..7bbed63135c 100644 --- a/Kernel/Memory/MemoryManager.cpp +++ b/Kernel/Memory/MemoryManager.cpp @@ -954,6 +954,28 @@ ErrorOr> MemoryManager::allocate_user_physical_page( return page.release_nonnull(); } +ErrorOr> MemoryManager::allocate_contiguous_user_physical_pages(size_t size) +{ + VERIFY(!(size % PAGE_SIZE)); + SpinlockLocker lock(s_mm_lock); + size_t page_count = ceil_div(size, static_cast(PAGE_SIZE)); + + for (auto& physical_region : m_user_physical_regions) { + auto physical_pages = physical_region.take_contiguous_free_pages(page_count); + if (!physical_pages.is_empty()) { + { + auto cleanup_region = TRY(MM.allocate_kernel_region(physical_pages[0].paddr(), PAGE_SIZE * page_count, "MemoryManager Allocation Sanitization", Region::Access::Read | Region::Access::Write)); + memset(cleanup_region->vaddr().as_ptr(), 0, PAGE_SIZE * page_count); + } + m_system_memory_info.user_physical_pages_used += page_count; + return physical_pages; + } + } + + dmesgln("MM: no contiguous user physical pages available"); + return ENOMEM; +} + ErrorOr> MemoryManager::allocate_contiguous_supervisor_physical_pages(size_t size) { VERIFY(!(size % PAGE_SIZE)); diff --git a/Kernel/Memory/MemoryManager.h b/Kernel/Memory/MemoryManager.h index d9754bc12a1..d7f1446bf61 100644 --- a/Kernel/Memory/MemoryManager.h +++ b/Kernel/Memory/MemoryManager.h @@ -174,6 +174,7 @@ public: ErrorOr> allocate_user_physical_page(ShouldZeroFill = ShouldZeroFill::Yes, bool* did_purge = nullptr); ErrorOr> allocate_supervisor_physical_page(); ErrorOr> allocate_contiguous_supervisor_physical_pages(size_t size); + ErrorOr> allocate_contiguous_user_physical_pages(size_t size); void deallocate_physical_page(PhysicalAddress); ErrorOr> allocate_contiguous_kernel_region(size_t, StringView name, Region::Access access, Region::Cacheable = Region::Cacheable::Yes);