diff options
| author | Manish Pandey <manish.pandey2@arm.com> | 2026-01-07 11:36:34 +0000 |
|---|---|---|
| committer | TrustedFirmware Code Review <review@review.trustedfirmware.org> | 2026-01-07 11:36:34 +0000 |
| commit | e9730867dbee4620e1af008e224108b1f2265ac0 (patch) | |
| tree | 0cdb7d6f1b17bf32e778192547d212d7c59fcfd4 | |
| parent | f6f91f71c96c24f1d38bc9d46e98867260646a9d (diff) | |
| parent | 07ba153fda3b31d515f0adc0b9d7991174bf7997 (diff) | |
| download | arm-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.h | 1 | ||||
| -rw-r--r-- | lib/locks/exclusive/aarch64/spinlock.c | 42 |
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; + } + } } /* |
