From e3d156ab0e020ade2a96ae82eba226d5f187aa2e Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Fri, 26 Nov 2021 15:35:11 -0800
Subject: [PATCH] hle: kernel: svc: Fix deadlock that can occur with single
 core.

---
 src/core/hle/kernel/svc.cpp | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 0e79e1be3d..359cf515df 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -308,12 +308,18 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
 
 /// Makes a blocking IPC call to an OS service.
 static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
-
     auto& kernel = system.Kernel();
 
     // Create the wait queue.
     KThreadQueue wait_queue(kernel);
 
+    // Get the client session from its handle.
+    KScopedAutoObject session =
+        kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
+    R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
+
+    LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
+
     auto thread = kernel.CurrentScheduler()->GetCurrentThread();
     {
         KScopedSchedulerLock lock(kernel);
@@ -321,15 +327,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
         // This is a synchronous request, so we should wait for our request to complete.
         GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
         GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
-
-        {
-            KScopedAutoObject session =
-                kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
-            R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
-            LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
-            session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(),
-                                     system.CoreTiming());
-        }
+        session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
     }
 
     return thread->GetWaitResult();