/* * Wrapper routine to for handling exceptions. */ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; /* * Interrupts are not disabled here. We need to disable * preemption, because kprobe_running() uses smp_processor_id(). */ preempt_disable(); switch (val) { case DIE_IABR_MATCH: case DIE_DABR_MATCH: case DIE_BPT: if (kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; case DIE_SSTEP: if (post_kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; case DIE_GPF: case DIE_PAGE_FAULT: if (kprobe_running() && kprobe_fault_handler(args->regs, args->trapnr)) ret = NOTIFY_STOP; break; default: break; } preempt_enable(); return ret; }
/* * Wrapper routine to for handling exceptions. */ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) { struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; pr_debug("kprobe_exceptions_notify: val=%lu, data=%p\n", val, data); switch (val) { case DIE_BREAKPOINT: if (kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; case DIE_SSTEP: if (post_kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; case DIE_FAULT: if (kprobe_running() && kprobe_fault_handler(args->regs, args->trapnr)) ret = NOTIFY_STOP; break; default: break; } return ret; }
static int __kprobes kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) { unsigned long flags; local_irq_save(flags); kprobe_handler(regs); local_irq_restore(flags); return 0; }
int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) { kprobe_handler(regs); return 0; }