diff options
Diffstat (limited to 'arch/x86')
| -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; |
