Skip to content

Commit 74c3354

Browse files
npigginmpe
authored andcommitted
powerpc/pseries/mce: restore msr before returning from handler
The pseries real-mode machine check handler can enable the MMU, and return from the handler with the MMU still enabled. This works, but real-mode handler wrapper exit handlers want to rely on the MMU being in real-mode. So change the pseries handler to restore the MSR after it has finished virtual mode tasks. Signed-off-by: Nicholas Piggin <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 56acfdd commit 74c3354

File tree

1 file changed

+15
-4
lines changed
  • arch/powerpc/platforms/pseries

1 file changed

+15
-4
lines changed

arch/powerpc/platforms/pseries/ras.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp)
717717
struct pseries_errorlog *pseries_log;
718718
struct pseries_mc_errorlog *mce_log = NULL;
719719
int disposition = rtas_error_disposition(errp);
720+
unsigned long msr;
720721
u8 error_type;
721722

722723
if (!rtas_error_extended(errp))
@@ -742,9 +743,21 @@ static int mce_handle_error(struct pt_regs *regs, struct rtas_error_log *errp)
742743
* SLB multihit is done by now.
743744
*/
744745
out:
745-
mtmsr(mfmsr() | MSR_IR | MSR_DR);
746+
msr = mfmsr();
747+
mtmsr(msr | MSR_IR | MSR_DR);
748+
746749
disposition = mce_handle_err_virtmode(regs, errp, mce_log,
747750
disposition);
751+
752+
/*
753+
* Queue irq work to log this rtas event later.
754+
* irq_work_queue uses per-cpu variables, so do this in virt
755+
* mode as well.
756+
*/
757+
irq_work_queue(&mce_errlog_process_work);
758+
759+
mtmsr(msr);
760+
748761
return disposition;
749762
}
750763

@@ -860,10 +873,8 @@ long pseries_machine_check_realmode(struct pt_regs *regs)
860873
* virtual mode.
861874
*/
862875
disposition = mce_handle_error(regs, errp);
863-
fwnmi_release_errinfo();
864876

865-
/* Queue irq work to log this rtas event later. */
866-
irq_work_queue(&mce_errlog_process_work);
877+
fwnmi_release_errinfo();
867878

868879
if (disposition == RTAS_DISP_FULLY_RECOVERED)
869880
return 1;

0 commit comments

Comments
 (0)