Linux-RISC-V Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo"
@ 2026-01-14  7:25 Vladimir Kondratiev
  2026-01-17  1:50 ` Paul Walmsley
  0 siblings, 1 reply; 10+ messages in thread
From: Vladimir Kondratiev @ 2026-01-14  7:25 UTC (permalink / raw)
  To: Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Yury Norov, Rasmus Villemoes
  Cc: Vladimir Kondratiev, Chao-ying Fu, Aleksandar Rikalo,
	Aleksa Paunovic, linux-kernel, linux-riscv

riscv have 3 instruction set extensions related to atomic operations:
- "zaamo": atomic instructions like AMOADD
- "zalrsc": LR and SC instructions
- "a" that is "zaamo" + "zalrsc"

Historically, "a" was first, and Linux was relying on "a";
then "zaamo"/"zalrsc" was introduced. It is possible to implement
most atomic operations with either AMO or LR/SC. AMO if more efficient
however more complex flows are possible with LR/SC only.

Platforms supporting only part of atomics starting to appear.
Notable is MIPS P8700 CPU [1] having only "zalrsc".

CPU reports ISA extensions supported in the "riscv,isa-extensions"
property of the CPU OF node. Platform supporting "zalrsc" only should
report "zalrsc" but no "a" in this property.

For the early stages of execution, before alternatives applied,
(ex: head.S) CPUs having no "zaamo" extension rely on firmware
emulating AMO through "invalid instruction" trap to the M-mode.

Speed-up the rest of execution using ALTERNATIVE,
replacing AMO versions with LR/SC ones

Implementation is generic, inspired by the patch [2]
by developers listed below, implementing similar patch as errata
for the MIPS P8700 CPU

[1] https://mips.com/products/hardware/p8700/
[2] https://lore.kernel.org/all/20251014-p8700-zalrsc-v3-1-9d81bd8093e0@htecgroup.com/

Suggested-by: Chao-ying Fu <cfu@mips.com>
Suggested-by: Aleksandar Rikalo <arikalo@gmail.com>
Suggested-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
 arch/riscv/include/asm/atomic.h    |  29 ++-----
 arch/riscv/include/asm/bitops.h    |  38 ++++----
 arch/riscv/include/asm/cmpxchg.h   |  13 +--
 arch/riscv/include/asm/futex.h     |  35 ++++----
 arch/riscv/include/asm/processor.h | 134 ++++++++++++++++++++++++++++-
 arch/riscv/kernel/cpu.c            |  12 ++-
 arch/riscv/kernel/cpufeature.c     |   5 ++
 arch/riscv/kernel/entry.S          |   8 +-
 8 files changed, 198 insertions(+), 76 deletions(-)

diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 5b96c2f61adb..fadfbc30ac1a 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -54,12 +54,9 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
 static __always_inline							\
 void arch_atomic##prefix##_##op(c_type i, atomic##prefix##_t *v)	\
 {									\
-	__asm__ __volatile__ (						\
-		"	amo" #asm_op "." #asm_type " zero, %1, %0"	\
-		: "+A" (v->counter)					\
-		: "r" (I)						\
-		: "memory");						\
-}									\
+	register __maybe_unused c_type ret, temp;			\
+	ALT_ATOMIC_OP(asm_op, I, asm_type, v, ret, temp);		\
+}
 
 #ifdef CONFIG_GENERIC_ATOMIC64
 #define ATOMIC_OPS(op, asm_op, I)					\
@@ -89,24 +86,16 @@ static __always_inline							\
 c_type arch_atomic##prefix##_fetch_##op##_relaxed(c_type i,		\
 					     atomic##prefix##_t *v)	\
 {									\
-	register c_type ret;						\
-	__asm__ __volatile__ (						\
-		"	amo" #asm_op "." #asm_type " %1, %2, %0"	\
-		: "+A" (v->counter), "=r" (ret)				\
-		: "r" (I)						\
-		: "memory");						\
+	register __maybe_unused c_type ret, temp;			\
+	ALT_ATOMIC_FETCH_OP_RELAXED(asm_op, I, asm_type, v, ret, temp);	\
 	return ret;							\
 }									\
 static __always_inline							\
 c_type arch_atomic##prefix##_fetch_##op(c_type i, atomic##prefix##_t *v)	\
-{									\
-	register c_type ret;						\
-	__asm__ __volatile__ (						\
-		"	amo" #asm_op "." #asm_type ".aqrl  %1, %2, %0"	\
-		: "+A" (v->counter), "=r" (ret)				\
-		: "r" (I)						\
-		: "memory");						\
-	return ret;							\
+{										\
+	register __maybe_unused c_type ret, temp;				\
+	ALT_ATOMIC_FETCH_OP(asm_op, I, asm_type, v, ret, temp);			\
+	return ret;								\
 }
 
 #define ATOMIC_OP_RETURN(op, asm_op, c_op, I, asm_type, c_type, prefix)	\
diff --git a/arch/riscv/include/asm/bitops.h b/arch/riscv/include/asm/bitops.h
index 77880677b06e..926d1fe91f7b 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -187,30 +187,27 @@ 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
 
-#define __test_and_op_bit_ord(op, mod, nr, addr, ord)		\
-({								\
-	unsigned long __res, __mask;				\
-	__mask = BIT_MASK(nr);					\
-	__asm__ __volatile__ (					\
-		__AMO(op) #ord " %0, %2, %1"			\
-		: "=r" (__res), "+A" (addr[BIT_WORD(nr)])	\
-		: "r" (mod(__mask))				\
-		: "memory");					\
-	((__res & __mask) != 0);				\
+#define __test_and_op_bit_ord(op, mod, nr, addr, ord)				\
+({										\
+	__maybe_unused unsigned long __res, __mask, __temp;			\
+	__mask = BIT_MASK(nr);							\
+	ALT_TEST_AND_OP_BIT_ORD(op, mod, nr, addr, ord, __res, __mask, __temp);	\
+	((__res & __mask) != 0);						\
 })
 
-#define __op_bit_ord(op, mod, nr, addr, ord)			\
-	__asm__ __volatile__ (					\
-		__AMO(op) #ord " zero, %1, %0"			\
-		: "+A" (addr[BIT_WORD(nr)])			\
-		: "r" (mod(BIT_MASK(nr)))			\
-		: "memory");
+#define __op_bit_ord(op, mod, nr, addr, ord)					\
+	__maybe_unused unsigned long __res, __temp;				\
+	ALT_OP_BIT_ORD(op, mod, nr, addr, ord, __res, __temp)
 
 #define __test_and_op_bit(op, mod, nr, addr) 			\
 	__test_and_op_bit_ord(op, mod, nr, addr, .aqrl)
@@ -354,12 +351,9 @@ 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)
 {
-	unsigned long res;
-	__asm__ __volatile__ (
-		__AMO(xor) ".rl %0, %2, %1"
-		: "=r" (res), "+A" (*addr)
-		: "r" (__NOP(mask))
-		: "memory");
+	__maybe_unused unsigned long res, temp;
+
+	ALT_ARCH_XOR_UNLOCK(mask, addr, res, temp);
 	return (res & BIT(7)) != 0;
 }
 
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 122e1485d39a..b231b49bcc66 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -54,15 +54,10 @@
 	}									\
 })
 
-#define __arch_xchg(sfx, prepend, append, r, p, n)			\
-({									\
-	__asm__ __volatile__ (						\
-		prepend							\
-		"	amoswap" sfx " %0, %2, %1\n"			\
-		append							\
-		: "=r" (r), "+A" (*(p))					\
-		: "r" (n)						\
-		: "memory");						\
+#define __arch_xchg(sfx, prepend, append, r, p, n)		\
+({								\
+	__typeof__(*(__ptr)) __maybe_unused temp;		\
+	ALT_ARCH_XCHG(sfx, prepend, append, r, p, n, temp);	\
 })
 
 #define _arch_xchg(ptr, new, sc_sfx, swap_sfx, prepend,			\
diff --git a/arch/riscv/include/asm/futex.h b/arch/riscv/include/asm/futex.h
index 90c86b115e00..d4b8660bc345 100644
--- a/arch/riscv/include/asm/futex.h
+++ b/arch/riscv/include/asm/futex.h
@@ -19,48 +19,43 @@
 #define __disable_user_access()		do { } while (0)
 #endif
 
-#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg, temp)	\
+{									\
+	__enable_user_access();						\
+	ALT_FUTEX_ATOMIC_OP(insn, ret, oldval, uaddr, oparg, temp);	\
+	__disable_user_access();					\
+}
+
+#define __futex_atomic_swap(ret, oldval, uaddr, oparg, temp)	\
 {								\
 	__enable_user_access();					\
-	__asm__ __volatile__ (					\
-	"1:	" insn "				\n"	\
-	"2:						\n"	\
-	_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r])			\
-	: [r] "+r" (ret), [ov] "=&r" (oldval),			\
-	  [u] "+m" (*uaddr)					\
-	: [op] "Jr" (oparg)					\
-	: "memory");						\
+	ALT_FUTEX_ATOMIC_SWAP(ret, oldval, uaddr, oparg, temp);	\
 	__disable_user_access();				\
 }
 
 static inline int
 arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
 {
-	int oldval = 0, ret = 0;
+	int __maybe_unused oldval = 0, ret = 0, temp = 0;
 
 	if (!access_ok(uaddr, sizeof(u32)))
 		return -EFAULT;
 
 	switch (op) {
 	case FUTEX_OP_SET:
-		__futex_atomic_op("amoswap.w.aqrl %[ov],%z[op],%[u]",
-				  ret, oldval, uaddr, oparg);
+		__futex_atomic_swap(ret, oldval, uaddr, oparg, temp);
 		break;
 	case FUTEX_OP_ADD:
-		__futex_atomic_op("amoadd.w.aqrl %[ov],%z[op],%[u]",
-				  ret, oldval, uaddr, oparg);
+		__futex_atomic_op(add, ret, oldval, uaddr, oparg, temp);
 		break;
 	case FUTEX_OP_OR:
-		__futex_atomic_op("amoor.w.aqrl %[ov],%z[op],%[u]",
-				  ret, oldval, uaddr, oparg);
+		__futex_atomic_op(or, ret, oldval, uaddr, oparg, temp);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_atomic_op("amoand.w.aqrl %[ov],%z[op],%[u]",
-				  ret, oldval, uaddr, ~oparg);
+		__futex_atomic_op(and, ret, oldval, uaddr, oparg, temp);
 		break;
 	case FUTEX_OP_XOR:
-		__futex_atomic_op("amoxor.w.aqrl %[ov],%z[op],%[u]",
-				  ret, oldval, uaddr, oparg);
+		__futex_atomic_op(xor, ret, oldval, uaddr, oparg, temp);
 		break;
 	default:
 		ret = -ENOSYS;
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index da5426122d28..74a7650a25e9 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -151,7 +151,139 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
 #define PREFETCHW_ASM(x)						\
 	ALTERNATIVE(__nops(1), PREFETCH_W(x, 0), 0,			\
 		    RISCV_ISA_EXT_ZICBOP, CONFIG_RISCV_ISA_ZICBOP)
-
+/* atomics - begin */
+#define ALT_ATOMIC_OP(asm_op, I, asm_type, v, ret, temp)		\
+asm(ALTERNATIVE(							\
+		"	amo" #asm_op "." #asm_type " zero, %3, %0\n"	\
+		__nops(3),						\
+		"1:	lr." #asm_type " %1, %0\n"			\
+		"	" #asm_op " %2, %1, %3\n"			\
+		"	sc." #asm_type " %2, %2, %0\n"			\
+		"	bnez %2, 1b\n",					\
+		0, RISCV_ISA_EXT_ZALRSC, 1)				\
+	: "+A" ((v)->counter), "=&r" (ret), "=&r" (temp)		\
+	: "r" (I)							\
+	: "memory")
+
+#define ALT_ATOMIC_FETCH_OP_RELAXED(asm_op, I, asm_type, v, ret, temp)	\
+asm(ALTERNATIVE(							\
+		"	amo" #asm_op "." #asm_type " %1, %3, %0\n"	\
+		__nops(3),						\
+		"1:	lr." #asm_type " %1, %0\n"			\
+		"	" #asm_op " %2, %1, %3\n"			\
+		"	sc." #asm_type " %2, %2, %0\n"			\
+		"	bnez %2, 1b\n",					\
+		0, RISCV_ISA_EXT_ZALRSC, 1)				\
+	: "+A" ((v)->counter), "=&r" (ret), "=&r" (temp)		\
+	: "r" (I)							\
+	: "memory")
+
+#define ALT_ATOMIC_FETCH_OP(asm_op, I, asm_type, v, ret, temp)		\
+asm(ALTERNATIVE(							\
+		"	amo" #asm_op "." #asm_type ".aqrl  %1, %3, %0\n"\
+		__nops(3),						\
+		"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",					\
+		0, RISCV_ISA_EXT_ZALRSC, 1)				\
+	: "+A" ((v)->counter), "=&r" (ret), "=&r" (temp)		\
+	: "r" (I)							\
+	: "memory")
+/* BITOPS.h */
+#define ALT_TEST_AND_OP_BIT_ORD(op, mod, nr, addr, ord, __res, __mask, __temp)	\
+asm(ALTERNATIVE(								\
+		__AMO(op) #ord " zero, %3, %1\n"				\
+		__nops(3),							\
+		"1:	" __LR #ord " %0, %1\n"					\
+			#op " %2, %0, %3\n"					\
+			__SC #ord " %2, %2, %1\n"				\
+			"bnez %2, 1b\n",					\
+		0, RISCV_ISA_EXT_ZALRSC, 1)					\
+	: "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)		\
+	: "r" (mod(__mask))							\
+	: "memory")
+
+#define ALT_OP_BIT_ORD(op, mod, nr, addr, ord, __res, __temp)		\
+asm(ALTERNATIVE(							\
+		__AMO(op) #ord " zero, %3, %1\n"			\
+		__nops(3),						\
+		"1:	" __LR #ord " %0, %1\n"				\
+			#op " %2, %0, %3\n"				\
+			__SC #ord " %2, %2, %1\n"			\
+			"bnez %2, 1b\n",				\
+		0, RISCV_ISA_EXT_ZALRSC, 1)				\
+	: "=&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=&r" (__temp)	\
+	: "r" (mod(BIT_MASK(nr)))					\
+	: "memory")
+
+#define ALT_ARCH_XOR_UNLOCK(mask, addr, __res, __temp)	\
+asm(ALTERNATIVE(					\
+		__AMO(xor) ".rl %0, %3, %1\n"		\
+		__nops(3),				\
+		"1:	" __LR ".rl %0, %1\n"		\
+			"xor %2, %0, %3\n"		\
+			__SC ".rl %2, %2, %1\n"		\
+			"bnez %2, 1b\n",		\
+		0, RISCV_ISA_EXT_ZALRSC, 1)		\
+	: "=&r" (__res), "+A" (*(addr)), "=&r" (__temp)	\
+	: "r" (__NOP(mask))				\
+	: "memory")
+
+#define ALT_ARCH_XCHG(sfx, prepend, append, r, p, n, temp)	\
+asm(ALTERNATIVE(						\
+		prepend						\
+		"	amoswap" sfx " %0, %3, %1\n"		\
+		__nops(2)					\
+		append,						\
+		prepend						\
+		"1:	lr" sfx " %0, %1\n"			\
+		"	sc" sfx " %2, %3, %1\n"			\
+		"	bnez %2, 1b\n"				\
+		append,						\
+		0, RISCV_ISA_EXT_ZALRSC, 1)			\
+	: "=&r" (r), "+A" (*(p)), "=&r" (temp)			\
+	: "r" (n)						\
+	: "memory")
+
+/* FUTEX.H */
+#define ALT_FUTEX_ATOMIC_OP(insn, ret, oldval, uaddr, oparg, temp)	\
+asm(ALTERNATIVE(							\
+		"1: amo" #insn ".w.aqrl %[ov],%z[op],%[u]\n"		\
+		__nops(3)						\
+		"2:\n"							\
+		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r]),			\
+		"1:	lr.w.aqrl %[ov], %[u]\n"			\
+		"	" #insn " %[t], %[ov], %z[op]\n"		\
+		"	sc.w.aqrl %[t], %[t], %[u]\n"			\
+		"	bnez %[t], 1b\n"				\
+		"2:\n"							\
+		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r]),			\
+		0, RISCV_ISA_EXT_ZALRSC, 1)				\
+	: [r] "+r" (ret), [ov] "=&r" (oldval),				\
+	  [t] "=&r" (temp), [u] "+m" (*(uaddr))				\
+	: [op] "Jr" (oparg)						\
+	: "memory")
+
+#define ALT_FUTEX_ATOMIC_SWAP(ret, oldval, uaddr, oparg, temp)	\
+asm(ALTERNATIVE(						\
+		"1: amoswap.w.aqrl %[ov],%z[op],%[u]\n"		\
+		__nops(3)					\
+		"2:\n"						\
+		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r]),		\
+		"1:	lr.w.aqrl %[ov], %[u]\n"		\
+		"	mv %[t], %z[op]\n"			\
+		"	sc.w.aqrl %[t], %[t], %[u]\n"		\
+		"	bnez %[t], 1b\n"			\
+		"2:\n"						\
+		_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[r]),		\
+		0, RISCV_ISA_EXT_ZALRSC, 1)			\
+	: [r] "+r" (ret), [ov] "=&r" (oldval),			\
+	  [t] "=&r" (temp), [u] "+m" (*(uaddr))			\
+	: [op] "Jr" (oparg)					\
+	: "memory")
+
+/* atomics - end */
 #ifdef CONFIG_RISCV_ISA_ZICBOP
 #define ARCH_HAS_PREFETCH
 static inline void prefetch(const void *x)
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 3dbc8cc557dd..b1db42e50891 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -82,9 +82,15 @@ 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;
+	}
+	/* any atomic supported? */
+	if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
+	    of_property_match_string(node, "riscv,isa-extensions", "zaamo") < 0 &&
+	    of_property_match_string(node, "riscv,isa-extensions", "zalrsc") < 0) {
+		pr_warn("CPU with hartid=%lu does not support any atomics", *hart);
 		return -ENODEV;
 	}
 
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 72ca768f4e91..edfdd91cb1fd 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -1164,6 +1164,11 @@ static bool riscv_cpufeature_patch_check(u16 id, u16 value)
 		 * then the alternative cannot be applied.
 		 */
 		return riscv_cboz_block_size <= (1U << value);
+	case RISCV_ISA_EXT_ZALRSC:
+		/*
+		 * Aply ZALRSC alternatives only if ZAAMO not available
+		 */
+		return !__riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ZAAMO);
 	}
 
 	return false;
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 9b9dec6893b8..e54d299bad9d 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -73,7 +73,13 @@
 	beq	a2, zero, .Lnew_vmalloc_restore_context
 
 	/* Atomically reset the current cpu bit in new_vmalloc */
-	amoxor.d	a0, a1, (a0)
+	ALTERNATIVE("amoxor.d a0, a1, (a0);	\
+		     .rept 3; nop; .endr;",
+		    "1:	lr.d a2, (a0);		\
+			xor a2, a2, a1;		\
+			sc.d a2, a2, (a0);	\
+			bnez a2, 1b;",
+		     0, RISCV_ISA_EXT_ZALRSC, 1)
 
 	/* Only emit a sfence.vma if the uarch caches invalid entries */
 	ALTERNATIVE("sfence.vma", "nop", 0, RISCV_ISA_EXT_SVVPTC, 1)

base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo"
  2026-01-14  7:25 [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo" Vladimir Kondratiev
@ 2026-01-17  1:50 ` Paul Walmsley
  2026-01-19  7:29   ` Vladimir Kondratiev
  0 siblings, 1 reply; 10+ messages in thread
From: Paul Walmsley @ 2026-01-17  1:50 UTC (permalink / raw)
  To: Vladimir Kondratiev, Palmer Dabbelt
  Cc: Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Paul Walmsley, Albert Ou, Alexandre Ghiti, Yury Norov,
	Rasmus Villemoes, Chao-ying Fu, Aleksandar Rikalo,
	Aleksa Paunovic, linux-kernel, linux-riscv, torvalds, olof

Hi,

On Wed, 14 Jan 2026, Vladimir Kondratiev wrote:

> riscv have 3 instruction set extensions related to atomic operations:
> - "zaamo": atomic instructions like AMOADD
> - "zalrsc": LR and SC instructions
> - "a" that is "zaamo" + "zalrsc"
> 
> Historically, "a" was first, and Linux was relying on "a";
> then "zaamo"/"zalrsc" was introduced. It is possible to implement
> most atomic operations with either AMO or LR/SC. AMO if more efficient
> however more complex flows are possible with LR/SC only.
> 
> Platforms supporting only part of atomics starting to appear.
> Notable is MIPS P8700 CPU [1] having only "zalrsc".

Are there any others?

Are development boards available yet for these kinds of designs?

> CPU reports ISA extensions supported in the "riscv,isa-extensions"
> property of the CPU OF node. Platform supporting "zalrsc" only should
> report "zalrsc" but no "a" in this property.
> 
> For the early stages of execution, before alternatives applied,
> (ex: head.S) CPUs having no "zaamo" extension rely on firmware
> emulating AMO through "invalid instruction" trap to the M-mode.
> 
> Speed-up the rest of execution using ALTERNATIVE,
> replacing AMO versions with LR/SC ones
> 
> Implementation is generic, inspired by the patch [2]
> by developers listed below, implementing similar patch as errata
> for the MIPS P8700 CPU

This doesn't look like an erratum.  The designers of this core just chose 
not to implement A support in this CPU, and that's why that AMO_II bit 
exists in the mipsconfig6 register, correct?

> [1] https://mips.com/products/hardware/p8700/
> [2] https://lore.kernel.org/all/20251014-p8700-zalrsc-v3-1-9d81bd8093e0@htecgroup.com/
> 
> Suggested-by: Chao-ying Fu <cfu@mips.com>
> Suggested-by: Aleksandar Rikalo <arikalo@gmail.com>
> Suggested-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>

I guess the proposal here is for the upstream kernel community to weaken 
our A support requirement to support these special cores that only support 
LR/SC?  

If so, I suppose the question is, should anyone in the upstream kernel 
community care about this case?  It wouldn't be enough for the kernel 
alone to support this.  A special userspace would also be needed.

This looks like a variant of the big-endian issue discussed earlier, 
 
  https://lore.kernel.org/linux-riscv/CAHk-=wgfpswvq0TypePyjv3dofO5YaUC_fSd_MjzY7jogCUnCg@mail.gmail.com/

If we take these changes, it increases the complexity of the upstream 
kernel, and increases our testing matrix as maintainers (and, in theory, 
for any patch submitters, who should theoretically be testing their work 
on the configurations that we support).  It's not clear what the gain 
would be for the broader community.  As maintainers, we're already 
considering stripping out other code that doesn't seem to have significant 
community support, like no-MMU, for similar reasons.

On the other hand, if boards with Zalrsc-only cores seemed popular in the 
marketplace, and some sort of support existed in common userspaces, such 
that we could be sure that there was some sort of commitment to maintain 
this across the entire ecosystem, the discussion could be more favorable, 
I guess?

Palmer might have some other thoughts here.


- Paul

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo"
  2026-01-17  1:50 ` Paul Walmsley
