* [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches
@ 2014-04-04 6:09 Anton Blanchard
2014-04-04 6:09 ` [PATCH 1/7] powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to modules Anton Blanchard
` (7 more replies)
0 siblings, 8 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
These patches apply against my last series and fix all known
ABIv2 issues.
To stress the module loader and dynamic ftrace code, I built an
allmodconfig kernel and inserted every module I could. I found a bunch
of bugs in the modules themselves, but in the end I managed to
get quite a few modules to load:
# cat /proc/modules | wc -l
3830
It survived a fair bit of poking (enabling/disabling function tracers
etc).
Anton Blanchard (7):
powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to
modules
powerpc: ftrace_caller, _mcount is exported to modules so needs
_GLOBAL_TOC()
powerpc/kprobes: Fix ABIv2 issues with kprobe_lookup_name
powerpc/modules: Create is_module_trampoline()
powerpc/modules: Create module_trampoline_target()
powerpc/ftrace: Use module loader helpers to parse trampolines
powerpc/ftrace: Fix ABIv2 issues with __ftrace_make_call
arch/powerpc/include/asm/kprobes.h | 5 +-
arch/powerpc/include/asm/module.h | 3 +
arch/powerpc/include/asm/ppc_asm.h | 12 ++++
arch/powerpc/kernel/entry_64.S | 7 +-
arch/powerpc/kernel/ftrace.c | 137 +++++++++++--------------------------
arch/powerpc/kernel/module_64.c | 80 ++++++++++++++++++++--
arch/powerpc/lib/copyuser_64.S | 2 +-
arch/powerpc/lib/memcpy_64.S | 2 +-
8 files changed, 136 insertions(+), 112 deletions(-)
--
1.8.3.2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/7] powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to modules
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:09 ` [PATCH 2/7] powerpc: ftrace_caller, _mcount is exported to modules so needs _GLOBAL_TOC() Anton Blanchard
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
If an assembly function that calls back into c code is exported to
modules, we need to ensure r2 is setup correctly. There are only
two places crazy enough to do it (two of which are my fault).
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/include/asm/ppc_asm.h | 12 ++++++++++++
arch/powerpc/lib/copyuser_64.S | 2 +-
arch/powerpc/lib/memcpy_64.S | 2 +-
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 2cc2511..6400f18 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -207,6 +207,16 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
.globl name; \
name:
+#define _GLOBAL_TOC(name) \
+ .section ".text"; \
+ .align 2 ; \
+ .type name,@function; \
+ .globl name; \
+name: \
+0: addis r2,r12,(.TOC.-0b)@ha; \
+ addi r2,r2,(.TOC.-0b)@l; \
+ .localentry name,.-name
+
#define _KPROBE(name) \
.section ".kprobes.text","a"; \
.align 2 ; \
@@ -235,6 +245,8 @@ name: \
.type GLUE(.,name),@function; \
GLUE(.,name):
+#define _GLOBAL_TOC(name) _GLOBAL(name)
+
#define _KPROBE(name) \
.section ".kprobes.text","a"; \
.align 2 ; \
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 596a285..0860ee4 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -18,7 +18,7 @@
#endif
.align 7
-_GLOBAL(__copy_tofrom_user)
+_GLOBAL_TOC(__copy_tofrom_user)
BEGIN_FTR_SECTION
nop
FTR_SECTION_ELSE
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index 9d3960c..bc9a2ca 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -10,7 +10,7 @@
#include <asm/ppc_asm.h>
.align 7
-_GLOBAL(memcpy)
+_GLOBAL_TOC(memcpy)
BEGIN_FTR_SECTION
std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) /* save destination pointer for return value */
FTR_SECTION_ELSE
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] powerpc: ftrace_caller, _mcount is exported to modules so needs _GLOBAL_TOC()
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
2014-04-04 6:09 ` [PATCH 1/7] powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to modules Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:09 ` [PATCH 3/7] powerpc/kprobes: Fix ABIv2 issues with kprobe_lookup_name Anton Blanchard
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
When testing the ftrace function tracer, I realised that ftrace_caller
and mcount are called from modules and they both call into C, therefore
they need the ABIv2 global entry point to establish r2.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/entry_64.S | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index cf4f6e6..9fde8a1 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1175,7 +1175,7 @@ _GLOBAL(mcount)
_GLOBAL(_mcount)
blr
-_GLOBAL(ftrace_caller)
+_GLOBAL_TOC(ftrace_caller)
/* Taken from output of objdump from lib64/glibc */
mflr r3
ld r11, 0(r1)
@@ -1199,10 +1199,7 @@ _GLOBAL(ftrace_graph_stub)
_GLOBAL(ftrace_stub)
blr
#else
-_GLOBAL(mcount)
- blr
-
-_GLOBAL(_mcount)
+_GLOBAL_TOC(_mcount)
/* Taken from output of objdump from lib64/glibc */
mflr r3
ld r11, 0(r1)
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/7] powerpc/kprobes: Fix ABIv2 issues with kprobe_lookup_name
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
2014-04-04 6:09 ` [PATCH 1/7] powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to modules Anton Blanchard
2014-04-04 6:09 ` [PATCH 2/7] powerpc: ftrace_caller, _mcount is exported to modules so needs _GLOBAL_TOC() Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:09 ` [PATCH 4/7] powerpc/modules: Create is_module_trampoline() Anton Blanchard
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
Use ppc_function_entry in places where we previously assumed
function descriptors exist.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/include/asm/kprobes.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h
index 7b6feab..af15d4d 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -30,6 +30,7 @@
#include <linux/ptrace.h>
#include <linux/percpu.h>
#include <asm/probes.h>
+#include <asm/code-patching.h>
#define __ARCH_WANT_KPROBES_INSN_SLOT
@@ -56,9 +57,9 @@ typedef ppc_opcode_t kprobe_opcode_t;
if ((colon = strchr(name, ':')) != NULL) { \
colon++; \
if (*colon != '\0' && *colon != '.') \
- addr = *(kprobe_opcode_t **)addr; \
+ addr = (kprobe_opcode_t *)ppc_function_entry(addr); \
} else if (name[0] != '.') \
- addr = *(kprobe_opcode_t **)addr; \
+ addr = (kprobe_opcode_t *)ppc_function_entry(addr); \
} else { \
char dot_name[KSYM_NAME_LEN]; \
dot_name[0] = '.'; \
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/7] powerpc/modules: Create is_module_trampoline()
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
` (2 preceding siblings ...)
2014-04-04 6:09 ` [PATCH 3/7] powerpc/kprobes: Fix ABIv2 issues with kprobe_lookup_name Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:09 ` [PATCH 5/7] powerpc/modules: Create module_trampoline_target() Anton Blanchard
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
ftrace has way too much knowledge of our kernel module trampoline
layout hidden inside it. Create is_module_trampoline() that can
abstract this away inside the module loader code.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/include/asm/module.h | 1 +
arch/powerpc/kernel/module_64.c | 51 +++++++++++++++++++++++++++++++++++----
2 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index c9c7aaa..f2711f0 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -78,6 +78,7 @@ struct mod_arch_specific {
# endif /* MODULE */
#endif
+bool is_module_trampoline(u32 *insns);
struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 0423601..4db5ecd 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -22,6 +22,7 @@
#include <linux/vmalloc.h>
#include <linux/ftrace.h>
#include <linux/bug.h>
+#include <linux/uaccess.h>
#include <asm/module.h>
#include <asm/firmware.h>
#include <asm/code-patching.h>
@@ -102,7 +103,9 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym)
jump, actually, to reset r2 (TOC+0x8000). */
struct ppc64_stub_entry
{
- /* 28 byte jump instruction sequence (7 instructions) */
+ /* 28 byte jump instruction sequence (7 instructions). We only
+ * need 6 instructions on ABIv2 but we always allocate 7 so
+ * so we don't have to modify the trampoline load instruction. */
u32 jump[7];
u32 unused;
/* Data for the above code */
@@ -122,8 +125,8 @@ struct ppc64_stub_entry
* 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 = {
+
+static u32 ppc64_stub_insns[] = {
0x3d620000, /* addis r11,r2, <high> */
0x396b0000, /* addi r11,r11, <low> */
/* Save current r2 value in magic place on the stack. */
@@ -135,7 +138,45 @@ static struct ppc64_stub_entry ppc64_stub =
#endif
0x7d8903a6, /* mtctr r12 */
0x4e800420 /* bctr */
-} };
+};
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+static u32 ppc64_stub_mask[] = {
+ 0xffff0000,
+ 0xffff0000,
+ 0xffffffff,
+ 0xffffffff,
+#if !defined(_CALL_ELF) || _CALL_ELF != 2
+ 0xffffffff,
+#endif
+ 0xffffffff,
+ 0xffffffff
+};
+
+bool is_module_trampoline(u32 *p)
+{
+ unsigned int i;
+ u32 insns[ARRAY_SIZE(ppc64_stub_insns)];
+
+ BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask));
+
+ if (probe_kernel_read(insns, p, sizeof(insns)))
+ return -EFAULT;
+
+ for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) {
+ u32 insna = insns[i];
+ u32 insnb = ppc64_stub_insns[i];
+ u32 mask = ppc64_stub_mask[i];
+
+ if ((insna & mask) != (insnb & mask))
+ return false;
+ }
+
+ return true;
+}
+
+#endif
/* Count how many different 24-bit relocations (different symbol,
different addend) */
@@ -350,7 +391,7 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
{
long reladdr;
- *entry = ppc64_stub;
+ memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns));
/* Stub uses address relative to r2. */
reladdr = (unsigned long)entry - my_r2(sechdrs, me);
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/7] powerpc/modules: Create module_trampoline_target()
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
` (3 preceding siblings ...)
2014-04-04 6:09 ` [PATCH 4/7] powerpc/modules: Create is_module_trampoline() Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:09 ` [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines Anton Blanchard
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
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>
---
arch/powerpc/include/asm/module.h | 2 ++
arch/powerpc/kernel/module_64.c | 29 +++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h
index f2711f0..dcfcad1 100644
--- a/arch/powerpc/include/asm/module.h
+++ b/arch/powerpc/include/asm/module.h
@@ -79,6 +79,8 @@ struct mod_arch_specific {
#endif
bool is_module_trampoline(u32 *insns);
+int module_trampoline_target(struct module *mod, u32 *trampoline,
+ unsigned long *target);
struct exception_table_entry;
void sort_ex_table(struct exception_table_entry *start,
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 4db5ecd..ef349d0 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,
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
` (4 preceding siblings ...)
2014-04-04 6:09 ` [PATCH 5/7] powerpc/modules: Create module_trampoline_target() Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-22 6:58 ` Rusty Russell
2014-04-04 6:09 ` [PATCH 7/7] powerpc/ftrace: Fix ABIv2 issues with __ftrace_make_call Anton Blanchard
2014-04-04 6:19 ` [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Michael Neuling
7 siblings, 1 reply; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
Now we have is_module_trampoline() and module_trampoline_target()
we can remove a bunch of intimate kernel module trampoline
knowledge from ftrace.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/ftrace.c | 97 +++++++++-----------------------------------
1 file changed, 20 insertions(+), 77 deletions(-)
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index b0ded97..b68e0ef 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -105,11 +105,9 @@ __ftrace_make_nop(struct module *mod,
struct dyn_ftrace *rec, unsigned long addr)
{
unsigned int op;
- unsigned int jmp[5];
unsigned long ptr;
unsigned long ip = rec->ip;
- unsigned long tramp;
- int offset;
+ void *tramp;
/* read where this goes */
if (probe_kernel_read(&op, (void *)ip, sizeof(int)))
@@ -122,96 +120,41 @@ __ftrace_make_nop(struct module *mod,
}
/* lets find where the pointer goes */
- tramp = find_bl_target(ip, op);
-
- /*
- * On PPC64 the trampoline looks like:
- * 0x3d, 0x82, 0x00, 0x00, addis r12,r2, <high>
- * 0x39, 0x8c, 0x00, 0x00, addi r12,r12, <low>
- * Where the bytes 2,3,6 and 7 make up the 32bit offset
- * to the TOC that holds the pointer.
- * to jump to.
- * 0xf8, 0x41, 0x00, 0x28, std r2,40(r1)
- * 0xe9, 0x6c, 0x00, 0x20, ld r11,32(r12)
- * The actually address is 32 bytes from the offset
- * into the TOC.
- * 0xe8, 0x4c, 0x00, 0x28, ld r2,40(r12)
- */
+ tramp = (void *)find_bl_target(ip, op);
- pr_devel("ip:%lx jumps to %lx r2: %lx", ip, tramp, mod->arch.toc);
+ pr_devel("ip:%lx jumps to %p", ip, tramp);
- /* Find where the trampoline jumps to */
- if (probe_kernel_read(jmp, (void *)tramp, sizeof(jmp))) {
- printk(KERN_ERR "Failed to read %lx\n", tramp);
- return -EFAULT;
- }
-
- pr_devel(" %08x %08x", jmp[0], jmp[1]);
-
- /* verify that this is what we expect it to be */
- if (((jmp[0] & 0xffff0000) != 0x3d820000) ||
- ((jmp[1] & 0xffff0000) != 0x398c0000) ||
- (jmp[2] != 0xf8410028) ||
- (jmp[3] != 0xe96c0020) ||
- (jmp[4] != 0xe84c0028)) {
+ if (!is_module_trampoline(tramp)) {
printk(KERN_ERR "Not a trampoline\n");
return -EINVAL;
}
- /* The bottom half is signed extended */
- offset = ((unsigned)((unsigned short)jmp[0]) << 16) +
- (int)((short)jmp[1]);
-
- pr_devel(" %x ", offset);
-
- /* get the address this jumps too */
- tramp = mod->arch.toc + offset + 32;
- pr_devel("toc: %lx", tramp);
-
- if (probe_kernel_read(jmp, (void *)tramp, 8)) {
- printk(KERN_ERR "Failed to read %lx\n", tramp);
+ if (module_trampoline_target(mod, tramp, &ptr)) {
+ printk(KERN_ERR "Failed to get trampoline target\n");
return -EFAULT;
}
- pr_devel(" %08x %08x\n", jmp[0], jmp[1]);
-
-#ifdef __LITTLE_ENDIAN__
- ptr = ((unsigned long)jmp[1] << 32) + jmp[0];
-#else
- ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
-#endif
+ pr_devel("trampoline target %lx", ptr);
/* This should match what was called */
if (ptr != ppc_function_entry((void *)addr)) {
- printk(KERN_ERR "addr does not match %lx\n", ptr);
+ printk(KERN_ERR "addr %lx does not match expected %lx\n",
+ ptr, ppc_function_entry((void *)addr));
return -EINVAL;
}
/*
- * We want to nop the line, but the next line is
- * 0xe8, 0x41, 0x00, 0x28 ld r2,40(r1)
- * This needs to be turned to a nop too.
- */
- if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE))
- return -EFAULT;
-
- if (op != 0xe8410028) {
- printk(KERN_ERR "Next line is not ld! (%08x)\n", op);
- return -EINVAL;
- }
-
- /*
- * Milton Miller pointed out that we can not blindly do nops.
- * If a task was preempted when calling a trace function,
- * the nops will remove the way to restore the TOC in r2
- * and the r2 TOC will get corrupted.
- */
-
- /*
- * Replace:
- * bl <tramp> <==== will be replaced with "b 1f"
- * ld r2,40(r1)
- * 1:
+ * Our original call site looks like:
+ *
+ * bl <tramp>
+ * ld r2,XX(r1)
+ *
+ * Milton Miller pointed out that we can not simply nop the branch.
+ * If a task was preempted when calling a trace function, the nops
+ * will remove the way to restore the TOC in r2 and the r2 TOC will
+ * get corrupted.
+ *
+ * Use a b +8 to jump over the load.
*/
op = 0x48000008; /* b +8 */
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/7] powerpc/ftrace: Fix ABIv2 issues with __ftrace_make_call
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
` (5 preceding siblings ...)
2014-04-04 6:09 ` [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines Anton Blanchard
@ 2014-04-04 6:09 ` Anton Blanchard
2014-04-04 6:19 ` [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Michael Neuling
7 siblings, 0 replies; 10+ messages in thread
From: Anton Blanchard @ 2014-04-04 6:09 UTC (permalink / raw)
To: benh, paulus, rusty, ulrich.weigand, amodra, mikey, mjw, rostedt,
philippe.bergheaud
Cc: linuxppc-dev
__ftrace_make_call assumed ABIv1 TOC stack offsets, so it
broke on ABIv2.
While we are here, we can simplify the instruction modification
code. Since we always update one instruction there is no need to
probe_kernel_write and flush_icache_range, just use patch_branch.
Signed-off-by: Anton Blanchard <anton@samba.org>
---
arch/powerpc/kernel/ftrace.c | 40 +++++++++++++++++++---------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c
index b68e0ef..6ab510d 100644
--- a/arch/powerpc/kernel/ftrace.c
+++ b/arch/powerpc/kernel/ftrace.c
@@ -292,19 +292,24 @@ static int
__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
{
unsigned int op[2];
- unsigned long ip = rec->ip;
+ void *ip = (void *)rec->ip;
/* read where this goes */
- if (probe_kernel_read(op, (void *)ip, MCOUNT_INSN_SIZE * 2))
+ if (probe_kernel_read(op, ip, sizeof(op)))
return -EFAULT;
/*
- * It should be pointing to two nops or
- * b +8; ld r2,40(r1)
+ * We expect to see:
+ *
+ * b +8
+ * ld r2,XX(r1)
+ *
+ * The load offset is different depending on the ABI. For simplicity
+ * just mask it out when doing the compare.
*/
- if (((op[0] != 0x48000008) || (op[1] != 0xe8410028)) &&
- ((op[0] != PPC_INST_NOP) || (op[1] != PPC_INST_NOP))) {
- printk(KERN_ERR "Expected NOPs but have %x %x\n", op[0], op[1]);
+ if ((op[0] != 0x48000008) || ((op[1] & 0xffff00000) != 0xe8410000)) {
+ printk(KERN_ERR "Unexpected call sequence: %x %x\n",
+ op[0], op[1]);
return -EINVAL;
}
@@ -314,23 +319,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return -EINVAL;
}
- /* create the branch to the trampoline */
- op[0] = create_branch((unsigned int *)ip,
- rec->arch.mod->arch.tramp, BRANCH_SET_LINK);
- if (!op[0]) {
- printk(KERN_ERR "REL24 out of range!\n");
+ /* Ensure branch is within 24 bits */
+ if (create_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
+ printk(KERN_ERR "Branch out of range");
return -EINVAL;
}
- /* ld r2,40(r1) */
- op[1] = 0xe8410028;
-
- pr_devel("write to %lx\n", rec->ip);
-
- if (probe_kernel_write((void *)ip, op, MCOUNT_INSN_SIZE * 2))
- return -EPERM;
-
- flush_icache_range(ip, ip + 8);
+ if (patch_branch(ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK)) {
+ printk(KERN_ERR "REL24 out of range!\n");
+ return -EINVAL;
+ }
return 0;
}
--
1.8.3.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
` (6 preceding siblings ...)
2014-04-04 6:09 ` [PATCH 7/7] powerpc/ftrace: Fix ABIv2 issues with __ftrace_make_call Anton Blanchard
@ 2014-04-04 6:19 ` Michael Neuling
7 siblings, 0 replies; 10+ messages in thread
From: Michael Neuling @ 2014-04-04 6:19 UTC (permalink / raw)
To: Anton Blanchard
Cc: philippe.bergheaud, amodra, rusty, rostedt, ulrich.weigand, mjw,
paulus, linuxppc-dev
Anton Blanchard <anton@samba.org> wrote:
> These patches apply against my last series and fix all known
> ABIv2 issues.
>
> To stress the module loader and dynamic ftrace code, I built an
> allmodconfig kernel and inserted every module I could. I found a bunch
> of bugs in the modules themselves, but in the end I managed to
> get quite a few modules to load:
>
> # cat /proc/modules | wc -l
> 3830
>From http://antonblanchardfacts.com/?270 :
Anton Blanchard's machine always has at least 3800 modules installed.
Mikey
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines
2014-04-04 6:09 ` [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines Anton Blanchard
@ 2014-04-22 6:58 ` Rusty Russell
0 siblings, 0 replies; 10+ messages in thread
From: Rusty Russell @ 2014-04-22 6:58 UTC (permalink / raw)
To: Anton Blanchard, benh, paulus, ulrich.weigand, amodra, mikey, mjw,
rostedt, philippe.bergheaud
Cc: linuxppc-dev
Anton Blanchard <anton@samba.org> writes:
> Now we have is_module_trampoline() and module_trampoline_target()
> we can remove a bunch of intimate kernel module trampoline
> knowledge from ftrace.
>
> Signed-off-by: Anton Blanchard <anton@samba.org>
Oh god, I had no idea this code existed.
I really wanted to implement the R_PPC64_TOCSAVE optimization, and I was
thinking of frobbing the stub code. At least now it's all in one place,
because I would have completely missed this.
Thanks,
Rusty.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-04-22 6:58 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-04 6:09 [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Anton Blanchard
2014-04-04 6:09 ` [PATCH 1/7] powerpc: Add _GLOBAL_TOC for ABIv2 assembly functions exported to modules Anton Blanchard
2014-04-04 6:09 ` [PATCH 2/7] powerpc: ftrace_caller, _mcount is exported to modules so needs _GLOBAL_TOC() Anton Blanchard
2014-04-04 6:09 ` [PATCH 3/7] powerpc/kprobes: Fix ABIv2 issues with kprobe_lookup_name Anton Blanchard
2014-04-04 6:09 ` [PATCH 4/7] powerpc/modules: Create is_module_trampoline() Anton Blanchard
2014-04-04 6:09 ` [PATCH 5/7] powerpc/modules: Create module_trampoline_target() Anton Blanchard
2014-04-04 6:09 ` [PATCH 6/7] powerpc/ftrace: Use module loader helpers to parse trampolines Anton Blanchard
2014-04-22 6:58 ` Rusty Russell
2014-04-04 6:09 ` [PATCH 7/7] powerpc/ftrace: Fix ABIv2 issues with __ftrace_make_call Anton Blanchard
2014-04-04 6:19 ` [PATCH 0/7] Build ppc64le kernel using ABIv2, supplemental patches Michael Neuling
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).