[PATCH 13/14] powerpc/pseries: consolidate slb exceptions
Nicholas Piggin
nicholas.piggin at gmail.com
Thu Jul 21 16:44:12 AEST 2016
slb exceptions all follow the same pattern, so put it in a macro.
Generated code should be the same.
Signed-off-by: Nick Piggin <npiggin at gmail.com>
---
arch/powerpc/kernel/exceptions-64s.S | 172 ++++++++++++++---------------------
1 file changed, 69 insertions(+), 103 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index b7a8a66..c317faf 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -497,111 +497,32 @@ MMU_FTR_SECTION_ELSE
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_RADIX)
COMMON_HANDLER_END(data_access_common)
-
-VECTOR_HANDLER_REAL_BEGIN(data_access_slb, 0x380, 0x400)
- SET_SCRATCH0(r13)
- EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r3,SPRN_DAR
- mfspr r12,SPRN_SRR1
-#ifndef CONFIG_RELOCATABLE
- b slb_miss_realmode
-#else
- /*
- * We can't just use a direct branch to slb_miss_realmode
- * because the distance from here to there depends on where
- * the kernel ends up being put.
- */
- mfctr r11
- ld r10,PACAKBASE(r13)
- LOAD_HANDLER_4G(r10, slb_miss_realmode)
- mtctr r10
- bctr
-#endif
-VECTOR_HANDLER_REAL_END(data_access_slb, 0x380, 0x400)
-
-VECTOR_HANDLER_VIRT_BEGIN(data_access_slb, 0x4380, 0x4400)
- SET_SCRATCH0(r13)
- EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r3,SPRN_DAR
- mfspr r12,SPRN_SRR1
-#ifndef CONFIG_RELOCATABLE
- b slb_miss_realmode
-#else
- /*
- * We can't just use a direct branch to slb_miss_realmode
- * because the distance from here to there depends on where
- * the kernel ends up being put.
- */
- mfctr r11
- ld r10,PACAKBASE(r13)
- LOAD_HANDLER_4G(r10, slb_miss_realmode)
- mtctr r10
- bctr
-#endif
-VECTOR_HANDLER_VIRT_END(data_access_slb, 0x4380, 0x4400)
-TRAMP_KVM_SKIP(PACA_EXSLB, 0x380)
-
-
-VECTOR_HANDLER_REAL(instruction_access, 0x400, 0x480)
-VECTOR_HANDLER_VIRT(instruction_access, 0x4400, 0x4480, 0x400)
-TRAMP_KVM(PACA_EXGEN, 0x400)
-COMMON_HANDLER_BEGIN(instruction_access_common)
- EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
- RECONCILE_IRQ_STATE(r10, r11)
- ld r12,_MSR(r1)
- ld r3,_NIP(r1)
- andis. r4,r12,0x5820
- li r5,0x400
- std r3,_DAR(r1)
- std r4,_DSISR(r1)
-BEGIN_MMU_FTR_SECTION
- b do_hash_page /* Try to handle as hpte fault */
-MMU_FTR_SECTION_ELSE
- b handle_page_fault
-ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_RADIX)
-COMMON_HANDLER_END(instruction_access_common)
-
-
-VECTOR_HANDLER_REAL_BEGIN(instruction_access_slb, 0x480, 0x500)
- SET_SCRATCH0(r13)
- EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
- mfspr r12,SPRN_SRR1
-#ifndef CONFIG_RELOCATABLE
- b slb_miss_realmode
-#else
- mfctr r11
- ld r10,PACAKBASE(r13)
- LOAD_HANDLER_4G(r10, slb_miss_realmode)
- mtctr r10
- bctr
-#endif
-VECTOR_HANDLER_REAL_END(instruction_access_slb, 0x480, 0x500)
-VECTOR_HANDLER_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x4500)
- SET_SCRATCH0(r13)
- EXCEPTION_PROLOG_0(PACA_EXSLB)
- EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
- std r3,PACA_EXSLB+EX_R3(r13)
- mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
- mfspr r12,SPRN_SRR1
-#ifndef CONFIG_RELOCATABLE
- b slb_miss_realmode
+/*
+ * SLB miss macro takes care of all 4 cases (I/D, real/virt)
+ */
+#if defined(CONFIG_RELOCATABLE)
+#define SLB_ACCESS_EXCEPTION(addr_spr, vec, TEST) \
+ SET_SCRATCH0(r13); \
+ EXCEPTION_PROLOG_0(PACA_EXSLB); \
+ EXCEPTION_PROLOG_1(PACA_EXSLB, TEST, vec); \
+ std r3,PACA_EXSLB+EX_R3(r13); \
+ mfspr r3,addr_spr; \
+ mfspr r12,SPRN_SRR1; \
+ mfctr r11; \
+ ld r10,PACAKBASE(r13); \
+ LOAD_HANDLER_4G(r10, slb_miss_realmode); \
+ mtctr r10; \
+ bctr;
#else
- mfctr r11
- ld r10,PACAKBASE(r13)
- LOAD_HANDLER_4G(r10, slb_miss_realmode)
- mtctr r10
- bctr
+#define SLB_ACCESS_EXCEPTION(addr_spr, vec, TEST) \
+ SET_SCRATCH0(r13); \
+ EXCEPTION_PROLOG_0(PACA_EXSLB); \
+ EXCEPTION_PROLOG_1(PACA_EXSLB, TEST, vec); \
+ std r3,PACA_EXSLB+EX_R3(r13); \
+ mfspr r3,addr_spr; \
+ mfspr r12,SPRN_SRR1; \
+ b slb_miss_realmode;
#endif
-VECTOR_HANDLER_VIRT_END(instruction_access_slb, 0x4480, 0x4500)
-TRAMP_KVM(PACA_EXSLB, 0x480)
-
TRAMP_HANDLER_BEGIN(slb_miss_realmode)
/*
@@ -674,6 +595,45 @@ COMMON_HANDLER_BEGIN(unrecov_slb)
COMMON_HANDLER_END(unrecov_slb)
+VECTOR_HANDLER_REAL_BEGIN(data_access_slb, 0x380, 0x400)
+ SLB_ACCESS_EXCEPTION(SPRN_DAR, 0x380, KVMTEST_PR)
+VECTOR_HANDLER_REAL_END(data_access_slb, 0x380, 0x400)
+
+VECTOR_HANDLER_VIRT_BEGIN(data_access_slb, 0x4380, 0x4400)
+ SLB_ACCESS_EXCEPTION(SPRN_DAR, 0x380, NOTEST)
+VECTOR_HANDLER_VIRT_END(data_access_slb, 0x4380, 0x4400)
+TRAMP_KVM_SKIP(PACA_EXSLB, 0x380)
+
+
+VECTOR_HANDLER_REAL(instruction_access, 0x400, 0x480)
+VECTOR_HANDLER_VIRT(instruction_access, 0x4400, 0x4480, 0x400)
+TRAMP_KVM(PACA_EXGEN, 0x400)
+COMMON_HANDLER_BEGIN(instruction_access_common)
+ EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+ RECONCILE_IRQ_STATE(r10, r11)
+ ld r12,_MSR(r1)
+ ld r3,_NIP(r1)
+ andis. r4,r12,0x5820
+ li r5,0x400
+ std r3,_DAR(r1)
+ std r4,_DSISR(r1)
+BEGIN_MMU_FTR_SECTION
+ b do_hash_page /* Try to handle as hpte fault */
+MMU_FTR_SECTION_ELSE
+ b handle_page_fault
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_RADIX)
+COMMON_HANDLER_END(instruction_access_common)
+
+
+VECTOR_HANDLER_REAL_BEGIN(instruction_access_slb, 0x480, 0x500)
+ SLB_ACCESS_EXCEPTION(SPRN_SRR0, 0x480, KVMTEST_PR)
+VECTOR_HANDLER_REAL_END(instruction_access_slb, 0x480, 0x500)
+VECTOR_HANDLER_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x4500)
+ SLB_ACCESS_EXCEPTION(SPRN_SRR0, 0x480, NOTEST)
+VECTOR_HANDLER_VIRT_END(instruction_access_slb, 0x4480, 0x4500)
+TRAMP_KVM(PACA_EXSLB, 0x480)
+
+
VECTOR_HANDLER_REAL_BEGIN(hardware_interrupt, 0x500, 0x600)
.globl hardware_interrupt_hv;
hardware_interrupt_hv:
@@ -922,7 +882,13 @@ TRAMP_KVM_HV(PACA_EXGEN, 0xe40)
COMMON_HANDLER(emulation_assist_common, 0xe40, emulation_assist_interrupt)
+/*
+ * hmi_exception trampoline is a special case. It jumps to hmi_exception_early
+ * first, and then eventaully from there to the trampoline to get into virtual
+ * mode.
+ */
__VECTOR_HANDLER_REAL_OOL_HV_DIRECT(hmi_exception, 0xe60, 0xe80, hmi_exception_early)
+__TRAMP_HANDLER_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60)
VECTOR_HANDLER_VIRT_NONE(0x4e60, 0x4e80)
TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
COMMON_HANDLER_BEGIN(hmi_exception_early)
--
2.8.1
More information about the Linuxppc-dev
mailing list