|
@@ -139,6 +139,21 @@ EXC_COMMON_BEGIN(system_reset_idle_common)
|
|
|
b pnv_powersave_wakeup
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * Set IRQS_ALL_DISABLED unconditionally so arch_irqs_disabled does
|
|
|
+ * the right thing. We do not want to reconcile because that goes
|
|
|
+ * through irq tracing which we don't want in NMI.
|
|
|
+ *
|
|
|
+ * Save PACAIRQHAPPENED because some code will do a hard disable
|
|
|
+ * (e.g., xmon). So we want to restore this back to where it was
|
|
|
+ * when we return. DAR is unused in the stack, so save it there.
|
|
|
+ */
|
|
|
+#define ADD_RECONCILE_NMI \
|
|
|
+ li r10,IRQS_ALL_DISABLED; \
|
|
|
+ stb r10,PACAIRQSOFTMASK(r13); \
|
|
|
+ lbz r10,PACAIRQHAPPENED(r13); \
|
|
|
+ std r10,_DAR(r1)
|
|
|
+
|
|
|
EXC_COMMON_BEGIN(system_reset_common)
|
|
|
/*
|
|
|
* Increment paca->in_nmi then enable MSR_RI. SLB or MCE will be able
|
|
@@ -157,16 +172,56 @@ EXC_COMMON_BEGIN(system_reset_common)
|
|
|
subi r1,r1,INT_FRAME_SIZE
|
|
|
EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100,
|
|
|
system_reset, system_reset_exception,
|
|
|
- ADD_NVGPRS;ADD_RECONCILE)
|
|
|
+ ADD_NVGPRS;ADD_RECONCILE_NMI)
|
|
|
+
|
|
|
+ /* This (and MCE) can be simplified with mtmsrd L=1 */
|
|
|
+ /* Clear MSR_RI before setting SRR0 and SRR1. */
|
|
|
+ li r0,MSR_RI
|
|
|
+ mfmsr r9
|
|
|
+ andc r9,r9,r0
|
|
|
+ mtmsrd r9,1
|
|
|
|
|
|
/*
|
|
|
- * The stack is no longer in use, decrement in_nmi.
|
|
|
+ * MSR_RI is clear, now we can decrement paca->in_nmi.
|
|
|
*/
|
|
|
lhz r10,PACA_IN_NMI(r13)
|
|
|
subi r10,r10,1
|
|
|
sth r10,PACA_IN_NMI(r13)
|
|
|
|
|
|
- b ret_from_except
|
|
|
+ /*
|
|
|
+ * Restore soft mask settings.
|
|
|
+ */
|
|
|
+ ld r10,_DAR(r1)
|
|
|
+ stb r10,PACAIRQHAPPENED(r13)
|
|
|
+ ld r10,SOFTE(r1)
|
|
|
+ stb r10,PACAIRQSOFTMASK(r13)
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Keep below code in synch with MACHINE_CHECK_HANDLER_WINDUP.
|
|
|
+ * Should share common bits...
|
|
|
+ */
|
|
|
+
|
|
|
+ /* Move original SRR0 and SRR1 into the respective regs */
|
|
|
+ ld r9,_MSR(r1)
|
|
|
+ mtspr SPRN_SRR1,r9
|
|
|
+ ld r3,_NIP(r1)
|
|
|
+ mtspr SPRN_SRR0,r3
|
|
|
+ ld r9,_CTR(r1)
|
|
|
+ mtctr r9
|
|
|
+ ld r9,_XER(r1)
|
|
|
+ mtxer r9
|
|
|
+ ld r9,_LINK(r1)
|
|
|
+ mtlr r9
|
|
|
+ REST_GPR(0, r1)
|
|
|
+ REST_8GPRS(2, r1)
|
|
|
+ REST_GPR(10, r1)
|
|
|
+ ld r11,_CCR(r1)
|
|
|
+ mtcr r11
|
|
|
+ REST_GPR(11, r1)
|
|
|
+ REST_2GPRS(12, r1)
|
|
|
+ /* restore original r1. */
|
|
|
+ ld r1,GPR1(r1)
|
|
|
+ RFI_TO_USER_OR_KERNEL
|
|
|
|
|
|
#ifdef CONFIG_PPC_PSERIES
|
|
|
/*
|