@ 2026-01-19  7:29   ` Vladimir Kondratiev
  2026-01-19 17:17     ` Gary Guo
  0 siblings, 1 reply; 10+ messages in thread
From: Vladimir Kondratiev @ 2026-01-19  7:29 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt
  Cc: Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Albert Ou, Alexandre Ghiti, Yury Norov, Rasmus Villemoes,
	Chao-ying Fu, Aleksandar Rikalo, Aleksa Paunovic,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	torvalds@linux-foundation.org, olof@lixom.net

> > Historically, "a" was first, and Linux was relying on "a";
> > then "zaamo"/"zalrsc" was introduced. It is possible to implement
> > most atomic operations with either AMO or LR/SC. AMO if more efficient
> > however more complex flows are possible with LR/SC only.
> >
> > Platforms supporting only part of atomics starting to appear.
> > Notable is MIPS P8700 CPU [1] having only "zalrsc".
> 
> Are there any others?

I don't know, I am working with the Mobileye platform only

> Are development boards available yet for these kinds of designs?

Sorry, no. Mobileye does not release (as of now) boards to the public, it
works only with automotive companies

<skip> 
> > Implementation is generic, inspired by the patch [2]
> > by developers listed below, implementing similar patch as errata
> > for the MIPS P8700 CPU
> 
> This doesn't look like an erratum.  The designers of this core just chose
> not to implement A support in this CPU, and that's why that AMO_II bit
> exists in the mipsconfig6 register, correct?

