Commit 26b31c1908e02a316edfba08080373342e662c14

Authored by Masami Hiramatsu
Committed by Linus Torvalds
1 parent 4a296e07c3

kprobes: add (un)register_jprobes for batch registration

Introduce unregister_/register_jprobes() for jprobe batch registration.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Cc: Shaohua Li <shaohua.li@intel.com>
Cc: David Miller <davem@davemloft.net>
Cc: "Frank Ch. Eigler" <fche@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 65 additions and 9 deletions Side-by-side Diff

include/linux/kprobes.h
... ... @@ -240,6 +240,8 @@
240 240 int longjmp_break_handler(struct kprobe *, struct pt_regs *);
241 241 int register_jprobe(struct jprobe *p);
242 242 void unregister_jprobe(struct jprobe *p);
  243 +int register_jprobes(struct jprobe **jps, int num);
  244 +void unregister_jprobes(struct jprobe **jps, int num);
243 245 void jprobe_return(void);
244 246 unsigned long arch_deref_entry_point(void *);
245 247  
246 248  
... ... @@ -279,7 +281,14 @@
279 281 {
280 282 return -ENOSYS;
281 283 }
  284 +static inline int register_jprobes(struct jprobe **jps, int num)
  285 +{
  286 + return -ENOSYS;
  287 +}
282 288 static inline void unregister_jprobe(struct jprobe *p)
  289 +{
  290 +}
  291 +static inline void unregister_jprobes(struct jprobe **jps, int num)
283 292 {
284 293 }
285 294 static inline void jprobe_return(void)
... ... @@ -755,26 +755,71 @@
755 755 return (unsigned long)entry;
756 756 }
757 757  
758   -int __kprobes register_jprobe(struct jprobe *jp)
  758 +static int __register_jprobes(struct jprobe **jps, int num,
  759 + unsigned long called_from)
759 760 {
760   - unsigned long addr = arch_deref_entry_point(jp->entry);
  761 + struct jprobe *jp;
  762 + int ret = 0, i;
761 763  
762   - if (!kernel_text_address(addr))
  764 + if (num <= 0)
763 765 return -EINVAL;
  766 + for (i = 0; i < num; i++) {
  767 + unsigned long addr;
  768 + jp = jps[i];
  769 + addr = arch_deref_entry_point(jp->entry);
764 770  
765   - /* Todo: Verify probepoint is a function entry point */
766   - jp->kp.pre_handler = setjmp_pre_handler;
767   - jp->kp.break_handler = longjmp_break_handler;
  771 + if (!kernel_text_address(addr))
  772 + ret = -EINVAL;
  773 + else {
  774 + /* Todo: Verify probepoint is a function entry point */
  775 + jp->kp.pre_handler = setjmp_pre_handler;
  776 + jp->kp.break_handler = longjmp_break_handler;
  777 + ret = __register_kprobe(&jp->kp, called_from);
  778 + }
  779 + if (ret < 0 && i > 0) {
  780 + unregister_jprobes(jps, i);
  781 + break;
  782 + }
  783 + }
  784 + return ret;
  785 +}
768 786  
769   - return __register_kprobe(&jp->kp,
  787 +int __kprobes register_jprobe(struct jprobe *jp)
  788 +{
  789 + return __register_jprobes(&jp, 1,
770 790 (unsigned long)__builtin_return_address(0));
771 791 }
772 792  
773 793 void __kprobes unregister_jprobe(struct jprobe *jp)
774 794 {
775   - unregister_kprobe(&jp->kp);
  795 + unregister_jprobes(&jp, 1);
776 796 }
777 797  
  798 +int __kprobes register_jprobes(struct jprobe **jps, int num)
  799 +{
  800 + return __register_jprobes(jps, num,
  801 + (unsigned long)__builtin_return_address(0));
  802 +}
  803 +
  804 +void __kprobes unregister_jprobes(struct jprobe **jps, int num)
  805 +{
  806 + int i;
  807 +
  808 + if (num <= 0)
  809 + return;
  810 + mutex_lock(&kprobe_mutex);
  811 + for (i = 0; i < num; i++)
  812 + if (__unregister_kprobe_top(&jps[i]->kp) < 0)
  813 + jps[i]->kp.addr = NULL;
  814 + mutex_unlock(&kprobe_mutex);
  815 +
  816 + synchronize_sched();
  817 + for (i = 0; i < num; i++) {
  818 + if (jps[i]->kp.addr)
  819 + __unregister_kprobe_bottom(&jps[i]->kp);
  820 + }
  821 +}
  822 +
778 823 #ifdef CONFIG_KRETPROBES
779 824 /*
780 825 * This kprobe pre_handler is registered with every kretprobe. When probe
... ... @@ -1236,6 +1281,8 @@
1236 1281 EXPORT_SYMBOL_GPL(unregister_kprobes);
1237 1282 EXPORT_SYMBOL_GPL(register_jprobe);
1238 1283 EXPORT_SYMBOL_GPL(unregister_jprobe);
  1284 +EXPORT_SYMBOL_GPL(register_jprobes);
  1285 +EXPORT_SYMBOL_GPL(unregister_jprobes);
1239 1286 #ifdef CONFIG_KPROBES
1240 1287 EXPORT_SYMBOL_GPL(jprobe_return);
1241 1288 #endif