troubleshoot.c (6250B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 4 */ 5 6#include <linux/ptrace.h> 7#include <linux/module.h> 8#include <linux/mm.h> 9#include <linux/fs.h> 10#include <linux/kdev_t.h> 11#include <linux/proc_fs.h> 12#include <linux/file.h> 13#include <linux/sched/mm.h> 14#include <linux/sched/debug.h> 15 16#include <asm/arcregs.h> 17#include <asm/irqflags.h> 18 19#define ARC_PATH_MAX 256 20 21static noinline void print_regs_scratch(struct pt_regs *regs) 22{ 23 pr_cont("BTA: 0x%08lx\n SP: 0x%08lx FP: 0x%08lx BLK: %pS\n", 24 regs->bta, regs->sp, regs->fp, (void *)regs->blink); 25 pr_cont("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", 26 regs->lp_start, regs->lp_end, regs->lp_count); 27 28 pr_info("r00: 0x%08lx\tr01: 0x%08lx\tr02: 0x%08lx\n" \ 29 "r03: 0x%08lx\tr04: 0x%08lx\tr05: 0x%08lx\n" \ 30 "r06: 0x%08lx\tr07: 0x%08lx\tr08: 0x%08lx\n" \ 31 "r09: 0x%08lx\tr10: 0x%08lx\tr11: 0x%08lx\n" \ 32 "r12: 0x%08lx\t", 33 regs->r0, regs->r1, regs->r2, 34 regs->r3, regs->r4, regs->r5, 35 regs->r6, regs->r7, regs->r8, 36 regs->r9, regs->r10, regs->r11, 37 regs->r12); 38} 39 40static void print_regs_callee(struct callee_regs *regs) 41{ 42 pr_cont("r13: 0x%08lx\tr14: 0x%08lx\n" \ 43 "r15: 0x%08lx\tr16: 0x%08lx\tr17: 0x%08lx\n" \ 44 "r18: 0x%08lx\tr19: 0x%08lx\tr20: 0x%08lx\n" \ 45 "r21: 0x%08lx\tr22: 0x%08lx\tr23: 0x%08lx\n" \ 46 "r24: 0x%08lx\tr25: 0x%08lx\n", 47 regs->r13, regs->r14, 48 regs->r15, regs->r16, regs->r17, 49 regs->r18, regs->r19, regs->r20, 50 regs->r21, regs->r22, regs->r23, 51 regs->r24, regs->r25); 52} 53 54static void print_task_path_n_nm(struct task_struct *tsk) 55{ 56 char *path_nm = NULL; 57 struct mm_struct *mm; 58 struct file *exe_file; 59 char buf[ARC_PATH_MAX]; 60 61 mm = get_task_mm(tsk); 62 if (!mm) 63 goto done; 64 65 exe_file = get_mm_exe_file(mm); 66 mmput(mm); 67 68 if (exe_file) { 69 path_nm = file_path(exe_file, buf, ARC_PATH_MAX-1); 70 fput(exe_file); 71 } 72 73done: 74 pr_info("Path: %s\n", !IS_ERR(path_nm) ? path_nm : "?"); 75} 76 77static void show_faulting_vma(unsigned long address) 78{ 79 struct vm_area_struct *vma; 80 struct mm_struct *active_mm = current->active_mm; 81 82 /* can't use print_vma_addr() yet as it doesn't check for 83 * non-inclusive vma 84 */ 85 mmap_read_lock(active_mm); 86 vma = vma_lookup(active_mm, address); 87 88 /* Lookup the vma at the address and report if the container VMA is not 89 * found 90 */ 91 if (vma) { 92 char buf[ARC_PATH_MAX]; 93 char *nm = "?"; 94 95 if (vma->vm_file) { 96 nm = file_path(vma->vm_file, buf, ARC_PATH_MAX-1); 97 if (IS_ERR(nm)) 98 nm = "?"; 99 } 100 pr_info(" @off 0x%lx in [%s] VMA: 0x%08lx to 0x%08lx\n", 101 vma->vm_start < TASK_UNMAPPED_BASE ? 102 address : address - vma->vm_start, 103 nm, vma->vm_start, vma->vm_end); 104 } else 105 pr_info(" @No matching VMA found\n"); 106 107 mmap_read_unlock(active_mm); 108} 109 110static void show_ecr_verbose(struct pt_regs *regs) 111{ 112 unsigned int vec, cause_code; 113 unsigned long address; 114 115 /* For Data fault, this is data address not instruction addr */ 116 address = current->thread.fault_address; 117 118 vec = regs->ecr_vec; 119 cause_code = regs->ecr_cause; 120 121 /* For DTLB Miss or ProtV, display the memory involved too */ 122 if (vec == ECR_V_DTLB_MISS) { 123 pr_cont("Invalid %s @ 0x%08lx by insn @ %pS\n", 124 (cause_code == 0x01) ? "Read" : 125 ((cause_code == 0x02) ? "Write" : "EX"), 126 address, (void *)regs->ret); 127 } else if (vec == ECR_V_ITLB_MISS) { 128 pr_cont("Insn could not be fetched\n"); 129 } else if (vec == ECR_V_MACH_CHK) { 130 pr_cont("Machine Check (%s)\n", (cause_code == 0x0) ? 131 "Double Fault" : "Other Fatal Err"); 132 133 } else if (vec == ECR_V_PROTV) { 134 if (cause_code == ECR_C_PROTV_INST_FETCH) 135 pr_cont("Execute from Non-exec Page\n"); 136 else if (cause_code == ECR_C_PROTV_MISALIG_DATA && 137 IS_ENABLED(CONFIG_ISA_ARCOMPACT)) 138 pr_cont("Misaligned r/w from 0x%08lx\n", address); 139 else 140 pr_cont("%s access not allowed on page\n", 141 (cause_code == 0x01) ? "Read" : 142 ((cause_code == 0x02) ? "Write" : "EX")); 143 } else if (vec == ECR_V_INSN_ERR) { 144 pr_cont("Illegal Insn\n"); 145#ifdef CONFIG_ISA_ARCV2 146 } else if (vec == ECR_V_MEM_ERR) { 147 if (cause_code == 0x00) 148 pr_cont("Bus Error from Insn Mem\n"); 149 else if (cause_code == 0x10) 150 pr_cont("Bus Error from Data Mem\n"); 151 else 152 pr_cont("Bus Error, check PRM\n"); 153 } else if (vec == ECR_V_MISALIGN) { 154 pr_cont("Misaligned r/w from 0x%08lx\n", address); 155#endif 156 } else if (vec == ECR_V_TRAP) { 157 if (regs->ecr_param == 5) 158 pr_cont("gcc generated __builtin_trap\n"); 159 } else { 160 pr_cont("Check Programmer's Manual\n"); 161 } 162} 163 164/************************************************************************ 165 * API called by rest of kernel 166 ***********************************************************************/ 167 168void show_regs(struct pt_regs *regs) 169{ 170 struct task_struct *tsk = current; 171 struct callee_regs *cregs = (struct callee_regs *)tsk->thread.callee_reg; 172 173 /* 174 * generic code calls us with preemption disabled, but some calls 175 * here could sleep, so re-enable to avoid lockdep splat 176 */ 177 preempt_enable(); 178 179 print_task_path_n_nm(tsk); 180 show_regs_print_info(KERN_INFO); 181 182 show_ecr_verbose(regs); 183 184 if (user_mode(regs)) 185 show_faulting_vma(regs->ret); /* faulting code, not data */ 186 187 pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\nSTAT: 0x%08lx", 188 regs->event, current->thread.fault_address, regs->ret, 189 regs->status32); 190 191#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" 192 193#ifdef CONFIG_ISA_ARCOMPACT 194 pr_cont(" [%2s%2s%2s%2s%2s%2s%2s]", 195 (regs->status32 & STATUS_U_MASK) ? "U " : "K ", 196 STS_BIT(regs, DE), STS_BIT(regs, AE), 197 STS_BIT(regs, A2), STS_BIT(regs, A1), 198 STS_BIT(regs, E2), STS_BIT(regs, E1)); 199#else 200 pr_cont(" [%2s%2s%2s%2s] ", 201 STS_BIT(regs, IE), 202 (regs->status32 & STATUS_U_MASK) ? "U " : "K ", 203 STS_BIT(regs, DE), STS_BIT(regs, AE)); 204#endif 205 206 print_regs_scratch(regs); 207 if (cregs) 208 print_regs_callee(cregs); 209 210 preempt_disable(); 211} 212 213void show_kernel_fault_diag(const char *str, struct pt_regs *regs, 214 unsigned long address) 215{ 216 current->thread.fault_address = address; 217 218 /* Show fault description */ 219 pr_info("\n%s\n", str); 220 221 /* Caller and Callee regs */ 222 show_regs(regs); 223 224 /* Show stack trace if this Fatality happened in kernel mode */ 225 if (!user_mode(regs)) 226 show_stacktrace(current, regs, KERN_DEFAULT); 227}