Index: kernel/generic/src/synch/irq_spinlock.c
===================================================================
--- kernel/generic/src/synch/irq_spinlock.c	(revision 2b264c4d5e2f74497c27c64df3d210b4b1899af2)
+++ kernel/generic/src/synch/irq_spinlock.c	(revision b076dfbb9aa63d562c009d67d8e9dd2d06e4b795)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2001-2004 Jakub Jermar
+ * Copyright (c) 2023 Jiří Zárevúcky
  * All rights reserved.
  *
@@ -39,4 +40,55 @@
 #include <synch/spinlock.h>
 
+#include <cpu.h>
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+
+#define CPU_OWNER ((CPU == NULL) ? (cpu_t *) UINTPTR_MAX : CPU)
+
+static inline bool owned_by_me(irq_spinlock_t *lock)
+{
+	return atomic_load_explicit(&lock->owner, memory_order_relaxed) == CPU_OWNER;
+}
+
+static inline bool not_owned_by_me(irq_spinlock_t *lock)
+{
+	return !owned_by_me(lock);
+}
+
+static inline void claim(irq_spinlock_t *lock)
+{
+	cpu_t *cpu = CPU_OWNER;
+	atomic_store_explicit(&lock->owner, cpu, memory_order_relaxed);
+	CURRENT->mutex_locks++;
+}
+
+static inline void unclaim(irq_spinlock_t *lock)
+{
+	CURRENT->mutex_locks--;
+	atomic_store_explicit(&lock->owner, NULL, memory_order_relaxed);
+}
+
+#else
+
+static inline bool owned_by_me(irq_spinlock_t *lock)
+{
+	return true;
+}
+
+static inline bool not_owned_by_me(irq_spinlock_t *lock)
+{
+	return true;
+}
+
+static inline void claim(irq_spinlock_t *lock)
+{
+}
+
+static inline void unclaim(irq_spinlock_t *lock)
+{
+}
+
+#endif
+
 /** Initialize interrupts-disabled spinlock
  *
@@ -47,7 +99,5 @@
 void irq_spinlock_initialize(irq_spinlock_t *lock, const char *name)
 {
-	spinlock_initialize(&(lock->lock), name);
-	lock->guard = false;
-	lock->ipl = 0;
+	*lock = (irq_spinlock_t) IRQ_SPINLOCK_INITIALIZER(name);
 }
 
@@ -63,4 +113,6 @@
 void irq_spinlock_lock(irq_spinlock_t *lock, bool irq_dis)
 {
+	ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
+
 	if (irq_dis) {
 		ipl_t ipl = interrupts_disable();
@@ -75,4 +127,6 @@
 		ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
 	}
+
+	claim(lock);
 }
 
@@ -89,4 +143,7 @@
 {
 	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
+	ASSERT_IRQ_SPINLOCK(owned_by_me(lock), lock);
+
+	unclaim(lock);
 
 	if (irq_res) {
@@ -119,4 +176,6 @@
 	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), lock);
 	bool ret = spinlock_trylock(&(lock->lock));
+	if (ret)
+		claim(lock);
 
 	ASSERT_IRQ_SPINLOCK((!ret) || (!lock->guard), lock);
@@ -138,4 +197,6 @@
 {
 	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
+	ASSERT_IRQ_SPINLOCK(owned_by_me(unlock), unlock);
+	ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
 
 	/* Pass guard from unlock to lock */
@@ -144,6 +205,10 @@
 	unlock->guard = false;
 
+	unclaim(unlock);
+
 	spinlock_unlock(&(unlock->lock));
 	spinlock_lock(&(lock->lock));
+
+	claim(lock);
 
 	ASSERT_IRQ_SPINLOCK(!lock->guard, lock);
@@ -169,4 +234,6 @@
 {
 	ASSERT_IRQ_SPINLOCK(interrupts_disabled(), unlock);
+	ASSERT_IRQ_SPINLOCK(owned_by_me(unlock), unlock);
+	ASSERT_IRQ_SPINLOCK(not_owned_by_me(lock), lock);
 
 	spinlock_lock(&(lock->lock));
@@ -180,4 +247,7 @@
 	}
 
+	claim(lock);
+	unclaim(unlock);
+
 	spinlock_unlock(&(unlock->lock));
 }
@@ -188,7 +258,7 @@
  * @return		True if the IRQ spinlock is locked, false otherwise.
  */
-bool irq_spinlock_locked(irq_spinlock_t *ilock)
-{
-	return spinlock_locked(&ilock->lock);
+bool irq_spinlock_locked(irq_spinlock_t *lock)
+{
+	return owned_by_me(lock) && spinlock_locked(&lock->lock);
 }
 
