Commit f47cd9b553aaada602449204513b5a5b29cba263

Authored by Abhishek Sagar
Committed by Linus Torvalds
1 parent 5beec4aa2a

kprobes: kretprobe user entry-handler

Provide support to add an optional user defined callback to be run at
function entry of a kretprobe'd function.  Also modify the kprobe smoke
tests to include an entry-handler during the kretprobe sanity test.

Signed-off-by: Abhishek Sagar <sagar.abhishek@gmail.com>
Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Acked-by: Jim Keniston <jkenisto@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 94 additions and 15 deletions Side-by-side Diff

Documentation/kprobes.txt
... ... @@ -96,8 +96,10 @@
96 96 The jprobe will work in either case, so long as the handler's
97 97 prototype matches that of the probed function.
98 98  
99   -1.3 How Does a Return Probe Work?
  99 +1.3 Return Probes
100 100  
  101 +1.3.1 How Does a Return Probe Work?
  102 +
101 103 When you call register_kretprobe(), Kprobes establishes a kprobe at
102 104 the entry to the function. When the probed function is called and this
103 105 probe is hit, Kprobes saves a copy of the return address, and replaces
... ... @@ -107,9 +109,9 @@
107 109  
108 110 When the probed function executes its return instruction, control
109 111 passes to the trampoline and that probe is hit. Kprobes' trampoline
110   -handler calls the user-specified handler associated with the kretprobe,
111   -then sets the saved instruction pointer to the saved return address,
112   -and that's where execution resumes upon return from the trap.
  112 +handler calls the user-specified return handler associated with the
  113 +kretprobe, then sets the saved instruction pointer to the saved return
  114 +address, and that's where execution resumes upon return from the trap.
113 115  
114 116 While the probed function is executing, its return address is
115 117 stored in an object of type kretprobe_instance. Before calling
... ... @@ -131,6 +133,30 @@
131 133 time the probed function is entered but there is no kretprobe_instance
132 134 object available for establishing the return probe.
133 135  
  136 +1.3.2 Kretprobe entry-handler
  137 +
  138 +Kretprobes also provides an optional user-specified handler which runs
  139 +on function entry. This handler is specified by setting the entry_handler
  140 +field of the kretprobe struct. Whenever the kprobe placed by kretprobe at the
  141 +function entry is hit, the user-defined entry_handler, if any, is invoked.
  142 +If the entry_handler returns 0 (success) then a corresponding return handler
  143 +is guaranteed to be called upon function return. If the entry_handler
  144 +returns a non-zero error then Kprobes leaves the return address as is, and
  145 +the kretprobe has no further effect for that particular function instance.
  146 +
  147 +Multiple entry and return handler invocations are matched using the unique
  148 +kretprobe_instance object associated with them. Additionally, a user
  149 +may also specify per return-instance private data to be part of each
  150 +kretprobe_instance object. This is especially useful when sharing private
  151 +data between corresponding user entry and return handlers. The size of each
  152 +private data object can be specified at kretprobe registration time by
  153 +setting the data_size field of the kretprobe struct. This data can be
  154 +accessed through the data field of each kretprobe_instance object.
  155 +
  156 +In case probed function is entered but there is no kretprobe_instance
  157 +object available, then in addition to incrementing the nmissed count,
  158 +the user entry_handler invocation is also skipped.
  159 +
134 160 2. Architectures Supported
135 161  
136 162 Kprobes, jprobes, and return probes are implemented on the following
... ... @@ -274,6 +300,8 @@
274 300 - ret_addr: the return address
275 301 - rp: points to the corresponding kretprobe object
276 302 - task: points to the corresponding task struct
  303 +- data: points to per return-instance private data; see "Kretprobe
  304 + entry-handler" for details.
277 305  
278 306 The regs_return_value(regs) macro provides a simple abstraction to
279 307 extract the return value from the appropriate register as defined by
280 308  
281 309  
282 310  
283 311  
284 312  
285 313  
... ... @@ -556,23 +584,52 @@
556 584 #include <linux/kernel.h>
557 585 #include <linux/module.h>
558 586 #include <linux/kprobes.h>
  587 +#include <linux/ktime.h>
559 588  
  589 +/* per-instance private data */
  590 +struct my_data {
  591 + ktime_t entry_stamp;
  592 +};
  593 +
560 594 static const char *probed_func = "sys_open";
561 595  
562   -/* Return-probe handler: If the probed function fails, log the return value. */
563   -static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  596 +/* Timestamp function entry. */
  597 +static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
