| From foo@baz Sun May 27 17:33:38 CEST 2018 |
| From: Will Deacon <will.deacon@arm.com> |
| Date: Wed, 31 Jan 2018 12:12:20 +0000 |
| Subject: arm64: spinlock: Fix theoretical trylock() A-B-A with LSE atomics |
| |
| From: Will Deacon <will.deacon@arm.com> |
| |
| [ Upstream commit 202fb4ef81e3ec765c23bd1e6746a5c25b797d0e ] |
| |
| If the spinlock "next" ticket wraps around between the initial LDR |
| and the cmpxchg in the LSE version of spin_trylock, then we can erroneously |
| think that we have successfuly acquired the lock because we only check |
| whether the next ticket return by the cmpxchg is equal to the owner ticket |
| in our updated lock word. |
| |
| This patch fixes the issue by performing a full 32-bit check of the lock |
| word when trying to determine whether or not the CASA instruction updated |
| memory. |
| |
| Reported-by: Catalin Marinas <catalin.marinas@arm.com> |
| Signed-off-by: Will Deacon <will.deacon@arm.com> |
| Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm64/include/asm/spinlock.h | 4 ++-- |
| 1 file changed, 2 insertions(+), 2 deletions(-) |
| |
| --- a/arch/arm64/include/asm/spinlock.h |
| +++ b/arch/arm64/include/asm/spinlock.h |
| @@ -141,8 +141,8 @@ static inline int arch_spin_trylock(arch |
| " cbnz %w1, 1f\n" |
| " add %w1, %w0, %3\n" |
| " casa %w0, %w1, %2\n" |
| - " and %w1, %w1, #0xffff\n" |
| - " eor %w1, %w1, %w0, lsr #16\n" |
| + " sub %w1, %w1, %3\n" |
| + " eor %w1, %w1, %w0\n" |
| "1:") |
| : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) |
| : "I" (1 << TICKET_SHIFT) |