From: Dmitry Kovalenko Date: Mon, 10 Jun 2013 09:29:46 +0000 (+0400) Subject: [IMPROVE] Kernel retprobes without exceptions X-Git-Tag: Tizen_SDK_2.3~309^2~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f9fc82513d5ed46d099615b1c1ce37bc5b437c5;p=kernel%2Fswap-modules.git [IMPROVE] Kernel retprobes without exceptions --- diff --git a/kprobe/arch/asm-arm/dbi_kprobes.c b/kprobe/arch/asm-arm/dbi_kprobes.c index 68f17fb..219e0d3 100644 --- a/kprobe/arch/asm-arm/dbi_kprobes.c +++ b/kprobe/arch/asm-arm/dbi_kprobes.c @@ -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; } diff --git a/kprobe/arch/asm-arm/dbi_kprobes_arm.S b/kprobe/arch/asm-arm/dbi_kprobes_arm.S index 73199c9..5b4c7bc 100644 --- a/kprobe/arch/asm-arm/dbi_kprobes_arm.S +++ b/kprobe/arch/asm-arm/dbi_kprobes_arm.S @@ -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: diff --git a/kprobe/arch/asm-arm/dbi_kprobes_arm.h b/kprobe/arch/asm-arm/dbi_kprobes_arm.h index d9d1890..914303a 100644 --- a/kprobe/arch/asm-arm/dbi_kprobes_arm.h +++ b/kprobe/arch/asm-arm/dbi_kprobes_arm.h @@ -1,3 +1,2 @@ -void kretprobe_trampoline(void); void gen_insn_execbuf(void); void pc_dep_insn_execbuf(void); diff --git a/kprobe/arch/dbi_kprobes.h b/kprobe/arch/dbi_kprobes.h index b1237e1..737d4db 100644 --- a/kprobe/arch/dbi_kprobes.h +++ b/kprobe/arch/dbi_kprobes.h @@ -48,7 +48,7 @@ * 2010 Ekaterina Gorelkina : redesign module for separating core and arch parts * */ - +#include #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); diff --git a/kprobe/dbi_kprobes.c b/kprobe/dbi_kprobes.c index c0519f2..9d66ac1 100644 --- a/kprobe/dbi_kprobes.c +++ b/kprobe/dbi_kprobes.c @@ -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);