int __kprobes arc_kprobe_handler()

in kernel/kprobes.c [193:242]


int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs)
{
	struct kprobe *p;
	struct kprobe_ctlblk *kcb;

	preempt_disable();

	kcb = get_kprobe_ctlblk();
	p = get_kprobe((unsigned long *)addr);

	if (p) {
		/*
		 * We have reentered the kprobe_handler, since another kprobe
		 * was hit while within the handler, we save the original
		 * kprobes and single step on the instruction of the new probe
		 * without calling any user handlers to avoid recursive
		 * kprobes.
		 */
		if (kprobe_running()) {
			save_previous_kprobe(kcb);
			set_current_kprobe(p);
			kprobes_inc_nmissed_count(p);
			setup_singlestep(p, regs);
			kcb->kprobe_status = KPROBE_REENTER;
			return 1;
		}

		set_current_kprobe(p);
		kcb->kprobe_status = KPROBE_HIT_ACTIVE;

		/* If we have no pre-handler or it returned 0, we continue with
		 * normal processing. If we have a pre-handler and it returned
		 * non-zero - which means user handler setup registers to exit
		 * to another instruction, we must skip the single stepping.
		 */
		if (!p->pre_handler || !p->pre_handler(p, regs)) {
			setup_singlestep(p, regs);
			kcb->kprobe_status = KPROBE_HIT_SS;
		} else {
			reset_current_kprobe();
			preempt_enable_no_resched();
		}

		return 1;
	}

	/* no_kprobe: */
	preempt_enable_no_resched();
	return 0;
}