aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
authorAnil S Keshavamurthy <anil.s.keshavamurthy@intel.com>2006-06-26 03:25:29 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:22 -0400
commite6f47f978bcd5413fff610613b18e9e0eab9bc1b (patch)
treebf9e698cb76a0e958a8c9157fba74fb6d8255298 /kernel/kprobes.c
parent3d5631e0631a11633c649bc995a6537ec21b67b4 (diff)
[PATCH] Notify page fault call chain
With this patch Kprobes now registers for page fault notifications only when their is an active probe registered. Once all the active probes are unregistered their is no need to be notified of page faults and kprobes unregisters itself from the page fault notifications. Hence we will have ZERO side effects when no probes are active. Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 507f26e7ae7c..64aab081153b 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -47,11 +47,17 @@
47 47
48static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; 48static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
49static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; 49static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
50static atomic_t kprobe_count;
50 51
51DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */ 52DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
52DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ 53DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
53static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; 54static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
54 55
56static struct notifier_block kprobe_page_fault_nb = {
57 .notifier_call = kprobe_exceptions_notify,
58 .priority = 0x7fffffff /* we need to notified first */
59};
60
55#ifdef __ARCH_WANT_KPROBES_INSN_SLOT 61#ifdef __ARCH_WANT_KPROBES_INSN_SLOT
56/* 62/*
57 * kprobe->ainsn.insn points to the copy of the instruction to be 63 * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -465,6 +471,8 @@ static int __kprobes __register_kprobe(struct kprobe *p,
465 old_p = get_kprobe(p->addr); 471 old_p = get_kprobe(p->addr);
466 if (old_p) { 472 if (old_p) {
467 ret = register_aggr_kprobe(old_p, p); 473 ret = register_aggr_kprobe(old_p, p);
474 if (!ret)
475 atomic_inc(&kprobe_count);
468 goto out; 476 goto out;
469 } 477 }
470 478
@@ -475,6 +483,10 @@ static int __kprobes __register_kprobe(struct kprobe *p,
475 hlist_add_head_rcu(&p->hlist, 483 hlist_add_head_rcu(&p->hlist,
476 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); 484 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
477 485
486 if (atomic_add_return(1, &kprobe_count) == \
487 (ARCH_INACTIVE_KPROBE_COUNT + 1))
488 register_page_fault_notifier(&kprobe_page_fault_nb);
489
478 arch_arm_kprobe(p); 490 arch_arm_kprobe(p);
479 491
480out: 492out:
@@ -553,6 +565,16 @@ valid_p:
553 } 565 }
554 mutex_unlock(&kprobe_mutex); 566 mutex_unlock(&kprobe_mutex);
555 } 567 }
568
569 /* Call unregister_page_fault_notifier()
570 * if no probes are active
571 */
572 mutex_lock(&kprobe_mutex);
573 if (atomic_add_return(-1, &kprobe_count) == \
574 ARCH_INACTIVE_KPROBE_COUNT)
575 unregister_page_fault_notifier(&kprobe_page_fault_nb);
576 mutex_unlock(&kprobe_mutex);
577 return;
556} 578}
557 579
558static struct notifier_block kprobe_exceptions_nb = { 580static struct notifier_block kprobe_exceptions_nb = {
@@ -560,10 +582,6 @@ static struct notifier_block kprobe_exceptions_nb = {
560 .priority = 0x7fffffff /* we need to be notified first */ 582 .priority = 0x7fffffff /* we need to be notified first */
561}; 583};
562 584
563static struct notifier_block kprobe_page_fault_nb = {
564 .notifier_call = kprobe_exceptions_notify,
565 .priority = 0x7fffffff /* we need to notified first */
566};
567 585
568int __kprobes register_jprobe(struct jprobe *jp) 586int __kprobes register_jprobe(struct jprobe *jp)
569{ 587{
@@ -673,14 +691,12 @@ static int __init init_kprobes(void)
673 INIT_HLIST_HEAD(&kprobe_table[i]); 691 INIT_HLIST_HEAD(&kprobe_table[i]);
674 INIT_HLIST_HEAD(&kretprobe_inst_table[i]); 692 INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
675 } 693 }
694 atomic_set(&kprobe_count, 0);
676 695
677 err = arch_init_kprobes(); 696 err = arch_init_kprobes();
678 if (!err) 697 if (!err)
679 err = register_die_notifier(&kprobe_exceptions_nb); 698 err = register_die_notifier(&kprobe_exceptions_nb);
680 699
681 if (!err)
682 err = register_page_fault_notifier(&kprobe_page_fault_nb);
683
684 return err; 700 return err;
685} 701}
686 702