diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index 9a5242706d..8e6f3b7c55 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -837,7 +837,7 @@ static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unl
   return was_unpaused;
 }
 
-void RunOnCPUThread(std::function<void()> function, bool wait_for_completion)
+void RunOnCPUThread(Core::System& system, std::function<void()> function, bool wait_for_completion)
 {
   // If the CPU thread is not running, assume there is no active CPU thread we can race against.
   if (!IsRunning() || IsCPUThread())
@@ -846,8 +846,6 @@ void RunOnCPUThread(std::function<void()> function, bool wait_for_completion)
     return;
   }
 
-  auto& system = Core::System::GetInstance();
-
   // Pause the CPU (set it to stepping mode).
   const bool was_running = PauseAndLock(system, true, true);
 
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 7564511573..95b8da2969 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -157,7 +157,7 @@ void OnFrameEnd(Core::System& system);
 
 // Run a function on the CPU thread, asynchronously.
 // This is only valid to call from the host thread, since it uses PauseAndLock() internally.
-void RunOnCPUThread(std::function<void()> function, bool wait_for_completion);
+void RunOnCPUThread(Core::System& system, std::function<void()> function, bool wait_for_completion);
 
 // for calling back into UI code without introducing a dependency on it in core
 using StateChangedCallbackFunc = std::function<void(Core::State)>;
diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp
index a21a5afb33..e759358e04 100644
--- a/Source/Core/Core/Movie.cpp
+++ b/Source/Core/Core/Movie.cpp
@@ -574,7 +574,7 @@ bool MovieManager::BeginRecordingInput(const ControllerTypeArray& controllers,
     if (Core::IsRunning())
       Core::UpdateWantDeterminism(m_system);
   };
-  Core::RunOnCPUThread(start_recording, true);
+  Core::RunOnCPUThread(m_system, start_recording, true);
 
   Core::DisplayMessage("Starting movie recording", 2000);
   return true;
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 4e7d061d36..90f07d2756 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -217,6 +217,7 @@ void LoadFromBuffer(Core::System& system, std::vector<u8>& buffer)
 #endif  // USE_RETRO_ACHIEVEMENTS
 
   Core::RunOnCPUThread(
+      system,
       [&] {
         u8* ptr = buffer.data();
         PointerWrap p(&ptr, buffer.size(), PointerWrap::Mode::Read);
@@ -228,6 +229,7 @@ void LoadFromBuffer(Core::System& system, std::vector<u8>& buffer)
 void SaveToBuffer(Core::System& system, std::vector<u8>& buffer)
 {
   Core::RunOnCPUThread(
+      system,
       [&] {
         u8* ptr = nullptr;
         PointerWrap p_measure(&ptr, 0, PointerWrap::Mode::Measure);
@@ -473,6 +475,7 @@ void SaveAs(Core::System& system, const std::string& filename, bool wait)
     return;
 
   Core::RunOnCPUThread(
+      system,
       [&] {
         {
           std::lock_guard lk_(s_state_writes_in_queue_mutex);
@@ -871,6 +874,7 @@ void LoadAs(Core::System& system, const std::string& filename)
     return;
 
   Core::RunOnCPUThread(
+      system,
       [&] {
         // Save temp buffer for undo load state
         auto& movie = system.GetMovie();
diff --git a/Source/Core/DolphinQt/GBAWidget.cpp b/Source/Core/DolphinQt/GBAWidget.cpp
index 15aef84a15..ad5e29bda9 100644
--- a/Source/Core/DolphinQt/GBAWidget.cpp
+++ b/Source/Core/DolphinQt/GBAWidget.cpp
@@ -37,7 +37,8 @@
 static void RestartCore(const std::weak_ptr<HW::GBA::Core>& core, std::string_view rom_path = {})
 {
   Core::RunOnCPUThread(
-      [core, rom_path = std::string(rom_path)] {
+      Core::System::GetInstance(),
+      [core, rom_path = std::string(rom_path)]() {
         if (auto core_ptr = core.lock())
         {
           auto& info = Config::MAIN_GBA_ROM_PATHS[core_ptr->GetCoreInfo().device_number];
@@ -57,7 +58,8 @@ static void RestartCore(const std::weak_ptr<HW::GBA::Core>& core, std::string_vi
 static void QueueEReaderCard(const std::weak_ptr<HW::GBA::Core>& core, std::string_view card_path)
 {
   Core::RunOnCPUThread(
-      [core, card_path = std::string(card_path)] {
+      Core::System::GetInstance(),
+      [core, card_path = std::string(card_path)]() {
         if (auto core_ptr = core.lock())
           core_ptr->EReaderQueueCard(card_path);
       },
@@ -159,7 +161,8 @@ void GBAWidget::ToggleDisconnect()
   m_force_disconnect = !m_force_disconnect;
 
   Core::RunOnCPUThread(
-      [core = m_core, force_disconnect = m_force_disconnect] {
+      Core::System::GetInstance(),
+      [core = m_core, force_disconnect = m_force_disconnect]() {
         if (auto core_ptr = core.lock())
           core_ptr->SetForceDisconnect(force_disconnect);
       },
@@ -221,7 +224,8 @@ void GBAWidget::DoState(bool export_state)
     return;
 
   Core::RunOnCPUThread(
-      [export_state, core = m_core, state_path = state_path.toStdString()] {
+      Core::System::GetInstance(),
+      [export_state, core = m_core, state_path = state_path.toStdString()]() {
         if (auto core_ptr = core.lock())
         {
           if (export_state)
@@ -251,7 +255,8 @@ void GBAWidget::ImportExportSave(bool export_save)
     return;
 
   Core::RunOnCPUThread(
-      [export_save, core = m_core, save_path = save_path.toStdString()] {
+      Core::System::GetInstance(),
+      [export_save, core = m_core, save_path = save_path.toStdString()]() {
         if (auto core_ptr = core.lock())
         {
           if (export_save)