aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/host_memory.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp14
2 files changed, 18 insertions, 0 deletions
diff --git a/src/common/host_memory.h b/src/common/host_memory.h
index a7fd0532b7..8747a1850f 100644
--- a/src/common/host_memory.h
+++ b/src/common/host_memory.h
@@ -68,6 +68,10 @@ public:
return virtual_base;
}
+ [[nodiscard]] size_t VirtualSize() const noexcept {
+ return virtual_size;
+ }
+
bool IsInVirtualRange(void* address) const noexcept {
return address >= virtual_base && address < virtual_base + virtual_size;
}
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;