| From a9f8553e935f26cb5447f67e280946b0923cd2dc Mon Sep 17 00:00:00 2001 |
| From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> |
| Date: Thu, 1 Jun 2017 16:18:15 +0530 |
| Subject: powerpc/kprobes: Pause function_graph tracing during jprobes handling |
| |
| From: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> |
| |
| commit a9f8553e935f26cb5447f67e280946b0923cd2dc upstream. |
| |
| This fixes a crash when function_graph and jprobes are used together. |
| This is essentially commit 237d28db036e ("ftrace/jprobes/x86: Fix |
| conflict between jprobes and function graph tracing"), but for powerpc. |
| |
| Jprobes breaks function_graph tracing since the jprobe hook needs to use |
| jprobe_return(), which never returns back to the hook, but instead to |
| the original jprobe'd function. The solution is to momentarily pause |
| function_graph tracing before invoking the jprobe hook and re-enable it |
| when returning back to the original jprobe'd function. |
| |
| Fixes: 6794c78243bf ("powerpc64: port of the function graph tracer") |
| Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> |
| Acked-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/powerpc/kernel/kprobes.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| --- a/arch/powerpc/kernel/kprobes.c |
| +++ b/arch/powerpc/kernel/kprobes.c |
| @@ -514,6 +514,15 @@ int __kprobes setjmp_pre_handler(struct |
| #endif |
| #endif |
| |
| + /* |
| + * jprobes use jprobe_return() which skips the normal return |
| + * path of the function, and this messes up the accounting of the |
| + * function graph tracer. |
| + * |
| + * Pause function graph tracing while performing the jprobe function. |
| + */ |
| + pause_graph_tracing(); |
| + |
| return 1; |
| } |
| |
| @@ -536,6 +545,8 @@ int __kprobes longjmp_break_handler(stru |
| * saved regs... |
| */ |
| memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs)); |
| + /* It's OK to start function graph tracing again */ |
| + unpause_graph_tracing(); |
| preempt_enable_no_resched(); |
| return 1; |
| } |