ftrace/x86: skip over the breakpoint for ftrace caller
authorKevin Hao <haokexin@gmail.com>
Wed, 23 Oct 2013 12:58:16 +0000 (20:58 +0800)
committerSteven Rostedt <rostedt@goodmis.org>
Tue, 5 Nov 2013 21:01:47 +0000 (16:01 -0500)
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>
arch/x86/kernel/ftrace.c

index 42a392a..d4bdd25 100644 (file)
@@ -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;