Skip to content

Commit 38acdee

Browse files
Alexandre Ghitipalmer-dabbelt
authored andcommitted
riscv: Implement cmpxchg32/64() using Zacas
This adds runtime support for Zacas in cmpxchg operations. Signed-off-by: Alexandre Ghiti <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Reviewed-by: Andrea Parri <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent af042c4 commit 38acdee

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

arch/riscv/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,22 @@ config RISCV_ISA_ZAWRS
632632
use of these instructions in the kernel when the Zawrs extension is
633633
detected at boot.
634634

635+
config TOOLCHAIN_HAS_ZACAS
636+
bool
637+
default y
638+
depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64ima_zacas)
639+
depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32ima_zacas)
640+
depends on AS_HAS_OPTION_ARCH
641+
642+
config RISCV_ISA_ZACAS
643+
bool "Zacas extension support for atomic CAS"
644+
depends on TOOLCHAIN_HAS_ZACAS
645+
depends on RISCV_ALTERNATIVE
646+
default y
647+
help
648+
Enable the use of the Zacas ISA-extension to implement kernel atomic
649+
cmpxchg operations when it is detected at boot.
650+
635651
If you don't know what to do here, say Y.
636652

637653
config TOOLCHAIN_HAS_ZBB

arch/riscv/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ else
8282
riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
8383
endif
8484

85+
# Check if the toolchain supports Zacas
86+
riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
87+
8588
# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
8689
# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
8790
KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')

arch/riscv/include/asm/cmpxchg.h

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <asm/fence.h>
1313
#include <asm/hwcap.h>
1414
#include <asm/insn-def.h>
15+
#include <asm/cpufeature-macros.h>
1516

1617
#define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n) \
1718
({ \
@@ -137,24 +138,37 @@
137138
r = (__typeof__(*(p)))((__retx & __mask) >> __s); \
138139
})
139140

140-
#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \
141+
#define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n) \
141142
({ \
142-
register unsigned int __rc; \
143+
if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) && \
144+
riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) { \
145+
r = o; \
143146
\
144-
__asm__ __volatile__ ( \
145-
prepend \
146-
"0: lr" lr_sfx " %0, %2\n" \
147-
" bne %0, %z3, 1f\n" \
148-
" sc" sc_sfx " %1, %z4, %2\n" \
149-
" bnez %1, 0b\n" \
150-
append \
151-
"1:\n" \
152-
: "=&r" (r), "=&r" (__rc), "+A" (*(p)) \
153-
: "rJ" (co o), "rJ" (n) \
154-
: "memory"); \
147+
__asm__ __volatile__ ( \
148+
prepend \
149+
" amocas" sc_cas_sfx " %0, %z2, %1\n" \
150+
append \
151+
: "+&r" (r), "+A" (*(p)) \
152+
: "rJ" (n) \
153+
: "memory"); \
154+
} else { \
155+
register unsigned int __rc; \
156+
\
157+
__asm__ __volatile__ ( \
158+
prepend \
159+
"0: lr" lr_sfx " %0, %2\n" \
160+
" bne %0, %z3, 1f\n" \
161+
" sc" sc_cas_sfx " %1, %z4, %2\n" \
162+
" bnez %1, 0b\n" \
163+
append \
164+
"1:\n" \
165+
: "=&r" (r), "=&r" (__rc), "+A" (*(p)) \
166+
: "rJ" (co o), "rJ" (n) \
167+
: "memory"); \
168+
} \
155169
})
156170

157-
#define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append) \
171+
#define _arch_cmpxchg(ptr, old, new, sc_cas_sfx, prepend, append) \
158172
({ \
159173
__typeof__(ptr) __ptr = (ptr); \
160174
__typeof__(*(__ptr)) __old = (old); \
@@ -164,15 +178,15 @@
164178
switch (sizeof(*__ptr)) { \
165179
case 1: \
166180
case 2: \
167-
__arch_cmpxchg_masked(sc_sfx, prepend, append, \
181+
__arch_cmpxchg_masked(sc_cas_sfx, prepend, append, \
168182
__ret, __ptr, __old, __new); \
169183
break; \
170184
case 4: \
171-
__arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \
185+
__arch_cmpxchg(".w", ".w" sc_cas_sfx, prepend, append, \
172186
__ret, __ptr, (long), __old, __new); \
173187
break; \
174188
case 8: \
175-
__arch_cmpxchg(".d", ".d" sc_sfx, prepend, append, \
189+
__arch_cmpxchg(".d", ".d" sc_cas_sfx, prepend, append, \
176190
__ret, __ptr, /**/, __old, __new); \
177191
break; \
178192
default: \

0 commit comments

Comments
 (0)