aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2012-11-02 02:21:43 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-11-14 23:08:05 -0500
commitc1fb6816fb1b78dd94b673b0fdaa9a7a16e97bd1 (patch)
tree80a3f3b0fa7aa6a999b2f586f9201aea69da4ca7 /arch
parent4700dfaf1e988b785bd9791064df92d3353e8b88 (diff)
powerpc: Add relocation on exception vector handlers
POWER8/v2.07 allows exceptions to be taken with the MMU still on. A new set of exception vectors is added at 0xc000_0000_0000_4xxx. When the HW takes us here, MSR IR/DR will be set already and we no longer need a costly RFID to turn the MMU back on again. The original 0x0 based exception vectors remain for when the HW can't leave the MMU on. Examples of this are when we can't trust the current MMU mappings, like when we are changing from guest to hypervisor (HV 0 -> 1) or when the MMU was off already. In these cases the HW will take us to the original 0x0 based exception vectors with the MMU off as before. This uses the new macros added previously too implement these new execption vectors at 0xc000_0000_0000_4xxx. We exit these exception vectors using mflr/blr (rather than mtspr SSR0/RFID), since we don't need the costly MMU switch anymore. This moves the __end_interrupts marker down past these new 0x4000 vectors since they will need to be copied down to 0x0 when the kernel is not at 0x0. Signed-off-by: Matt Evans <matt@ozlabs.org> Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h4
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S180
-rw-r--r--arch/powerpc/kernel/head_64.S3
3 files changed, 177 insertions, 10 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 10787d3673ac..ad708dda3ba3 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -115,6 +115,7 @@
115 mfspr r10,SPRN_CFAR; \ 115 mfspr r10,SPRN_CFAR; \
116 std r10,area+EX_CFAR(r13); \ 116 std r10,area+EX_CFAR(r13); \
117 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ 117 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
118 SAVE_LR(r10, area); \
118 mfcr r9; \ 119 mfcr r9; \
119 extra(vec); \ 120 extra(vec); \
120 std r11,area+EX_R11(r13); \ 121 std r11,area+EX_R11(r13); \
@@ -215,6 +216,7 @@ do_kvm_##n: \
215 sth r1,PACA_TRAP_SAVE(r13); \ 216 sth r1,PACA_TRAP_SAVE(r13); \
216 std r3,area+EX_R3(r13); \ 217 std r3,area+EX_R3(r13); \
217 addi r3,r13,area; /* r3 -> where regs are saved*/ \ 218 addi r3,r13,area; /* r3 -> where regs are saved*/ \
219 RESTORE_LR(r1, area); \
218 b bad_stack; \ 220 b bad_stack; \
2193: std r9,_CCR(r1); /* save CR in stackframe */ \ 2213: std r9,_CCR(r1); /* save CR in stackframe */ \
220 std r11,_NIP(r1); /* save SRR0 in stackframe */ \ 222 std r11,_NIP(r1); /* save SRR0 in stackframe */ \
@@ -240,8 +242,8 @@ do_kvm_##n: \
240 ld r10,area+EX_CFAR(r13); \ 242 ld r10,area+EX_CFAR(r13); \
241 std r10,ORIG_GPR3(r1); \ 243 std r10,ORIG_GPR3(r1); \
242 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ 244 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
245 GET_LR(r9,area); /* Get LR, later save to stack */ \
243 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ 246 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
244 mflr r9; /* save LR in stackframe */ \
245 std r9,_LINK(r1); \ 247 std r9,_LINK(r1); \
246 mfctr r10; /* save CTR in stackframe */ \ 248 mfctr r10; /* save CTR in stackframe */ \
247 std r10,_CTR(r1); \ 249 std r10,_CTR(r1); \
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4dc1a045052a..4665e82fa377 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -19,11 +19,13 @@
19/* 19/*
20 * We layout physical memory as follows: 20 * We layout physical memory as follows:
21 * 0x0000 - 0x00ff : Secondary processor spin code 21 * 0x0000 - 0x00ff : Secondary processor spin code
22 * 0x0100 - 0x2fff : pSeries Interrupt prologs 22 * 0x0100 - 0x17ff : pSeries Interrupt prologs
23 * 0x3000 - 0x5fff : interrupt support common interrupt prologs 23 * 0x1800 - 0x4000 : interrupt support common interrupt prologs
24 * 0x6000 - 0x6fff : Initial (CPU0) segment table 24 * 0x4000 - 0x5fff : pSeries interrupts with IR=1,DR=1
25 * 0x6000 - 0x6fff : more interrupt support including for IR=1,DR=1
25 * 0x7000 - 0x7fff : FWNMI data area 26 * 0x7000 - 0x7fff : FWNMI data area
26 * 0x8000 - : Early init and support code 27 * 0x8000 - 0x8fff : Initial (CPU0) segment table
28 * 0x9000 - : Early init and support code
27 */ 29 */
28 /* Syscall routine is used twice, in reloc-off and reloc-on paths */ 30 /* Syscall routine is used twice, in reloc-off and reloc-on paths */
29#define SYSCALL_PSERIES_1 \ 31#define SYSCALL_PSERIES_1 \
@@ -619,10 +621,6 @@ slb_miss_user_pseries:
619 b . /* prevent spec. execution */ 621 b . /* prevent spec. execution */
620#endif /* __DISABLED__ */ 622#endif /* __DISABLED__ */
621 623
622 .align 7
623 .globl __end_interrupts
624__end_interrupts:
625
626/* 624/*
627 * Code from here down to __end_handlers is invoked from the 625 * Code from here down to __end_handlers is invoked from the
628 * exception prologs above. Because the prologs assemble the 626 * exception prologs above. Because the prologs assemble the
@@ -673,7 +671,158 @@ machine_check_common:
673 STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception) 671 STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
674#endif /* CONFIG_CBE_RAS */ 672#endif /* CONFIG_CBE_RAS */
675 673
674 /*
675 * Relocation-on interrupts: A subset of the interrupts can be delivered
676 * with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering
677 * it. Addresses are the same as the original interrupt addresses, but
678 * offset by 0xc000000000004000.
679 * It's impossible to receive interrupts below 0x300 via this mechanism.
680 * KVM: None of these traps are from the guest ; anything that escalated
681 * to HV=1 from HV=0 is delivered via real mode handlers.
682 */
683
684 /*
685 * This uses the standard macro, since the original 0x300 vector
686 * only has extra guff for STAB-based processors -- which never
687 * come here.
688 */
689 STD_RELON_EXCEPTION_PSERIES(0x4300, 0x300, data_access)
690 . = 0x4380
691 .globl data_access_slb_relon_pSeries
692data_access_slb_relon_pSeries:
693 HMT_MEDIUM
694 SET_SCRATCH0(r13)
695 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380)
696 std r3,PACA_EXSLB+EX_R3(r13)
697 mfspr r3,SPRN_DAR
698 mfspr r12,SPRN_SRR1
699#ifndef CONFIG_RELOCATABLE
700 b .slb_miss_realmode
701#else
702 /*
703 * We can't just use a direct branch to .slb_miss_realmode
704 * because the distance from here to there depends on where
705 * the kernel ends up being put.
706 */
707 mfctr r11
708 ld r10,PACAKBASE(r13)
709 LOAD_HANDLER(r10, .slb_miss_realmode)
710 mtctr r10
711 bctr
712#endif
713
714 STD_RELON_EXCEPTION_PSERIES(0x4400, 0x400, instruction_access)
715 . = 0x4480
716 .globl instruction_access_slb_relon_pSeries
717instruction_access_slb_relon_pSeries:
718 HMT_MEDIUM
719 SET_SCRATCH0(r13)
720 EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480)
721 std r3,PACA_EXSLB+EX_R3(r13)
722 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
723 mfspr r12,SPRN_SRR1
724#ifndef CONFIG_RELOCATABLE
725 b .slb_miss_realmode
726#else
727 mfctr r11
728 ld r10,PACAKBASE(r13)
729 LOAD_HANDLER(r10, .slb_miss_realmode)
730 mtctr r10
731 bctr
732#endif
733
734 . = 0x4500
735 .globl hardware_interrupt_relon_pSeries;
736 .globl hardware_interrupt_relon_hv;
737hardware_interrupt_relon_pSeries:
738hardware_interrupt_relon_hv:
739 BEGIN_FTR_SECTION
740 _MASKABLE_RELON_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV, SOFTEN_TEST_HV)
741 FTR_SECTION_ELSE
742 _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD, SOFTEN_TEST_PR)
743 ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_206)
744 STD_RELON_EXCEPTION_PSERIES(0x4600, 0x600, alignment)
745 STD_RELON_EXCEPTION_PSERIES(0x4700, 0x700, program_check)
746 STD_RELON_EXCEPTION_PSERIES(0x4800, 0x800, fp_unavailable)
747 MASKABLE_RELON_EXCEPTION_PSERIES(0x4900, 0x900, decrementer)
748 STD_RELON_EXCEPTION_HV(0x4980, 0x982, hdecrementer)
749 STD_RELON_EXCEPTION_PSERIES(0x4b00, 0xb00, trap_0b)
750
751 . = 0x4c00
752 .globl system_call_relon_pSeries
753system_call_relon_pSeries:
754 HMT_MEDIUM
755 SYSCALL_PSERIES_1
756 SYSCALL_PSERIES_2_DIRECT
757 SYSCALL_PSERIES_3
758
759 STD_RELON_EXCEPTION_PSERIES(0x4d00, 0xd00, single_step)
760
761 . = 0x4e00
762 b h_data_storage_relon_hv
763
764 . = 0x4e20
765 b h_instr_storage_relon_hv
766
767 . = 0x4e40
768 b emulation_assist_relon_hv
769
770 . = 0x4e50
771 b hmi_exception_relon_hv
772
773 . = 0x4e60
774 b hmi_exception_relon_hv
775
776 /* For when we support the doorbell interrupt:
777 STD_RELON_EXCEPTION_HYPERVISOR(0x4e80, 0xe80, doorbell_hyper)
778 */
779
780performance_monitor_relon_pSeries_1:
781 . = 0x4f00
782 b performance_monitor_relon_pSeries
783
784altivec_unavailable_relon_pSeries_1:
785 . = 0x4f20
786 b altivec_unavailable_relon_pSeries
787
788vsx_unavailable_relon_pSeries_1:
789 . = 0x4f40
790 b vsx_unavailable_relon_pSeries
791
792#ifdef CONFIG_CBE_RAS
793 STD_RELON_EXCEPTION_HV(0x5200, 0x1202, cbe_system_error)
794#endif /* CONFIG_CBE_RAS */
795 STD_RELON_EXCEPTION_PSERIES(0x5300, 0x1300, instruction_breakpoint)
796#ifdef CONFIG_PPC_DENORMALISATION
797 . = 0x5500
798 b denorm_exception_hv
799#endif
800#ifdef CONFIG_CBE_RAS
801 STD_RELON_EXCEPTION_HV(0x5600, 0x1602, cbe_maintenance)
802#else
803#ifdef CONFIG_HVC_SCOM
804 STD_RELON_EXCEPTION_HV(0x5600, 0x1600, maintence_interrupt)
805 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1600)
806#endif /* CONFIG_HVC_SCOM */
807#endif /* CONFIG_CBE_RAS */
808 STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
809#ifdef CONFIG_CBE_RAS
810 STD_RELON_EXCEPTION_HV(0x5800, 0x1802, cbe_thermal)
811#endif /* CONFIG_CBE_RAS */
812
813 /* Other future vectors */
814 .align 7
815 .globl __end_interrupts
816__end_interrupts:
817
676 .align 7 818 .align 7
819system_call_entry_direct:
820#if defined(CONFIG_RELOCATABLE)
821 /* The first level prologue may have used LR to get here, saving
822 * orig in r10. To save hacking/ifdeffing common code, restore here.
823 */
824 mtlr r10
825#endif
677system_call_entry: 826system_call_entry:
678 b system_call_common 827 b system_call_common
679 828
@@ -1196,6 +1345,21 @@ _GLOBAL(do_stab_bolted)
1196 rfid 1345 rfid
1197 b . /* prevent speculative execution */ 1346 b . /* prevent speculative execution */
1198 1347
1348
1349 /* Equivalents to the above handlers for relocation-on interrupt vectors */
1350 STD_RELON_EXCEPTION_HV(., 0xe00, h_data_storage)
1351 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe00)
1352 STD_RELON_EXCEPTION_HV(., 0xe20, h_instr_storage)
1353 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe20)
1354 STD_RELON_EXCEPTION_HV(., 0xe40, emulation_assist)
1355 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe40)
1356 STD_RELON_EXCEPTION_HV(., 0xe60, hmi_exception)
1357 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe60)
1358
1359 STD_RELON_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
1360 STD_RELON_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
1361 STD_RELON_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
1362
1199#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 1363#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
1200/* 1364/*
1201 * Data area reserved for FWNMI option. 1365 * Data area reserved for FWNMI option.
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 11a4df9dd580..116f0868695b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -432,7 +432,8 @@ _STATIC(__after_prom_start)
432 cmplwi cr0,r7,1 432 cmplwi cr0,r7,1
433 bne 3f 433 bne 3f
434 434
435 li r5,__end_interrupts - _stext /* just copy interrupts */ 435 /* just copy interrupts */
436 LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
436 b 5f 437 b 5f
4373: 4383:
438#endif 439#endif