linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
       [not found] <20210503110713.751840-1-npiggin__45037.8389026568$1620040079$gmane$org@gmail.com>
@ 2021-05-03 11:37 ` Andreas Schwab
  2021-05-03 14:38   ` Michal Suchánek
  0 siblings, 1 reply; 9+ messages in thread
From: Andreas Schwab @ 2021-05-03 11:37 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: Michal Suchánek, linuxppc-dev

Should this add a tag to the module vermagic?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-03 11:37 ` [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels Andreas Schwab
@ 2021-05-03 14:38   ` Michal Suchánek
  2021-05-04 10:27     ` Nicholas Piggin
  2021-05-05 12:07     ` Michael Ellerman
  0 siblings, 2 replies; 9+ messages in thread
From: Michal Suchánek @ 2021-05-03 14:38 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: linuxppc-dev, Nicholas Piggin

On Mon, May 03, 2021 at 01:37:57PM +0200, Andreas Schwab wrote:
> Should this add a tag to the module vermagic?

Would the modues link even if the vermagic was not changed?

I suppose something like this might do it.

Thanks

Michal

diff --git a/arch/powerpc/include/asm/vermagic.h b/arch/powerpc/include/asm/vermagic.h
index b054a8576e5d..3fdaacd7a743 100644
--- a/arch/powerpc/include/asm/vermagic.h
+++ b/arch/powerpc/include/asm/vermagic.h
@@ -14,7 +14,14 @@
 #define MODULE_ARCH_VERMAGIC_RELOCATABLE	""
 #endif
 
+
+#ifdef CONFIG_PPC64_BUILD_BIG_ENDIAN_ELF_V2_ABI
+#define MODULE_ARCH_VERMAGIC_ELF_V2_ABI	"abi-elfv2 "
+#else
+#define MODULE_ARCH_VERMAGIC_ELF_V2_ABI	""
+#endif
+
 #define MODULE_ARCH_VERMAGIC \
-		MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE
+		MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE MODULE_ARCH_VERMAGIC_ELF_V2_ABI
 
 #endif /* _ASM_VERMAGIC_H */

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-03 14:38   ` Michal Suchánek
@ 2021-05-04 10:27     ` Nicholas Piggin
  2021-05-05 12:07     ` Michael Ellerman
  1 sibling, 0 replies; 9+ messages in thread
From: Nicholas Piggin @ 2021-05-04 10:27 UTC (permalink / raw)
  To: Michal Suchánek, Andreas Schwab; +Cc: linuxppc-dev

Excerpts from Michal Suchánek's message of May 4, 2021 12:38 am:
> On Mon, May 03, 2021 at 01:37:57PM +0200, Andreas Schwab wrote:
>> Should this add a tag to the module vermagic?

Good question.

> 
> Would the modues link even if the vermagic was not changed?
> 
> I suppose something like this might do it.

Yeah I don't know how robust the loader would be to a mismatch. We could 
add this patch.

Thanks,
Nick

> 
> Thanks
> 
> Michal
> 
> diff --git a/arch/powerpc/include/asm/vermagic.h b/arch/powerpc/include/asm/vermagic.h
> index b054a8576e5d..3fdaacd7a743 100644
> --- a/arch/powerpc/include/asm/vermagic.h
> +++ b/arch/powerpc/include/asm/vermagic.h
> @@ -14,7 +14,14 @@
>  #define MODULE_ARCH_VERMAGIC_RELOCATABLE	""
>  #endif
>  
> +
> +#ifdef CONFIG_PPC64_BUILD_BIG_ENDIAN_ELF_V2_ABI
> +#define MODULE_ARCH_VERMAGIC_ELF_V2_ABI	"abi-elfv2 "
> +#else
> +#define MODULE_ARCH_VERMAGIC_ELF_V2_ABI	""
> +#endif
> +
>  #define MODULE_ARCH_VERMAGIC \
> -		MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE
> +		MODULE_ARCH_VERMAGIC_FTRACE MODULE_ARCH_VERMAGIC_RELOCATABLE MODULE_ARCH_VERMAGIC_ELF_V2_ABI
>  
>  #endif /* _ASM_VERMAGIC_H */
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-03 14:38   ` Michal Suchánek
  2021-05-04 10:27     ` Nicholas Piggin
@ 2021-05-05 12:07     ` Michael Ellerman
  2021-05-05 13:25       ` Michal Suchánek
  2021-05-14 19:36       ` Michal Suchánek
  1 sibling, 2 replies; 9+ messages in thread
From: Michael Ellerman @ 2021-05-05 12:07 UTC (permalink / raw)
  To: Michal Suchánek, Andreas Schwab; +Cc: linuxppc-dev, Nicholas Piggin

