/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Based on arch/arm/include/asm/traps.h
 *
 * Copyright (C) 2012 ARM Ltd.
 */
#ifndef __ASM_TRAP_H
#define __ASM_TRAP_H

#include <linux/list.h>
#include <asm/esr.h>
#include <asm/ptrace.h>
#include <asm/sections.h>

#ifdef CONFIG_ARMV8_DEPRECATED
bool try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn);
#else
static inline bool
try_emulate_armv8_deprecated(struct pt_regs *regs, u32 insn)
{
	return false;
}
#endif /* CONFIG_ARMV8_DEPRECATED */

void force_signal_inject(int signal, int code, unsigned long address, unsigned long err);
void arm64_notify_segfault(unsigned long addr);
void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str);
void arm64_force_sig_fault_pkey(unsigned long far, const char *str, int pkey);
void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str);
void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str);

int bug_brk_handler(struct pt_regs *regs, unsigned long esr);
int cfi_brk_handler(struct pt_regs *regs, unsigned long esr);
int reserved_fault_brk_handler(struct pt_regs *regs, unsigned long esr);
int kasan_brk_handler(struct pt_regs *regs, unsigned long esr);
int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr);

int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs);

/*
 * Move regs->pc to next instruction and do necessary setup before it
 * is executed.
 */
void arm64_skip_faulting_instruction(struct pt_regs *regs, unsigned long size);

static inline int __in_irqentry_text(unsigned long ptr)
{
	return ptr >= (unsigned long)&__irqentry_text_start &&
	       ptr < (unsigned long)&__irqentry_text_end;
}

static inline int in_entry_text(unsigned long ptr)
{
	return ptr >= (unsigned long)&__entry_text_start &&
	       ptr < (unsigned long)&__entry_text_end;
}

/*
 * CPUs with the RAS extensions have an Implementation-Defined-Syndrome bit
 * to indicate whether this ESR has a RAS encoding. CPUs without this feature
 * have a ISS-Valid bit in the same position.
 * If this bit is set, we know its not a RAS SError.
 * If its clear, we need to know if the CPU supports RAS. Uncategorized RAS
 * errors share the same encoding as an all-zeros encoding from a CPU that
 * doesn't support RAS.
 */
static inline bool arm64_is_ras_serror(unsigned long esr)
{
	WARN_ON(preemptible());

	if (esr & ESR_ELx_IDS)
		return false;

	if (this_cpu_has_cap(ARM64_HAS_RAS_EXTN))
		return true;
	else
		return false;
}

/*
 * Return the AET bits from a RAS SError's ESR.
 *
 * It is implementation defined whether Uncategorized errors are containable.
 * We treat them as Uncontainable.
 * Non-RAS SError's are reported as Uncontained/Uncategorized.
 */
static inline unsigned long arm64_ras_serror_get_severity(unsigned long esr)
{
	unsigned long aet = esr & ESR_ELx_AET;

	if (!arm64_is_ras_serror(esr)) {
		/* Not a RAS error, we can't interpret the ESR. */
		return ESR_ELx_AET_UC;
	}

	/*
	 * AET is RES0 if 'the value returned in the DFSC field is not
	 * [ESR_ELx_FSC_SERROR]'
	 */
	if ((esr & ESR_ELx_FSC) != ESR_ELx_FSC_SERROR) {
		/* No severity information : Uncategorized */
		return ESR_ELx_AET_UC;
	}

	return aet;
}

bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned long esr);
void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr);

static inline void arm64_mops_reset_regs(struct user_pt_regs *regs, unsigned long esr)
{
	bool wrong_option = esr & ESR_ELx_MOPS_ISS_WRONG_OPTION;
	bool option_a = esr & ESR_ELx_MOPS_ISS_OPTION_A;
	int dstreg = ESR_ELx_MOPS_ISS_DESTREG(esr);
	int srcreg = ESR_ELx_MOPS_ISS_SRCREG(esr);
	int sizereg = ESR_ELx_MOPS_ISS_SIZEREG(esr);
	unsigned long dst, size;

	dst = regs->regs[dstreg];
	size = regs->regs[sizereg];

	/*
	 * Put the registers back in the original format suitable for a
	 * prologue instruction, using the generic return routine from the
	 * Arm ARM (DDI 0487I.a) rules CNTMJ and MWFQH.
	 */
	if (esr & ESR_ELx_MOPS_ISS_MEM_INST) {
		/* SET* instruction */
		if (option_a ^ wrong_option) {
			/* Format is from Option A; forward set */
			regs->regs[dstreg] = dst + size;
			regs->regs[sizereg] = -size;
		}
	} else {
		/* CPY* instruction */
		unsigned long src = regs->regs[srcreg];
		if (!(option_a ^ wrong_option)) {
			/* Format is from Option B */
			if (regs->pstate & PSR_N_BIT) {
				/* Backward copy */
				regs->regs[dstreg] = dst - size;
				regs->regs[srcreg] = src - size;
			}
		} else {
			/* Format is from Option A */
			if (size & BIT(63)) {
				/* Forward copy */
				regs->regs[dstreg] = dst + size;
				regs->regs[srcreg] = src + size;
				regs->regs[sizereg] = -size;
			}
		}
	}

	if (esr & ESR_ELx_MOPS_ISS_FROM_EPILOGUE)
		regs->pc -= 8;
	else
		regs->pc -= 4;
}
#endif
