[PATCH v2] powerpc: Add gpr1 and fpu save/restore functions
Christophe Leroy
christophe.leroy at csgroup.eu
Wed Feb 14 02:13:41 AEDT 2024
Le 12/02/2024 à 18:14, 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.
>
> 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 | 244 +++++++++++++++++++++++++
> scripts/mod/modpost.c | 4 +
> 3 files changed, 250 insertions(+), 2 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..6cd870aacd7f 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
> @@ -435,6 +436,127 @@ _restgpr0_31:
> mtlr r0
> blr
>
> +.globl _savegpr1_14
> +_savegpr1_14:
> + std r14,-144(r12)
> +.globl _savegpr1_15
> +_savegpr1_15:
> + std r15,-136(r12)
> +.globl _savegpr1_16
> +_savegpr1_16:
> + std r16,-128(r12)
> +.globl _savegpr1_17
> +_savegpr1_17:
> + std r17,-120(r12)
> +.globl _savegpr1_18
> +_savegpr1_18:
> + std r18,-112(r12)
> +.globl _savegpr1_19
> +_savegpr1_19:
> + std r19,-104(r12)
> +.globl _savegpr1_20
> +_savegpr1_20:
> + std r20,-96(r12)
> +.globl _savegpr1_21
> +_savegpr1_21:
> + std r21,-88(r12)
> +.globl _savegpr1_22
> +_savegpr1_22:
> + std r22,-80(r12)
> +.globl _savegpr1_23
> +_savegpr1_23:
> + std r23,-72(r12)
> +.globl _savegpr1_24
> +_savegpr1_24:
> + std r24,-64(r12)
> +.globl _savegpr1_25
> +_savegpr1_25:
> + std r25,-56(r12)
> +.globl _savegpr1_26
> +_savegpr1_26:
> + std r26,-48(r12)
> +.globl _savegpr1_27
> +_savegpr1_27:
> + std r27,-40(r12)
> +.globl _savegpr1_28
> +_savegpr1_28:
> + std r28,-32(r12)
> +.globl _savegpr1_29
> +_savegpr1_29:
> + std r29,-24(r12)
> +.globl _savegpr1_30
> +_savegpr1_30:
> + std r30,-16(r12)
> +.globl _savegpr1_31
> +_savegpr1_31:
> + std r31,-8(r12)
> + std r0,16(r12)
> + blr
All this looks very similar to savegpr0_xx and restgpr0_xx with the
difference being that r12 is used instead of r1.
Could we avoid duplication by using macros ?
> +
> +.globl _restgpr1_14
> +_restgpr1_14:
> + ld r14,-144(r12)
> +.globl _restgpr1_15
> +_restgpr1_15:
> + ld r15,-136(r12)
> +.globl _restgpr1_16
> +_restgpr1_16:
> + ld r16,-128(r12)
> +.globl _restgpr1_17
> +_restgpr1_17:
> + ld r17,-120(r12)
> +.globl _restgpr1_18
> +_restgpr1_18:
> + ld r18,-112(r12)
> +.globl _restgpr1_19
> +_restgpr1_19:
> + ld r19,-104(r12)
> +.globl _restgpr1_20
> +_restgpr1_20:
> + ld r20,-96(r12)
> +.globl _restgpr1_21
> +_restgpr1_21:
> + ld r21,-88(r12)
> +.globl _restgpr1_22
> +_restgpr1_22:
> + ld r22,-80(r12)
> +.globl _restgpr1_23
> +_restgpr1_23:
> + ld r23,-72(r12)
> +.globl _restgpr1_24
> +_restgpr1_24:
> + ld r24,-64(r12)
> +.globl _restgpr1_25
> +_restgpr1_25:
> + ld r25,-56(r12)
> +.globl _restgpr1_26
> +_restgpr1_26:
> + ld r26,-48(r12)
> +.globl _restgpr1_27
> +_restgpr1_27:
> + ld r27,-40(r12)
> +.globl _restgpr1_28
> +_restgpr1_28:
> + ld r28,-32(r12)
> +.globl _restgpr1_29
> +_restgpr1_29:
> + ld r0,16(r12)
> + ld r29,-24(r12)
> + mtlr r0
> + ld r30,-16(r12)
> + ld r31,-8(r12)
> + blr
> +
> +.globl _restgpr1_30
> +_restgpr1_30:
> + ld r30,-16(r12)
> +.globl _restgpr1_31
> +_restgpr1_31:
> + ld r0,16(r12)
> + ld r31,-8(r12)
> + mtlr r0
> + blr
> +
> #ifdef CONFIG_ALTIVEC
> /* Called with r0 pointing just beyond the end of the vector save area. */
>
> @@ -540,6 +662,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