Absolutely agree; this is why I re-factored this as a generic feature
rather than errata.

<skip>
> I guess the proposal here is for the upstream kernel community to weaken
> our A support requirement to support these special cores that only support
> LR/SC? 

Yes indeed. In fact, any AMO instruction may be re-implemented as an LR/SC
sequence provided memory area is LR/SC capable; opposite is not true.
Actually "a" is not a real requirement to implement atomics, we just need
some way to do so, and "LR/SC only" is sufficient.

> If so, I suppose the question is, should anyone in the upstream kernel
> community care about this case?  It wouldn't be enough for the kernel
> alone to support this.  A special userspace would also be needed.

Userspace should provide "-march=rv64imc_zalrsc" instead of "-march=rv64imac"
for all compilation; this will instruct compiler to use LR/SC for atomic_t and alike

<skip>
> If we take these changes, it increases the complexity of the upstream
> kernel, and increases our testing matrix as maintainers (and, in theory,
> for any patch submitters, who should theoretically be testing their work
> on the configurations that we support).  It's not clear what the gain
> would be for the broader community.  As maintainers, we're already
> considering stripping out other code that doesn't seem to have significant
> community support, like no-MMU, for similar reasons.
> 
> On the other hand, if boards with Zalrsc-only cores seemed popular in the
> marketplace, and some sort of support existed in common userspaces, such
> that we could be sure that there was some sort of commitment to maintain
> this across the entire ecosystem, the discussion could be more favorable,
> I guess?

