diff options
author | Kevin Hao <haokexin@gmail.com> | 2013-10-23 12:58:16 (GMT) |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-11-05 21:01:47 (GMT) |
commit | ab4ead02ec235d706d0611d8741964628291237e (patch) | |
tree | 3a0d764b40cc2219d8ded433dcf4fe48b1b3e7fc /arch/x86/kernel/ftrace.c | |
parent | 9cd804ac1f39e10510bf93700f1f7ea66b2e1b38 (diff) | |
download | linux-ab4ead02ec235d706d0611d8741964628291237e.tar.xz |
ftrace/x86: skip over the breakpoint for ftrace caller
In commit 8a4d0a687a59 "ftrace: Use breakpoint method to update ftrace
caller", we choose to use breakpoint method to update the ftrace
caller. But we also need to skip over the breakpoint in function
ftrace_int3_handler() for them. Otherwise weird things would happen.
Cc: stable@vger.kernel.org # 3.5+
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'arch/x86/kernel/ftrace.c')
-rw-r--r-- | arch/x86/kernel/ftrace.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 42a392a..d4bdd25 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -248,6 +248,15 @@ int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } +static int is_ftrace_caller(unsigned long ip) +{ + if (ip == (unsigned long)(&ftrace_call) || + ip == (unsigned long)(&ftrace_regs_call)) + return 1; + + return 0; +} + /* * A breakpoint was added to the code address we are about to * modify, and this is the handle that will just skip over it. @@ -257,10 +266,13 @@ int ftrace_update_ftrace_func(ftrace_func_t func) */ int ftrace_int3_handler(struct pt_regs *regs) { + unsigned long ip; + if (WARN_ON_ONCE(!regs)) return 0; - if (!ftrace_location(regs->ip - 1)) + ip = regs->ip - 1; + if (!ftrace_location(ip) && !is_ftrace_caller(ip)) return 0; regs->ip += MCOUNT_INSN_SIZE - 1; |