aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/exceptions-64s.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2011-06-28 20:18:26 -0400
committerAvi Kivity <avi@redhat.com>2011-07-12 06:16:48 -0400
commitb01c8b54a1a271c0fc4243845927fe1d250767a3 (patch)
tree4e818a41d602aa07cbdc06eca9372b9b95c533a4 /arch/powerpc/kernel/exceptions-64s.S
parentf05ed4d56e9cff1c46d2b3049ba0c72e7e29392f (diff)
powerpc, KVM: Rework KVM checks in first-level interrupt handlers
Instead of branching out-of-line with the DO_KVM macro to check if we are in a KVM guest at the time of an interrupt, this moves the KVM check inline in the first-level interrupt handlers. This speeds up the non-KVM case and makes sure that none of the interrupt handlers are missing the check. Because the first-level interrupt handlers are now larger, some things had to be move out of line in exceptions-64s.S. This all necessitated some minor changes to the interrupt entry code in KVM. This also streamlines the book3s_32 KVM test. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64s.S')
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S189
1 files changed, 115 insertions, 74 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a85f4874cba7..e76472cbf3b5 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -40,7 +40,6 @@ __start_interrupts:
40 .globl system_reset_pSeries; 40 .globl system_reset_pSeries;
41system_reset_pSeries: 41system_reset_pSeries:
42 HMT_MEDIUM; 42 HMT_MEDIUM;
43 DO_KVM 0x100;
44 SET_SCRATCH0(r13) 43 SET_SCRATCH0(r13)
45#ifdef CONFIG_PPC_P7_NAP 44#ifdef CONFIG_PPC_P7_NAP
46BEGIN_FTR_SECTION 45BEGIN_FTR_SECTION
@@ -65,67 +64,45 @@ BEGIN_FTR_SECTION
65 beq . 64 beq .
66END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206) 65END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
67#endif /* CONFIG_PPC_P7_NAP */ 66#endif /* CONFIG_PPC_P7_NAP */
68 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD) 67 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
68 NOTEST, 0x100)
69 69
70 . = 0x200 70 . = 0x200
71_machine_check_pSeries: 71machine_check_pSeries_1:
72 HMT_MEDIUM 72 /* This is moved out of line as it can be patched by FW, but
73 DO_KVM 0x200 73 * some code path might still want to branch into the original
74 SET_SCRATCH0(r13) 74 * vector
75 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD) 75 */
76 b machine_check_pSeries
76 77
77 . = 0x300 78 . = 0x300
78 .globl data_access_pSeries 79 .globl data_access_pSeries
79data_access_pSeries: 80data_access_pSeries:
80 HMT_MEDIUM 81 HMT_MEDIUM
81 DO_KVM 0x300
82 SET_SCRATCH0(r13) 82 SET_SCRATCH0(r13)
83#ifndef CONFIG_POWER4_ONLY
83BEGIN_FTR_SECTION 84BEGIN_FTR_SECTION
84 GET_PACA(r13) 85 b data_access_check_stab
85 std r9,PACA_EXSLB+EX_R9(r13) 86data_access_not_stab:
86 std r10,PACA_EXSLB+EX_R10(r13) 87END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
87 mfspr r10,SPRN_DAR 88#endif
88 mfspr r9,SPRN_DSISR 89 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD,
89 srdi r10,r10,60 90 KVMTEST, 0x300)
90 rlwimi r10,r9,16,0x20
91 mfcr r9
92 cmpwi r10,0x2c
93 beq do_stab_bolted_pSeries
94 ld r10,PACA_EXSLB+EX_R10(r13)
95 std r11,PACA_EXGEN+EX_R11(r13)
96 ld r11,PACA_EXSLB+EX_R9(r13)
97 std r12,PACA_EXGEN+EX_R12(r13)
98 GET_SCRATCH0(r12)
99 std r10,PACA_EXGEN+EX_R10(r13)
100 std r11,PACA_EXGEN+EX_R9(r13)
101 std r12,PACA_EXGEN+EX_R13(r13)
102 EXCEPTION_PROLOG_PSERIES_1(data_access_common, EXC_STD)
103FTR_SECTION_ELSE
104 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD)
105ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_SLB)
106 91
107 . = 0x380 92 . = 0x380
108 .globl data_access_slb_pSeries 93 .globl data_access_slb_pSeries
109data_access_slb_pSeries: 94data_access_slb_pSeries:
110 HMT_MEDIUM 95 HMT_MEDIUM
111 DO_KVM 0x380
112 SET_SCRATCH0(r13) 96 SET_SCRATCH0(r13)
113 GET_PACA(r13) 97 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x380)
114 std r3,PACA_EXSLB+EX_R3(r13) 98 std r3,PACA_EXSLB+EX_R3(r13)
115 mfspr r3,SPRN_DAR 99 mfspr r3,SPRN_DAR
116 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
117 mfcr r9
118#ifdef __DISABLED__ 100#ifdef __DISABLED__
119 /* Keep that around for when we re-implement dynamic VSIDs */ 101 /* Keep that around for when we re-implement dynamic VSIDs */
120 cmpdi r3,0 102 cmpdi r3,0
121 bge slb_miss_user_pseries 103 bge slb_miss_user_pseries
122#endif /* __DISABLED__ */ 104#endif /* __DISABLED__ */
123 std r10,PACA_EXSLB+EX_R10(r13) 105 mfspr r12,SPRN_SRR1
124 std r11,PACA_EXSLB+EX_R11(r13)
125 std r12,PACA_EXSLB+EX_R12(r13)
126 GET_SCRATCH0(r10)
127 std r10,PACA_EXSLB+EX_R13(r13)
128 mfspr r12,SPRN_SRR1 /* and SRR1 */
129#ifndef CONFIG_RELOCATABLE 106#ifndef CONFIG_RELOCATABLE
130 b .slb_miss_realmode 107 b .slb_miss_realmode
131#else 108#else
@@ -147,24 +124,16 @@ data_access_slb_pSeries:
147 .globl instruction_access_slb_pSeries 124 .globl instruction_access_slb_pSeries
148instruction_access_slb_pSeries: 125instruction_access_slb_pSeries:
149 HMT_MEDIUM 126 HMT_MEDIUM
150 DO_KVM 0x480
151 SET_SCRATCH0(r13) 127 SET_SCRATCH0(r13)
152 GET_PACA(r13) 128 EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST, 0x480)
153 std r3,PACA_EXSLB+EX_R3(r13) 129 std r3,PACA_EXSLB+EX_R3(r13)
154 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 130 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
155 std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
156 mfcr r9
157#ifdef __DISABLED__ 131#ifdef __DISABLED__
158 /* Keep that around for when we re-implement dynamic VSIDs */ 132 /* Keep that around for when we re-implement dynamic VSIDs */
159 cmpdi r3,0 133 cmpdi r3,0
160 bge slb_miss_user_pseries 134 bge slb_miss_user_pseries
161#endif /* __DISABLED__ */ 135#endif /* __DISABLED__ */
162 std r10,PACA_EXSLB+EX_R10(r13) 136 mfspr r12,SPRN_SRR1
163 std r11,PACA_EXSLB+EX_R11(r13)
164 std r12,PACA_EXSLB+EX_R12(r13)
165 GET_SCRATCH0(r10)
166 std r10,PACA_EXSLB+EX_R13(r13)
167 mfspr r12,SPRN_SRR1 /* and SRR1 */
168#ifndef CONFIG_RELOCATABLE 137#ifndef CONFIG_RELOCATABLE
169 b .slb_miss_realmode 138 b .slb_miss_realmode
170#else 139#else
@@ -184,26 +153,46 @@ instruction_access_slb_pSeries:
184hardware_interrupt_pSeries: 153hardware_interrupt_pSeries:
185hardware_interrupt_hv: 154hardware_interrupt_hv:
186 BEGIN_FTR_SECTION 155 BEGIN_FTR_SECTION
187 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD) 156 _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt,
157 EXC_STD, SOFTEN_TEST)
158 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500)
188 FTR_SECTION_ELSE 159 FTR_SECTION_ELSE
189 _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV) 160 _MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt,
161 EXC_HV, SOFTEN_TEST_HV)
162 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502)
190 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206) 163 ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206)
191 164
192 STD_EXCEPTION_PSERIES(0x600, 0x600, alignment) 165 STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
166 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x600)
167
193 STD_EXCEPTION_PSERIES(0x700, 0x700, program_check) 168 STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
169 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x700)
170
194 STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable) 171 STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
172 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x800)
195 173
196 MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer) 174 MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
197 MASKABLE_EXCEPTION_HV(0x980, 0x980, decrementer) 175 MASKABLE_EXCEPTION_HV(0x980, 0x982, decrementer)
198 176
199 STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a) 177 STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
178 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xa00)
179
200 STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b) 180 STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
181 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xb00)
201 182
202 . = 0xc00 183 . = 0xc00
203 .globl system_call_pSeries 184 .globl system_call_pSeries
204system_call_pSeries: 185system_call_pSeries:
205 HMT_MEDIUM 186 HMT_MEDIUM
206 DO_KVM 0xc00 187#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
188 SET_SCRATCH0(r13)
189 GET_PACA(r13)
190 std r9,PACA_EXGEN+EX_R9(r13)
191 std r10,PACA_EXGEN+EX_R10(r13)
192 mfcr r9
193 KVMTEST(0xc00)
194 GET_SCRATCH0(r13)
195#endif
207BEGIN_FTR_SECTION 196BEGIN_FTR_SECTION
208 cmpdi r0,0x1ebe 197 cmpdi r0,0x1ebe
209 beq- 1f 198 beq- 1f
@@ -220,6 +209,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
220 rfid 209 rfid
221 b . /* prevent speculative execution */ 210 b . /* prevent speculative execution */
222 211
212 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00)
213
223/* Fast LE/BE switch system call */ 214/* Fast LE/BE switch system call */
2241: mfspr r12,SPRN_SRR1 2151: mfspr r12,SPRN_SRR1
225 xori r12,r12,MSR_LE 216 xori r12,r12,MSR_LE
@@ -228,6 +219,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
228 b . 219 b .
229 220
230 STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step) 221 STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
222 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xd00)
231 223
232 /* At 0xe??? we have a bunch of hypervisor exceptions, we branch 224 /* At 0xe??? we have a bunch of hypervisor exceptions, we branch
233 * out of line to handle them 225 * out of line to handle them
@@ -262,30 +254,93 @@ vsx_unavailable_pSeries_1:
262 254
263#ifdef CONFIG_CBE_RAS 255#ifdef CONFIG_CBE_RAS
264 STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error) 256 STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
257 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1202)
265#endif /* CONFIG_CBE_RAS */ 258#endif /* CONFIG_CBE_RAS */
259
266 STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) 260 STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
261 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1300)
262
267#ifdef CONFIG_CBE_RAS 263#ifdef CONFIG_CBE_RAS
268 STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) 264 STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
265 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602)
269#endif /* CONFIG_CBE_RAS */ 266#endif /* CONFIG_CBE_RAS */
267
270 STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist) 268 STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
269 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x1700)
270
271#ifdef CONFIG_CBE_RAS 271#ifdef CONFIG_CBE_RAS
272 STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal) 272 STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
273 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1802)
273#endif /* CONFIG_CBE_RAS */ 274#endif /* CONFIG_CBE_RAS */
274 275
275 . = 0x3000 276 . = 0x3000
276 277
277/*** Out of line interrupts support ***/ 278/*** Out of line interrupts support ***/
278 279
280 /* moved from 0x200 */
281machine_check_pSeries:
282 .globl machine_check_fwnmi
283machine_check_fwnmi:
284 HMT_MEDIUM
285 SET_SCRATCH0(r13) /* save r13 */
286 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common,
287 EXC_STD, KVMTEST, 0x200)
288 KVM_HANDLER_SKIP(PACA_EXMC, EXC_STD, 0x200)
289
290#ifndef CONFIG_POWER4_ONLY
291 /* moved from 0x300 */
292data_access_check_stab:
293 GET_PACA(r13)
294 std r9,PACA_EXSLB+EX_R9(r13)
295 std r10,PACA_EXSLB+EX_R10(r13)
296 mfspr r10,SPRN_DAR
297 mfspr r9,SPRN_DSISR
298 srdi r10,r10,60
299 rlwimi r10,r9,16,0x20
300#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
301 lbz r9,PACA_KVM_SVCPU+SVCPU_IN_GUEST(r13)
302 rlwimi r10,r9,8,0x300
303#endif
304 mfcr r9
305 cmpwi r10,0x2c
306 beq do_stab_bolted_pSeries
307 mtcrf 0x80,r9
308 ld r9,PACA_EXSLB+EX_R9(r13)
309 ld r10,PACA_EXSLB+EX_R10(r13)
310 b data_access_not_stab
311do_stab_bolted_pSeries:
312 std r11,PACA_EXSLB+EX_R11(r13)
313 std r12,PACA_EXSLB+EX_R12(r13)
314 GET_SCRATCH0(r10)
315 std r10,PACA_EXSLB+EX_R13(r13)
316 EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
317#endif /* CONFIG_POWER4_ONLY */
318
319 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x300)
320 KVM_HANDLER_SKIP(PACA_EXSLB, EXC_STD, 0x380)
321 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x400)
322 KVM_HANDLER(PACA_EXSLB, EXC_STD, 0x480)
323 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x900)
324 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982)
325
326 .align 7
279 /* moved from 0xe00 */ 327 /* moved from 0xe00 */
280 STD_EXCEPTION_HV(., 0xe00, h_data_storage) 328 STD_EXCEPTION_HV(., 0xe02, h_data_storage)
281 STD_EXCEPTION_HV(., 0xe20, h_instr_storage) 329 KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0xe02)
282 STD_EXCEPTION_HV(., 0xe40, emulation_assist) 330 STD_EXCEPTION_HV(., 0xe22, h_instr_storage)
283 STD_EXCEPTION_HV(., 0xe60, hmi_exception) /* need to flush cache ? */ 331 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe22)
332 STD_EXCEPTION_HV(., 0xe42, emulation_assist)
333 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe42)
334 STD_EXCEPTION_HV(., 0xe62, hmi_exception) /* need to flush cache ? */
335 KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe62)
284 336
285 /* moved from 0xf00 */ 337 /* moved from 0xf00 */
286 STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor) 338 STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
339 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf00)
287 STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable) 340 STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
341 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf20)
288 STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable) 342 STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
343 KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf40)
289 344
290/* 345/*
291 * An interrupt came in while soft-disabled; clear EE in SRR1, 346 * An interrupt came in while soft-disabled; clear EE in SRR1,
@@ -317,14 +372,6 @@ masked_Hinterrupt:
317 hrfid 372 hrfid
318 b . 373 b .
319 374
320 .align 7
321do_stab_bolted_pSeries:
322 std r11,PACA_EXSLB+EX_R11(r13)
323 std r12,PACA_EXSLB+EX_R12(r13)
324 GET_SCRATCH0(r10)
325 std r10,PACA_EXSLB+EX_R13(r13)
326 EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
327
328#ifdef CONFIG_PPC_PSERIES 375#ifdef CONFIG_PPC_PSERIES
329/* 376/*
330 * Vectors for the FWNMI option. Share common code. 377 * Vectors for the FWNMI option. Share common code.
@@ -334,14 +381,8 @@ do_stab_bolted_pSeries:
334system_reset_fwnmi: 381system_reset_fwnmi:
335 HMT_MEDIUM 382 HMT_MEDIUM
336 SET_SCRATCH0(r13) /* save r13 */ 383 SET_SCRATCH0(r13) /* save r13 */
337 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD) 384 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD,
338 385 NOTEST, 0x100)
339 .globl machine_check_fwnmi
340 .align 7
341machine_check_fwnmi:
342 HMT_MEDIUM
343 SET_SCRATCH0(r13) /* save r13 */
344 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
345 386
346#endif /* CONFIG_PPC_PSERIES */ 387#endif /* CONFIG_PPC_PSERIES */
347 388