Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K
@ 2026-10-08  5:37 Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

Rust on 32-bit ARM is limited to kernels that contain an ARMv7 CPU.
This series extends it to ARMv6K-only, ARMv5TE and ARMv4T kernels.
Based on v7.3-rc1.

Linus Walleij asked for older ARM cores during review of the ARMv7
support [1]. Christian Schrefl's earlier ARMv5 attempt [2] hit atomic
and ABI problems. The kernel crate now uses C atomic helpers, and the
*-linux-gnueabi targets used here keep the Linux EABI.

Patch 1 fixes a Rust build failure with gcc 8.1.0 and
CC_OPTIMIZE_FOR_SIZE on ARMv7, without the rest of this series. It can
be merged separately and is tagged for stable.

Patches 4 and 5 depend on patch 2 for 16-bit xchg() on pre-ARMv6 CPUs.
Patch 6 switches ARMv7 kernels to the ARMv7 Rust target and can be left
out. Combined ARMv6K and ARMv7 kernels keep the generic ARMv6 target.

Arnd suggested -Ctarget-cpu with arm-unknown-linux-gnueabi. Its explicit
+v6 remains in effect with -Ctarget-cpu=arm926ej-s, so libcore contains
ARMv6 instructions. Disabling +v6 produces ARMv5TE code but warns about
an unstable target feature. The ARMv4T and ARMv5TE targets also declare
32-bit atomics rather than 64-bit. The series selects the target next
to -march.

ARMv4 without Thumb, ARMv7-M and plain ARMv6 (ARM1136r0) stay excluded.

The Rust samples, Rust KUnit suites and doctests passed in the following
ARM-mode kernels on v7.3-rc1.

QEMU:

- ARMv4T: sx1 (OMAP310, ARM925T), omap1_defconfig, 360 doctests.
  CPU_DCACHE_WRITETHROUGH was disabled because QEMU does not implement
  the CP15 register it writes.
- ARMv5TE: versatilepb (ARM926EJ-S), versatile_defconfig, 355 doctests.
- ARMv6K: raspi0 (ARM1176), bcm2835_defconfig without ARCH_MULTI_V7,
  368 doctests.
- ARMv7: virt (Cortex-A15), 371 doctests. With clang 22.1.8, Rust
  modules also loaded, including the PCI and DMA samples on pci-testdev.

The ARMv4T, ARMv5TE and ARMv6K QEMU runs used these toolchains:

- clang 22.1.8, rustc 1.99.0, bindgen 0.73.2
- gcc 15.2.0, rustc 1.98.0, bindgen 0.72.1
- minimum LLVM 17.0.1, rustc 1.85.0, bindgen 0.71.1
- minimum gcc 8.1.0, binutils 2.30, rustc 1.85.0, bindgen 0.71.1

ARMv7 virt also passed with both minimum toolchains. No additional
toolchain requirement was found.

Hardware:

- Microchip SAM9X75 Curiosity (ARM926EJ-S), clang 22.1.8, 356 doctests.
  Tested with an ARMv5-only config and with at91_dt_defconfig, which is
  built for ARMv4T. Rust sample modules loaded and unloaded.
- Raspberry Pi 400 (Cortex-A72), 32-bit LPAE kernel, 371 doctests.
  Both ARMv6 and ARMv7 Rust targets were tested with clang 22.1.8 and
  with gcc 8.1.0 at CC_OPTIMIZE_FOR_SIZE. With the ARMv7 target and both
  compilers, Rust sample modules loaded and unloaded. rnull read and
  write tests passed, and Rust cpufreq-dt switched between 600 MHz and
  1.8 GHz.

The optional panic QR renderer was disabled for the GCC build with the
ARMv7 Rust target. With rustc 1.85.0 and size optimization, its object
references __aeabi_uldivmod, which the ARM kernel does not provide.
An unpatched v7.3-rc1 QR object has the same reference.

ARMv6K has been tested in QEMU only.

Built-in Rust code ran on Thumb-2 kernels on the Pi 400 and in QEMU,
with both ARMv6 and ARMv7 Rust targets. Tested Rust modules failed with
"unsupported interworking call (ARM -> Thumb)", also on unpatched
v7.3-rc1. One open question is whether HAVE_RUST should exclude
THUMB2_KERNEL && MODULES or leave module loading to a follow-up.

I plan to submit the enablement patches through Russell's patch system
unless the ARM and Rust maintainers agree on another route.

Changes in v2:
- Select the rustc target next to -march and explain why -Ctarget-cpu
  on the generic target is not enough (Arnd).
- Add ARMv4T and ARMv6K-only support (Arnd).
- Add optional patch 6 for the ARMv7 Rust target (Arnd).
- Keep ARMv7-M and plain ARMv6 excluded (Arnd, Bradley).
- Test Thumb-2 kernels and document the Rust module failure (Arnd).
- Test gcc and the minimum tool versions (Miguel).
- Add patch 1 for the build failure found with gcc 8.1.0.
- Patch 2: unchanged code, collected Arnd's Acked-by and Reviewed-by
  tags from Linus Walleij and Bradley Morgan, and explained the plain
  ARMv6 exclusion (Arnd).
- Update the atomic-helper architecture lists and architecture table.

v1: https://lore.kernel.org/rust-for-linux/20261003093827.77857-1-kmehltretter@gmail.com/

[1] https://lore.kernel.org/rust-for-linux/CACRpkdYF0sVB2-qgy=GzETSR3+2sagVQPGdunDQDJrn8KqJorA@mail.gmail.com/
[2] https://lore.kernel.org/rust-for-linux/b13d37bd-ec68-4713-94e5-e9ed4d6a6354@gmail.com/

Karl Mehltretter (6):
  ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg()
  ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
  ARM: rust: Enable Rust support for ARMv6K-only kernels
  ARM: rust: Enable Rust support for ARMv5TE
  ARM: rust: Enable Rust support for ARMv4T
  ARM: rust: Build Rust code for ARMv7 on ARMv7 kernels

 Documentation/rust/arch-support.rst |  8 ++++----
 arch/arm/Kconfig                    |  8 +++++++-
 arch/arm/Makefile                   | 10 +++++++++-
 arch/arm/include/asm/cmpxchg.h      | 26 +++++++++++++++++---------
 rust/helpers/atomic_ext.c           |  4 ++--
 5 files changed, 39 insertions(+), 17 deletions(-)


base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg()
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  2026-10-08  9:01   ` Gary Guo
  2026-10-09  9:50   ` Gary Guo
  2026-10-08  5:37 ` [PATCH v2 2/6] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

__arch_xchg(), __cmpxchg() and __cmpxchg_local() end in a default case
that calls an undefined function. That turns an unsupported size into a
link error. It relies on the functions being inlined, so that the
compiler can drop the default case for a constant size.

They are only marked inline. gcc 8.1.0 with CC_OPTIMIZE_FOR_SIZE does
not inline them in rust/helpers/helpers.c, which calls xchg() and
cmpxchg() from many small helpers. The out-of-line copies keep the
default case and the link fails.

  helpers.c:(.text+0x424): undefined reference to `__bad_xchg'
  helpers.c:(.text+0x4ac): undefined reference to `__bad_cmpxchg'

Seen with bcm2835_defconfig and CONFIG_RUST=y on v7.3-rc1. The same
config links with CONFIG_RUST=n. It also links with gcc 15.2.0 and
with clang.

v6.19 links. Commit ab717dd98bee ("rust: helpers: Add i8/i16 atomic
xchg_acquire helpers") in v7.0 triggers __bad_xchg. Commit
ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
in v7.1 also triggers __bad_cmpxchg.

Mark the functions __always_inline.

Fixes: ab717dd98bee ("rust: helpers: Add i8/i16 atomic xchg_acquire helpers")
Fixes: ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 arch/arm/include/asm/cmpxchg.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index 9beb64d30586..0ce5225af442 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -26,7 +26,7 @@
 #define swp_is_buggy
 #endif
 
-static inline unsigned long
+static __always_inline unsigned long
 __arch_xchg(unsigned long x, volatile void *ptr, int size)
 {
 	extern void __bad_xchg(volatile void *, int);
@@ -155,8 +155,8 @@ extern void __bad_cmpxchg(volatile void *ptr, int size);
  * cmpxchg only support 32-bits operands on ARMv6.
  */
 
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-				      unsigned long new, int size)
+static __always_inline unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	unsigned long oldval, res;
 
@@ -220,9 +220,9 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 				      sizeof(*(ptr)));			\
 })
 
-static inline unsigned long __cmpxchg_local(volatile void *ptr,
-					    unsigned long old,
-					    unsigned long new, int size)
+static __always_inline unsigned long
+__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
+		int size)
 {
 	unsigned long ret;
 
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 2/6] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 3/6] ARM: rust: Enable Rust support for ARMv6K-only kernels Karl Mehltretter
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

Pre-ARMv6 CPUs have no halfword swp, so __arch_xchg() only handles 1-
and 4-byte exchanges there and turns any other size into a link error
via __bad_xchg().

No C code needs a 16-bit xchg() on these CPUs, but the Rust atomic
helpers in rust/helpers/atomic_ext.c provide xchg() for Atomic<i16>
unconditionally, so building with CONFIG_RUST=y for ARMv5 fails:

  ld.lld: error: undefined symbol: __bad_xchg
  >>> referenced by helpers.c
  >>>               rust/helpers/helpers.o:(rust_helper_atomic_i16_xchg)

Implement the 2-byte case with interrupts disabled, as the pre-ARMv6
atomic_t operations already do. This is safe because a kernel built
for ARMv5 or older is never SMP.

ARMv6 before ARMv6K (ARM1136r0) has no 16-bit exclusive access either.
It is not handled here. Rust stays disabled for those kernels, and
they cannot be SMP since commit d70242427110 ("ARM: rework ARM11 CPU
selection logic").

Acked-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 arch/arm/include/asm/cmpxchg.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
index 0ce5225af442..18555ae22893 100644
--- a/arch/arm/include/asm/cmpxchg.h
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -31,11 +31,10 @@ __arch_xchg(unsigned long x, volatile void *ptr, int size)
 {
 	extern void __bad_xchg(volatile void *, int);
 	unsigned long ret;
-#ifdef swp_is_buggy
-	unsigned long flags;
-#endif
 #if __LINUX_ARM_ARCH__ >= 6
 	unsigned int tmp;
+#else
+	unsigned long flags;
 #endif
 
 	prefetchw((const void *)ptr);
@@ -106,6 +105,15 @@ __arch_xchg(unsigned long x, volatile void *ptr, int size)
 			: "r" (x), "r" (ptr)
 			: "memory", "cc");
 		break;
+#endif
+#if __LINUX_ARM_ARCH__ < 6
+	case 2:
+		/* swp has no halfword form. Pre-ARMv6 is never SMP. */
+		raw_local_irq_save(flags);
+		ret = *(volatile unsigned short *)ptr;
+		*(volatile unsigned short *)ptr = x;
+		raw_local_irq_restore(flags);
+		break;
 #endif
 	default:
 		/* Cause a link-time error, the xchg() size is not supported */
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 3/6] ARM: rust: Enable Rust support for ARMv6K-only kernels
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 2/6] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 4/6] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

HAVE_RUST is selected for CPU_32v7 only. A combined ARMv6K and ARMv7
kernel has CPU_32v7 and can use Rust today. A kernel built for ARMv6K
alone cannot. There is no technical reason for that.

No CPU flags are passed to rustc on ARM. The arm-unknown-linux-gnueabi
target has +v6 in its feature list, so Rust code is built as ARMv6 on
all of these kernels already.

Select HAVE_RUST for CPU_32v6K instead. CPU_V7 selects CPU_32v6K, so
ARMv7 stays covered.

Plain ARMv6 (CPU_V6, ARM1136r0) is excluded. It has no 1- and 2-byte
xchg() and no 2-byte cmpxchg(), which the Rust atomic helpers need. A
kernel that combines CPU_V6 with ARMv7 can enable Rust today and does
not link.

Tested in QEMU raspi0 (ARM1176) with bcm2835_defconfig without
ARCH_MULTI_V7. The Rust samples, all Rust KUnit suites and the
doctests pass with the current and with the minimum tool versions.

Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 Documentation/rust/arch-support.rst | 2 +-
 arch/arm/Kconfig                    | 2 +-
 rust/helpers/atomic_ext.c           | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 4f980815e92a..bdc42a24bf30 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -15,7 +15,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 =============  ================  ==============================================
 Architecture   Level of support  Constraints
 =============  ================  ==============================================
-``arm``        Maintained        ARMv7 Little Endian only.
+``arm``        Maintained        ARMv6K and ARMv7, Little Endian only.
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
 ``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ffbc7f386131..b5816f28783a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -138,7 +138,7 @@ config ARM
 	select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
-	select HAVE_RUST if CPU_LITTLE_ENDIAN && CPU_32v7 && !KASAN
+	select HAVE_RUST if CPU_LITTLE_ENDIAN && CPU_32v6K && !CPU_V6 && !KASAN
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/rust/helpers/atomic_ext.c b/rust/helpers/atomic_ext.c
index c267d5190529..1d157df29229 100644
--- a/rust/helpers/atomic_ext.c
+++ b/rust/helpers/atomic_ext.c
@@ -42,7 +42,7 @@ GEN_READ_SET_HELPERS(ptr, const void *)
  * xchg helpers depend on ARCH_SUPPORTS_ATOMIC_RMW and on the
  * architecture provding xchg() support for i8 and i16.
  *
- * The architectures that currently support Rust (x86_64, armv7,
+ * The architectures that currently support Rust (x86_64, arm,
  * arm64, riscv, and loongarch) satisfy these requirements.
  */
 #define GEN_XCHG_HELPER(tname, type, suffix)					\
@@ -66,7 +66,7 @@ GEN_XCHG_HELPERS(ptr, const void *)
  * try_cmpxchg helpers depend on ARCH_SUPPORTS_ATOMIC_RMW and on the
  * architecture provding try_cmpxchg() support for i8 and i16.
  *
- * The architectures that currently support Rust (x86_64, armv7,
+ * The architectures that currently support Rust (x86_64, arm,
  * arm64, riscv, and loongarch) satisfy these requirements.
  */
 #define GEN_TRY_CMPXCHG_HELPER(tname, type, suffix)				\
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 4/6] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
                   ` (2 preceding siblings ...)
  2026-10-08  5:37 ` [PATCH v2 3/6] ARM: rust: Enable Rust support for ARMv6K-only kernels Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T Karl Mehltretter
  2026-10-08  5:37 ` [PATCH v2 6/6] ARM: rust: Build Rust code for ARMv7 on ARMv7 kernels Karl Mehltretter
  5 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

