Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56e13dba authored by Alexander Graf's avatar Alexander Graf
Browse files

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 7ef4e985
Loading
Loading
Loading
Loading
+22 −13
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ kvmppc_interrupt:
	/* Save guest PC and MSR */
#ifdef CONFIG_PPC64
BEGIN_FTR_SECTION
	mr	r10, r12
	andi.	r0,r12,0x2
	beq	1f
	mfspr	r3,SPRN_HSRR0
@@ -322,23 +323,17 @@ no_dcbz32_off:
	 * Having set up SRR0/1 with the address where we want
	 * to continue with relocation on (potentially in module
	 * space), we either just go straight there with rfi[d],
	 * or we jump to an interrupt handler with bctr if there
	 * is an interrupt to be handled first.  In the latter
	 * case, the rfi[d] at the end of the interrupt handler
	 * will get us back to where we want to continue.
	 * or we jump to an interrupt handler if there is an
	 * interrupt to be handled first.  In the latter case,
	 * the rfi[d] at the end of the interrupt handler will
	 * 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:
	 *
	 * R1       = host R1
	 * R2       = host R2
	 * R10      = raw exit handler id
	 * R12      = exit handler id
	 * R13      = shadow vcpu (32-bit) or PACA (64-bit)
	 * SVCPU.*  = guest *
@@ -348,12 +343,26 @@ no_dcbz32_off:
	PPC_LL	r6, HSTATE_HOST_MSR(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
	/* Load highmem handler address */
	mtsrr0	r8

	/* 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
kvmppc_handler_trampoline_exit_end: