[PATCH v3] powerpc: Add gpr1 and fpu save/restore functions
Christophe Leroy
christophe.leroy at csgroup.eu
Sun Feb 18 03:39:06 AEDT 2024
Le 16/02/2024 à 18:24, Timothy Pearson a écrit :
> When building the kernel in size optimized mode with the amdgpu module enabled,
> gcc will begin referencing external gpr1 and fpu save/restore functions. This
> will then cause a linker failure as we do not link against libgcc which
> normally contains those builtin functions.
Right, but modules are linked with --save-restore-funcs when using gcc
so crtsavres.o is not used and only your change to scripts/mod/modpost.c
seems to be required to be able to build amdgpu module with GCC.
Maybe that's different with clang, but maybe worth a test and then a
second patch ?
Nevertheless, see comments below, you can do even shorter and more
readable using GAS macros.
>
> Implement gpr1 and fpu save/restore functions per the PowerPC 64-bit ELFv2 ABI
> documentation.
>
> Tested on a Talos II with a WX7100 installed and running in DisplayCore mode.
>
> Reported-by: kernel test robot <lkp at intel.com>
> Tested-by: Timothy Pearson <tpearson at raptorengineering.com>
> Signed-off-by: Timothy Pearson <tpearson at raptorengineering.com>
> ---
> arch/powerpc/kernel/prom_init_check.sh | 4 +-
> arch/powerpc/lib/crtsavres.S | 363 +++++++++++++++++--------
> scripts/mod/modpost.c | 4 +
> 3 files changed, 253 insertions(+), 118 deletions(-)
>
> diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
> index 69623b9045d5..76c5651e29d3 100644
> --- a/arch/powerpc/kernel/prom_init_check.sh
> +++ b/arch/powerpc/kernel/prom_init_check.sh
> @@ -72,10 +72,10 @@ do
>
> # ignore register save/restore funcitons
> case $UNDEF in
> - _restgpr_*|_restgpr0_*|_rest32gpr_*)
> + _restgpr_*|_restgpr0_*|_restgpr1_*|_rest32gpr_*)
> OK=1
> ;;
> - _savegpr_*|_savegpr0_*|_save32gpr_*)
> + _savegpr_*|_savegpr0_*|_restgpr0_*|_save32gpr_*)
> OK=1
> ;;
> esac
> diff --git a/arch/powerpc/lib/crtsavres.S b/arch/powerpc/lib/crtsavres.S
> index 7e5e1c28e56a..f97270d36720 100644
> --- a/arch/powerpc/lib/crtsavres.S
> +++ b/arch/powerpc/lib/crtsavres.S
> @@ -3,6 +3,7 @@
> *
> * Copyright (C) 1995, 1996, 1998, 2000, 2001 Free Software Foundation, Inc.
> * Copyright 2008 Freescale Semiconductor, Inc.
> + * Copyright 2024 Raptor Engineering, LLC
> * Written By Michael Meissner
> *
> * Based on gcc/config/rs6000/crtsavres.asm from gcc
> @@ -314,126 +315,134 @@ _GLOBAL(_restvr_31)
>
> #else /* CONFIG_PPC64 */
>
> -.globl _savegpr0_14
> -_savegpr0_14:
> - std r14,-144(r1)
> -.globl _savegpr0_15
> -_savegpr0_15:
> - std r15,-136(r1)
> -.globl _savegpr0_16
> -_savegpr0_16:
> - std r16,-128(r1)
> -.globl _savegpr0_17
> -_savegpr0_17:
> - std r17,-120(r1)
> -.globl _savegpr0_18
> -_savegpr0_18:
> - std r18,-112(r1)
> -.globl _savegpr0_19
> -_savegpr0_19:
> - std r19,-104(r1)
> -.globl _savegpr0_20
> -_savegpr0_20:
> - std r20,-96(r1)
> -.globl _savegpr0_21
> -_savegpr0_21:
> - std r21,-88(r1)
> -.globl _savegpr0_22
> -_savegpr0_22:
> - std r22,-80(r1)
> -.globl _savegpr0_23
> -_savegpr0_23:
> - std r23,-72(r1)
> -.globl _savegpr0_24
> -_savegpr0_24:
> - std r24,-64(r1)
> -.globl _savegpr0_25
> -_savegpr0_25:
> - std r25,-56(r1)
> -.globl _savegpr0_26
> -_savegpr0_26:
> - std r26,-48(r1)
> -.globl _savegpr0_27
> -_savegpr0_27:
> - std r27,-40(r1)
> -.globl _savegpr0_28
> -_savegpr0_28:
> - std r28,-32(r1)
> -.globl _savegpr0_29
> -_savegpr0_29:
> - std r29,-24(r1)
> -.globl _savegpr0_30
> -_savegpr0_30:
> - std r30,-16(r1)
> -.globl _savegpr0_31
> -_savegpr0_31:
> - std r31,-8(r1)
> - std r0,16(r1)
> +#define __PPC64_SAVEGPR(n,base) \
> +.globl _savegpr##n##_14 \
> +_savegpr##n##_14: \
> + std r14,-144(base) \
> +.globl _savegpr##n##_15 \
> +_savegpr##n##_15: \
> + std r15,-136(base) \
> +.globl _savegpr##n##_16 \
> +_savegpr##n##_16: \
> + std r16,-128(base) \
> +.globl _savegpr##n##_17 \
> +_savegpr##n##_17: \
> + std r17,-120(base) \
> +.globl _savegpr##n##_18 \
> +_savegpr##n##_18: \
> + std r18,-112(base) \
> +.globl _savegpr##n##_19 \
> +_savegpr##n##_19: \
> + std r19,-104(base) \
> +.globl _savegpr##n##_20 \
> +_savegpr##n##_20: \
> + std r20,-96(base) \
> +.globl _savegpr##n##_21 \
> +_savegpr##n##_21: \
> + std r21,-88(base) \
> +.globl _savegpr##n##_22 \
> +_savegpr##n##_22: \
> + std r22,-80(base) \
> +.globl _savegpr##n##_23 \
> +_savegpr##n##_23: \
> + std r23,-72(base) \
> +.globl _savegpr##n##_24 \
> +_savegpr##n##_24: \
> + std r24,-64(base) \
> +.globl _savegpr##n##_25 \
> +_savegpr##n##_25: \
> + std r25,-56(base) \
> +.globl _savegpr##n##_26 \
> +_savegpr##n##_26: \
> + std r26,-48(base) \
> +.globl _savegpr##n##_27 \
> +_savegpr##n##_27: \
> + std r27,-40(base) \
> +.globl _savegpr##n##_28 \
> +_savegpr##n##_28: \
> + std r28,-32(base) \
> +.globl _savegpr##n##_29 \
> +_savegpr##n##_29: \
> + std r29,-24(base) \
> +.globl _savegpr##n##_30 \
> +_savegpr##n##_30: \
> + std r30,-16(base) \
> +.globl _savegpr##n##_31 \
> +_savegpr##n##_31: \
> + std r31,-8(base) \
> + std r0,16(base) \
> blr
>
> -.globl _restgpr0_14
> -_restgpr0_14:
> - ld r14,-144(r1)
> -.globl _restgpr0_15
> -_restgpr0_15:
> - ld r15,-136(r1)
> -.globl _restgpr0_16
> -_restgpr0_16:
> - ld r16,-128(r1)
> -.globl _restgpr0_17
> -_restgpr0_17:
> - ld r17,-120(r1)
> -.globl _restgpr0_18
> -_restgpr0_18:
> - ld r18,-112(r1)
> -.globl _restgpr0_19
> -_restgpr0_19:
> - ld r19,-104(r1)
> -.globl _restgpr0_20
> -_restgpr0_20:
> - ld r20,-96(r1)
> -.globl _restgpr0_21
> -_restgpr0_21:
> - ld r21,-88(r1)
> -.globl _restgpr0_22
> -_restgpr0_22:
> - ld r22,-80(r1)
> -.globl _restgpr0_23
> -_restgpr0_23:
> - ld r23,-72(r1)
> -.globl _restgpr0_24
> -_restgpr0_24:
> - ld r24,-64(r1)
> -.globl _restgpr0_25
> -_restgpr0_25:
> - ld r25,-56(r1)
> -.globl _restgpr0_26
> -_restgpr0_26:
> - ld r26,-48(r1)
> -.globl _restgpr0_27
> -_restgpr0_27:
> - ld r27,-40(r1)
> -.globl _restgpr0_28
> -_restgpr0_28:
> - ld r28,-32(r1)
> -.globl _restgpr0_29
> -_restgpr0_29:
> - ld r0,16(r1)
> - ld r29,-24(r1)
> - mtlr r0
> - ld r30,-16(r1)
> - ld r31,-8(r1)
> +#define __PPC64_RESTGPR(n,base) \
> +.globl _restgpr##n##_14 \
> +_restgpr##n##_14: \
> + ld r14,-144(base) \
> +.globl _restgpr##n##_15 \
> +_restgpr##n##_15: \
> + ld r15,-136(base) \
> +.globl _restgpr##n##_16 \
> +_restgpr##n##_16: \
> + ld r16,-128(base) \
> +.globl _restgpr##n##_17 \
> +_restgpr##n##_17: \
> + ld r17,-120(base) \
> +.globl _restgpr##n##_18 \
> +_restgpr##n##_18: \
> + ld r18,-112(base) \
> +.globl _restgpr##n##_19 \
> +_restgpr##n##_19: \
> + ld r19,-104(base) \
> +.globl _restgpr##n##_20 \
> +_restgpr##n##_20: \
> + ld r20,-96(base) \
> +.globl _restgpr##n##_21 \
> +_restgpr##n##_21: \
> + ld r21,-88(base) \
> +.globl _restgpr##n##_22 \
> +_restgpr##n##_22: \
> + ld r22,-80(base) \
> +.globl _restgpr##n##_23 \
> +_restgpr##n##_23: \
> + ld r23,-72(base) \
> +.globl _restgpr##n##_24 \
> +_restgpr##n##_24: \
> + ld r24,-64(base) \
> +.globl _restgpr##n##_25 \
> +_restgpr##n##_25: \
> + ld r25,-56(base) \
> +.globl _restgpr##n##_26 \
> +_restgpr##n##_26: \
> + ld r26,-48(base) \
> +.globl _restgpr##n##_27 \
> +_restgpr##n##_27: \
> + ld r27,-40(base) \
> +.globl _restgpr##n##_28 \
> +_restgpr##n##_28: \
> + ld r28,-32(base) \
> +.globl _restgpr##n##_29 \
> +_restgpr##n##_29: \
> + ld r0,16(base) \
> + ld r29,-24(base) \
> + mtlr r0 \
> + ld r30,-16(base) \
> + ld r31,-8(base) \
> + blr \
> + \
> +.globl _restgpr##n##_30 \
> +_restgpr##n##_30: \
> + ld r30,-16(base) \
> +.globl _restgpr##n##_31 \
> +_restgpr##n##_31: \
> + ld r0,16(base) \
> + ld r31,-8(base) \
> + mtlr r0 \
> blr
I was thinking more about GAS macro, to avoid those ugly backslashes.
Also, every three line is worth a macro in itself
+.globl _savegpr##n##_14 \
+_savegpr##n##_14: \
+ std r14,-144(base) \
Something like (untested):
.macro savegpr \n \base \num
.globl _savegpr\n_\num
_savegpr\num:
std \num, -256+8*\num(base)
.end
Then
.macro __ppc64_savegpr n, base
savegpr 14 \n \base
savegpr 15 \n \base
savegpr 16 \n \base
savegpr 17 \n \base
savegpr 18 \n \base
savegpr 19 \n \base
savegpr 20 \n \base
savegpr 21 \n \base
savegpr 22 \n \base
savegpr 23 \n \base
savegpr 24 \n \base
savegpr 25 \n \base
savegpr 26 \n \base
savegpr 27 \n \base
savegpr 28 \n \base
savegpr 29 \n \base
savegpr 30 \n \base
savegpr 31 \n \base
std r0,16(\base)
blr
.endm
>
> -.globl _restgpr0_30
> -_restgpr0_30:
> - ld r30,-16(r1)
> -.globl _restgpr0_31
> -_restgpr0_31:
> - ld r0,16(r1)
> - ld r31,-8(r1)
> - mtlr r0
> - blr
> +__PPC64_RESTGPR(0, r1)
> +__PPC64_RESTGPR(1, r12)
> +
> +__PPC64_SAVEGPR(0, r1)
> +__PPC64_SAVEGPR(1, r12)
>
> #ifdef CONFIG_ALTIVEC
> /* Called with r0 pointing just beyond the end of the vector save area. */
> @@ -540,6 +549,128 @@ _restvr_31:
>
> #endif /* CONFIG_ALTIVEC */
>
> +#ifdef CONFIG_PPC_FPU
> +
> +.globl _savefpr_14
> +_savefpr_14:
> + stfd f14,-144(r1)
> +.globl _savefpr_15
> +_savefpr_15:
> + stfd f15,-136(r1)
> +.globl _savefpr_16
> +_savefpr_16:
> + stfd f16,-128(r1)
> +.globl _savefpr_17
> +_savefpr_17:
> + stfd f17,-120(r1)
> +.globl _savefpr_18
> +_savefpr_18:
> + stfd f18,-112(r1)
> +.globl _savefpr_19
> +_savefpr_19:
> + stfd f19,-104(r1)
> +.globl _savefpr_20
> +_savefpr_20:
> + stfd f20,-96(r1)
> +.globl _savefpr_21
> +_savefpr_21:
> + stfd f21,-88(r1)
> +.globl _savefpr_22
> +_savefpr_22:
> + stfd f22,-80(r1)
> +.globl _savefpr_23
> +_savefpr_23:
> + stfd f23,-72(r1)
> +.globl _savefpr_24
> +_savefpr_24:
> + stfd f24,-64(r1)
> +.globl _savefpr_25
> +_savefpr_25:
> + stfd f25,-56(r1)
> +.globl _savefpr_26
> +_savefpr_26:
> + stfd f26,-48(r1)
> +.globl _savefpr_27
> +_savefpr_27:
> + stfd f27,-40(r1)
> +.globl _savefpr_28
> +_savefpr_28:
> + stfd f28,-32(r1)
> +.globl _savefpr_29
> +_savefpr_29:
> + stfd f29,-24(r1)
> +.globl _savefpr_30
> +_savefpr_30:
> + stfd f30,-16(r1)
> +.globl _savefpr_31
> +_savefpr_31:
> + stfd f31,-8(r1)
> + std r0, 16(r1)
> + blr
> +
> +.globl _restfpr_14
> +_restfpr_14:
> + lfd f14,-144(r1)
> +.globl _restfpr_15
> +_restfpr_15:
> + lfd f15,-136(r1)
> +.globl _restfpr_16
> +_restfpr_16:
> + lfd f16,-128(r1)
> +.globl _restfpr_17
> +_restfpr_17:
> + lfd f17,-120(r1)
> +.globl _restfpr_18
> +_restfpr_18:
> + lfd f18,-112(r1)
> +.globl _restfpr_19
> +_restfpr_19:
> + lfd f19,-104(r1)
> +.globl _restfpr_20
> +_restfpr_20:
> + lfd f20,-96(r1)
> +.globl _restfpr_21
> +_restfpr_21:
> + lfd f21,-88(r1)
> +.globl _restfpr_22
> +_restfpr_22:
> + lfd f22,-80(r1)
> +.globl _restfpr_23
> +_restfpr_23:
> + lfd f23,-72(r1)
> +.globl _restfpr_24
> +_restfpr_24:
> + lfd f24,-64(r1)
> +.globl _restfpr_25
> +_restfpr_25:
> + lfd f25,-56(r1)
> +.globl _restfpr_26
> +_restfpr_26:
> + lfd f26,-48(r1)
> +.globl _restfpr_27
> +_restfpr_27:
> + lfd f27,-40(r1)
> +.globl _restfpr_28
> +_restfpr_28:
> + lfd f28,-32(r1)
> +.globl _restfpr_29
> +_restfpr_29:
> + ld r0, 16(r1)
> + lfd f29,-24(r1)
> + mtlr r0
> + lfd f30,-16(r1)
> + lfd f31,-8(r1)
> + blr
> +.globl _restfpr_30
> +_restfpr_30:
> + lfd f30,-16(r1)
> +.globl _restfpr_31
> +_restfpr_31:
> + ld r0, 16(r1)
> + lfd f31,-8(r1)
> +
> +#endif /* CONFIG_PPC_FPU */
> +
> #endif /* CONFIG_PPC64 */
>
> #endif
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 267b9a0a3abc..153a163ba3f7 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -597,8 +597,12 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname)
> /* Special register function linked on all modules during final link of .ko */
> if (strstarts(symname, "_restgpr0_") ||
> strstarts(symname, "_savegpr0_") ||
> + strstarts(symname, "_restgpr1_") ||
> + strstarts(symname, "_savegpr1_") ||
> strstarts(symname, "_restvr_") ||
> strstarts(symname, "_savevr_") ||
> + strstarts(symname, "_restfpr_") ||
> + strstarts(symname, "_savefpr_") ||
> strcmp(symname, ".TOC.") == 0)
> return 1;
>
More information about the Linuxppc-dev
mailing list