summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2016-12-19 19:30:07 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2017-04-28 13:02:25 +0200
commit2b4f3ac5642672595ef6f71d1572b32475e94863 (patch)
tree3281669fba772ba54d641541c659337bbf8ab58f /arch/powerpc/kernel
parentpowerpc/64s: Dedicated system reset interrupt stack (diff)
downloadlinux-2b4f3ac5642672595ef6f71d1572b32475e94863.tar.xz
linux-2b4f3ac5642672595ef6f71d1572b32475e94863.zip
powerpc: Mark system reset as an NMI with nmi_enter/exit()
System reset is a non-maskable interrupt from Linux's point of view (occurs under local_irq_disable()), so it should use nmi_enter/exit. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/traps.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 2393d3c46236..6a81a451d767 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -279,6 +279,14 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
void system_reset_exception(struct pt_regs *regs)
{
+ /*
+ * Avoid crashes in case of nested NMI exceptions. Recoverability
+ * is determined by RI and in_nmi
+ */
+ bool nested = in_nmi();
+ if (!nested)
+ nmi_enter();
+
/* See if any machine dependent calls */
if (ppc_md.system_reset_exception) {
if (ppc_md.system_reset_exception(regs))
@@ -297,6 +305,9 @@ out:
if (!(regs->msr & MSR_RI))
panic("Unrecoverable System Reset");
+ if (!nested)
+ nmi_exit();
+
/* What should we do here? We could issue a shutdown or hard reset. */
}