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 <[email protected]> > Tested-by: Timothy Pearson <[email protected]> > Signed-off-by: Timothy Pearson <[email protected]> > --- > 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; >
