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

static 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, 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);
}
