powerpc/64s/exception: move interrupt entry code above the common handler
authorNicholas Piggin <npiggin@gmail.com>
Fri, 2 Aug 2019 10:56:58 +0000 (20:56 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 30 Aug 2019 01:14:58 +0000 (11:14 +1000)
This better reflects the order in which the code is executed.

No generated code change except BUG line number constants.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-34-npiggin@gmail.com
arch/powerpc/kernel/exceptions-64s.S

index c223587..aabd84e 100644 (file)
@@ -180,101 +180,6 @@ BEGIN_FTR_SECTION_NESTED(943)                                             \
        std     ra,offset(r13);                                         \
 END_FTR_SECTION_NESTED(ftr,ftr,943)
 
-.macro INT_SAVE_SRR_AND_JUMP label, hsrr, set_ri
-       ld      r10,PACAKMSR(r13)       /* get MSR value for kernel */
-       .if ! \set_ri
-       xori    r10,r10,MSR_RI          /* Clear MSR_RI */
-       .endif
-       .if \hsrr == EXC_HV_OR_STD
-       BEGIN_FTR_SECTION
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
-       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
-       mtspr   SPRN_HSRR1,r10
-       FTR_SECTION_ELSE
-       mfspr   r11,SPRN_SRR0           /* save SRR0 */
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       mtspr   SPRN_SRR1,r10
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-       .elseif \hsrr
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
-       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
-       mtspr   SPRN_HSRR1,r10
-       .else
-       mfspr   r11,SPRN_SRR0           /* save SRR0 */
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       mtspr   SPRN_SRR1,r10
-       .endif
-       LOAD_HANDLER(r10, \label\())
-       .if \hsrr == EXC_HV_OR_STD
-       BEGIN_FTR_SECTION
-       mtspr   SPRN_HSRR0,r10
-       HRFI_TO_KERNEL
-       FTR_SECTION_ELSE
-       mtspr   SPRN_SRR0,r10
-       RFI_TO_KERNEL
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-       .elseif \hsrr
-       mtspr   SPRN_HSRR0,r10
-       HRFI_TO_KERNEL
-       .else
-       mtspr   SPRN_SRR0,r10
-       RFI_TO_KERNEL
-       .endif
-       b       .       /* prevent speculative execution */
-.endm
-
-/* INT_SAVE_SRR_AND_JUMP works for real or virt, this is faster but virt only */
-.macro INT_VIRT_SAVE_SRR_AND_JUMP label, hsrr
-#ifdef CONFIG_RELOCATABLE
-       .if \hsrr == EXC_HV_OR_STD
-       BEGIN_FTR_SECTION
-       mfspr   r11,SPRN_HSRR0  /* save HSRR0 */
-       FTR_SECTION_ELSE
-       mfspr   r11,SPRN_SRR0   /* save SRR0 */
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-       .elseif \hsrr
-       mfspr   r11,SPRN_HSRR0  /* save HSRR0 */
-       .else
-       mfspr   r11,SPRN_SRR0   /* save SRR0 */
-       .endif
-       LOAD_HANDLER(r12, \label\())
-       mtctr   r12
-       .if \hsrr == EXC_HV_OR_STD
-       BEGIN_FTR_SECTION
-       mfspr   r12,SPRN_HSRR1  /* and HSRR1 */
-       FTR_SECTION_ELSE
-       mfspr   r12,SPRN_SRR1   /* and HSRR1 */
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-       .elseif \hsrr
-       mfspr   r12,SPRN_HSRR1  /* and HSRR1 */
-       .else
-       mfspr   r12,SPRN_SRR1   /* and HSRR1 */
-       .endif
-       li      r10,MSR_RI
-       mtmsrd  r10,1           /* Set RI (EE=0) */
-       bctr
-#else
-       .if \hsrr == EXC_HV_OR_STD
-       BEGIN_FTR_SECTION
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
-       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
-       FTR_SECTION_ELSE
-       mfspr   r11,SPRN_SRR0           /* save SRR0 */
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-       .elseif \hsrr
-       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
-       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
-       .else
-       mfspr   r11,SPRN_SRR0           /* save SRR0 */
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-       .endif
-       li      r10,MSR_RI
-       mtmsrd  r10,1                   /* Set RI (EE=0) */
-       b       \label
-#endif
-.endm
-
 /*
  * Branch to label using its 0xC000 address. This results in instruction
  * address suitable for MSR[IR]=0 or 1, which allows relocation to be turned
@@ -288,6 +193,15 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
        mtctr   reg;                                                    \
        bctr
 
+.macro INT_KVM_HANDLER vec, hsrr, area, skip
+       .if \hsrr
+       TRAMP_KVM_BEGIN(do_kvm_H\vec\())
+       .else
+       TRAMP_KVM_BEGIN(do_kvm_\vec\())
+       .endif
+       KVM_HANDLER \vec, \hsrr, \area, \skip
+.endm
+
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 /*
@@ -390,6 +304,222 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948)
 .endm
 #endif
 
+.macro INT_SAVE_SRR_AND_JUMP label, hsrr, set_ri
+       ld      r10,PACAKMSR(r13)       /* get MSR value for kernel */
+       .if ! \set_ri
+       xori    r10,r10,MSR_RI          /* Clear MSR_RI */
+       .endif
+       .if \hsrr == EXC_HV_OR_STD
+       BEGIN_FTR_SECTION
+       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
+       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
+       mtspr   SPRN_HSRR1,r10
+       FTR_SECTION_ELSE
+       mfspr   r11,SPRN_SRR0           /* save SRR0 */
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+       mtspr   SPRN_SRR1,r10
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+       .elseif \hsrr
+       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
+       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
+       mtspr   SPRN_HSRR1,r10
+       .else
+       mfspr   r11,SPRN_SRR0           /* save SRR0 */
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+       mtspr   SPRN_SRR1,r10
+       .endif
+       LOAD_HANDLER(r10, \label\())
+       .if \hsrr == EXC_HV_OR_STD
+       BEGIN_FTR_SECTION
+       mtspr   SPRN_HSRR0,r10
+       HRFI_TO_KERNEL
+       FTR_SECTION_ELSE
+       mtspr   SPRN_SRR0,r10
+       RFI_TO_KERNEL
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+       .elseif \hsrr
+       mtspr   SPRN_HSRR0,r10
+       HRFI_TO_KERNEL
+       .else
+       mtspr   SPRN_SRR0,r10
+       RFI_TO_KERNEL
+       .endif
+       b       .       /* prevent speculative execution */
+.endm
+
+/* INT_SAVE_SRR_AND_JUMP works for real or virt, this is faster but virt only */
+.macro INT_VIRT_SAVE_SRR_AND_JUMP label, hsrr
+#ifdef CONFIG_RELOCATABLE
+       .if \hsrr == EXC_HV_OR_STD
+       BEGIN_FTR_SECTION
+       mfspr   r11,SPRN_HSRR0  /* save HSRR0 */
+       FTR_SECTION_ELSE
+       mfspr   r11,SPRN_SRR0   /* save SRR0 */
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+       .elseif \hsrr
+       mfspr   r11,SPRN_HSRR0  /* save HSRR0 */
+       .else
+       mfspr   r11,SPRN_SRR0   /* save SRR0 */
+       .endif
+       LOAD_HANDLER(r12, \label\())
+       mtctr   r12
+       .if \hsrr == EXC_HV_OR_STD
+       BEGIN_FTR_SECTION
+       mfspr   r12,SPRN_HSRR1  /* and HSRR1 */
+       FTR_SECTION_ELSE
+       mfspr   r12,SPRN_SRR1   /* and HSRR1 */
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+       .elseif \hsrr
+       mfspr   r12,SPRN_HSRR1  /* and HSRR1 */
+       .else
+       mfspr   r12,SPRN_SRR1   /* and HSRR1 */
+       .endif
+       li      r10,MSR_RI
+       mtmsrd  r10,1           /* Set RI (EE=0) */
+       bctr
+#else
+       .if \hsrr == EXC_HV_OR_STD
+       BEGIN_FTR_SECTION
+       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
+       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
+       FTR_SECTION_ELSE
+       mfspr   r11,SPRN_SRR0           /* save SRR0 */
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+       ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+       .elseif \hsrr
+       mfspr   r11,SPRN_HSRR0          /* save HSRR0 */
+       mfspr   r12,SPRN_HSRR1          /* and HSRR1 */
+       .else
+       mfspr   r11,SPRN_SRR0           /* save SRR0 */
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+       .endif
+       li      r10,MSR_RI
+       mtmsrd  r10,1                   /* Set RI (EE=0) */
+       b       \label
+#endif
+.endm
+
+/*
+ * This is the BOOK3S interrupt entry code macro.
+ *
+ * This can result in one of several things happening:
+ * - Branch to the _common handler, relocated, in virtual mode.
+ *   These are normal interrupts (synchronous and asynchronous) handled by
+ *   the kernel.
+ * - Branch to KVM, relocated but real mode interrupts remain in real mode.
+ *   These occur when HSTATE_IN_GUEST is set. The interrupt may be caused by
+ *   / intended for host or guest kernel, but KVM must always be involved
+ *   because the machine state is set for guest execution.
+ * - Branch to the masked handler, unrelocated.
+ *   These occur when maskable asynchronous interrupts are taken with the
+ *   irq_soft_mask set.
+ * - Branch to an "early" handler in real mode but relocated.
+ *   This is done if early=1. MCE and HMI use these to handle errors in real
+ *   mode.
+ * - Fall through and continue executing in real, unrelocated mode.
+ *   This is done if early=2.
+ */
+.macro INT_HANDLER name, vec, ool=0, early=0, virt=0, hsrr=0, area=PACA_EXGEN, ri=1, dar=0, dsisr=0, bitmask=0, kvm=0
+       SET_SCRATCH0(r13)                       /* save r13 */
+       GET_PACA(r13)
+       std     r9,\area\()+EX_R9(r13)          /* save r9 */
+       OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR)
+       HMT_MEDIUM
+       std     r10,\area\()+EX_R10(r13)        /* save r10 - r12 */
+       OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
+       .if \ool
+       .if !\virt
+       b       tramp_real_\name
+       .pushsection .text
+       TRAMP_REAL_BEGIN(tramp_real_\name)
+       .else
+       b       tramp_virt_\name
+       .pushsection .text
+       TRAMP_VIRT_BEGIN(tramp_virt_\name)
+       .endif
+       .endif
+
+       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
+       SAVE_CTR(r10, \area\())
+       mfcr    r9
+       .if \kvm
+               KVMTEST \hsrr \vec
+       .endif
+       .if \bitmask
+               lbz     r10,PACAIRQSOFTMASK(r13)
+               andi.   r10,r10,\bitmask
+               /* Associate vector numbers with bits in paca->irq_happened */
+               .if \vec == 0x500 || \vec == 0xea0
+               li      r10,PACA_IRQ_EE
+               .elseif \vec == 0x900
+               li      r10,PACA_IRQ_DEC
+               .elseif \vec == 0xa00 || \vec == 0xe80
+               li      r10,PACA_IRQ_DBELL
+               .elseif \vec == 0xe60
+               li      r10,PACA_IRQ_HMI
+               .elseif \vec == 0xf00
+               li      r10,PACA_IRQ_PMI
+               .else
+               .abort "Bad maskable vector"
+               .endif
+
+               .if \hsrr == EXC_HV_OR_STD
+               BEGIN_FTR_SECTION
+               bne     masked_Hinterrupt
+               FTR_SECTION_ELSE
+               bne     masked_interrupt
+               ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
+               .elseif \hsrr
+               bne     masked_Hinterrupt
+               .else
+               bne     masked_interrupt
+               .endif
+       .endif
+
+       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
+       .if \hsrr
+       mfspr   r10,SPRN_HDAR
+       .else
+       mfspr   r10,SPRN_DAR
+       .endif
+       std     r10,\area\()+EX_DAR(r13)
+       .endif
+       .if \dsisr
+       .if \hsrr
+       mfspr   r10,SPRN_HDSISR
+       .else
+       mfspr   r10,SPRN_DSISR
+       .endif
+       stw     r10,\area\()+EX_DSISR(r13)
+       .endif
+
+       .if \early == 2
+       /* nothing more */
+       .elseif \early
+       mfctr   r10                     /* save ctr, even for !RELOCATABLE */
+       BRANCH_TO_C000(r11, \name\()_early_common)
+       .elseif !\virt
+       INT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr, \ri
+       .else
+       INT_VIRT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr
+       .endif
+       .if \ool
+       .popsection
+       .endif
+.endm
+
 /*
  * On entry r13 points to the paca, r9-r13 are saved in the paca,
  * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
@@ -555,136 +685,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
 #define FINISH_NAP
 #endif
 
-/*
- * This is the BOOK3S interrupt entry code macro.
- *
- * This can result in one of several things happening:
- * - Branch to the _common handler, relocated, in virtual mode.
- *   These are normal interrupts (synchronous and asynchronous) handled by
- *   the kernel.
- * - Branch to KVM, relocated but real mode interrupts remain in real mode.
- *   These occur when HSTATE_IN_GUEST is set. The interrupt may be caused by
- *   / intended for host or guest kernel, but KVM must always be involved
- *   because the machine state is set for guest execution.
- * - Branch to the masked handler, unrelocated.
- *   These occur when maskable asynchronous interrupts are taken with the
- *   irq_soft_mask set.
- * - Branch to an "early" handler in real mode but relocated.
- *   This is done if early=1. MCE and HMI use these to handle errors in real
- *   mode.
- * - Fall through and continue executing in real, unrelocated mode.
- *   This is done if early=2.
- */
-.macro INT_HANDLER name, vec, ool=0, early=0, virt=0, hsrr=0, area=PACA_EXGEN, ri=1, dar=0, dsisr=0, bitmask=0, kvm=0
-       SET_SCRATCH0(r13)                       /* save r13 */
-       GET_PACA(r13)
-       std     r9,\area\()+EX_R9(r13)          /* save r9 */
-       OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR)
-       HMT_MEDIUM
-       std     r10,\area\()+EX_R10(r13)        /* save r10 - r12 */
-       OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
-       .if \ool
-       .if !\virt
-       b       tramp_real_\name
-       .pushsection .text
-       TRAMP_REAL_BEGIN(tramp_real_\name)
-       .else
-       b       tramp_virt_\name
-       .pushsection .text
-       TRAMP_VIRT_BEGIN(tramp_virt_\name)
-       .endif
-       .endif
-
-       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
-       SAVE_CTR(r10, \area\())
-       mfcr    r9
-       .if \kvm
-               KVMTEST \hsrr \vec
-       .endif
-       .if \bitmask
-               lbz     r10,PACAIRQSOFTMASK(r13)
-               andi.   r10,r10,\bitmask
-               /* Associate vector numbers with bits in paca->irq_happened */
-               .if \vec == 0x500 || \vec == 0xea0
-               li      r10,PACA_IRQ_EE
-               .elseif \vec == 0x900
-               li      r10,PACA_IRQ_DEC
-               .elseif \vec == 0xa00 || \vec == 0xe80
-               li      r10,PACA_IRQ_DBELL
-               .elseif \vec == 0xe60
-               li      r10,PACA_IRQ_HMI
-               .elseif \vec == 0xf00
-               li      r10,PACA_IRQ_PMI
-               .else
-               .abort "Bad maskable vector"
-               .endif
-
-               .if \hsrr == EXC_HV_OR_STD
-               BEGIN_FTR_SECTION
-               bne     masked_Hinterrupt
-               FTR_SECTION_ELSE
-               bne     masked_interrupt
-               ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
-               .elseif \hsrr
-               bne     masked_Hinterrupt
-               .else
-               bne     masked_interrupt
-               .endif
-       .endif
-
-       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
-       .if \hsrr
-       mfspr   r10,SPRN_HDAR
-       .else
-       mfspr   r10,SPRN_DAR
-       .endif
-       std     r10,\area\()+EX_DAR(r13)
-       .endif
-       .if \dsisr
-       .if \hsrr
-       mfspr   r10,SPRN_HDSISR
-       .else
-       mfspr   r10,SPRN_DSISR
-       .endif
-       stw     r10,\area\()+EX_DSISR(r13)
-       .endif
-
-       .if \early == 2
-       /* nothing more */
-       .elseif \early
-       mfctr   r10                     /* save ctr, even for !RELOCATABLE */
-       BRANCH_TO_C000(r11, \name\()_early_common)
-       .elseif !\virt
-       INT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr, \ri
-       .else
-       INT_VIRT_SAVE_SRR_AND_JUMP \name\()_common, \hsrr
-       .endif
-       .if \ool
-       .popsection
-       .endif
-.endm
-
-.macro INT_KVM_HANDLER vec, hsrr, area, skip
-       .if \hsrr
-       TRAMP_KVM_BEGIN(do_kvm_H\vec\())
-       .else
-       TRAMP_KVM_BEGIN(do_kvm_\vec\())
-       .endif
-       KVM_HANDLER \vec, \hsrr, \area, \skip
-.endm
-
 #define EXC_COMMON(name, realvec, hdlr)                                        \
        EXC_COMMON_BEGIN(name);                                         \
        INT_COMMON realvec, PACA_EXGEN, 1, 1, 1, 0, 0 ;                 \