From 282cd3e5fe1ffe01d1ab008ef6b2a15266708d24 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Mon, 17 Oct 2022 00:01:50 -0400
Subject: [PATCH] kernel: fix slab heap ABA

---
 src/core/hle/kernel/k_slab_heap.h | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h
index 2b303537e..a8c77a7d4 100644
--- a/src/core/hle/kernel/k_slab_heap.h
+++ b/src/core/hle/kernel/k_slab_heap.h
@@ -8,6 +8,7 @@
 #include "common/assert.h"
 #include "common/common_funcs.h"
 #include "common/common_types.h"
+#include "common/spin_lock.h"
 
 namespace Kernel {
 
@@ -36,28 +37,34 @@ public:
     }
 
     void* Allocate() {
-        Node* ret = m_head.load();
+        // KScopedInterruptDisable di;
 
-        do {
-            if (ret == nullptr) {
-                break;
-            }
-        } while (!m_head.compare_exchange_weak(ret, ret->next));
+        m_lock.lock();
 
+        Node* ret = m_head;
+        if (ret != nullptr) [[likely]] {
+            m_head = ret->next;
+        }
+
+        m_lock.unlock();
         return ret;
     }
 
     void Free(void* obj) {
-        Node* node = static_cast<Node*>(obj);
+        // KScopedInterruptDisable di;
 
-        Node* cur_head = m_head.load();
-        do {
-            node->next = cur_head;
-        } while (!m_head.compare_exchange_weak(cur_head, node));
+        m_lock.lock();
+
+        Node* node = static_cast<Node*>(obj);
+        node->next = m_head;
+        m_head = node;
+
+        m_lock.unlock();
     }
 
 private:
     std::atomic<Node*> m_head{};
+    Common::SpinLock m_lock;
 };
 
 } // namespace impl