Re: [PATCH 1/2] ARM: cmpxchg: support 2-byte xchg() on pre-ARMv6 CPUs
From: Bradley Morgan
Date: Tue Oct 06 2026 - 10:49:41 EST
On 3 October 2026 10:38:26 BST, Karl Mehltretter <kmehltretter@xxxxxxxxx>
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().
>
>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
Reviewed-by: Bradley Morgan <brads@xxxxxxxxxxxxxx>
>Signed-off-by: Karl Mehltretter <kmehltretter@xxxxxxxxx>
>---
> 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 */
>
--- Thanks!
"I'm not a very positive person" - Linus torvalds