From 5c729a115e4727fd71308e4d68846f64fa460ead Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 18 Mar 2014 20:13:03 +1030 Subject: [PATCH] powerpc: modules: skip r2 setup for ELFv2 ELFv2 doesn't need to set up r2 when calling a function. Signed-off-by: Rusty Russell --- arch/powerpc/kernel/module_64.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index f8b6d28..d722249 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -59,12 +59,19 @@ struct ppc64_stub_entry struct ppc64_opd_entry opd; }; -/* We use a stub to fix up r2 (TOC ptr) and to jump to the (external) - function which may be more than 24-bits away. We could simply - patch the new r2 value and function pointer into the stub, but it's - significantly shorter to put these values at the end of the stub - code, and patch the stub address (32-bits relative to the TOC ptr, - r2) into the stub. */ +/* + * PPC64 uses 24 bit jumps, but we need to jump into other modules or + * the kernel which may be further. So we jump to a stub. + * + * For ELFv1 we need to use this to set up the new r2 value (aka TOC + * pointer). For ELFv2 it's the callee's responsibility to set up the + * new r2, but for both we need to save the old r2. + * + * We could simply patch the new r2 value and function pointer into + * the stub, but it's significantly shorter to put these values at the + * end of the stub code, and patch the stub address (32-bits relative + * to the TOC ptr, r2) into the stub. + */ static struct ppc64_stub_entry ppc64_stub = { .jump = { 0x3d620000, /* addis r11,r2, */ @@ -72,7 +79,10 @@ static struct ppc64_stub_entry ppc64_stub = /* Save current r2 value in magic place on the stack. */ 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */ 0xe98b0020, /* ld r12,32(r11) */ +#if !defined(_CALL_ELF) || _CALL_ELF != 2 + /* Set up new r2 from function descriptor */ 0xe84b0026, /* ld r2,40(r11) */ +#endif 0x7d8903a6, /* mtctr r12 */ 0x4e800420 /* bctr */ } }; -- 2.7.4