diff options
Diffstat (limited to 'arch/ia64/kernel/kprobes.c')
-rw-r--r-- | arch/ia64/kernel/kprobes.c | 16 |
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 */ | ||
400 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | 401 | void __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 | ||
712 | out: | 709 | out: |
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 | ||