// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/regset.h>
#include <linux/hw_breakpoint.h>

#include <asm/debug.h>

#include "ptrace-decl.h"

void user_enable_single_step(struct task_struct *task)
{
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL)
		regs_set_return_msr(regs, (regs->msr & ~MSR_BE) | MSR_SE);
	set_tsk_thread_flag(task, TIF_SINGLESTEP);
}

void user_enable_block_step(struct task_struct *task)
{
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL)
		regs_set_return_msr(regs, (regs->msr & ~MSR_SE) | MSR_BE);
	set_tsk_thread_flag(task, TIF_SINGLESTEP);
}

void user_disable_single_step(struct task_struct *task)
{
	struct pt_regs *regs = task->thread.regs;

	if (regs != NULL)
		regs_set_return_msr(regs, regs->msr & ~(MSR_SE | MSR_BE));

	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
}

void ppc_gethwdinfo(struct ppc_debug_info *dbginfo)
{
	dbginfo->version = 1;
	dbginfo->num_instruction_bps = 0;
	if (ppc_breakpoint_available())
		dbginfo->num_data_bps = nr_wp_slots();
	else
		dbginfo->num_data_bps = 0;
	dbginfo->num_condition_regs = 0;
	dbginfo->data_bp_alignment = sizeof(long);
	dbginfo->sizeof_condition = 0;
	if (IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT)) {
		dbginfo->features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
		if (dawr_enabled())
			dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR;
	} else {
		dbginfo->features = 0;
	}
	if (cpu_has_feature(CPU_FTR_ARCH_31))
		dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_ARCH_31;
}

int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
			unsigned long __user *datalp)
{
	unsigned long dabr_fake;

	/* We only support one DABR and no IABRS at the moment */
	if (addr > 0)
		return -EINVAL;
	dabr_fake = ((child->thread.hw_brk[0].address & (~HW_BRK_TYPE_DABR)) |
		     (child->thread.hw_brk[0].type & HW_BRK_TYPE_DABR));
	return put_user(dabr_fake, datalp);
}

/*
 * ptrace_set_debugreg() fakes DABR and DABR is only one. So even if
 * internal hw supports more than one watchpoint, we support only one
 * watchpoint with this interface.
 */
int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, unsigned long data)
{
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	int ret;
	struct thread_struct *thread = &task->thread;
	struct perf_event *bp;
	struct perf_event_attr attr;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
	bool set_bp = true;
	struct arch_hw_breakpoint hw_brk;

	/* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
	 *  For embedded processors we support one DAC and no IAC's at the
	 *  moment.
	 */
	if (addr > 0)
		return -EINVAL;

	/* The bottom 3 bits in dabr are flags */
	if ((data & ~0x7UL) >= TASK_SIZE)
		return -EIO;

	/* For processors using DABR (i.e. 970), the bottom 3 bits are flags.
	 *  It was assumed, on previous implementations, that 3 bits were
	 *  passed together with the data address, fitting the design of the
	 *  DABR register, as follows:
	 *
	 *  bit 0: Read flag
	 *  bit 1: Write flag
	 *  bit 2: Breakpoint translation
	 *
	 *  Thus, we use them here as so.
	 */

	/* Ensure breakpoint translation bit is set */
	if (data && !(data & HW_BRK_TYPE_TRANSLATE))
		return -EIO;
	hw_brk.address = data & (~HW_BRK_TYPE_DABR);
	hw_brk.type = (data & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
	hw_brk.len = DABR_MAX_LEN;
	hw_brk.hw_len = DABR_MAX_LEN;
	set_bp = (data) && (hw_brk.type & HW_BRK_TYPE_RDWR);
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	bp = thread->ptrace_bps[0];
	if (!set_bp) {
		if (bp) {
			unregister_hw_breakpoint(bp);
			thread->ptrace_bps[0] = NULL;
		}
		return 0;
	}
	if (bp) {
		attr = bp->attr;
		attr.bp_addr = hw_brk.address;
		attr.bp_len = DABR_MAX_LEN;
		arch_bp_generic_fields(hw_brk.type, &attr.bp_type);

		/* Enable breakpoint */
		attr.disabled = false;

		ret =  modify_user_hw_breakpoint(bp, &attr);
		if (ret)
			return ret;

		thread->ptrace_bps[0] = bp;
		thread->hw_brk[0] = hw_brk;
		return 0;
	}

	/* Create a new breakpoint request if one doesn't exist already */
	hw_breakpoint_init(&attr);
	attr.bp_addr = hw_brk.address;
	attr.bp_len = DABR_MAX_LEN;
	arch_bp_generic_fields(hw_brk.type,
			       &attr.bp_type);

	thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
					       ptrace_triggered, NULL, task);
	if (IS_ERR(bp)) {
		thread->ptrace_bps[0] = NULL;
		return PTR_ERR(bp);
	}

#else /* !CONFIG_HAVE_HW_BREAKPOINT */
	if (set_bp && (!ppc_breakpoint_available()))
		return -ENODEV;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
	task->thread.hw_brk[0] = hw_brk;
	return 0;
}

