Documentation/rust/arch-support.rst | 1 + arch/arm/Kconfig | 1 + arch/arm/Makefile | 1 + rust/Makefile | 8 ++++++++ rust/bindgen_parameters | 4 ++++ rust/compiler_builtins.rs | 24 ++++++++++++++++++++++++ scripts/generate_rust_target.rs | 4 +++- 7 files changed, 42 insertions(+), 1 deletion(-)
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 AArch64 version by Jamie Cunliffe.
I have tested the rust samples and a custom simple MMIO module
on hardware (De1SoC FPGA + Arm A9 CPU).
This only includes support for ARMv7, but supporting other
sub-architectures in the future should be as simple as setting
the correct rustc target.
Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
---
Changes since V1 [1]:
- Removed unrelated whitespace change.
- Added target name to panic message in scripts/generate_rust_target.rs.
- Fixed the comment in rust/bindgen_parameters.
[1]: https://lore.kernel.org/rust-for-linux/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/bindgen_parameters | 4 ++++
rust/compiler_builtins.rs | 24 ++++++++++++++++++++++++
scripts/generate_rust_target.rs | 4 +++-
7 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
index b13e19d84744..4bf5205f526d 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`` only.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ee5115252aac..f07149fe078b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -126,6 +126,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 71afdd98ddf2..9cc10e32e8be 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 f70d5e244fee..8214a6f378e3 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -287,6 +287,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,
@@ -413,6 +414,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/bindgen_parameters b/rust/bindgen_parameters
index a721d466bee4..83f28ae4bb2b 100644
--- a/rust/bindgen_parameters
+++ b/rust/bindgen_parameters
@@ -24,3 +24,7 @@
# These functions use the `__preserve_most` calling convention, which neither bindgen
# nor Rust currently understand, and which Clang currently declares to be unstable.
--blocklist-function __list_.*_report
+
+# Depending on how the architecture defines `ARCH_SLAB_MINALIGN`, `bindgen` might generate a binding.
+# Disable this here as there is a `const` item that will always be generated in `bindings_helper.h`
+--blocklist-item ARCH_SLAB_MINALIGN
diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
index bba2922c6ef7..c37142b16a45 100644
--- a/rust/compiler_builtins.rs
+++ b/rust/compiler_builtins.rs
@@ -70,5 +70,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 641b713a033a..c3a6058fdf30 100644
--- a/scripts/generate_rust_target.rs
+++ b/scripts/generate_rust_target.rs
@@ -148,7 +148,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 arm-unknown-linux-gnueabi 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") {
base-commit: 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0
--
2.45.2
Greetings,
Friendly Ping :)
This has been on the mailing list for quite some time with only a few responses.
Please let me know if something is needed from my side (like rebasing or wanted changes).
Cheers
Christian
On 17.06.24 6:03 PM, Christian Schrefl wrote:
> 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 AArch64 version by Jamie Cunliffe.
>
> I have tested the rust samples and a custom simple MMIO module
> on hardware (De1SoC FPGA + Arm A9 CPU).
>
> This only includes support for ARMv7, but supporting other
> sub-architectures in the future should be as simple as setting
> the correct rustc target.
>
> Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com>
> ---
> Changes since V1 [1]:
> - Removed unrelated whitespace change.
> - Added target name to panic message in scripts/generate_rust_target.rs.
> - Fixed the comment in rust/bindgen_parameters.
>
>
> [1]: https://lore.kernel.org/rust-for-linux/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/bindgen_parameters | 4 ++++
> rust/compiler_builtins.rs | 24 ++++++++++++++++++++++++
> scripts/generate_rust_target.rs | 4 +++-
> 7 files changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/rust/arch-support.rst b/Documentation/rust/arch-support.rst
> index b13e19d84744..4bf5205f526d 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`` only.
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index ee5115252aac..f07149fe078b 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -126,6 +126,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 71afdd98ddf2..9cc10e32e8be 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 f70d5e244fee..8214a6f378e3 100644
> --- a/rust/Makefile
> +++ b/rust/Makefile
> @@ -287,6 +287,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,
> @@ -413,6 +414,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/bindgen_parameters b/rust/bindgen_parameters
> index a721d466bee4..83f28ae4bb2b 100644
> --- a/rust/bindgen_parameters
> +++ b/rust/bindgen_parameters
> @@ -24,3 +24,7 @@
> # These functions use the `__preserve_most` calling convention, which neither bindgen
> # nor Rust currently understand, and which Clang currently declares to be unstable.
> --blocklist-function __list_.*_report
> +
> +# Depending on how the architecture defines `ARCH_SLAB_MINALIGN`, `bindgen` might generate a binding.
> +# Disable this here as there is a `const` item that will always be generated in `bindings_helper.h`
> +--blocklist-item ARCH_SLAB_MINALIGN
> diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
> index bba2922c6ef7..c37142b16a45 100644
> --- a/rust/compiler_builtins.rs
> +++ b/rust/compiler_builtins.rs
> @@ -70,5 +70,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 641b713a033a..c3a6058fdf30 100644
> --- a/scripts/generate_rust_target.rs
> +++ b/scripts/generate_rust_target.rs
> @@ -148,7 +148,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 arm-unknown-linux-gnueabi 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") {
>
> base-commit: 1613e604df0cd359cf2a7fbd9be7a0bcfacfabd0
On Mon, Jul 29, 2024 at 11:58 AM Christian Schrefl
<chrisi.schrefl@gmail.com> wrote:
>
> This has been on the mailing list for quite some time with only a few responses.
Up to arm to take it -- if it helps, I tried the patch, including
building, booting in QEMU, running the KUnit tests and loading the
sample modules. Thus:
Acked-by: Miguel Ojeda <ojeda@kernel.org>
Tested-by: Miguel Ojeda <ojeda@kernel.org>
However, to keep our build Clippy-clean, it requires a a patch like:
https://lore.kernel.org/rust-for-linux/20240730155702.1110144-1-ojeda@kernel.org/
which should ideally be applied together.
I hope that helps!
(Nit: please avoid top-posting, see https://subspace.kernel.org/etiquette.html)
Cheers,
Miguel
On 30.07.24 6:00 PM, Miguel Ojeda wrote: > On Mon, Jul 29, 2024 at 11:58 AM Christian Schrefl > <chrisi.schrefl@gmail.com> wrote: >> >> This has been on the mailing list for quite some time with only a few responses. > > Up to arm to take it -- if it helps, I tried the patch, including > building, booting in QEMU, running the KUnit tests and loading the > sample modules. Thus: > > Acked-by: Miguel Ojeda <ojeda@kernel.org> > Tested-by: Miguel Ojeda <ojeda@kernel.org> Did you apply it on 6.11-rc1? > However, to keep our build Clippy-clean, it requires a a patch like: > > https://lore.kernel.org/rust-for-linux/20240730155702.1110144-1-ojeda@kernel.org/ > > which should ideally be applied together. I think that I ran clippy, maybe that changed between 6.10 and 6.11. > I hope that helps! > > (Nit: please avoid top-posting, see https://subspace.kernel.org/etiquette.html) Sorry, I'm still getting used to using the mailing list. Cheers, Christian
On Tue, Jul 30, 2024 at 6:35 PM Christian Schrefl <chrisi.schrefl@gmail.com> wrote: > > Did you apply it on 6.11-rc1? Yeah. > I think that I ran clippy, maybe that changed between 6.10 and 6.11. It also triggers on top of v6.10-rc1 from a quick test (we had also this lint or similar even before we were in mainline, I think), but no worries, it is not a big deal :) Cheers, Miguel
(cc Russell) On Tue, 30 Jul 2024 at 18:01, Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote: > > On Mon, Jul 29, 2024 at 11:58 AM Christian Schrefl > <chrisi.schrefl@gmail.com> wrote: > > > > This has been on the mailing list for quite some time with only a few responses. > > Up to arm to take it -- if it helps, I tried the patch, including > building, booting in QEMU, running the KUnit tests and loading the > sample modules. Thus: > > Acked-by: Miguel Ojeda <ojeda@kernel.org> > Tested-by: Miguel Ojeda <ojeda@kernel.org> > Acked-by: Ard Biesheuvel <ardb@kernel.org> If this needs to go via the ARM tree, it will need to go into Russell's patch tracker https://www.armlinux.org.uk/developer/patches/
On Mon, Jun 17, 2024 at 6:04 PM Christian Schrefl <chrisi.schrefl@gmail.com> wrote: > > 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 AArch64 version by Jamie Cunliffe. > > I have tested the rust samples and a custom simple MMIO module > on hardware (De1SoC FPGA + Arm A9 CPU). > > This only includes support for ARMv7, but supporting other > sub-architectures in the future should be as simple as setting > the correct rustc target. > > Signed-off-by: Christian Schrefl <chrisi.schrefl@gmail.com> With the clarification from Ard, I give: Reviewed-by: Alice Ryhl <aliceryhl@google.com>
On Mon, Jun 17, 2024 at 6:04 PM Christian Schrefl <chrisi.schrefl@gmail.com> wrote: > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > index 71afdd98ddf2..9cc10e32e8be 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 On arm64 we use a target called aarch64-unknown-none. Should you also be using arm-unknown-none? Or maybe the arm64 target should be changed to aarch64-unknown-linux-gnueabi? Alice
On Thu, 4 Jul 2024 at 10:20, Alice Ryhl <aliceryhl@google.com> wrote: > > On Mon, Jun 17, 2024 at 6:04 PM Christian Schrefl > <chrisi.schrefl@gmail.com> wrote: > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > > index 71afdd98ddf2..9cc10e32e8be 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 > > On arm64 we use a target called aarch64-unknown-none. Should you also > be using arm-unknown-none? Or maybe the arm64 target should be changed > to aarch64-unknown-linux-gnueabi? > Neither. EABI is highly specific to 32-bit ARM, no point in trying to align this between architectures.
On Thu, Jul 4, 2024 at 10:42 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Thu, 4 Jul 2024 at 10:20, Alice Ryhl <aliceryhl@google.com> wrote: > > > > On Mon, Jun 17, 2024 at 6:04 PM Christian Schrefl > > <chrisi.schrefl@gmail.com> wrote: > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile > > > index 71afdd98ddf2..9cc10e32e8be 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 > > > > On arm64 we use a target called aarch64-unknown-none. Should you also > > be using arm-unknown-none? Or maybe the arm64 target should be changed > > to aarch64-unknown-linux-gnueabi? > > > > Neither. EABI is highly specific to 32-bit ARM, no point in trying to > align this between architectures. Ok. Thanks for the clarification. Alice
© 2016 - 2025 Red Hat, Inc.