mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-24 19:36:17 +00:00
Proper error handling for MapMemory errors (#2938)
* Properly handle ENOMEM error return in MapMemory Needed for Assassin's Creed Unity to behave properly. * Change error message If I left the message as-is, we'd probably see inexperienced people claiming the assert means your device needs more memory, which is completely false. * Clang You know you're doing something right when Clang complains. * Attempt to handle MemoryMapFlags::NoOverwrite Based on my interpretation of red_prig's descriptions. These changes are untested, as I'm not able to test right now. * Fix flag description * Move overwrite check to while condition
This commit is contained in:
parent
7de6aec337
commit
4d769d9c7e
1 changed files with 8 additions and 5 deletions
|
@ -376,19 +376,22 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M
|
|||
// To account for this, unmap any reserved areas within this mapping range first.
|
||||
auto unmap_addr = mapped_addr;
|
||||
auto unmap_size = size;
|
||||
while (!vma.IsMapped() && unmap_addr < mapped_addr + size && remaining_size < size) {
|
||||
// If flag NoOverwrite is provided, don't overwrite mapped VMAs.
|
||||
// When it isn't provided, VMAs can be overwritten regardless of if they're mapped.
|
||||
while ((False(flags & MemoryMapFlags::NoOverwrite) || !vma.IsMapped()) &&
|
||||
unmap_addr < mapped_addr + size && remaining_size < size) {
|
||||
auto unmapped = UnmapBytesFromEntry(unmap_addr, vma, unmap_size);
|
||||
unmap_addr += unmapped;
|
||||
unmap_size -= unmapped;
|
||||
vma = FindVMA(unmap_addr)->second;
|
||||
}
|
||||
|
||||
// This should return SCE_KERNEL_ERROR_ENOMEM but rarely happens.
|
||||
vma = FindVMA(mapped_addr)->second;
|
||||
remaining_size = vma.base + vma.size - mapped_addr;
|
||||
ASSERT_MSG(!vma.IsMapped() && remaining_size >= size,
|
||||
"Memory region {:#x} to {:#x} isn't free enough to map region {:#x} to {:#x}",
|
||||
vma.base, vma.base + vma.size, virtual_addr, virtual_addr + size);
|
||||
if (vma.IsMapped() || remaining_size < size) {
|
||||
LOG_ERROR(Kernel_Vmm, "Unable to map {:#x} bytes at address {:#x}", size, mapped_addr);
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
// Find the first free area starting with provided virtual address.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue