// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 */

#include <linux/ptrace.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/proc_fs.h>
#include <linux/file.h>
#include <linux/sched/mm.h>
#include <linux/sched/debug.h>

#include <asm/arcregs.h>
#include <asm/irqflags.h>

#define ARC_PATH_MAX	256

static noinline void print_regs_scratch(struct pt_regs *regs)
{
	pr_cont("BTA: 0x%08lx\n SP: 0x%08lx  FP: 0x%08lx BLK: %pS\n",
		regs->bta, regs->sp, regs->fp, (void *)regs->blink);
	pr_cont("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
		regs->lp_start, regs->lp_end, regs->lp_count);

	pr_info("r00: 0x%08lx\tr01: 0x%08lx\tr02: 0x%08lx\n"	\
		"r03: 0x%08lx\tr04: 0x%08lx\tr05: 0x%08lx\n"	\
		"r06: 0x%08lx\tr07: 0x%08lx\tr08: 0x%08lx\n"	\
		"r09: 0x%08lx\tr10: 0x%08lx\tr11: 0x%08lx\n"	\
		"r12: 0x%08lx\t",
		regs->r0, regs->r1, regs->r2,
		regs->r3, regs->r4, regs->r5,
		regs->r6, regs->r7, regs->r8,
		regs->r9, regs->r10, regs->r11,
		regs->r12);
}

static void print_regs_callee(struct callee_regs *regs)
{
	pr_cont("r13: 0x%08lx\tr14: 0x%08lx\n"			\
		"r15: 0x%08lx\tr16: 0x%08lx\tr17: 0x%08lx\n"	\
		"r18: 0x%08lx\tr19: 0x%08lx\tr20: 0x%08lx\n"	\
		"r21: 0x%08lx\tr22: 0x%08lx\tr23: 0x%08lx\n"	\
		"r24: 0x%08lx\tr25: 0x%08lx\n",
		regs->r13, regs->r14,
		regs->r15, regs->r16, regs->r17,
		regs->r18, regs->r19, regs->r20,
		regs->r21, regs->r22, regs->r23,
		regs->r24, regs->r25);
}

static void print_task_path_n_nm(struct task_struct *tsk)
{
	char *path_nm = NULL;
	struct mm_struct *mm;
	struct file *exe_file;
	char buf[ARC_PATH_MAX];

	mm = get_task_mm(tsk);
	if (!mm)
		goto done;

	exe_file = get_mm_exe_file(mm);
	mmput(mm);

	if (exe_file) {
		path_nm = file_path(exe_file, buf, ARC_PATH_MAX-1);
		fput(exe_file);
	}

done:
	pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?");
}

static void show_faulting_vma(unsigned long address)
{
	struct vm_area_struct *vma;
	struct mm_struct *active_mm = current->active_mm;

	/* can't use print_vma_addr() yet as it doesn't check for
	 * non-inclusive vma
	 */
	mmap_read_lock(active_mm);
	vma = vma_lookup(active_mm, address);

	/* Lookup the vma at the address and report if the container VMA is not
	 * found
	 */
	if (vma) {
		char buf[ARC_PATH_MAX];
		char *nm = "anon";

		if (vma->vm_file) {
			/* XXX: can we use %pD below and get rid of buf? */
			nm = d_path(file_user_path(vma->vm_file), buf,
				    ARC_PATH_MAX-1);
			if (IS_ERR(nm))
				nm = "?";
		}
		pr_info("  @off 0x%lx in [%s]  VMA: 0x%08lx to 0x%08lx\n",
			vma->vm_start < TASK_UNMAPPED_BASE ?
				address : address - vma->vm_start,
			nm, vma->vm_start, vma->vm_end);
	} else
		pr_info("    @No matching VMA found\n");

	mmap_read_unlock(active_mm);
}

static void show_ecr_verbose(struct pt_regs *regs)
{
	unsigned int vec, cause_code;
	unsigned long address;

	/* For Data fault, this is data address not instruction addr */
	address = current->thread.fault_address;

	vec = regs->ecr.vec;
	cause_code = regs->ecr.cause;

	/* For DTLB Miss or ProtV, display the memory involved too */
	if (vec == ECR_V_DTLB_MISS) {
		pr_cont("Invalid %s @ 0x%08lx by insn @ %pS\n",
		       (cause_code == 0x01) ? "Read" :
		       ((cause_code == 0x02) ? "Write" : "EX"),
		       address, (void *)regs->ret);
	} else if (vec == ECR_V_ITLB_MISS) {
		pr_cont("Insn could not be fetched\n");
	} else if (vec == ECR_V_MACH_CHK) {
		pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ?
					"Double Fault" : "Other Fatal Err");

	} else if (vec == ECR_V_PROTV) {
		if (cause_code == ECR_C_PROTV_INST_FETCH)
			pr_cont("Execute from Non-exec Page\n");
		else if (cause_code == ECR_C_PROTV_MISALIG_DATA &&
		         IS_ENABLED(CONFIG_ISA_ARCOMPACT))
			pr_cont("Misaligned r/w from 0x%08lx\n", address);
		else
			pr_cont("%s access not allowed on page\n",
				(cause_code == 0x01) ? "Read" :
				((cause_code == 0x02) ? "Write" : "EX"));
	} else if (vec == ECR_V_INSN_ERR) {
		pr_cont("Illegal Insn\n");
#ifdef CONFIG_ISA_ARCV2
	} else if (vec == ECR_V_MEM_ERR) {
		if (cause_code == 0x00)
			pr_cont("Bus Error from Insn Mem\n");
		else if (cause_code == 0x10)
			pr_cont("Bus Error from Data Mem\n");
		else
			pr_cont("Bus Error, check PRM\n");
	} else if (vec == ECR_V_MISALIGN) {
		pr_cont("Misaligned r/w from 0x%08lx\n", address);
#endif
	} else if (vec == ECR_V_TRAP) {
		if (regs->ecr.param == 5)
			pr_cont("gcc generated __builtin_trap\n");
	} else {
		pr_cont("Check Programmer's Manual\n");
	}
}

/************************************************************************
 *  API called by rest of kernel
 ***********************************************************************/

void show_regs(struct pt_regs *regs)
{
	struct task_struct *tsk = current;
	struct callee_regs *cregs = (struct callee_regs *)tsk->thread.callee_reg;

	/*
	 * generic code calls us with preemption disabled, but some calls
	 * here could sleep, so re-enable to avoid lockdep splat
	 */
	preempt_enable();

	print_task_path_n_nm(tsk);
	show_regs_print_info(KERN_INFO);

	show_ecr_verbose(regs);

	if (user_mode(regs))
		show_faulting_vma(regs->ret); /* faulting code, not data */

	pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n",
		regs->ecr.full, current->thread.fault_address, regs->ret);

	pr_info("STAT32: 0x%08lx", regs->status32);

#define STS_BIT(r, bit)	r->status32 & STATUS_##bit##_MASK ? #bit" " : ""

#ifdef CONFIG_ISA_ARCOMPACT
	pr_cont(" [%2s%2s%2s%2s%2s%2s%2s]",
			(regs->status32 & STATUS_U_MASK) ? "U " : "K ",
			STS_BIT(regs, DE), STS_BIT(regs, AE),
			STS_BIT(regs, A2), STS_BIT(regs, A1),
			STS_BIT(regs, E2), STS_BIT(regs, E1));
#else
	pr_cont(" [%2s%2s%2s%2s]   ",
			STS_BIT(regs, IE),
			(regs->status32 & STATUS_U_MASK) ? "U " : "K ",
			STS_BIT(regs, DE), STS_BIT(regs, AE));
#endif

	print_regs_scratch(regs);
	if (cregs)
		print_regs_callee(cregs);

	preempt_disable();
}

void show_kernel_fault_diag(const char *str, struct pt_regs *regs,
			    unsigned long address)
{
	current->thread.fault_address = address;

	/* Show fault description */
	pr_info("\n%s\n", str);

	/* Caller and Callee regs */
	show_regs(regs);

	/* Show stack trace if this Fatality happened in kernel mode */
	if (!user_mode(regs))
		show_stacktrace(current, regs, KERN_DEFAULT);
}
