From 017a8eea4f04b7ca69fa11a5d1f8d03153feb368 Mon Sep 17 00:00:00 2001 From: Daniel Leung Date: Mon, 6 Jan 2020 17:27:27 -0800 Subject: [PATCH] xtensa: fix atomic_cas reporting value swapped even when not The atomic_cas function was using incorrect register when determining whether value was swapped. The swapping instruction s32c1i in atomic_cas stores the value at memory location in register a4 regardless of whether swapping is done. In this case, the register a4 should be used to determine whether a swap is done. However, register a3 (containing the oldValue as function argument) is used instead. Since register a5 contains the old value at address loaded before the swapping instruction, a3 and a5 contain the same value. Since a3 == a5 is always true in this case, the function will always return 1 even though values are not swapped. So fix it by using the correct register. Also, in case the value is not swapped, it jumps to where it returns zero instead of loading from memory and comparing again. The function was simply looping until swapping was done, which did not align with the API where it would return 0 when swapping is not done (regardless whether the memory location contains the old value or not). Signed-off-by: Daniel Leung --- arch/xtensa/core/atomic.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/core/atomic.S b/arch/xtensa/core/atomic.S index ff93314cb67..13082bb1c54 100644 --- a/arch/xtensa/core/atomic.S +++ b/arch/xtensa/core/atomic.S @@ -391,15 +391,15 @@ atomic_xor: .align 4 atomic_cas: ENTRY(48) -.L_LoopCas: l32ai a5, a2, 0 - beq a5, a3, 1f - movi a2, 0 - j 2f + beq a5, a3, 2f 1: + movi a2, 0 + j 3f +2: wsr a5, scompare1 s32c1i a4, a2, 0 - bne a3, a5, .L_LoopCas + bne a4, a5, 1b movi a2, 1 -2: +3: RET(48)