summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2021-07-14 11:38:20 -0600
committerRaul Rangel <rrangel@chromium.org>2021-07-18 15:14:00 +0000
commita98d302fe9dcce13a1c60b4bdfaf2e713fd11b51 (patch)
tree88354526393b35f6e3a598ba61c90b9a7521d01e
parent9ba36abdc542b881df7e0f0c5883a9dab1b9bc50 (diff)
downloadcoreboot-a98d302fe9dcce13a1c60b4bdfaf2e713fd11b51.tar.gz
coreboot-a98d302fe9dcce13a1c60b4bdfaf2e713fd11b51.tar.bz2
coreboot-a98d302fe9dcce13a1c60b4bdfaf2e713fd11b51.zip
x86/smp/spinlock: Disable thread coop when taking spinlock
Switching threads while holding a spinlock can lead to a deadlock. This happens if you have two thread trying to print to the serial console because the uart code uses udelay. BUG=b:179699789 TEST=Boot guybrush and no longer see a deadlock when printing to console from a second thread. Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: I1b929070b7f175965d4f37be693462fef26be052 Reviewed-on: https://review.coreboot.org/c/coreboot/+/56320 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Furquan Shaikh <furquan@google.com> Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
-rw-r--r--src/arch/x86/include/arch/smp/spinlock.h8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/arch/x86/include/arch/smp/spinlock.h b/src/arch/x86/include/arch/smp/spinlock.h
index 799ac2c8b814..0c06c22bbaf3 100644
--- a/src/arch/x86/include/arch/smp/spinlock.h
+++ b/src/arch/x86/include/arch/smp/spinlock.h
@@ -3,6 +3,8 @@
#ifndef ARCH_SMP_SPINLOCK_H
#define ARCH_SMP_SPINLOCK_H
+#include <thread.h>
+
/*
* Your basic SMP spinlocks, allowing only a single CPU anywhere
*/
@@ -54,10 +56,16 @@ static __always_inline void spin_lock(spinlock_t *lock)
__asm__ __volatile__(
spin_lock_string
: "=m" (lock->lock) : : "memory");
+
+ /* Switching contexts while holding a spinlock will lead to deadlocks */
+ thread_coop_disable();
+
}
static __always_inline void spin_unlock(spinlock_t *lock)
{
+ thread_coop_enable();
+
__asm__ __volatile__(
spin_unlock_string
: "=m" (lock->lock) : : "memory");