diff --git a/src/core/core.cpp b/src/core/core.cpp
index 1d6179a80e..5d4ecdce5a 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -467,6 +467,14 @@ const Kernel::Scheduler& System::CurrentScheduler() const {
     return impl->CurrentPhysicalCore().Scheduler();
 }
 
+Kernel::PhysicalCore& System::CurrentPhysicalCore() {
+    return impl->CurrentPhysicalCore();
+}
+
+const Kernel::PhysicalCore& System::CurrentPhysicalCore() const {
+    return impl->CurrentPhysicalCore();
+}
+
 Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
     return impl->GetPhysicalCore(core_index).Scheduler();
 }
diff --git a/src/core/core.h b/src/core/core.h
index 7f170fc54e..9a0dd10753 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -27,6 +27,7 @@ class VfsFilesystem;
 namespace Kernel {
 class GlobalScheduler;
 class KernelCore;
+class PhysicalCore;
 class Process;
 class Scheduler;
 } // namespace Kernel
@@ -211,6 +212,12 @@ public:
     /// Gets the scheduler for the CPU core that is currently running
     const Kernel::Scheduler& CurrentScheduler() const;
 
+    /// Gets the physical core for the CPU core that is currently running
+    Kernel::PhysicalCore& CurrentPhysicalCore();
+
+    /// Gets the physical core for the CPU core that is currently running
+    const Kernel::PhysicalCore& CurrentPhysicalCore() const;
+
     /// Gets a reference to an ARM interface for the CPU core with the specified index
     ARM_Interface& ArmInterface(std::size_t core_index);
 
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index dfb032b4b6..2a218e2942 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -27,6 +27,7 @@
 #include "core/hle/kernel/memory/memory_block.h"
 #include "core/hle/kernel/memory/page_table.h"
 #include "core/hle/kernel/mutex.h"
+#include "core/hle/kernel/physical_core.h"
 #include "core/hle/kernel/process.h"
 #include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/resource_limit.h"
@@ -1071,6 +1072,7 @@ static ResultCode GetThreadPriority(Core::System& system, u32* priority, Handle
     const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
     const std::shared_ptr<Thread> thread = handle_table.Get<Thread>(handle);
     if (!thread) {
+        *priority = 0;
         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", handle);
         return ERR_INVALID_HANDLE;
     }
@@ -1105,14 +1107,13 @@ static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 pri
 
     thread->SetPriority(priority);
 
-    system.PrepareReschedule(thread->GetProcessorID());
     return RESULT_SUCCESS;
 }
 
 /// Get which CPU core is executing the current thread
 static u32 GetCurrentProcessorNumber(Core::System& system) {
     LOG_TRACE(Kernel_SVC, "called");
-    return system.CurrentScheduler().GetCurrentThread()->GetProcessorID();
+    return static_cast<u32>(system.CurrentPhysicalCore().CoreIndex());
 }
 
 static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr,
@@ -1430,8 +1431,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e
 
     ThreadType type = THREADTYPE_USER;
     CASCADE_RESULT(std::shared_ptr<Thread> thread,
-                   Thread::Create(system, type, "", entry_point, priority, arg, processor_id, stack_top,
-                                  current_process));
+                   Thread::Create(system, type, "", entry_point, priority, arg, processor_id,
+                                  stack_top, current_process));
 
     const auto new_thread_handle = current_process->GetHandleTable().Create(thread);
     if (new_thread_handle.Failed()) {
@@ -1804,6 +1805,8 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle,
     if (!thread) {
         LOG_ERROR(Kernel_SVC, "Thread handle does not exist, thread_handle=0x{:08X}",
                   thread_handle);
+        *core = 0;
+        *mask = 0;
         return ERR_INVALID_HANDLE;
     }
 
@@ -1866,11 +1869,7 @@ static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle,
         return ERR_INVALID_HANDLE;
     }
 
-    system.PrepareReschedule(thread->GetProcessorID());
-    thread->ChangeCore(core, affinity_mask);
-    system.PrepareReschedule(thread->GetProcessorID());
-
-    return RESULT_SUCCESS;
+    return thread->SetCoreAndAffinityMask(core, affinity_mask);
 }
 
 static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index d9e6102722..e6bb7c6663 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -250,6 +250,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
 }
 
 void Thread::SetPriority(u32 priority) {
+    SchedulerLock lock(kernel);
     ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST,
                "Invalid priority value.");
     nominal_priority = priority;
@@ -383,10 +384,6 @@ void Thread::UpdatePriority() {
     lock_owner->UpdatePriority();
 }
 
-void Thread::ChangeCore(u32 core, u64 mask) {
-    SetCoreAndAffinityMask(core, mask);
-}
-
 bool Thread::AllSynchronizationObjectsReady() const {
     return std::none_of(wait_objects.begin(), wait_objects.end(),
                         [this](const std::shared_ptr<SynchronizationObject>& object) {
@@ -467,6 +464,7 @@ void Thread::SetCurrentPriority(u32 new_priority) {
 }
 
 ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
+    SchedulerLock lock(kernel);
     const auto HighestSetCore = [](u64 mask, u32 max_cores) {
         for (s32 core = static_cast<s32>(max_cores - 1); core >= 0; core--) {
             if (((mask >> core) & 1) != 0) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 78a4357b00..29fe5483b4 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -221,7 +221,7 @@ public:
     void UpdatePriority();
 
     /// Changes the core that the thread is running or scheduled to run on.
-    void ChangeCore(u32 core, u64 mask);
+    ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
 
     /**
      * Gets the thread's thread ID
@@ -522,7 +522,6 @@ private:
 
     void SetSchedulingStatus(ThreadSchedStatus new_status);
     void SetCurrentPriority(u32 new_priority);
-    ResultCode SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask);
 
     void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);