in kernel/kprobes.c [820:862]
int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
switch(kcb->kprobe_status) {
case KPROBE_HIT_SS:
case KPROBE_REENTER:
/*
* We are here because the instruction being single
* stepped caused a page fault. We reset the current
* kprobe and the instruction pointer points back to
* the probe address and allow the page fault handler
* to continue as a normal page fault.
*/
regs->cr_iip = ((unsigned long)cur->addr) & ~0xFULL;
ia64_psr(regs)->ri = ((unsigned long)cur->addr) & 0xf;
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
else
reset_current_kprobe();
preempt_enable_no_resched();
break;
case KPROBE_HIT_ACTIVE:
case KPROBE_HIT_SSDONE:
/*
* In case the user-specified fault handler returned
* zero, try to fix up.
*/
if (ia64_done_with_exception(regs))
return 1;
/*
* Let ia64_do_page_fault() fix it.
*/
break;
default:
break;
}
return 0;
}