The arm-unknown-linux-gnueabi target used so far has +v6 in its
feature list and emits ARMv6 instructions such as uxtb, uxth and rev.
It cannot be used for ARMv5.

-Ctarget-cpu does not help. It can add features but it does not remove
the +v6 of the target. libcore built with -Ctarget-cpu=arm926ej-s is
still ARMv6. Adding -Ctarget-feature=-v6 gives ARMv5TE code, but rustc
warns about an unstable feature on every invocation. The generic target
also declares 64-bit atomics, where the ARMv5 one declares 32 bit.

Use rustc's armv5te-unknown-linux-gnueabi target for CPU_32v5. It keeps
the Linux EABI (no short enums, unlike the -none-eabi targets) and is
soft-float and strict-align. The target is chosen next to the -march
option so that both follow the same CPU selection.

Kernels that also contain ARMv4 or ARMv4T CPUs are built for the
lowest architecture and stay excluded here. CPU_32v5 also covers the
ARMv5T ARM1020. C code is already built with -march=armv5te there, so
Rust matches.

The kernel crate implements atomics through the C helpers rather than
core::sync::atomic, so the missing atomic instructions on ARMv5 do not
matter. The only gap was the 2-byte xchg() added by "ARM: cmpxchg:
support 2-byte xchg() on pre-ARMv6 CPUs".