#ifdef CONFIG_HAVE_HW_BREAKPOINT
static int find_empty_ptrace_bp(struct thread_struct *thread)
{
	int i;

	for (i = 0; i < nr_wp_slots(); i++) {
		if (!thread->ptrace_bps[i])
			return i;
	}
	return -1;
}
#endif

static int find_empty_hw_brk(struct thread_struct *thread)
{
	int i;

	for (i = 0; i < nr_wp_slots(); i++) {
		if (!thread->hw_brk[i].address)
			return i;
	}
	return -1;
}

long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
{
	int i;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	int len = 0;
	struct thread_struct *thread = &child->thread;
	struct perf_event *bp;
	struct perf_event_attr attr;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
	struct arch_hw_breakpoint brk;

	if (bp_info->version != 1)
		return -ENOTSUPP;
	/*
	 * We only support one data breakpoint
	 */
	if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
	    (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
	    bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
		return -EINVAL;

	if ((unsigned long)bp_info->addr >= TASK_SIZE)
		return -EIO;

	brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
	brk.type = HW_BRK_TYPE_TRANSLATE | HW_BRK_TYPE_PRIV_ALL;
	brk.len = DABR_MAX_LEN;
	brk.hw_len = DABR_MAX_LEN;
	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
		brk.type |= HW_BRK_TYPE_READ;
	if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
		brk.type |= HW_BRK_TYPE_WRITE;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
		len = bp_info->addr2 - bp_info->addr;
	else if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_EXACT)
		len = 1;
	else
		return -EINVAL;

	i = find_empty_ptrace_bp(thread);
	if (i < 0)
		return -ENOSPC;

	/* Create a new breakpoint request if one doesn't exist already */
	hw_breakpoint_init(&attr);
	attr.bp_addr = (unsigned long)bp_info->addr;
	attr.bp_len = len;
	arch_bp_generic_fields(brk.type, &attr.bp_type);

	bp = register_user_hw_breakpoint(&attr, ptrace_triggered, NULL, child);
	thread->ptrace_bps[i] = bp;
	if (IS_ERR(bp)) {
		thread->ptrace_bps[i] = NULL;
		return PTR_ERR(bp);
	}

	return i + 1;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */

	if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
		return -EINVAL;

	i = find_empty_hw_brk(&child->thread);
	if (i < 0)
		return -ENOSPC;

	if (!ppc_breakpoint_available())
		return -ENODEV;

	child->thread.hw_brk[i] = brk;

	return i + 1;
}

long ppc_del_hwdebug(struct task_struct *child, long data)
{
#ifdef CONFIG_HAVE_HW_BREAKPOINT
	int ret = 0;
	struct thread_struct *thread = &child->thread;
	struct perf_event *bp;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
	if (data < 1 || data > nr_wp_slots())
		return -EINVAL;

#ifdef CONFIG_HAVE_HW_BREAKPOINT
	bp = thread->ptrace_bps[data - 1];
	if (bp) {
		unregister_hw_breakpoint(bp);
		thread->ptrace_bps[data - 1] = NULL;
	} else {
		ret = -ENOENT;
	}
	return ret;
#else /* CONFIG_HAVE_HW_BREAKPOINT */
	if (!(child->thread.hw_brk[data - 1].flags & HW_BRK_FLAG_DISABLED) &&
	    child->thread.hw_brk[data - 1].address == 0)
		return -ENOENT;

	child->thread.hw_brk[data - 1].address = 0;
	child->thread.hw_brk[data - 1].type = 0;
	child->thread.hw_brk[data - 1].flags = 0;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */

	return 0;
}