564 598 {
  599 + struct my_data *data;
  600 +
  601 + if(!current->mm)
  602 + return 1; /* skip kernel threads */
  603 +
  604 + data = (struct my_data *)ri->data;
  605 + data->entry_stamp = ktime_get();
  606 + return 0;
  607 +}
  608 +
  609 +/* If the probed function failed, log the return value and duration.
  610 + * Duration may turn out to be zero consistently, depending upon the
  611 + * granularity of time accounting on the platform. */
  612 +static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  613 +{
565 614 int retval = regs_return_value(regs);
  615 + struct my_data *data = (struct my_data *)ri->data;
  616 + s64 delta;
  617 + ktime_t now;
  618 +
566 619 if (retval < 0) {
567   - printk("%s returns %d\n", probed_func, retval);
  620 + now = ktime_get();
  621 + delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
  622 + printk("%s: return val = %d (duration = %lld ns)\n",
  623 + probed_func, retval, delta);
568 624 }
569 625 return 0;
570 626 }
571 627  
572 628 static struct kretprobe my_kretprobe = {
573   - .handler = ret_handler,
574   - /* Probe up to 20 instances concurrently. */
575   - .maxactive = 20
  629 + .handler = return_handler,
  630 + .entry_handler = entry_handler,
  631 + .data_size = sizeof(struct my_data),
  632 + .maxactive = 20, /* probe up to 20 instances concurrently */
576 633 };
577 634  
578 635 static int __init kretprobe_init(void)
... ... @@ -584,7 +641,7 @@
584 641 printk("register_kretprobe failed, returned %d\n", ret);
585 642 return -1;
586 643 }
587   - printk("Planted return probe at %p\n", my_kretprobe.kp.addr);
  644 + printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name);
588 645 return 0;
589 646 }
590 647  
... ... @@ -594,7 +651,7 @@
594 651 printk("kretprobe unregistered\n");
595 652 /* nmissed > 0 suggests that maxactive was set too low. */
596 653 printk("Missed probing %d instances of %s\n",
597   - my_kretprobe.nmissed, probed_func);
  654 + my_kretprobe.nmissed, probed_func);
598 655 }
599 656  
600 657 module_init(kretprobe_init)
include/linux/kprobes.h
... ... @@ -152,8 +152,10 @@
152 152 struct kretprobe {
153 153 struct kprobe kp;
154 154 kretprobe_handler_t handler;
  155 + kretprobe_handler_t entry_handler;
155 156 int maxactive;
156 157 int nmissed;
  158 + size_t data_size;
157 159 struct hlist_head free_instances;
158 160 struct hlist_head used_instances;
159 161 };
... ... @@ -164,6 +166,7 @@
164 166 struct kretprobe *rp;
165 167 kprobe_opcode_t *ret_addr;
166 168 struct task_struct *task;
  169 + char data[0];
167 170 };
168 171  
169 172 struct kretprobe_blackpoint {
... ... @@ -699,6 +699,12 @@
699 699 struct kretprobe_instance, uflist);
700 700 ri->rp = rp;
701 701 ri->task = current;
  702 +
  703 + if (rp->entry_handler && rp->entry_handler(ri, regs)) {
  704 + spin_unlock_irqrestore(&kretprobe_lock, flags);
  705 + return 0;
  706 + }
  707 +
702 708 arch_prepare_kretprobe(ri, regs);
703 709  
704 710 /* XXX(hch): why is there no hlist_move_head? */
... ... @@ -745,7 +751,8 @@
745 751 INIT_HLIST_HEAD(&rp->used_instances);
746 752 INIT_HLIST_HEAD(&rp->free_instances);
747 753 for (i = 0; i < rp->maxactive; i++) {
748   - inst = kmalloc(sizeof(struct kretprobe_instance), GFP_KERNEL);
  754 + inst = kmalloc(sizeof(struct kretprobe_instance) +
  755 + rp->data_size, GFP_KERNEL);
749 756 if (inst == NULL) {
750 757 free_rp_inst(rp);
751 758 return -ENOMEM;
kernel/test_kprobes.c
... ... @@ -135,6 +135,12 @@
135 135 #ifdef CONFIG_KRETPROBES
136 136 static u32 krph_val;
137 137  
  138 +static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  139 +{
  140 + krph_val = (rand1 / div_factor);
  141 + return 0;
  142 +}
  143 +
138 144 static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
139 145 {
140 146 unsigned long ret = regs_return_value(regs);
141 147  
142 148  
... ... @@ -144,13 +150,19 @@
144 150 printk(KERN_ERR "Kprobe smoke test failed: "
145 151 "incorrect value in kretprobe handler\n");
146 152 }
  153 + if (krph_val == 0) {
  154 + handler_errors++;
  155 + printk(KERN_ERR "Kprobe smoke test failed: "
  156 + "call to kretprobe entry handler failed\n");
  157 + }
147 158  
148   - krph_val = (rand1 / div_factor);
  159 + krph_val = rand1;
149 160 return 0;
150 161 }
151 162  
152 163 static struct kretprobe rp = {
153 164 .handler = return_handler,
  165 + .entry_handler = entry_handler,
154 166 .kp.symbol_name = "kprobe_target"
155 167 };
156 168  
... ... @@ -167,7 +179,7 @@
167 179  
168 180 ret = kprobe_target(rand1);
169 181 unregister_kretprobe(&rp);
170   - if (krph_val == 0) {
  182 + if (krph_val != rand1) {
171 183 printk(KERN_ERR "Kprobe smoke test failed: "
172 184 "kretprobe handler not called\n");
173 185 handler_errors++;