aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/kprobes/ftrace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 22:58:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-10 22:58:13 -0500
commit1dd7dcb6eaa677b034e7ef63df8320277507ae70 (patch)
tree3f1592b634d7bdde94e00570925be2dade8433d4 /arch/x86/kernel/kprobes/ftrace.c
parentb6da0076bab5a12afb19312ffee41c95490af2a0 (diff)
parent3558a5ac50dbb2419cc649d5e154af161d661037 (diff)
Merge tag 'trace-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: "There was a lot of clean ups and minor fixes. One of those clean ups was to the trace_seq code. It also removed the return values to the trace_seq_*() functions and use trace_seq_has_overflowed() to see if the buffer filled up or not. This is similar to work being done to the seq_file code as well in another tree. Some of the other goodies include: - Added some "!" (NOT) logic to the tracing filter. - Fixed the frame pointer logic to the x86_64 mcount trampolines - Added the logic for dynamic trampolines on !CONFIG_PREEMPT systems. That is, the ftrace trampoline can be dynamically allocated and be called directly by functions that only have a single hook to them" * tag 'trace-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (55 commits) tracing: Truncated output is better than nothing tracing: Add additional marks to signal very large time deltas Documentation: describe trace_buf_size parameter more accurately tracing: Allow NOT to filter AND and OR clauses tracing: Add NOT to filtering logic ftrace/fgraph/x86: Have prepare_ftrace_return() take ip as first parameter ftrace/x86: Get rid of ftrace_caller_setup ftrace/x86: Have save_mcount_regs macro also save stack frames if needed ftrace/x86: Add macro MCOUNT_REG_SIZE for amount of stack used to save mcount regs ftrace/x86: Simplify save_mcount_regs on getting RIP ftrace/x86: Have save_mcount_regs store RIP in %rdi for first parameter ftrace/x86: Rename MCOUNT_SAVE_FRAME and add more detailed comments ftrace/x86: Move MCOUNT_SAVE_FRAME out of header file ftrace/x86: Have static tracing also use ftrace_caller_setup ftrace/x86: Have static function tracing always test for function graph kprobes: Add IPMODIFY flag to kprobe_ftrace_ops ftrace, kprobes: Support IPMODIFY flag to find IP modify conflict kprobes/ftrace: Recover original IP if pre_handler doesn't change it tracing/trivial: Fix typos and make an int into a bool tracing: Deletion of an unnecessary check before iput() ...
Diffstat (limited to 'arch/x86/kernel/kprobes/ftrace.c')
-rw-r--r--arch/x86/kernel/kprobes/ftrace.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c
index 717b02a22e67..5f8f0b3cc674 100644
--- a/arch/x86/kernel/kprobes/ftrace.c
+++ b/arch/x86/kernel/kprobes/ftrace.c
@@ -27,7 +27,7 @@
27 27
28static nokprobe_inline 28static nokprobe_inline
29int __skip_singlestep(struct kprobe *p, struct pt_regs *regs, 29int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
30 struct kprobe_ctlblk *kcb) 30 struct kprobe_ctlblk *kcb, unsigned long orig_ip)
31{ 31{
32 /* 32 /*
33 * Emulate singlestep (and also recover regs->ip) 33 * Emulate singlestep (and also recover regs->ip)
@@ -39,6 +39,8 @@ int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
39 p->post_handler(p, regs, 0); 39 p->post_handler(p, regs, 0);
40 } 40 }
41 __this_cpu_write(current_kprobe, NULL); 41 __this_cpu_write(current_kprobe, NULL);
42 if (orig_ip)
43 regs->ip = orig_ip;
42 return 1; 44 return 1;
43} 45}
44 46
@@ -46,7 +48,7 @@ int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
46 struct kprobe_ctlblk *kcb) 48 struct kprobe_ctlblk *kcb)
47{ 49{
48 if (kprobe_ftrace(p)) 50 if (kprobe_ftrace(p))
49 return __skip_singlestep(p, regs, kcb); 51 return __skip_singlestep(p, regs, kcb, 0);
50 else 52 else
51 return 0; 53 return 0;
52} 54}
@@ -71,13 +73,14 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
71 if (kprobe_running()) { 73 if (kprobe_running()) {
72 kprobes_inc_nmissed_count(p); 74 kprobes_inc_nmissed_count(p);
73 } else { 75 } else {
76 unsigned long orig_ip = regs->ip;
74 /* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */ 77 /* Kprobe handler expects regs->ip = ip + 1 as breakpoint hit */
75 regs->ip = ip + sizeof(kprobe_opcode_t); 78 regs->ip = ip + sizeof(kprobe_opcode_t);
76 79
77 __this_cpu_write(current_kprobe, p); 80 __this_cpu_write(current_kprobe, p);
78 kcb->kprobe_status = KPROBE_HIT_ACTIVE; 81 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
79 if (!p->pre_handler || !p->pre_handler(p, regs)) 82 if (!p->pre_handler || !p->pre_handler(p, regs))
80 __skip_singlestep(p, regs, kcb); 83 __skip_singlestep(p, regs, kcb, orig_ip);
81 /* 84 /*
82 * If pre_handler returns !0, it sets regs->ip and 85 * If pre_handler returns !0, it sets regs->ip and
83 * resets current kprobe. 86 * resets current kprobe.