mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE
@ 2026-10-03  9:38 Karl Mehltretter
  2026-10-03  9:38 ` [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Karl Mehltretter @ 2026-10-03  9:38 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 is currently limited to ARMv7 on 32-bit ARM. This series extends
it to ARMv5TE.

Linus Walleij asked for older ARM cores during review of the ARMv7
support [1]. Christian Schrefl tried ARMv5 with the armv5te-none-eabi
target at the time [2]. He hit missing core atomics, missing
__aeabi_mem* symbols and a floating-point helper reached from
pr_info!() formatting. None of these show up anymore. The kernel crate
now implements atomics through the C helpers, and the
armv5te-unknown-linux-gnueabi target used here keeps the Linux EABI.

The only remaining problem was a link error. Pre-ARMv6 __arch_xchg()
has no 2-byte case, which the Rust Atomic<i16> helpers need. Patch 1
adds it the way the other pre-ARMv6 atomics work, with interrupts
disabled. Patch 2 enables Rust for ARMv5TE.

Bradley Morgan's two-byte cmpxchg() emulation series [3] does not
overlap with this. Its ARMv6 part was dropped in v2 and it never
covered xchg() or pre-ARMv6.

Tested on v7.3-rc1 with clang 22.1.8, rustc 1.99.0 and bindgen 0.73.2.

- QEMU versatilepb (ARM926EJ-S). The Rust samples, all Rust KUnit
  suites and 355 doctests pass.
- Microchip SAM9X75 Curiosity board (ARM926EJ-S), at91_dt_defconfig
  without the ARMv4T AT91RM9200. The samples, all Rust KUnit suites and
  356 doctests pass. The Rust sample modules (rust_minimal, rust_print,
  rust_misc_device, rust_driver_faux) load and unload cleanly.
- Build test with every Rust driver, abstraction and sample that can be
  selected on ARMv5TE (rnull, binder, the two PHY drivers, cpufreq-dt,
  the DRM panic QR code). PWM_TH1520 is the exception. It uses a native
  u64 division, which does not link on 32-bit ARM.

As a further test I ported the Atmel PWM driver to Rust and ran it next
to the C driver on the SAM9X75 board. The port is not part of this
series. The comparison found a prescaler bug in the C driver for
periods of 2^32 clock cycles or more [4].

I plan to get a Raspberry Pi 1 Model B+ and then add ARMv6K support as
a separate patch.

The ARMv7 enablement went in through Russell's patch system as
"ARM: 9441/1". Unless someone prefers another route I would submit
this series there after review.

[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/
[3] https://lore.kernel.org/lkml/20260922173354.14404-1-brads@mainlining.org/
[4] https://lore.kernel.org/linux-pwm/20261003083036.21584-1-kmehltretter@gmail.com/

Karl Mehltretter (2):
  ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
  ARM: rust: Enable Rust support for ARMv5TE

 Documentation/rust/arch-support.rst |  2 +-
 arch/arm/Kconfig                    |  2 +-
 arch/arm/Makefile                   |  4 ++++
 arch/arm/include/asm/cmpxchg.h      | 14 +++++++++++---
 4 files changed, 17 insertions(+), 5 deletions(-)


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


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

* [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
  2026-10-03  9:38 [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
@ 2026-10-03  9:38 ` Karl Mehltretter
  2026-10-03 10:12   ` Arnd Bergmann
  2026-10-03  9:38 ` [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
  2026-10-03 16:03 ` [PATCH 0/2] " Bradley Morgan
  2 siblings, 1 reply; 10+ messages in thread
From: Karl Mehltretter @ 2026-10-03  9:38 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 SMP requires
ARMv6K or later.

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 9beb64d30586..3077f7d7f520 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	[flat|nested] 10+ messages in thread

* [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03  9:38 [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
  2026-10-03  9:38 ` [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
@ 2026-10-03  9:38 ` Karl Mehltretter
  2026-10-03 10:24   ` Miguel Ojeda
  2026-10-03 10:45   ` Arnd Bergmann
  2026-10-03 16:03 ` [PATCH 0/2] " Bradley Morgan
  2 siblings, 2 replies; 10+ messages in thread
From: Karl Mehltretter @ 2026-10-03  9:38 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 currently selected for CPU_32v7 only. The
arm-unknown-linux-gnueabi target used for ARMv7 emits ARMv6
instructions (+v6), so it cannot be used for ARMv5. Use rustc's
built-in armv5te-unknown-linux-gnueabi target instead. It keeps the
Linux EABI (no short enums, unlike the -none-eabi targets) and is
soft-float and strict-align.

Kernels that also contain ARMv4 or ARMv4T CPUs are built for the
lowest architecture and stay excluded. 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 on v7.3-rc1 with clang 22.1.8, rustc 1.99.0 and bindgen 0.73.2
in QEMU versatilepb and on a Microchip SAM9X75 Curiosity board (both
ARM926EJ-S). The Rust samples, all Rust KUnit suites and the doctests
pass.

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                    | 2 +-
 arch/arm/Makefile                   | 4 ++++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 4f980815e92a..2193d8e1e156 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        ARMv5TE 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..f6b14d9f0e1f 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_32v7 || (CPU_32v5 && !CPU_32v4T && !CPU_32v4)) && !KASAN
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 573813ef5e77..ef94eae1f047 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -150,7 +150,11 @@ 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
+ifdef CONFIG_CPU_32v5
+KBUILD_RUSTFLAGS += --target=armv5te-unknown-linux-gnueabi
+else
 KBUILD_RUSTFLAGS += --target=arm-unknown-linux-gnueabi
+endif
 
 CHECKFLAGS	+= -D__arm__
 
-- 
2.39.5 (Apple Git-154)


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

* Re: [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
  2026-10-03  9:38 ` [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
@ 2026-10-03 10:12   ` Arnd Bergmann
  0 siblings, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2026-10-03 10:12 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, 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,
	Krzysztof Kozlowski

On Sat, Oct 3, 2026, at 11:38, Karl Mehltretter wrote:
> 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().

Note that 16-bit atomics are only in ARMv6K (1136r1, 1176),
not ARMv6 (1136r0). 

> 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 SMP requires
> ARMv6K or later.

This was previously impossible because you could have ARMv6 kernels
with SMP enabled, but now that Krzysztof has merged my series to
remove OMAP2 and i.MX6, this should work.

If anyone wants to backport this to older kernels, they would
also require d70242427110 ("ARM: rework ARM11 CPU selection logic").

Otherwise, this looks good,

Acked-by: Arnd Bergmann <arnd@arndb.de>

    Arnd

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

* Re: [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03  9:38 ` [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
@ 2026-10-03 10:24   ` Miguel Ojeda
  2026-10-04 18:56     ` Karl Mehltretter
  2026-10-03 10:45   ` Arnd Bergmann
  1 sibling, 1 reply; 10+ messages in thread
From: Miguel Ojeda @ 2026-10-03 10:24 UTC (permalink / raw)
  To: Karl Mehltretter
  Cc: Russell King, Miguel Ojeda, 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 Sat, Oct 3, 2026 at 11:38 AM Karl Mehltretter <kmehltretter@gmail.com> wrote:
>
> Tested on v7.3-rc1 with clang 22.1.8, rustc 1.99.0 and bindgen 0.73.2

Great to see more arch support! Just to confirm, are there any
toolchain requirements to be aware of?

If yes, then we should add them to Kconfig, `scripts/min-tool-version.sh` etc.

If not, then please test with the minimum versions too! :)

Thanks!

Cheers,
Miguel

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

* Re: [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03  9:38 ` [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
  2026-10-03 10:24   ` Miguel Ojeda
@ 2026-10-03 10:45   ` Arnd Bergmann
  2026-10-03 17:07     ` Karl Mehltretter
  1 sibling, 1 reply; 10+ messages in thread
From: Arnd Bergmann @ 2026-10-03 10:45 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, 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 Sat, Oct 3, 2026, at 11:38, Karl Mehltretter wrote:
> HAVE_RUST is currently selected for CPU_32v7 only. The
> arm-unknown-linux-gnueabi target used for ARMv7 emits ARMv6
> instructions (+v6), so it cannot be used for ARMv5. Use rustc's
> built-in armv5te-unknown-linux-gnueabi target instead. It keeps the
> Linux EABI (no short enums, unlike the -none-eabi targets) and is
> soft-float and strict-align.
>
> Kernels that also contain ARMv4 or ARMv4T CPUs are built for the
> lowest architecture and stay excluded. CPU_32v5 also covers the ARMv5T
> ARM1020. C code is already built with -march=armv5te there, so Rust
> matches.

None of this makes sense to me: The target should not control
the instruction set, that is what the -march= flag is needed for.
Does that not get passed for Rust?

If an ARMv7 kernel includes ARMv6 instructions, that is broken
on ARMv8 CPUs that are lacking the CP15 barriers and swp style
atomics, so that needs to be fixed.

I don't see what part of rust would depend on ARMv5 instructions,
it should just work on ARMv4T as well, though ARMv4 may be
trickier because missing bx instructions etc.

> ==============================================
> -``arm``        Maintained        ARMv7 Little Endian only.
> +``arm``        Maintained        ARMv5TE and ARMv7, Little Endian only.

Here you exclude ARMv6K and ARMv8-A-aarch32...

> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index ffbc7f386131..f6b14d9f0e1f 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_32v7 || (CPU_32v5 && 
> !CPU_32v4T && !CPU_32v4)) && !KASAN

but here you allow it, so I think one of them should change,
and you need to better explain what the dependency on !CPU_32v4T
is about, and what happens for an ARMv6K-only kernel, compared
to a combined ARMv6K+ARMv7-A one.

>  KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) 
> -include $(srctree)/arch/arm/include/asm/unified.h -msoft-float
> +ifdef CONFIG_CPU_32v5
> +KBUILD_RUSTFLAGS += --target=armv5te-unknown-linux-gnueabi
> +else
>  KBUILD_RUSTFLAGS += --target=arm-unknown-linux-gnueabi
> +endif

This looks wrong, the choice between armv5 and armv7 should work
the same way as the choice between armv6 and armv7/v8, if I read
the rustc docs correctly, this should be using the target-cpu=
argument on the generic arm-unknown-linux-gnueabi target.

      Arnd

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

* Re: [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03  9:38 [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
  2026-10-03  9:38 ` [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
  2026-10-03  9:38 ` [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
@ 2026-10-03 16:03 ` Bradley Morgan
  2 siblings, 0 replies; 10+ messages in thread
From: Bradley Morgan @ 2026-10-03 16:03 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,
	Paul E . McKenney, Nathan Chancellor, Nick Desaulniers,
	Bill Wendling, Justin Stitt, linux-arm-kernel, rust-for-linux,
	llvm, linux-doc, linux-kernel

On 3 October 2026 10:38:25 BST, Karl Mehltretter <kmehltretter@gmail.com>
wrote:
>Rust is currently limited to ARMv7 on 32-bit ARM. This series extends
>it to ARMv5TE.
>
>Linus Walleij asked for older ARM cores during review of the ARMv7
>support [1]. Christian Schrefl tried ARMv5 with the armv5te-none-eabi
>target at the time [2]. He hit missing core atomics, missing
>__aeabi_mem* symbols and a floating-point helper reached from
>pr_info!() formatting. None of these show up anymore. The kernel crate
>now implements atomics through the C helpers, and the
>armv5te-unknown-linux-gnueabi target used here keeps the Linux EABI.
>
>The only remaining problem was a link error. Pre-ARMv6 __arch_xchg()
>has no 2-byte case, which the Rust Atomic<i16> helpers need. Patch 1
>adds it the way the other pre-ARMv6 atomics work, with interrupts
>disabled. Patch 2 enables Rust for ARMv5TE.
>
>Bradley Morgan's two-byte cmpxchg() emulation series [3] does not
>overlap with this. Its ARMv6 part was dropped in v2 and it never
>covered xchg() or pre-ARMv6.

On purpose! It'll be dead code after one of ards changes

>
>Tested on v7.3-rc1 with clang 22.1.8, rustc 1.99.0 and bindgen 0.73.2.
>
>- QEMU versatilepb (ARM926EJ-S). The Rust samples, all Rust KUnit
>  suites and 355 doctests pass.
>- Microchip SAM9X75 Curiosity board (ARM926EJ-S), at91_dt_defconfig
>  without the ARMv4T AT91RM9200. The samples, all Rust KUnit suites and
>  356 doctests pass. The Rust sample modules (rust_minimal, rust_print,
>  rust_misc_device, rust_driver_faux) load and unload cleanly.
>- Build test with every Rust driver, abstraction and sample that can be
>  selected on ARMv5TE (rnull, binder, the two PHY drivers, cpufreq-dt,
>  the DRM panic QR code). PWM_TH1520 is the exception. It uses a native
>  u64 division, which does not link on 32-bit ARM.
>
>As a further test I ported the Atmel PWM driver to Rust and ran it next
>to the C driver on the SAM9X75 board. The port is not part of this
>series. The comparison found a prescaler bug in the C driver for
>periods of 2^32 clock cycles or more [4].
>
>I plan to get a Raspberry Pi 1 Model B+ and then add ARMv6K support as
>a separate patch.
>
>The ARMv7 enablement went in through Russell's patch system as
>"ARM: 9441/1". Unless someone prefers another route I would submit
>this series there after review.
>
>[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/
>[3]
>https://lore.kernel.org/lkml/20260922173354.14404-1-brads@mainlining.org/
>[4]
>https://lore.kernel.org/linux-pwm/20261003083036.21584-1-kmehltretter@gmail.com/
>
>Karl Mehltretter (2):
>  ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
>  ARM: rust: Enable Rust support for ARMv5TE
>
> Documentation/rust/arch-support.rst |  2 +-
> arch/arm/Kconfig                    |  2 +-
> arch/arm/Makefile                   |  4 ++++
> arch/arm/include/asm/cmpxchg.h      | 14 +++++++++++---
> 4 files changed, 17 insertions(+), 5 deletions(-)
>
>
>base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
>

--- Thanks!
https://lore.kernel.org/all/EE579805-42F2-4C58-B752-F28779EEB717@grrlz.net/

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

* Re: [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03 10:45   ` Arnd Bergmann
@ 2026-10-03 17:07     ` Karl Mehltretter
  2026-10-03 20:54       ` Arnd Bergmann
  0 siblings, 1 reply; 10+ messages in thread
From: Karl Mehltretter @ 2026-10-03 17:07 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Russell King, Miguel Ojeda, 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, 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 Sat, Oct 03, 2026 at 12:45:07PM +0100, Arnd Bergmann wrote:

Hi Arnd,

> > Kernels that also contain ARMv4 or ARMv4T CPUs are built for the
> > lowest architecture and stay excluded. CPU_32v5 also covers the ARMv5T
> > ARM1020. C code is already built with -march=armv5te there, so Rust
> > matches.
> 
> None of this makes sense to me: The target should not control
> the instruction set, that is what the -march= flag is needed for.
> Does that not get passed for Rust?

No. arch/arm/Makefile only passes --target=arm-unknown-linux-gnueabi,
no CPU or feature flags. That target has "+v6" built in, so Rust code
in an ARMv7 kernel is built as ARMv6 today.

I tried the generic target with CPU flags (libcore for versatile on
v7.3-rc1, rustc 1.99.0, CPU arch from the build attributes of core.o):

  --target=arm-unknown-linux-gnueabi
      ARMv6, uses uxtb/uxth/sxth/rev
  --target=arm-unknown-linux-gnueabi -Ctarget-cpu=arm926ej-s
      still ARMv6
  --target=arm-unknown-linux-gnueabi -Ctarget-cpu=arm926ej-s
  -Ctarget-feature=-v6
      ARMv5TE, but every rustc call warns
      "unstable feature specified for `-Ctarget-feature`: `v6`"
  --target=armv5te-unknown-linux-gnueabi
      ARMv5TE
  --target=armv4t-unknown-linux-gnueabi
      ARMv4T, no clz, no blx

So -Ctarget-cpu can add features but does not remove the +v6. The
generic target also declares 64-bit atomics, armv5te and armv4t only
32 bit. Below ARMv6 I only see the separate targets.

> 
> If an ARMv7 kernel includes ARMv6 instructions, that is broken
> on ARMv8 CPUs that are lacking the CP15 barriers and swp style
> atomics, so that needs to be fixed.

The Rust objects from the generic target have no swp and no CP15
access. The atomics go through the C helpers.

Building the Rust code of ARMv7 kernels as ARMv7 would be a separate
change. I can look at that after this series.

> 
> I don't see what part of rust would depend on ARMv5 instructions,
> it should just work on ARMv4T as well, though ARMv4 may be
> trickier because missing bx instructions etc.

Agreed. !CPU_32v4T only came from the armv5te target, which emits clz
and blx. With the armv4t target it can go. ARMv4 has no rustc target.

> 
> > ==============================================
> > -``arm``        Maintained        ARMv7 Little Endian only.
> > +``arm``        Maintained        ARMv5TE and ARMv7, Little Endian only.
> 
> Here you exclude ARMv6K and ARMv8-A-aarch32...
> [..] 
> but here you allow it, so I think one of them should change,
> 

Right. A v6K+v7 kernel has CPU_32v7 and gets HAVE_RUST already, a
v6K-only kernel does not. No technical reason. I have a patch for
v6K-only that I held back until I have a Pi 1, but I guess QEMU
suffices.

> This looks wrong, the choice between armv5 and armv7 should work
> the same way as the choice between armv6 and armv7/v8, if I read
> the rustc docs correctly, this should be using the target-cpu=
> argument on the generic arm-unknown-linux-gnueabi target.

There is no choice between ARMv6 and ARMv7 today. Both get the generic
target without flags and so ARMv6 code. And target-cpu= on the generic
target does not get below ARMv6, see the table above. That is why I
used a separate target for ARMv5.

For a v2 of this I would

- pick the rustc target next to the -march lines: armv4t for
  CPU_32v4T, armv5te for CPU_32v5, the generic one from ARMv6K upwards
- select HAVE_RUST for everything except CPU_32v4 and plain CPU_V6
- make arch-support.rst say the same

I have this running in QEMU on v7.3-rc1 with
- sx1 (OMAP310, ARM925T, ARMv4T), omap1_defconfig
- versatilepb (ARM926EJ-S), versatile_defconfig
- raspi0 (ARM1176), bcm2835_defconfig without ARCH_MULTI_V7

Would that be ok for you?

Thanks
Karl

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

* Re: [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03 17:07     ` Karl Mehltretter
@ 2026-10-03 20:54       ` Arnd Bergmann
  0 siblings, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2026-10-03 20:54 UTC (permalink / raw)
  To: Karl Mehltretter
  Cc: Russell King, Miguel Ojeda, 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, 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 Sat, Oct 3, 2026, at 19:07, Karl Mehltretter wrote:
> On Sat, Oct 03, 2026 at 12:45:07PM +0100, Arnd Bergmann wrote:
>>
>> > Kernels that also contain ARMv4 or ARMv4T CPUs are built for the
>> > lowest architecture and stay excluded. CPU_32v5 also covers the ARMv5T
>> > ARM1020. C code is already built with -march=armv5te there, so Rust
>> > matches.
>> 
>> None of this makes sense to me: The target should not control
>> the instruction set, that is what the -march= flag is needed for.
>> Does that not get passed for Rust?
>
> No. arch/arm/Makefile only passes --target=arm-unknown-linux-gnueabi,
> no CPU or feature flags. That target has "+v6" built in, so Rust code
> in an ARMv7 kernel is built as ARMv6 today.

How do you build ARMv7-A rust code in user space? If the default is
ARMv6, doesn't that rule out things like thumb2, vfpv3 and sensible
(inlined) atomics?

In the kernel, we don't normally allow neon code, but it sounds like
we may need to make rust depend on !CONFIG_THUMB2_KERNEL, as that
may be problematic when linking with v6 code.

> I tried the generic target with CPU flags (libcore for versatile on
> v7.3-rc1, rustc 1.99.0, CPU arch from the build attributes of core.o):
>
>   --target=arm-unknown-linux-gnueabi
>       ARMv6, uses uxtb/uxth/sxth/rev
>   --target=arm-unknown-linux-gnueabi -Ctarget-cpu=arm926ej-s
>       still ARMv6
>   --target=arm-unknown-linux-gnueabi -Ctarget-cpu=arm926ej-s

Ok, so I guess this is more like -mtune= in clang and gcc?

>  -Ctarget-feature=-v6
>      ARMv5TE, but every rustc call warns
>      "unstable feature specified for `-Ctarget-feature`: `v6`"
...
> So -Ctarget-cpu can add features but does not remove the +v6. The
> generic target also declares 64-bit atomics, armv5te and armv4t only
> 32 bit. Below ARMv6 I only see the separate targets.

Maybe this should be "+v7-a" instead of "-v6" to allow allow the
compiler to use all ARMv7-A features instead? It would be surprising
if they added 32-bit Arm support to Rust without a way to target what
is in almost every single chip and Linux distro today.

>> I don't see what part of rust would depend on ARMv5 instructions,
>> it should just work on ARMv4T as well, though ARMv4 may be
>> trickier because missing bx instructions etc.
>
> Agreed. !CPU_32v4T only came from the armv5te target, which emits clz
> and blx. With the armv4t target it can go. ARMv4 has no rustc target.

Ok, makes sense.

>> This looks wrong, the choice between armv5 and armv7 should work
>> the same way as the choice between armv6 and armv7/v8, if I read
>> the rustc docs correctly, this should be using the target-cpu=
>> argument on the generic arm-unknown-linux-gnueabi target.
>
> There is no choice between ARMv6 and ARMv7 today. Both get the generic
> target without flags and so ARMv6 code. And target-cpu= on the generic
> target does not get below ARMv6, see the table above. That is why I
> used a separate target for ARMv5.
>
> For a v2 of this I would
>
> - pick the rustc target next to the -march lines: armv4t for
>   CPU_32v4T, armv5te for CPU_32v5, the generic one from ARMv6K upwards
> - select HAVE_RUST for everything except CPU_32v4 and plain CPU_V6

I would leave out CPU_V7M as well, it's not worth trying to
support, and likely going away soon. It's probably not supported
by rust either, as this requires building with -march=armv7 or
-march=armv7-m and is definitely incompatible with -march=armv7-a
and -march=armv6k.

> - make arch-support.rst say the same
>
> I have this running in QEMU on v7.3-rc1 with
> - sx1 (OMAP310, ARM925T, ARMv4T), omap1_defconfig
> - versatilepb (ARM926EJ-S), versatile_defconfig
> - raspi0 (ARM1176), bcm2835_defconfig without ARCH_MULTI_V7
>
> Would that be ok for you?

Yes, sounds fine to me, though I would still hope to get native
ARMv7-A support in place of "build for v6 and hope for the best"
approach eventually. 

      Arnd

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

* Re: [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE
  2026-10-03 10:24   ` Miguel Ojeda
@ 2026-10-04 18:56     ` Karl Mehltretter
  0 siblings, 0 replies; 10+ messages in thread
From: Karl Mehltretter @ 2026-10-04 18:56 UTC (permalink / raw)
  To: Miguel Ojeda
  Cc: Russell King, Miguel Ojeda, 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 Sat, Oct 03, 2026 at 12:24:35PM +0100, Miguel Ojeda wrote:
> On Sat, Oct 3, 2026 at 11:38 AM Karl Mehltretter <kmehltretter@gmail.com> wrote:
> >
> > Tested on v7.3-rc1 with clang 22.1.8, rustc 1.99.0 and bindgen 0.73.2
> 
> Great to see more arch support! Just to confirm, are there any
> toolchain requirements to be aware of?
> 
> If yes, then we should add them to Kconfig, `scripts/min-tool-version.sh` etc.
> 
> If not, then please test with the minimum versions too! :)
> 

Thanks for suggesting that! No extra requirements as far as I can tell.
I now also test with the minimum versions (LLVM 17.0.1 and gcc 8.1.0,
with rustc 1.85.0 and bindgen 0.71.1).

So far I found one small issue with gcc 8.1.0. A fix for that will be in
the v2 series.

Karl

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

end of thread, other threads:[~2026-10-04 18:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-03  9:38 [PATCH 0/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
2026-10-03  9:38 ` [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs Karl Mehltretter
2026-10-03 10:12   ` Arnd Bergmann
2026-10-03  9:38 ` [PATCH 2/2] ARM: rust: Enable Rust support for ARMv5TE Karl Mehltretter
2026-10-03 10:24   ` Miguel Ojeda
2026-10-04 18:56     ` Karl Mehltretter
2026-10-03 10:45   ` Arnd Bergmann
2026-10-03 17:07     ` Karl Mehltretter
2026-10-03 20:54       ` Arnd Bergmann
2026-10-03 16:03 ` [PATCH 0/2] " Bradley Morgan

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

all inboxes | Powered by JetHome®