diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index cb41a664a..e890324df 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -7,8 +7,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/scope_exit.h" -#include "common/singleton.h" -#include "core/file_sys/fs.h" +#include "common/singleton.h"9 #include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/memory.h" #include "core/libraries/kernel/orbis_error.h" @@ -553,30 +552,47 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolBatch(const OrbisKernelMemoryPoolBatchEntry* return result; } -int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset, - void** res) { - LOG_INFO(Kernel_Vmm, "called addr = {}, len = {}, prot = {}, flags = {}, fd = {}, offset = {}", - fmt::ptr(addr), len, prot, flags, fd, offset); - auto* h = Common::Singleton::Instance(); +void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, s64 phys_addr) { + LOG_INFO(Kernel_Vmm, "called addr = {}, len = {}, prot = {}, flags = {}, fd = {}, phys_addr = {}", + fmt::ptr(addr), len, prot, flags, fd, phys_addr); + + void* addr_out; auto* memory = Core::Memory::Instance(); const auto mem_prot = static_cast(prot); const auto mem_flags = static_cast(flags); + + s32 result = 0; if (fd == -1) { - return memory->MapMemory(res, std::bit_cast(addr), len, mem_prot, mem_flags, - Core::VMAType::Flexible); + result = memory->MapMemory(&addr_out, std::bit_cast(addr), len, mem_prot, mem_flags, + Core::VMAType::Flexible); } else { - const uintptr_t handle = h->GetFile(fd)->f.GetFileMapping(); - return memory->MapFile(res, std::bit_cast(addr), len, mem_prot, mem_flags, handle, - offset); + result = memory->MapFile(&addr_out, std::bit_cast(addr), len, mem_prot, mem_flags, + fd, phys_addr); } + + if (result < 0) { + // If the memory mappings fail, mmap sets errno to the appropriate error code, + // then returns (void*)-1; + ErrSceToPosix(result); + return reinterpret_cast(-1); + } + + return addr_out; } -void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) { - void* ptr; - LOG_INFO(Kernel_Vmm, "posix mmap redirect to sceKernelMmap"); - int result = sceKernelMmap(addr, len, prot, flags, fd, offset, &ptr); - ASSERT(result == 0); - return ptr; +s32 PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, s32 prot, s32 flags, s32 fd, s64 phys_addr, + void** res) { + void* addr_out = posix_mmap(addr, len, prot, flags, fd, phys_addr); + + 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()); + } + + // Set the outputted address + *res = addr_out; + return 0; } s32 PS4_SYSV_ABI sceKernelConfiguredFlexibleMemorySize(u64* sizeOut) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 8c496f816..f3e3500c1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/config.h" #include "common/debug.h" +#include "core/file_sys/fs.h" #include "core/libraries/kernel/memory.h" #include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/process.h" @@ -459,8 +460,15 @@ int MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, size_t size, Mem vma.base, vma.base + vma.size, virtual_addr, virtual_addr + size); } - // Map the file. - impl.MapFile(mapped_addr, size_aligned, offset, std::bit_cast(prot), fd); + // Get the file to map + auto file = h->GetFile(fd); + if (file == nullptr) { + return ORBIS_KERNEL_ERROR_EBADF; + } + + const auto handle = file->f.GetFileMapping(); + + impl.MapFile(mapped_addr, size_aligned, phys_addr, std::bit_cast(prot), fd); if (prot >= MemoryProt::GpuRead) { // PS4s only map to GPU memory when the protection includes GPU access. diff --git a/src/core/memory.h b/src/core/memory.h index 883b48854..aba8b47cc 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -195,8 +195,8 @@ public: MemoryMapFlags flags, VMAType type, std::string_view name = "anon", bool is_exec = false, PAddr phys_addr = -1, u64 alignment = 0); - int MapFile(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot, - MemoryMapFlags flags, uintptr_t fd, size_t offset); + s32 MapFile(void** out_addr, VAddr virtual_addr, u64 size, MemoryProt prot, + MemoryMapFlags flags, s32 fd, s64 phys_addr); s32 PoolDecommit(VAddr virtual_addr, size_t size);