From 89c86a1411351451ac1705392ff067ed4c259039 Mon Sep 17 00:00:00 2001 From: DH Date: Sat, 6 Dec 2025 17:41:09 +0300 Subject: [PATCH] fix sys_batch_map dmem map --- kernel/orbis/src/sys/sys_sce.cpp | 97 +++++++++++++++++++------------- 1 file changed, 58 insertions(+), 39 deletions(-) diff --git a/kernel/orbis/src/sys/sys_sce.cpp b/kernel/orbis/src/sys/sys_sce.cpp index 050b70fbc..266c88621 100644 --- a/kernel/orbis/src/sys/sys_sce.cpp +++ b/kernel/orbis/src/sys/sys_sce.cpp @@ -32,6 +32,52 @@ struct orbis::AppMountInfo { static_assert(sizeof(orbis::AppMountInfo) == 120); +static std::pair +mmap_dmem(orbis::Thread *thread, orbis::uintptr_t addr, orbis::size_t len, + orbis::MemoryType memoryType, + rx::EnumBitSet prot, + rx::EnumBitSet flags, + orbis::off_t directMemoryStart, std::uint64_t callerAddress) { + auto alignment = orbis::dmem::kPageSize; + + { + auto unpacked = unpackMapFlags(flags, orbis::dmem::kPageSize); + alignment = unpacked.first; + flags = unpacked.second; + } + + len = rx::alignUp(len, orbis::dmem::kPageSize); + + rx::EnumBitSet allocFlags{}; + + if (prot & orbis::vmem::Protection::CpuExec) { + return {{}, orbis::ErrorCode::INVAL}; + } + + if (flags & orbis::vmem::MapFlags::Fixed) { + allocFlags = orbis::AllocationFlags::Fixed; + } else if (addr == 0) { + addr = 0xfe0000000; + } + + if (flags & orbis::vmem::MapFlags::NoOverwrite) { + allocFlags |= orbis::AllocationFlags::NoOverwrite; + } + + auto name = callerAddress ? rx::format("anon:{:012x}", callerAddress) : ""; + + auto [range, errc] = orbis::vmem::mapDirect( + thread->tproc, addr, + rx::AddressRange::fromBeginSize(directMemoryStart, len), prot, allocFlags, + name, alignment, callerAddress, memoryType); + + if (errc != orbis::ErrorCode{}) { + return {{}, errc}; + } + + return {range.beginAddress(), {}}; +} + orbis::SysResult orbis::sys_netcontrol(Thread *thread, FileDescriptor fd, uint op, ptr buf, uint nbuf) { return {}; @@ -439,6 +485,8 @@ orbis::SysResult orbis::sys_batch_map(Thread *thread, sint unk, ORBIS_LOG_ERROR(__FUNCTION__, unk, flags.toUnderlying(), entries, entriesCount, processedCount); + auto callerAddress = getCallerAddress(thread); + int processed = 0; for (int i = 0; i < entriesCount; ++i) { BatchMapEntry _entry; @@ -448,13 +496,14 @@ orbis::SysResult orbis::sys_batch_map(Thread *thread, sint unk, _entry.offset); switch (_entry.operation) { - case 0: - result = sys_mmap_dmem( - thread, _entry.start, _entry.length, - static_cast(_entry.type), + case 0: { + auto [address, errc] = mmap_dmem( + thread, _entry.start, _entry.length, MemoryType::Invalid, rx::EnumBitSet::fromUnderlying(_entry.protection), - flags, _entry.offset); + flags, _entry.offset, callerAddress); + result = errc; break; + } case 1: result = sys_munmap(thread, _entry.start, _entry.length); break; @@ -1515,50 +1564,20 @@ orbis::SysResult orbis::sys_mmap_dmem(Thread *thread, uintptr_t addr, rx::EnumBitSet prot, rx::EnumBitSet flags, off_t directMemoryStart) { - - auto callerAddress = getCallerAddress(thread); - auto alignment = dmem::kPageSize; - if (static_cast(memoryType) > 10) { return ErrorCode::INVAL; } - { - auto unpacked = unpackMapFlags(flags, dmem::kPageSize); - alignment = unpacked.first; - flags = unpacked.second; - } + auto callerAddress = getCallerAddress(thread); - len = rx::alignUp(len, dmem::kPageSize); - - rx::EnumBitSet allocFlags{}; - - if (prot & vmem::Protection::CpuExec) { - return ErrorCode::INVAL; - } - - if (flags & vmem::MapFlags::Fixed) { - allocFlags = AllocationFlags::Fixed; - } else if (addr == 0) { - addr = 0xfe0000000; - } - - if (flags & vmem::MapFlags::NoOverwrite) { - allocFlags |= AllocationFlags::NoOverwrite; - } - - auto name = callerAddress ? rx::format("anon:{:012x}", callerAddress) : ""; - - auto [range, errc] = vmem::mapDirect( - thread->tproc, addr, - rx::AddressRange::fromBeginSize(directMemoryStart, len), prot, allocFlags, - name, alignment, callerAddress, memoryType); + auto [result, errc] = mmap_dmem(thread, addr, len, memoryType, prot, flags, + directMemoryStart, callerAddress); if (errc != ErrorCode{}) { return errc; } - thread->retval[0] = range.beginAddress(); + thread->retval[0] = result; return {}; } orbis::SysResult orbis::sys_physhm_open(Thread *thread /* TODO */) {