mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
parent
2576f5f916
commit
116ac378bb
|
@ -574,6 +574,9 @@ EXPORT_SYMBOL_GPL(machine_check_print_event_info);
|
||||||
long machine_check_early(struct pt_regs *regs)
|
long machine_check_early(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
long handled = 0;
|
long handled = 0;
|
||||||
|
bool nested = in_nmi();
|
||||||
|
if (!nested)
|
||||||
|
nmi_enter();
|
||||||
|
|
||||||
hv_nmi_check_nonrecoverable(regs);
|
hv_nmi_check_nonrecoverable(regs);
|
||||||
|
|
||||||
|
@ -582,6 +585,10 @@ long machine_check_early(struct pt_regs *regs)
|
||||||
*/
|
*/
|
||||||
if (ppc_md.machine_check_early)
|
if (ppc_md.machine_check_early)
|
||||||
handled = ppc_md.machine_check_early(regs);
|
handled = ppc_md.machine_check_early(regs);
|
||||||
|
|
||||||
|
if (!nested)
|
||||||
|
nmi_exit();
|
||||||
|
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -823,7 +823,19 @@ int machine_check_generic(struct pt_regs *regs)
|
||||||
void machine_check_exception(struct pt_regs *regs)
|
void machine_check_exception(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int recover = 0;
|
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)
|
if (!nested)
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue