Skip to content

Commit

Permalink
MIPS: Print correct PC in trace dump after NMI exception
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Leonid Yegoshin authored and Ralf Baechle committed Oct 29, 2013
1 parent d9f897c commit 83e4da1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
14 changes: 11 additions & 3 deletions arch/mips/kernel/genex.S
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,20 @@ NESTED(except_vec_nmi, 0, sp)
NESTED(nmi_handler, PT_SIZE, sp)
.set push
.set noat
/*
* Clear ERL - restore segment mapping
* Clear BEV - required for page fault exception handler to work
*/
mfc0 k0, CP0_STATUS
ori k0, k0, ST0_EXL
li k1, ~(ST0_BEV | ST0_ERL)
and k0, k0, k1
mtc0 k0, CP0_STATUS
_ehb
SAVE_ALL
move a0, sp
jal nmi_exception_handler
RESTORE_ALL
.set mips3
eret
/* nmi_exception_handler never returns */
.set pop
END(nmi_handler)

Expand Down
13 changes: 11 additions & 2 deletions arch/mips/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ void show_regs(struct pt_regs *regs)
void show_registers(struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
mm_segment_t old_fs = get_fs();

__show_regs(regs);
print_modules();
Expand All @@ -344,9 +345,13 @@ void show_registers(struct pt_regs *regs)
printk("*HwTLS: %0*lx\n", field, tls);
}

if (!user_mode(regs))
/* Necessary for getting the correct stack content */
set_fs(KERNEL_DS);
show_stacktrace(current, regs);
show_code((unsigned int __user *) regs->cp0_epc);
printk("\n");
set_fs(old_fs);
}

static int regs_to_trapnr(struct pt_regs *regs)
Expand Down Expand Up @@ -1488,10 +1493,14 @@ int register_nmi_notifier(struct notifier_block *nb)

void __noreturn nmi_exception_handler(struct pt_regs *regs)
{
char str[100];

raw_notifier_call_chain(&nmi_chain, 0, regs);
bust_spinlocks(1);
printk("NMI taken!!!!\n");
die("NMI", regs);
snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
smp_processor_id(), regs->cp0_epc);
regs->cp0_epc = read_c0_errorepc();
die(str, regs);
}

#define VECTORSPACING 0x100 /* for EI/VI mode */
Expand Down

0 comments on commit 83e4da1

Please sign in to comment.