From 6f568eaec93482b650a5ba71bc88b296684ced58 Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Thu, 25 Jun 2026 19:57:24 -0400 Subject: [PATCH] Replace IsValidMapping asserts with accurate errors during MapMemory and Unmap (#4623) Some titles need this properly handled to run. --- src/core/libraries/kernel/memory.cpp | 5 ++++- src/core/memory.cpp | 26 +++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index c823f846e..266b05059 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -705,6 +705,7 @@ void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, if (len == 0) { // If length is 0, mmap returns EINVAL. ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); + LOG_ERROR(Kernel_Vmm, "Invalid length"); return reinterpret_cast(-1); } @@ -721,6 +722,7 @@ void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, if (True(mem_flags & Core::MemoryMapFlags::Fixed) && vaddr != aligned_addr) { // If flags Fixed is specified, the input address must be aligned. ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); + LOG_ERROR(Kernel_Vmm, "Misaligned input address"); return reinterpret_cast(-1); } @@ -748,9 +750,11 @@ void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, // If the memory mappings fail, mmap sets errno to the appropriate error code, // then returns (void*)-1; ErrSceToPosix(result); + LOG_ERROR(Kernel_Vmm, "error = {}", *__Error()); return reinterpret_cast(-1); } + LOG_INFO(Kernel_Vmm, "addr_out = {}", fmt::ptr(addr_out)); return addr_out; } @@ -760,7 +764,6 @@ s32 PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, if (addr_out == reinterpret_cast(-1)) { // posix_mmap failed, calculate and return the appropriate kernel error code using errno. - LOG_ERROR(Kernel_Fs, "error = {}", *__Error()); return ErrnoToSceKernelError(*__Error()); } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 911776de7..5a6e0a793 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -546,8 +546,11 @@ s32 MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, u64 size, Memo if (True(flags & MemoryMapFlags::Fixed) && True(flags & MemoryMapFlags::NoOverwrite)) { // Perform necessary error checking for Fixed & NoOverwrite case - ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", - virtual_addr); + if (!IsValidMapping(virtual_addr, size)) { + LOG_ERROR(Kernel_Vmm, "addr = {:#x} size = {:#x} is outside the memory map", + virtual_addr, size); + return ORBIS_KERNEL_ERROR_ENOMEM; + } auto vma = FindVMA(virtual_addr)->second; auto remaining_size = vma.base + vma.size - virtual_addr; if (!vma.IsFree() || remaining_size < size) { @@ -721,8 +724,11 @@ s32 MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, u64 size, Memory } if (True(flags & MemoryMapFlags::Fixed) && True(flags & MemoryMapFlags::NoOverwrite)) { - ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", - virtual_addr); + if (!IsValidMapping(virtual_addr, size)) { + LOG_ERROR(Kernel_Vmm, "addr = {:#x} size = {:#x} is outside the memory map", + virtual_addr, size); + return ORBIS_KERNEL_ERROR_ENOMEM; + } auto vma = FindVMA(virtual_addr)->second; auto remaining_size = vma.base + vma.size - virtual_addr; @@ -853,8 +859,11 @@ s32 MemoryManager::UnmapMemory(VAddr virtual_addr, u64 size) { // Align address and size appropriately virtual_addr = Common::AlignDown(virtual_addr, 16_KB); size = Common::AlignUp(size, 16_KB); - ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", - virtual_addr); + if (!IsValidMapping(virtual_addr, size)) { + LOG_ERROR(Kernel_Vmm, "addr = {:#x} size = {:#x} is outside the memory map", virtual_addr, + size); + return ORBIS_KERNEL_ERROR_EINVAL; + } // If the requested range has GPU access, unmap from GPU. if (IsValidGpuMapping(virtual_addr, size)) { @@ -1382,7 +1391,10 @@ VAddr MemoryManager::SearchFree(VAddr virtual_addr, u64 size, u32 alignment) { } // If the requested address is beyond the maximum our code can handle, throw an assert - ASSERT_MSG(IsValidMapping(virtual_addr), "Input address {:#x} is out of bounds", virtual_addr); + if (!IsValidMapping(virtual_addr)) { + LOG_ERROR(Kernel_Vmm, "addr = {:#x} is outside the memory map", virtual_addr); + return -1; + } // Align up the virtual_addr first. virtual_addr = Common::AlignUp(virtual_addr, alignment);