core::sync::atomic types up to 32 bits still compile on this target,
but LLVM lowers them to __sync_* libcalls which the kernel does not
provide. Nothing in the tree uses them. Such code would fail to link
on ARMv5 while it links on ARMv7.

Tested in QEMU versatilepb (ARM926EJ-S) with versatile_defconfig. The
Rust samples, all Rust KUnit suites and the doctests pass with the
current and with the minimum tool versions. They also pass on a
Microchip SAM9X75 Curiosity board (ARM926EJ-S).

Link: https://lore.kernel.org/rust-for-linux/CACRpkdYF0sVB2-qgy=GzETSR3+2sagVQPGdunDQDJrn8KqJorA@mail.gmail.com/
Link: https://lore.kernel.org/rust-for-linux/b13d37bd-ec68-4713-94e5-e9ed4d6a6354@gmail.com/
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 Documentation/rust/arch-support.rst | 2 +-
 arch/arm/Kconfig                    | 8 +++++++-
 arch/arm/Makefile                   | 7 ++++++-
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index bdc42a24bf30..d6d1bef44c8f 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -15,7 +15,7 @@ support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 =============  ================  ==============================================
 Architecture   Level of support  Constraints
 =============  ================  ==============================================
-``arm``        Maintained        ARMv6K and ARMv7, Little Endian only.
+``arm``        Maintained        ARMv5TE, ARMv6K and ARMv7, Little Endian only.
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
 ``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b5816f28783a..9275a85f95e9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -138,7 +138,7 @@ config ARM
 	select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_RSEQ
-	select HAVE_RUST if CPU_LITTLE_ENDIAN && CPU_32v6K && !CPU_V6 && !KASAN
+	select HAVE_RUST if CPU_LITTLE_ENDIAN && ARM_RUST_TARGET && !KASAN
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
@@ -172,6 +172,12 @@ config ARM
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
+# The CPU selections for which rustc has a matching target
+config ARM_RUST_TARGET
+	def_bool y
+	depends on (CPU_32v6K && !CPU_V6) || \
+		   (CPU_32v5 && !CPU_32v4T && !CPU_32v4)
+
 config ARM_HAS_GROUP_RELOCS
 	def_bool !COMPILE_TEST
 	help
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 573813ef5e77..168779e9e93d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -73,6 +73,11 @@ arch-$(CONFIG_CPU_32v4T)	:=-march=armv4t
 arch-$(CONFIG_CPU_32v4)		:=-march=armv4
 arch-$(CONFIG_CPU_32v3)		:=-march=armv3m
 
+# The rustc target fixes the instruction set. -Ctarget-cpu cannot remove
+# the +v6 of the generic target, so older CPUs need their own target.
+rust-target-y				:=arm-unknown-linux-gnueabi
+rust-target-$(CONFIG_CPU_32v5)		:=armv5te-unknown-linux-gnueabi
+
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
 # testing for a specific architecture or later rather impossible.
@@ -150,7 +155,7 @@ endif
 KBUILD_CPPFLAGS	+=$(cpp-y)
 KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include $(srctree)/arch/arm/include/asm/unified.h -msoft-float
-KBUILD_RUSTFLAGS += --target=arm-unknown-linux-gnueabi
+KBUILD_RUSTFLAGS += --target=$(rust-target-y)
 
 CHECKFLAGS	+= -D__arm__
 
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
                   ` (3 preceding siblings ...)
  2026-10-08  5:37 ` [PATCH v2 4/6] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  2026-10-08  9:08   ` Gary Guo
  2026-10-08  5:37 ` [PATCH v2 6/6] ARM: rust: Build Rust code for ARMv7 on ARMv7 kernels Karl Mehltretter
  5 siblings, 1 reply; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

The armv5te target emits clz and blx, which ARMv4T lacks. Kernels that
contain an ARMv4T CPU are excluded from Rust for that reason.

Nothing else in the Rust code depends on ARMv5. Use rustc's
armv4t-unknown-linux-gnueabi target for these kernels. Like the C code,
the Rust code of a combined ARMv4T and ARMv5 kernel is then built for
ARMv4T.

ARMv4 (StrongARM, FA526) stays excluded. It has no bx and rustc has no
target for it.

Tested in QEMU sx1 (OMAP310, ARM925T) with omap1_defconfig. The Rust
samples, all Rust KUnit suites and the doctests pass with the current
and with the minimum tool versions.

at91_dt_defconfig combines ARMv4T and ARMv5 and is built for ARMv4T.
That kernel passes the same tests on a Microchip SAM9X75 Curiosity
board (ARM926EJ-S).

Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 Documentation/rust/arch-support.rst | 8 ++++----
 arch/arm/Kconfig                    | 2 +-
 arch/arm/Makefile                   | 1 +
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index d6d1bef44c8f..3f39cf55b6f4 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -12,15 +12,15 @@ which uses ``libclang``.
 Below is a general summary of architectures that currently work. Level of
 support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 
-=============  ================  ==============================================
+=============  ================  ======================================================
 Architecture   Level of support  Constraints
-=============  ================  ==============================================
-``arm``        Maintained        ARMv5TE, ARMv6K and ARMv7, Little Endian only.
+=============  ================  ======================================================
+``arm``        Maintained        ARMv4T, ARMv5TE, ARMv6K and ARMv7, Little Endian only.
 ``arm64``      Maintained        Little Endian only.
 ``loongarch``  Maintained        \-
 ``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
 ``s390``       Maintained        ``CONFIG_EXPOLINE`` must be disabled.
 ``um``         Maintained        \-
 ``x86``        Maintained        ``x86_64`` only.
-=============  ================  ==============================================
+=============  ================  ======================================================
 
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9275a85f95e9..cf782fc04872 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -176,7 +176,7 @@ config ARM
 config ARM_RUST_TARGET
 	def_bool y
 	depends on (CPU_32v6K && !CPU_V6) || \
-		   (CPU_32v5 && !CPU_32v4T && !CPU_32v4)
+		   ((CPU_32v5 || CPU_32v4T) && !CPU_32v4)
 
 config ARM_HAS_GROUP_RELOCS
 	def_bool !COMPILE_TEST
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 168779e9e93d..a72843890241 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -77,6 +77,7 @@ arch-$(CONFIG_CPU_32v3)		:=-march=armv3m
 # the +v6 of the generic target, so older CPUs need their own target.
 rust-target-y				:=arm-unknown-linux-gnueabi
 rust-target-$(CONFIG_CPU_32v5)		:=armv5te-unknown-linux-gnueabi
+rust-target-$(CONFIG_CPU_32v4T)	:=armv4t-unknown-linux-gnueabi
 
 # Note that GCC does not numerically define an architecture version
 # macro, but instead defines a whole series of macros which makes
-- 
2.39.5 (Apple Git-154)



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

