Skip to content

Commit 54280ca

Browse files
Leonardo Braspalmer-dabbelt
authored andcommitted
riscv/cmpxchg: Implement cmpxchg for variables of size 1 and 2
cmpxchg for variables of size 1-byte and 2-bytes is not yet available for riscv, even though its present in other architectures such as arm64 and x86. This could lead to not being able to implement some locking mechanisms or requiring some rework to make it work properly. Implement 1-byte and 2-bytes cmpxchg in order to achieve parity with other architectures. Signed-off-by: Leonardo Bras <leobras@redhat.com> Tested-by: Guo Ren <guoren@kernel.org> Link: https://lore.kernel.org/r/20240103163203.72768-6-leobras@redhat.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 9061237 commit 54280ca

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

arch/riscv/include/asm/cmpxchg.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,35 @@
7272
* indicated by comparing RETURN with OLD.
7373
*/
7474

75+
#define __arch_cmpxchg_masked(sc_sfx, prepend, append, r, p, o, n) \
76+
({ \
77+
u32 *__ptr32b = (u32 *)((ulong)(p) & ~0x3); \
78+
ulong __s = ((ulong)(p) & (0x4 - sizeof(*p))) * BITS_PER_BYTE; \
79+
ulong __mask = GENMASK(((sizeof(*p)) * BITS_PER_BYTE) - 1, 0) \
80+
<< __s; \
81+
ulong __newx = (ulong)(n) << __s; \
82+
ulong __oldx = (ulong)(o) << __s; \
83+
ulong __retx; \
84+
ulong __rc; \
85+
\
86+
__asm__ __volatile__ ( \
87+
prepend \
88+
"0: lr.w %0, %2\n" \
89+
" and %1, %0, %z5\n" \
90+
" bne %1, %z3, 1f\n" \
91+
" and %1, %0, %z6\n" \
92+
" or %1, %1, %z4\n" \
93+
" sc.w" sc_sfx " %1, %1, %2\n" \
94+
" bnez %1, 0b\n" \
95+
append \
96+
"1:\n" \
97+
: "=&r" (__retx), "=&r" (__rc), "+A" (*(__ptr32b)) \
98+
: "rJ" ((long)__oldx), "rJ" (__newx), \
99+
"rJ" (__mask), "rJ" (~__mask) \
100+
: "memory"); \
101+
\
102+
r = (__typeof__(*(p)))((__retx & __mask) >> __s); \
103+
})
75104

76105
#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \
77106
({ \
@@ -98,6 +127,11 @@
98127
__typeof__(*(__ptr)) __ret; \
99128
\
100129
switch (sizeof(*__ptr)) { \
130+
case 1: \
131+
case 2: \
132+
__arch_cmpxchg_masked(sc_sfx, prepend, append, \
133+
__ret, __ptr, __old, __new); \
134+
break; \
101135
case 4: \
102136
__arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \
103137
__ret, __ptr, (long), __old, __new); \

0 commit comments

Comments
 (0)