Skip to content

Commit 56e13db

Browse files
committed
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 <[email protected]>
1 parent 7ef4e98 commit 56e13db

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

arch/powerpc/kvm/book3s_segment.S

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ kvmppc_interrupt:
197197
/* Save guest PC and MSR */
198198
#ifdef CONFIG_PPC64
199199
BEGIN_FTR_SECTION
200+
mr r10, r12
200201
andi. r0,r12,0x2
201202
beq 1f
202203
mfspr r3,SPRN_HSRR0
@@ -322,23 +323,17 @@ no_dcbz32_off:
322323
* Having set up SRR0/1 with the address where we want
323324
* to continue with relocation on (potentially in module
324325
* space), we either just go straight there with rfi[d],
325-
* or we jump to an interrupt handler with bctr if there
326-
* is an interrupt to be handled first. In the latter
327-
* case, the rfi[d] at the end of the interrupt handler
328-
* will get us back to where we want to continue.
326+
* or we jump to an interrupt handler if there is an
327+
* interrupt to be handled first. In the latter case,
328+
* the rfi[d] at the end of the interrupt handler will
329+
* get us back to where we want to continue.
329330
*/
330331

331-
cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL
332-
beq 1f
333-
cmpwi r12, BOOK3S_INTERRUPT_DECREMENTER
334-
beq 1f
335-
cmpwi r12, BOOK3S_INTERRUPT_PERFMON
336-
1: mtctr r12
337-
338332
/* Register usage at this point:
339333
*
340334
* R1 = host R1
341335
* R2 = host R2
336+
* R10 = raw exit handler id
342337
* R12 = exit handler id
343338
* R13 = shadow vcpu (32-bit) or PACA (64-bit)
344339
* SVCPU.* = guest *
@@ -348,12 +343,26 @@ no_dcbz32_off:
348343
PPC_LL r6, HSTATE_HOST_MSR(r13)
349344
PPC_LL r8, HSTATE_VMHANDLER(r13)
350345

351-
/* Restore host msr -> SRR1 */
346+
#ifdef CONFIG_PPC64
347+
BEGIN_FTR_SECTION
348+
andi. r0,r10,0x2
349+
beq 1f
350+
mtspr SPRN_HSRR1, r6
351+
mtspr SPRN_HSRR0, r8
352+
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
353+
#endif
354+
1: /* Restore host msr -> SRR1 */
352355
mtsrr1 r6
353356
/* Load highmem handler address */
354357
mtsrr0 r8
355358

356359
/* 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+
358367
RFI
359368
kvmppc_handler_trampoline_exit_end:

0 commit comments

Comments
 (0)