I understand the argument, but I can't say for all risc-v community or how
important is Mobileye chip to justify special support.
CPU vendor is MIPS, perhaps they can share arguments about decision to
implement only LR/SC but not AMO.
Good if people crafting LR/SC only platforms will comment here. 

> 
> Palmer might have some other thoughts here.

Thanks, Vladimir

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo"
  2026-01-19  7:29   ` Vladimir Kondratiev
@ 2026-01-19 17:17     ` Gary Guo
  2026-01-19 17:40       ` Linus Torvalds
  2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
  0 siblings, 2 replies; 10+ messages in thread
From: Gary Guo @ 2026-01-19 17:17 UTC (permalink / raw)
  To: Vladimir Kondratiev, Paul Walmsley, Palmer Dabbelt
  Cc: Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Albert Ou, Alexandre Ghiti, Yury Norov, Rasmus Villemoes,
	Chao-ying Fu, Aleksandar Rikalo, Aleksa Paunovic,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	torvalds@linux-foundation.org, olof@lixom.net

On Mon Jan 19, 2026 at 7:29 AM GMT, Vladimir Kondratiev wrote:
>> > Historically, "a" was first, and Linux was relying on "a";
>> > then "zaamo"/"zalrsc" was introduced. It is possible to implement
>> > most atomic operations with either AMO or LR/SC. AMO if more efficient
>> > however more complex flows are possible with LR/SC only.
>> >
>> > Platforms supporting only part of atomics starting to appear.
>> > Notable is MIPS P8700 CPU [1] having only "zalrsc".
>> 
>> Are there any others?
>
> I don't know, I am working with the Mobileye platform only
>
>> Are development boards available yet for these kinds of designs?
>
> Sorry, no. Mobileye does not release (as of now) boards to the public, it
> works only with automotive companies
>
> <skip> 
>> > Implementation is generic, inspired by the patch [2]
>> > by developers listed below, implementing similar patch as errata
>> > for the MIPS P8700 CPU
>> 
>> This doesn't look like an erratum.  The designers of this core just chose
>> not to implement A support in this CPU, and that's why that AMO_II bit
>> exists in the mipsconfig6 register, correct?
>
> Absolutely agree; this is why I re-factored this as a generic feature
> rather than errata.
>
> <skip>
>> I guess the proposal here is for the upstream kernel community to weaken
>> our A support requirement to support these special cores that only support
>> LR/SC? 
>
> Yes indeed. In fact, any AMO instruction may be re-implemented as an LR/SC
> sequence provided memory area is LR/SC capable; opposite is not true.
> Actually "a" is not a real requirement to implement atomics, we just need
> some way to do so, and "LR/SC only" is sufficient.

Most RVA processors today the full A extensions, and multiple distros built
software for the full A extensions. On these machines you're just adding
extra space overhead to all atomic accesses.

At minimum, it needs to be something that can compiled out completely using
Kconfig, so say, Debian's RISC-V build won't need to include any of these. The
need to rebuild entire userspace certainly suggest that ALTERNATIVE mechanism
isn't the correct tool here.

>
>> If so, I suppose the question is, should anyone in the upstream kernel
>> community care about this case?  It wouldn't be enough for the kernel
>> alone to support this.  A special userspace would also be needed.
>
> Userspace should provide "-march=rv64imc_zalrsc" instead of "-march=rv64imac"
> for all compilation; this will instruct compiler to use LR/SC for atomic_t and alike
>
> <skip>
>> If we take these changes, it increases the complexity of the upstream
>> kernel, and increases our testing matrix as maintainers (and, in theory,
>> for any patch submitters, who should theoretically be testing their work
>> on the configurations that we support).  It's not clear what the gain
>> would be for the broader community.  As maintainers, we're already
>> considering stripping out other code that doesn't seem to have significant
>> community support, like no-MMU, for similar reasons.
>> 
>> On the other hand, if boards with Zalrsc-only cores seemed popular in the
>> marketplace, and some sort of support existed in common userspaces, such
>> that we could be sure that there was some sort of commitment to maintain
>> this across the entire ecosystem, the discussion could be more favorable,
>> I guess?
>
> I understand the argument, but I can't say for all risc-v community or how
> important is Mobileye chip to justify special support.
> CPU vendor is MIPS, perhaps they can share arguments about decision to
> implement only LR/SC but not AMO.
> Good if people crafting LR/SC only platforms will comment here. 

I'd be curious to know if any kind of performance evaluation has been done.
atomic_inc is quite heavily used in the kernel.

Best,
Gary

>
>> 
>> Palmer might have some other thoughts here.
>
> Thanks, Vladimir


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo"
  2026-01-19 17:17     ` Gary Guo
