diff options
-rw-r--r-- | arch/powerpc/kernel/mce.c | 7 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 14 |
2 files changed, 20 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/mce.c b/arch/powerpc/kernel/mce.c index 8077b5fb18a7..be7e3f92a7b5 100644 --- a/arch/powerpc/kernel/mce.c +++ b/arch/powerpc/kernel/mce.c @@ -574,6 +574,9 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info); long machine_check_early(struct pt_regs *regs) { long handled = 0; + bool nested = in_nmi(); + if (!nested) + nmi_enter(); hv_nmi_check_nonrecoverable(regs); @@ -582,6 +585,10 @@ long machine_check_early(struct pt_regs *regs) */ if (ppc_md.machine_check_early) handled = ppc_md.machine_check_early(regs); + + if (!nested) + nmi_exit(); + return handled; } diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3fca22276bb1..9f6852322e59 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -823,7 +823,19 @@ int machine_check_generic(struct pt_regs *regs) void machine_check_exception(struct pt_regs *regs) { int recover = 0; - bool nested = in_nmi(); + bool nested; + + /* + * BOOK3S_64 does not call this handler as a non-maskable interrupt + * (it uses its own early real-mode handler to handle the MCE proper + * and then raises irq_work to call this handler when interrupts are + * enabled). Set nested = true for this case, which just makes it avoid + * the nmi_enter/exit. + */ + if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) || in_nmi()) + nested = true; + else + nested = false; if (!nested) nmi_enter(); |