[IMPROVE] Kernel retprobes without exceptions
authorDmitry Kovalenko <d.kovalenko@samsung.com>
Mon, 10 Jun 2013 09:29:46 +0000 (13:29 +0400)
committerDmitry Kovalenko <d.kovalenko@samsung.com>
Mon, 10 Jun 2013 09:29:46 +0000 (13:29 +0400)
kprobe/arch/asm-arm/dbi_kprobes.c
kprobe/arch/asm-arm/dbi_kprobes_arm.S
kprobe/arch/asm-arm/dbi_kprobes_arm.h
kprobe/arch/dbi_kprobes.h
kprobe/dbi_kprobes.c

index 68f17fb..219e0d3 100644 (file)
@@ -1438,6 +1438,7 @@ int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs)
        struct hlist_node *node, *tmp;
        unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address = (unsigned long) &kretprobe_trampoline;
+       unsigned long ret = 1;
 
        struct kretprobe *crp = NULL;
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk ();
@@ -1509,7 +1510,9 @@ int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs)
        if ((ri->rp && ri->rp->kp.tgid) || (ri->rp2 && ri->rp2->kp.tgid))
                BUG_ON (trampoline_address == (unsigned long) &kretprobe_trampoline);
 
-       regs->uregs[14] = orig_ret_address;
+       if (p && p->tgid)
+               regs->uregs[14] = orig_ret_address;
+
        DBPRINTF ("regs->uregs[14] = 0x%lx\n", regs->uregs[14]);
        DBPRINTF ("regs->uregs[15] = 0x%lx\n", regs->uregs[15]);
 
@@ -1517,8 +1520,7 @@ int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs)
        {
                regs->uregs[15] = orig_ret_address;
        }else{
-               if (!thumb_mode( regs )) regs->uregs[15] += 4;
-               else regs->uregs[15] += 2;
+               ret = (void *)orig_ret_address;
        }
 
        DBPRINTF ("regs->uregs[15] = 0x%lx\n", regs->uregs[15]);
@@ -1596,7 +1598,20 @@ int trampoline_probe_handler (struct kprobe *p, struct pt_regs *regs)
         * to run (and have re-enabled preemption)
         */
 
-       return 1;
+       return ret;
+}
+
+void __naked kretprobe_trampoline(void)
+{
+       __asm__ __volatile__ (
+               "stmdb  sp!, {r0 - r11}         \n\t"
+               "mov    r1, sp                  \n\t"
+               "mov    r0, #0                  \n\t"
+               "bl     trampoline_probe_handler\n\t"
+               "mov    lr, r0                  \n\t"
+               "ldmia  sp!, {r0 - r11}         \n\t"
+               "bx     lr                      \n\t"
+               : : : "memory");
 }
 
 void  __arch_prepare_kretprobe (struct kretprobe *rp, struct pt_regs *regs)
@@ -1706,10 +1721,6 @@ int __init arch_init_kprobes (void)
        do_kpro(&undef_ho_k);
        do_kpro(&undef_ho_u);
        do_kpro(&undef_ho_u_t);
-       if ((ret = dbi_register_kprobe (&trampoline_p)) != 0) {
-               //dbi_unregister_jprobe(&do_exit_p, 0);
-               return ret;
-       }
        return ret;
 }
 
index 73199c9..5b4c7bc 100644 (file)
@@ -4,14 +4,6 @@
  *     - When the probed function returns, this probe
  *             causes the handlers to fire
  */
-               .global kretprobe_trampoline
-
-kretprobe_trampoline:
-               nop
-               nop
-               mov pc, r14
-
-
 
                .global gen_insn_execbuf
 gen_insn_execbuf:
index d9d1890..914303a 100644 (file)
@@ -1,3 +1,2 @@
-void kretprobe_trampoline(void);
 void gen_insn_execbuf(void);
 void pc_dep_insn_execbuf(void);
index b1237e1..737d4db 100644 (file)
@@ -48,7 +48,7 @@
  * 2010         Ekaterina Gorelkina <e.gorelkina@samsung.com>: redesign module for separating core and arch parts
  *
  */
-
+#include <linux/compiler.h>
 
 #define REENTER
 
@@ -64,7 +64,7 @@ struct prev_kprobe {
        unsigned long status;
 };
 
-void kretprobe_trampoline (void);
+void __naked kretprobe_trampoline (void);
 
 extern void __arch_prepare_kretprobe (struct kretprobe *rp, struct pt_regs *regs);
 extern int arch_prepare_kprobe (struct kprobe *p);
index c0519f2..9d66ac1 100644 (file)
@@ -767,12 +767,12 @@ void dbi_unregister_kretprobe (struct kretprobe *rp)
                sched_rp = NULL;
 
        while ((ri = get_used_rp_inst (rp)) != NULL) {
-               if (dbi_disarm_krp_inst(ri) == 0)
-                       recycle_rp_inst(ri);
-               else
-                       panic("%s (%d/%d): cannot disarm krp instance (%08lx)",
+               if (!dbi_disarm_krp_inst(ri)) {
+                       printk("%s (%d/%d): cannot disarm krp instance (%08lx)\n",
                                        ri->task->comm, ri->task->tgid, ri->task->pid,
                                        (unsigned long)rp->kp.addr);
+               }
+               recycle_rp_inst(ri);
        }
 
        spin_unlock_irqrestore (&kretprobe_lock, flags);