summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Pandey <manish.pandey2@arm.com>2026-01-07 11:36:34 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2026-01-07 11:36:34 +0000
commite9730867dbee4620e1af008e224108b1f2265ac0 (patch)
tree0cdb7d6f1b17bf32e778192547d212d7c59fcfd4
parentf6f91f71c96c24f1d38bc9d46e98867260646a9d (diff)
parent07ba153fda3b31d515f0adc0b9d7991174bf7997 (diff)
downloadarm-trusted-firmware-e9730867dbee4620e1af008e224108b1f2265ac0.tar.gz
arm-trusted-firmware-e9730867dbee4620e1af008e224108b1f2265ac0.zip
Merge changes I1a57de22,If97ea5fd into integration
* changes: feat(locks): make spin_trylock with exclusives spin until it knows the state of the lock fix(locks): restore spin_trylock's ability to acquire a lock
-rw-r--r--include/lib/spinlock.h1
-rw-r--r--lib/locks/exclusive/aarch64/spinlock.c42
2 files changed, 28 insertions, 15 deletions
diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h
index 56d9b51a8..11826247e 100644
--- a/include/lib/spinlock.h
+++ b/include/lib/spinlock.h
@@ -26,6 +26,7 @@ void spin_unlock(spinlock_t *lock);
void bit_lock(bitlock_t *lock, uint8_t mask);
void bit_unlock(bitlock_t *lock, uint8_t mask);
+/* non-blocking spin_lock(). Returns whether the lock was acquired. */
bool spin_trylock(spinlock_t *lock);
#else
diff --git a/lib/locks/exclusive/aarch64/spinlock.c b/lib/locks/exclusive/aarch64/spinlock.c
index 20eec53f3..d568b57a4 100644
--- a/lib/locks/exclusive/aarch64/spinlock.c
+++ b/lib/locks/exclusive/aarch64/spinlock.c
@@ -94,21 +94,33 @@ static bool spin_trylock_atomic(volatile uint32_t *dst)
static bool spin_trylock_excl(volatile uint32_t *dst)
{
uint32_t src = 1;
- uint32_t tmp;
- bool out;
-
- __asm__ volatile (
- "ldaxr %w[tmp], [%[dst]]\n"
- "cbnz %w[tmp], 1f\n"
- "stxr %w[tmp], %w[src], [%[dst]]\n"
- "cbnz %w[tmp], 1f\n"
- "mov %w[out], #1\n"
- "1:\n" /* fail */
- "mov %w[out], #0\n"
- : "+m" (*dst), [tmp] "=&r" (tmp), [out] "=r" (out)
- : [src] "r" (src), [dst] "r" (dst));
-
- return out;
+ uint32_t ret;
+
+ /*
+ * Loop until we either get the lock or are certain that we don't have
+ * it. The exclusive store can fail due to racing and not because we
+ * don't hold the lock.
+ */
+ while (1) {
+ __asm__ volatile (
+ "ldaxr %w[ret], [%[dst]]\n"
+ : [ret] "=r" (ret)
+ : "m" (*dst), [dst] "r" (dst));
+
+ /* 1 means lock is held */
+ if (ret != 0) {
+ return false;
+ }
+
+ __asm__ volatile (
+ "stxr %w[ret], %w[src], [%[dst]]\n"
+ : "+m" (*dst), [ret] "=r" (ret)
+ : [src] "r" (src), [dst] "r" (dst));
+
+ if (ret == 0) {
+ return true;
+ }
+ }
}
/*