@ 2026-01-19 17:40       ` Linus Torvalds
  2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
  1 sibling, 0 replies; 10+ messages in thread
From: Linus Torvalds @ 2026-01-19 17:40 UTC (permalink / raw)
  To: Gary Guo
  Cc: Vladimir Kondratiev, Paul Walmsley, Palmer Dabbelt, Will Deacon,
	Peter Zijlstra, Boqun Feng, Mark Rutland, Albert Ou,
	Alexandre Ghiti, Yury Norov, Rasmus Villemoes, Chao-ying Fu,
	Aleksandar Rikalo, Aleksa Paunovic, linux-kernel@vger.kernel.org,
	linux-riscv@lists.infradead.org, olof@lixom.net

On Mon, 19 Jan 2026 at 09:17, Gary Guo <gary@garyguo.net> wrote:
>
> I'd be curious to know if any kind of performance evaluation has been done.
> atomic_inc is quite heavily used in the kernel.

LR/SC isn't generally a huge problem in itself - the problem is
typically that it requires a somewhat smart cache coherency to not get
into nasty "almost livelock" situations where heavy contention can
make things very unfair, and while the system on the whole makes
progress, some cores may end up starved.

That typically isn't seen unless you have lots of cores, though.

Of course, any CPU design that then left out AMO instructions in the
name of simplicity, probably *also* didn't put a lot of effort into
making the cache coherency have any kind of fairness guarantees.

So the platform is probably garbage for various other reasons.

             Linus

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO
  2026-01-19 17:17     ` Gary Guo
  2026-01-19 17:40       ` Linus Torvalds
@ 2026-01-20 14:26       ` Vladimir Kondratiev
  2026-01-20 14:26         ` [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc" Vladimir Kondratiev
                           ` (2 more replies)
  1 sibling, 3 replies; 10+ messages in thread
