diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 8dae78397..f40cf92b1 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -113,7 +113,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) {
         // Remove waiter thread.
         bool has_waiters{};
         KThread* const next_owner_thread =
-            owner_thread->RemoveWaiterByKey(std::addressof(has_waiters), addr);
+            owner_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
 
         // Determine the next tag.
         u32 next_value{};
@@ -283,7 +283,7 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) {
             // Remove waiter thread.
             bool has_waiters{};
             KThread* next_owner_thread =
-                cur_thread->RemoveWaiterByKey(std::addressof(has_waiters), addr);
+                cur_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
 
             // Update for the next owner thread.
             u32 next_value{};
diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp
index b922a67a5..14cb615da 100644
--- a/src/core/hle/kernel/k_light_lock.cpp
+++ b/src/core/hle/kernel/k_light_lock.cpp
@@ -91,7 +91,7 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) {
 
         // Get the next owner.
         bool has_waiters;
-        KThread* next_owner = owner_thread->RemoveWaiterByKey(
+        KThread* next_owner = owner_thread->RemoveKernelWaiterByKey(
             std::addressof(has_waiters), reinterpret_cast<uintptr_t>(std::addressof(tag)));
 
         // Pass the lock to the next owner.
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 514f20ef4..d44f6e921 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -157,7 +157,7 @@ bool KProcess::ReleaseUserException(KThread* thread) {
 
         // Remove waiter thread.
         bool has_waiters{};
-        if (KThread* next = thread->RemoveWaiterByKey(
+        if (KThread* next = thread->RemoveKernelWaiterByKey(
                 std::addressof(has_waiters),
                 reinterpret_cast<uintptr_t>(std::addressof(exception_thread)));
             next != nullptr) {
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 2831df733..8c403f5fd 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -933,12 +933,14 @@ void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) {
     held_lock_info_list.push_front(*lock_info);
 }
 
-KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key_) {
+KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(VAddr address_key_,
+                                                                bool is_kernel_address_key_) {
     ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
 
     // Try to find an existing held lock.
     for (auto& held_lock : held_lock_info_list) {
-        if (held_lock.GetAddressKey() == address_key_) {
+        if (held_lock.GetAddressKey() == address_key_ &&
+            held_lock.GetIsKernelAddressKey() == is_kernel_address_key_) {
             return std::addressof(held_lock);
         }
     }
@@ -961,7 +963,7 @@ void KThread::AddWaiterImpl(KThread* thread) {
     }
 
     // Get the relevant lock info.
-    auto* lock_info = this->FindHeldLock(address_key_);
+    auto* lock_info = this->FindHeldLock(address_key_, is_kernel_address_key_);
     if (lock_info == nullptr) {
         // Create a new lock for the address key.
         lock_info =
@@ -1067,11 +1069,11 @@ void KThread::RemoveWaiter(KThread* thread) {
     }
 }
 
-KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key) {
+KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, VAddr key, bool is_kernel_address_key_) {
     ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
 
     // Get the relevant lock info.
-    auto* lock_info = this->FindHeldLock(key);
+    auto* lock_info = this->FindHeldLock(key, is_kernel_address_key_);
     if (lock_info == nullptr) {
         *out_has_waiters = false;
         return nullptr;
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index e09dcbea0..bd125f5f1 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -595,7 +595,13 @@ public:
 
     [[nodiscard]] Result GetThreadContext3(std::vector<u8>& out);
 
-    [[nodiscard]] KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key);
+    [[nodiscard]] KThread* RemoveUserWaiterByKey(bool* out_has_waiters, VAddr key) {
+        return this->RemoveWaiterByKey(out_has_waiters, key, false);
+    }
+
+    [[nodiscard]] KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, VAddr key) {
+        return this->RemoveWaiterByKey(out_has_waiters, key, true);
+    }
 
     [[nodiscard]] VAddr GetAddressKey() const {
         return address_key;
@@ -666,6 +672,9 @@ public:
     }
 
 private:
+    [[nodiscard]] KThread* RemoveWaiterByKey(bool* out_has_waiters, VAddr key,
+                                             bool is_kernel_address_key);
+
     static constexpr size_t PriorityInheritanceCountMax = 10;
     union SyncObjectBuffer {
         std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> sync_objects{};
@@ -850,7 +859,7 @@ public:
     }
 
     void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info);
-    LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key);
+    LockWithPriorityInheritanceInfo* FindHeldLock(VAddr address_key, bool is_kernel_address_key);
 
 private:
     using LockWithPriorityInheritanceInfoList =
@@ -926,6 +935,7 @@ public:
         condvar_key = cv_key;
         address_key = address;
         address_key_value = value;
+        is_kernel_address_key = false;
     }
 
     void ClearConditionVariable() {