diff mbox series

[v3] arm: rust: Enable Rust support for ARMv7

Message ID 20250123-rfl-arm32-v3-1-8f13623d42c5@gmail.com (mailing list archive)
State New
Headers show
Series [v3] arm: rust: Enable Rust support for ARMv7 | expand

Commit Message

Christian Schrefl Jan. 23, 2025, 10:40 p.m. UTC
This commit allows building ARMv7 kernels with Rust support.

The rust core library expects some __eabi_... functions
that are not implemented in the kernel.
Those functions are some float operations and __aeabi_uldivmod.
For now those are implemented with define_panicking_intrinsics!.

This is based on the code by Sven Van Asbroeck from the original
rust branch and inspired by the AArch version by Jamie Cunliffe.

I have tested the rust samples and a custom simple MMIO module
on hardware (De1SoC FPGA + Arm A9 CPU).

Tested-by: Rudraksha Gupta <guptarud@gmail.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
---
I've updated my Rust ARMv7 patches. 
Not much has changed since v2 but I want to send it out again
before sending it to Russell's ARM patch tracker, since I should
hopefully have more time to work on this again.

I'm not sure how exactly the patch tracker works, I assume I
should just sent it to the tracker once all review comments are 
addressed and it has sat in the mailing list for some time? 

I've kept the Tags from v2 since nothing signifficant has changed,
I hope thats fine with everyone.
---
Changes in v3:
- Rebased ontop of v6.13
    Removing the rust/bindgen_parameters changes which are
    already in 732cd686cdd6 (rust: fix `ARCH_SLAB_MINALIGN` multiple
    definition error) 
- Link to v2: https://lore.kernel.org/r/2dbd1491-149d-443c-9802-75786a6a3b73@gmail.com

Changes in v2:
- Removed unrelated whitespace change.
- Added target name to panic message in scripts/generate_rust_target.rs.
- Fixed the comment in rust/bindgen_parameters.
- Link to v1: https://lore.kernel.org/r/4e0f5932-c7bc-4878-862c-1186cbecd71d@gmail.com
---
 Documentation/rust/arch-support.rst |  1 +
 arch/arm/Kconfig                    |  1 +
 arch/arm/Makefile                   |  1 +
 rust/Makefile                       |  8 ++++++++
 rust/compiler_builtins.rs           | 24 ++++++++++++++++++++++++
 scripts/generate_rust_target.rs     |  4 +++-
 6 files changed, 38 insertions(+), 1 deletion(-)


---
base-commit: ffd294d346d185b70e28b1a28abe367bbfe53c04
change-id: 20250123-rfl-arm32-f93334146367

Best regards,
diff mbox series

Patch

diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index 54be7ddf3e57a732dbbca85541b137c62e834d7d..6e6a515d08991a130a8e79dc4ad7ad09da244020 100644
--- a/Documentation/rust/arch-support.rst
+++ b/Documentation/rust/arch-support.rst
@@ -15,6 +15,7 @@  support corresponds to ``S`` values in the ``MAINTAINERS`` file.
 =============  ================  ==============================================
 Architecture   Level of support  Constraints
 =============  ================  ==============================================
+``arm``        Maintained        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 202397be76d8037b531b34dee16c7dfcfd0124ef..3375c91e698c024f95a85682f5a91d9815c355e5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -130,6 +130,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
 	select HAVE_STACKPROTECTOR
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UID16
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 00ca7886b18efe2d01f33bc079eda2483ec807a7..4808d3ed98e42d39afc676f2654381f288d1b5b7 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -150,6 +150,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 asm/unified.h -msoft-float
+KBUILD_RUSTFLAGS += --target=arm-unknown-linux-gnueabi
 
 CHECKFLAGS	+= -D__arm__
 
diff --git a/rust/Makefile b/rust/Makefile
index a40a3936126d603836e0ec9b42a1285916b60e45..71932a088c860b9a129b9fe06811f67f5771b984 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -243,6 +243,7 @@  bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
 # Derived from `scripts/Makefile.clang`.
 BINDGEN_TARGET_x86	:= x86_64-linux-gnu
 BINDGEN_TARGET_arm64	:= aarch64-linux-gnu
+BINDGEN_TARGET_arm	:= arm-linux-gnueabi
 BINDGEN_TARGET		:= $(BINDGEN_TARGET_$(SRCARCH))
 
 # All warnings are inhibited since GCC builds are very experimental,
@@ -394,6 +395,13 @@  redirect-intrinsics = \
 	__muloti4 __multi3 \
 	__udivmodti4 __udivti3 __umodti3
 
+ifdef CONFIG_ARM
+	# Add eabi initrinsics for ARM 32-bit
+	redirect-intrinsics += \
+		__aeabi_fadd __aeabi_fmul __aeabi_fcmpeq __aeabi_fcmple __aeabi_fcmplt __aeabi_fcmpun \
+		__aeabi_dadd __aeabi_dmul __aeabi_dcmple __aeabi_dcmplt __aeabi_dcmpun \
+		__aeabi_uldivmod
+endif
 ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),)
 	# These intrinsics are defined for ARM64 and RISCV64
 	redirect-intrinsics += \
diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
index f14b8d7caf89964198313deace1bcb06fea82964..dd16c1dc899cbc755630ef3bae71e6eb0fd2c62a 100644
--- a/rust/compiler_builtins.rs
+++ b/rust/compiler_builtins.rs
@@ -73,5 +73,29 @@  pub extern "C" fn $ident() {
     __umodti3,
 });
 
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`f32` should not be used", {
+    __aeabi_fadd,
+    __aeabi_fmul,
+    __aeabi_fcmpeq,
+    __aeabi_fcmple,
+    __aeabi_fcmplt,
+    __aeabi_fcmpun,
+});
+
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`f64` should not be used", {
+    __aeabi_dadd,
+    __aeabi_dmul,
+    __aeabi_dcmple,
+    __aeabi_dcmplt,
+    __aeabi_dcmpun,
+});
+
+#[cfg(target_arch = "arm")]
+define_panicking_intrinsics!("`u64` division/modulo should not be used", {
+    __aeabi_uldivmod,
+});
+
 // NOTE: if you are adding a new intrinsic here, you should also add it to
 // `redirect-intrinsics` in `rust/Makefile`.
diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs
index 0d00ac3723b5e5971acb47478d6c2a63bc4ed6c6..f8e7fb38bf160ab35c9331a732fcd2fe4023fead 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -172,7 +172,9 @@  fn main() {
     let mut ts = TargetSpec::new();
 
     // `llvm-target`s are taken from `scripts/Makefile.clang`.
-    if cfg.has("ARM64") {
+    if cfg.has("ARM") {
+        panic!("arm uses the builtin rustc target");
+    } else if cfg.has("ARM64") {
         panic!("arm64 uses the builtin rustc aarch64-unknown-none target");
     } else if cfg.has("RISCV") {
         if cfg.has("64BIT") {