From: Vladimir Kondratiev @ 2026-01-20 14:26 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
	aleksa.paunovic, arikalo
  Cc: Vladimir Kondratiev, linux-riscv, linux-kernel,
	Vladimir.Kondratiev

Primary goal is to support Mobileye eyeq7h automotive platform
based on MIPS P8700 CPU [1] having only "zalrsc" ISA extension but
not full "a".

Such platforms need userspace to be compiled with correct
"-march" flags to generate proper instructions for the atomic types
so there's not feasible to use universal userspace for it.
Thus there's no point to do same binary kernel suitable for both
"full A" and "LRSC only" platform types. Do a compile time
alternatives and require CONFIG_NONPORTABLE for this

[1] https://mips.com/products/hardware/p8700/

Patch 1 do most of work to provide compile-time LR/SC alternatives
        for the AMO instructions
Patch 2 adjust tests for reported CPU extensions compatibility with
        the code

Changes in v2: switch from dynamic atomic flavor resolution to
compile-time one.

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
Vladimir Kondratiev (2):
      riscv: support ISA extensions "zaamo" and "zalrsc"
      riscv: more accurate check for CPU atomics support

 arch/riscv/Kconfig               | 19 ++++++++++++++
 arch/riscv/Makefile              | 16 ++++++++----
 arch/riscv/include/asm/atomic.h  | 56 +++++++++++++++++++++++++++++++++++++++-
 arch/riscv/include/asm/bitops.h  | 48 ++++++++++++++++++++++++++++++++++
 arch/riscv/include/asm/cmpxchg.h | 18 +++++++++++++
 arch/riscv/include/asm/futex.h   | 52 +++++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/cpu.c          | 22 +++++++++++++---
 arch/riscv/kernel/entry.S        |  9 +++++++
 arch/riscv/kernel/head.S         | 18 +++++++++++++
 9 files changed, 248 insertions(+), 10 deletions(-)
---
base-commit: 7d0a66e4bb9081d75c82ec4957c50034cb0ea449
change-id: 20260120-lrsc-only-cc06422f5bb1

Best regards,
-- 
Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc"
  2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
@ 2026-01-20 14:26         ` Vladimir Kondratiev
  2026-01-20 14:26         ` [PATCH v2 2/2] riscv: more accurate check for CPU atomics support Vladimir Kondratiev
  2026-01-21 18:19         ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Paul Walmsley
  2 siblings, 0 replies; 10+ messages in thread
From: Vladimir Kondratiev @ 2026-01-20 14:26 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
	aleksa.paunovic, arikalo
  Cc: Vladimir Kondratiev, linux-riscv, linux-kernel,
	Vladimir.Kondratiev

riscv have 3 instruction set extensions related to atomic operations:
- "zaamo": atomic instructions like AMOADD
- "zalrsc": LR and SC instructions
- "a" that is "zaamo" + "zalrsc"

Historically, "a" was first, and Linux was relying on "a";
then "zaamo"/"zalrsc" was introduced. It is possible to implement
most atomic operations with either AMO or LR/SC. AMO if more efficient
however more complex flows are possible with LR/SC only.

Platforms supporting only part of atomics starting to appear.
Notable is MIPS P8700 CPU [1] having only "zalrsc".

Support configurations not having "A" but supporting one of
"zaamo"/"zalrsc".

The "RISC-V C API" [2] defines architecture extension test macros.
It says naming rule for the test macros is __riscv_<ext_name>, where
<ext_name> is all lower-case.

Alternative to the __riscv_a macro name, __riscv_atomic, is deprecated
but used by old toolchains.

Fix "-march" compiler flag and use extension test macros in code

For decisions use
 #if defined(__riscv_atomic) || defined(__riscv_zaamo)
For the full "A" support, old toolchains set __riscv_atomic while
new ones set __riscv_a, __riscv_zaamo and __riscv_zalrsc

Add alternative LR/SC implementations for AMO based code fragments,
prefer AMO if possible and fallback to LR/SC

[1] https://mips.com/products/hardware/p8700/
[2] https://github.com/riscv-non-isa/riscv-c-api-doc

Suggested-by: Chao-ying Fu <cfu@wavecomp.com>
Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
 arch/riscv/Kconfig               | 19 ++++++++++++++
 arch/riscv/Makefile              | 16 ++++++++----
 arch/riscv/include/asm/atomic.h  | 56 +++++++++++++++++++++++++++++++++++++++-
 arch/riscv/include/asm/bitops.h  | 48 ++++++++++++++++++++++++++++++++++
 arch/riscv/include/asm/cmpxchg.h | 18 +++++++++++++
 arch/riscv/include/asm/futex.h   | 52 +++++++++++++++++++++++++++++++++++++
 arch/riscv/kernel/entry.S        |  9 +++++++
 arch/riscv/kernel/head.S         | 18 +++++++++++++
 8 files changed, 230 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index fadec20b87a8e3ef97bed64270e496ddb45244ac..824c9c64851c1c4d751d1a6b3c81e6a519e9fb31 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -710,6 +710,25 @@ 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
+	   support AMO instructions.
+
+	   If you don't know what to do here, say Y.
+
+config RISCV_ISA_ZALRSC
+	bool "Zalrsc extension support for LR/SC atomics" if NONPORTABLE
+	default y
+	help
+	   support lr and sc to build atomic functions.
+
+	   If you don't know what to do here, say Y.
+
+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 4c6de57f65ef0e0339358f6c9ab8d4e7a6d1263f..607f3e12e9ccda5fe031821965a4e4901925b715 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
@@ -81,14 +82,19 @@ riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) := $(riscv-march-y)_zacas
 # Check if the toolchain supports Zabha
 riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) := $(riscv-march-y)_zabha
 
