Some exception entry requires DAR and/or DSISR to be saved into the
paca exception save area. Add options to the standard exception
macros for these.

Generated code changes slightly due to code structure.

-     554:      a6 02 72 7d     mfdsisr r11
-     558:      a8 00 4d f9     std     r10,168(r13)
-     55c:      b0 00 6d 91     stw     r11,176(r13)
+     554:      a8 00 4d f9     std     r10,168(r13)
+     558:      a6 02 52 7d     mfdsisr r10
+     55c:      b0 00 4d 91     stw     r10,176(r13)

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 arch/powerpc/kernel/exceptions-64s.S | 103 ++++++++++++---------------
 1 file changed, 46 insertions(+), 57 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 2412b5269e25..16d5ea1c86bb 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -136,7 +136,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
        OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
 .endm
 
-.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask
+.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, dar, dsisr, bitmask
        OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR)
        OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR)
        INTERRUPT_TO_KERNEL
@@ -172,8 +172,22 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
 
        std     r11,\area\()+EX_R11(r13)
        std     r12,\area\()+EX_R12(r13)
+
+       /*
+        * DAR/DSISR, SCRATCH0 must be read before setting MSR[RI],
+        * because a d-side MCE will clobber those registers so is
+        * not recoverable if they are live.
+        */
        GET_SCRATCH0(r10)
        std     r10,\area\()+EX_R13(r13)
+       .if \dar
+       mfspr   r10,SPRN_DAR
+       std     r10,\area\()+EX_DAR(r13)
+       .endif
+       .if \dsisr
+       mfspr   r10,SPRN_DSISR
+       stw     r10,\area\()+EX_DSISR(r13)
+       .endif
 .endm
 
 .macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri
@@ -528,7 +542,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_REAL_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);              /* save r13 */                  \
        EXCEPTION_PROLOG_0 area ;                                       \
-       EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0 ;                 \
+       EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0, 0, 0 ;           \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ;             \
        EXC_REAL_END(name, start, size)
 
@@ -539,7 +553,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_VIRT_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);    /* save r13 */                            \
        EXCEPTION_PROLOG_0 area ;                                       \
-       EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0;                \
+       EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0, 0, 0;          \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ;                \
        EXC_VIRT_END(name, start, size)
 
@@ -550,7 +564,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_REAL_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);    /* save r13 */                            \
        EXCEPTION_PROLOG_0 PACA_EXGEN ;                                 \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, bitmask ;     \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, 0, 0, bitmask ; \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ;             \
        EXC_REAL_END(name, start, size)
 
@@ -558,7 +572,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_VIRT_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);    /* save r13 */                            \
        EXCEPTION_PROLOG_0 PACA_EXGEN ;                                 \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ;   \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, 0, 0, bitmask ; \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ;                \
        EXC_VIRT_END(name, start, size)
 
@@ -566,7 +580,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_REAL_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);              /* save r13 */                  \
        EXCEPTION_PROLOG_0 PACA_EXGEN;                                  \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0 ;            \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0, 0, 0 ;      \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ;              \
        EXC_REAL_END(name, start, size)
 
@@ -574,7 +588,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
        EXC_VIRT_BEGIN(name, start, size);                              \
        SET_SCRATCH0(r13);              /* save r13 */                  \
        EXCEPTION_PROLOG_0 PACA_EXGEN;                                  \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ;          \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, 0 ;    \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ;                 \
        EXC_VIRT_END(name, start, size)
 
@@ -587,7 +601,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_REAL_OOL(name, vec)                                    \
        TRAMP_REAL_BEGIN(tramp_real_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ;     \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0, 0, 0 ;       \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1
 
 #define EXC_REAL_OOL(name, start, size)                                        
\
@@ -599,7 +613,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask)                  \
        TRAMP_REAL_BEGIN(tramp_real_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ;       \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0, 0, bitmask ; \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1
 
 #define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask)              \
@@ -618,7 +632,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_REAL_OOL_HV(name, vec)                                 \
        TRAMP_REAL_BEGIN(tramp_real_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ;      \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0, 0, 0 ;        \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1
 
 #define EXC_REAL_OOL_HV(name, start, size)                             \
@@ -630,7 +644,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask)               \
        TRAMP_REAL_BEGIN(tramp_real_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ;        \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0, 0, bitmask ;  \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1
 
 #define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask)           \
@@ -646,7 +660,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_VIRT_OOL(name, realvec)                                        
\
        TRAMP_VIRT_BEGIN(tramp_virt_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ;             \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0, 0, 0 ;       \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD
 
 #define EXC_VIRT_OOL(name, start, size, realvec)                       \
@@ -658,7 +672,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask)              \
        TRAMP_VIRT_BEGIN(tramp_virt_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ;   \
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, 0, 0, bitmask ; \
        EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1
 
 #define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask)     \
@@ -670,7 +684,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_VIRT_OOL_HV(name, realvec)                             \
        TRAMP_VIRT_BEGIN(tramp_virt_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ;          \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, 0 ;    \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV
 
 #define EXC_VIRT_OOL_HV(name, start, size, realvec)                    \
@@ -682,7 +696,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 
 #define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask)           \
        TRAMP_VIRT_BEGIN(tramp_virt_##name);                            \
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, bitmask ;    \
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, bitmask ; \
        EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV
 
 #define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask)  \
@@ -852,7 +866,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXNMI
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 1, 0x100, 0
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 1, 0x100, 0, 0, 0
        EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0
        /*
         * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is
@@ -879,7 +893,7 @@ TRAMP_REAL_BEGIN(system_reset_fwnmi)
        SET_SCRATCH0(r13)               /* save r13 */
        /* See comment at system_reset exception, don't turn on RI */
        EXCEPTION_PROLOG_0 PACA_EXNMI
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0, 0, 0
        EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0
 
 #endif /* CONFIG_PPC_PSERIES */
@@ -957,7 +971,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
 EXC_REAL_END(machine_check, 0x200, 0x100)
 EXC_VIRT_NONE(0x4200, 0x100)
 TRAMP_REAL_BEGIN(machine_check_common_early)
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0, 0, 0
        /*
         * Register contents:
         * R13          = PACA
@@ -1042,7 +1056,7 @@ BEGIN_FTR_SECTION
        b       machine_check_common_early
 END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)
 machine_check_pSeries_0:
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0, 0, 0
        /*
         * MSR_RI is not enabled, because PACA_EXMC is being used, so a
         * nested machine check corrupts it. machine_check_common enables
@@ -1259,26 +1273,13 @@ EXC_REAL_BEGIN(data_access, 0x300, 0x80)
 EXC_REAL_END(data_access, 0x300, 0x80)
 
 TRAMP_REAL_BEGIN(tramp_real_data_access)
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0
-       /*
-        * DAR/DSISR must be read before setting MSR[RI], because
-        * a d-side MCE will clobber those registers so is not
-        * recoverable if they are live.
-        */
-       mfspr   r10,SPRN_DAR
-       mfspr   r11,SPRN_DSISR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       stw     r11,PACA_EXGEN+EX_DSISR(r13)
-EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 1, 1, 0
+       EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1
 
 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80)
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXGEN
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0
-       mfspr   r10,SPRN_DAR
-       mfspr   r11,SPRN_DSISR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       stw     r11,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 1, 1, 0
 EXCEPTION_PROLOG_2_VIRT data_access_common, EXC_STD
 EXC_VIRT_END(data_access, 0x4300, 0x80)
 
@@ -1313,17 +1314,13 @@ EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80)
 EXC_REAL_END(data_access_slb, 0x380, 0x80)
 
 TRAMP_REAL_BEGIN(tramp_real_data_access_slb)
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 0
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXSLB+EX_DAR(r13)
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 1, 0, 0
        EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1
 
 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXSLB
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXSLB+EX_DAR(r13)
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 1, 0, 0
        EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD
 EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
 
@@ -1408,10 +1405,10 @@ EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100)
        SET_SCRATCH0(r13)       /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXGEN
 BEGIN_FTR_SECTION
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED
        EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1
 FTR_SECTION_ELSE
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED
        EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1
 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 EXC_REAL_END(hardware_interrupt, 0x500, 0x100)
@@ -1420,10 +1417,10 @@ EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100)
        SET_SCRATCH0(r13)       /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXGEN
 BEGIN_FTR_SECTION
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED
        EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV
 FTR_SECTION_ELSE
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED
        EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD
 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
 EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
@@ -1436,22 +1433,14 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, 
do_IRQ)
 EXC_REAL_BEGIN(alignment, 0x600, 0x100)
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXGEN
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0
-       mfspr   r10,SPRN_DAR
-       mfspr   r11,SPRN_DSISR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       stw     r11,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 1, 1, 0
        EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1
 EXC_REAL_END(alignment, 0x600, 0x100)
 
 EXC_VIRT_BEGIN(alignment, 0x4600, 0x100)
        SET_SCRATCH0(r13)               /* save r13 */
        EXCEPTION_PROLOG_0 PACA_EXGEN
-       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0
-       mfspr   r10,SPRN_DAR
-       mfspr   r11,SPRN_DSISR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       stw     r11,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 1, 1, 0
        EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD
 EXC_VIRT_END(alignment, 0x4600, 0x100)
 
@@ -1752,7 +1741,7 @@ __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, 
IRQS_DISABLED)
 EXC_VIRT_NONE(0x4e60, 0x20)
 TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
 TRAMP_REAL_BEGIN(hmi_exception_early)
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0, 0, 0
        mr      r10,r1                  /* Save r1 */
        ld      r1,PACAEMERGSP(r13)     /* Use emergency stack for realmode */
        subi    r1,r1,INT_FRAME_SIZE    /* alloc stack frame            */
@@ -1937,7 +1926,7 @@ EXC_VIRT_NONE(0x5400, 0x100)
 EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
        mtspr   SPRN_SPRG_HSCRATCH0,r13
        EXCEPTION_PROLOG_0 PACA_EXGEN
-       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0
+       EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0, 0, 0
 
 #ifdef CONFIG_PPC_DENORMALISATION
        mfspr   r10,SPRN_HSRR1
-- 
2.20.1

Reply via email to