[PATCH v3] powerpc: Add gpr1 and fpu save/restore functions
Timothy Pearson
tpearson at raptorengineering.com
Sat Feb 17 04:24:07 AEDT 2024
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 | 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
More information about the Linuxppc-dev
mailing list