summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/module_64.c
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2014-04-04 06:58:42 +0200
committerAnton Blanchard <anton@samba.org>2014-04-23 02:05:34 +0200
commitdd9fa162505c07e1917c96a1a12ca117b1afe55a (patch)
tree9ce7575c9d5adb622c58c491688fa66510069657 /arch/powerpc/kernel/module_64.c
parentpowerpc/modules: Create is_module_trampoline() (diff)
downloadlinux-dd9fa162505c07e1917c96a1a12ca117b1afe55a.tar.xz
linux-dd9fa162505c07e1917c96a1a12ca117b1afe55a.zip
powerpc/modules: Create module_trampoline_target()
ftrace has way too much knowledge of our kernel module trampoline layout hidden inside it. Create module_trampoline_target() that gives the target address of a kernel module trampoline. Signed-off-by: Anton Blanchard <anton@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/module_64.c')
-rw-r--r--arch/powerpc/kernel/module_64.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 4db5ecdc06e6..ef349d077129 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -176,6 +176,35 @@ bool is_module_trampoline(u32 *p)
return true;
}
+int module_trampoline_target(struct module *mod, u32 *trampoline,
+ unsigned long *target)
+{
+ u32 buf[2];
+ u16 upper, lower;
+ long offset;
+ void *toc_entry;
+
+ if (probe_kernel_read(buf, trampoline, sizeof(buf)))
+ return -EFAULT;
+
+ upper = buf[0] & 0xffff;
+ lower = buf[1] & 0xffff;
+
+ /* perform the addis/addi, both signed */
+ offset = ((short)upper << 16) + (short)lower;
+
+ /*
+ * Now get the address this trampoline jumps to. This
+ * is always 32 bytes into our trampoline stub.
+ */
+ toc_entry = (void *)mod->arch.toc + offset + 32;
+
+ if (probe_kernel_read(target, toc_entry, sizeof(*target)))
+ return -EFAULT;
+
+ return 0;
+}
+
#endif
/* Count how many different 24-bit relocations (different symbol,