[PATCH v2] powerpc/64: BE option to use ELFv2 ABI for big endian kernels
Michal Suchánek
msuchanek at suse.de
Mon May 3 02:57:57 AEST 2021
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 <msuchanek at suse.de>
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
>
> Reviewed-by: Segher Boessenkool <segher at kernel.crashing.org>
> Signed-off-by: Nicholas Piggin <npiggin at 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
> else
> diff --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.S
> diff --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
>
More information about the Linuxppc-dev
mailing list