aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/kprobes.c
diff options
context:
space:
mode:
authorAnanth N Mavinakayanahalli <ananth@in.ibm.com>2005-11-07 04:00:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:46 -0500
commit991a51d83a3d9bebfafdd1e692cf310899d60791 (patch)
tree4cc6eaa2a868838e59c7737da9868f2358f2bb19 /arch/ia64/kernel/kprobes.c
parent3516a46042508a495fac13c2e73530d936ebe015 (diff)
[PATCH] Kprobes: Use RCU for (un)register synchronization - arch changes
Changes to the arch kprobes infrastructure to take advantage of the locking changes introduced by usage of RCU for synchronization. All handlers are now run without any locks held, so they have to be re-entrant or provide their own synchronization. Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> 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 'arch/ia64/kernel/kprobes.c')
-rw-r--r--arch/ia64/kernel/kprobes.c16
1 files changed, 6 insertions, 10 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 17e70b1b8d7..fddbac32d44 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -26,7 +26,6 @@
26#include <linux/config.h> 26#include <linux/config.h>
27#include <linux/kprobes.h> 27#include <linux/kprobes.h>
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/spinlock.h>
30#include <linux/string.h> 29#include <linux/string.h>
31#include <linux/slab.h> 30#include <linux/slab.h>
32#include <linux/preempt.h> 31#include <linux/preempt.h>
@@ -343,10 +342,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
343 struct kretprobe_instance *ri = NULL; 342 struct kretprobe_instance *ri = NULL;
344 struct hlist_head *head; 343 struct hlist_head *head;
345 struct hlist_node *node, *tmp; 344 struct hlist_node *node, *tmp;
346 unsigned long orig_ret_address = 0; 345 unsigned long flags, orig_ret_address = 0;
347 unsigned long trampoline_address = 346 unsigned long trampoline_address =
348 ((struct fnptr *)kretprobe_trampoline)->ip; 347 ((struct fnptr *)kretprobe_trampoline)->ip;
349 348
349 spin_lock_irqsave(&kretprobe_lock, flags);
350 head = kretprobe_inst_table_head(current); 350 head = kretprobe_inst_table_head(current);
351 351
352 /* 352 /*
@@ -386,7 +386,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
386 regs->cr_iip = orig_ret_address; 386 regs->cr_iip = orig_ret_address;
387 387
388 reset_current_kprobe(); 388 reset_current_kprobe();
389 unlock_kprobes(); 389 spin_unlock_irqrestore(&kretprobe_lock, flags);
390 preempt_enable_no_resched(); 390 preempt_enable_no_resched();
391 391
392 /* 392 /*
@@ -397,6 +397,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
397 return 1; 397 return 1;
398} 398}
399 399
400/* Called with kretprobe_lock held */
400void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 401void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
401 struct pt_regs *regs) 402 struct pt_regs *regs)
402{ 403{
@@ -612,7 +613,6 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
612 if ((kcb->kprobe_status == KPROBE_HIT_SS) && 613 if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
613 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { 614 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
614 ia64_psr(regs)->ss = 0; 615 ia64_psr(regs)->ss = 0;
615 unlock_kprobes();
616 goto no_kprobe; 616 goto no_kprobe;
617 } 617 }
618 /* We have reentered the pre_kprobe_handler(), since 618 /* We have reentered the pre_kprobe_handler(), since
@@ -641,10 +641,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
641 } 641 }
642 } 642 }
643 643
644 lock_kprobes();
645 p = get_kprobe(addr); 644 p = get_kprobe(addr);
646 if (!p) { 645 if (!p) {
647 unlock_kprobes();
648 if (!is_ia64_break_inst(regs)) { 646 if (!is_ia64_break_inst(regs)) {
649 /* 647 /*
650 * The breakpoint instruction was removed right 648 * The breakpoint instruction was removed right
@@ -707,7 +705,6 @@ static int __kprobes post_kprobes_handler(struct pt_regs *regs)
707 goto out; 705 goto out;
708 } 706 }
709 reset_current_kprobe(); 707 reset_current_kprobe();
710 unlock_kprobes();
711 708
712out: 709out:
713 preempt_enable_no_resched(); 710 preempt_enable_no_resched();
@@ -728,7 +725,6 @@ static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
728 if (kcb->kprobe_status & KPROBE_HIT_SS) { 725 if (kcb->kprobe_status & KPROBE_HIT_SS) {
729 resume_execution(cur, regs); 726 resume_execution(cur, regs);
730 reset_current_kprobe(); 727 reset_current_kprobe();
731 unlock_kprobes();
732 preempt_enable_no_resched(); 728 preempt_enable_no_resched();
733 } 729 }
734 730
@@ -741,7 +737,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
741 struct die_args *args = (struct die_args *)data; 737 struct die_args *args = (struct die_args *)data;
742 int ret = NOTIFY_DONE; 738 int ret = NOTIFY_DONE;
743 739
744 preempt_disable(); 740 rcu_read_lock();
745 switch(val) { 741 switch(val) {
746 case DIE_BREAK: 742 case DIE_BREAK:
747 if (pre_kprobes_handler(args)) 743 if (pre_kprobes_handler(args))
@@ -757,7 +753,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
757 default: 753 default:
758 break; 754 break;
759 } 755 }
760 preempt_enable(); 756 rcu_read_unlock();
761 return ret; 757 return ret;
762} 758}
763 759