mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 12:26:18 +00:00
Core: Pooled Memory Fixes (#2895)
Some checks are pending
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
* Update sceKernelMemoryPoolExpand Hardware tests show that this function is basically the same as sceKernelAllocateDirectMemory, with some minor differences. Update the memory searching code to match my updated AllocateDirectMemory code, with appropriate error conditions. * Update MemoryPoolReserve Only difference between real hw and our code is behavior with addr = 0. * Don't coalesce PoolReserved areas. Real hardware doesn't coalesce them. * Update PoolCommit Plenty of edge case behaviors to handle here. Addresses are treated as fixed, EINVAL is returned for bad mappings, name should be preserved from PoolReserving, committed areas should coalesce, reserved areas get their phys_base updated * Formatting * Adjust fixed PoolReserve path Hardware tests suggest this will overwrite all VMAs in the range. Run UnmapMemoryImpl on the full area, then reserve. Same logic applies to normal reservations too. Also adjusts logic of the non-fixed path to more closely align with hardware observations. * Remove phys_base modifications This can be handled later. Doing the logic properly would likely take work in MergeAdjacent, and would probably need to be applied to normal dmem mappings too. * Use VMAHandle.Contains() Why do extra math when we have a function specifically for this? * Update memory.cpp * Remove unnecessary code Since I've removed those two asserts, these two lines of code effectively do nothing. * Clang * Fix names * Fix PoolDecommit Should fix the address space regressions in UE titles on Windows. * Fix error log Should make the cause of this clearer? * Clang * Oops * Remove coalesce on PoolCommit Windows makes this more difficult. * Track pool budgets If you try to commit more pooled memory than is allocated, PoolCommit returns ENOMEM. Also fixes error conditions for PoolDecommit, that should return EINVAL if given an address that isn't part of the pool. Note: Seems like the pool budget can't hit zero? I used a <= comparison based on hardware tests, otherwise we're able to make more mappings than real hardware can.
This commit is contained in:
parent
6ece91c763
commit
afcf3a12a3
3 changed files with 111 additions and 65 deletions
|
@ -383,13 +383,12 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolExpand(u64 searchStart, u64 searchEnd, size_
|
|||
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
const bool is_in_range = searchEnd - searchStart >= len;
|
||||
if (len <= 0 || !Common::Is64KBAligned(len) || !is_in_range) {
|
||||
LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!");
|
||||
if (len <= 0 || !Common::Is64KBAligned(len)) {
|
||||
LOG_ERROR(Kernel_Vmm, "Provided length {:#x} is invalid!", len);
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (alignment != 0 && !Common::Is64KBAligned(alignment)) {
|
||||
LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!");
|
||||
LOG_ERROR(Kernel_Vmm, "Alignment {:#x} is invalid!", alignment);
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (physAddrOut == nullptr) {
|
||||
|
@ -397,8 +396,21 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolExpand(u64 searchStart, u64 searchEnd, size_
|
|||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
const bool is_in_range = searchEnd - searchStart >= len;
|
||||
if (searchEnd <= searchStart || searchEnd < len || !is_in_range) {
|
||||
LOG_ERROR(Kernel_Vmm,
|
||||
"Provided address range is too small!"
|
||||
" searchStart = {:#x}, searchEnd = {:#x}, length = {:#x}",
|
||||
searchStart, searchEnd, len);
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
auto* memory = Core::Memory::Instance();
|
||||
PAddr phys_addr = memory->PoolExpand(searchStart, searchEnd, len, alignment);
|
||||
if (phys_addr == -1) {
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
*physAddrOut = static_cast<s64>(phys_addr);
|
||||
|
||||
LOG_INFO(Kernel_Vmm,
|
||||
|
@ -413,10 +425,6 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolReserve(void* addrIn, size_t len, size_t ali
|
|||
LOG_INFO(Kernel_Vmm, "addrIn = {}, len = {:#x}, alignment = {:#x}, flags = {:#x}",
|
||||
fmt::ptr(addrIn), len, alignment, flags);
|
||||
|
||||
if (addrIn == nullptr) {
|
||||
LOG_ERROR(Kernel_Vmm, "Address is invalid!");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (len == 0 || !Common::Is2MBAligned(len)) {
|
||||
LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 2MB aligned!");
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
|
@ -469,9 +477,8 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolDecommit(void* addr, size_t len, int flags)
|
|||
|
||||
const VAddr pool_addr = reinterpret_cast<VAddr>(addr);
|
||||
auto* memory = Core::Memory::Instance();
|
||||
memory->PoolDecommit(pool_addr, len);
|
||||
|
||||
return ORBIS_OK;
|
||||
return memory->PoolDecommit(pool_addr, len);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue