powerpc/64s: Move __replay_interrupt function below handlers
[cascardo/linux.git] / arch / powerpc / kernel / exceptions-64s.S
index 3e347c7..9b26b7b 100644 (file)
@@ -1015,33 +1015,136 @@ EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception)
 
 
 __EXC_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0, 0xec0)
+__TRAMP_REAL_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0)
+__EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x4ec0)
+__TRAMP_REAL_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0xea0)
+TRAMP_KVM_HV(PACA_EXGEN, 0xea0)
+EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ)
+
 
 EXC_REAL_NONE(0xec0, 0xf00)
+EXC_VIRT_NONE(0x4ec0, 0x4f00)
+
 
 __EXC_REAL_OOL(performance_monitor, 0xf00, 0xf20)
+__TRAMP_REAL_REAL_OOL(performance_monitor, 0xf00)
+__EXC_VIRT_OOL(performance_monitor, 0x4f00, 0x4f20)
+__TRAMP_REAL_VIRT_OOL(performance_monitor, 0xf00)
+TRAMP_KVM(PACA_EXGEN, 0xf00)
+EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception)
+
 
 __EXC_REAL_OOL(altivec_unavailable, 0xf20, 0xf40)
+__TRAMP_REAL_REAL_OOL(altivec_unavailable, 0xf20)
+__EXC_VIRT_OOL(altivec_unavailable, 0x4f20, 0x4f40)
+__TRAMP_REAL_VIRT_OOL(altivec_unavailable, 0xf20)
+TRAMP_KVM(PACA_EXGEN, 0xf20)
+EXC_COMMON_BEGIN(altivec_unavailable_common)
+       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+       beq     1f
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+  BEGIN_FTR_SECTION_NESTED(69)
+       /* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
+        * transaction), go do TM stuff
+        */
+       rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
+       bne-    2f
+  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
+#endif
+       bl      load_up_altivec
+       b       fast_exception_return
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+2:     /* User process was in a transaction */
+       bl      save_nvgprs
+       RECONCILE_IRQ_STATE(r10, r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      altivec_unavailable_tm
+       b       ret_from_except
+#endif
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+       bl      save_nvgprs
+       RECONCILE_IRQ_STATE(r10, r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      altivec_unavailable_exception
+       b       ret_from_except
+
 
 __EXC_REAL_OOL(vsx_unavailable, 0xf40, 0xf60)
+__TRAMP_REAL_REAL_OOL(vsx_unavailable, 0xf40)
+__EXC_VIRT_OOL(vsx_unavailable, 0x4f40, 0x4f60)
+__TRAMP_REAL_VIRT_OOL(vsx_unavailable, 0xf40)
+TRAMP_KVM(PACA_EXGEN, 0xf40)
+EXC_COMMON_BEGIN(vsx_unavailable_common)
+       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       beq     1f
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+  BEGIN_FTR_SECTION_NESTED(69)
+       /* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
+        * transaction), go do TM stuff
+        */
+       rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
+       bne-    2f
+  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
+#endif
+       b       load_up_vsx
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+2:     /* User process was in a transaction */
+       bl      save_nvgprs
+       RECONCILE_IRQ_STATE(r10, r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      vsx_unavailable_tm
+       b       ret_from_except
+#endif
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
+       bl      save_nvgprs
+       RECONCILE_IRQ_STATE(r10, r11)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      vsx_unavailable_exception
+       b       ret_from_except
+
 
 __EXC_REAL_OOL(facility_unavailable, 0xf60, 0xf80)
+__TRAMP_REAL_REAL_OOL(facility_unavailable, 0xf60)
+__EXC_VIRT_OOL(facility_unavailable, 0x4f60, 0x4f80)
+__TRAMP_REAL_VIRT_OOL(facility_unavailable, 0xf60)
+TRAMP_KVM(PACA_EXGEN, 0xf60)
+EXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception)
+
 
 __EXC_REAL_OOL_HV(h_facility_unavailable, 0xf80, 0xfa0)
+__TRAMP_REAL_REAL_OOL_HV(h_facility_unavailable, 0xf80)
+__EXC_VIRT_OOL_HV(h_facility_unavailable, 0x4f80, 0x4fa0)
+__TRAMP_REAL_VIRT_OOL_HV(h_facility_unavailable, 0xf80)
+TRAMP_KVM_HV(PACA_EXGEN, 0xf80)
+EXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception)
+
 
 EXC_REAL_NONE(0xfa0, 0x1200)
+EXC_VIRT_NONE(0x4fa0, 0x5200)
 
 #ifdef CONFIG_CBE_RAS
 EXC_REAL_HV(cbe_system_error, 0x1200, 0x1300)
-
+EXC_VIRT_NONE(0x5200, 0x5300)
 TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1200)
-
+EXC_COMMON(cbe_system_error_common, 0x1200, cbe_system_error_exception)
 #else /* CONFIG_CBE_RAS */
 EXC_REAL_NONE(0x1200, 0x1300)
 #endif
 
-EXC_REAL(instruction_breakpoint, 0x1300, 0x1400)
 
+EXC_REAL(instruction_breakpoint, 0x1300, 0x1400)
+EXC_VIRT(instruction_breakpoint, 0x5300, 0x5400, 0x1300)
 TRAMP_KVM_SKIP(PACA_EXGEN, 0x1300)
+EXC_COMMON(instruction_breakpoint_common, 0x1300, instruction_breakpoint_exception)
+
 
 EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x1600)
        mtspr   SPRN_SPRG_HSCRATCH0,r13
@@ -1060,34 +1163,15 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x1600)
        EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV)
 EXC_REAL_END(denorm_exception_hv, 0x1500, 0x1600)
 
-TRAMP_KVM_SKIP(PACA_EXGEN, 0x1500)
-
-#ifdef CONFIG_CBE_RAS
-EXC_REAL_HV(cbe_maintenance, 0x1600, 0x1700)
-
-TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1600)
-
-#else /* CONFIG_CBE_RAS */
-EXC_REAL_NONE(0x1600, 0x1700)
-#endif
-
-EXC_REAL(altivec_assist, 0x1700, 0x1800)
-
-TRAMP_KVM(PACA_EXGEN, 0x1700)
-
-#ifdef CONFIG_CBE_RAS
-EXC_REAL_HV(cbe_thermal, 0x1800, 0x1900)
-
-TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1800)
-
-#else /* CONFIG_CBE_RAS */
-EXC_REAL_NONE(0x1800, 0x1900)
+#ifdef CONFIG_PPC_DENORMALISATION
+EXC_VIRT_BEGIN(denorm_exception, 0x5500, 0x5600)
+       b       exc_real_0x1500_denorm_exception_hv
+EXC_VIRT_END(denorm_exception, 0x5500, 0x5600)
+#else
+EXC_VIRT_NONE(0x5500, 0x5600)
 #endif
 
-
-/*** Out of line interrupts support ***/
-
-       /* moved from 0x200 */
+TRAMP_KVM_SKIP(PACA_EXGEN, 0x1500)
 
 #ifdef CONFIG_PPC_DENORMALISATION
 TRAMP_REAL_BEGIN(denorm_assist)
@@ -1153,25 +1237,38 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
        b       .
 #endif
 
-       /* moved from 0xe00 */
-__TRAMP_REAL_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0)
-TRAMP_KVM_HV(PACA_EXGEN, 0xea0)
+EXC_COMMON_HV(denorm_common, 0x1500, unknown_exception)
 
-       /* moved from 0xf00 */
-__TRAMP_REAL_REAL_OOL(performance_monitor, 0xf00)
-TRAMP_KVM(PACA_EXGEN, 0xf00)
 
-__TRAMP_REAL_REAL_OOL(altivec_unavailable, 0xf20)
-TRAMP_KVM(PACA_EXGEN, 0xf20)
+#ifdef CONFIG_CBE_RAS
+EXC_REAL_HV(cbe_maintenance, 0x1600, 0x1700)
+EXC_VIRT_NONE(0x5600, 0x5700)
+TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1600)
+EXC_COMMON(cbe_maintenance_common, 0x1600, cbe_maintenance_exception)
+#else /* CONFIG_CBE_RAS */
+EXC_REAL_NONE(0x1600, 0x1700)
+#endif
 
-__TRAMP_REAL_REAL_OOL(vsx_unavailable, 0xf40)
-TRAMP_KVM(PACA_EXGEN, 0xf40)
 
-__TRAMP_REAL_REAL_OOL(facility_unavailable, 0xf60)
-TRAMP_KVM(PACA_EXGEN, 0xf60)
+EXC_REAL(altivec_assist, 0x1700, 0x1800)
+EXC_VIRT(altivec_assist, 0x5700, 0x5800, 0x1700)
+TRAMP_KVM(PACA_EXGEN, 0x1700)
+#ifdef CONFIG_ALTIVEC
+EXC_COMMON(altivec_assist_common, 0x1700, altivec_assist_exception)
+#else
+EXC_COMMON(altivec_assist_common, 0x1700, unknown_exception)
+#endif
+
+
+#ifdef CONFIG_CBE_RAS
+EXC_REAL_HV(cbe_thermal, 0x1800, 0x1900)
+EXC_VIRT_NONE(0x5800, 0x5900)
+TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1800)
+EXC_COMMON(cbe_thermal_common, 0x1800, cbe_thermal_exception)
+#else /* CONFIG_CBE_RAS */
+EXC_REAL_NONE(0x1800, 0x1900)
+#endif
 
-__TRAMP_REAL_REAL_OOL_HV(h_facility_unavailable, 0xf80)
-TRAMP_KVM_HV(PACA_EXGEN, 0xf80)
 
 /*
  * An interrupt came in while soft-disabled. We set paca->irq_happened, then:
@@ -1220,43 +1317,6 @@ USE_FIXED_SECTION(virt_trampolines)
        MASKED_INTERRUPT()
        MASKED_INTERRUPT(H)
 
-/*
- * Called from arch_local_irq_enable when an interrupt needs
- * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
- * which kind of interrupt. MSR:EE is already off. We generate a
- * stackframe like if a real interrupt had happened.
- *
- * Note: While MSR:EE is off, we need to make sure that _MSR
- * in the generated frame has EE set to 1 or the exception
- * handler will not properly re-enable them.
- */
-USE_TEXT_SECTION()
-_GLOBAL(__replay_interrupt)
-       /* We are going to jump to the exception common code which
-        * will retrieve various register values from the PACA which
-        * we don't give a damn about, so we don't bother storing them.
-        */
-       mfmsr   r12
-       mflr    r11
-       mfcr    r9
-       ori     r12,r12,MSR_EE
-       cmpwi   r3,0x900
-       beq     decrementer_common
-       cmpwi   r3,0x500
-       beq     hardware_interrupt_common
-BEGIN_FTR_SECTION
-       cmpwi   r3,0xe80
-       beq     h_doorbell_common
-       cmpwi   r3,0xea0
-       beq     h_virt_irq_common
-       cmpwi   r3,0xe60
-       beq     hmi_exception_common
-FTR_SECTION_ELSE
-       cmpwi   r3,0xa00
-       beq     doorbell_super_common
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
-       blr
-
 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER
 TRAMP_REAL_BEGIN(kvmppc_skip_interrupt)
        /*
@@ -1293,16 +1353,6 @@ TRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt)
 /*** Common interrupt handlers ***/
 
 
-EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ)
-EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception)
-EXC_COMMON(instruction_breakpoint_common, 0x1300, instruction_breakpoint_exception)
-EXC_COMMON_HV(denorm_common, 0x1500, unknown_exception)
-#ifdef CONFIG_ALTIVEC
-EXC_COMMON(altivec_assist_common, 0x1700, altivec_assist_exception)
-#else
-EXC_COMMON(altivec_assist_common, 0x1700, unknown_exception)
-#endif
-
        /*
         * Relocation-on interrupts: A subset of the interrupts can be delivered
         * with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering
@@ -1319,116 +1369,9 @@ EXC_COMMON(altivec_assist_common, 0x1700, unknown_exception)
         * come here.
         */
 
-__EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x4ec0)
-
-EXC_VIRT_NONE(0x4ec0, 0x4f00)
-
-__EXC_VIRT_OOL(performance_monitor, 0x4f00, 0x4f20)
-
-__EXC_VIRT_OOL(altivec_unavailable, 0x4f20, 0x4f40)
-
-__EXC_VIRT_OOL(vsx_unavailable, 0x4f40, 0x4f60)
-
-__EXC_VIRT_OOL(facility_unavailable, 0x4f60, 0x4f80)
-
-__EXC_VIRT_OOL_HV(h_facility_unavailable, 0x4f80, 0x4fa0)
-
-EXC_VIRT_NONE(0x4fa0, 0x5200)
-
-EXC_VIRT_NONE(0x5200, 0x5300)
-
-EXC_VIRT(instruction_breakpoint, 0x5300, 0x5400, 0x1300)
-
-#ifdef CONFIG_PPC_DENORMALISATION
-EXC_VIRT_BEGIN(denorm_exception, 0x5500, 0x5600)
-       b       exc_real_0x1500_denorm_exception_hv
-EXC_VIRT_END(denorm_exception, 0x5500, 0x5600)
-#else
-EXC_VIRT_NONE(0x5500, 0x5600)
-#endif
-
-EXC_VIRT_NONE(0x5600, 0x5700)
-
-EXC_VIRT(altivec_assist, 0x5700, 0x5800, 0x1700)
-
-EXC_VIRT_NONE(0x5800, 0x5900)
-
 EXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline)
        b       __ppc64_runlatch_on
 
-EXC_COMMON_BEGIN(altivec_unavailable_common)
-       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-       beq     1f
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-  BEGIN_FTR_SECTION_NESTED(69)
-       /* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
-        * transaction), go do TM stuff
-        */
-       rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
-       bne-    2f
-  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
-#endif
-       bl      load_up_altivec
-       b       fast_exception_return
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-2:     /* User process was in a transaction */
-       bl      save_nvgprs
-       RECONCILE_IRQ_STATE(r10, r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      altivec_unavailable_tm
-       b       ret_from_except
-#endif
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif
-       bl      save_nvgprs
-       RECONCILE_IRQ_STATE(r10, r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      altivec_unavailable_exception
-       b       ret_from_except
-
-EXC_COMMON_BEGIN(vsx_unavailable_common)
-       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       beq     1f
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-  BEGIN_FTR_SECTION_NESTED(69)
-       /* Test if 2 TM state bits are zero.  If non-zero (ie. userspace was in
-        * transaction), go do TM stuff
-        */
-       rldicl. r0, r12, (64-MSR_TS_LG), (64-2)
-       bne-    2f
-  END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69)
-#endif
-       b       load_up_vsx
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-2:     /* User process was in a transaction */
-       bl      save_nvgprs
-       RECONCILE_IRQ_STATE(r10, r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      vsx_unavailable_tm
-       b       ret_from_except
-#endif
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
-       bl      save_nvgprs
-       RECONCILE_IRQ_STATE(r10, r11)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      vsx_unavailable_exception
-       b       ret_from_except
-
-       /* Equivalents to the above handlers for relocation-on interrupt vectors */
-__TRAMP_REAL_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0xea0)
-__TRAMP_REAL_VIRT_OOL(performance_monitor, 0xf00)
-__TRAMP_REAL_VIRT_OOL(altivec_unavailable, 0xf20)
-__TRAMP_REAL_VIRT_OOL(vsx_unavailable, 0xf40)
-__TRAMP_REAL_VIRT_OOL(facility_unavailable, 0xf60)
-__TRAMP_REAL_VIRT_OOL_HV(h_facility_unavailable, 0xf80)
-
 USE_FIXED_SECTION(virt_trampolines)
        /*
         * The __end_interrupts marker must be past the out-of-line (OOL)
@@ -1442,16 +1385,6 @@ USE_FIXED_SECTION(virt_trampolines)
 __end_interrupts:
 DEFINE_FIXED_SYMBOL(__end_interrupts)
 
-EXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception)
-EXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception)
-
-#ifdef CONFIG_CBE_RAS
-EXC_COMMON(cbe_system_error_common, 0x1200, cbe_system_error_exception)
-EXC_COMMON(cbe_maintenance_common, 0x1600, cbe_maintenance_exception)
-EXC_COMMON(cbe_thermal_common, 0x1800, cbe_thermal_exception)
-#endif /* CONFIG_CBE_RAS */
-
-
 #ifdef CONFIG_PPC_970_NAP
 TRAMP_REAL_BEGIN(power4_fixup_nap)
        andc    r9,r9,r10
@@ -1613,3 +1546,39 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
 1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      kernel_bad_stack
        b       1b
+
+/*
+ * Called from arch_local_irq_enable when an interrupt needs
+ * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate
+ * which kind of interrupt. MSR:EE is already off. We generate a
+ * stackframe like if a real interrupt had happened.
+ *
+ * Note: While MSR:EE is off, we need to make sure that _MSR
+ * in the generated frame has EE set to 1 or the exception
+ * handler will not properly re-enable them.
+ */
+_GLOBAL(__replay_interrupt)
+       /* We are going to jump to the exception common code which
+        * will retrieve various register values from the PACA which
+        * we don't give a damn about, so we don't bother storing them.
+        */
+       mfmsr   r12
+       mflr    r11
+       mfcr    r9
+       ori     r12,r12,MSR_EE
+       cmpwi   r3,0x900
+       beq     decrementer_common
+       cmpwi   r3,0x500
+       beq     hardware_interrupt_common
+BEGIN_FTR_SECTION
+       cmpwi   r3,0xe80
+       beq     h_doorbell_common
+       cmpwi   r3,0xea0
+       beq     h_virt_irq_common
+       cmpwi   r3,0xe60
+       beq     hmi_exception_common
+FTR_SECTION_ELSE
+       cmpwi   r3,0xa00
+       beq     doorbell_super_common
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
+       blr