Linux Trace Kernel
 help / color / mirror / Atom feed
* [PATCH v5 0/3] riscv: support CPUs with slow Zaamo
@ 2026-11-05 16:37 Vladimir Kondratiev
  2026-11-05 16:37 ` [PATCH v5 1/3] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Vladimir Kondratiev @ 2026-11-05 16:37 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Will Deacon, Peter Zijlstra, Mark Rutland, Gary Guo, Yury Norov,
	Rasmus Villemoes, Chao-ying Fu, torvalds, olof, aleksa.paunovic,
	arikalo, Boqun Feng, Alexei Starovoitov, Daniel Borkmann,
	Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
	Emil Tsalapatis, Ihor Solodrai, Luke Nelson, Xi Wang,
	Björn Töpel, Pu Lehui, Puranjay Mohan, Masami Hiramatsu,
	Oleg Nesterov, Boqun Feng
  Cc: linux-riscv, linux-kernel, Vladimir.Kondratiev, bpf,
	linux-trace-kernel, Vladimir Kondratiev

RISC-V split the A extension into Zaamo (AMO*.w/AMO*.d) and Zalrsc
(LR/SC). The kernel puts "a" in -march and emits AMO for atomic_add,
bitops, xchg and the like, and LR/SC for cmpxchg.

Zaamo is not always native. On MIPS P8700 [1] every AMO instruction
traps into M-mode and is emulated there, so the extension is formally
supported, and advertised to userspace, but very slow. A typical
uncontended atomic increment costs:

  native AMO                                     2..5 cycles
  LR/SC, private L1 reservation monitor         6..12 cycles
  LR/SC, PoC (L2) reservation monitor       about 40 cycles
  AMO emulated by an M-mode trap           about 600 cycles

The last two were measured on the eyeq7h hardware. On such a CPU the
kernel has to use LR/SC for every atomic.

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.

Patch 1 adds RISCV_ISA_ZAAMO. It defaults to y and nothing changes:
-march keeps "a" and the generated code is the same. When it is turned
off, -march carries _zalrsc instead of "a" and every kernel atomic is
an LR/SC loop. Such a kernel runs on any hart that implements A, it
just does not use AMO, so the option does not depend on NONPORTABLE.
Turning Zaamo off needs a compiler that accepts _zaamo and _zalrsc in
-march; GCC 15.1 is the first release that does.

The choice is made at compile time rather than with alternatives.
Nearly every CPU has a native A extension, and an alternative would
inflate all those kernels with the nops needed to pad one AMO to the
size of an LR/SC loop, at every atomic site, for the benefit of a few.

Nothing changes for userspace. The hart still advertises "a", which is
true. Userspace that cares can know about the slow AMO upfront, or
measure it.

Zalrsc stays mandatory. cmpxchg, conditional atomics and futex CAS are
already LR/SC sequences; Zaamo cannot replace them. RISCV_ISA_ZALRSC
is always y and exists as the Kconfig counterpart of
RISCV_ISA_EXT_ZALRSC, which hwcap.h already has next to
RISCV_ISA_EXT_ZAAMO; the two sets are tested together, for example by
rv_ext_enabled() in the BPF JIT. RISCV_ISA_A exists for the same
reason, paired with RISCV_ISA_EXT_A.

Three sets of extensions provide every atomic Linux needs: "a", which
is what the kernel supports today; Zalrsc plus Ziccrse, which this
series adds, with Ziccrse as the forward-progress guarantee for the
constrained LR/SC loops; and Zaamo plus Zacas, with CAS loops in place
of LR/SC as on x86. The series leaves the last one open:
RISCV_ISA_ZALRSC is where it would go, by allowing "n" there and making
amocas the base implementation.

The BPF JIT encodes its own atomics. Patch 2 makes it emit LR/SC loops
when Zaamo is disabled, so BPF programs do not trap either. The Zabha
and Zacas paths in the JIT and in cmpxchg.h are selected at runtime
from the ISA string; firmware for a CPU that emulates AMO should not
advertise them, as both extensions are AMO.

A breakpoint inside an LR/SC sequence drops the reservation and the
loop never completes. With every atomic an LR/SC loop that is easy to
hit, so patch 3 makes kprobes and uprobes reject such addresses.
kprobes walk from the enclosing symbol; uprobes scan forward using the
constrained-sequence rules from the ISA. This patch fixes a problem
that exists today, since cmpxchg is already an LR/SC loop. It does not
depend on the rest of the series and can be merged on its own.

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

Changes in v5:
- Treat Zaamo as supported but slow rather than absent. The hart keeps
  advertising "a" and the kernel keeps accepting it, so the boot-time
  extension check patch is dropped.
- Drop the NONPORTABLE dependency. A kernel built without Zaamo runs
  on any hart that implements A.
- Rename TOOLCHAIN_HAS_ZALRSC to TOOLCHAIN_HAS_ZALRSC_ZAAMO and test
  both _zaamo and _zalrsc in -march.
- Explain why RISCV_ISA_ZALRSC and RISCV_ISA_A exist, and why the
  choice is made at compile time rather than with alternatives.
- Add the BPF JIT patch. Without Zaamo the JIT emits LR/SC loops for
  the BPF read-modify-write atomics on RV32 and RV64, and reserves a
  second exception-table entry for the sc of an arena atomic.
- Reject kprobes and uprobes on lr and sc, and on any instruction
  between them.
- Link to v4: https://patch.msgid.link/20261101-lrsc-only-v4-0-4e1d010463b3@mobileye.com

Changes in v4:
- Require a compiler that accepts _zalrsc in -march before Zaamo can
  be disabled. GCC 15.1 introduces that support. Older compilers keep
  Zaamo enabled and -march keeps "a".
- Link to v3: https://patch.msgid.link/20261026-lrsc-only-v3-0-ec29c8190fb1@mobileye.com

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 (3):
      riscv: build kernel atomics from LR/SC when Zaamo is disabled
      riscv, bpf: emit LR/SC loops when Zaamo is disabled
      riscv: probes: reject probes inside an LR/SC sequence

 arch/riscv/Kconfig                     |  53 ++++++++++++++++
 arch/riscv/Makefile                    |  16 +++--
 arch/riscv/include/asm/atomic.h        |  52 +++++++++++++++-
 arch/riscv/include/asm/bitops.h        |  47 ++++++++++++++
 arch/riscv/include/asm/cmpxchg.h       |  16 +++++
 arch/riscv/include/asm/futex.h         |  45 ++++++++++++++
 arch/riscv/include/asm/insn.h          |  28 +++++++++
 arch/riscv/kernel/entry.S              |   7 +++
 arch/riscv/kernel/head.S               |  12 ++++
 arch/riscv/kernel/probes/decode-insn.c |  94 ++++++++++++++++++++++++++++
 arch/riscv/kernel/probes/decode-insn.h |   7 +++
 arch/riscv/kernel/probes/kprobes.c     |  22 ++++++-
 arch/riscv/kernel/probes/uprobes.c     |  31 ++++++++++
 arch/riscv/net/bpf_jit.h               |   1 +
 arch/riscv/net/bpf_jit_comp32.c        |  81 +++++++++++++++++++++++--
 arch/riscv/net/bpf_jit_comp64.c        | 108 ++++++++++++++++++++++++++++++++-
 arch/riscv/net/bpf_jit_core.c          |  29 +++++++++
 17 files changed, 636 insertions(+), 13 deletions(-)
---
base-commit: c03c1a14507dfaf8b856c2608f9ac216021fc222
change-id: 20260120-lrsc-only-cc06422f5bb1

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


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

end of thread, other threads:[~2026-11-05 17:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-05 16:37 [PATCH v5 0/3] riscv: support CPUs with slow Zaamo Vladimir Kondratiev
2026-11-05 16:37 ` [PATCH v5 1/3] riscv: build kernel atomics from LR/SC when Zaamo is disabled Vladimir Kondratiev
2026-11-05 17:03   ` sashiko-bot
2026-11-05 17:33   ` bot+bpf-ci
2026-11-05 16:37 ` [PATCH v5 2/3] riscv, bpf: emit LR/SC loops " Vladimir Kondratiev
2026-11-05 16:37 ` [PATCH v5 3/3] riscv: probes: reject probes inside an LR/SC sequence Vladimir Kondratiev
2026-11-05 16:54   ` sashiko-bot

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