Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv: Implement cmpxchg32/64() using Zacas

This adds runtime support for Zacas in cmpxchg operations.

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Andrea Parri <parri.andrea@gmail.com>
Link: https://lore.kernel.org/r/20241103145153.105097-4-alexghiti@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Alexandre Ghiti and committed by
Palmer Dabbelt
38acdee3 af042c45

+50 -17
+16
arch/riscv/Kconfig
··· 632 632 use of these instructions in the kernel when the Zawrs extension is 633 633 detected at boot. 634 634 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 + 635 651 If you don't know what to do here, say Y. 636 652 637 653 config TOOLCHAIN_HAS_ZBB
+3
arch/riscv/Makefile
··· 82 82 riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei 83 83 endif 84 84 85 + # Check if the toolchain supports Zacas 86 + riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas 87 + 85 88 # Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by 86 89 # matching non-v and non-multi-letter extensions out with the filter ([^v_]*) 87 90 KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
+31 -17
arch/riscv/include/asm/cmpxchg.h
··· 12 12 #include <asm/fence.h> 13 13 #include <asm/hwcap.h> 14 14 #include <asm/insn-def.h> 15 + #include <asm/cpufeature-macros.h> 15 16 16 17 #define __arch_xchg_masked(sc_sfx, prepend, append, r, p, n) \ 17 18 ({ \ ··· 138 137 r = (__typeof__(*(p)))((__retx & __mask) >> __s); \ 139 138 }) 140 139 141 - #define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \ 140 + #define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n) \ 142 141 ({ \ 143 - register unsigned int __rc; \ 142 + if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) && \ 143 + riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS)) { \ 144 + r = o; \ 144 145 \ 145 - __asm__ __volatile__ ( \ 146 - prepend \ 147 - "0: lr" lr_sfx " %0, %2\n" \ 148 - " bne %0, %z3, 1f\n" \ 149 - " sc" sc_sfx " %1, %z4, %2\n" \ 150 - " bnez %1, 0b\n" \ 151 - append \ 152 - "1:\n" \ 153 - : "=&r" (r), "=&r" (__rc), "+A" (*(p)) \ 154 - : "rJ" (co o), "rJ" (n) \ 155 - : "memory"); \ 146 + __asm__ __volatile__ ( \ 147 + prepend \ 148 + " amocas" sc_cas_sfx " %0, %z2, %1\n" \ 149 + append \ 150 + : "+&r" (r), "+A" (*(p)) \ 151 + : "rJ" (n) \ 152 + : "memory"); \ 153 + } else { \ 154 + register unsigned int __rc; \ 155 + \ 156 + __asm__ __volatile__ ( \ 157 + prepend \ 158 + "0: lr" lr_sfx " %0, %2\n" \ 159 + " bne %0, %z3, 1f\n" \ 160 + " sc" sc_cas_sfx " %1, %z4, %2\n" \ 161 + " bnez %1, 0b\n" \ 162 + append \ 163 + "1:\n" \ 164 + : "=&r" (r), "=&r" (__rc), "+A" (*(p)) \ 165 + : "rJ" (co o), "rJ" (n) \ 166 + : "memory"); \ 167 + } \ 156 168 }) 157 169 158 - #define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append) \ 170 + #define _arch_cmpxchg(ptr, old, new, sc_cas_sfx, prepend, append) \ 159 171 ({ \ 160 172 __typeof__(ptr) __ptr = (ptr); \ 161 173 __typeof__(*(__ptr)) __old = (old); \ ··· 178 164 switch (sizeof(*__ptr)) { \ 179 165 case 1: \ 180 166 case 2: \ 181 - __arch_cmpxchg_masked(sc_sfx, prepend, append, \ 167 + __arch_cmpxchg_masked(sc_cas_sfx, prepend, append, \ 182 168 __ret, __ptr, __old, __new); \ 183 169 break; \ 184 170 case 4: \ 185 - __arch_cmpxchg(".w", ".w" sc_sfx, prepend, append, \ 171 + __arch_cmpxchg(".w", ".w" sc_cas_sfx, prepend, append, \ 186 172 __ret, __ptr, (long), __old, __new); \ 187 173 break; \ 188 174 case 8: \ 189 - __arch_cmpxchg(".d", ".d" sc_sfx, prepend, append, \ 175 + __arch_cmpxchg(".d", ".d" sc_cas_sfx, prepend, append, \ 190 176 __ret, __ptr, /**/, __old, __new); \ 191 177 break; \ 192 178 default: \