From nobody Sun Feb 8 04:12:54 2026 Received: from esa4.hc555-34.eu.iphmx.com (esa4.hc555-34.eu.iphmx.com [207.54.77.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3BDF843C07B for ; Tue, 20 Jan 2026 14:26:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.54.77.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768919212; cv=none; b=DOzxjDhph4+eNj2Z55I9zFuLihn4ljRcHG4af2AeOoNXOMgjrLUbkVC4mqCA2NvAc6+6HIrbHOcS+/DRtfDqR5pS4EEQvR+Z29W8loszdQNCZQqrICSu7ls68sasWWUAJ7ZFSdoXmuyIhdUKsX3DCyvl+V3h059SGyfTPBv+i4Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768919212; c=relaxed/simple; bh=KgEbObj6LRbnWeJnWyMVVKHZSnBi7hTCUuGMjny4SlQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=odfBXvruemnDscXDNK7k1gu8C52P2Etexn5gIwWDnoYS0eYowMR02wOYXWa2fbmUEPR0blDCGDw5D7pklyZucaaH4Rks+iAe4QBCey2RHwZIsHi2EA53zYemNFM8GQVfSqXCO3JAZDm+x9bmHtfNIzkS8Trs4F9QvlHhGmZm0Ns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mobileye.com; spf=pass smtp.mailfrom=mobileye.com; dkim=fail (0-bit key) header.d=mobileye.com header.i=@mobileye.com header.b=etd+dLph reason="key not found in DNS"; arc=none smtp.client-ip=207.54.77.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mobileye.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mobileye.com Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mobileye.com header.i=@mobileye.com header.b="etd+dLph" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mobileye.com; i=@mobileye.com; q=dns/txt; s=MoEyIP; t=1768919209; x=1800455209; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KgEbObj6LRbnWeJnWyMVVKHZSnBi7hTCUuGMjny4SlQ=; b=etd+dLphOPYjuRQXzEfPDx4Dkjv84ZRpWPKRAzR00SnknQRL0p6GINGG +efhg8Em6h5DNr7HXIjrMEIiFG7Mae2uW10MzawN7T/W+zcf2HZARU4mZ DJyiZoK7eXNEnzW6NlCfRlw48PFU28/sxYU86vzP33gAVR9D6htQpJ9Z5 6SlIwVFZJyo2mFHMlfpg8E8u57d29dtZ1bbwvT7fEDYNm13ns72du7L7E jbsPjQzDqK0Fof8Yak6bI9xoDyI+t3k413IB5SDaTObAYmbcBLPkYarim PqI52S0S50edq56tEQArKYzOdHgtVIkbgghtbEYliV/ZkD0w747xleVxs Q==; X-CSE-ConnectionGUID: Dsrjy+i9SwahaNeHiSQ/Fw== X-CSE-MsgGUID: 6Wtf/lJsTJSb0t3buALnIA== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from unknown (HELO ces01_data.me-corp.lan) ([146.255.191.134]) by esa4.hc555-34.eu.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jan 2026 16:26:41 +0200 X-CSE-ConnectionGUID: BdjDCN4mSrKaOXvNp3LWBA== X-CSE-MsgGUID: TwPu6DwXQ32E+ztCmtG3dA== Received: from unknown (HELO epgd071.me-corp.lan) ([10.154.54.6]) by ces01_data.me-corp.lan with SMTP; 20 Jan 2026 16:28:36 +0200 Received: by epgd071.me-corp.lan (sSMTP sendmail emulation); Tue, 20 Jan 2026 16:26:40 +0200 From: Vladimir Kondratiev To: Paul Walmsley , 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, aleksa.paunovic@htecgroup.com, arikalo@gmail.com Cc: Vladimir Kondratiev , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Vladimir.Kondratiev@mobileye.com Subject: [PATCH v2 1/2] riscv: support ISA extensions "zaamo" and "zalrsc" Date: Tue, 20 Jan 2026 16:26:23 +0200 Message-ID: <20260120-lrsc-only-v2-1-a522e640d27d@mobileye.com> In-Reply-To: <20260120-lrsc-only-v2-0-a522e640d27d@mobileye.com> References: <20260120-lrsc-only-v2-0-a522e640d27d@mobileye.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.14.2 Content-Transfer-Encoding: quoted-printable 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_, where 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 Signed-off-by: Vladimir Kondratiev --- 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..824c9c64851c1c4d751d1a6b3c8= 1e6a519e9fb31 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -710,6 +710,25 @@ config RISCV_ISA_ZACAS =20 If you don't know what to do here, say Y. =20 +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..607f3e12e9ccda5fe031821965a= 4e4901925b715 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -58,8 +58,9 @@ ifeq ($(CONFIG_SHADOW_CALL_STACK),y) endif =20 # ISA string setting -riscv-march-$(CONFIG_ARCH_RV32I) :=3D rv32ima -riscv-march-$(CONFIG_ARCH_RV64I) :=3D rv64ima +riscv-march-$(CONFIG_ARCH_RV32I) :=3D rv32im +riscv-march-$(CONFIG_ARCH_RV64I) :=3D rv64im +riscv-march-$(CONFIG_RISCV_ISA_A) :=3D $(riscv-march-y)a riscv-march-$(CONFIG_FPU) :=3D $(riscv-march-y)fd riscv-march-$(CONFIG_RISCV_ISA_C) :=3D $(riscv-march-y)c riscv-march-$(CONFIG_RISCV_ISA_V) :=3D $(riscv-march-y)v @@ -81,14 +82,19 @@ riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZACAS) :=3D $(riscv-= march-y)_zacas # Check if the toolchain supports Zabha riscv-march-$(CONFIG_TOOLCHAIN_HAS_ZABHA) :=3D $(riscv-march-y)_zabha =20 +# if "A" not supported, toolchain shall support zaamo/zalrsc +ifneq ($(CONFIG_RISCV_ISA_A),y) +riscv-march-$(CONFIG_RISCV_ISA_ZAAMO) :=3D $(riscv-march-y)_zaamo +riscv-march-$(CONFIG_RISCV_ISA_ZALRSC) :=3D $(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 +=3D -march=3D$(shell echo $(riscv-march-y) | sed -E 's/(rv3= 2ima|rv64ima)fd([^v_]*)v?/\1\2/') - +KBUILD_CFLAGS +=3D -march=3D$(shell echo $(riscv-march-y) | sed -E 's/(rv3= 2ima?|rv64ima?)fd([^v_]*)v?/\1\2/') KBUILD_AFLAGS +=3D -march=3D$(riscv-march-y) =20 # For C code built with floating-point support, exclude V but keep F and D. -CC_FLAGS_FPU :=3D -march=3D$(shell echo $(riscv-march-y) | sed -E 's/(rv3= 2ima|rv64ima)([^v_]*)v?/\1\2/') +CC_FLAGS_FPU :=3D -march=3D$(shell echo $(riscv-march-y) | sed -E 's/(rv3= 2ima?|rv64ima?)([^v_]*)v?/\1\2/') =20 KBUILD_CFLAGS +=3D -mno-save-restore =20 diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomi= c.h index 5b96c2f61adb596caf8ee6355d4ee86dbc19903b..1fa57e5a19590c668e81341c05a= aff14a0bee6b9 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 on= ly * 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), "=3D&r" (ret), "=3D&r" (temp) \ + : "r" (I) \ + : "memory"); \ +} +#else +#error "Need AMO or LR/SC atomics" +#endif =20 #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 re= turn * 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, atom= ic##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), "=3D&r" (ret), "=3D&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), "=3D&r" (ret), "=3D&r" (temp) \ + : "r" (I) \ + : "memory"); \ + return ret; \ +} +#else +#error "Need AMO or LR/SC atomics" +#endif =20 #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/bitop= s.h index 77880677b06e03875721f33515a6d2ac9166c373..994b15c8a5cd3349bc929cc847f= fde4629ce0251 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) =20 #if (BITS_PER_LONG =3D=3D 64) #define __AMO(op) "amo" #op ".d" +#define __LR "lr.d" +#define __SC "sc.d" #elif (BITS_PER_LONG =3D=3D 32) #define __AMO(op) "amo" #op ".w" +#define __LR "lr.w" +#define __SC "sc.w" #else #error "Unexpected BITS_PER_LONG" #endif =20 +#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 =3D 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" \ + : "=3D&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=3D&r" (__temp) \ + : "r" (mod(__mask)) \ + : "memory"); \ + ((__res & __mask) !=3D 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" \ + : "=3D&r" (__res), "+A" (addr[BIT_WORD(nr)]), "=3D&r" (__temp) \ + : "r" (mod(BIT_MASK(nr))) \ + : "memory") +#else +#error "Need AMO or LR/SC atomics" +#endif =20 #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" : "=3Dr" (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" + : "=3D&r" (res), "+A" (*addr), "=3D&r" (temp) + : "r" (__NOP(mask)) + : "memory"); +#else +#error "Need AMO or LR/SC atomics" +#endif return (res & BIT(7)) !=3D 0; } =20 diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpx= chg.h index 122e1485d39a0ad44ec4357cb23148dc6e58dc6b..c0feb20241590a589e5d62d08a8= f6c9a37d339c3 100644 --- a/arch/riscv/include/asm/cmpxchg.h +++ b/arch/riscv/include/asm/cmpxchg.h @@ -54,6 +54,7 @@ } \ }) =20 +#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 \ + : "=3D&r" (r), "+A" (*(p)), "=3D&r" (temp) \ + : "r" (n) \ + : "memory"); \ +}) +#else +#error "Need AMO or LR/SC atomics" +#endif =20 #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..bb9393a2a1abd19f56d9f960a20= 7e24dadf30670 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 =20 +#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] "=3D&r" (oldval), \ + [t] "=3D&r" (temp), [u] "+m" (*(uaddr)) \ + : [op] "Jr" (oparg) \ + : "memory"); \ + __disable_user_access(); \ +} +#else +#error "Need AMO or LR/SC atomics" +#endif =20 static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uadd= r) { +#if defined(__riscv_atomic) || defined(__riscv_zaamo) int oldval =3D 0, ret =3D 0; +#elif defined(__riscv_zalrsc) + int oldval =3D 0, ret =3D 0, temp =3D 0; +#else +#error "Need AMO or LR/SC atomics" +#endif =20 if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; =20 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 =3D -ENOSYS; } diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 9b9dec6893b81a6b0c39af654590848e9ef754c1..a9a39a15a7c685265527be74e37= c37add7416446 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -73,7 +73,16 @@ beq a2, zero, .Lnew_vmalloc_restore_context =20 /* 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 =20 /* 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..6e4c977ff782f78e23cb344cc28= f98ea20f016f6 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 =20 #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 =20 --=20 2.43.0 From nobody Sun Feb 8 04:12:54 2026 Received: from esa4.hc555-34.eu.iphmx.com (esa4.hc555-34.eu.iphmx.com [207.54.77.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 17F7843D4F2 for ; Tue, 20 Jan 2026 14:26:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=207.54.77.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768919216; cv=none; b=BegroZCXO6ISe0n6QZ8p8LvO/H2XVms+qJtHug58/G+4Lj+7aWhz3Ra+6S8tEB/zDRt32AwTO0hskT2v6M9JexUPPYUDUxIjSFdv8Vcq6qjnNrPvSDBoh50ndMZKqnkU06AwWQVAfILP0FbKExrSkgdYWu0O72uocJkEYp5ejDo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768919216; c=relaxed/simple; bh=8EBLwHT55IuAbkABwax6AVrddslo69S70L3DGkHyKUU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Toe0pw6MrU45pPRx5tBlCAxg9NuCCnyCWkbBMW/wKLW/Qkv8AsbhTEIrpdEoCA96xiReodbtiiRTqI5KTazaKzIXYZylspCA1HzXOhMAmPw4tMN4RynMH5KzktlQa6tp80ccz2tsoXcHUBAIjWZzh9mxfpLpi6DEV4DqSAlSIK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mobileye.com; spf=pass smtp.mailfrom=mobileye.com; dkim=fail (0-bit key) header.d=mobileye.com header.i=@mobileye.com header.b=PBf2z58Z reason="key not found in DNS"; arc=none smtp.client-ip=207.54.77.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mobileye.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mobileye.com Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mobileye.com header.i=@mobileye.com header.b="PBf2z58Z" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=mobileye.com; i=@mobileye.com; q=dns/txt; s=MoEyIP; t=1768919213; x=1800455213; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8EBLwHT55IuAbkABwax6AVrddslo69S70L3DGkHyKUU=; b=PBf2z58ZyswSvoAo8ovxocpVTFx2my7xWtPdgCv+SZ9YFcBYphjFvhJ7 uP5cuh4+thJOtb9PXES5KxCsJPhSQIqNHDO5F4JIABlKtEWcctgD5sjd1 6ya2xRtYY/HTZGeHu6SdRl/VKqGJOxq+yCmPo9YtLc1QcNKatK6Yz9MEt AXLSgJvcF7a6M2U/BbRZXWNe60TUPpF1o1wESi8fpA2J/dS3kuWjam4iz KjqUU4tek5Z1ewTXS/DuNuaTeefUdnHYr9QpJ2bQWpOaPP8dRgxg99yna OwA2k9+ue0M/KmVve6yWAqPZ7xaL0mbHjJzFAXw6nPV3zE3kFVlJg7Qtc w==; X-CSE-ConnectionGUID: mY3C/lZxQ9+riliCFUNlcw== X-CSE-MsgGUID: oFqke7kCQKKBCthqGaX0Uw== X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from unknown (HELO ces03_data.me-corp.lan) ([146.255.191.134]) by esa4.hc555-34.eu.iphmx.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Jan 2026 16:26:43 +0200 X-CSE-ConnectionGUID: Pp58k23DRzexhP6tmk/wuQ== X-CSE-MsgGUID: i54Ppv5KSm6oKZVU4VwrHA== Received: from unknown (HELO epgd071.me-corp.lan) ([10.154.54.2]) by ces03_data.me-corp.lan with SMTP; 20 Jan 2026 16:28:31 +0200 Received: by epgd071.me-corp.lan (sSMTP sendmail emulation); Tue, 20 Jan 2026 16:26:41 +0200 From: Vladimir Kondratiev To: Paul Walmsley , 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, aleksa.paunovic@htecgroup.com, arikalo@gmail.com Cc: Vladimir Kondratiev , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Vladimir.Kondratiev@mobileye.com Subject: [PATCH v2 2/2] riscv: more accurate check for CPU atomics support Date: Tue, 20 Jan 2026 16:26:24 +0200 Message-ID: <20260120-lrsc-only-v2-2-a522e640d27d@mobileye.com> In-Reply-To: <20260120-lrsc-only-v2-0-a522e640d27d@mobileye.com> References: <20260120-lrsc-only-v2-0-a522e640d27d@mobileye.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" X-Mailer: b4 0.14.2 Content-Transfer-Encoding: quoted-printable 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 --- 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..84d4a549b6136e0c97a35025a18= ce710afbedad5 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 devic= e_node *node, unsigned lo return -ENODEV; =20 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=3D%lu does not support ima", *hart); + of_property_match_string(node, "riscv,isa-extensions", "m") < 0) { + pr_warn("CPU with hartid=3D%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=3D%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=3D%lu does not support LS/SC atomics", *hart); + return -ENODEV; + } +#else +#error "need atomic or zalrsc extension" +#endif return 0; =20 old_interface: --=20 2.43.0