aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/kprobes.c
diff options
context:
space:
mode:
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 17e70b1b8d79..fddbac32d44a 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