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.c126
1 files changed, 69 insertions, 57 deletions
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 471086b808a4..96736a119c91 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>
@@ -38,13 +37,8 @@
38 37
39extern void jprobe_inst_return(void); 38extern void jprobe_inst_return(void);
40 39
41/* kprobe_status settings */ 40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42#define KPROBE_HIT_ACTIVE 0x00000001 41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43#define KPROBE_HIT_SS 0x00000002
44
45static struct kprobe *current_kprobe, *kprobe_prev;
46static unsigned long kprobe_status, kprobe_status_prev;
47static struct pt_regs jprobe_saved_regs;
48 42
49enum instruction_type {A, I, M, F, B, L, X, u}; 43enum instruction_type {A, I, M, F, B, L, X, u};
50static enum instruction_type bundle_encoding[32][3] = { 44static enum instruction_type bundle_encoding[32][3] = {
@@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
313 return 0; 307 return 0;
314} 308}
315 309
316static inline void save_previous_kprobe(void) 310static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
317{ 311{
318 kprobe_prev = current_kprobe; 312 kcb->prev_kprobe.kp = kprobe_running();
319 kprobe_status_prev = kprobe_status; 313 kcb->prev_kprobe.status = kcb->kprobe_status;
320} 314}
321 315
322static inline void restore_previous_kprobe(void) 316static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
323{ 317{
324 current_kprobe = kprobe_prev; 318 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
325 kprobe_status = kprobe_status_prev; 319 kcb->kprobe_status = kcb->prev_kprobe.status;
326} 320}
327 321
328static inline void set_current_kprobe(struct kprobe *p) 322static inline void set_current_kprobe(struct kprobe *p,
323 struct kprobe_ctlblk *kcb)
329{ 324{
330 current_kprobe = p; 325 __get_cpu_var(current_kprobe) = p;
331} 326}
332 327
333static void kretprobe_trampoline(void) 328static void kretprobe_trampoline(void)
@@ -347,10 +342,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
347 struct kretprobe_instance *ri = NULL; 342 struct kretprobe_instance *ri = NULL;
348 struct hlist_head *head; 343 struct hlist_head *head;
349 struct hlist_node *node, *tmp; 344 struct hlist_node *node, *tmp;
350 unsigned long orig_ret_address = 0; 345 unsigned long flags, orig_ret_address = 0;
351 unsigned long trampoline_address = 346 unsigned long trampoline_address =
352 ((struct fnptr *)kretprobe_trampoline)->ip; 347 ((struct fnptr *)kretprobe_trampoline)->ip;
353 348
349 spin_lock_irqsave(&kretprobe_lock, flags);
354 head = kretprobe_inst_table_head(current); 350 head = kretprobe_inst_table_head(current);
355 351
356 /* 352 /*
@@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
389 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 385 BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
390 regs->cr_iip = orig_ret_address; 386 regs->cr_iip = orig_ret_address;
391 387
392 unlock_kprobes(); 388 reset_current_kprobe();
389 spin_unlock_irqrestore(&kretprobe_lock, flags);
393 preempt_enable_no_resched(); 390 preempt_enable_no_resched();
394 391
395 /* 392 /*
396 * By returning a non-zero value, we are telling 393 * By returning a non-zero value, we are telling
397 * kprobe_handler() that we have handled unlocking 394 * kprobe_handler() that we don't want the post_handler
398 * and re-enabling preemption. 395 * to run (and have re-enabled preemption)
399 */ 396 */
400 return 1; 397 return 1;
401} 398}
402 399
400/* Called with kretprobe_lock held */
403void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, 401void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
404 struct pt_regs *regs) 402 struct pt_regs *regs)
405{ 403{
@@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
606 int ret = 0; 604 int ret = 0;
607 struct pt_regs *regs = args->regs; 605 struct pt_regs *regs = args->regs;
608 kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs); 606 kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
607 struct kprobe_ctlblk *kcb;
609 608
609 /*
610 * We don't want to be preempted for the entire
611 * duration of kprobe processing
612 */
610 preempt_disable(); 613 preempt_disable();
614 kcb = get_kprobe_ctlblk();
611 615
612 /* Handle recursion cases */ 616 /* Handle recursion cases */
613 if (kprobe_running()) { 617 if (kprobe_running()) {
614 p = get_kprobe(addr); 618 p = get_kprobe(addr);
615 if (p) { 619 if (p) {
616 if ( (kprobe_status == KPROBE_HIT_SS) && 620 if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
617 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { 621 (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
618 ia64_psr(regs)->ss = 0; 622 ia64_psr(regs)->ss = 0;
619 unlock_kprobes();
620 goto no_kprobe; 623 goto no_kprobe;
621 } 624 }
622 /* We have reentered the pre_kprobe_handler(), since 625 /* We have reentered the pre_kprobe_handler(), since
@@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
625 * just single step on the instruction of the new probe 628 * just single step on the instruction of the new probe
626 * without calling any user handlers. 629 * without calling any user handlers.
627 */ 630 */
628 save_previous_kprobe(); 631 save_previous_kprobe(kcb);
629 set_current_kprobe(p); 632 set_current_kprobe(p, kcb);
630 p->nmissed++; 633 p->nmissed++;
631 prepare_ss(p, regs); 634 prepare_ss(p, regs);
632 kprobe_status = KPROBE_REENTER; 635 kcb->kprobe_status = KPROBE_REENTER;
633 return 1; 636 return 1;
634 } else if (args->err == __IA64_BREAK_JPROBE) { 637 } else if (args->err == __IA64_BREAK_JPROBE) {
635 /* 638 /*
636 * jprobe instrumented function just completed 639 * jprobe instrumented function just completed
637 */ 640 */
638 p = current_kprobe; 641 p = __get_cpu_var(current_kprobe);
639 if (p->break_handler && p->break_handler(p, regs)) { 642 if (p->break_handler && p->break_handler(p, regs)) {
640 goto ss_probe; 643 goto ss_probe;
641 } 644 }
@@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
645 } 648 }
646 } 649 }
647 650
648 lock_kprobes();
649 p = get_kprobe(addr); 651 p = get_kprobe(addr);
650 if (!p) { 652 if (!p) {
651 unlock_kprobes();
652 if (!is_ia64_break_inst(regs)) { 653 if (!is_ia64_break_inst(regs)) {
653 /* 654 /*
654 * The breakpoint instruction was removed right 655 * The breakpoint instruction was removed right
@@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
665 goto no_kprobe; 666 goto no_kprobe;
666 } 667 }
667 668
668 kprobe_status = KPROBE_HIT_ACTIVE; 669 set_current_kprobe(p, kcb);
669 set_current_kprobe(p); 670 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
670 671
671 if (p->pre_handler && p->pre_handler(p, regs)) 672 if (p->pre_handler && p->pre_handler(p, regs))
672 /* 673 /*
@@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
678 679
679ss_probe: 680ss_probe:
680 prepare_ss(p, regs); 681 prepare_ss(p, regs);
681 kprobe_status = KPROBE_HIT_SS; 682 kcb->kprobe_status = KPROBE_HIT_SS;
682 return 1; 683 return 1;
683 684
684no_kprobe: 685no_kprobe:
@@ -688,23 +689,25 @@ no_kprobe:
688 689
689static int __kprobes post_kprobes_handler(struct pt_regs *regs) 690static int __kprobes post_kprobes_handler(struct pt_regs *regs)
690{ 691{
691 if (!kprobe_running()) 692 struct kprobe *cur = kprobe_running();
693 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
694
695 if (!cur)
692 return 0; 696 return 0;
693 697
694 if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { 698 if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
695 kprobe_status = KPROBE_HIT_SSDONE; 699 kcb->kprobe_status = KPROBE_HIT_SSDONE;
696 current_kprobe->post_handler(current_kprobe, regs, 0); 700 cur->post_handler(cur, regs, 0);
697 } 701 }
698 702
699 resume_execution(current_kprobe, regs); 703 resume_execution(cur, regs);
700 704
701 /*Restore back the original saved kprobes variables and continue. */ 705 /*Restore back the original saved kprobes variables and continue. */
702 if (kprobe_status == KPROBE_REENTER) { 706 if (kcb->kprobe_status == KPROBE_REENTER) {
703 restore_previous_kprobe(); 707 restore_previous_kprobe(kcb);
704 goto out; 708 goto out;
705 } 709 }
706 710 reset_current_kprobe();
707 unlock_kprobes();
708 711
709out: 712out:
710 preempt_enable_no_resched(); 713 preempt_enable_no_resched();
@@ -713,16 +716,15 @@ out:
713 716
714static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) 717static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
715{ 718{
716 if (!kprobe_running()) 719 struct kprobe *cur = kprobe_running();
717 return 0; 720 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
718 721
719 if (current_kprobe->fault_handler && 722 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
720 current_kprobe->fault_handler(current_kprobe, regs, trapnr))
721 return 1; 723 return 1;
722 724
723 if (kprobe_status & KPROBE_HIT_SS) { 725 if (kcb->kprobe_status & KPROBE_HIT_SS) {
724 resume_execution(current_kprobe, regs); 726 resume_execution(cur, regs);
725 unlock_kprobes(); 727 reset_current_kprobe();
726 preempt_enable_no_resched(); 728 preempt_enable_no_resched();
727 } 729 }
728 730
@@ -733,31 +735,38 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
733 unsigned long val, void *data) 735 unsigned long val, void *data)
734{ 736{
735 struct die_args *args = (struct die_args *)data; 737 struct die_args *args = (struct die_args *)data;
738 int ret = NOTIFY_DONE;
739
736 switch(val) { 740 switch(val) {
737 case DIE_BREAK: 741 case DIE_BREAK:
738 if (pre_kprobes_handler(args)) 742 if (pre_kprobes_handler(args))
739 return NOTIFY_STOP; 743 ret = NOTIFY_STOP;
740 break; 744 break;
741 case DIE_SS: 745 case DIE_SS:
742 if (post_kprobes_handler(args->regs)) 746 if (post_kprobes_handler(args->regs))
743 return NOTIFY_STOP; 747 ret = NOTIFY_STOP;
744 break; 748 break;
745 case DIE_PAGE_FAULT: 749 case DIE_PAGE_FAULT:
746 if (kprobes_fault_handler(args->regs, args->trapnr)) 750 /* kprobe_running() needs smp_processor_id() */
747 return NOTIFY_STOP; 751 preempt_disable();
752 if (kprobe_running() &&
753 kprobes_fault_handler(args->regs, args->trapnr))
754 ret = NOTIFY_STOP;
755 preempt_enable();
748 default: 756 default:
749 break; 757 break;
750 } 758 }
751 return NOTIFY_DONE; 759 return ret;
752} 760}
753 761
754int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 762int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
755{ 763{
756 struct jprobe *jp = container_of(p, struct jprobe, kp); 764 struct jprobe *jp = container_of(p, struct jprobe, kp);
757 unsigned long addr = ((struct fnptr *)(jp->entry))->ip; 765 unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
766 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
758 767
759 /* save architectural state */ 768 /* save architectural state */
760 jprobe_saved_regs = *regs; 769 kcb->jprobe_saved_regs = *regs;
761 770
762 /* after rfi, execute the jprobe instrumented function */ 771 /* after rfi, execute the jprobe instrumented function */
763 regs->cr_iip = addr & ~0xFULL; 772 regs->cr_iip = addr & ~0xFULL;
@@ -775,7 +784,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
775 784
776int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 785int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
777{ 786{
778 *regs = jprobe_saved_regs; 787 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
788
789 *regs = kcb->jprobe_saved_regs;
790 preempt_enable_no_resched();
779 return 1; 791 return 1;
780} 792}
781 793