Skip to content

Commit b15a0fa

Browse files
committed
lk_cmpxchg: do not use a hard-coded temp register when using LSE
__cmpxchg_case_##name hard-coded x30 as a temp register, but the compiler flags did not exclude the use of x30. This has been causing heisenbugs when LSE was in use.
1 parent c6fd724 commit b15a0fa

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

ext/linux/include/lk_cmpxchg.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,25 +223,28 @@ __CMPXCHG_CASE( , , mb_8, dmb ish, , l, "memory")
223223

224224
#define __LSE_CMPXCHG_CASE(w, sz, name, mb, cl...) \
225225
static inline unsigned long __cmpxchg_case_##name(volatile void *ptr, \
226-
unsigned long old, \
227-
unsigned long new) \
226+
unsigned long old, \
227+
unsigned long new) \
228228
{ \
229229
register unsigned long x0 asm ("x0") = (unsigned long)ptr; \
230230
register unsigned long x1 asm ("x1") = old; \
231231
register unsigned long x2 asm ("x2") = new; \
232+
unsigned long tmp; \
232233
\
233234
asm volatile( \
234235
/* LSE atomics */ \
235-
" mov " #w "30, %" #w "[old]\n" \
236-
" cas" #mb #sz "\t" #w "30, %" #w "[new], %[v]\n" \
237-
" mov %" #w "[ret], " #w "30" \
238-
: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr) \
236+
" mov %" #w "[tmp], %" #w "[old]\n" \
237+
" cas" #mb #sz "\t%" #w "[tmp], %" #w "[new], %[v]\n" \
238+
" mov %" #w "[ret], %" #w "[tmp]" \
239+
: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr), \
240+
[tmp] "=&r" (tmp) \
239241
: [old] "r" (x1), [new] "r" (x2) \
240242
: cl); \
241243
\
242244
return x0; \
243245
}
244246

247+
// w sz name mb cl
245248
__LSE_CMPXCHG_CASE(w, b, 1, )
246249
__LSE_CMPXCHG_CASE(w, h, 2, )
247250
__LSE_CMPXCHG_CASE(w, , 4, )

0 commit comments

Comments
 (0)