Index: kernel/generic/include/time/timeout.h
===================================================================
--- kernel/generic/include/time/timeout.h	(revision 78acbc721cee3d7063c5c7c8adbf897587243cb1)
+++ kernel/generic/include/time/timeout.h	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
@@ -53,4 +53,6 @@
 	/** On which processor is this timeout registered. */
 	cpu_t *cpu;
+	/** Used to synchronize with the handler callback. */
+	atomic_bool finished;
 } timeout_t;
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 78acbc721cee3d7063c5c7c8adbf897587243cb1)
+++ kernel/generic/src/time/clock.c	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
@@ -168,8 +168,12 @@
 		timeout_handler_t handler = timeout->handler;
 		void *arg = timeout->arg;
+		atomic_bool *finished = &timeout->finished;
 
 		irq_spinlock_unlock(&CPU->timeoutlock, false);
 
 		handler(arg);
+
+		/* Signal that the handler is finished. */
+		atomic_store_explicit(finished, true, memory_order_release);
 
 		irq_spinlock_lock(&CPU->timeoutlock, false);
Index: kernel/generic/src/time/timeout.c
===================================================================
--- kernel/generic/src/time/timeout.c	(revision 78acbc721cee3d7063c5c7c8adbf897587243cb1)
+++ kernel/generic/src/time/timeout.c	(revision ba25c4bbca58a62473323b0e9c57e9cb14bcbf5a)
@@ -90,8 +90,11 @@
 	assert(!link_in_use(&timeout->link));
 
-	timeout->cpu = CPU;
-	timeout->deadline = CPU->current_clock_tick + us2ticks(time);
-	timeout->handler = handler;
-	timeout->arg = arg;
+	*timeout = (timeout_t) {
+		.cpu = CPU,
+		.deadline = CPU->current_clock_tick + us2ticks(time),
+		.handler = handler,
+		.arg = arg,
+		.finished = ATOMIC_VAR_INIT(false),
+	};
 
 	/* Insert timeout into the active timeouts list according to timeout->deadline. */
@@ -135,4 +138,11 @@
 
 	irq_spinlock_unlock(&timeout->cpu->timeoutlock, true);
+
+	if (!success) {
+		/* Timeout was fired, we need to wait for the callback to finish. */
+		while (!atomic_load_explicit(&timeout->finished, memory_order_acquire))
+			cpu_spin_hint();
+	}
+
 	return success;
 }