Michal Suchánek <msuchanek@suse.de> writes:
> On Mon, May 03, 2021 at 01:37:57PM +0200, Andreas Schwab wrote:
>> Should this add a tag to the module vermagic?
>
> Would the modues link even if the vermagic was not changed?

Most modules will require some symbols from the kernel, and those will
be dot symbols, which won't resolve.

But there are a few small modules that don't rely on any kernel symbols,
which can load.

> I suppose something like this might do it.

It would, but I feel like we should be handling this at the ELF level.
ie. we don't allow loading modules with a different ELF machine type, so
neither should we allow loading a module with the wrong ELF ABI.

And you can build the kernel without MODVERSIONS, so relying on
MODVERSIONS still leaves a small exposure (same kernel version
with/without ELFv2).

I don't see an existing hook that would do what we want. There's
elf_check_arch(), but that also applies to userspace binaries, which is
not what we want.

Maybe something like below.

cheers


diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index 857d9ff24295..d0e9368982d8 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -83,5 +83,28 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
 }
 #endif
 
+#ifdef CONFIG_PPC64
+static inline bool elf_check_module_arch(Elf_Ehdr *hdr)
+{
+	unsigned long flags;
+
+	if (!elf_check_arch(hdr))
+		return false;
+
+	flags = hdr->e_flags & 0x3;
+
+#ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
+	if (flags == 2)
+		return true;
+#else
+	if (flags < 2)
+		return true;
+#endif
+	return false;
+}
+
+#define elf_check_module_arch elf_check_module_arch
+#endif /* CONFIG_PPC64 */
+
 #endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_MODULE_H */
diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
index 9e09d11ffe5b..fdc042a84562 100644
--- a/include/linux/moduleloader.h
+++ b/include/linux/moduleloader.h
@@ -13,6 +13,11 @@
  * must be implemented by each architecture.
  */
 
+// Allow arch to optionally do additional checking of module ELF header
+#ifndef elf_check_module_arch
+#define elf_check_module_arch elf_check_arch
+#endif
+
 /* Adjust arch-specific sections.  Return 0 on success.  */
 int module_frob_arch_sections(Elf_Ehdr *hdr,
 			      Elf_Shdr *sechdrs,
diff --git a/kernel/module.c b/kernel/module.c
index b5dd92e35b02..c71889107226 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2941,7 +2941,7 @@ static int elf_validity_check(struct load_info *info)
 
 	if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
 	    || info->hdr->e_type != ET_REL
-	    || !elf_check_arch(info->hdr)
+	    || !elf_check_module_arch(info->hdr)
 	    || info->hdr->e_shentsize != sizeof(Elf_Shdr))
 		return -ENOEXEC;
 

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-05 12:07     ` Michael Ellerman
@ 2021-05-05 13:25       ` Michal Suchánek
  2021-05-14 19:36       ` Michal Suchánek
  1 sibling, 0 replies; 9+ messages in thread
From: Michal Suchánek @ 2021-05-05 13:25 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Andreas Schwab, Nicholas Piggin

On Wed, May 05, 2021 at 10:07:29PM +1000, Michael Ellerman wrote:
> Michal Suchánek <msuchanek@suse.de> writes:
> > On Mon, May 03, 2021 at 01:37:57PM +0200, Andreas Schwab wrote:
> >> Should this add a tag to the module vermagic?
> >
> > Would the modues link even if the vermagic was not changed?
> 
> Most modules will require some symbols from the kernel, and those will
> be dot symbols, which won't resolve.
> 
> But there are a few small modules that don't rely on any kernel symbols,
> which can load.
> 
> > I suppose something like this might do it.
> 
> It would, but I feel like we should be handling this at the ELF level.
> ie. we don't allow loading modules with a different ELF machine type, so
> neither should we allow loading a module with the wrong ELF ABI.
> 
> And you can build the kernel without MODVERSIONS, so relying on
> MODVERSIONS still leaves a small exposure (same kernel version
> with/without ELFv2).
> 
> I don't see an existing hook that would do what we want. There's
> elf_check_arch(), but that also applies to userspace binaries, which is
> not what we want.
> 
> Maybe something like below.
Yes, that looks better.

Thanks

Michal
> 
> cheers
> 
> 
> diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
> index 857d9ff24295..d0e9368982d8 100644
> --- a/arch/powerpc/include/asm/module.h
> +++ b/arch/powerpc/include/asm/module.h
> @@ -83,5 +83,28 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
>  }
>  #endif
>  
> +#ifdef CONFIG_PPC64
> +static inline bool elf_check_module_arch(Elf_Ehdr *hdr)
> +{
> +	unsigned long flags;
> +
> +	if (!elf_check_arch(hdr))
> +		return false;
> +
> +	flags = hdr->e_flags & 0x3;
> +
> +#ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> +	if (flags == 2)
> +		return true;
> +#else
> +	if (flags < 2)
> +		return true;
> +#endif
> +	return false;
> +}
> +
> +#define elf_check_module_arch elf_check_module_arch
> +#endif /* CONFIG_PPC64 */
> +
>  #endif /* __KERNEL__ */
>  #endif	/* _ASM_POWERPC_MODULE_H */
> diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
> index 9e09d11ffe5b..fdc042a84562 100644
> --- a/include/linux/moduleloader.h
> +++ b/include/linux/moduleloader.h
> @@ -13,6 +13,11 @@
>   * must be implemented by each architecture.
>   */
>  
> +// Allow arch to optionally do additional checking of module ELF header
> +#ifndef elf_check_module_arch
> +#define elf_check_module_arch elf_check_arch
> +#endif
> +
>  /* Adjust arch-specific sections.  Return 0 on success.  */
>  int module_frob_arch_sections(Elf_Ehdr *hdr,
>  			      Elf_Shdr *sechdrs,
> diff --git a/kernel/module.c b/kernel/module.c
> index b5dd92e35b02..c71889107226 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2941,7 +2941,7 @@ static int elf_validity_check(struct load_info *info)
>  
>  	if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
>  	    || info->hdr->e_type != ET_REL
> -	    || !elf_check_arch(info->hdr)
> +	    || !elf_check_module_arch(info->hdr)
>  	    || info->hdr->e_shentsize != sizeof(Elf_Shdr))
>  		return -ENOEXEC;
>  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-05 12:07     ` Michael Ellerman
  2021-05-05 13:25       ` Michal Suchánek
@ 2021-05-14 19:36       ` Michal Suchánek
  1 sibling, 0 replies; 9+ messages in thread
