lkml.org 
[lkml]   [2012]   [Jun]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH -tip v2 9/9] kprobes/x86: ftrace based optimization for x86
    Date
    Add function tracer based kprobe optimization support
    handlers on x86. This allows kprobes to use function
    tracer for probing on mcount call.

    Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    ---

    arch/x86/include/asm/kprobes.h | 1 +
    arch/x86/kernel/kprobes.c | 48 ++++++++++++++++++++++++++++++++++++++++
    2 files changed, 49 insertions(+), 0 deletions(-)

    diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h
    index 5478825..d3ddd17 100644
    --- a/arch/x86/include/asm/kprobes.h
    +++ b/arch/x86/include/asm/kprobes.h
    @@ -27,6 +27,7 @@
    #include <asm/insn.h>

    #define __ARCH_WANT_KPROBES_INSN_SLOT
    +#define ARCH_SUPPORTS_KPROBES_ON_FTRACE

    struct pt_regs;
    struct kprobe;
    diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
    index e2f751e..4c46c55 100644
    --- a/arch/x86/kernel/kprobes.c
    +++ b/arch/x86/kernel/kprobes.c
    @@ -1052,6 +1052,54 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
    return 0;
    }

    +#ifdef KPROBES_CAN_USE_FTRACE
    +/* Ftrace callback handler for kprobes */
    +void __kprobes kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
    + struct pt_regs *regs)
    +{
    + struct kprobe *p;
    + struct kprobe_ctlblk *kcb;
    + unsigned long flags;
    +
    + /* Disable irq for emulating a breakpoint and avoiding preempt */
    + local_irq_save(flags);
    +
    + p = get_kprobe((kprobe_opcode_t *)ip);
    + if (unlikely(!p) || kprobe_disabled(p))
    + goto end;
    +
    + kcb = get_kprobe_ctlblk();
    + if (kprobe_running()) {
    + kprobes_inc_nmissed_count(p);
    + } else {
    + regs->ip += sizeof(kprobe_opcode_t);
    +
    + __this_cpu_write(current_kprobe, p);
    + kcb->kprobe_status = KPROBE_HIT_ACTIVE;
    + if (p->pre_handler)
    + p->pre_handler(p, regs);
    +
    + if (unlikely(p->post_handler)) {
    + /* Emulate singlestep as if there is a 5byte nop */
    + regs->ip = ip + MCOUNT_INSN_SIZE;
    + kcb->kprobe_status = KPROBE_HIT_SSDONE;
    + p->post_handler(p, regs, 0);
    + }
    + __this_cpu_write(current_kprobe, NULL);
    + regs->ip = ip; /* Recover for next callback */
    + }
    +end:
    + local_irq_restore(flags);
    +}
    +
    +int __kprobes arch_prepare_kprobe_ftrace(struct kprobe *p)
    +{
    + p->ainsn.insn = NULL;
    + p->ainsn.boostable = -1;
    + return 0;
    +}
    +#endif
    +
    int __init arch_init_kprobes(void)
    {
    return arch_init_optprobes();


    \
     
     \ /
      Last update: 2012-06-05 15:01    [W:3.773 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site