Re: [PATCH v2] powerpc/64: BE option to use ELFv2 ABI for big endian kernels
From: Michal Suchánek <hidden>
Date: 2021-05-02 16:58:28
Subsystem:
linux for powerpc (32-bit and 64-bit), the rest · Maintainers:
Madhavan Srinivasan, Michael Ellerman, Linus Torvalds
On Tue, Apr 28, 2020 at 09:25:17PM +1000, Nicholas Piggin wrote:
Provide an option to use ELFv2 ABI for big endian builds. This works on GCC and clang (since 2014). It is less well tested and supported by the GNU toolchain, but it can give some useful advantages of the ELFv2 ABI for BE (e.g., less stack usage). Some distros even build BE ELFv2 userspace.
Fixes BTFID failure on BE for me and the ELF ABIv2 kernel boots. Tested-by: Michal Suchánek <redacted> Also can we enable mprofile on BE now? I don't see anything endian-specific in the mprofile code at a glance but don't have any idea how to test it. Thanks Michal
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6a4ad11f6349..75b3afbfc378 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig@@ -495,7 +495,7 @@ config LD_HEAD_STUB_CATCH If unsure, say "N". config MPROFILE_KERNEL - depends on PPC64 && CPU_LITTLE_ENDIAN && FUNCTION_TRACER + depends on PPC64 && BUILD_ELF_V2 && FUNCTION_TRACER def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__) config HOTPLUG_CPU
quoted hunk ↗ jump to hunk
Reviewed-by: Segher Boessenkool <redacted> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- Since v1: - Improved the override flavour name suggested by Segher. - Improved changelog wording. arch/powerpc/Kconfig | 19 +++++++++++++++++++ arch/powerpc/Makefile | 15 ++++++++++----- arch/powerpc/boot/Makefile | 4 ++++ drivers/crypto/vmx/Makefile | 8 ++++++-- drivers/crypto/vmx/ppc-xlate.pl | 10 ++++++---- 5 files changed, 45 insertions(+), 11 deletions(-)diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 924c541a9260..d9d2abc06c2c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig@@ -147,6 +147,7 @@ config PPC select ARCH_WEAK_RELEASE_ACQUIRE select BINFMT_ELF select BUILDTIME_TABLE_SORT + select BUILD_ELF_V2 if PPC64 && CPU_LITTLE_ENDIAN select CLONE_BACKWARDS select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN select DYNAMIC_FTRACE if FUNCTION_TRACER@@ -541,6 +542,24 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE +config BUILD_ELF_V2 + bool + +config BUILD_BIG_ENDIAN_ELF_V2 + bool "Build big-endian kernel using ELFv2 ABI (EXPERIMENTAL)" + depends on PPC64 && CPU_BIG_ENDIAN && EXPERT + default n + select BUILD_ELF_V2 + help + This builds the kernel image using the ELFv2 ABI, which has a + reduced stack overhead and faster function calls. This does not + affect the userspace ABIs. + + ELFv2 is the standard ABI for little-endian, but for big-endian + this is an experimental option that is less tested (kernel and + toolchain). This requires gcc 4.9 or newer and binutils 2.24 or + newer. + config RELOCATABLE bool "Build a relocatable kernel" depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE))diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index f310c32e88a4..e306b39d847e 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile@@ -92,10 +92,14 @@ endif ifdef CONFIG_PPC64 ifndef CONFIG_CC_IS_CLANG -cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1) -cflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mcall-aixdesc) -aflags-$(CONFIG_CPU_BIG_ENDIAN) += $(call cc-option,-mabi=elfv1) -aflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -mabi=elfv2 +ifdef CONFIG_BUILD_ELF_V2 +cflags-y += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc)) +aflags-y += $(call cc-option,-mabi=elfv2) +else +cflags-y += $(call cc-option,-mabi=elfv1) +cflags-y += $(call cc-option,-mcall-aixdesc) +aflags-y += $(call cc-option,-mabi=elfv1) +endif endif endif@@ -144,7 +148,7 @@ endif CFLAGS-$(CONFIG_PPC64) := $(call cc-option,-mtraceback=no) ifndef CONFIG_CC_IS_CLANG -ifdef CONFIG_CPU_LITTLE_ENDIAN +ifdef CONFIG_BUILD_ELF_V2 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc)) AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv2) else@@ -153,6 +157,7 @@ CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcall-aixdesc) AFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mabi=elfv1) endif endif + CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,$(call cc-option,-mminimal-toc)) CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index c53a1b8bba8b..03942d08695d 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile@@ -41,6 +41,10 @@ endif BOOTCFLAGS += -isystem $(shell $(BOOTCC) -print-file-name=include) +ifdef CONFIG_BUILD_ELF_V2 +BOOTCFLAGS += $(call cc-option,-mabi=elfv2) +endif + ifdef CONFIG_CPU_BIG_ENDIAN BOOTCFLAGS += -mbig-endian elsediff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile index 709670d2b553..9aea34602beb 100644 --- a/drivers/crypto/vmx/Makefile +++ b/drivers/crypto/vmx/Makefile@@ -5,18 +5,22 @@ vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) override flavour := linux-ppc64le else +ifdef CONFIG_BUILD_ELF_V2 +override flavour := linux-ppc64-elfv2 +else override flavour := linux-ppc64 endif +endif quiet_cmd_perl = PERL $@ cmd_perl = $(PERL) $(<) $(flavour) > $(@) targets += aesp8-ppc.S ghashp8-ppc.S -$(obj)/aesp8-ppc.S: $(src)/aesp8-ppc.pl FORCE +$(obj)/aesp8-ppc.S: $(src)/aesp8-ppc.pl $(src)/ppc-xlate.pl FORCE $(call if_changed,perl) -$(obj)/ghashp8-ppc.S: $(src)/ghashp8-ppc.pl FORCE +$(obj)/ghashp8-ppc.S: $(src)/ghashp8-ppc.pl $(src)/ppc-xlate.pl FORCE $(call if_changed,perl) clean-files := aesp8-ppc.S ghashp8-ppc.Sdiff --git a/drivers/crypto/vmx/ppc-xlate.pl b/drivers/crypto/vmx/ppc-xlate.pl index 36db2ef09e5b..9db0937d318b 100644 --- a/drivers/crypto/vmx/ppc-xlate.pl +++ b/drivers/crypto/vmx/ppc-xlate.pl@@ -9,6 +9,8 @@ open STDOUT,">$output" || die "can't open $output: $!"; my %GLOBALS; my $dotinlocallabels=($flavour=~/linux/)?1:0; +my $abielfv2=(($flavour =~ /linux-ppc64le/) or ($flavour =~ /linux-ppc64-elfv2/))?1:0; +my $dotfunctions=($abielfv2=~1)?0:1; ################################################################ # directives which need special treatment on different platforms@@ -40,7 +42,7 @@ my $globl = sub { }; my $text = sub { my $ret = ($flavour =~ /aix/) ? ".csect\t.text[PR],7" : ".text"; - $ret = ".abiversion 2\n".$ret if ($flavour =~ /linux.*64le/); + $ret = ".abiversion 2\n".$ret if ($abielfv2); $ret; }; my $machine = sub {@@ -56,8 +58,8 @@ my $size = sub { if ($flavour =~ /linux/) { shift; my $name = shift; $name =~ s|^[\.\_]||; - my $ret = ".size $name,.-".($flavour=~/64$/?".":"").$name; - $ret .= "\n.size .$name,.-.$name" if ($flavour=~/64$/); + my $ret = ".size $name,.-".($dotfunctions?".":"").$name; + $ret .= "\n.size .$name,.-.$name" if ($dotfunctions); $ret; } else@@ -142,7 +144,7 @@ my $vmr = sub { # Some ABIs specify vrsave, special-purpose register #256, as reserved # for system use. -my $no_vrsave = ($flavour =~ /linux-ppc64le/); +my $no_vrsave = ($abielfv2); my $mtspr = sub { my ($f,$idx,$ra) = @_; if ($idx == 256 && $no_vrsave) {-- 2.23.0