From 5561161153eb069be042357b27eb6b9d4c721a2c Mon Sep 17 00:00:00 2001 From: David Gow Date: Thu, 23 Jun 2022 14:10:12 +0800 Subject: [PATCH 1/2] arch: x86: Implement mod/div compiler builtins While the kernel deliberately doesn't implement compiler builtins for 64-bit division and modulus on 32-bit x86, it seems that rust may require them for some standard library code. Add basic implementations which are based on the math64.h macros. Note that these currently live in moddiv_32.c, because they're for 32-bit x86, even though they operate on 64-bit integers (confusing, isn't it). The right solution is probably to put them in rust's compiler_builtins implentation, with all of its symbol hiding, etc. Signed-off-by: David Gow --- arch/x86/lib/Makefile | 1 + arch/x86/lib/moddiv_32.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 arch/x86/lib/moddiv_32.c diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 7ba5f61d727353..6f267fc07e8119 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -63,6 +63,7 @@ ifeq ($(CONFIG_X86_32),y) ifneq ($(CONFIG_X86_CMPXCHG64),y) lib-y += cmpxchg8b_emu.o atomic64_386_32.o endif + lib-y += moddiv_32.o else obj-y += iomap_copy_64.o ifneq ($(CONFIG_GENERIC_CSUM),y) diff --git a/arch/x86/lib/moddiv_32.c b/arch/x86/lib/moddiv_32.c new file mode 100644 index 00000000000000..ea85042472b651 --- /dev/null +++ b/arch/x86/lib/moddiv_32.c @@ -0,0 +1,13 @@ +#include + +unsigned long long __udivdi3(unsigned long long a, unsigned long long b) +{ + return div64_u64(a, b); +} + +unsigned long long __umoddi3(unsigned long long a, unsigned long long b) +{ + unsigned long long rem; + div64_u64_rem(a, b, &rem); + return rem; +} From 10c154633e8d149449f80e2f94e15ed5de2238c9 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 13 May 2022 16:22:14 +0800 Subject: [PATCH 2/2] rust: 32-bit x86 support [BROKEN] Add support for 32-bit i386 targets when building Rust code. In addition, support 32-bit i386 for UML. Note that this doesn't work at the moment, due to a nasty crash which I _think_ is somewhere deep in the printk / fmt code. It does, however, work fine under UML, so all is not yet totally lost. I've not got around to setting CI up (since it's broken anyway), but some KUnit commands for testing work for me: qemu/i386: ./tools/testing/kunit/kunit.py run --arch i386 --make_options LLVM=1 --kconfig_add CONFIG_RUST=y UML/i386: ./tools/testing/kunit/kunit.py run --make_options LLVM=1 --kconfig_add CONFIG_RUST=y --kconfig_add CONFIG_64BIT=n Signed-off-by: David Gow --- arch/um/Kconfig | 2 +- arch/x86/Kconfig | 2 +- scripts/generate_rust_target.rs | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 4db186f019ae46..94ee2d35404b39 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -28,7 +28,7 @@ config UML select TRACE_IRQFLAGS_SUPPORT select TTY # Needed for line.c select HAVE_ARCH_VMAP_STACK - select HAVE_RUST if X86_64 + select HAVE_RUST config MMU bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6d1879ef933a2c..98d64f5c301b49 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -263,7 +263,7 @@ config X86 select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL select HAVE_PREEMPT_DYNAMIC_CALL select HAVE_RSEQ - select HAVE_RUST if X86_64 + select HAVE_RUST select HAVE_SYSCALL_TRACEPOINTS select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL select HAVE_UNSTABLE_SCHED_CLOCK diff --git a/scripts/generate_rust_target.rs b/scripts/generate_rust_target.rs index 0a1ba95d74e772..87c1d23f0a2eea 100644 --- a/scripts/generate_rust_target.rs +++ b/scripts/generate_rust_target.rs @@ -211,6 +211,19 @@ fn main() { ts.push("features", features); ts.push("llvm-target", "x86_64-linux-gnu"); ts.push("target-pointer-width", "64"); + } else if cfg.has("X86_32") { + ts.push("arch", "x86"); + ts.push( + "data-layout", + "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", + ); + let mut features = "-3dnow,-3dnowa,-mmx,+soft-float".to_string(); + if cfg.has("RETPOLINE") { + features += ",+retpoline-external-thunk"; + } + ts.push("features", features); + ts.push("llvm-target", "i386-unknown-linux-gnu"); + ts.push("target-pointer-width", "32"); } else { panic!("Unsupported architecture"); }