+# 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 += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima|rv64ima)fd([^v_]*)v?/\1\2/')
-
+KBUILD_CFLAGS += -march=$(shell echo $(riscv-march-y) | sed -E 's/(rv32ima?|rv64ima?)fd([^v_]*)v?/\1\2/')
 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 5b96c2f61adb596caf8ee6355d4ee86dbc19903b..1fa57e5a19590c668e81341c05aaff14a0bee6b9 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 arithmatic 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 77880677b06e03875721f33515a6d2ac9166c373..994b15c8a5cd3349bc929cc847ffde4629ce0251 100644
--- a/arch/riscv/include/asm/bitops.h
+++ b/arch/riscv/include/asm/bitops.h
@@ -187,12 +187,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;				\
@@ -211,6 +216,35 @@ 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)			\
+	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")
+#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)
@@ -354,12 +388,26 @@ 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 122e1485d39a0ad44ec4357cb23148dc6e58dc6b..c0feb20241590a589e5d62d08a8f6c9a37d339c3 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -54,6 +54,7 @@
 	}									\
 })
 
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
 #define __arch_xchg(sfx, prepend, append, r, p, n)			\
 ({									\
 	__asm__ __volatile__ (						\
@@ -64,6 +65,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 90c86b115e008a1fb08f3da64382fb4a64d9cc2f..bb9393a2a1abd19f56d9f960a207e24dadf30670 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,16 +33,43 @@
 	: "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"	\
+	"	sc.w.aqrl %[t], %[t], %[u]		\n"	\
+	"	bnez %[t], 1b				\n"	\
+	"2:						\n"	\
+	_ASM_EXTABLE_UACCESS_ERR(1b, 2b, %[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;
 
 	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);
@@ -62,6 +90,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 9b9dec6893b81a6b0c39af654590848e9ef754c1..a9a39a15a7c685265527be74e37c37add7416446 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -73,7 +73,16 @@
 	beq	a2, zero, .Lnew_vmalloc_restore_context
 
 	/* Atomically reset the current cpu bit in new_vmalloc */
+#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
 
 	/* Only emit a sfence.vma if the uarch caches invalid entries */
 	ALTERNATIVE("sfence.vma", "nop", 0, RISCV_ISA_EXT_SVVPTC, 1)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index bdf3352acf4cb48aaaa47f7b0e5fc98c0c5b1712..6e4c977ff782f78e23cb344cc28f98ea20f016f6 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -259,7 +259,17 @@ 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)
+1:	lr.w t0, (a3)
+	addw 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
 
 #else
@@ -269,7 +279,15 @@ SYM_CODE_START(_start_kernel)
 	XIP_FIXUP_OFFSET a2
 	XIP_FIXUP_FLASH_OFFSET a3
 	lw t1, (a3)
+#if defined(__riscv_atomic) || defined(__riscv_zaamo)
 	amoswap.w t0, t1, (a2)
+#elif defined(__riscv_zalrsc)
+1:	lr.w t0, (a2)
+	sc.w t2, t1, (a2)
+	bnez t2, 1b
+#else
+#error "Need AMO or LR/SC atomics"
+#endif
 	/* first time here if hart_lottery in RAM is not set */
 	beq t0, t1, .Lsecondary_start
 

-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/2] riscv: more accurate check for CPU atomics support
  2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
  2026-01-20 14:26         ` [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc" Vladimir Kondratiev
@ 2026-01-20 14:26         ` Vladimir Kondratiev
  2026-01-21 18:19         ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Paul Walmsley
  2 siblings, 0 replies; 10+ messages in thread
From: Vladimir Kondratiev @ 2026-01-20 14:26 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
	aleksa.paunovic, arikalo
  Cc: Vladimir Kondratiev, linux-riscv, linux-kernel,
	Vladimir.Kondratiev

CPU reports extensions supported in "riscv,isa-extensions" property
of the CPU node, for atomic operations it is
- "a" extension meaning both AMO and LR/SC supported
- "zaamo" extension meaning AMO instructions supported
- "zalrsc" extension meaning LR/SC supported

Code can also be compiled with subset of atomics support

Relax requirements for CPU extension support from full "a"
to subset compatible with software configuration

Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
---
 arch/riscv/kernel/cpu.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index 3dbc8cc557dd1d71101959a003ea7195af3c92a0..84d4a549b6136e0c97a35025a18ce710afbedad5 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -82,12 +82,26 @@ 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;
 	}
-
+	/* any atomic supported? */
+#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;
+	}
+#elif 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 LS/SC atomics", *hart);
+		return -ENODEV;
+	}
+#else
+#error "need atomic or zalrsc extension"
+#endif
 	return 0;
 
 old_interface:

-- 
2.43.0


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO
  2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
  2026-01-20 14:26         ` [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc" Vladimir Kondratiev
  2026-01-20 14:26         ` [PATCH v2 2/2] riscv: more accurate check for CPU atomics support Vladimir Kondratiev
@ 2026-01-21 18:19         ` Paul Walmsley
  2026-04-08 11:50           ` Aleksa Paunovic
  2 siblings, 1 reply; 10+ messages in thread
From: Paul Walmsley @ 2026-01-21 18:19 UTC (permalink / raw)
  To: Vladimir Kondratiev
  Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo,
	Yury Norov, Rasmus Villemoes, cfu, torvalds, olof,
	aleksa.paunovic, arikalo, linux-riscv, linux-kernel

Hi Vladimir,

On Tue, 20 Jan 2026, Vladimir Kondratiev wrote:

> Primary goal is to support Mobileye eyeq7h automotive platform
> based on MIPS P8700 CPU [1] having only "zalrsc" ISA extension but
> not full "a".
> 
> Such platforms need userspace to be compiled with correct
> "-march" flags to generate proper instructions for the atomic types
> so there's not feasible to use universal userspace for it.
> Thus there's no point to do same binary kernel suitable for both
> "full A" and "LRSC only" platform types. Do a compile time
> alternatives and require CONFIG_NONPORTABLE for this
> 
> [1] https://mips.com/products/hardware/p8700/
> 
> Patch 1 do most of work to provide compile-time LR/SC alternatives
>         for the AMO instructions
> Patch 2 adjust tests for reported CPU extensions compatibility with
>         the code
> 
> Changes in v2: switch from dynamic atomic flavor resolution to
> compile-time one.
> 
> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>

