// SPDX-License-Identifier: GPL-2.0
/*
 * arch/parisc/kernel/kprobes.c
 *
 * PA-RISC kprobes implementation
 *
 * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
 * Copyright (c) 2022 Helge Deller <deller@gmx.de>
 */

#include <linux/types.h>
#include <linux/kprobes.h>
#include <linux/slab.h>
#include <asm/cacheflush.h>
#include <asm/text-patching.h>

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

int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
	if ((unsigned long)p->addr & 3UL)
		return -EINVAL;

	p->ainsn.insn = get_insn_slot();
	if (!p->ainsn.insn)
		return -ENOMEM;

	/*
	 * Set up new instructions. Second break instruction will
	 * trigger call of parisc_kprobe_ss_handler().
	 */
	p->opcode = *p->addr;
	p->ainsn.insn[0] = p->opcode;
	p->ainsn.insn[1] = PARISC_KPROBES_BREAK_INSN2;

	flush_insn_slot(p);
	return 0;
}

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
	if (!p->ainsn.insn)
		return;

	free_insn_slot(p->ainsn.insn, 0);
	p->ainsn.insn = NULL;
}

void __kprobes arch_arm_kprobe(struct kprobe *p)
{
	patch_text(p->addr, PARISC_KPROBES_BREAK_INSN);
}

void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
	patch_text(p->addr, p->opcode);
}

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 setup_singlestep(struct kprobe *p,
		struct kprobe_ctlblk *kcb, struct pt_regs *regs)
{
	kcb->iaoq[0] = regs->iaoq[0];
	kcb->iaoq[1] = regs->iaoq[1];
	instruction_pointer_set(regs, (unsigned long)p->ainsn.insn);
}

int __kprobes parisc_kprobe_break_handler(struct pt_regs *regs)
{
	struct kprobe *p;
	struct kprobe_ctlblk *kcb;

	preempt_disable();

	kcb = get_kprobe_ctlblk();
	p = get_kprobe((unsigned long *)regs->iaoq[0]);

	if (!p) {
		preempt_enable_no_resched();
		return 0;
	}

	if (kprobe_running()) {
		/*
		 * 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.
		 */
		save_previous_kprobe(kcb);
		set_current_kprobe(p);
		kprobes_inc_nmissed_count(p);
		setup_singlestep(p, kcb, 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, kcb, regs);
		kcb->kprobe_status = KPROBE_HIT_SS;
	} else {
		reset_current_kprobe();
		preempt_enable_no_resched();
	}
	return 1;
}

int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs)
{
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
	struct kprobe *p = kprobe_running();

	if (!p)
		return 0;

	if (regs->iaoq[0] != (unsigned long)p->ainsn.insn+4)
		return 0;

	/* restore back original saved kprobe variables and continue */
	if (kcb->kprobe_status == KPROBE_REENTER) {
		restore_previous_kprobe(kcb);
		return 1;
	}

	/* for absolute branch instructions we can copy iaoq_b. for relative
	 * branch instructions we need to calculate the new address based on the
	 * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without
	 * modifications because it's based on our ainsn.insn address.
	 */

	if (p->post_handler)
		p->post_handler(p, regs, 0);

	switch (regs->iir >> 26) {
	case 0x38: /* BE */
	case 0x39: /* BE,L */
	case 0x3a: /* BV */
	case 0x3b: /* BVE */
		/* for absolute branches, regs->iaoq[1] has already the right
		 * address
		 */
		regs->iaoq[0] = kcb->iaoq[1];
		break;
	default:
		regs->iaoq[0] = kcb->iaoq[1];
		regs->iaoq[1] = regs->iaoq[0] + 4;
		break;
	}
	kcb->kprobe_status = KPROBE_HIT_SSDONE;
	reset_current_kprobe();
	return 1;
}

void __kretprobe_trampoline(void)
{
	asm volatile("nop");
	asm volatile("nop");
}

static int __kprobes trampoline_probe_handler(struct kprobe *p,
					      struct pt_regs *regs);

static struct kprobe trampoline_p = {
	.pre_handler = trampoline_probe_handler
};

static int __kprobes trampoline_probe_handler(struct kprobe *p,
					      struct pt_regs *regs)
{
	__kretprobe_trampoline_handler(regs, NULL);

	return 1;
}

void arch_kretprobe_fixup_return(struct pt_regs *regs,
				 kprobe_opcode_t *correct_ret_addr)
{
	regs->gr[2] = (unsigned long)correct_ret_addr;
}

void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
				      struct pt_regs *regs)
{
	ri->ret_addr = (kprobe_opcode_t *)regs->gr[2];
	ri->fp = NULL;

	/* Replace the return addr with trampoline addr. */
	regs->gr[2] = (unsigned long)trampoline_p.addr;
}

int __kprobes arch_trampoline_kprobe(struct kprobe *p)
{
	return p->addr == trampoline_p.addr;
}

int __init arch_init_kprobes(void)
{
	trampoline_p.addr = (kprobe_opcode_t *)
		dereference_function_descriptor(__kretprobe_trampoline);
	return register_kprobe(&trampoline_p);
}
