aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>2013-10-08 07:39:31 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-10-29 16:25:35 -0400
commit83e4da1ed45441c3aadc39ac47d33895ab23c841 (patch)
tree50bef4e0e7482196fb59a6b87845a4c00dd183ae /arch/mips/kernel/traps.c
parentd9f897c912b4108076afb00036a139e3b8144a64 (diff)
MIPS: Print correct PC in trace dump after NMI exception
An NMI exception delivered from YAMON delivers the PC in ErrorPC instead of EPC. It's also necessary to clear the Status.BEV bit for the page fault exception handler to work properly. [ralf@linux-mips: Let the assembler do the loading of the mask value rather than the convoluted explicit %hi/%lo manual relocation sequence from the original patch.] Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6035/ Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Reviewed-by: Markos Chandras <markos.chandras@imgtec.com> Patchwork: https://patchwork.linux-mips.org/patch/6084/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f2ae9cb57ff0..a17b6efb8bfe 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -330,6 +330,7 @@ void show_regs(struct pt_regs *regs)
330void show_registers(struct pt_regs *regs) 330void show_registers(struct pt_regs *regs)
331{ 331{
332 const int field = 2 * sizeof(unsigned long); 332 const int field = 2 * sizeof(unsigned long);
333 mm_segment_t old_fs = get_fs();
333 334
334 __show_regs(regs); 335 __show_regs(regs);
335 print_modules(); 336 print_modules();
@@ -344,9 +345,13 @@ void show_registers(struct pt_regs *regs)
344 printk("*HwTLS: %0*lx\n", field, tls); 345 printk("*HwTLS: %0*lx\n", field, tls);
345 } 346 }
346 347
348 if (!user_mode(regs))
349 /* Necessary for getting the correct stack content */
350 set_fs(KERNEL_DS);
347 show_stacktrace(current, regs); 351 show_stacktrace(current, regs);
348 show_code((unsigned int __user *) regs->cp0_epc); 352 show_code((unsigned int __user *) regs->cp0_epc);
349 printk("\n"); 353 printk("\n");
354 set_fs(old_fs);
350} 355}
351 356
352static int regs_to_trapnr(struct pt_regs *regs) 357static int regs_to_trapnr(struct pt_regs *regs)
@@ -1488,10 +1493,14 @@ int register_nmi_notifier(struct notifier_block *nb)
1488 1493
1489void __noreturn nmi_exception_handler(struct pt_regs *regs) 1494void __noreturn nmi_exception_handler(struct pt_regs *regs)
1490{ 1495{
1496 char str[100];
1497
1491 raw_notifier_call_chain(&nmi_chain, 0, regs); 1498 raw_notifier_call_chain(&nmi_chain, 0, regs);
1492 bust_spinlocks(1); 1499 bust_spinlocks(1);
1493 printk("NMI taken!!!!\n"); 1500 snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
1494 die("NMI", regs); 1501 smp_processor_id(), regs->cp0_epc);
1502 regs->cp0_epc = read_c0_errorepc();
1503 die(str, regs);
1495} 1504}
1496 1505
1497#define VECTORSPACING 0x100 /* for EI/VI mode */ 1506#define VECTORSPACING 0x100 /* for EI/VI mode */