summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@sifive.com>2019-09-24 20:30:15 -0700
committerRich Felker <dalias@aerifal.cx>2019-09-25 13:11:48 -0400
commit7d5c5706a0e1d2f4019a92e1a869d71d552bbb49 (patch)
tree24b64b53c59cc8c5cde0e675467427d77cbe88e0 /arch
parentf5eee489f7662b08ad1bba4b1267e34eb9565bba (diff)
downloadmusl-7d5c5706a0e1d2f4019a92e1a869d71d552bbb49.tar.gz
correct the operand specifiers in the riscv64 CAS routines
The operand sepcifiers in a_cas and a_cas_p for riscv64 were incorrect: there's a backwards branch in the routine, so despite tmp being written at the end of the assembly fragment it cannot be allocated in one of the input registers because the input values may be needed for another trip around the loop. For code that follows the guaranteed forward progress requirements, the backwards branch is rarely taken: SiFive's hardware only fails a store conditional on execptional cases (ie, instruction cache misses inside the loop), and until recently a bug in QEMU allowed back-to-back store conditionals to succeed. The bug has been fixed in the latest QEMU release, but it turns out that the fix caused this latent bug in musl to manifest.
Diffstat (limited to 'arch')
-rw-r--r--arch/riscv64/atomic_arch.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/riscv64/atomic_arch.h b/arch/riscv64/atomic_arch.h
index c9765342..41ad4d04 100644
--- a/arch/riscv64/atomic_arch.h
+++ b/arch/riscv64/atomic_arch.h
@@ -14,7 +14,7 @@ static inline int a_cas(volatile int *p, int t, int s)
" sc.w.aqrl %1, %4, (%2)\n"
" bnez %1, 1b\n"
"1:"
- : "=&r"(old), "=r"(tmp)
+ : "=&r"(old), "=&r"(tmp)
: "r"(p), "r"(t), "r"(s)
: "memory");
return old;
@@ -31,7 +31,7 @@ static inline void *a_cas_p(volatile void *p, void *t, void *s)
" sc.d.aqrl %1, %4, (%2)\n"
" bnez %1, 1b\n"
"1:"
- : "=&r"(old), "=r"(tmp)
+ : "=&r"(old), "=&r"(tmp)
: "r"(p), "r"(t), "r"(s)
: "memory");
return old;