* [PATCH v2 6/6] ARM: rust: Build Rust code for ARMv7 on ARMv7 kernels
  2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
                   ` (4 preceding siblings ...)
  2026-10-08  5:37 ` [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T Karl Mehltretter
@ 2026-10-08  5:37 ` Karl Mehltretter
  5 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-08  5:37 UTC (permalink / raw)
  To: Russell King, Miguel Ojeda
  Cc: Karl Mehltretter, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

The arm-unknown-linux-gnueabi target builds ARMv6 code. An ARMv7 kernel
gets that as well, because no CPU flags are passed to rustc. Its Rust
code cannot use movw/movt or any other ARMv7 instruction.

Use rustc's armv7-unknown-linux-gnueabi target when the kernel is built
with -march=armv7-a. It is ARMv7-A with the soft-float EABI and NEON
disabled. Unlike the generic target, it does not set +strict-align.
This allows unaligned word and halfword accesses, matching C code on
MMU-enabled ARMv7 kernels. A kernel that also contains an ARMv6K CPU
is built with -march=armv6k and keeps the generic target.

This builds the Rust code for the same architecture level as the C
code. In the tested Raspberry Pi 400 configuration, Rust text grows
by 1.9 %. Six small benchmarks range from 10 % shorter to 5 % longer
runtimes.

The generic target would turn a full memory barrier from
core::sync::atomic into the deprecated CP15 operation. The armv7 target
emits dmb. No kernel Rust code uses these atomics today, so this is not
a fix.

Tested on a Raspberry Pi 400 (Cortex-A72, LPAE) with clang 22.1.8 and
in QEMU virt (Cortex-A15) with the minimum tool versions. Rust modules
load with the movw/movt relocations.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
---
 arch/arm/Makefile | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index a72843890241..28eb8484ff82 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -73,9 +73,11 @@ arch-$(CONFIG_CPU_32v4T)	:=-march=armv4t
 arch-$(CONFIG_CPU_32v4)		:=-march=armv4
 arch-$(CONFIG_CPU_32v3)		:=-march=armv3m
 
-# The rustc target fixes the instruction set. -Ctarget-cpu cannot remove
-# the +v6 of the generic target, so older CPUs need their own target.
+# The rustc target fixes the instruction set, so pick it like -march above.
+# The generic target builds ARMv6 code. -Ctarget-cpu cannot remove its +v6.
 rust-target-y				:=arm-unknown-linux-gnueabi
+rust-target-$(CONFIG_CPU_32v7)		:=armv7-unknown-linux-gnueabi
+rust-target-$(CONFIG_CPU_32v6)		:=arm-unknown-linux-gnueabi
 rust-target-$(CONFIG_CPU_32v5)		:=armv5te-unknown-linux-gnueabi
 rust-target-$(CONFIG_CPU_32v4T)	:=armv4t-unknown-linux-gnueabi
 
-- 
2.39.5 (Apple Git-154)



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

* Re: [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg()
  2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
@ 2026-10-08  9:01   ` Gary Guo
  2026-10-09  1:17     ` Karl Mehltretter
  2026-10-09  9:50   ` Gary Guo
  1 sibling, 1 reply; 12+ messages in thread
From: Gary Guo @ 2026-10-08  9:01 UTC (permalink / raw)
  To: Karl Mehltretter, Russell King, Miguel Ojeda
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
	Onur Özkan, Arnd Bergmann, Linus Walleij, Christian Schrefl,
	Bradley Morgan, Paul E . McKenney, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-arm-kernel,
	rust-for-linux, llvm, linux-doc, linux-kernel

On Thu Oct 8, 2026 at 7:37 AM CEST, Karl Mehltretter wrote:
> __arch_xchg(), __cmpxchg() and __cmpxchg_local() end in a default case
> that calls an undefined function. That turns an unsupported size into a
> link error. It relies on the functions being inlined, so that the
> compiler can drop the default case for a constant size.
>
> They are only marked inline. gcc 8.1.0 with CC_OPTIMIZE_FOR_SIZE does
> not inline them in rust/helpers/helpers.c, which calls xchg() and
> cmpxchg() from many small helpers. The out-of-line copies keep the
> default case and the link fails.
>
>   helpers.c:(.text+0x424): undefined reference to `__bad_xchg'
>   helpers.c:(.text+0x4ac): undefined reference to `__bad_cmpxchg'
>
> Seen with bcm2835_defconfig and CONFIG_RUST=y on v7.3-rc1. The same
> config links with CONFIG_RUST=n. It also links with gcc 15.2.0 and
> with clang.
>
> v6.19 links. Commit ab717dd98bee ("rust: helpers: Add i8/i16 atomic
> xchg_acquire helpers") in v7.0 triggers __bad_xchg. Commit
> ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
> in v7.1 also triggers __bad_cmpxchg.

I think the issue is that when you get multiple function calls in a function,
GCC starts to think that not inlining can result in code deduplication where
that is not actually true.

But I am surprised that it hasn't been seen in the past, perhaps there're only
calls with single size from any translation unit previously?

The fix LGTM, but Sashiko's report is worth looking into.

Best,
Gary

>
> Mark the functions __always_inline.
>
> Fixes: ab717dd98bee ("rust: helpers: Add i8/i16 atomic xchg_acquire helpers")
> Fixes: ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
>  arch/arm/include/asm/cmpxchg.h | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
> index 9beb64d30586..0ce5225af442 100644
> --- a/arch/arm/include/asm/cmpxchg.h
> +++ b/arch/arm/include/asm/cmpxchg.h
> @@ -26,7 +26,7 @@
>  #define swp_is_buggy
>  #endif
>  
> -static inline unsigned long
> +static __always_inline unsigned long
>  __arch_xchg(unsigned long x, volatile void *ptr, int size)
>  {
>  	extern void __bad_xchg(volatile void *, int);
> @@ -155,8 +155,8 @@ extern void __bad_cmpxchg(volatile void *ptr, int size);
>   * cmpxchg only support 32-bits operands on ARMv6.
>   */
>  
> -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
> -				      unsigned long new, int size)
> +static __always_inline unsigned long
> +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
>  {
>  	unsigned long oldval, res;
>  
> @@ -220,9 +220,9 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
>  				      sizeof(*(ptr)));			\
>  })
>  
> -static inline unsigned long __cmpxchg_local(volatile void *ptr,
> -					    unsigned long old,
> -					    unsigned long new, int size)
> +static __always_inline unsigned long
> +__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
> +		int size)
>  {
>  	unsigned long ret;
>  




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

* Re: [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T
  2026-10-08  5:37 ` [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T Karl Mehltretter
@ 2026-10-08  9:08   ` Gary Guo
  2026-10-09  1:21     ` Karl Mehltretter
  0 siblings, 1 reply; 12+ messages in thread
From: Gary Guo @ 2026-10-08  9:08 UTC (permalink / raw)
  To: Karl Mehltretter, Russell King, Miguel Ojeda
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
	Onur Özkan, Arnd Bergmann, Linus Walleij, Christian Schrefl,
	Bradley Morgan, Paul E . McKenney, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-arm-kernel,
	rust-for-linux, llvm, linux-doc, linux-kernel

On Thu Oct 8, 2026 at 7:37 AM CEST, Karl Mehltretter wrote:
> The armv5te target emits clz and blx, which ARMv4T lacks. Kernels that
> contain an ARMv4T CPU are excluded from Rust for that reason.
>
> Nothing else in the Rust code depends on ARMv5. Use rustc's
> armv4t-unknown-linux-gnueabi target for these kernels. Like the C code,
> the Rust code of a combined ARMv4T and ARMv5 kernel is then built for
> ARMv4T.
>
> ARMv4 (StrongARM, FA526) stays excluded. It has no bx and rustc has no
> target for it.
>
> Tested in QEMU sx1 (OMAP310, ARM925T) with omap1_defconfig. The Rust
> samples, all Rust KUnit suites and the doctests pass with the current
> and with the minimum tool versions.
>
> at91_dt_defconfig combines ARMv4T and ARMv5 and is built for ARMv4T.
> That kernel passes the same tests on a Microchip SAM9X75 Curiosity
> board (ARM926EJ-S).
>
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
>  Documentation/rust/arch-support.rst | 8 ++++----
>  arch/arm/Kconfig                    | 2 +-
>  arch/arm/Makefile                   | 1 +
>  3 files changed, 6 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
> index d6d1bef44c8f..3f39cf55b6f4 100644
> --- a/Documentation/rust/arch-support.rst
> +++ b/Documentation/rust/arch-support.rst
> @@ -12,15 +12,15 @@ which uses ``libclang``.
>  Below is a general summary of architectures that currently work. Level of
>  support corresponds to ``S`` values in the ``MAINTAINERS`` file.
>  
> -=============  ================  ==============================================
> +=============  ================  ======================================================
>  Architecture   Level of support  Constraints
> -=============  ================  ==============================================
> -``arm``        Maintained        ARMv5TE, ARMv6K and ARMv7, Little Endian only.
> +=============  ================  ======================================================
> +``arm``        Maintained        ARMv4T, ARMv5TE, ARMv6K and ARMv7, Little Endian only.

Can we say "ARMv4T or above" or something similar?

Best,
Gary

>  ``arm64``      Maintained        Little Endian only.
>  ``loongarch``  Maintained        \-
>  ``riscv``      Maintained        ``riscv64`` and LLVM/Clang only.
>  ``s390``       Maintained        ``CONFIG_EXPOLINE`` must be disabled.
>  ``um``         Maintained        \-
>  ``x86``        Maintained        ``x86_64`` only.
> -=============  ================  ==============================================
> +=============  ================  ======================================================



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

* Re: [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg()
  2026-10-08  9:01   ` Gary Guo
@ 2026-10-09  1:17     ` Karl Mehltretter
  0 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-09  1:17 UTC (permalink / raw)
  To: Gary Guo
  Cc: Russell King, Miguel Ojeda, Boqun Feng, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

On Thu, Oct 08, 2026 at 11:01:32AM +0100, Gary Guo wrote:
> > v6.19 links. Commit ab717dd98bee ("rust: helpers: Add i8/i16 atomic
> > xchg_acquire helpers") in v7.0 triggers __bad_xchg. Commit
> > ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
> > in v7.1 also triggers __bad_cmpxchg.
> 
> I think the issue is that when you get multiple function calls in a function,
> GCC starts to think that not inlining can result in code deduplication where
> that is not actually true.
> 
> But I am surprised that it hasn't been seen in the past, perhaps there're only
> calls with single size from any translation unit previously?

The sizes were already mixed. It is the number of callers.

Commit 5dbc0a692459 ("rust: helpers: Add i8/i16 atomic xchg helpers")
has 1-, 2- and 4-byte xchg() in helpers.c and no __bad_xchg. The next
commit, ab717dd98bee, adds two more callers of the same sizes, the
xchg_acquire helpers, and has it.

> The fix LGTM, but Sashiko's report is worth looking into.

It's a valid concern. __generic_cmpxchg_local() has the same weakness
and patch 1 does not touch it. No file in the tree fails today. A test
file triggers it on ARMv5 with gcc 8.1.0 and CC_OPTIMIZE_FOR_SIZE:

- 12 valid cmpxchg_local() callers link
- 24 leave an undefined reference to wrong_size_cmpxchg
- __always_inline on __generic_cmpxchg_local() removes it

helpers.c stays below that. The ARMv4T and ARMv5TE kernels of this
series link with gcc 8.1.0. I will send this asm-generic change as a
separate patch.

Thanks,
Karl


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

* Re: [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T
  2026-10-08  9:08   ` Gary Guo
@ 2026-10-09  1:21     ` Karl Mehltretter
  0 siblings, 0 replies; 12+ messages in thread
From: Karl Mehltretter @ 2026-10-09  1:21 UTC (permalink / raw)
  To: Gary Guo
  Cc: Russell King, Miguel Ojeda, Boqun Feng, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, Arnd Bergmann, Linus Walleij,
	Christian Schrefl, Bradley Morgan, Paul E . McKenney,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
	linux-arm-kernel, rust-for-linux, llvm, linux-doc, linux-kernel

On Thu, Oct 08, 2026 at 11:08:52AM +0100, Gary Guo wrote:
> > +=============  ================  ======================================================
> >  Architecture   Level of support  Constraints
> > -=============  ================  ==============================================
> > -``arm``        Maintained        ARMv5TE, ARMv6K and ARMv7, Little Endian only.
> > +=============  ================  ======================================================
> > +``arm``        Maintained        ARMv4T, ARMv5TE, ARMv6K and ARMv7, Little Endian only.
> 
> Can we say "ARMv4T or above" or something similar?
> 

Plain ARMv6 (CPU_V6, ARM1136r0) and ARMv7-M stay excluded, so "or above"
alone would cover too much. It could be

  ARMv4T and above except plain ARMv6 and ARMv7-M, Little Endian only.

That is longer than the list. I can change it if there is a preference
for this form.

Thanks,
Karl


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

* Re: [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg()
  2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
  2026-10-08  9:01   ` Gary Guo
@ 2026-10-09  9:50   ` Gary Guo
  1 sibling, 0 replies; 12+ messages in thread
From: Gary Guo @ 2026-10-09  9:50 UTC (permalink / raw)
  To: Karl Mehltretter, Russell King, Miguel Ojeda
  Cc: Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich,
	Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
	Onur Özkan, Arnd Bergmann, Linus Walleij, Christian Schrefl,
	Bradley Morgan, Paul E . McKenney, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt, linux-arm-kernel,
	rust-for-linux, llvm, linux-doc, linux-kernel

On Thu Oct 8, 2026 at 6:37 AM BST, Karl Mehltretter wrote:
> __arch_xchg(), __cmpxchg() and __cmpxchg_local() end in a default case
> that calls an undefined function. That turns an unsupported size into a
> link error. It relies on the functions being inlined, so that the
> compiler can drop the default case for a constant size.
>
> They are only marked inline. gcc 8.1.0 with CC_OPTIMIZE_FOR_SIZE does
> not inline them in rust/helpers/helpers.c, which calls xchg() and
> cmpxchg() from many small helpers. The out-of-line copies keep the
> default case and the link fails.
>
>   helpers.c:(.text+0x424): undefined reference to `__bad_xchg'
>   helpers.c:(.text+0x4ac): undefined reference to `__bad_cmpxchg'
>
> Seen with bcm2835_defconfig and CONFIG_RUST=y on v7.3-rc1. The same
> config links with CONFIG_RUST=n. It also links with gcc 15.2.0 and
> with clang.
>
> v6.19 links. Commit ab717dd98bee ("rust: helpers: Add i8/i16 atomic
> xchg_acquire helpers") in v7.0 triggers __bad_xchg. Commit
> ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
> in v7.1 also triggers __bad_cmpxchg.

The change is okay, but the commit message is typical Claude style verbosity.
Especially this paragraph. Just describe what is the issue and what is the fix.
The mention of what other okay config you tried can be stripped. Mentions of
v6.19, v7.0 and v7.1 are completely unnecessary information.

Consider something like this:

    ...

    They are only marked inline. gcc 8.1.0 with CC_OPTIMIZE_FOR_SIZE decides to
    not inline them in rust/helpers/helpers.c, which calls xchg() and
    cmpxchg() from many small helpers. With bcm2835_defconfig and CONFIG_RUST=y,
    linking fails with:

        helpers.c:(.text+0x424): undefined reference to `__bad_xchg'
        helpers.c:(.text+0x4ac): undefined reference to `__bad_cmpxchg'

    Since the absence of inlining always produce a linker error, mark these
    functions as __always_inline instead.

With a better commit message:

Reviewed-by: Gary Guo <gary@garyguo.net>

>
> Mark the functions __always_inline.
>
> Fixes: ab717dd98bee ("rust: helpers: Add i8/i16 atomic xchg_acquire helpers")
> Fixes: ac8f06ade38a ("rust: sync: atomic: Add Atomic<*{mut,const} T> support")
> Cc: stable@vger.kernel.org

Arguably the commit in the fixed tags are not buggy themselves. They just add a
ok user that triggers the symptom of lack of inlining on an archaic GCC.

Best,
Gary

> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
> ---
>  arch/arm/include/asm/cmpxchg.h | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
> index 9beb64d30586..0ce5225af442 100644
> --- a/arch/arm/include/asm/cmpxchg.h
> +++ b/arch/arm/include/asm/cmpxchg.h
> @@ -26,7 +26,7 @@
>  #define swp_is_buggy
>  #endif
>  
> -static inline unsigned long
> +static __always_inline unsigned long
>  __arch_xchg(unsigned long x, volatile void *ptr, int size)
>  {
>  	extern void __bad_xchg(volatile void *, int);
> @@ -155,8 +155,8 @@ extern void __bad_cmpxchg(volatile void *ptr, int size);
>   * cmpxchg only support 32-bits operands on ARMv6.
>   */
>  
> -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
> -				      unsigned long new, int size)
> +static __always_inline unsigned long
> +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
>  {
>  	unsigned long oldval, res;
>  
> @@ -220,9 +220,9 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
>  				      sizeof(*(ptr)));			\
>  })
>  
> -static inline unsigned long __cmpxchg_local(volatile void *ptr,
> -					    unsigned long old,
> -					    unsigned long new, int size)
> +static __always_inline unsigned long
> +__cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new,
> +		int size)
>  {
>  	unsigned long ret;
>  




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

end of thread, other threads:[~2026-10-09  9:50 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08  5:37 [PATCH v2 0/6] ARM: rust: Enable Rust support for ARMv4T, ARMv5TE and ARMv6K Karl Mehltretter
2026-10-08  5:37 ` [PATCH v2 1/6] ARM: cmpxchg: always inline __arch_xchg() and __cmpxchg() Karl Mehltretter
2026-10-08  9:01   ` Gary Guo
2026-10-09  1:17     ` Karl Mehltretter
2026-10-09  9:50   ` Gary Guo
2026-10-08  5:37 ` [PATCH v2 2/6] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
2026-10-08  5:37 ` [PATCH v2 3/6] ARM: rust: Enable Rust support for ARMv6K-only kernels Karl Mehltretter
2026-10-08  5:37 ` [PATCH v2 4/6] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
2026-10-08  5:37 ` [PATCH v2 5/6] ARM: rust: Enable Rust support for ARMv4T Karl Mehltretter
2026-10-08  9:08   ` Gary Guo
2026-10-09  1:21     ` Karl Mehltretter
2026-10-08  5:37 ` [PATCH v2 6/6] ARM: rust: Build Rust code for ARMv7 on ARMv7 kernels Karl Mehltretter

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