Commit 11f7d6c2 authored by Alexander Graf's avatar Alexander Graf

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: default avatarAlexander Graf <agraf@suse.de>
parent 978b4fae
...@@ -198,6 +198,7 @@ kvmppc_interrupt: ...@@ -198,6 +198,7 @@ kvmppc_interrupt:
/* Save guest PC and MSR */ /* Save guest PC and MSR */
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
BEGIN_FTR_SECTION BEGIN_FTR_SECTION
mr r10, r12
andi. r0,r12,0x2 andi. r0,r12,0x2
beq 1f beq 1f
mfspr r3,SPRN_HSRR0 mfspr r3,SPRN_HSRR0
...@@ -317,23 +318,17 @@ no_dcbz32_off: ...@@ -317,23 +318,17 @@ no_dcbz32_off:
* Having set up SRR0/1 with the address where we want * Having set up SRR0/1 with the address where we want
* to continue with relocation on (potentially in module * to continue with relocation on (potentially in module
* space), we either just go straight there with rfi[d], * space), we either just go straight there with rfi[d],
* or we jump to an interrupt handler with bctr if there * or we jump to an interrupt handler if there is an
* is an interrupt to be handled first. In the latter * interrupt to be handled first. In the latter case,
* case, the rfi[d] at the end of the interrupt handler * the rfi[d] at the end of the interrupt handler will
* will get us back to where we want to continue. * get us back to where we want to continue.
*/ */
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
beq 1f
cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
beq 1f
cmpwi r12, BOOK3S_INTERRUPT_PERFMON
1: mtctr r12
/* Register usage at this point: /* Register usage at this point:
* *
* R1 = host R1 * R1 = host R1
* R2 = host R2 * R2 = host R2
* R10 = raw exit handler id
* R12 = exit handler id * R12 = exit handler id
* R13 = shadow vcpu (32-bit) or PACA (64-bit) * R13 = shadow vcpu (32-bit) or PACA (64-bit)
* SVCPU.* = guest * * SVCPU.* = guest *
...@@ -343,12 +338,26 @@ no_dcbz32_off: ...@@ -343,12 +338,26 @@ no_dcbz32_off:
PPC_LL r6, HSTATE_HOST_MSR(r13) PPC_LL r6, HSTATE_HOST_MSR(r13)
PPC_LL r8, HSTATE_VMHANDLER(r13) PPC_LL r8, HSTATE_VMHANDLER(r13)
/* Restore host msr -> SRR1 */ #ifdef CONFIG_PPC64
BEGIN_FTR_SECTION
andi. r0,r10,0x2
beq 1f
mtspr SPRN_HSRR1, r6
mtspr SPRN_HSRR0, r8
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
#endif
1: /* Restore host msr -> SRR1 */
mtsrr1 r6 mtsrr1 r6
/* Load highmem handler address */ /* Load highmem handler address */
mtsrr0 r8 mtsrr0 r8
/* RFI into the highmem handler, or jump to interrupt handler */ /* RFI into the highmem handler, or jump to interrupt handler */
beqctr cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
beqa BOOK3S_INTERRUPT_EXTERNAL
cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
beqa BOOK3S_INTERRUPT_DECREMENTER
cmpwi r12, BOOK3S_INTERRUPT_PERFMON
beqa BOOK3S_INTERRUPT_PERFMON
RFI RFI
kvmppc_handler_trampoline_exit_end: kvmppc_handler_trampoline_exit_end:
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment