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 <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 -.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; -- 2.39.2