* [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo
@ 2026-10-26 9:20 Vladimir Kondratiev
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Vladimir Kondratiev @ 2026-10-26 9:20 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, Boqun Feng
Cc: linux-riscv, linux-kernel, Vladimir.Kondratiev, Vladimir Kondratiev
RISC-V split the A extension into Zaamo (AMO*.w/AMO*.d) and Zalrsc
(LR/SC). Linux has so far required the whole A extension.
MIPS P8700 [1] implements only Zalrsc. AMO instructions are emulated by a
trap into SBI. I measured typical userspace atomics on this CPU: an
LR/SC atomic takes about 40 cycles, an AMO atomic about 600. The same
ratio applies to kernel refcounts, bitops, xchg and futexes, so the
kernel needs to emit LR/SC when Zaamo is not implemented.
Mobileye is going to use the "eyeq7h" platform, built on this CPU, for
ADAS and autonomous driving. Kernel atomics are on the scheduling,
memory-management and driver paths of that product, so the emulated
AMO cost is not acceptable there.
This series keeps today's default: both extensions on, -march still
contains "a", generated code is unchanged. Turning Zaamo off is a
NONPORTABLE choice. The resulting kernel matches one -march, which
userspace has to use as well, so a runtime alternative would not
produce a portable image.
Zalrsc stays mandatory. cmpxchg, conditional atomics and futex CAS are
already LR/SC sequences; Zaamo cannot replace them. BPF atomic ops
still emit AMO and remain unsupported on a Zalrsc-only kernel.
[1] https://mips.com/products/hardware/p8700/
Changes in v3:
- Make Zalrsc mandatory. cmpxchg and the conditional atomics already
use LR/SC, so RISCV_ISA_ZALRSC can no longer be turned off.
- Check AMO and LR/SC support independently. A kernel that emits both
requires "a", or both "zaamo" and "zalrsc".
- Put the LR/SC bitop sequence in its own block so two inlined
set_bit or clear_bit calls compile.
- Remove the LR/SC loop that ran after the hart lottery and accessed
address 1. Build the lottery increment with add so RV32 assembles.
- Add an exception-table entry for sc as well as lr in the futex
LR/SC helper.
Changes in v2:
- Switch from a runtime choice of atomic implementation to a
compile-time one, gated by NONPORTABLE.
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
Vladimir Kondratiev (2):
riscv: build kernel atomics from LR/SC when Zaamo is disabled
riscv: accept the atomic extensions this kernel was built with
arch/riscv/Kconfig | 23 +++++++++++++++++
arch/riscv/Makefile | 15 ++++++++---
arch/riscv/include/asm/atomic.h | 56 +++++++++++++++++++++++++++++++++++++++-
arch/riscv/include/asm/bitops.h | 51 ++++++++++++++++++++++++++++++++++++
arch/riscv/include/asm/cmpxchg.h | 18 +++++++++++++
arch/riscv/include/asm/futex.h | 53 +++++++++++++++++++++++++++++++++++++
arch/riscv/kernel/cpu.c | 28 +++++++++++++++++---
arch/riscv/kernel/entry.S | 9 +++++++
arch/riscv/kernel/head.S | 14 ++++++++++
9 files changed, 258 insertions(+), 9 deletions(-)
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20260120-lrsc-only-cc06422f5bb1
Best regards,
--
Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
2026-10-26 9:20 [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Vladimir Kondratiev
@ 2026-10-26 9:20 ` Vladimir Kondratiev
2026-10-31 1:54 ` kernel test robot
` (2 more replies)
2026-10-26 9:20 ` [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with Vladimir Kondratiev
2026-10-26 10:30 ` [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Peter Zijlstra
2 siblings, 3 replies; 9+ messages in thread
From: Vladimir Kondratiev @ 2026-10-26 9:20 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, Boqun Feng
Cc: linux-riscv, linux-kernel, Vladimir.Kondratiev, Vladimir Kondratiev
The A extension is Zaamo plus Zalrsc. MIPS P8700 implements only
Zalrsc, and its AMO instructions trap to SBI. A typical atomic is
about 40 cycles with LR/SC and about 600 cycles with an emulated AMO,
so keep the existing AMO sequences when the toolchain defines
__riscv_zaamo or __riscv_atomic, and use an LR/SC loop otherwise.
Add RISCV_ISA_ZAAMO and RISCV_ISA_ZALRSC. Both default on, and that
selection still passes "a" in -march. Zaamo can be turned off only
with CONFIG_NONPORTABLE; Zalrsc remains required because cmpxchg and
the conditional atomics are LR/SC sequences. An LR/SC-only build
passes _zalrsc instead of "a".
Suggested-by: Chao-ying Fu <cfu@wavecomp.com>
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
arch/riscv/Kconfig | 23 +++++++++++++++++
arch/riscv/Makefile | 15 ++++++++---
arch/riscv/include/asm/atomic.h | 56 +++++++++++++++++++++++++++++++++++++++-
arch/riscv/include/asm/bitops.h | 51 ++++++++++++++++++++++++++++++++++++
arch/riscv/include/asm/cmpxchg.h | 18 +++++++++++++
arch/riscv/include/asm/futex.h | 53 +++++++++++++++++++++++++++++++++++++
arch/riscv/kernel/entry.S | 9 +++++++
arch/riscv/kernel/head.S | 14 ++++++++++
8 files changed, 234 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5874ca30f4f6..1403445482b9 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -730,6 +730,29 @@ config RISCV_ISA_ZACAS
If you don't know what to do here, say Y.
+config RISCV_ISA_ZAAMO
+ bool "Zaamo extension support for AMO atomics" if NONPORTABLE
+ default y
+ help
+ Use AMO instructions for kernel atomic memory operations. When
+ disabled, those operations are built from LR/SC and the kernel
+ is compiled with zalrsc instead of the A extension.
+
+ Disable this only for a hart that implements Zalrsc but not
+ Zaamo, such as the MIPS P8700. The resulting kernel cannot run
+ on a hart without LR/SC.
+
+ If you don't know what to do here, say Y.
+
+config RISCV_ISA_ZALRSC
+ def_bool y
+ help
+ Zalrsc provides LR/SC. cmpxchg and the conditional atomics
+ require it, so it is always enabled.
+
+config RISCV_ISA_A
+ def_bool RISCV_ISA_ZAAMO && RISCV_ISA_ZALRSC
+
config TOOLCHAIN_HAS_ZBB
bool
default y
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 44f5a439741a..23ecf68a761d 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -58,8 +58,9 @@ ifeq ($(CONFIG_SHADOW_CALL_STACK),y)
endif
# ISA string setting
-riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
-riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
+riscv-march-$(CONFIG_ARCH_RV32I) := rv32im
+riscv-march-$(CONFIG_ARCH_RV64I) := rv64im
+riscv-march-$(CONFIG_RISCV_ISA_A) := $(riscv-march-y)a
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
@@ -75,9 +76,15 @@ else
riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
endif
-KBUILD_BASE_ISA = -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
+KBUILD_BASE_ISA = -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima?|rv64ima?)fd([^v_]*)v?/\1\2/')
export KBUILD_BASE_ISA
+# if "A" not supported, toolchain shall support zaamo/zalrsc
+ifneq ($(CONFIG_RISCV_ISA_A),y)
+riscv-march-$(CONFIG_RISCV_ISA_ZAAMO) := $(riscv-march-y)_zaamo
+riscv-march-$(CONFIG_RISCV_ISA_ZALRSC) := $(riscv-march-y)_zalrsc
+endif
+
# Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
# matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
KBUILD_CFLAGS += $(KBUILD_BASE_ISA)
@@ -85,7 +92,7 @@ KBUILD_CFLAGS += $(KBUILD_BASE_ISA)
KBUILD_AFLAGS += -march=$(riscv-march-y)
# For C code built with floating-point support, exclude V but keep F and D.
-CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)([^v_]*)v?/\1\2/')
+CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima?|rv64ima?)([^v_]*)v?/\1\2/')
KBUILD_CFLAGS += -mno-save-restore
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 616b8b332ac5..dc6a8c95c975 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -50,6 +50,7 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
* have the AQ or RL bits set. These don't return anything, so there's only
* one version to worry about.
*/
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix) \
static __always_inline \
void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
@@ -59,7 +60,25 @@ void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
: "+A" (v->counter) \
: "r" (I) \
: "memory"); \
-} \
+}
+#elif defined(__riscv_zalrsc)
+#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix) \
+static __always_inline \
+void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
+{ \
+ register c_type ret, temp; \
+ __asm__ __volatile__ ( \
+ "1: lr." #asm_type " %1, %0\n" \
+ " " #asm_op " %2, %1, %3\n" \
+ " sc." #asm_type " %2, %2, %0\n" \
+ " bnez %2, 1b\n" \
+ : "+A" (v->counter), "=&r" (ret), "=&r" (temp) \
+ : "r" (I) \
+ : "memory"); \
+}
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
#ifdef CONFIG_GENERIC_ATOMIC64
#define ATOMIC_OPS(op, asm_op, I) \
@@ -84,6 +103,7 @@ ATOMIC_OPS(xor, xor, i)
* There's two flavors of these: the arithmetic ops have both fetch and return
* versions, while the logical ops only have fetch versions.
*/
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix) \
static __always_inline \
c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i, \
@@ -108,6 +128,40 @@ c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v) \
: "memory"); \
return ret; \
}
+#elif defined(__riscv_zalrsc)
+#define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix) \
+static __always_inline \
+c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i, \
+ atomic##prefix##_t *v) \
+{ \
+ register c_type ret, temp; \
+ __asm__ __volatile__ ( \
+ "1: lr." #asm_type " %1, %0\n" \
+ " " #asm_op " %2, %1, %3\n" \
+ " sc." #asm_type " %2, %2, %0\n" \
+ " bnez %2, 1b\n" \
+ : "+A" (v->counter), "=&r" (ret), "=&r" (temp) \
+ : "r" (I) \
+ : "memory"); \
+ return ret; \
+} \
+static __always_inline \
+c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v) \
+{ \
+ register c_type ret, temp; \
+ __asm__ __volatile__ ( \
+ "1: lr." #asm_type ".aqrl %1, %0\n" \
+ " " #asm_op " %2, %1, %3\n" \
+ " sc." #asm_type ".aqrl %2, %2, %0\n" \
+ " bnez %2, 1b\n" \
+ : "+A" (v->counter), "=&r" (ret), "=&r" (temp) \
+ : "r" (I) \
+ : "memory"); \
+ return ret; \
+}
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
#define ATOMIC_OP_RETURN(op, asm_op, c_op, I, asm_type, c_type, prefix) \
static __always_inline \
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 3c1a15be54d8..311547558ff5 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -170,12 +170,17 @@ static __always_inline int variable_fls(unsigned int x)
#if (BITS_PER_LONG == 64)
#define __AMO(op) "amo" #op ".d"
+#define __LR "lr.d"
+#define __SC "sc.d"
#elif (BITS_PER_LONG == 32)
#define __AMO(op) "amo" #op ".w"
+#define __LR "lr.w"
+#define __SC "sc.w"
#else
#error "Unexpected BITS_PER_LONG"
#endif
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define __test_and_op_bit_ord(op, mod, nr, addr, ord) \
({ \
unsigned long __res, __mask; \
@@ -194,6 +199,37 @@ static __always_inline int variable_fls(unsigned int x)
: "+A" (addr[BIT_WORD(nr)]) \
: "r" (mod(BIT_MASK(nr))) \
: "memory");
+#elif defined(__riscv_zalrsc)
+#define __test_and_op_bit_ord(op, mod, nr, addr, ord) \
+({ \
+ unsigned long __res, __mask, __temp; \
+ __mask = BIT_MASK(nr); \
+ __asm__ __volatile__ ( \
+ "1: " __LR #ord " %0, %1\n" \
+ #op " %2, %0, %3\n" \
+ __SC #ord " %2, %2, %1\n" \
+ "bnez %2, 1b\n" \
+ : "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp) \
+ : "r" (mod(__mask)) \
+ : "memory"); \
+ ((__res & __mask) != 0); \
+})
+
+#define __op_bit_ord(op, mod, nr, addr, ord) \
+do { \
+ unsigned long __res, __temp; \
+ __asm__ __volatile__ ( \
+ "1: " __LR #ord " %0, %1\n" \
+ #op " %2, %0, %3\n" \
+ __SC #ord " %2, %2, %1\n" \
+ "bnez %2, 1b\n" \
+ : "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp) \
+ : "r" (mod(BIT_MASK(nr))) \
+ : "memory"); \
+} while (0)
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
#define __test_and_op_bit(op, mod, nr, addr) \
__test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
@@ -337,12 +373,27 @@ static __always_inline void arch___clear_bit_unlock(
static __always_inline bool arch_xor_unlock_is_negative_byte(unsigned long mask,
volatile unsigned long *addr)
{
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
unsigned long res;
__asm__ __volatile__ (
__AMO(xor) ".rl %0, %2, %1"
: "=r" (res), "+A" (*addr)
: "r" (__NOP(mask))
: "memory");
+#elif defined(__riscv_zalrsc)
+ unsigned long res, temp;
+
+ __asm__ __volatile__ (
+ "1: " __LR ".rl %0, %1\n"
+ "xor %2, %0, %3\n"
+ __SC ".rl %2, %2, %1\n"
+ "bnez %2, 1b\n"
+ : "=&r" (res), "+A" (*addr), "=&r" (temp)
+ : "r" (__NOP(mask))
+ : "memory");
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
return (res & BIT(7)) != 0;
}
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 662e160b0522..0399c5b4ef35 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -57,6 +57,7 @@
} \
})
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define __arch_xchg(sfx, prepend, append, r, p, n) \
({ \
__asm__ __volatile__ ( \
@@ -67,6 +68,23 @@
: "r" (n) \
: "memory"); \
})
+#elif defined(__riscv_zalrsc)
+#define __arch_xchg(sfx, prepend, append, r, p, n) \
+({ \
+ __typeof__(*(__ptr)) temp; \
+ __asm__ __volatile__ ( \
+ prepend \
+ "1: lr" sfx " %0, %1\n" \
+ " sc" sfx " %2, %3, %1\n" \
+ " bnez %2, 1b\n" \
+ append \
+ : "=&r" (r), "+A" (*(p)), "=&r" (temp) \
+ : "r" (n) \
+ : "memory"); \
+})
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
#define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend, \
sc_append, swap_append) \
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 6f3bc9bdb85e..06fe227197d9 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -19,6 +19,7 @@
#define __disable_user_access() do { } while (0)
#endif
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
{ \
__enable_user_access(); \
@@ -32,17 +33,45 @@
: "memory"); \
__disable_user_access(); \
}
+#elif defined(__riscv_zalrsc)
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
+{ \
+ __enable_user_access(); \
+ __asm__ __volatile__ ( \
+ "1: lr.w.aqrl %[ov], %[u] \n" \
+ " " insn " \n" \
+ "2: sc.w.aqrl %[t], %[t], %[u] \n" \
+ " bnez %[t], 1b \n" \
+ "3: \n" \
+ _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %[r]) \
+ _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %[r]) \
+ : [r] "+r" (ret), [ov] "=&r" (oldval), \
+ [t] "=&r" (temp), [u] "+m" (*(uaddr)) \
+ : [op] "Jr" (oparg) \
+ : "memory"); \
+ __disable_user_access(); \
+}
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
static inline int
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
{
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
int oldval = 0, ret = 0;
+#elif defined(__riscv_zalrsc)
+ int oldval = 0, ret = 0, temp = 0;
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
uaddr = untagged_addr(uaddr);
switch (op) {
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
case FUTEX_OP_SET:
__futex_atomic_op("amoswap.w.aqrl %[ov],%z[op],%[u]",
ret, oldval, uaddr, oparg);
@@ -63,6 +92,30 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
__futex_atomic_op("amoxor.w.aqrl %[ov],%z[op],%[u]",
ret, oldval, uaddr, oparg);
break;
+#elif defined(__riscv_zalrsc)
+ case FUTEX_OP_SET:
+ __futex_atomic_op("mv %[t], %z[op]",
+ ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+ __futex_atomic_op("add %[t], %[ov], %z[op]",
+ ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ __futex_atomic_op("or %[t], %[ov], %z[op]",
+ ret, oldval, uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ __futex_atomic_op("and %[t], %[ov], %z[op]",
+ ret, oldval, uaddr, ~oparg);
+ break;
+ case FUTEX_OP_XOR:
+ __futex_atomic_op("xor %[t], %[ov], %z[op]",
+ ret, oldval, uaddr, oparg);
+ break;
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
default:
ret = -ENOSYS;
}
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 61b7a7716697..1c7bbd7fbff8 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -73,7 +73,16 @@
beq a2, zero, .Lnew_valid_map_cpus_restore_context
/* Atomically reset the current cpu bit in new_valid_map_cpus */
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
amoxor.d a0, a1, (a0)
+#elif defined(__riscv_zalrsc)
+1: lr.d a2, (a0)
+ xor a2, a1, a2
+ sc.d a2, a2, (a0)
+ bnez a2, 1b
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
/*
* A sfence.vma is required here. Even if we had Svvptc, there's no
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index f6a8ca49e627..515669bbbc96 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -265,7 +265,21 @@ SYM_CODE_START(_start_kernel)
/* Pick one hart to run the main boot sequence */
la a3, hart_lottery
li a2, 1
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
amoadd.w a3, a2, (a3)
+#elif defined(__riscv_zalrsc)
+ /*
+ * hart_lottery is a small 32-bit counter. add is valid on RV32
+ * and RV64; sc.w stores the low 32 bits.
+ */
+1: lr.w t0, (a3)
+ add t1, t0, a2
+ sc.w t1, t1, (a3)
+ bnez t1, 1b
+ mv a3, t0
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
bnez a3, .Lsecondary_start
#endif /* CONFIG_RISCV_BOOT_SPINWAIT */
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with
2026-10-26 9:20 [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Vladimir Kondratiev
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
@ 2026-10-26 9:20 ` Vladimir Kondratiev
2026-11-02 18:21 ` Conor Dooley
2026-10-26 10:30 ` [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Peter Zijlstra
2 siblings, 1 reply; 9+ messages in thread
From: Vladimir Kondratiev @ 2026-10-26 9:20 UTC (permalink / raw)
To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, Boqun Feng
Cc: linux-riscv, linux-kernel, Vladimir.Kondratiev, Vladimir Kondratiev
riscv_early_of_processor_hartid() rejects a hart unless its
riscv,isa-extensions property contains "a". That rejects a Zalrsc-only
hart even when the kernel was built to use only LR/SC.
Require "a" or "zaamo" when the kernel emits AMO, and "a" or "zalrsc"
when it emits LR/SC. A normal build defines both toolchain macros and
still requires the full A extension. The legacy "riscv,isa" fallback
keeps its rv{32,64}ima check.
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
arch/riscv/kernel/cpu.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 3dbc8cc557dd..5d1e39d16e59 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -82,12 +82,32 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
return -ENODEV;
if (of_property_match_string(node, "riscv,isa-extensions", "i") < 0 ||
- of_property_match_string(node, "riscv,isa-extensions", "m") < 0 ||
- of_property_match_string(node, "riscv,isa-extensions", "a") < 0) {
- pr_warn("CPU with hartid=%lu does not support ima", *hart);
+ of_property_match_string(node, "riscv,isa-extensions", "m") < 0) {
+ pr_warn("CPU with hartid=%lu does not support im", *hart);
return -ENODEV;
}
-
+#if !defined(__riscv_atomic) && !defined(__riscv_zaamo) && !defined(__riscv_zalrsc)
+#error "Need AMO or LR/SC atomics"
+#endif
+ /*
+ * Require each atomic form this kernel emits. The single-letter
+ * "a" extension satisfies either check. A Zalrsc-only build defines
+ * __riscv_zalrsc and checks that extension only.
+ */
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
+ if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
+ of_property_match_string(node, "riscv,isa-extensions", "zaamo") < 0) {
+ pr_warn("CPU with hartid=%lu does not support AMO atomics", *hart);
+ return -ENODEV;
+ }
+#endif
+#if defined(__riscv_atomic) || defined(__riscv_zalrsc)
+ if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
+ of_property_match_string(node, "riscv,isa-extensions", "zalrsc") < 0) {
+ pr_warn("CPU with hartid=%lu does not support LR/SC atomics", *hart);
+ return -ENODEV;
+ }
+#endif
return 0;
old_interface:
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo
2026-10-26 9:20 [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Vladimir Kondratiev
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
2026-10-26 9:20 ` [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with Vladimir Kondratiev
@ 2026-10-26 10:30 ` Peter Zijlstra
2026-10-26 11:06 ` Vladimir Kondratiev
2 siblings, 1 reply; 9+ messages in thread
From: Peter Zijlstra @ 2026-10-26 10:30 UTC (permalink / raw)
To: Vladimir Kondratiev
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, linux-riscv, linux-kernel
On Mon, Oct 26, 2026 at 11:20:01AM +0200, Vladimir Kondratiev wrote:
> RISC-V split the A extension into Zaamo (AMO*.w/AMO*.d) and Zalrsc
> (LR/SC). Linux has so far required the whole A extension.
>
> MIPS P8700 [1] implements only Zalrsc. AMO instructions are emulated by a
> trap into SBI. I measured typical userspace atomics on this CPU: an
> LR/SC atomic takes about 40 cycles, an AMO atomic about 600. The same
> ratio applies to kernel refcounts, bitops, xchg and futexes, so the
> kernel needs to emit LR/SC when Zaamo is not implemented.
>
> Mobileye is going to use the "eyeq7h" platform, built on this CPU, for
> ADAS and autonomous driving. Kernel atomics are on the scheduling,
> memory-management and driver paths of that product, so the emulated
> AMO cost is not acceptable there.
>
> This series keeps today's default: both extensions on, -march still
> contains "a", generated code is unchanged. Turning Zaamo off is a
> NONPORTABLE choice. The resulting kernel matches one -march, which
> userspace has to use as well, so a runtime alternative would not
> produce a portable image.
>
> Zalrsc stays mandatory. cmpxchg, conditional atomics and futex CAS are
> already LR/SC sequences; Zaamo cannot replace them. BPF atomic ops
> still emit AMO and remain unsupported on a Zalrsc-only kernel.
The comment with RISCV_QUEUED_SPINLOCKS state that Zalrsc requires that
cmpxchg() loops have forward progress; which is much stronger than the
typical LL/SC implementation.
Does this MIPS thing indeed provide this?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo
2026-10-26 10:30 ` [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Peter Zijlstra
@ 2026-10-26 11:06 ` Vladimir Kondratiev
0 siblings, 0 replies; 9+ messages in thread
From: Vladimir Kondratiev @ 2026-10-26 11:06 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, linux-riscv, linux-kernel
On 10/26/26 12:30, Peter Zijlstra wrote:
> The comment with RISCV_QUEUED_SPINLOCKS state that Zalrsc requires that
> cmpxchg() loops have forward progress; which is much stronger than the
> typical LL/SC implementation.
>
> Does this MIPS thing indeed provide this?
You mean Ziccrse extension? Yes, p8700 does provide it. I explicitly
confirmed it with hardware designers.
In fact, I use RISCV_QUEUED_SPINLOCKS on this platform
Thanks, Vladimir
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
@ 2026-10-31 1:54 ` kernel test robot
2026-10-31 2:14 ` kernel test robot
2026-11-02 18:46 ` Conor Dooley
2 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2026-10-31 1:54 UTC (permalink / raw)
To: Vladimir Kondratiev, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Will Deacon, Peter Zijlstra, Mark Rutland,
Gary Guo, Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
aleksa.paunovic, arikalo, Boqun Feng
Cc: oe-kbuild-all, linux-riscv, linux-kernel, Vladimir.Kondratiev
Hi Vladimir,
kernel test robot noticed the following build errors:
[auto build test ERROR on c03c1a14507dfaf8b856c2608f9ac216021fc222]
url: https://github.com/intel-lab-lkp/linux/commits/Vladimir-Kondratiev/riscv-build-kernel-atomics-from-LR-SC-when-Zaamo-is-disabled/20261026-112002
base: c03c1a14507dfaf8b856c2608f9ac216021fc222
patch link: https://lore.kernel.org/r/20261026-lrsc-only-v3-1-ec29c8190fb1%40mobileye.com
patch subject: [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
config: riscv-randconfig-1001-20261031 (https://download.01.org/0day-ci/archive/20261031/202610310951.FopXBJty-lkp@intel.com/config)
compiler: riscv64-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261031/202610310951.FopXBJty-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610310951.FopXBJty-lkp@intel.com/
All errors (new ones prefixed by >>):
>> cc1: error: -march=rv64im_zalrsc: unsupported ISA substring '_zalrsc'
make[3]: *** [scripts/Makefile.build:290: scripts/mod/empty.o] Error 1 shuffle=1929180073
>> cc1: error: -march=rv64im_zalrsc: unsupported ISA substring '_zalrsc'
make[3]: *** [scripts/Makefile.build:185: scripts/mod/devicetable-offsets.s] Error 1 shuffle=1929180073
make[3]: Target 'scripts/mod/' not remade because of errors.
make[2]: *** [Makefile:1424: prepare0] Error 2 shuffle=1929180073
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2 shuffle=1929180073
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2 shuffle=1929180073
make: Target 'prepare' not remade because of errors.
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
2026-10-31 1:54 ` kernel test robot
@ 2026-10-31 2:14 ` kernel test robot
2026-11-02 18:46 ` Conor Dooley
2 siblings, 0 replies; 9+ messages in thread
From: kernel test robot @ 2026-10-31 2:14 UTC (permalink / raw)
To: Vladimir Kondratiev, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Will Deacon, Peter Zijlstra, Mark Rutland,
Gary Guo, Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
aleksa.paunovic, arikalo, Boqun Feng
Cc: oe-kbuild-all, linux-riscv, linux-kernel, Vladimir.Kondratiev
Hi Vladimir,
kernel test robot noticed the following build errors:
[auto build test ERROR on c03c1a14507dfaf8b856c2608f9ac216021fc222]
url: https://github.com/intel-lab-lkp/linux/commits/Vladimir-Kondratiev/riscv-build-kernel-atomics-from-LR-SC-when-Zaamo-is-disabled/20261026-112002
base: c03c1a14507dfaf8b856c2608f9ac216021fc222
patch link: https://lore.kernel.org/r/20261026-lrsc-only-v3-1-ec29c8190fb1%40mobileye.com
patch subject: [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
config: riscv-randconfig-1000-20261031 (https://download.01.org/0day-ci/archive/20261031/202610311058.zODtC2bF-lkp@intel.com/config)
compiler: riscv32-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261031/202610311058.zODtC2bF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610311058.zODtC2bF-lkp@intel.com/
All errors (new ones prefixed by >>):
>> cc1: error: -march=rv32imc_zalrsc: unsupported ISA substring '_zalrsc'
make[3]: *** [scripts/Makefile.build:290: scripts/mod/empty.o] Error 1 shuffle=1963593903
>> cc1: error: -march=rv32imc_zalrsc: unsupported ISA substring '_zalrsc'
make[3]: *** [scripts/Makefile.build:185: scripts/mod/devicetable-offsets.s] Error 1 shuffle=1963593903
make[3]: Target 'scripts/mod/' not remade because of errors.
make[2]: *** [Makefile:1424: prepare0] Error 2 shuffle=1963593903
make[2]: Target 'prepare' not remade because of errors.
make[1]: *** [Makefile:248: __sub-make] Error 2 shuffle=1963593903
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:248: __sub-make] Error 2 shuffle=1963593903
make: Target 'prepare' not remade because of errors.
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with
2026-10-26 9:20 ` [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with Vladimir Kondratiev
@ 2026-11-02 18:21 ` Conor Dooley
0 siblings, 0 replies; 9+ messages in thread
From: Conor Dooley @ 2026-11-02 18:21 UTC (permalink / raw)
To: Vladimir Kondratiev
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, linux-riscv, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2625 bytes --]
On Mon, Oct 26, 2026 at 11:20:03AM +0200, Vladimir Kondratiev wrote:
> riscv_early_of_processor_hartid() rejects a hart unless its
> riscv,isa-extensions property contains "a". That rejects a Zalrsc-only
> hart even when the kernel was built to use only LR/SC.
>
> Require "a" or "zaamo" when the kernel emits AMO, and "a" or "zalrsc"
> when it emits LR/SC. A normal build defines both toolchain macros and
> still requires the full A extension. The legacy "riscv,isa" fallback
> keeps its rv{32,64}ima check.
>
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com
>
IMO, this should not be a separate patch.
> ---
> arch/riscv/kernel/cpu.c | 28 ++++++++++++++++++++++++----
> 1 file changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> index 3dbc8cc557dd..5d1e39d16e59 100644
> --- a/arch/riscv/kernel/cpu.c
> +++ b/arch/riscv/kernel/cpu.c
> @@ -82,12 +82,32 @@ int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned lo
> return -ENODEV;
>
> if (of_property_match_string(node, "riscv,isa-extensions", "i") < 0 ||
> - of_property_match_string(node, "riscv,isa-extensions", "m") < 0 ||
> - of_property_match_string(node, "riscv,isa-extensions", "a") < 0) {
> - pr_warn("CPU with hartid=%lu does not support ima", *hart);
> + of_property_match_string(node, "riscv,isa-extensions", "m") < 0) {
> + pr_warn("CPU with hartid=%lu does not support im", *hart);
> return -ENODEV;
> }
> -
> +#if !defined(__riscv_atomic) && !defined(__riscv_zaamo) && !defined(__riscv_zalrsc)
> +#error "Need AMO or LR/SC atomics"
> +#endif
> + /*
> + * Require each atomic form this kernel emits. The single-letter
> + * "a" extension satisfies either check. A Zalrsc-only build defines
> + * __riscv_zalrsc and checks that extension only.
> + */
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
> + if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
> + of_property_match_string(node, "riscv,isa-extensions", "zaamo") < 0) {
> + pr_warn("CPU with hartid=%lu does not support AMO atomics", *hart);
> + return -ENODEV;
> + }
> +#endif
> +#if defined(__riscv_atomic) || defined(__riscv_zalrsc)
> + if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
> + of_property_match_string(node, "riscv,isa-extensions", "zalrsc") < 0) {
> + pr_warn("CPU with hartid=%lu does not support LR/SC atomics", *hart);
> + return -ENODEV;
> + }
> +#endif
> return 0;
>
> old_interface:
>
> --
> 2.43.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
2026-10-31 1:54 ` kernel test robot
2026-10-31 2:14 ` kernel test robot
@ 2026-11-02 18:46 ` Conor Dooley
2 siblings, 0 replies; 9+ messages in thread
From: Conor Dooley @ 2026-11-02 18:46 UTC (permalink / raw)
To: Vladimir Kondratiev
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
Rasmus Villemoes, cfu, torvalds, olof, aleksa.paunovic, arikalo,
Boqun Feng, linux-riscv, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 7231 bytes --]
On Mon, Oct 26, 2026 at 11:20:02AM +0200, Vladimir Kondratiev wrote:
> The A extension is Zaamo plus Zalrsc. MIPS P8700 implements only
> Zalrsc, and its AMO instructions trap to SBI. A typical atomic is
> about 40 cycles with LR/SC and about 600 cycles with an emulated AMO,
> so keep the existing AMO sequences when the toolchain defines
> __riscv_zaamo or __riscv_atomic, and use an LR/SC loop otherwise.
>
> Add RISCV_ISA_ZAAMO and RISCV_ISA_ZALRSC. Both default on, and that
> selection still passes "a" in -march. Zaamo can be turned off only
> with CONFIG_NONPORTABLE; Zalrsc remains required because cmpxchg and
> the conditional atomics are LR/SC sequences. An LR/SC-only build
> passes _zalrsc instead of "a".
>
> Suggested-by: Chao-ying Fu <cfu@wavecomp.com>
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
As you can see by the lkp reports, this is not the right way to do this.
> ---
> arch/riscv/Kconfig | 23 +++++++++++++++++
> arch/riscv/Makefile | 15 ++++++++---
> arch/riscv/include/asm/atomic.h | 56 +++++++++++++++++++++++++++++++++++++++-
> arch/riscv/include/asm/bitops.h | 51 ++++++++++++++++++++++++++++++++++++
> arch/riscv/include/asm/cmpxchg.h | 18 +++++++++++++
> arch/riscv/include/asm/futex.h | 53 +++++++++++++++++++++++++++++++++++++
> arch/riscv/kernel/entry.S | 9 +++++++
> arch/riscv/kernel/head.S | 14 ++++++++++
> 8 files changed, 234 insertions(+), 5 deletions(-)
> +
> config TOOLCHAIN_HAS_ZBB
> bool
> default y
>
> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
> index 5874ca30f4f6..1403445482b9 100644
> --- a/arch/riscv/Kconfig
> +++ b/arch/riscv/Kconfig
> @@ -730,6 +730,29 @@ config RISCV_ISA_ZACAS
>
> If you don't know what to do here, say Y.
>
> +config RISCV_ISA_ZAAMO
> + bool "Zaamo extension support for AMO atomics" if NONPORTABLE
> + default y
> + help
> + Use AMO instructions for kernel atomic memory operations. When
> + disabled, those operations are built from LR/SC and the kernel
> + is compiled with zalrsc instead of the A extension.
> +
> + Disable this only for a hart that implements Zalrsc but not
> + Zaamo, such as the MIPS P8700. The resulting kernel cannot run
> + on a hart without LR/SC.
The text here doesn't really make much sense, given it is default
disabled as it depends on NONPORTABLE that is default disabled.
If this is retained, it should be default n and the text reworded.
> +
> + If you don't know what to do here, say Y.
> +
> +config RISCV_ISA_ZALRSC
> + def_bool y
> + help
> + Zalrsc provides LR/SC. cmpxchg and the conditional atomics
> + require it, so it is always enabled.
So why have a kconfig option for it then? It's pointless if always
enabled.
> +
> +config RISCV_ISA_A
> + def_bool RISCV_ISA_ZAAMO && RISCV_ISA_ZALRSC
I think this all needs a redo...
> diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
> index 616b8b332ac5..dc6a8c95c975 100644
> --- a/arch/riscv/include/asm/atomic.h
> +++ b/arch/riscv/include/asm/atomic.h
> @@ -50,6 +50,7 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
> * have the AQ or RL bits set. These don't return anything, so there's only
> * one version to worry about.
> */
> +#if defined(__riscv_atomic) || defined(__riscv_zaamo)
> #define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix) \
> static __always_inline \
> void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
> @@ -59,7 +60,25 @@ void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
> : "+A" (v->counter) \
> : "r" (I) \
> : "memory"); \
> -} \
> +}
> +#elif defined(__riscv_zalrsc)
...why are we making this a compiletime decision in the first place?
Why can't this be an alternative, starting with the zalrsc stuff and
moving to the better implementation if available?
Is there some zaamo code that gets generated automatically that we lose
out on by always building the kernel with zalrsc instead of with all of a?
> +#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix) \
> +static __always_inline \
> +void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v) \
> +{ \
> + register c_type ret, temp; \
> + __asm__ __volatile__ ( \
> + "1: lr." #asm_type " %1, %0\n" \
> + " " #asm_op " %2, %1, %3\n" \
> + " sc." #asm_type " %2, %2, %0\n" \
> + " bnez %2, 1b\n" \
> + : "+A" (v->counter), "=&r" (ret), "=&r" (temp) \
> + : "r" (I) \
> + : "memory"); \
> +}
> +#else
> +#error "Need AMO or LR/SC atomics"
> +#endif
>
> #ifdef CONFIG_GENERIC_ATOMIC64
> #define ATOMIC_OPS(op, asm_op, I) \
> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
> index 44f5a439741a..23ecf68a761d 100644
> --- a/arch/riscv/Makefile
> +++ b/arch/riscv/Makefile
> @@ -58,8 +58,9 @@ ifeq ($(CONFIG_SHADOW_CALL_STACK),y)
> endif
>
> # ISA string setting
> -riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
> -riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
> +riscv-march-$(CONFIG_ARCH_RV32I) := rv32im
> +riscv-march-$(CONFIG_ARCH_RV64I) := rv64im
> +riscv-march-$(CONFIG_RISCV_ISA_A) := $(riscv-march-y)a
> riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
> riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
> riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
> @@ -75,9 +76,15 @@ else
> riscv-march-$(CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI) := $(riscv-march-y)_zicsr_zifencei
> endif
>
> -KBUILD_BASE_ISA = -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
> +KBUILD_BASE_ISA = -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima?|rv64ima?)fd([^v_]*)v?/\1\2/')
> export KBUILD_BASE_ISA
>
> +# if "A" not supported, toolchain shall support zaamo/zalrsc
Obviously this is not true, disabling some Kconfig option has no bearing
on what a toolchain is capable of. You cannot put _foo in here without
checking if the toolchain actually supports it.
If no zaamo instructions are automatically generated, this dance isn't
needed, so my suggestions for how to proceed depend on the answer to
that question.
pw-bot: changes-requested
Thanks,
Conor.
> +ifneq ($(CONFIG_RISCV_ISA_A),y)
> +riscv-march-$(CONFIG_RISCV_ISA_ZAAMO) := $(riscv-march-y)_zaamo
> +riscv-march-$(CONFIG_RISCV_ISA_ZALRSC) := $(riscv-march-y)_zalrsc
> +endif
> +
> # Remove F,D,V from isa string for all. Keep extensions between "fd" and "v" by
> # matching non-v and non-multi-letter extensions out with the filter ([^v_]*)
> KBUILD_CFLAGS += $(KBUILD_BASE_ISA)
> @@ -85,7 +92,7 @@ KBUILD_CFLAGS += $(KBUILD_BASE_ISA)
> KBUILD_AFLAGS += -march=$(riscv-march-y)
>
> # For C code built with floating-point support, exclude V but keep F and D.
> -CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)([^v_]*)v?/\1\2/')
> +CC_FLAGS_FPU := -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima?|rv64ima?)([^v_]*)v?/\1\2/')
>
> KBUILD_CFLAGS += -mno-save-restore
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-11-02 18:46 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 9:20 [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Vladimir Kondratiev
2026-10-26 9:20 ` [PATCH v3 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
2026-10-31 1:54 ` kernel test robot
2026-10-31 2:14 ` kernel test robot
2026-11-02 18:46 ` Conor Dooley
2026-10-26 9:20 ` [PATCH v3 2/2] riscv: accept the atomic extensions this kernel was built with Vladimir Kondratiev
2026-11-02 18:21 ` Conor Dooley
2026-10-26 10:30 ` [PATCH v3 0/2] riscv: support CPUs with Zalrsc but not Zaamo Peter Zijlstra
2026-10-26 11:06 ` Vladimir Kondratiev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®