// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 */

#include <linux/types.h>
#include <linux/kprobes.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kdebug.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/current.h>
#include <asm/disasm.h>

#define MIN_STACK_SIZE(addr)	min((unsigned long)MAX_STACK_SIZE, \
		(unsigned long)current_thread_info() + THREAD_SIZE - (addr))

DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
	/* Attempt to probe at unaligned address */
	if ((unsigned long)p->addr & 0x01)
		return -EINVAL;

	/* Address should not be in exception handling code */

	p->ainsn.is_short = is_short_instr((unsigned long)p->addr);
	p->opcode = *p->addr;

	return 0;
}

void __kprobes arch_arm_kprobe(struct kprobe *p)
{
	*p->addr = UNIMP_S_INSTRUCTION;

	flush_icache_range((unsigned long)p->addr,
			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));
}

void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
	*p->addr = p->opcode;

	flush_icache_range((unsigned long)p->addr,
			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));
}

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
	arch_disarm_kprobe(p);

	/* Can we remove the kprobe in the middle of kprobe handling? */
	if (p->ainsn.t1_addr) {
		*(p->ainsn.t1_addr) = p->ainsn.t1_opcode;

		flush_icache_range((unsigned long)p->ainsn.t1_addr,
				   (unsigned long)p->ainsn.t1_addr +
				   sizeof(kprobe_opcode_t));

		p->ainsn.t1_addr = NULL;
	}

	if (p->ainsn.t2_addr) {
		*(p->ainsn.t2_addr) = p->ainsn.t2_opcode;

		flush_icache_range((unsigned long)p->ainsn.t2_addr,
				   (unsigned long)p->ainsn.t2_addr +
				   sizeof(kprobe_opcode_t));

		p->ainsn.t2_addr = NULL;
	}
}

static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
{
	kcb->prev_kprobe.kp = kprobe_running();
	kcb->prev_kprobe.status = kcb->kprobe_status;
}

static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
{
	__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
	kcb->kprobe_status = kcb->prev_kprobe.status;
}

static inline void __kprobes set_current_kprobe(struct kprobe *p)
{
	__this_cpu_write(current_kprobe, p);
}

static void __kprobes resume_execution(struct kprobe *p, unsigned long addr,
				       struct pt_regs *regs)
{
	/* Remove the trap instructions inserted for single step and
	 * restore the original instructions
	 */
	if (p->ainsn.t1_addr) {
		*(p->ainsn.t1_addr) = p->ainsn.t1_opcode;

		flush_icache_range((unsigned long)p->ainsn.t1_addr,
				   (unsigned long)p->ainsn.t1_addr +
				   sizeof(kprobe_opcode_t));

		p->ainsn.t1_addr = NULL;
	}

	if (p->ainsn.t2_addr) {
		*(p->ainsn.t2_addr) = p->ainsn.t2_opcode;

		flush_icache_range((unsigned long)p->ainsn.t2_addr,
				   (unsigned long)p->ainsn.t2_addr +
				   sizeof(kprobe_opcode_t));

		p->ainsn.t2_addr = NULL;
	}

	return;
}

static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs)
{
	unsigned long next_pc;
	unsigned long tgt_if_br = 0;
	int is_branch;
	unsigned long bta;

	/* Copy the opcode back to the kprobe location and execute the
	 * instruction. Because of this we will not be able to get into the
	 * same kprobe until this kprobe is done
	 */
	*(p->addr) = p->opcode;

	flush_icache_range((unsigned long)p->addr,
			   (unsigned long)p->addr + sizeof(kprobe_opcode_t));

	/* Now we insert the trap at the next location after this instruction to
	 * single step. If it is a branch we insert the trap at possible branch
	 * targets
	 */

	bta = regs->bta;

	if (regs->status32 & 0x40) {
		/* We are in a delay slot with the branch taken */

		next_pc = bta & ~0x01;

		if (!p->ainsn.is_short) {
			if (bta & 0x01)
				regs->blink += 2;
			else {
				/* Branch not taken */
				next_pc += 2;

				/* next pc is taken from bta after executing the
				 * delay slot instruction
				 */
				regs->bta += 2;
			}
		}

		is_branch = 0;
	} else
		is_branch =
		    disasm_next_pc((unsigned long)p->addr, regs,
			(struct callee_regs *) current->thread.callee_reg,
			&next_pc, &tgt_if_br);

	p->ainsn.t1_addr = (kprobe_opcode_t *) next_pc;
	p->ainsn.t1_opcode = *(p->ainsn.t1_addr);
	*(p->ainsn.t1_addr) = TRAP_S_2_INSTRUCTION;

	flush_icache_range((unsigned long)p->ainsn.t1_addr,
			   (unsigned long)p->ainsn.t1_addr +
			   sizeof(kprobe_opcode_t));

	if (is_branch) {
		p->ainsn.t2_addr = (kprobe_opcode_t *) tgt_if_br;
		p->ainsn.t2_opcode = *(p->ainsn.t2_addr);
		*(p->ainsn.t2_addr) = TRAP_S_2_INSTRUCTION;

		flush_icache_range((unsigned long)p->ainsn.t2_addr,
				   (unsigned long)p->ainsn.t2_addr +
				   sizeof(kprobe_opcode_t));
	}
}

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;
}

static int __kprobes arc_post_kprobe_handler(unsigned long addr,
					 struct pt_regs *regs)
{
	struct kprobe *cur = kprobe_running();
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();

	if (!cur)
		return 0;

	resume_execution(cur, addr, regs);

	/* Rearm the kprobe */
	arch_arm_kprobe(cur);

	/*
	 * When we return from trap instruction we go to the next instruction
	 * We restored the actual instruction in resume_exectuiont and we to
	 * return to the same address and execute it
	 */
	regs->ret = addr;

	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
		kcb->kprobe_status = KPROBE_HIT_SSDONE;
		cur->post_handler(cur, regs, 0);
	}

	if (kcb->kprobe_status == KPROBE_REENTER) {
		restore_previous_kprobe(kcb);
		goto out;
	}

	reset_current_kprobe();

out:
	preempt_enable_no_resched();
	return 1;
}

/*
 * Fault can be for the instruction being single stepped or for the
 * pre/post handlers in the module.
 * This is applicable for applications like user probes, where we have the
 * probe in user space and the handlers in the kernel
 */

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;
}

int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
				       unsigned long val, void *data)
{
	struct die_args *args = data;
	unsigned long addr = args->err;
	int ret = NOTIFY_DONE;

	switch (val) {
	case DIE_IERR:
		if (arc_kprobe_handler(addr, args->regs))
			return NOTIFY_STOP;
		break;

	case DIE_TRAP:
		if (arc_post_kprobe_handler(addr, args->regs))
			return NOTIFY_STOP;
		break;

	default:
		break;
	}

	return ret;
}

static void __used kretprobe_trampoline_holder(void)
{
	__asm__ __volatile__(".global kretprobe_trampoline\n"
			     "kretprobe_trampoline:\n" "nop\n");
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
				      struct pt_regs *regs)
{

	ri->ret_addr = (kprobe_opcode_t *) regs->blink;
	ri->fp = NULL;

	/* Replace the return addr with trampoline addr */
	regs->blink = (unsigned long)&kretprobe_trampoline;
}

static int __kprobes trampoline_probe_handler(struct kprobe *p,
					      struct pt_regs *regs)
{
	regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);

	/* By returning a non zero value, we are telling the kprobe handler
	 * that we don't want the post_handler to run
	 */
	return 1;
}

static struct kprobe trampoline_p = {
	.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
	.pre_handler = trampoline_probe_handler
};

int __init arch_init_kprobes(void)
{
	/* Registering the trampoline code for the kret probe */
	return register_kprobe(&trampoline_p);
}

int __kprobes arch_trampoline_kprobe(struct kprobe *p)
{
	if (p->addr == (kprobe_opcode_t *) &kretprobe_trampoline)
		return 1;

	return 0;
}

void trap_is_kprobe(unsigned long address, struct pt_regs *regs)
{
	notify_die(DIE_TRAP, "kprobe_trap", regs, address, 0, SIGTRAP);
}
