diff options
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b437dd4b4e..f006d129a7 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -22,6 +22,7 @@ #include "core/arm/arm_interface.h" #include "core/arm/exclusive_monitor.h" #include "core/core.h" +#include "core/device_memory.h" #include "core/core_timing.h" #include "core/cpu_manager.h" #include "core/hardware_properties.h" @@ -138,8 +139,21 @@ struct KernelCore::Impl { CloseServices(); if (application_process) { + // A process still referenced here is never finalized, so its memory stays mapped in + // the fastmem arena, and the next game's mappings at the same addresses failed: it ran + // on the old game's memory and crashed or hung at boot (a Switch 2 game left its + // process with 55-60 references). Detach the process from the arena, so a late + // finalize can't unmap the next game's memory, and clear the arena. + const u32 references = application_process->GetReferenceCount(); + application_process->GetPageTable().GetImpl().fastmem_arena = nullptr; application_process->Close(system.Kernel()); application_process = nullptr; + if (references > 1) { + LOG_WARNING(Kernel, "Application process still had {} references at shutdown", + references); + } + auto& arena = system.DeviceMemory().buffer; + arena.Unmap(0, arena.VirtualSize(), false); } next_object_id = 0; |
