int __kprobes kprobe_fault_handler()

in kernel/kprobes.c [289:337]


int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned long 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 the fault. We reset the current kprobe and allow the
		 * exception handler as if it is regular exception. In our
		 * case it doesn't matter because the system will be halted
		 */
		resume_execution(cur, (unsigned long)cur->addr, regs);

		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:
		/*
		 * We are here because the instructions in the pre/post handler
		 * caused the fault.
		 */

		/*
		 * In case the user-specified fault handler returned zero,
		 * try to fix up.
		 */
		if (fixup_exception(regs))
			return 1;

		/*
		 * fixup_exception() could not handle it,
		 * Let do_page_fault() fix it.
		 */
		break;

	default:
		break;
	}
	return 0;
}