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>
This commit is contained in:
Raul E Rangel 2021-07-14 11:38:20 -06:00 committed by Raul Rangel
parent 9ba36abdc5
commit a98d302fe9
1 changed files with 8 additions and 0 deletions

View File

@ -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");