aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2016-06-08 10:10:57 -0400
committerWill Deacon <will.deacon@arm.com>2016-06-15 04:51:36 -0400
commit3a5facd09da848193f5bcb0dea098a298bc1a29d (patch)
tree179c031fe6a5e8d9ce4b27ea966a2e09356bf847
parent38b850a73034f075c4088e7511b36ebbef9dce00 (diff)
arm64: spinlock: fix spin_unlock_wait for LSE atomics
Commit d86b8da04dfa ("arm64: spinlock: serialise spin_unlock_wait against concurrent lockers") fixed spin_unlock_wait for LL/SC-based atomics under the premise that the LSE atomics (in particular, the LDADDA instruction) are indivisible. Unfortunately, these instructions are only indivisible when used with the -AL (full ordering) suffix and, consequently, the same issue can theoretically be observed with LSE atomics, where a later (in program order) load can be speculated before the write portion of the atomic operation. This patch fixes the issue by performing a CAS of the lock once we've established that it's unlocked, in much the same way as the LL/SC code. Fixes: d86b8da04dfa ("arm64: spinlock: serialise spin_unlock_wait against concurrent lockers") Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/include/asm/spinlock.h10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h
index aac64d55cb22..d5c894253e73 100644
--- a/arch/arm64/include/asm/spinlock.h
+++ b/arch/arm64/include/asm/spinlock.h
@@ -43,13 +43,17 @@ static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
43"2: ldaxr %w0, %2\n" 43"2: ldaxr %w0, %2\n"
44" eor %w1, %w0, %w0, ror #16\n" 44" eor %w1, %w0, %w0, ror #16\n"
45" cbnz %w1, 1b\n" 45" cbnz %w1, 1b\n"
46 /* Serialise against any concurrent lockers */
46 ARM64_LSE_ATOMIC_INSN( 47 ARM64_LSE_ATOMIC_INSN(
47 /* LL/SC */ 48 /* LL/SC */
48" stxr %w1, %w0, %2\n" 49" stxr %w1, %w0, %2\n"
49" cbnz %w1, 2b\n", /* Serialise against any concurrent lockers */
50 /* LSE atomics */
51" nop\n" 50" nop\n"
52" nop\n") 51" nop\n",
52 /* LSE atomics */
53" mov %w1, %w0\n"
54" cas %w0, %w0, %2\n"
55" eor %w1, %w1, %w0\n")
56" cbnz %w1, 2b\n"
53 : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) 57 : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock)
54 : 58 :
55 : "memory"); 59 : "memory");