From 3a56c75fe4cd5ee2b5f5c50ba5dbc2ba8b957cfb Mon Sep 17 00:00:00 2001 From: Exverge Date: Thu, 6 Aug 2026 23:47:49 -0400 Subject: [PATCH] [hle] fix explicitly allocated memory, workaround for TLS pages --- src/core/hle/kernel/k_memory_manager.cpp | 4 ++-- src/core/hle/kernel/k_memory_manager.h | 2 +- src/core/hle/kernel/k_page_table_base.cpp | 2 +- src/core/hle/kernel/k_thread_local_page.cpp | 5 +++++ 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp index c14cf6daf2..7c94708484 100644 --- a/src/core/hle/kernel/k_memory_manager.cpp +++ b/src/core/hle/kernel/k_memory_manager.cpp @@ -388,7 +388,7 @@ Result KMemoryManager::AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 op } Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 option, - u64 process_id, u8 fill_pattern) { + u64 process_id, u8 fill_pattern, KProcessAddress expected_vaddr) { ASSERT(out != nullptr); ASSERT(out->GetNumPages() == 0); @@ -407,7 +407,7 @@ Result KMemoryManager::AllocateForProcess(KPageGroup* out, size_t num_pages, u32 // Allocate the page group. R_TRY(this->AllocatePageGroupImpl(out, num_pages, pool, dir, has_optimized && !is_optimized, - false, 0)); + false, expected_vaddr)); // Set whether we should optimize. optimized = has_optimized && is_optimized; diff --git a/src/core/hle/kernel/k_memory_manager.h b/src/core/hle/kernel/k_memory_manager.h index 5ce0a11140..f0569ea970 100644 --- a/src/core/hle/kernel/k_memory_manager.h +++ b/src/core/hle/kernel/k_memory_manager.h @@ -61,7 +61,7 @@ public: KPhysicalAddress AllocateAndOpenContinuous(size_t num_pages, size_t align_pages, u32 option); Result AllocateAndOpen(KPageGroup* out, size_t num_pages, u32 option, KProcessAddress expected_vaddr = 0); Result AllocateForProcess(KPageGroup* out, size_t num_pages, u32 option, u64 process_id, - u8 fill_pattern); + u8 fill_pattern, KProcessAddress expected_vaddr = 0); Pool GetPool(KPhysicalAddress address) const { return this->GetManager(address).GetPool(); diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index c6050e0fac..2cad5020bd 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -5206,7 +5206,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) { KPageGroup pg(m_system.Kernel(), m_block_info_manager); R_TRY(m_system.Kernel().MemoryManager().AllocateForProcess( std::addressof(pg), (size - mapped_size) / PageSize, m_allocate_option, - GetCurrentProcess(m_system.Kernel()).GetId(), m_heap_fill_value)); + GetCurrentProcess(m_system.Kernel()).GetId(), m_heap_fill_value, address)); // If we fail in the next bit (or retry), we need to cleanup the pages. auto pg_guard = SCOPE_GUARD { diff --git a/src/core/hle/kernel/k_thread_local_page.cpp b/src/core/hle/kernel/k_thread_local_page.cpp index 1952c00831..fd446c3b0c 100644 --- a/src/core/hle/kernel/k_thread_local_page.cpp +++ b/src/core/hle/kernel/k_thread_local_page.cpp @@ -20,6 +20,11 @@ Result KThreadLocalPage::Initialize(KernelCore& kernel, KProcess* process) { // Allocate a new page. KPageBuffer* page_buf = KPageBuffer::Allocate(kernel); + // TODO: this sucks and wastes memory don't do this + while (!Common::IsAligned(reinterpret_cast(page_buf), Common::HostPageSize)) { + page_buf = KPageBuffer::Allocate(kernel); + } + R_UNLESS(page_buf != nullptr, ResultOutOfMemory); auto page_buf_guard = SCOPE_GUARD { KPageBuffer::Free(kernel, page_buf);