/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/sched.h>
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/interrupt.h>
#include <asm/sections.h>
#include <asm/ptrace.h>
#include <asm/bitops.h>
#include <asm/stacktrace.h>
#include <asm/unwind.h>

unsigned long unwind_get_return_address(struct unwind_state *state)
{
	if (unwind_done(state))
		return 0;
	return __kernel_text_address(state->ip) ? state->ip : 0;
}
EXPORT_SYMBOL_GPL(unwind_get_return_address);

static bool outside_of_stack(struct unwind_state *state, unsigned long sp)
{
	return (sp <= state->sp) ||
		(sp > state->stack_info.end - sizeof(struct stack_frame));
}

static bool update_stack_info(struct unwind_state *state, unsigned long sp)
{
	struct stack_info *info = &state->stack_info;
	unsigned long *mask = &state->stack_mask;

	/* New stack pointer leaves the current stack */
	if (get_stack_info(sp, state->task, info, mask) != 0 ||
	    !on_stack(info, sp, sizeof(struct stack_frame)))
		/* 'sp' does not point to a valid stack */
		return false;
	return true;
}

bool unwind_next_frame(struct unwind_state *state)
{
	struct stack_info *info = &state->stack_info;
	struct stack_frame *sf;
	struct pt_regs *regs;
	unsigned long sp, ip;
	bool reliable;

	regs = state->regs;
	if (unlikely(regs)) {
		if (state->reuse_sp) {
			sp = state->sp;
			state->reuse_sp = false;
		} else {
			sp = READ_ONCE_NOCHECK(regs->gprs[15]);
			if (unlikely(outside_of_stack(state, sp))) {
				if (!update_stack_info(state, sp))
					goto out_err;
			}
		}
		sf = (struct stack_frame *) sp;
		ip = READ_ONCE_NOCHECK(sf->gprs[8]);
		reliable = false;
		regs = NULL;
	} else {
		sf = (struct stack_frame *) state->sp;
		sp = READ_ONCE_NOCHECK(sf->back_chain);
		if (likely(sp)) {
			/* Non-zero back-chain points to the previous frame */
			if (unlikely(outside_of_stack(state, sp))) {
				if (!update_stack_info(state, sp))
					goto out_err;
			}
			sf = (struct stack_frame *) sp;
			ip = READ_ONCE_NOCHECK(sf->gprs[8]);
			reliable = true;
		} else {
			/* No back-chain, look for a pt_regs structure */
			sp = state->sp + STACK_FRAME_OVERHEAD;
			if (!on_stack(info, sp, sizeof(struct pt_regs)))
				goto out_stop;
			regs = (struct pt_regs *) sp;
			if (READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE)
				goto out_stop;
			ip = READ_ONCE_NOCHECK(regs->psw.addr);
			reliable = true;
		}
	}

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	/* Decode any ftrace redirection */
	if (ip == (unsigned long) return_to_handler)
		ip = ftrace_graph_ret_addr(state->task, &state->graph_idx,
					   ip, (void *) sp);
#endif

	/* Update unwind state */
	state->sp = sp;
	state->ip = ip;
	state->regs = regs;
	state->reliable = reliable;
	return true;

out_err:
	state->error = true;
out_stop:
	state->stack_info.type = STACK_TYPE_UNKNOWN;
	return false;
}
EXPORT_SYMBOL_GPL(unwind_next_frame);

void __unwind_start(struct unwind_state *state, struct task_struct *task,
		    struct pt_regs *regs, unsigned long sp)
{
	struct stack_info *info = &state->stack_info;
	unsigned long *mask = &state->stack_mask;
	bool reliable, reuse_sp;
	struct stack_frame *sf;
	unsigned long ip;

	memset(state, 0, sizeof(*state));
	state->task = task;
	state->regs = regs;

	/* Don't even attempt to start from user mode regs: */
	if (regs && user_mode(regs)) {
		info->type = STACK_TYPE_UNKNOWN;
		return;
	}

	/* Get current stack pointer and initialize stack info */
	if (get_stack_info(sp, task, info, mask) != 0 ||
	    !on_stack(info, sp, sizeof(struct stack_frame))) {
		/* Something is wrong with the stack pointer */
		info->type = STACK_TYPE_UNKNOWN;
		state->error = true;
		return;
	}

	/* Get the instruction pointer from pt_regs or the stack frame */
	if (regs) {
		ip = READ_ONCE_NOCHECK(regs->psw.addr);
		reliable = true;
		reuse_sp = true;
	} else {
		sf = (struct stack_frame *) sp;
		ip = READ_ONCE_NOCHECK(sf->gprs[8]);
		reliable = false;
		reuse_sp = false;
	}

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
	/* Decode any ftrace redirection */
	if (ip == (unsigned long) return_to_handler)
		ip = ftrace_graph_ret_addr(state->task, &state->graph_idx,
					   ip, NULL);
#endif

	/* Update unwind state */
	state->sp = sp;
	state->ip = ip;
	state->reliable = reliable;
	state->reuse_sp = reuse_sp;
}
EXPORT_SYMBOL_GPL(__unwind_start);