From: Michal Suchánek @ 2021-05-14 19:36 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev, Andreas Schwab, Nicholas Piggin

On Wed, May 05, 2021 at 10:07:29PM +1000, Michael Ellerman wrote:
> Michal Suchánek <msuchanek@suse.de> writes:
> > On Mon, May 03, 2021 at 01:37:57PM +0200, Andreas Schwab wrote:
> >> Should this add a tag to the module vermagic?
> >
> > Would the modues link even if the vermagic was not changed?
> 
> Most modules will require some symbols from the kernel, and those will
> be dot symbols, which won't resolve.
> 
> But there are a few small modules that don't rely on any kernel symbols,
> which can load.
> 
> > I suppose something like this might do it.
> 
> It would, but I feel like we should be handling this at the ELF level.
> ie. we don't allow loading modules with a different ELF machine type, so
> neither should we allow loading a module with the wrong ELF ABI.
> 
> And you can build the kernel without MODVERSIONS, so relying on
> MODVERSIONS still leaves a small exposure (same kernel version
> with/without ELFv2).
> 
> I don't see an existing hook that would do what we want. There's
> elf_check_arch(), but that also applies to userspace binaries, which is
> not what we want.
> 
> Maybe something like below.

The below patch works for me.

Tested-by: Michal Suchánek <msuchanek@suse.de>

Built a Hello World module for both v1 and v2 ABI, and kernels built
with v1 and v2 ABI rejected module with the other ABI.

[  100.602943] Module has invalid ELF structures
insmod: ERROR: could not insert module moin_v1.ko: Invalid module format

Thanks

Michal
> 
> cheers
> 
> 
> diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
> index 857d9ff24295..d0e9368982d8 100644
> --- a/arch/powerpc/include/asm/module.h
> +++ b/arch/powerpc/include/asm/module.h
> @@ -83,5 +83,28 @@ static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sec
>  }
>  #endif
>  
> +#ifdef CONFIG_PPC64
> +static inline bool elf_check_module_arch(Elf_Ehdr *hdr)
> +{
> +	unsigned long flags;
> +
> +	if (!elf_check_arch(hdr))
> +		return false;
> +
> +	flags = hdr->e_flags & 0x3;
> +
> +#ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> +	if (flags == 2)
> +		return true;
> +#else
> +	if (flags < 2)
> +		return true;
> +#endif
> +	return false;
> +}
> +
> +#define elf_check_module_arch elf_check_module_arch
> +#endif /* CONFIG_PPC64 */
> +
>  #endif /* __KERNEL__ */
>  #endif	/* _ASM_POWERPC_MODULE_H */
> diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h
> index 9e09d11ffe5b..fdc042a84562 100644
> --- a/include/linux/moduleloader.h
> +++ b/include/linux/moduleloader.h
> @@ -13,6 +13,11 @@
>   * must be implemented by each architecture.
>   */
>  
> +// Allow arch to optionally do additional checking of module ELF header
> +#ifndef elf_check_module_arch
> +#define elf_check_module_arch elf_check_arch
> +#endif
> +
>  /* Adjust arch-specific sections.  Return 0 on success.  */
>  int module_frob_arch_sections(Elf_Ehdr *hdr,
>  			      Elf_Shdr *sechdrs,
> diff --git a/kernel/module.c b/kernel/module.c
> index b5dd92e35b02..c71889107226 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -2941,7 +2941,7 @@ static int elf_validity_check(struct load_info *info)
>  
>  	if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
>  	    || info->hdr->e_type != ET_REL
> -	    || !elf_check_arch(info->hdr)
> +	    || !elf_check_module_arch(info->hdr)
>  	    || info->hdr->e_shentsize != sizeof(Elf_Shdr))
>  		return -ENOEXEC;
>  

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-05 15:23 ` Michal Suchánek
@ 2021-05-05 15:55   ` Michal Suchánek
  0 siblings, 0 replies; 9+ messages in thread
