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 <l...@intel.com>
> Tested-by: Timothy Pearson <tpear...@raptorengineering.com>
> Signed-off-by: Timothy Pearson <tpear...@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;
>   

Reply via email to