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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Nov 2013 19:11:50 +0000 (11:11 -0800)
commit ab4ead02ec235d706d0611d8741964628291237e upstream.

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.

Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kernel/ftrace.c

index 42a392a9fd02fd3c0e306e3a4f4da323444dc3fd..d4bdd253fea71358ca080ba567a44935a9830396 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;