aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-30 00:54:09 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-30 00:54:09 -0400
commit74cbdf00565e17b793d4b4927538f4bfe9b9ac8d (patch)
tree6b9bb0072f3991159dd5c4759fcb6659054983a7 /src/core/hle/kernel
parentd56039ace99338293658f931a871e4dba203e3ab (diff)
kernel: clear the fastmem arena when the application process is closed
Loading a Switch 2 game after another one in the same window hung or crashed it at boot. The first game's process still had 55-60 references at kernel shutdown, so it was never finalized and its memory stayed mapped in the fastmem arena. The next game's mappings at the same addresses then failed ("Failed to split placeholder" / "Failed to map placeholder"), and it ran on the first game's memory: Mario Kart World loaded after another Switch 2 game jumped to a garbage address from rtld, or hung. Detach the closed process from the arena (a late finalize must not unmap the next game's memory), unmap the whole arena, and log when the process was still referenced.
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/kernel.cpp14
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;