diff options
author | Nicholas Piggin <npiggin@gmail.com> | 2020-05-08 06:34:03 +0200 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2020-05-18 16:10:34 +0200 |
commit | 116ac378bb3ff844df333e7609e7604651a0db9d (patch) | |
tree | d4d450c112d899d277babdfd5d58bce99e637117 /arch/powerpc/kernel/traps.c | |
parent | powerpc/pseries: Machine check use rtas_call_unlocked() with args on stack (diff) | |
download | linux-116ac378bb3ff844df333e7609e7604651a0db9d.tar.xz linux-116ac378bb3ff844df333e7609e7604651a0db9d.zip |
powerpc/64s: machine check interrupt update NMI accounting
machine_check_early() is taken as an NMI, so nmi_enter() is used
there. machine_check_exception() is no longer taken as an NMI (it's
invoked via irq_work in the case a machine check hits in kernel mode),
so remove the nmi_enter() from that case.
In NMI context, hash faults don't try to refill the hash table, which
can lead to crashes accessing non-pinned kernel pages. System reset
still has this potential problem.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Drop change in show_regs() which breaks Book3E]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200508043408.886394-12-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r-- | arch/powerpc/kernel/traps.c | 14 |
1 files changed, 13 insertions, 1 deletions
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(); |