aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-04-27 10:33:35 -0400
committerAlexander Graf <agraf@suse.de>2012-05-16 09:02:10 -0400
commit56e13dbae3eddb1648e6e94ae251c83cdc8304e0 (patch)
treed9e7df8e8bf1917e82711e9437673535f40c8f55 /arch
parent7ef4e985d54bad2773f260da38530f858a9a8491 (diff)
KVM: PPC: Fix PR KVM on POWER7 bare metal
When running on a system that is HV capable, some interrupts use HSRR SPRs instead of the normal SRR SPRs. These are also used in the Linux handlers to jump back to code after an interrupt got processed. Unfortunately, in our "jump back to the real host handler after we've done the context switch" code, we were only setting the SRR SPRs, rendering Linux to jump back to some invalid IP after it's processed the interrupt. This fixes random crashes on p7 opal mode with PR KVM for me. Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kvm/book3s_segment.S35
1 files changed, 22 insertions, 13 deletions
diff --git a/arch/powerpc/kvm/book3s_segment.S b/arch/powerpc/kvm/book3s_segment.S
index 012fc9281213..87cfc1def241 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -197,6 +197,7 @@ kvmppc_interrupt:
197 /* Save guest PC and MSR */ 197 /* Save guest PC and MSR */
198#ifdef CONFIG_PPC64 198#ifdef CONFIG_PPC64
199BEGIN_FTR_SECTION 199BEGIN_FTR_SECTION
200 mr r10, r12
200 andi. r0,r12,0x2 201 andi. r0,r12,0x2
201 beq 1f 202 beq 1f
202 mfspr r3,SPRN_HSRR0 203 mfspr r3,SPRN_HSRR0
@@ -322,23 +323,17 @@ no_dcbz32_off:
322 * Having set up SRR0/1 with the address where we want 323 * Having set up SRR0/1 with the address where we want
323 * to continue with relocation on (potentially in module 324 * to continue with relocation on (potentially in module
324 * space), we either just go straight there with rfi[d], 325 * space), we either just go straight there with rfi[d],
325 * or we jump to an interrupt handler with bctr if there 326 * or we jump to an interrupt handler if there is an
326 * is an interrupt to be handled first. In the latter 327 * interrupt to be handled first. In the latter case,
327 * case, the rfi[d] at the end of the interrupt handler 328 * the rfi[d] at the end of the interrupt handler will
328 * will get us back to where we want to continue. 329 * get us back to where we want to continue.
329 */ 330 */
330 331
331 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
332 beq 1f
333 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
334 beq 1f
335 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
3361: mtctr r12
337
338 /* Register usage at this point: 332 /* Register usage at this point:
339 * 333 *
340 * R1 = host R1 334 * R1 = host R1
341 * R2 = host R2 335 * R2 = host R2
336 * R10 = raw exit handler id
342 * R12 = exit handler id 337 * R12 = exit handler id
343 * R13 = shadow vcpu (32-bit) or PACA (64-bit) 338 * R13 = shadow vcpu (32-bit) or PACA (64-bit)
344 * SVCPU.* = guest * 339 * SVCPU.* = guest *
@@ -348,12 +343,26 @@ no_dcbz32_off:
348 PPC_LL r6, HSTATE_HOST_MSR(r13) 343 PPC_LL r6, HSTATE_HOST_MSR(r13)
349 PPC_LL r8, HSTATE_VMHANDLER(r13) 344 PPC_LL r8, HSTATE_VMHANDLER(r13)
350 345
351 /* Restore host msr -> SRR1 */ 346#ifdef CONFIG_PPC64
347BEGIN_FTR_SECTION
348 andi. r0,r10,0x2
349 beq 1f
350 mtspr SPRN_HSRR1, r6
351 mtspr SPRN_HSRR0, r8
352END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
353#endif
3541: /* Restore host msr -> SRR1 */
352 mtsrr1 r6 355 mtsrr1 r6
353 /* Load highmem handler address */ 356 /* Load highmem handler address */
354 mtsrr0 r8 357 mtsrr0 r8
355 358
356 /* RFI into the highmem handler, or jump to interrupt handler */ 359 /* RFI into the highmem handler, or jump to interrupt handler */
357 beqctr 360 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
361 beqa BOOK3S_INTERRUPT_EXTERNAL
362 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
363 beqa BOOK3S_INTERRUPT_DECREMENTER
364 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
365 beqa BOOK3S_INTERRUPT_PERFMON
366
358 RFI 367 RFI
359kvmppc_handler_trampoline_exit_end: 368kvmppc_handler_trampoline_exit_end: