summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/module_64.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2014-03-18 20:12:44 +1030
committerAnton Blanchard <anton@samba.org>2014-04-23 10:05:30 +1000
commitd2fae548039987e0c64957ede44822305fdafb66 (patch)
tree5f4cbf485eb80f32e533efb512a1c9dcded1af97 /arch/powerpc/kernel/module_64.c
parent5b12c5c69415b184aadb930660a47a8af4c6deb5 (diff)
powerpc: modules: change r2 save/restore offset for ELFv2 ABI.
ELFv2 uses a different stack offset (24 vs 40) to save r2. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'arch/powerpc/kernel/module_64.c')
-rw-r--r--arch/powerpc/kernel/module_64.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 05b27a5efc7e..8bfcf1b8b6d4 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -41,6 +41,12 @@
#define DEBUGP(fmt , ...)
#endif
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+#define R2_STACK_OFFSET 24
+#else
+#define R2_STACK_OFFSET 40
+#endif
+
/* Like PPC32, we need little trampolines to do > 24-bit jumps (into
the kernel itself). But on PPC64, these need to be used for every
jump, actually, to reset r2 (TOC+0x8000). */
@@ -61,14 +67,14 @@ struct ppc64_stub_entry
r2) into the stub. */
static struct ppc64_stub_entry ppc64_stub =
{ .jump = {
- 0x3d820000, /* addis r12,r2, <high> */
- 0x398c0000, /* addi r12,r12, <low> */
+ 0x3d820000, /* addis r12,r2, <high> */
+ 0x398c0000, /* addi r12,r12, <low> */
/* Save current r2 value in magic place on the stack. */
- 0xf8410028, /* std r2,40(r1) */
- 0xe96c0020, /* ld r11,32(r12) */
- 0xe84c0028, /* ld r2,40(r12) */
- 0x7d6903a6, /* mtctr r11 */
- 0x4e800420 /* bctr */
+ 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */
+ 0xe96c0020, /* ld r11,32(r12) */
+ 0xe84c0028, /* ld r2,40(r12) */
+ 0x7d6903a6, /* mtctr r11 */
+ 0x4e800420 /* bctr */
} };
/* Count how many different 24-bit relocations (different symbol,
@@ -338,7 +344,8 @@ static int restore_r2(u32 *instruction, struct module *me)
me->name, *instruction);
return 0;
}
- *instruction = 0xe8410028; /* ld r2,40(r1) */
+ /* ld r2,R2_STACK_OFFSET(r1) */
+ *instruction = 0xe8410000 | R2_STACK_OFFSET;
return 1;
}