From: Michal Suchánek @ 2021-05-05 15:55 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: linuxppc-dev

On Wed, May 05, 2021 at 05:23:37PM +0200, Michal Suchánek wrote:
> Hello,
> 
> looks like the ABI flags are not correctly applied when cross-compiling.
> 
> While building natively success of BTFIDS depends on the kernel ABI but
> when cross-compiling success of BTFIDS depends on the default toolchain
> ABI.
> 
> It's problem independent of this patch - the problem exists both before
> and after.

Actually this is not the case. Now retested with LE toolchain and BTFIDS
fails on BE v2 kernel with either one but earlier the default LE
toolchain produced BTFIDS on BE v1 kernel.

No idea what is going on except the general issue that success/failure
of BTFIDS when cross-compiling ppc64 is not representative of
success/failure when building natively. Don't even want to know what
would happen if I tried to link a BPF program with the kernel code using
that info.

Thanks

Michal

> 
> Thanks
> 
> Michal
> 
> On Mon, May 03, 2021 at 09:07:13PM +1000, Nicholas Piggin wrote:
> > Provide an option to build big-endian kernels using the ELFv2 ABI. This
> > works on GCC only so far, although it is rumored to work with clang
> > that's not been tested yet.
> > 
> > This can give big-endian kernels some useful advantages of the ELFv2 ABI
> > (e.g., less stack usage, -mprofile-kernel, better compatibility with bpf
> > tools).
> > 
> > BE+ELFv2 is not officially supported by the GNU toolchain, but it works
> > fine in testing and has been used by some userspace for some time (e.g.,
> > Void Linux).
> > 
> > Tested-by: Michal Suchánek <msuchanek@suse.de>
> > Reviewed-by: Segher Boessenkool <segher@kernel.crashing.org>
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> > 
> > I didn't add the -mprofile-kernel change but I think it would be a good
> > one that can be merged independently if it works.
> > 
> > Since v2:
> > - Rebased, tweaked changelog.
> > - Changed ELF_V2 to ELF_V2_ABI in config options, to be clearer.
> > 
> > Since v1:
> > - Improved the override flavour name suggested by Segher.
> > - Improved changelog wording.
> > 
> >  arch/powerpc/Kconfig                | 22 ++++++++++++++++++++++
> >  arch/powerpc/Makefile               | 18 ++++++++++++------
> >  arch/powerpc/boot/Makefile          |  4 +++-
> >  arch/powerpc/kernel/vdso64/Makefile | 13 +++++++++++++
> >  drivers/crypto/vmx/Makefile         |  8 ++++++--
> >  drivers/crypto/vmx/ppc-xlate.pl     | 10 ++++++----
> >  6 files changed, 62 insertions(+), 13 deletions(-)
> > 
> > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> > index 1e6230bea09d..d3f78d3d574d 100644
> > --- a/arch/powerpc/Kconfig
> > +++ b/arch/powerpc/Kconfig
> > @@ -160,6 +160,7 @@ config PPC
> >  	select ARCH_WEAK_RELEASE_ACQUIRE
> >  	select BINFMT_ELF
> >  	select BUILDTIME_TABLE_SORT
> > +	select PPC64_BUILD_ELF_V2_ABI		if PPC64 && CPU_LITTLE_ENDIAN
> >  	select CLONE_BACKWARDS
> >  	select DCACHE_WORD_ACCESS		if PPC64 && CPU_LITTLE_ENDIAN
> >  	select DMA_OPS				if PPC64
> > @@ -568,6 +569,27 @@ config KEXEC_FILE
> >  config ARCH_HAS_KEXEC_PURGATORY
> >  	def_bool KEXEC_FILE
> >  
> > +config PPC64_BUILD_ELF_V2_ABI
> > +	bool
> > +
> > +config PPC64_BUILD_BIG_ENDIAN_ELF_V2_ABI
> > +	bool "Build big-endian kernel using ELF ABI V2 (EXPERIMENTAL)"
> > +	depends on PPC64 && CPU_BIG_ENDIAN && EXPERT
> > +	depends on CC_IS_GCC && LD_VERSION >= 22400
> > +	default n
> > +	select PPC64_BUILD_ELF_V2_ABI
> > +	help
> > +	  This builds the kernel image using the "Power Architecture 64-Bit ELF
> > +	  V2 ABI Specification", which has a reduced stack overhead and faster
> > +	  function calls. This internal kernel ABI option does not affect
> > +          userspace compatibility.
> > +
> > +	  The V2 ABI is standard for 64-bit little-endian, but for big-endian
> > +	  it is less well tested by kernel and toolchain. However some distros
> > +	  build userspace this way, and it can produce a functioning kernel.
> > +
> > +	  This requires GCC 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 3212d076ac6a..b90b5cb799aa 100644
> > --- a/arch/powerpc/Makefile
> > +++ b/arch/powerpc/Makefile
> > @@ -91,10 +91,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_PPC64_BUILD_ELF_V2_ABI
> > +cflags-y				+= $(call cc-option,-mabi=elfv2)
> > +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
> >  
> > @@ -142,15 +146,17 @@ endif
> >  
> >  CFLAGS-$(CONFIG_PPC64)	:= $(call cc-option,-mtraceback=no)
> >  ifndef CONFIG_CC_IS_CLANG
> > -ifdef CONFIG_CPU_LITTLE_ENDIAN
> > -CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
> > +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> > +CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
> >  AFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
> >  else
> > +# Keep these in synch with arch/powerpc/kernel/vdso64/Makefile
> >  CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv1)
> >  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 2b8da923ceca..be84a72f8258 100644
> > --- a/arch/powerpc/boot/Makefile
> > +++ b/arch/powerpc/boot/Makefile
> > @@ -40,6 +40,9 @@ BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
> >  
> >  ifdef CONFIG_PPC64_BOOT_WRAPPER
> >  BOOTCFLAGS	+= -m64
> > +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> > +BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
> > +endif
> >  else
> >  BOOTCFLAGS	+= -m32
> >  endif
> > @@ -50,7 +53,6 @@ ifdef CONFIG_CPU_BIG_ENDIAN
> >  BOOTCFLAGS	+= -mbig-endian
> >  else
> >  BOOTCFLAGS	+= -mlittle-endian
> > -BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
> >  endif
> >  
> >  BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
> > diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
> > index 2813e3f98db6..d783c07e558f 100644
> > --- a/arch/powerpc/kernel/vdso64/Makefile
> > +++ b/arch/powerpc/kernel/vdso64/Makefile
> > @@ -25,6 +25,19 @@ KCOV_INSTRUMENT := n
> >  UBSAN_SANITIZE := n
> >  KASAN_SANITIZE := n
> >  
> > +# Always build vdso64 with ELFv1 ABI for BE kernels
> > +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> > +ifdef CONFIG_CPU_BIG_ENDIAN
> > +KBUILD_CFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_CFLAGS))
> > +KBUILD_AFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_AFLAGS))
> > +
> > +# These are derived from arch/powerpc/Makefile
> > +KBUILD_CFLAGS += $(call cc-option,-mabi=elfv1)
> > +KBUILD_CFLAGS += $(call cc-option,-mcall-aixdesc)
> > +KBUILD_AFLAGS += $(call cc-option,-mabi=elfv1)
> > +endif
> > +endif
> > +
> >  ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
> >  	-Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both
> >  asflags-y := -D__VDSO64__ -s
> > diff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile
> > index 709670d2b553..d9ccf9fc3483 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_PPC64_BUILD_ELF_V2_ABI
> > +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..b583898c11ae 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 $elfv2abi=(($flavour =~ /linux-ppc64le/) or ($flavour =~ /linux-ppc64-elfv2/))?1:0;
> > +my $dotfunctions=($elfv2abi=~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 ($elfv2abi);
> >      $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 = ($elfv2abi);
> >  my $mtspr = sub {
> >      my ($f,$idx,$ra) = @_;
> >      if ($idx == 256 && $no_vrsave) {
> > -- 
> > 2.23.0
> > 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
  2021-05-03 11:07 Nicholas Piggin
@ 2021-05-05 15:23 ` Michal Suchánek
  2021-05-05 15:55   ` Michal Suchánek
  0 siblings, 1 reply; 9+ messages in thread
From: Michal Suchánek @ 2021-05-05 15:23 UTC (permalink / raw)
  To: Nicholas Piggin; +Cc: linuxppc-dev

Hello,

looks like the ABI flags are not correctly applied when cross-compiling.

While building natively success of BTFIDS depends on the kernel ABI but
when cross-compiling success of BTFIDS depends on the default toolchain
ABI.

It's problem independent of this patch - the problem exists both before
and after.

Thanks

Michal

On Mon, May 03, 2021 at 09:07:13PM +1000, Nicholas Piggin wrote:
> Provide an option to build big-endian kernels using the ELFv2 ABI. This
> works on GCC only so far, although it is rumored to work with clang
> that's not been tested yet.
> 
> This can give big-endian kernels some useful advantages of the ELFv2 ABI
> (e.g., less stack usage, -mprofile-kernel, better compatibility with bpf
> tools).
> 
> BE+ELFv2 is not officially supported by the GNU toolchain, but it works
> fine in testing and has been used by some userspace for some time (e.g.,
> Void Linux).
> 
> Tested-by: Michal Suchánek <msuchanek@suse.de>
> Reviewed-by: Segher Boessenkool <segher@kernel.crashing.org>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
> 
> I didn't add the -mprofile-kernel change but I think it would be a good
> one that can be merged independently if it works.
> 
> Since v2:
> - Rebased, tweaked changelog.
> - Changed ELF_V2 to ELF_V2_ABI in config options, to be clearer.
> 
> Since v1:
> - Improved the override flavour name suggested by Segher.
> - Improved changelog wording.
> 
>  arch/powerpc/Kconfig                | 22 ++++++++++++++++++++++
>  arch/powerpc/Makefile               | 18 ++++++++++++------
>  arch/powerpc/boot/Makefile          |  4 +++-
>  arch/powerpc/kernel/vdso64/Makefile | 13 +++++++++++++
>  drivers/crypto/vmx/Makefile         |  8 ++++++--
>  drivers/crypto/vmx/ppc-xlate.pl     | 10 ++++++----
>  6 files changed, 62 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 1e6230bea09d..d3f78d3d574d 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -160,6 +160,7 @@ config PPC
>  	select ARCH_WEAK_RELEASE_ACQUIRE
>  	select BINFMT_ELF
>  	select BUILDTIME_TABLE_SORT
> +	select PPC64_BUILD_ELF_V2_ABI		if PPC64 && CPU_LITTLE_ENDIAN
>  	select CLONE_BACKWARDS
>  	select DCACHE_WORD_ACCESS		if PPC64 && CPU_LITTLE_ENDIAN
>  	select DMA_OPS				if PPC64
> @@ -568,6 +569,27 @@ config KEXEC_FILE
>  config ARCH_HAS_KEXEC_PURGATORY
>  	def_bool KEXEC_FILE
>  
> +config PPC64_BUILD_ELF_V2_ABI
> +	bool
> +
> +config PPC64_BUILD_BIG_ENDIAN_ELF_V2_ABI
> +	bool "Build big-endian kernel using ELF ABI V2 (EXPERIMENTAL)"
> +	depends on PPC64 && CPU_BIG_ENDIAN && EXPERT
> +	depends on CC_IS_GCC && LD_VERSION >= 22400
> +	default n
> +	select PPC64_BUILD_ELF_V2_ABI
> +	help
> +	  This builds the kernel image using the "Power Architecture 64-Bit ELF
> +	  V2 ABI Specification", which has a reduced stack overhead and faster
> +	  function calls. This internal kernel ABI option does not affect
> +          userspace compatibility.
> +
> +	  The V2 ABI is standard for 64-bit little-endian, but for big-endian
> +	  it is less well tested by kernel and toolchain. However some distros
> +	  build userspace this way, and it can produce a functioning kernel.
> +
> +	  This requires GCC 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 3212d076ac6a..b90b5cb799aa 100644
> --- a/arch/powerpc/Makefile
> +++ b/arch/powerpc/Makefile
> @@ -91,10 +91,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_PPC64_BUILD_ELF_V2_ABI
> +cflags-y				+= $(call cc-option,-mabi=elfv2)
> +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
>  
> @@ -142,15 +146,17 @@ endif
>  
>  CFLAGS-$(CONFIG_PPC64)	:= $(call cc-option,-mtraceback=no)
>  ifndef CONFIG_CC_IS_CLANG
> -ifdef CONFIG_CPU_LITTLE_ENDIAN
> -CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
> +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> +CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
>  AFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
>  else
> +# Keep these in synch with arch/powerpc/kernel/vdso64/Makefile
>  CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv1)
>  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 2b8da923ceca..be84a72f8258 100644
> --- a/arch/powerpc/boot/Makefile
> +++ b/arch/powerpc/boot/Makefile
> @@ -40,6 +40,9 @@ BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
>  
>  ifdef CONFIG_PPC64_BOOT_WRAPPER
>  BOOTCFLAGS	+= -m64
> +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> +BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
> +endif
>  else
>  BOOTCFLAGS	+= -m32
>  endif
> @@ -50,7 +53,6 @@ ifdef CONFIG_CPU_BIG_ENDIAN
>  BOOTCFLAGS	+= -mbig-endian
>  else
>  BOOTCFLAGS	+= -mlittle-endian
> -BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
>  endif
>  
>  BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
> diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
> index 2813e3f98db6..d783c07e558f 100644
> --- a/arch/powerpc/kernel/vdso64/Makefile
> +++ b/arch/powerpc/kernel/vdso64/Makefile
> @@ -25,6 +25,19 @@ KCOV_INSTRUMENT := n
>  UBSAN_SANITIZE := n
>  KASAN_SANITIZE := n
>  
> +# Always build vdso64 with ELFv1 ABI for BE kernels
> +ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
> +ifdef CONFIG_CPU_BIG_ENDIAN
> +KBUILD_CFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_CFLAGS))
> +KBUILD_AFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_AFLAGS))
> +
> +# These are derived from arch/powerpc/Makefile
> +KBUILD_CFLAGS += $(call cc-option,-mabi=elfv1)
> +KBUILD_CFLAGS += $(call cc-option,-mcall-aixdesc)
> +KBUILD_AFLAGS += $(call cc-option,-mabi=elfv1)
> +endif
> +endif
> +
>  ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
>  	-Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both
>  asflags-y := -D__VDSO64__ -s
> diff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile
> index 709670d2b553..d9ccf9fc3483 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_PPC64_BUILD_ELF_V2_ABI
> +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..b583898c11ae 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 $elfv2abi=(($flavour =~ /linux-ppc64le/) or ($flavour =~ /linux-ppc64-elfv2/))?1:0;
> +my $dotfunctions=($elfv2abi=~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 ($elfv2abi);
>      $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 = ($elfv2abi);
>  my $mtspr = sub {
>      my ($f,$idx,$ra) = @_;
>      if ($idx == 256 && $no_vrsave) {
> -- 
> 2.23.0
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels
@ 2021-05-03 11:07 Nicholas Piggin
  2021-05-05 15:23 ` Michal Suchánek
  0 siblings, 1 reply; 9+ messages in thread
From: Nicholas Piggin @ 2021-05-03 11:07 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Michal Suchánek, Nicholas Piggin

Provide an option to build big-endian kernels using the ELFv2 ABI. This
works on GCC only so far, although it is rumored to work with clang
that's not been tested yet.

This can give big-endian kernels some useful advantages of the ELFv2 ABI
(e.g., less stack usage, -mprofile-kernel, better compatibility with bpf
tools).

BE+ELFv2 is not officially supported by the GNU toolchain, but it works
fine in testing and has been used by some userspace for some time (e.g.,
Void Linux).

Tested-by: Michal Suchánek <msuchanek@suse.de>
Reviewed-by: Segher Boessenkool <segher@kernel.crashing.org>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---

I didn't add the -mprofile-kernel change but I think it would be a good
one that can be merged independently if it works.

Since v2:
- Rebased, tweaked changelog.
- Changed ELF_V2 to ELF_V2_ABI in config options, to be clearer.

Since v1:
- Improved the override flavour name suggested by Segher.
- Improved changelog wording.

 arch/powerpc/Kconfig                | 22 ++++++++++++++++++++++
 arch/powerpc/Makefile               | 18 ++++++++++++------
 arch/powerpc/boot/Makefile          |  4 +++-
 arch/powerpc/kernel/vdso64/Makefile | 13 +++++++++++++
 drivers/crypto/vmx/Makefile         |  8 ++++++--
 drivers/crypto/vmx/ppc-xlate.pl     | 10 ++++++----
 6 files changed, 62 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1e6230bea09d..d3f78d3d574d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -160,6 +160,7 @@ config PPC
 	select ARCH_WEAK_RELEASE_ACQUIRE
 	select BINFMT_ELF
 	select BUILDTIME_TABLE_SORT
+	select PPC64_BUILD_ELF_V2_ABI		if PPC64 && CPU_LITTLE_ENDIAN
 	select CLONE_BACKWARDS
 	select DCACHE_WORD_ACCESS		if PPC64 && CPU_LITTLE_ENDIAN
 	select DMA_OPS				if PPC64
@@ -568,6 +569,27 @@ config KEXEC_FILE
 config ARCH_HAS_KEXEC_PURGATORY
 	def_bool KEXEC_FILE
 
+config PPC64_BUILD_ELF_V2_ABI
+	bool
+
+config PPC64_BUILD_BIG_ENDIAN_ELF_V2_ABI
+	bool "Build big-endian kernel using ELF ABI V2 (EXPERIMENTAL)"
+	depends on PPC64 && CPU_BIG_ENDIAN && EXPERT
+	depends on CC_IS_GCC && LD_VERSION >= 22400
+	default n
+	select PPC64_BUILD_ELF_V2_ABI
+	help
+	  This builds the kernel image using the "Power Architecture 64-Bit ELF
+	  V2 ABI Specification", which has a reduced stack overhead and faster
+	  function calls. This internal kernel ABI option does not affect
+          userspace compatibility.
+
+	  The V2 ABI is standard for 64-bit little-endian, but for big-endian
+	  it is less well tested by kernel and toolchain. However some distros
+	  build userspace this way, and it can produce a functioning kernel.
+
+	  This requires GCC 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 3212d076ac6a..b90b5cb799aa 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -91,10 +91,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_PPC64_BUILD_ELF_V2_ABI
+cflags-y				+= $(call cc-option,-mabi=elfv2)
+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
 
@@ -142,15 +146,17 @@ endif
 
 CFLAGS-$(CONFIG_PPC64)	:= $(call cc-option,-mtraceback=no)
 ifndef CONFIG_CC_IS_CLANG
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2,$(call cc-option,-mcall-aixdesc))
+ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
+CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
 AFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv2)
 else
+# Keep these in synch with arch/powerpc/kernel/vdso64/Makefile
 CFLAGS-$(CONFIG_PPC64)	+= $(call cc-option,-mabi=elfv1)
 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 2b8da923ceca..be84a72f8258 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,6 +40,9 @@ BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
 
 ifdef CONFIG_PPC64_BOOT_WRAPPER
 BOOTCFLAGS	+= -m64
+ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
+BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
+endif
 else
 BOOTCFLAGS	+= -m32
 endif
@@ -50,7 +53,6 @@ ifdef CONFIG_CPU_BIG_ENDIAN
 BOOTCFLAGS	+= -mbig-endian
 else
 BOOTCFLAGS	+= -mlittle-endian
-BOOTCFLAGS	+= $(call cc-option,-mabi=elfv2)
 endif
 
 BOOTAFLAGS	:= -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index 2813e3f98db6..d783c07e558f 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -25,6 +25,19 @@ KCOV_INSTRUMENT := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 
+# Always build vdso64 with ELFv1 ABI for BE kernels
+ifdef CONFIG_PPC64_BUILD_ELF_V2_ABI
+ifdef CONFIG_CPU_BIG_ENDIAN
+KBUILD_CFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_CFLAGS))
+KBUILD_AFLAGS := $(filter-out -mabi=elfv2,$(KBUILD_AFLAGS))
+
+# These are derived from arch/powerpc/Makefile
+KBUILD_CFLAGS += $(call cc-option,-mabi=elfv1)
+KBUILD_CFLAGS += $(call cc-option,-mcall-aixdesc)
+KBUILD_AFLAGS += $(call cc-option,-mabi=elfv1)
+endif
+endif
+
 ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
 	-Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both
 asflags-y := -D__VDSO64__ -s
diff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile
index 709670d2b553..d9ccf9fc3483 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_PPC64_BUILD_ELF_V2_ABI
+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..b583898c11ae 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 $elfv2abi=(($flavour =~ /linux-ppc64le/) or ($flavour =~ /linux-ppc64-elfv2/))?1:0;
+my $dotfunctions=($elfv2abi=~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 ($elfv2abi);
     $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 = ($elfv2abi);
 my $mtspr = sub {
     my ($f,$idx,$ra) = @_;
     if ($idx == 256 && $no_vrsave) {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-05-14 19:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20210503110713.751840-1-npiggin__45037.8389026568$1620040079$gmane$org@gmail.com>
2021-05-03 11:37 ` [PATCH v3] powerpc/64: Option to use ELFv2 ABI for big-endian kernels Andreas Schwab
2021-05-03 14:38   ` Michal Suchánek
2021-05-04 10:27     ` Nicholas Piggin
2021-05-05 12:07     ` Michael Ellerman
2021-05-05 13:25       ` Michal Suchánek
2021-05-14 19:36       ` Michal Suchánek
2021-05-03 11:07 Nicholas Piggin
2021-05-05 15:23 ` Michal Suchánek
2021-05-05 15:55   ` Michal Suchánek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).