aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2013-03-22 07:46:49 -0400
committerVineet Gupta <vgupta@synopsys.com>2013-05-07 04:13:54 -0400
commitbd3c8b11eccddd311c9e6a56aa00c1af24ea5958 (patch)
tree0f3374e644f51d63cd9744718a7a65d9f480b896 /arch/arc/kernel
parent68e4790ec4383c57224d69ed9e0a94e4ef005f35 (diff)
ARC: Debug/crash-printing Improvements
* Remove the line-break between scratch/callee-regs (sneaked in when we converted from printk to pr_* * Use %pS to print the symbol names of faulting PC (ret pseudo register) and BLINK (call return register) * Don't print user-vma for a kernel crash (only do it for print-fatal-signals based regfile dump) * Verbose print the Interrupt/Exception Enable/Active state * for main executable link address is 0x10000 based (vs. 0) thus offset of faulting PC needs to be adjusted Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel')
-rw-r--r--arch/arc/kernel/troubleshoot.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/arch/arc/kernel/troubleshoot.c b/arch/arc/kernel/troubleshoot.c
index 7c10873c311f..a39d5812cc09 100644
--- a/arch/arc/kernel/troubleshoot.c
+++ b/arch/arc/kernel/troubleshoot.c
@@ -26,7 +26,6 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
26 char buf[512]; 26 char buf[512];
27 int n = 0, len = sizeof(buf); 27 int n = 0, len = sizeof(buf);
28 28
29 /* weird loop because pt_regs regs rev r12..r0, r25..r13 */
30 for (i = start_num; i < start_num + 13; i++) { 29 for (i = start_num; i < start_num + 13; i++) {
31 n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t", 30 n += scnprintf(buf + n, len - n, "r%02u: 0x%08lx\t",
32 i, (unsigned long)*reg_rev); 31 i, (unsigned long)*reg_rev);
@@ -34,13 +33,18 @@ static noinline void print_reg_file(long *reg_rev, int start_num)
34 if (((i + 1) % 3) == 0) 33 if (((i + 1) % 3) == 0)
35 n += scnprintf(buf + n, len - n, "\n"); 34 n += scnprintf(buf + n, len - n, "\n");
36 35
36 /* because pt_regs has regs reversed: r12..r0, r25..r13 */
37 reg_rev--; 37 reg_rev--;
38 } 38 }
39 39
40 if (start_num != 0) 40 if (start_num != 0)
41 n += scnprintf(buf + n, len - n, "\n\n"); 41 n += scnprintf(buf + n, len - n, "\n\n");
42 42
43 pr_info("%s", buf); 43 /* To continue printing callee regs on same line as scratch regs */
44 if (start_num == 0)
45 pr_info("%s", buf);
46 else
47 pr_cont("%s\n", buf);
44} 48}
45 49
46static void show_callee_regs(struct callee_regs *cregs) 50static void show_callee_regs(struct callee_regs *cregs)
@@ -83,6 +87,10 @@ static void show_faulting_vma(unsigned long address, char *buf)
83 dev_t dev = 0; 87 dev_t dev = 0;
84 char *nm = buf; 88 char *nm = buf;
85 89
90 /* can't use print_vma_addr() yet as it doesn't check for
91 * non-inclusive vma
92 */
93
86 vma = find_vma(current->active_mm, address); 94 vma = find_vma(current->active_mm, address);
87 95
88 /* check against the find_vma( ) behaviour which returns the next VMA 96 /* check against the find_vma( ) behaviour which returns the next VMA
@@ -98,10 +106,13 @@ static void show_faulting_vma(unsigned long address, char *buf)
98 ino = inode->i_ino; 106 ino = inode->i_ino;
99 } 107 }
100 pr_info(" @off 0x%lx in [%s]\n" 108 pr_info(" @off 0x%lx in [%s]\n"
101 " VMA: 0x%08lx to 0x%08lx\n\n", 109 " VMA: 0x%08lx to 0x%08lx\n",
102 address - vma->vm_start, nm, vma->vm_start, vma->vm_end); 110 vma->vm_start < TASK_UNMAPPED_BASE ?
103 } else 111 address : address - vma->vm_start,
112 nm, vma->vm_start, vma->vm_end);
113 } else {
104 pr_info(" @No matching VMA found\n"); 114 pr_info(" @No matching VMA found\n");
115 }
105} 116}
106 117
107static void show_ecr_verbose(struct pt_regs *regs) 118static void show_ecr_verbose(struct pt_regs *regs)
@@ -110,7 +121,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
110 unsigned long address; 121 unsigned long address;
111 122
112 cause_reg = current->thread.cause_code; 123 cause_reg = current->thread.cause_code;
113 pr_info("\n[ECR]: 0x%08x => ", cause_reg); 124 pr_info("\n[ECR ]: 0x%08x => ", cause_reg);
114 125
115 /* For Data fault, this is data address not instruction addr */ 126 /* For Data fault, this is data address not instruction addr */
116 address = current->thread.fault_address; 127 address = current->thread.fault_address;
@@ -120,7 +131,7 @@ static void show_ecr_verbose(struct pt_regs *regs)
120 131
121 /* For DTLB Miss or ProtV, display the memory involved too */ 132 /* For DTLB Miss or ProtV, display the memory involved too */
122 if (vec == ECR_V_DTLB_MISS) { 133 if (vec == ECR_V_DTLB_MISS) {
123 pr_cont("Invalid (%s) @ 0x%08lx by insn @ 0x%08lx\n", 134 pr_cont("Invalid %s 0x%08lx by insn @ 0x%08lx\n",
124 (cause_code == 0x01) ? "Read From" : 135 (cause_code == 0x01) ? "Read From" :
125 ((cause_code == 0x02) ? "Write to" : "EX"), 136 ((cause_code == 0x02) ? "Write to" : "EX"),
126 address, regs->ret); 137 address, regs->ret);
@@ -167,20 +178,23 @@ void show_regs(struct pt_regs *regs)
167 if (current->thread.cause_code) 178 if (current->thread.cause_code)
168 show_ecr_verbose(regs); 179 show_ecr_verbose(regs);
169 180
170 pr_info("[EFA]: 0x%08lx\n", current->thread.fault_address); 181 pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n",
171 pr_info("[ERET]: 0x%08lx (PC of Faulting Instr)\n", regs->ret); 182 current->thread.fault_address,
183 (void *)regs->blink, (void *)regs->ret);
172 184
173 show_faulting_vma(regs->ret, buf); /* faulting code, not data */ 185 if (user_mode(regs))
186 show_faulting_vma(regs->ret, buf); /* faulting code, not data */
174 187
175 /* can't use print_vma_addr() yet as it doesn't check for 188 pr_info("[STAT32]: 0x%08lx", regs->status32);
176 * non-inclusive vma 189
177 */ 190#define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit : ""
191 if (!user_mode(regs))
192 pr_cont(" : %2s %2s %2s %2s %2s\n",
193 STS_BIT(regs, AE), STS_BIT(regs, A2), STS_BIT(regs, A1),
194 STS_BIT(regs, E2), STS_BIT(regs, E1));
178 195
179 /* print special regs */ 196 pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n",
180 pr_info("status32: 0x%08lx\n", regs->status32); 197 regs->bta, regs->sp, regs->fp);
181 pr_info(" SP: 0x%08lx\tFP: 0x%08lx\n", regs->sp, regs->fp);
182 pr_info("BTA: 0x%08lx\tBLINK: 0x%08lx\n",
183 regs->bta, regs->blink);
184 pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", 198 pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n",
185 regs->lp_start, regs->lp_end, regs->lp_count); 199 regs->lp_start, regs->lp_end, regs->lp_count);
186 200