diff options
-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 42a392a9fd02..d4bdd253fea7 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) | |||
248 | return ret; | 248 | return ret; |
249 | } | 249 | } |
250 | 250 | ||
251 | static int is_ftrace_caller(unsigned long ip) | ||
252 | { | ||
253 | if (ip == (unsigned long)(&ftrace_call) || | ||
254 | ip == (unsigned long)(&ftrace_regs_call)) | ||
255 | return 1; | ||
256 | |||
257 | return 0; | ||
258 | } | ||
259 | |||
251 | /* | 260 | /* |
252 | * A breakpoint was added to the code address we are about to | 261 | * A breakpoint was added to the code address we are about to |
253 | * modify, and this is the handle that will just skip over it. | 262 | * 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) | |||
257 | */ | 266 | */ |
258 | int ftrace_int3_handler(struct pt_regs *regs) | 267 | int ftrace_int3_handler(struct pt_regs *regs) |
259 | { | 268 | { |
269 | unsigned long ip; | ||
270 | |||
260 | if (WARN_ON_ONCE(!regs)) | 271 | if (WARN_ON_ONCE(!regs)) |
261 | return 0; | 272 | return 0; |
262 | 273 | ||
263 | if (!ftrace_location(regs->ip - 1)) | 274 | ip = regs->ip - 1; |
275 | if (!ftrace_location(ip) && !is_ftrace_caller(ip)) | ||
264 | return 0; | 276 | return 0; |
265 | 277 | ||
266 | regs->ip += MCOUNT_INSN_SIZE - 1; | 278 | regs->ip += MCOUNT_INSN_SIZE - 1; |