ftrace/x86: skip over the breakpoint for ftrace caller

In commit 8a4d0a687a "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>
This commit is contained in:
Kevin Hao 2013-10-23 20:58:16 +08:00 committed by Steven Rostedt
parent 9cd804ac1f
commit ab4ead02ec
1 changed files with 13 additions and 1 deletions

View File

@ -248,6 +248,15 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return ret; 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 * A breakpoint was added to the code address we are about to
* modify, and this is the handle that will just skip over it. * 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) int ftrace_int3_handler(struct pt_regs *regs)
{ {
unsigned long ip;
if (WARN_ON_ONCE(!regs)) if (WARN_ON_ONCE(!regs))
return 0; return 0;
if (!ftrace_location(regs->ip - 1)) ip = regs->ip - 1;
if (!ftrace_location(ip) && !is_ftrace_caller(ip))
return 0; return 0;
regs->ip += MCOUNT_INSN_SIZE - 1; regs->ip += MCOUNT_INSN_SIZE - 1;