// 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 = "?";

		if (vma->vm_file) {
			nm = file_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\nSTAT: 0x%08lx",
		regs->event, current->thread.fault_address, regs->ret,
		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);
}
