xref: /openbmc/linux/arch/arc/kernel/kprobes.c (revision adf8a61a)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
24d86dfbbSVineet Gupta /*
34d86dfbbSVineet Gupta  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
44d86dfbbSVineet Gupta  */
54d86dfbbSVineet Gupta 
64d86dfbbSVineet Gupta #include <linux/types.h>
74d86dfbbSVineet Gupta #include <linux/kprobes.h>
84d86dfbbSVineet Gupta #include <linux/slab.h>
94d86dfbbSVineet Gupta #include <linux/module.h>
104d86dfbbSVineet Gupta #include <linux/kdebug.h>
114d86dfbbSVineet Gupta #include <linux/sched.h>
124d86dfbbSVineet Gupta #include <linux/uaccess.h>
134d86dfbbSVineet Gupta #include <asm/cacheflush.h>
144d86dfbbSVineet Gupta #include <asm/current.h>
154d86dfbbSVineet Gupta #include <asm/disasm.h>
164d86dfbbSVineet Gupta 
174d86dfbbSVineet Gupta #define MIN_STACK_SIZE(addr)	min((unsigned long)MAX_STACK_SIZE, \
184d86dfbbSVineet Gupta 		(unsigned long)current_thread_info() + THREAD_SIZE - (addr))
194d86dfbbSVineet Gupta 
204d86dfbbSVineet Gupta DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
214d86dfbbSVineet Gupta DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
224d86dfbbSVineet Gupta 
arch_prepare_kprobe(struct kprobe * p)234d86dfbbSVineet Gupta int __kprobes arch_prepare_kprobe(struct kprobe *p)
244d86dfbbSVineet Gupta {
254d86dfbbSVineet Gupta 	/* Attempt to probe at unaligned address */
264d86dfbbSVineet Gupta 	if ((unsigned long)p->addr & 0x01)
274d86dfbbSVineet Gupta 		return -EINVAL;
284d86dfbbSVineet Gupta 
294d86dfbbSVineet Gupta 	/* Address should not be in exception handling code */
304d86dfbbSVineet Gupta 
314d86dfbbSVineet Gupta 	p->ainsn.is_short = is_short_instr((unsigned long)p->addr);
324d86dfbbSVineet Gupta 	p->opcode = *p->addr;
334d86dfbbSVineet Gupta 
344d86dfbbSVineet Gupta 	return 0;
354d86dfbbSVineet Gupta }
364d86dfbbSVineet Gupta 
arch_arm_kprobe(struct kprobe * p)374d86dfbbSVineet Gupta void __kprobes arch_arm_kprobe(struct kprobe *p)
384d86dfbbSVineet Gupta {
394d86dfbbSVineet Gupta 	*p->addr = UNIMP_S_INSTRUCTION;
404d86dfbbSVineet Gupta 
414d86dfbbSVineet Gupta 	flush_icache_range((unsigned long)p->addr,
424d86dfbbSVineet Gupta 			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));
434d86dfbbSVineet Gupta }
444d86dfbbSVineet Gupta 
arch_disarm_kprobe(struct kprobe * p)454d86dfbbSVineet Gupta void __kprobes arch_disarm_kprobe(struct kprobe *p)
464d86dfbbSVineet Gupta {
474d86dfbbSVineet Gupta 	*p->addr = p->opcode;
484d86dfbbSVineet Gupta 
494d86dfbbSVineet Gupta 	flush_icache_range((unsigned long)p->addr,
504d86dfbbSVineet Gupta 			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));
514d86dfbbSVineet Gupta }
524d86dfbbSVineet Gupta 
arch_remove_kprobe(struct kprobe * p)534d86dfbbSVineet Gupta void __kprobes arch_remove_kprobe(struct kprobe *p)
544d86dfbbSVineet Gupta {
554d86dfbbSVineet Gupta 	arch_disarm_kprobe(p);
564d86dfbbSVineet Gupta 
574d86dfbbSVineet Gupta 	/* Can we remove the kprobe in the middle of kprobe handling? */
584d86dfbbSVineet Gupta 	if (p->ainsn.t1_addr) {
594d86dfbbSVineet Gupta 		*(p->ainsn.t1_addr) = p->ainsn.t1_opcode;
604d86dfbbSVineet Gupta 
614d86dfbbSVineet Gupta 		flush_icache_range((unsigned long)p->ainsn.t1_addr,
624d86dfbbSVineet Gupta 				   (unsigned long)p->ainsn.t1_addr +
634d86dfbbSVineet Gupta 				   sizeof(kprobe_opcode_t));
644d86dfbbSVineet Gupta 
654d86dfbbSVineet Gupta 		p->ainsn.t1_addr = NULL;
664d86dfbbSVineet Gupta 	}
674d86dfbbSVineet Gupta 
684d86dfbbSVineet Gupta 	if (p->ainsn.t2_addr) {
694d86dfbbSVineet Gupta 		*(p->ainsn.t2_addr) = p->ainsn.t2_opcode;
704d86dfbbSVineet Gupta 
714d86dfbbSVineet Gupta 		flush_icache_range((unsigned long)p->ainsn.t2_addr,
724d86dfbbSVineet Gupta 				   (unsigned long)p->ainsn.t2_addr +
734d86dfbbSVineet Gupta 				   sizeof(kprobe_opcode_t));
744d86dfbbSVineet Gupta 
754d86dfbbSVineet Gupta 		p->ainsn.t2_addr = NULL;
764d86dfbbSVineet Gupta 	}
774d86dfbbSVineet Gupta }
784d86dfbbSVineet Gupta 
save_previous_kprobe(struct kprobe_ctlblk * kcb)794d86dfbbSVineet Gupta static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
804d86dfbbSVineet Gupta {
814d86dfbbSVineet Gupta 	kcb->prev_kprobe.kp = kprobe_running();
824d86dfbbSVineet Gupta 	kcb->prev_kprobe.status = kcb->kprobe_status;
834d86dfbbSVineet Gupta }
844d86dfbbSVineet Gupta 
restore_previous_kprobe(struct kprobe_ctlblk * kcb)854d86dfbbSVineet Gupta static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
864d86dfbbSVineet Gupta {
876855e95cSChristoph Lameter 	__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
884d86dfbbSVineet Gupta 	kcb->kprobe_status = kcb->prev_kprobe.status;
894d86dfbbSVineet Gupta }
904d86dfbbSVineet Gupta 
set_current_kprobe(struct kprobe * p)914d86dfbbSVineet Gupta static inline void __kprobes set_current_kprobe(struct kprobe *p)
924d86dfbbSVineet Gupta {
936855e95cSChristoph Lameter 	__this_cpu_write(current_kprobe, p);
944d86dfbbSVineet Gupta }
954d86dfbbSVineet Gupta 
resume_execution(struct kprobe * p,unsigned long addr,struct pt_regs * regs)964d86dfbbSVineet Gupta static void __kprobes resume_execution(struct kprobe *p, unsigned long addr,
974d86dfbbSVineet Gupta 				       struct pt_regs *regs)
984d86dfbbSVineet Gupta {
994d86dfbbSVineet Gupta 	/* Remove the trap instructions inserted for single step and
1004d86dfbbSVineet Gupta 	 * restore the original instructions
1014d86dfbbSVineet Gupta 	 */
1024d86dfbbSVineet Gupta 	if (p->ainsn.t1_addr) {
1034d86dfbbSVineet Gupta 		*(p->ainsn.t1_addr) = p->ainsn.t1_opcode;
1044d86dfbbSVineet Gupta 
1054d86dfbbSVineet Gupta 		flush_icache_range((unsigned long)p->ainsn.t1_addr,
1064d86dfbbSVineet Gupta 				   (unsigned long)p->ainsn.t1_addr +
1074d86dfbbSVineet Gupta 				   sizeof(kprobe_opcode_t));
1084d86dfbbSVineet Gupta 
1094d86dfbbSVineet Gupta 		p->ainsn.t1_addr = NULL;
1104d86dfbbSVineet Gupta 	}
1114d86dfbbSVineet Gupta 
1124d86dfbbSVineet Gupta 	if (p->ainsn.t2_addr) {
1134d86dfbbSVineet Gupta 		*(p->ainsn.t2_addr) = p->ainsn.t2_opcode;
1144d86dfbbSVineet Gupta 
1154d86dfbbSVineet Gupta 		flush_icache_range((unsigned long)p->ainsn.t2_addr,
1164d86dfbbSVineet Gupta 				   (unsigned long)p->ainsn.t2_addr +
1174d86dfbbSVineet Gupta 				   sizeof(kprobe_opcode_t));
1184d86dfbbSVineet Gupta 
1194d86dfbbSVineet Gupta 		p->ainsn.t2_addr = NULL;
1204d86dfbbSVineet Gupta 	}
1214d86dfbbSVineet Gupta 
1224d86dfbbSVineet Gupta 	return;
1234d86dfbbSVineet Gupta }
1244d86dfbbSVineet Gupta 
setup_singlestep(struct kprobe * p,struct pt_regs * regs)1254d86dfbbSVineet Gupta static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs)
1264d86dfbbSVineet Gupta {
1274d86dfbbSVineet Gupta 	unsigned long next_pc;
1284d86dfbbSVineet Gupta 	unsigned long tgt_if_br = 0;
1294d86dfbbSVineet Gupta 	int is_branch;
1304d86dfbbSVineet Gupta 	unsigned long bta;
1314d86dfbbSVineet Gupta 
1324d86dfbbSVineet Gupta 	/* Copy the opcode back to the kprobe location and execute the
1334d86dfbbSVineet Gupta 	 * instruction. Because of this we will not be able to get into the
1344d86dfbbSVineet Gupta 	 * same kprobe until this kprobe is done
1354d86dfbbSVineet Gupta 	 */
1364d86dfbbSVineet Gupta 	*(p->addr) = p->opcode;
1374d86dfbbSVineet Gupta 
1384d86dfbbSVineet Gupta 	flush_icache_range((unsigned long)p->addr,
1394d86dfbbSVineet Gupta 			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));
1404d86dfbbSVineet Gupta 
1414d86dfbbSVineet Gupta 	/* Now we insert the trap at the next location after this instruction to
1424d86dfbbSVineet Gupta 	 * single step. If it is a branch we insert the trap at possible branch
1434d86dfbbSVineet Gupta 	 * targets
1444d86dfbbSVineet Gupta 	 */
1454d86dfbbSVineet Gupta 
1464d86dfbbSVineet Gupta 	bta = regs->bta;
1474d86dfbbSVineet Gupta 
1484d86dfbbSVineet Gupta 	if (regs->status32 & 0x40) {
1494d86dfbbSVineet Gupta 		/* We are in a delay slot with the branch taken */
1504d86dfbbSVineet Gupta 
1514d86dfbbSVineet Gupta 		next_pc = bta & ~0x01;
1524d86dfbbSVineet Gupta 
1534d86dfbbSVineet Gupta 		if (!p->ainsn.is_short) {
1544d86dfbbSVineet Gupta 			if (bta & 0x01)
1554d86dfbbSVineet Gupta 				regs->blink += 2;
1564d86dfbbSVineet Gupta 			else {
1574d86dfbbSVineet Gupta 				/* Branch not taken */
1584d86dfbbSVineet Gupta 				next_pc += 2;
1594d86dfbbSVineet Gupta 
1604d86dfbbSVineet Gupta 				/* next pc is taken from bta after executing the
1614d86dfbbSVineet Gupta 				 * delay slot instruction
1624d86dfbbSVineet Gupta 				 */
1634d86dfbbSVineet Gupta 				regs->bta += 2;
1644d86dfbbSVineet Gupta 			}
1654d86dfbbSVineet Gupta 		}
1664d86dfbbSVineet Gupta 
1674d86dfbbSVineet Gupta 		is_branch = 0;
1684d86dfbbSVineet Gupta 	} else
1694d86dfbbSVineet Gupta 		is_branch =
1704d86dfbbSVineet Gupta 		    disasm_next_pc((unsigned long)p->addr, regs,
1714d86dfbbSVineet Gupta 			(struct callee_regs *) current->thread.callee_reg,
1724d86dfbbSVineet Gupta 			&next_pc, &tgt_if_br);
1734d86dfbbSVineet Gupta 
1744d86dfbbSVineet Gupta 	p->ainsn.t1_addr = (kprobe_opcode_t *) next_pc;
1754d86dfbbSVineet Gupta 	p->ainsn.t1_opcode = *(p->ainsn.t1_addr);
1764d86dfbbSVineet Gupta 	*(p->ainsn.t1_addr) = TRAP_S_2_INSTRUCTION;
1774d86dfbbSVineet Gupta 
1784d86dfbbSVineet Gupta 	flush_icache_range((unsigned long)p->ainsn.t1_addr,
1794d86dfbbSVineet Gupta 			   (unsigned long)p->ainsn.t1_addr +
1804d86dfbbSVineet Gupta 			   sizeof(kprobe_opcode_t));
1814d86dfbbSVineet Gupta 
1824d86dfbbSVineet Gupta 	if (is_branch) {
1834d86dfbbSVineet Gupta 		p->ainsn.t2_addr = (kprobe_opcode_t *) tgt_if_br;
1844d86dfbbSVineet Gupta 		p->ainsn.t2_opcode = *(p->ainsn.t2_addr);
1854d86dfbbSVineet Gupta 		*(p->ainsn.t2_addr) = TRAP_S_2_INSTRUCTION;
1864d86dfbbSVineet Gupta 
1874d86dfbbSVineet Gupta 		flush_icache_range((unsigned long)p->ainsn.t2_addr,
1884d86dfbbSVineet Gupta 				   (unsigned long)p->ainsn.t2_addr +
1894d86dfbbSVineet Gupta 				   sizeof(kprobe_opcode_t));
1904d86dfbbSVineet Gupta 	}
1914d86dfbbSVineet Gupta }
1924d86dfbbSVineet Gupta 
arc_kprobe_handler(unsigned long addr,struct pt_regs * regs)1934d86dfbbSVineet Gupta int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs)
1944d86dfbbSVineet Gupta {
1954d86dfbbSVineet Gupta 	struct kprobe *p;
1964d86dfbbSVineet Gupta 	struct kprobe_ctlblk *kcb;
1974d86dfbbSVineet Gupta 
1984d86dfbbSVineet Gupta 	preempt_disable();
1994d86dfbbSVineet Gupta 
2004d86dfbbSVineet Gupta 	kcb = get_kprobe_ctlblk();
2014d86dfbbSVineet Gupta 	p = get_kprobe((unsigned long *)addr);
2024d86dfbbSVineet Gupta 
2034d86dfbbSVineet Gupta 	if (p) {
2044d86dfbbSVineet Gupta 		/*
2054d86dfbbSVineet Gupta 		 * We have reentered the kprobe_handler, since another kprobe
2064d86dfbbSVineet Gupta 		 * was hit while within the handler, we save the original
2074d86dfbbSVineet Gupta 		 * kprobes and single step on the instruction of the new probe
2084d86dfbbSVineet Gupta 		 * without calling any user handlers to avoid recursive
2094d86dfbbSVineet Gupta 		 * kprobes.
2104d86dfbbSVineet Gupta 		 */
2114d86dfbbSVineet Gupta 		if (kprobe_running()) {
2124d86dfbbSVineet Gupta 			save_previous_kprobe(kcb);
2134d86dfbbSVineet Gupta 			set_current_kprobe(p);
2144d86dfbbSVineet Gupta 			kprobes_inc_nmissed_count(p);
2154d86dfbbSVineet Gupta 			setup_singlestep(p, regs);
2164d86dfbbSVineet Gupta 			kcb->kprobe_status = KPROBE_REENTER;
2174d86dfbbSVineet Gupta 			return 1;
2184d86dfbbSVineet Gupta 		}
2194d86dfbbSVineet Gupta 
2204d86dfbbSVineet Gupta 		set_current_kprobe(p);
2214d86dfbbSVineet Gupta 		kcb->kprobe_status = KPROBE_HIT_ACTIVE;
2224d86dfbbSVineet Gupta 
2234d86dfbbSVineet Gupta 		/* If we have no pre-handler or it returned 0, we continue with
2244d86dfbbSVineet Gupta 		 * normal processing. If we have a pre-handler and it returned
225e00f1993SMasami Hiramatsu 		 * non-zero - which means user handler setup registers to exit
226e00f1993SMasami Hiramatsu 		 * to another instruction, we must skip the single stepping.
2274d86dfbbSVineet Gupta 		 */
2284d86dfbbSVineet Gupta 		if (!p->pre_handler || !p->pre_handler(p, regs)) {
2294d86dfbbSVineet Gupta 			setup_singlestep(p, regs);
2304d86dfbbSVineet Gupta 			kcb->kprobe_status = KPROBE_HIT_SS;
231cce188bdSMasami Hiramatsu 		} else {
232cce188bdSMasami Hiramatsu 			reset_current_kprobe();
233cce188bdSMasami Hiramatsu 			preempt_enable_no_resched();
2344d86dfbbSVineet Gupta 		}
2354d86dfbbSVineet Gupta 
2364d86dfbbSVineet Gupta 		return 1;
2374d86dfbbSVineet Gupta 	}
2384d86dfbbSVineet Gupta 
2394d86dfbbSVineet Gupta 	/* no_kprobe: */
2404d86dfbbSVineet Gupta 	preempt_enable_no_resched();
2414d86dfbbSVineet Gupta 	return 0;
2424d86dfbbSVineet Gupta }
2434d86dfbbSVineet Gupta 
arc_post_kprobe_handler(unsigned long addr,struct pt_regs * regs)2444d86dfbbSVineet Gupta static int __kprobes arc_post_kprobe_handler(unsigned long addr,
2454d86dfbbSVineet Gupta 					 struct pt_regs *regs)
2464d86dfbbSVineet Gupta {
2474d86dfbbSVineet Gupta 	struct kprobe *cur = kprobe_running();
2484d86dfbbSVineet Gupta 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
2494d86dfbbSVineet Gupta 
2504d86dfbbSVineet Gupta 	if (!cur)
2514d86dfbbSVineet Gupta 		return 0;
2524d86dfbbSVineet Gupta 
2534d86dfbbSVineet Gupta 	resume_execution(cur, addr, regs);
2544d86dfbbSVineet Gupta 
2554d86dfbbSVineet Gupta 	/* Rearm the kprobe */
2564d86dfbbSVineet Gupta 	arch_arm_kprobe(cur);
2574d86dfbbSVineet Gupta 
2584d86dfbbSVineet Gupta 	/*
2594d86dfbbSVineet Gupta 	 * When we return from trap instruction we go to the next instruction
2604d86dfbbSVineet Gupta 	 * We restored the actual instruction in resume_exectuiont and we to
2614d86dfbbSVineet Gupta 	 * return to the same address and execute it
2624d86dfbbSVineet Gupta 	 */
2634d86dfbbSVineet Gupta 	regs->ret = addr;
2644d86dfbbSVineet Gupta 
2654d86dfbbSVineet Gupta 	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
2664d86dfbbSVineet Gupta 		kcb->kprobe_status = KPROBE_HIT_SSDONE;
2674d86dfbbSVineet Gupta 		cur->post_handler(cur, regs, 0);
2684d86dfbbSVineet Gupta 	}
2694d86dfbbSVineet Gupta 
2704d86dfbbSVineet Gupta 	if (kcb->kprobe_status == KPROBE_REENTER) {
2714d86dfbbSVineet Gupta 		restore_previous_kprobe(kcb);
2724d86dfbbSVineet Gupta 		goto out;
2734d86dfbbSVineet Gupta 	}
2744d86dfbbSVineet Gupta 
2754d86dfbbSVineet Gupta 	reset_current_kprobe();
2764d86dfbbSVineet Gupta 
2774d86dfbbSVineet Gupta out:
2784d86dfbbSVineet Gupta 	preempt_enable_no_resched();
2794d86dfbbSVineet Gupta 	return 1;
2804d86dfbbSVineet Gupta }
2814d86dfbbSVineet Gupta 
2824d86dfbbSVineet Gupta /*
2834d86dfbbSVineet Gupta  * Fault can be for the instruction being single stepped or for the
2844d86dfbbSVineet Gupta  * pre/post handlers in the module.
2854d86dfbbSVineet Gupta  * This is applicable for applications like user probes, where we have the
2864d86dfbbSVineet Gupta  * probe in user space and the handlers in the kernel
2874d86dfbbSVineet Gupta  */
2884d86dfbbSVineet Gupta 
kprobe_fault_handler(struct pt_regs * regs,unsigned long trapnr)2894d86dfbbSVineet Gupta int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned long trapnr)
2904d86dfbbSVineet Gupta {
2914d86dfbbSVineet Gupta 	struct kprobe *cur = kprobe_running();
2924d86dfbbSVineet Gupta 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
2934d86dfbbSVineet Gupta 
2944d86dfbbSVineet Gupta 	switch (kcb->kprobe_status) {
2954d86dfbbSVineet Gupta 	case KPROBE_HIT_SS:
2964d86dfbbSVineet Gupta 	case KPROBE_REENTER:
2974d86dfbbSVineet Gupta 		/*
2984d86dfbbSVineet Gupta 		 * We are here because the instruction being single stepped
2994d86dfbbSVineet Gupta 		 * caused the fault. We reset the current kprobe and allow the
3004d86dfbbSVineet Gupta 		 * exception handler as if it is regular exception. In our
3014d86dfbbSVineet Gupta 		 * case it doesn't matter because the system will be halted
3024d86dfbbSVineet Gupta 		 */
3034d86dfbbSVineet Gupta 		resume_execution(cur, (unsigned long)cur->addr, regs);
3044d86dfbbSVineet Gupta 
3054d86dfbbSVineet Gupta 		if (kcb->kprobe_status == KPROBE_REENTER)
3064d86dfbbSVineet Gupta 			restore_previous_kprobe(kcb);
3074d86dfbbSVineet Gupta 		else
3084d86dfbbSVineet Gupta 			reset_current_kprobe();
3094d86dfbbSVineet Gupta 
3104d86dfbbSVineet Gupta 		preempt_enable_no_resched();
3114d86dfbbSVineet Gupta 		break;
3124d86dfbbSVineet Gupta 
3134d86dfbbSVineet Gupta 	case KPROBE_HIT_ACTIVE:
3144d86dfbbSVineet Gupta 	case KPROBE_HIT_SSDONE:
3154d86dfbbSVineet Gupta 		/*
3164d86dfbbSVineet Gupta 		 * We are here because the instructions in the pre/post handler
3174d86dfbbSVineet Gupta 		 * caused the fault.
3184d86dfbbSVineet Gupta 		 */
3194d86dfbbSVineet Gupta 
3204d86dfbbSVineet Gupta 		/*
3214d86dfbbSVineet Gupta 		 * In case the user-specified fault handler returned zero,
3224d86dfbbSVineet Gupta 		 * try to fix up.
3234d86dfbbSVineet Gupta 		 */
3244d86dfbbSVineet Gupta 		if (fixup_exception(regs))
3254d86dfbbSVineet Gupta 			return 1;
3264d86dfbbSVineet Gupta 
3274d86dfbbSVineet Gupta 		/*
3284d86dfbbSVineet Gupta 		 * fixup_exception() could not handle it,
3294d86dfbbSVineet Gupta 		 * Let do_page_fault() fix it.
3304d86dfbbSVineet Gupta 		 */
3314d86dfbbSVineet Gupta 		break;
3324d86dfbbSVineet Gupta 
3334d86dfbbSVineet Gupta 	default:
3344d86dfbbSVineet Gupta 		break;
3354d86dfbbSVineet Gupta 	}
3364d86dfbbSVineet Gupta 	return 0;
3374d86dfbbSVineet Gupta }
3384d86dfbbSVineet Gupta 
kprobe_exceptions_notify(struct notifier_block * self,unsigned long val,void * data)3394d86dfbbSVineet Gupta int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
3404d86dfbbSVineet Gupta 				       unsigned long val, void *data)
3414d86dfbbSVineet Gupta {
3424d86dfbbSVineet Gupta 	struct die_args *args = data;
3434d86dfbbSVineet Gupta 	unsigned long addr = args->err;
3444d86dfbbSVineet Gupta 	int ret = NOTIFY_DONE;
3454d86dfbbSVineet Gupta 
3464d86dfbbSVineet Gupta 	switch (val) {
3474d86dfbbSVineet Gupta 	case DIE_IERR:
3484d86dfbbSVineet Gupta 		if (arc_kprobe_handler(addr, args->regs))
3494d86dfbbSVineet Gupta 			return NOTIFY_STOP;
3504d86dfbbSVineet Gupta 		break;
3514d86dfbbSVineet Gupta 
3524d86dfbbSVineet Gupta 	case DIE_TRAP:
3534d86dfbbSVineet Gupta 		if (arc_post_kprobe_handler(addr, args->regs))
3544d86dfbbSVineet Gupta 			return NOTIFY_STOP;
3554d86dfbbSVineet Gupta 		break;
3564d86dfbbSVineet Gupta 
3574d86dfbbSVineet Gupta 	default:
3584d86dfbbSVineet Gupta 		break;
3594d86dfbbSVineet Gupta 	}
3604d86dfbbSVineet Gupta 
3614d86dfbbSVineet Gupta 	return ret;
3624d86dfbbSVineet Gupta }
3634d86dfbbSVineet Gupta 
kretprobe_trampoline_holder(void)3644d86dfbbSVineet Gupta static void __used kretprobe_trampoline_holder(void)
3654d86dfbbSVineet Gupta {
366*adf8a61aSMasami Hiramatsu 	__asm__ __volatile__(".global __kretprobe_trampoline\n"
367*adf8a61aSMasami Hiramatsu 			     "__kretprobe_trampoline:\n"
368*adf8a61aSMasami Hiramatsu 			     "nop\n");
3694d86dfbbSVineet Gupta }
3704d86dfbbSVineet Gupta 
arch_prepare_kretprobe(struct kretprobe_instance * ri,struct pt_regs * regs)3714d86dfbbSVineet Gupta void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
3724d86dfbbSVineet Gupta 				      struct pt_regs *regs)
3734d86dfbbSVineet Gupta {
3744d86dfbbSVineet Gupta 
3754d86dfbbSVineet Gupta 	ri->ret_addr = (kprobe_opcode_t *) regs->blink;
376f75dd136SMasami Hiramatsu 	ri->fp = NULL;
3774d86dfbbSVineet Gupta 
3784d86dfbbSVineet Gupta 	/* Replace the return addr with trampoline addr */
379*adf8a61aSMasami Hiramatsu 	regs->blink = (unsigned long)&__kretprobe_trampoline;
3804d86dfbbSVineet Gupta }
3814d86dfbbSVineet Gupta 
trampoline_probe_handler(struct kprobe * p,struct pt_regs * regs)3824d86dfbbSVineet Gupta static int __kprobes trampoline_probe_handler(struct kprobe *p,
3834d86dfbbSVineet Gupta 					      struct pt_regs *regs)
3844d86dfbbSVineet Gupta {
38596fed8acSMasami Hiramatsu 	regs->ret = __kretprobe_trampoline_handler(regs, NULL);
3864d86dfbbSVineet Gupta 
3874d86dfbbSVineet Gupta 	/* By returning a non zero value, we are telling the kprobe handler
3884d86dfbbSVineet Gupta 	 * that we don't want the post_handler to run
3894d86dfbbSVineet Gupta 	 */
3904d86dfbbSVineet Gupta 	return 1;
3914d86dfbbSVineet Gupta }
3924d86dfbbSVineet Gupta 
3934d86dfbbSVineet Gupta static struct kprobe trampoline_p = {
394*adf8a61aSMasami Hiramatsu 	.addr = (kprobe_opcode_t *) &__kretprobe_trampoline,
3954d86dfbbSVineet Gupta 	.pre_handler = trampoline_probe_handler
3964d86dfbbSVineet Gupta };
3974d86dfbbSVineet Gupta 
arch_init_kprobes(void)3984d86dfbbSVineet Gupta int __init arch_init_kprobes(void)
3994d86dfbbSVineet Gupta {
4004d86dfbbSVineet Gupta 	/* Registering the trampoline code for the kret probe */
4014d86dfbbSVineet Gupta 	return register_kprobe(&trampoline_p);
4024d86dfbbSVineet Gupta }
4034d86dfbbSVineet Gupta 
arch_trampoline_kprobe(struct kprobe * p)4044d86dfbbSVineet Gupta int __kprobes arch_trampoline_kprobe(struct kprobe *p)
4054d86dfbbSVineet Gupta {
406*adf8a61aSMasami Hiramatsu 	if (p->addr == (kprobe_opcode_t *) &__kretprobe_trampoline)
4074d86dfbbSVineet Gupta 		return 1;
4084d86dfbbSVineet Gupta 
4094d86dfbbSVineet Gupta 	return 0;
4104d86dfbbSVineet Gupta }
4114d86dfbbSVineet Gupta 
trap_is_kprobe(unsigned long address,struct pt_regs * regs)41238a9ff6dSVineet Gupta void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
4134d86dfbbSVineet Gupta {
41438a9ff6dSVineet Gupta 	notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP);
4154d86dfbbSVineet Gupta }
416