aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s_segment.S
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-04-27 10:33:35 -0400
committerAlexander Graf <agraf@suse.de>2012-05-06 10:19:10 -0400
commit11f7d6c2d1b17abf7b91e0f2d43bfe9de0b9e5cf (patch)
tree776b1daa70a1d1f08f861a0e7b6247c3a364ed5e /arch/powerpc/kvm/book3s_segment.S
parent978b4fae45b3fae803a9f56e2262f01f71b7dbc9 (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/powerpc/kvm/book3s_segment.S')
-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 6bae0a9414ba..8b2fc66a3066 100644
--- a/arch/powerpc/kvm/book3s_segment.S
+++ b/arch/powerpc/kvm/book3s_segment.S
@@ -198,6 +198,7 @@ kvmppc_interrupt:
198 /* Save guest PC and MSR */ 198 /* Save guest PC and MSR */
199#ifdef CONFIG_PPC64 199#ifdef CONFIG_PPC64
200BEGIN_FTR_SECTION 200BEGIN_FTR_SECTION
201 mr r10, r12
201 andi. r0,r12,0x2 202 andi. r0,r12,0x2
202 beq 1f 203 beq 1f
203 mfspr r3,SPRN_HSRR0 204 mfspr r3,SPRN_HSRR0
@@ -317,23 +318,17 @@ no_dcbz32_off:
317 * Having set up SRR0/1 with the address where we want 318 * Having set up SRR0/1 with the address where we want
318 * to continue with relocation on (potentially in module 319 * to continue with relocation on (potentially in module
319 * space), we either just go straight there with rfi[d], 320 * space), we either just go straight there with rfi[d],
320 * or we jump to an interrupt handler with bctr if there 321 * or we jump to an interrupt handler if there is an
321 * is an interrupt to be handled first. In the latter 322 * interrupt to be handled first. In the latter case,
322 * case, the rfi[d] at the end of the interrupt handler 323 * the rfi[d] at the end of the interrupt handler will
323 * will get us back to where we want to continue. 324 * get us back to where we want to continue.
324 */ 325 */
325 326
326 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
327 beq 1f
328 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
329 beq 1f
330 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
3311: mtctr r12
332
333 /* Register usage at this point: 327 /* Register usage at this point:
334 * 328 *
335 * R1 = host R1 329 * R1 = host R1
336 * R2 = host R2 330 * R2 = host R2
331 * R10 = raw exit handler id
337 * R12 = exit handler id 332 * R12 = exit handler id
338 * R13 = shadow vcpu (32-bit) or PACA (64-bit) 333 * R13 = shadow vcpu (32-bit) or PACA (64-bit)
339 * SVCPU.* = guest * 334 * SVCPU.* = guest *
@@ -343,12 +338,26 @@ no_dcbz32_off:
343 PPC_LL r6, HSTATE_HOST_MSR(r13) 338 PPC_LL r6, HSTATE_HOST_MSR(r13)
344 PPC_LL r8, HSTATE_VMHANDLER(r13) 339 PPC_LL r8, HSTATE_VMHANDLER(r13)
345 340
346 /* Restore host msr -> SRR1 */ 341#ifdef CONFIG_PPC64
342BEGIN_FTR_SECTION
343 andi. r0,r10,0x2
344 beq 1f
345 mtspr SPRN_HSRR1, r6
346 mtspr SPRN_HSRR0, r8
347END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
348#endif
3491: /* Restore host msr -> SRR1 */
347 mtsrr1 r6 350 mtsrr1 r6
348 /* Load highmem handler address */ 351 /* Load highmem handler address */
349 mtsrr0 r8 352 mtsrr0 r8
350 353
351 /* RFI into the highmem handler, or jump to interrupt handler */ 354 /* RFI into the highmem handler, or jump to interrupt handler */
352 beqctr 355 cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
356 beqa BOOK3S_INTERRUPT_EXTERNAL
357 cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
358 beqa BOOK3S_INTERRUPT_DECREMENTER
359 cmpwi r12, BOOK3S_INTERRUPT_PERFMON
360 beqa BOOK3S_INTERRUPT_PERFMON
361
353 RFI 362 RFI
354kvmppc_handler_trampoline_exit_end: 363kvmppc_handler_trampoline_exit_end: