Skip to contentSkip to conversation

Patch "powerpc/module: Handle R_PPC64_ENTRY relocations" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Jan 27, 2016

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

powerpc/module: Handle R_PPC64_ENTRY relocations

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
powerpc-module-handle-r_ppc64_entry-relocations.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From a61674bdfc7c2bf909c4010699607b62b69b7bec Mon Sep 17 00:00:00 2001

From: Ulrich Weigand <[email protected]>
Date: Tue, 12 Jan 2016 23:14:23 +1100
Subject: powerpc/module: Handle R_PPC64_ENTRY relocations

From: Ulrich Weigand <[email protected]>

commit a61674bdfc7c2bf909c4010699607b62b69b7bec upstream.

GCC 6 will include changes to generated code with -mcmodel=large, which is used to build kernel modules on powerpc64le. This was necessary because the large model is supposed to allow arbitrary sizes and locations of the code and data sections, but the ELFv2 global entry point prolog still made the unconditional assumption that the TOC associated with any particular function can be found within 2 GB of the function entry point:

func:

	addis r2,r12,(.TOC.-func)@ha
	addi  r2,r2,(.TOC.-func)@l
	.localentry func, .-func

To remove this assumption, GCC will now generate instead this global entry point prolog sequence when using -mcmodel=large:

.quad .TOC.-func
func:

	.reloc ., R_PPC64_ENTRY
	ld    r2, -8(r12)
	add   r2, r2, r12
	.localentry func, .-func

The new .reloc triggers an optimization in the linker that will replace this new prolog with the original code (see above) if the linker determines that the distance between .TOC. and func is in range after all.

Since this new relocation is now present in module object files, the kernel module loader is required to handle them too. This patch adds support for the new relocation and implements the same optimization done by the GNU linker.

---
 arch/powerpc/include/uapi/asm/elf.h |    2 ++
 arch/powerpc/kernel/module_64.c     |   27 +++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)
arch/powerpc/include/uapi/asm/elf.h +2 -0
@@ -295,6 +295,8 @@ do {									\
 #define R_PPC64_TLSLD		108
 #define R_PPC64_TOCSAVE		109
 
+#define R_PPC64_ENTRY		118
+
 #define R_PPC64_REL16		249
 #define R_PPC64_REL16_LO	250
 #define R_PPC64_REL16_HI	251
arch/powerpc/kernel/module_64.c +27 -0
@@ -635,6 +635,33 @@ int apply_relocate_add(Elf64_Shdr *sechd
 			 */
 			break;
 
+		case R_PPC64_ENTRY:
+			/*
+			 * Optimize ELFv2 large code model entry point if
+			 * the TOC is within 2GB range of current location.
+			 */
+			value = my_r2(sechdrs, me) - (unsigned long)location;
+			if (value + 0x80008000 > 0xffffffff)
+				break;
+			/*
+			 * Check for the large code model prolog sequence:
+		         *	ld r2, ...(r12)
+			 *	add r2, r2, r12
+			 */
+			if ((((uint32_t *)location)[0] & ~0xfffc)
+			    != 0xe84c0000)
+				break;
+			if (((uint32_t *)location)[1] != 0x7c426214)
+				break;
+			/*
+			 * If found, replace it with:
+			 *	addis r2, r12, (.TOC.-func)@ha
+			 *	addi r2, r12, (.TOC.-func)@l
+			 */
+			((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value);
+			((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value);
+			break;
+
 		case R_PPC64_REL16_HA:
 			/* Subtract location pointer */
 			value -= (unsigned long)location;

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/powerpc-module-handle-r_ppc64_entry-relocations.patch queue-4.4/scripts-recordmcount.pl-support-data-in-text-section-on-powerpc.patch