RISC-V Without AMO: Building a Kernel for Cores That Only Implement Zalrsc
For as long as RISC-V has had a Linux port, one letter carried all of its atomic machinery:
“A”. A kernel built for rv64ima assumed the hart could both issue
AMO* read-modify-write instructions and run LR/SC reservation loops,
because the specification said A was one indivisible thing. It is not, and has not been since 2024. A
v4 patch series posted on 1 November 2026 by Vladimir Kondratiev of
Mobileye is the first attempt to teach the kernel about the difference — and the reason
is a shipping automotive CPU that implements only half of the letter.
linux-riscv mailing list, plus the ratified
Zaamo and Zalrsc specification v1.0.0 (2024-04-25). The series is at v4 and is not
merged. The cycle-cost figures are the author's own measurements on one part and have not been
independently reproduced here. Where the patch set's description of the silicon conflicts with the vendor's
own product page, both are quoted.The Letter That Stopped Being Atomic
The 20240411 revision of the RISC-V unprivileged manual closed a long-running argument by writing the answer into the A chapter itself: “The A extension comprises instructions provided by the Zaamo and Zalrsc extensions.” Two standalone specifications were then ratified on 25 April 2024, each describing exactly half of what A used to mean.
| Extension | Contains | Ratified | Why it exists |
|---|---|---|---|
| Zaamo | AMOSWAP, AMOADD, AMOAND,
AMOOR, AMOXOR, AMOMAX[U], AMOMIN[U] — .W
on RV32, .W/.D on RV64 | v1.0.0, 2024-04-25 | Cacheless microcontroller-class cores can offer atomics without reservation loops they cannot implement |
| Zalrsc | LR.W, SC.W on RV32; LR.W/LR.D,
SC.W/SC.D on RV64 | v1.0.0, 2024-04-25 | Fetch-and-op primitives scale better on highly parallel systems; simpler designs may implement only this subset |
| A | Alias for Zaamo + Zalrsc together | — | Kept for compatibility; Zacas (compare-and-swap) depends on Zaamo |
On paper this is bookkeeping. In practice it opened a door the kernel had welded shut: nothing in
arch/riscv distinguished the two halves, so a hart advertising zalrsc without
zaamo was simply rejected at boot. riscv_early_of_processor_hartid() demanded the
string a in riscv,isa-extensions and warned
“CPU with hartid=N does not support ima” if it was absent. Because the Linux workload
itself leans heavily on AMO — reference counts, bit operations, xchg, futex
compare-and-swap — assuming the full A extension was a reasonable default. It stopped being reasonable
the moment someone built a real core with only half of it.
The Silicon That Forced the Issue
That core is the MIPS P8700. MIPS, now a GlobalFoundries company, describes it as the
industry's first AI-enabled RISC-V automotive CPU: a 4-issue, 16-stage out-of-order pipeline with 1- or 2-way
simultaneous multithreading, a coherence manager supporting up to eight coherent initiators, up to 2 MB of
cluster-level L2, and a 256-bit ACE or AXI system interface. Its published ISA string is
RV64GCZba_Zbb plus MIPS custom instructions for memory operations and data movement. It is aimed
squarely at ADAS and autonomous driving, and the microarchitecture behind it already ships in more than 28 car
models.
According to the patch series, that core implements Zalrsc only. Its AMO
instructions do not execute in hardware; they trap into SBI and are emulated in firmware. Kondratiev measured
the consequence on typical userspace atomics:
| Atomic form | Implementation on MIPS P8700 | Typical cost |
|---|---|---|
LR/SC loop | Native hardware reservation | ~40 cycles |
AMO* | Traps to SBI, emulated | ~600 cycles |
Ratio, and it carries over to kernel refcounts, bitops, xchg and futexes |
~15× | |
Fifteen times is survivable in a benchmark and not survivable in a scheduler. Mobileye intends to use the eyeQ7H platform, built on this CPU, for ADAS and autonomous driving, where kernel atomics sit directly on the scheduling, memory-management and driver paths. Emulated AMO there is not a micro-optimisation problem; it is a latency problem on the critical path of a safety-relevant system.
RV64GCZba_Zbb, and G is defined as including A. The patch series states
that the silicon implements Zalrsc only, with AMO trapped to SBI. Both statements are
reproduced here as published. If the second is right, the vendor's ISA string is broader than the hardware, and
that is precisely the kind of gap a kernel needs to be told about rather than left to discover at a trap.Compile-Time, Not Runtime
The most interesting design decision in the series is the one that was reversed. v2 chose a runtime
alternative: patch the atomic primitives at boot depending on what the hart reported. v3 threw
that away in favour of a compile-time choice behind CONFIG_NONPORTABLE, and the cover
letter is explicit about why:
“The resulting kernel matches one
-march, which userspace has to use as well, so a runtime alternative would not produce a portable image.”
That is the whole argument in one sentence. A truly portable kernel image would have to carry both encodings
and pick between them at runtime; but the compiler decides instruction selection from the -march
string, so a kernel built without zaamo in its -march simply will not contain the
AMO sequences a runtime switch would need to fall back to. Since userspace is compiled against the
same baseline, a Zalrsc-only kernel is a platform decision, not an image property — and
platform decisions belong behind NONPORTABLE, where distributions cannot accidentally ship them.
The default behaviour is unchanged and that matters: both extensions stay on, -march keeps the
single letter a, and generated code is bit-identical to today.
What the Patch Set Actually Changes
Nine files, 267 insertions and 9 deletions, against base commit
c03c1a14507dfaf8b856c2608f9ac216021fc222. The structure is a new pair of Kconfig symbols that
decompose the old single assumption:
| Symbol | Type | Meaning |
|---|---|---|
TOOLCHAIN_HAS_ZALRSC | bool, auto | Probes with cc-option whether
the compiler accepts -march=rv64im_zalrsc. GCC 15.1 is where that support
arrives; older compilers fail the probe and the option cannot be turned off |
RISCV_ISA_ZAAMO | bool, default y | Visible only when
NONPORTABLE && TOOLCHAIN_HAS_ZALRSC. Turning it off compiles atomics from
LR/SC and switches -march from a to
_zalrsc |
RISCV_ISA_ZALRSC | def_bool y | Always on. Not a choice |
RISCV_ISA_A | def_bool | True only when
ZAAMO && ZALRSC — this is what keeps a in the ISA string on normal
builds |
Why Zalrsc is forced on rather than offered as a symmetric switch is spelled out in the commit
message: compare-and-swap already is an LR/SC sequence. cmpxchg, the conditional
atomics and the futex CAS path cannot be expressed in AMO at all, so Zaamo can be removed but
Zalrsc cannot. The 32-bit -march base also had to be split —
rv32ima/rv64ima become rv32im/rv64im with the
a appended conditionally, and the two sed expressions that strip V from the FPU
flags were widened from rv64ima to rv64ima? to keep matching when the letter is
absent.
The instruction-level work is mechanical but has to be exhaustive, because a single missed site gives you
an illegal instruction on the target part. arch/riscv/include/asm/atomic.h now selects between two
definitions of ATOMIC_OP and ATOMIC_FETCH_OP based on compiler-provided macros, with
a hard #error if neither is present:
#if defined(__riscv_atomic) || defined(__riscv_zaamo)
#define ATOMIC_OP(op, asm_op, I, asm_type, c_type, prefix) \
... asm_op " %0, %1, %2" /* single AMO instruction */ \
#elif defined(__riscv_zalrsc)
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
The ordered variants reuse the same loop and only change the acquire/release suffix on the two
reservation instructions (lr.d becomes lr.d.aqrl), which is a neat illustration of the
one genuine advantage AMO has: .aq/.rl on a single instruction replaces an explicit
fence pair. bitops.h gets the same treatment through a new __LR/__SC
macro pair, with __test_and_op_bit_ord() and __op_bit_ord() rebuilt as loops and
arch_xor_unlock_is_negative_byte() — the primitive behind set_bit_unlock_is_negative_byte()
in page-lock handling — rewritten as lr.rl / xor / sc.rl.
cmpxchg.h and futex.h follow.
Two details in the change history are the sort that only surface from real review. v3 had to
“remove the LR/SC loop that ran after the hart lottery and accessed address
1” — an early-boot path that would have tripped over a Zalrsc-only hart before memory was fully
mapped — and had to “add an exception-table entry for sc as well as
lr” in the futex helper, because a faulting store-conditional needs the same recovery
path as a faulting load-reserved.
The boot-time half
Patch 2 is the smaller of the two and, in a sense, the one that makes the first one usable. Rejecting a hart is what would have kept a Zalrsc-only board from booting at all, so the acceptance test now asks for exactly the forms the kernel was compiled to emit:
if (of_property_match_string(node, "riscv,isa-extensions", "i") < 0 ||
of_property_match_string(node, "riscv,isa-extensions", "m") < 0) {
pr_warn("CPU with hartid=%lu does not support im", *hart);
return -ENODEV;
}
#if defined(__riscv_atomic) || defined(__riscv_zaamo)
if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
of_property_match_string(node, "riscv,isa-extensions", "zaamo") < 0) {
pr_warn("CPU with hartid=%lu does not support AMO atomics", *hart);
return -ENODEV;
}
#endif
#if defined(__riscv_atomic) || defined(__riscv_zalrsc)
if (of_property_match_string(node, "riscv,isa-extensions", "a") < 0 &&
of_property_match_string(node, "riscv,isa-extensions", "zalrsc") < 0) {
pr_warn("CPU with hartid=%lu does not support LR/SC atomics", *hart);
return -ENODEV;
}
#endif
The single letter a satisfies either check, so a normal build behaves exactly as before while
gaining a better error message. The legacy riscv,isa fallback path keeps its
rv{32,64}ima string match, which means a Zalrsc-only hart must describe itself with the modern
riscv,isa-extensions property — no old-style ISA strings get to skip the new logic.
What It Does Not Fix
Three limitations are stated in the series itself, and they define the shape of what has been achieved.
BPF is still out. The cover letter is direct: “BPF atomic ops still emit
AMO and remain unsupported on a Zalrsc-only kernel.” Anything that reaches for
BPF_ATOMIC instructions will not work on P8700-class silicon regardless of this patch set. For an
ADAS image that is probably acceptable; for a general-purpose distribution kernel it is a hard blocker.
It is one platform, one -march, for the whole system. Turning
Zaamo off is a NONPORTABLE choice precisely because the resulting kernel matches a
single ISA string that userspace must also be compiled against. There is no portable cross-vendor image coming
out of this, and the series does not pretend otherwise.
It is v4 of an unmerged series. Patchwork lists both patches as New. The
40-versus-600-cycle numbers are the author's measurements on the target part. No hwprobe exposure,
no ACPI path, and no changes to how Zacas interacts with the split are included, and the
Zacas question is a real one: the ratified Zaamo text says Zacas depends on
Zaamo, so a Zalrsc-only kernel also cannot use the CAS instructions that would have been the
obvious fast path for a compare-and-swap replacement.
Why It Matters Past Automotive
RVA23 exists to stop RISC-V from fragmenting, and by and large it has worked: the lettered extensions became
mandatory baselines so that one binary could boot anywhere. But the A split created a legitimate, ratified,
profile-relevant way for a core to implement part of a letter, and Linux had no vocabulary for it. What this
series does is give the kernel that vocabulary in the place where it belongs — a Kconfig symbol behind
NONPORTABLE, a -march that stops lying, and a boot check that can name the missing
extension instead of vaguely complaining about ima.
That pattern is worth watching for anyone shipping or buying RISC-V silicon. If you are specifying a core,
the practical question is no longer “does it have A?” but “does it have both halves, and if
not, which one?” — because the answer determines whether your kernel is a normal build or a
NONPORTABLE one, and whether your BPF, your futexes and your page-lock fast path run in hardware
or in firmware.
一句话结论:RISC-V 的「A 扩展」自 2024 年被拆成 Zaamo(AMO 指令)与
Zalrsc(LR/SC)两个独立规范后,Linux 内核一直只认整字 A。Mobileye 的 Vladimir Kondratiev 于
2026 年 11 月 1 日发出 v4 补丁系列,首次让内核可以只依赖 Zalrsc 构建。
为什么现在才做:MIPS P8700(GlobalFoundries 旗下 MIPS,面向 ADAS/自动驾驶的 4 发射 16 级乱序核,1/2 路 SMT,最多 8 个一致性发起者、2MB 簇级 L2、256 位 ACE/AXI)据该系列称 只实现了 Zalrsc,AMO 指令会陷入 SBI 由固件模拟。作者实测:LR/SC 原子约 40 周期,AMO 约 600 周期,约 15 倍;该比例同样适用于内核引用计数、bitops、 xchg 与 futex。Mobileye 计划用基于该核的 eyeQ7H 平台做 ADAS,而这些路径正好落在调度、 内存管理与驱动关键路径上。
关键设计取舍:v2 曾做运行时切换,v3 改为编译期选择并由
CONFIG_NONPORTABLE 把守——因为 -march 决定指令选择,没有 zaamo 的
镜像根本不含可供回退的 AMO 序列,运行时方案产不出可移植镜像。默认行为完全不变(两个扩展都开,
-march 仍是单字母 a,生成代码一致)。
Kconfig 结构:TOOLCHAIN_HAS_ZALRSC 用 cc-option 探测编译器
是否接受 rv64im_zalrsc(GCC 15.1 起支持);RISCV_ISA_ZAAMO
可关(仅限 NONPORTABLE 且工具链支持);RISCV_ISA_ZALRSC 恒为 y(因为
cmpxchg、条件原子与 futex CAS 本身就是 LR/SC 序列,AMO 无法替代);
RISCV_ISA_A = ZAAMO && ZALRSC 保证正常构建仍带 a。共 9 文件
+267/−9。
改了什么:atomic.h 的 ATOMIC_OP/ATOMIC_FETCH_OP
按 __riscv_atomic || __riscv_zaamo 与 __riscv_zalrsc 二选一,两者皆无则
#error;bitops.h 新增 __LR/__SC 宏并重建
__test_and_op_bit_ord、__op_bit_ord 与
arch_xor_unlock_is_negative_byte;cmpxchg.h、futex.h 同步。
补丁 2 改 cpu.c:启动时不再硬性要求 a,而是「内核发 AMO 则需 a 或 zaamo,
发 LR/SC 则需 a 或 zalrsc」,单字母 a 同时满足两者,旧 riscv,isa 回退路径仍要求
rv{32,64}ima。
仍未解决(原文明确承认):BPF 原子指令仍发 AMO,Zalrsc-only 内核上不支持
BPF 原子操作;这是一个平台级、单一 -march 的选择,用户态必须同基线,不会产出可移植
镜像;系列仍是 v4 未合并,周期数为作者单平台实测;此外按已批准的 Zaamo 规范
Zacas 依赖 Zaamo,Zalrsc-only 内核同样用不了 CAS 指令。
一处需要留意的矛盾:MIPS 产品页把 P8700 标为 RV64GCZba_Zbb(G 含 A),
而补丁系列称其仅实现 Zalrsc、AMO 陷入 SBI 模拟。两说并存如实列出。
Суть: расширение A в RISC-V с 2024 года является псевдонимом:
A = Zaamo + Zalrsc. Спецификации Zaamo и Zalrsc ратифицированы
25 апреля 2024 (v1.0.0). Ядро Linux до сих пор требовало всё расширение целиком, и ядро
rv64ima считало, что процессор умеет и AMO*, и циклы LR/SC.
Что изменилось: 1 ноября 2026 года Владимир Кондратьев (Mobileye)
опубликовал v4 серию из двух патчей, которая делает реализацию атомарных операций ядра
выбираемой на этапе компиляции. Причина — MIPS P8700: по утверждению серии,
ядро реализует только Zalrsc, а инструкции AMO ловятся в SBI и эмулируются.
Измерения автора: атомарная операция на LR/SC — около 40 тактов,
на AMO — около 600, то есть примерно 15×. Это же
соотношение переносится на счётчики ссылок ядра, bitops, xchg и futex. Mobileye
планирует использовать платформу eyeQ7H на этом ядре для ADAS, где атомарные операции лежат
прямо на путях планировщика, управления памятью и драйверов.
Ключевое решение: в v2 был вариант с переключением во время загрузки, в v3 от него
отказались в пользу выбора при компиляции под CONFIG_NONPORTABLE — потому что
-march определяет выбор инструкций, и образ без zaamo просто не содержит
последовательностей AMO, к которым можно было бы откатиться. Поведение по умолчанию не
изменилось: оба расширения включены, -march по-прежнему содержит a, генерируемый
код идентичен.
Структура: TOOLCHAIN_HAS_ZALRSC проверяет через cc-option,
принимает ли компилятор rv64im_zalrsc (поддержка с GCC 15.1);
RISCV_ISA_ZAAMO можно отключить (только при NONPORTABLE);
RISCV_ISA_ZALRSC всегда включён, так как cmpxchg, условные атомарные операции и
futex CAS сами являются последовательностями LR/SC; RISCV_ISA_A
истинно только при наличии обоих. Изменено 9 файлов, +267/−9. Второй патч правит
riscv_early_of_processor_hartid(): вместо жёсткого требования a проверяется
именно та форма, которую генерирует ядро.
Ограничения (указаны в самой серии): атомарные операции BPF по-прежнему используют
AMO и не поддерживаются на Zalrsc-only ядре; это выбор уровня платформы с
единственным -march, пользовательское пространство должно совпадать; серия всё ещё
v4 и не принята в mainline; числа тактов — измерение автора на одном кристалле. Кроме
того, по ратифицированной спецификации Zacas зависит от Zaamo, поэтому CAS-инструкции
на таком ядре тоже недоступны.
Расхождение, которое стоит отметить: на странице продукта MIPS P8700 указан как
RV64GCZba_Zbb (а G включает A), тогда как серия утверждает, что
реализован только Zalrsc. Оба утверждения приведены как опубликованы.
La idea en una línea: desde 2024 la extensión A de RISC-V es un alias,
A = Zaamo + Zalrsc. Las especificaciones Zaamo y Zalrsc se
ratificaron el 25 de abril de 2024 (v1.0.0), pero el kernel de Linux siguió exigiendo la
letra completa.
Qué cambió: el 1 de noviembre de 2026, Vladimir Kondratiev
(Mobileye) publicó una serie v4 de dos parches que hace que las operaciones atómicas del
kernel se elijan en tiempo de compilación. El detonante es el MIPS P8700: según
la serie, el núcleo implementa solo Zalrsc y las instrucciones AMO
trapan a SBI para ser emuladas. Mediciones del autor: un atómico con LR/SC cuesta unos
40 ciclos y con AMO unos 600, es decir ~15×;
la misma proporción aplica a los contadores de referencia, bitops, xchg y futex del
kernel. Mobileye prevé usar la plataforma eyeQ7H, basada en ese núcleo, para ADAS y conducción
autónoma, donde los atómicos están en las rutas de planificación, gestión de memoria y drivers.
La decisión de diseño: la v2 planteaba una alternativa en tiempo de ejecución; la v3 la
descartó por una elección de compilación protegida por CONFIG_NONPORTABLE, porque
-march determina la selección de instrucciones y una imagen sin zaamo simplemente no
contiene las secuencias AMO a las que volver. El comportamiento por defecto no cambia: ambas
extensiones activas, -march conserva la letra a y el código generado es idéntico.
Estructura: TOOLCHAIN_HAS_ZALRSC comprueba con cc-option si el
compilador acepta rv64im_zalrsc (desde GCC 15.1);
RISCV_ISA_ZAAMO se puede desactivar solo con NONPORTABLE;
RISCV_ISA_ZALRSC está siempre activo porque cmpxchg, los atómicos condicionales y el
CAS de futex ya son secuencias LR/SC; RISCV_ISA_A solo es cierto con
ambas. Nueve archivos, +267/−9. El segundo parche ajusta
riscv_early_of_processor_hartid() para exigir la forma exacta que el kernel emite, en lugar de la
letra a a secas.
Lo que no resuelve (reconocido en la propia serie): las operaciones atómicas de BPF siguen
emitiendo AMO y no están soportadas en un kernel solo-Zalrsc; es una
decisión de plataforma con un único -march, y el espacio de usuario debe coincidir; la serie sigue
en v4 sin fusionar; y los ciclos son medición del autor en un solo chip. Además, según la
especificación ratificada, Zacas depende de Zaamo, así que las instrucciones CAS
tampoco están disponibles.
Una discrepancia a señalar: la página de producto de MIPS presenta el P8700 como
RV64GCZba_Zbb (y G incluye A), mientras la serie afirma que solo
implementa Zalrsc. Ambas afirmaciones se reproducen tal como se publicaron.
L'essentiel en une phrase : depuis 2024, l'extension A de RISC-V n'est
qu'un alias — A = Zaamo + Zalrsc. Les spécifications Zaamo et
Zalrsc ont été ratifiées le 25 avril 2024 (v1.0.0), mais le noyau Linux a continué
d'exiger la lettre entière.
Ce qui change : le 1er novembre 2026, Vladimir
Kondratiev (Mobileye) a publié une série v4 de deux patches qui rend les opérations
atomiques du noyau sélectionnables à la compilation. Le déclencheur est le MIPS
P8700 : d'après la série, ce cœur n'implémente que Zalrsc et les
instructions AMO déclenchent un trap vers SBI pour être émulées. Mesures de l'auteur : environ
40 cycles pour un atomique en LR/SC contre 600 en
AMO, soit ~15× ; le même rapport vaut pour les compteurs de références,
bitops, xchg et les futex. Mobileye prévoit d'utiliser la plateforme
eyeQ7H, bâtie sur ce cœur, pour l'ADAS et la conduite autonome, où ces opérations se trouvent
sur le chemin critique de l'ordonnanceur, de la gestion mémoire et des pilotes.
Le choix de conception : la v2 proposait une bascule à l'exécution ; la v3 l'a abandonnée
au profit d'un choix à la compilation protégé par CONFIG_NONPORTABLE, car -march
détermine la sélection d'instructions : une image sans zaamo ne contient tout simplement pas les
séquences AMO vers lesquelles retomber. Le comportement par défaut est inchangé : les deux
extensions actives, -march conserve la lettre a, code généré identique.
Structure : TOOLCHAIN_HAS_ZALRSC teste via cc-option si le
compilateur accepte rv64im_zalrsc (à partir de GCC 15.1) ;
RISCV_ISA_ZAAMO n'est désactivable qu'avec NONPORTABLE ;
RISCV_ISA_ZALRSC reste toujours actif car cmpxchg, les atomiques conditionnels et le
CAS des futex sont déjà des séquences LR/SC ; RISCV_ISA_A n'est vrai
qu'avec les deux. Neuf fichiers, +267/−9. Le second patch adapte
riscv_early_of_processor_hartid() pour exiger la forme exacte émise par le noyau plutôt que la
seule lettre a.
Ce que cela ne règle pas (reconnu dans la série) : les opérations atomiques BPF émettent
toujours AMO et ne sont pas prises en charge sur un noyau Zalrsc
seul ; il s'agit d'un choix de plateforme à -march unique, l'espace utilisateur devant suivre ; la
série reste en v4 non fusionnée ; et les cycles sont des mesures de l'auteur sur une seule
puce. De plus, selon la spécification ratifiée, Zacas dépend de Zaamo : les
instructions CAS sont donc également indisponibles.
Une divergence à signaler : la page produit de MIPS présente le P8700 comme
RV64GCZba_Zbb (et G inclut A), alors que la série affirme qu'il
n'implémente que Zalrsc. Les deux affirmations sont reproduites telles que publiées.
In einem Satz: Seit 2024 ist die RISC-V-Erweiterung A nur noch ein Alias
— A = Zaamo + Zalrsc. Die Spezifikationen Zaamo und Zalrsc
wurden am 25. April 2024 ratifiziert (v1.0.0), der Linux-Kernel verlangte aber weiterhin den
vollständigen Buchstaben.
Was sich ändert: Am 1. November 2026 veröffentlichte Vladimir
Kondratiev (Mobileye) eine v4-Patchserie aus zwei Patches, die die atomaren
Operationen des Kernels zur Compile-Zeit wählbar macht. Auslöser ist der MIPS
P8700: Laut der Serie implementiert dieser Kern nur Zalrsc, und
AMO-Instruktionen lösen einen Trap nach SBI aus, um emuliert zu werden. Messungen des Autors:
etwa 40 Zyklen für ein LR/SC-Atomik gegenüber 600
für AMO, also rund 15×; dasselbe Verhältnis gilt für Refcounts,
bitops, xchg und Futexe. Mobileye will die Plattform eyeQ7H auf
diesem Kern für ADAS und autonomes Fahren einsetzen, wo diese Operationen direkt auf den Pfaden von Scheduler,
Speicherverwaltung und Treibern liegen.
Die Designentscheidung: v2 sah noch eine Laufzeitumschaltung vor; v3 verwarf sie zugunsten
einer Compile-Zeit-Wahl hinter CONFIG_NONPORTABLE, weil -march die Instruktionsauswahl
bestimmt und ein Image ohne zaamo die AMO-Sequenzen schlicht nicht enthält, auf die
zurückgefallen werden könnte. Das Standardverhalten bleibt unverändert: beide Erweiterungen aktiv,
-march behält a, identischer generierter Code.
Aufbau: TOOLCHAIN_HAS_ZALRSC prüft per cc-option, ob der
Compiler rv64im_zalrsc akzeptiert (ab GCC 15.1);
RISCV_ISA_ZAAMO ist nur mit NONPORTABLE abschaltbar;
RISCV_ISA_ZALRSC bleibt immer aktiv, da cmpxchg, die bedingten Atomiks und der
Futex-CAS bereits LR/SC-Sequenzen sind; RISCV_ISA_A gilt nur bei beiden.
Neun Dateien, +267/−9. Der zweite Patch passt riscv_early_of_processor_hartid() an, sodass genau
die vom Kernel erzeugte Form verlangt wird statt des bloßen Buchstabens a.
Was es nicht löst (in der Serie eingeräumt): BPF-Atomiks erzeugen weiterhin AMO
und werden auf einem reinen Zalrsc-Kernel nicht unterstützt; es ist eine
Plattformentscheidung mit genau einem -march, Userspace muss dazu passen; die Serie ist weiterhin
v4 und nicht gemergt; die Zyklenzahlen sind Messungen des Autors an einem Chip. Zudem hängt
Zacas laut ratifizierter Spezifikation von Zaamo ab — CAS-Instruktionen sind
damit ebenfalls nicht verfügbar.
Eine anzumerkende Diskrepanz: Die MIPS-Produktseite führt den P8700 als
RV64GCZba_Zbb (und G enthält A), während die Serie behauptet, es sei nur
Zalrsc implementiert. Beide Aussagen werden so wiedergegeben, wie sie veröffentlicht wurden.
خلاصه در یک خط: از سال ۲۰۲۴، افزونهٔ A در RISC-V تنها یک نام مستعار است:
A = Zaamo + Zalrsc. مشخصات Zaamo و Zalrsc در
۲۵ آوریل ۲۰۲۴ (نسخهٔ ۱٫۰٫۰) تصویب شدند، اما هستهٔ لینوکس همچنان کل حرف را الزامی میدانست.
چه تغییر کرد: در ۱ نوامبر ۲۰۲۶، ولادیمیر کوندراتیف
از Mobileye مجموعهٔ وصلهٔ v4 شامل دو وصله را منتشر کرد که عملیات اتمیک هسته را
در زمان کامپایل قابل انتخاب میکند. محرک این کار MIPS P8700 است: بر پایهٔ
این مجموعه، این هسته تنها Zalrsc را پیادهسازی میکند و دستورهای
AMO به SBI تله میزنند و شبیهسازی میشوند. اندازهگیری نویسنده: یک عملیات اتمیک با
LR/SC حدود ۴۰ چرخه و با AMO حدود
۶۰۰ چرخه، یعنی نزدیک ۱۵ برابر؛ همین نسبت برای شمارندههای مرجع،
bitops، xchg و futex هم برقرار است. Mobileye قصد دارد سکوی
eyeQ7H را بر پایهٔ این هسته برای ADAS و رانندگی خودکار به کار ببرد، جایی که این عملیات
دقیقاً روی مسیر زمانبندی، مدیریت حافظه و درایورها قرار دارند.
تصمیم طراحی: نسخهٔ v2 گزینهٔ سوئیچ در زمان اجرا را داشت؛ v3 آن را کنار گذاشت و انتخاب
زمان کامپایل را پشت CONFIG_NONPORTABLE قرار داد، زیرا -march انتخاب دستورها را
تعیین میکند و ایمیجی بدون zaamo اصلاً دنبالهٔ AMOای ندارد که بتوان به آن بازگشت.
رفتار پیشفرض تغییر نکرده است: هر دو افزونه فعال، -march همچنان حرف a را دارد و
کد تولیدشده یکسان است.
ساختار: TOOLCHAIN_HAS_ZALRSC با cc-option بررسی میکند که
کامپایلر rv64im_zalrsc را میپذیرد یا نه (از GCC 15.1 به بعد)؛
RISCV_ISA_ZAAMO تنها با NONPORTABLE خاموششدنی است؛
RISCV_ISA_ZALRSC همیشه روشن است چون cmpxchg، اتمیکهای شرطی و CAS در futex خودشان
دنبالهٔ LR/SC هستند؛ RISCV_ISA_A فقط با وجود هر دو درست است.
نُه فایل، ۲۶۷ افزوده و ۹ حذفشده. وصلهٔ دوم riscv_early_of_processor_hartid() را تغییر میدهد
تا بهجای حرف سادهٔ a، دقیقاً همان شکلی را بخواهد که هسته تولید میکند.
آنچه حل نمیکند (در خود مجموعه تصریح شده): عملیات اتمیک BPF همچنان AMO
تولید میکند و روی هستهٔ صرفاً Zalrsc پشتیبانی نمیشود؛ این یک انتخاب سطح
سکو با یک -march واحد است و فضای کاربری باید همراستا باشد؛ مجموعه هنوز
v4 و ادغامنشده است؛ و اعداد چرخه اندازهگیری نویسنده روی یک تراشه است. همچنین بر پایهٔ
مشخصات تصویبشده، Zacas به Zaamo وابسته است، پس دستورهای CAS هم در دسترس
نیستند.
یک ناسازگاری که باید توجه کرد: صفحهٔ محصول MIPS، پردازندهٔ P8700 را
RV64GCZba_Zbb معرفی میکند (و G شامل A است)، در حالی که مجموعهٔ وصله
میگوید تنها Zalrsc پیادهسازی شده است. هر دو گفته همانگونه که منتشر شدهاند نقل میشوند.
Sources / 参考来源
- linux-riscv mailing list — [PATCH v4 0/2] riscv: support CPUs with Zalrsc but not Zaamo (Vladimir Kondratiev, Mobileye, 2026-11-01)
- [PATCH v4 1/2] riscv: build kernel atomics from LR/SC when Zaamo is disabled (Kconfig, Makefile, atomic.h, bitops.h, cmpxchg.h, futex.h)
- [PATCH v4 2/2] riscv: accept the atomic extensions this kernel was built with (arch/riscv/kernel/cpu.c)
- Patchwork — series 1198095, state New (both patches unmerged as of 2026-11-02)
- RISC-V International — Zaamo and Zalrsc Extensions, v1.0.0, ratified 2024-04-25
- riscv/riscv-zaamo-zalrsc — source of the ratified specification text
- MIPS — P8700 Series product page (RV64GCZba_Zbb, 4-issue 16-stage OoO, 1-/2-way SMT, 8 coherent initiators, 2 MB L2, 256-bit ACE/AXI)
- RISC-V tech-unprivileged list — confirmation that A = Zaamo + Zalrsc per the 20240411 unprivileged spec