diff options
| author | Masami Hiramatsu <mhiramat@redhat.com> | 2008-04-28 05:14:29 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:32 -0400 |
| commit | 26b31c1908e02a316edfba08080373342e662c14 (patch) | |
| tree | d9140d82ccc9ed3faa2062549d0e7471da9c9b29 /kernel | |
| parent | 4a296e07c3a410c09b9155da4c2fa84a07964f38 (diff) | |
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>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kprobes.c | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 5e3144ad9b64..1e0250cb9486 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -755,24 +755,69 @@ unsigned long __weak arch_deref_entry_point(void *entry) | |||
| 755 | return (unsigned long)entry; | 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 | return -EINVAL; | 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); | ||
| 770 | |||
| 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 | } | ||
| 764 | 786 | ||
| 765 | /* Todo: Verify probepoint is a function entry point */ | 787 | int __kprobes register_jprobe(struct jprobe *jp) |
| 766 | jp->kp.pre_handler = setjmp_pre_handler; | 788 | { |
| 767 | jp->kp.break_handler = longjmp_break_handler; | 789 | return __register_jprobes(&jp, 1, |
| 768 | |||
| 769 | return __register_kprobe(&jp->kp, | ||
| 770 | (unsigned long)__builtin_return_address(0)); | 790 | (unsigned long)__builtin_return_address(0)); |
| 771 | } | 791 | } |
| 772 | 792 | ||
| 773 | void __kprobes unregister_jprobe(struct jprobe *jp) | 793 | void __kprobes unregister_jprobe(struct jprobe *jp) |
| 774 | { | 794 | { |
| 775 | unregister_kprobe(&jp->kp); | 795 | unregister_jprobes(&jp, 1); |
| 796 | } | ||
| 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 | } | ||
| 776 | } | 821 | } |
| 777 | 822 | ||
| 778 | #ifdef CONFIG_KRETPROBES | 823 | #ifdef CONFIG_KRETPROBES |
| @@ -1236,6 +1281,8 @@ EXPORT_SYMBOL_GPL(register_kprobes); | |||
| 1236 | EXPORT_SYMBOL_GPL(unregister_kprobes); | 1281 | EXPORT_SYMBOL_GPL(unregister_kprobes); |
| 1237 | EXPORT_SYMBOL_GPL(register_jprobe); | 1282 | EXPORT_SYMBOL_GPL(register_jprobe); |
| 1238 | EXPORT_SYMBOL_GPL(unregister_jprobe); | 1283 | EXPORT_SYMBOL_GPL(unregister_jprobe); |
| 1284 | EXPORT_SYMBOL_GPL(register_jprobes); | ||
| 1285 | EXPORT_SYMBOL_GPL(unregister_jprobes); | ||
| 1239 | #ifdef CONFIG_KPROBES | 1286 | #ifdef CONFIG_KPROBES |
| 1240 | EXPORT_SYMBOL_GPL(jprobe_return); | 1287 | EXPORT_SYMBOL_GPL(jprobe_return); |
| 1241 | #endif | 1288 | #endif |
