Skip to content

Commit

Permalink
powerpc/64s: machine check interrupt update NMI accounting
Browse files Browse the repository at this point in the history
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
  • Loading branch information
npiggin authored and mpe committed May 18, 2020
1 parent 2576f5f commit 116ac37
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
7 changes: 7 additions & 0 deletions arch/powerpc/kernel/mce.c
Expand Up @@ -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);

Expand All @@ -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;
}

Expand Down
14 changes: 13 additions & 1 deletion arch/powerpc/kernel/traps.c
Expand Up @@ -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();

Expand Down

0 comments on commit 116ac37

Please sign in to comment.