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

static inline bool is_task_pt_regs(struct unwind_state *state,
				   struct pt_regs *regs)
{
	return task_pt_regs(state->task) == regs;
}

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)) {
		sp = state->sp;
		sf = (struct stack_frame *) sp;
		ip = READ_ONCE_NOCHECK(sf->gprs[8]);
		reliable = false;
		regs = NULL;
		if (!__kernel_text_address(ip)) {
			/* skip bogus %r14 */
			state->regs = NULL;
			return unwind_next_frame(state);
		}
	} 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_err;
			regs = (struct pt_regs *) sp;
			if (is_task_pt_regs(state, regs))
				goto out_stop;
			ip = READ_ONCE_NOCHECK(regs->psw.addr);
			sp = READ_ONCE_NOCHECK(regs->gprs[15]);
			if (unlikely(outside_of_stack(state, sp))) {
				if (!update_stack_info(state, sp))
					goto out_err;
			}
			reliable = true;
		}
	}

	/* Sanity check: ABI requires SP to be aligned 8 bytes. */
	if (sp & 0x7)
		goto out_err;

	ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, (void *) sp);

	/* 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 first_frame)
{
	struct stack_info *info = &state->stack_info;
	struct stack_frame *sf;
	unsigned long ip, sp;

	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 the instruction pointer from pt_regs or the stack frame */
	if (regs) {
		ip = regs->psw.addr;
		sp = regs->gprs[15];
	} else if (task == current) {
		sp = current_frame_address();
	} else {
		sp = task->thread.ksp;
	}

	/* Get current stack pointer and initialize stack info */
	if (!update_stack_info(state, sp)) {
		/* Something is wrong with the stack pointer */
		info->type = STACK_TYPE_UNKNOWN;
		state->error = true;
		return;
	}

	if (!regs) {
		/* Stack frame is within valid stack */
		sf = (struct stack_frame *)sp;
		ip = READ_ONCE_NOCHECK(sf->gprs[8]);
	}

	ip = ftrace_graph_ret_addr(state->task, &state->graph_idx, ip, NULL);

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

	if (!first_frame)
		return;
	/* Skip through the call chain to the specified starting frame */
	while (!unwind_done(state)) {
		if (on_stack(&state->stack_info, first_frame, sizeof(struct stack_frame))) {
			if (state->sp >= first_frame)
				break;
		}
		unwind_next_frame(state);
	}
}
EXPORT_SYMBOL_GPL(__unwind_start);