Thanks for updating the patches so quickly to deal with Gary's comments. I 
think we should hold off on merging them until common userspace providers 
(like Linux distributions) or distribution builders (like OE/Yocto or 
Buildroot) merge support for this configuration, along with underlying 
projects like glibc.  That way, the rest of us have a way to test our 
patches on this unusual configuration before sending them to the list, or 
sending PRs upstream.  It should be straightforward to get the Zalrsc-only 
userspace support patches tested on existing RISC-V Linux hardware, since 
it supports a superset of this behavior.  I guess the only question is 
whether other projects are interested in committing to carrying forward 
the necessary changes.

It also would be good to see publicly available MIPS P8700 boards being 
used on an ongoing basis by at least one active participant on this list, 
who can post Tested-by:s for key series and who can post review feedback 
and Reviewed-by:s for other RISC-V patch series.  That way, we'd have more 
confidence that there actually is an ongoing user population for this 
board who cares about upstream.  This is particularly important for folks 
who care about these MIPS P8700 cores, which don't seem to be a 
from-scratch design for RISC-V, and which don't have AMO support like all 
of the other cores we support.  (For what it's worth, we're trying to 
foster this engagement for other core microarchitectures as well; thanks 
Joel Stanley of TensTorrent, Andrew Jones and Anup Patel of 
Ventana/Qualcomm, and Andreas Korb of Fraunhofer working on the Core-V 
designs for showing how this is done.)


thanks,

- Paul



_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO
  2026-01-21 18:19         ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Paul Walmsley
@ 2026-04-08 11:50           ` Aleksa Paunovic
  0 siblings, 0 replies; 10+ messages in thread
From: Aleksa Paunovic @ 2026-04-08 11:50 UTC (permalink / raw)
  To: Paul Walmsley, Vladimir Kondratiev
  Cc: Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Will Deacon,
	Peter Zijlstra, Boqun Feng, Mark Rutland, Gary Guo, Yury Norov,
	Rasmus Villemoes, cfu@wavecomp.com, torvalds@linux-foundation.org,
	olof@lixom.net, arikalo@gmail.com,
	linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org

Hi Paul,

On 1/21/26 19:19, Paul Walmsley wrote:
> Hi Vladimir,
>
> On Tue, 20 Jan 2026, Vladimir Kondratiev wrote:
>
>> Primary goal is to support Mobileye eyeq7h automotive platform
>> based on MIPS P8700 CPU [1] having only "zalrsc" ISA extension but
>> not full "a".
>>
>> Such platforms need userspace to be compiled with correct
>> "-march" flags to generate proper instructions for the atomic types
>> so there's not feasible to use universal userspace for it.
>> Thus there's no point to do same binary kernel suitable for both
>> "full A" and "LRSC only" platform types. Do a compile time
>> alternatives and require CONFIG_NONPORTABLE for this
>>
>> [1] https://mips.com/products/hardware/p8700/
>>
>> Patch 1 do most of work to provide compile-time LR/SC alternatives
>>         for the AMO instructions
>> Patch 2 adjust tests for reported CPU extensions compatibility with
>>         the code
>>
>> Changes in v2: switch from dynamic atomic flavor resolution to
>> compile-time one.
>>
>> Signed-off-by: Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
> Thanks for updating the patches so quickly to deal with Gary's comments. I
> think we should hold off on merging them until common userspace providers
> (like Linux distributions) or distribution builders (like OE/Yocto or
> Buildroot) merge support for this configuration, along with underlying
> projects like glibc.  That way, the rest of us have a way to test our
> patches on this unusual configuration before sending them to the list, or
> sending PRs upstream.  It should be straightforward to get the Zalrsc-only
> userspace support patches tested on existing RISC-V Linux hardware, since
> it supports a superset of this behavior.  I guess the only question is
> whether other projects are interested in committing to carrying forward
> the necessary changes.

Zaamo instructions are emulated on the SBI level, so testing any future patches
on this configuration shouldn't be an issue. We have been using userspaces
with libraries compiled with upstream GCC releases for a while now.  

Of course, a Zalrsc-only userspace would probably work faster on the P8700.

> It also would be good to see publicly available MIPS P8700 boards being
> used on an ongoing basis by at least one active participant on this list,
> who can post Tested-by:s for key series and who can post review feedback
> and Reviewed-by:s for other RISC-V patch series.  That way, we'd have more
> confidence that there actually is an ongoing user population for this
> board who cares about upstream.  This is particularly important for folks
> who care about these MIPS P8700 cores, which don't seem to be a
> from-scratch design for RISC-V, and which don't have AMO support like all
> of the other cores we support.  (For what it's worth, we're trying to
> foster this engagement for other core microarchitectures as well; thanks
> Joel Stanley of TensTorrent, Andrew Jones and Anup Patel of
> Ventana/Qualcomm, and Andreas Korb of Fraunhofer working on the Core-V
> designs for showing how this is done.)

We tested the series on an eight-core QEMU configuration and the Boston board with a single-core MIPS P8700 CPU. 
Most of the testing was done using kselftests (futex, rseq, ptrace, and locking). 
We also ran an overnight locktorture test on the board, which completed without any issues. I should
note that the kernel we used for locktorture testing on the board was non-preemptive. I also ran a
brief rcutorture test on QEMU (a few hours) which showed no issues. 

The kernel was compiled with GCC 15.1.0, using GNU Binutils version 2.45. 

Best regards,
Aleksa Paunovic
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-04-08 11:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-14  7:25 [PATCH] riscv: support CPUs having only "zalrsc" but no "zaamo" Vladimir Kondratiev
2026-01-17  1:50 ` Paul Walmsley
2026-01-19  7:29   ` Vladimir Kondratiev
2026-01-19 17:17     ` Gary Guo
2026-01-19 17:40       ` Linus Torvalds
2026-01-20 14:26       ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Vladimir Kondratiev
2026-01-20 14:26         ` [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc" Vladimir Kondratiev
2026-01-20 14:26         ` [PATCH v2 2/2] riscv: more accurate check for CPU atomics support Vladimir Kondratiev
2026-01-21 18:19         ` [PATCH v2 0/2] Support for Risc-V CPUs implementing LR/SC but not AMO Paul Walmsley
2026-04-08 11:50           ` Aleksa Paunovic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox