Replace IsValidMapping asserts with accurate errors during MapMemory and Unmap (#4623)

Some titles need this properly handled to run.
This commit is contained in:
Stephen Miller 2026-06-25 19:57:24 -04:00 committed by GitHub
parent 55bc0be82d
commit 6f568eaec9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 8 deletions

View File

@ -705,6 +705,7 @@ void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd,
if (len == 0) { if (len == 0) {
// If length is 0, mmap returns EINVAL. // If length is 0, mmap returns EINVAL.
ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL);
LOG_ERROR(Kernel_Vmm, "Invalid length");
return reinterpret_cast<void*>(-1); return reinterpret_cast<void*>(-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 (True(mem_flags & Core::MemoryMapFlags::Fixed) && vaddr != aligned_addr) {
// If flags Fixed is specified, the input address must be aligned. // If flags Fixed is specified, the input address must be aligned.
ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL); ErrSceToPosix(ORBIS_KERNEL_ERROR_EINVAL);
LOG_ERROR(Kernel_Vmm, "Misaligned input address");
return reinterpret_cast<void*>(-1); return reinterpret_cast<void*>(-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, // If the memory mappings fail, mmap sets errno to the appropriate error code,
// then returns (void*)-1; // then returns (void*)-1;
ErrSceToPosix(result); ErrSceToPosix(result);
LOG_ERROR(Kernel_Vmm, "error = {}", *__Error());
return reinterpret_cast<void*>(-1); return reinterpret_cast<void*>(-1);
} }
LOG_INFO(Kernel_Vmm, "addr_out = {}", fmt::ptr(addr_out));
return 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<void*>(-1)) { if (addr_out == reinterpret_cast<void*>(-1)) {
// posix_mmap failed, calculate and return the appropriate kernel error code using errno. // posix_mmap failed, calculate and return the appropriate kernel error code using errno.
LOG_ERROR(Kernel_Fs, "error = {}", *__Error());
return ErrnoToSceKernelError(*__Error()); return ErrnoToSceKernelError(*__Error());
} }

View File

@ -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)) { if (True(flags & MemoryMapFlags::Fixed) && True(flags & MemoryMapFlags::NoOverwrite)) {
// Perform necessary error checking for Fixed & NoOverwrite case // Perform necessary error checking for Fixed & NoOverwrite case
ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", if (!IsValidMapping(virtual_addr, size)) {
virtual_addr); 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 vma = FindVMA(virtual_addr)->second;
auto remaining_size = vma.base + vma.size - virtual_addr; auto remaining_size = vma.base + vma.size - virtual_addr;
if (!vma.IsFree() || remaining_size < size) { 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)) { if (True(flags & MemoryMapFlags::Fixed) && True(flags & MemoryMapFlags::NoOverwrite)) {
ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", if (!IsValidMapping(virtual_addr, size)) {
virtual_addr); 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 vma = FindVMA(virtual_addr)->second;
auto remaining_size = vma.base + vma.size - virtual_addr; 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 // Align address and size appropriately
virtual_addr = Common::AlignDown(virtual_addr, 16_KB); virtual_addr = Common::AlignDown(virtual_addr, 16_KB);
size = Common::AlignUp(size, 16_KB); size = Common::AlignUp(size, 16_KB);
ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", if (!IsValidMapping(virtual_addr, size)) {
virtual_addr); 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 the requested range has GPU access, unmap from GPU.
if (IsValidGpuMapping(virtual_addr, size)) { 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 // 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. // Align up the virtual_addr first.
virtual_addr = Common::AlignUp(virtual_addr, alignment); virtual_addr = Common::AlignUp(virtual_addr, alignment);