// SPDX-License-Identifier: GPL-2.0-only
/*
 * KVM nVHE hypervisor stack tracing support.
 *
 * Copyright (C) 2022 Google LLC
 */
#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
#include <asm/memory.h>
#include <asm/percpu.h>

DEFINE_PER_CPU(unsigned long [OVERFLOW_STACK_SIZE/sizeof(long)], overflow_stack)
	__aligned(16);

DEFINE_PER_CPU(struct kvm_nvhe_stacktrace_info, kvm_stacktrace_info);

/*
 * hyp_prepare_backtrace - Prepare non-protected nVHE backtrace.
 *
 * @fp : frame pointer at which to start the unwinding.
 * @pc : program counter at which to start the unwinding.
 *
 * Save the information needed by the host to unwind the non-protected
 * nVHE hypervisor stack in EL1.
 */
static void hyp_prepare_backtrace(unsigned long fp, unsigned long pc)
{
	struct kvm_nvhe_stacktrace_info *stacktrace_info = this_cpu_ptr(&kvm_stacktrace_info);
	struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params);

	stacktrace_info->stack_base = (unsigned long)(params->stack_hyp_va - PAGE_SIZE);
	stacktrace_info->overflow_stack_base = (unsigned long)this_cpu_ptr(overflow_stack);
	stacktrace_info->fp = fp;
	stacktrace_info->pc = pc;
}

#ifdef CONFIG_PROTECTED_NVHE_STACKTRACE
#include <asm/stacktrace/nvhe.h>

DEFINE_PER_CPU(unsigned long [NVHE_STACKTRACE_SIZE/sizeof(long)], pkvm_stacktrace);

static bool on_overflow_stack(unsigned long sp, unsigned long size,
			      struct stack_info *info)
{
	unsigned long low = (unsigned long)this_cpu_ptr(overflow_stack);
	unsigned long high = low + OVERFLOW_STACK_SIZE;

	return on_stack(sp, size, low, high, STACK_TYPE_OVERFLOW, info);
}

static bool on_hyp_stack(unsigned long sp, unsigned long size,
			      struct stack_info *info)
{
	struct kvm_nvhe_init_params *params = this_cpu_ptr(&kvm_init_params);
	unsigned long high = params->stack_hyp_va;
	unsigned long low = high - PAGE_SIZE;

	return on_stack(sp, size, low, high, STACK_TYPE_HYP, info);
}

static bool on_accessible_stack(const struct task_struct *tsk,
				unsigned long sp, unsigned long size,
				struct stack_info *info)
{
	if (info)
		info->type = STACK_TYPE_UNKNOWN;

	return (on_overflow_stack(sp, size, info) ||
		on_hyp_stack(sp, size, info));
}

static int unwind_next(struct unwind_state *state)
{
	struct stack_info info;

	return unwind_next_common(state, &info, on_accessible_stack, NULL);
}

static void notrace unwind(struct unwind_state *state,
			   stack_trace_consume_fn consume_entry,
			   void *cookie)
{
	while (1) {
		int ret;

		if (!consume_entry(cookie, state->pc))
			break;
		ret = unwind_next(state);
		if (ret < 0)
			break;
	}
}

/*
 * pkvm_save_backtrace_entry - Saves a protected nVHE HYP stacktrace entry
 *
 * @arg    : index of the entry in the stacktrace buffer
 * @where  : the program counter corresponding to the stack frame
 *
 * Save the return address of a stack frame to the shared stacktrace buffer.
 * The host can access this shared buffer from EL1 to dump the backtrace.
 */
static bool pkvm_save_backtrace_entry(void *arg, unsigned long where)
{
	unsigned long *stacktrace = this_cpu_ptr(pkvm_stacktrace);
	int *idx = (int *)arg;

	/*
	 * Need 2 free slots: 1 for current entry and 1 for the
	 * delimiter.
	 */
	if (*idx > ARRAY_SIZE(pkvm_stacktrace) - 2)
		return false;

	stacktrace[*idx] = where;
	stacktrace[++*idx] = 0UL;

	return true;
}

/*
 * pkvm_save_backtrace - Saves the protected nVHE HYP stacktrace
 *
 * @fp : frame pointer at which to start the unwinding.
 * @pc : program counter at which to start the unwinding.
 *
 * Save the unwinded stack addresses to the shared stacktrace buffer.
 * The host can access this shared buffer from EL1 to dump the backtrace.
 */
static void pkvm_save_backtrace(unsigned long fp, unsigned long pc)
{
	struct unwind_state state;
	int idx = 0;

	kvm_nvhe_unwind_init(&state, fp, pc);

	unwind(&state, pkvm_save_backtrace_entry, &idx);
}
#else /* !CONFIG_PROTECTED_NVHE_STACKTRACE */
static void pkvm_save_backtrace(unsigned long fp, unsigned long pc)
{
}
#endif /* CONFIG_PROTECTED_NVHE_STACKTRACE */

/*
 * kvm_nvhe_prepare_backtrace - prepare to dump the nVHE backtrace
 *
 * @fp : frame pointer at which to start the unwinding.
 * @pc : program counter at which to start the unwinding.
 *
 * Saves the information needed by the host to dump the nVHE hypervisor
 * backtrace.
 */
void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc)
{
	if (is_protected_kvm_enabled())
		pkvm_save_backtrace(fp, pc);
	else
		hyp_prepare_backtrace(fp, pc);
}
