Commit 19dbe673 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

powerpc/64s/exception: machine check fix KVM guest test



The machine_check_handle_early hypervisor guest test is skipped if
!HVMODE or MSR[HV]=0, which is wrong for PR or nested hypervisors
that could be running a guest in this state.

Test HSTATE_IN_GUEST up front and use that to branch out to the KVM
handler, then MSR[PR] alone can test for this kernel's userspace.
This matches all other interrupt handling.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-4-npiggin@gmail.com
parent 1039f624
Loading
Loading
Loading
Loading
+13 −20
Original line number Diff line number Diff line
@@ -1108,9 +1108,6 @@ EXC_COMMON_BEGIN(machine_check_handle_early)
	bl	machine_check_early
	std	r3,RESULT(r1)	/* Save result */
	ld	r12,_MSR(r1)
BEGIN_FTR_SECTION
	b	4f
END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE)

#ifdef CONFIG_PPC_P7_NAP
	/*
@@ -1128,30 +1125,26 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
#endif

	/*
	 * Check if we are coming from hypervisor userspace. If yes then we
	 * continue in host kernel in V mode to deliver the MC event.
	 */
	rldicl.	r11,r12,4,63		/* See if MC hit while in HV mode. */
	beq	5f
4:	andi.	r11,r12,MSR_PR		/* See if coming from user. */
	bne	9f			/* continue in V mode if we are. */

5:
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
BEGIN_FTR_SECTION
	/*
	 * We are coming from kernel context. Check if we are coming from
	 * guest. if yes, then we can continue. We will fall through
	 * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest.
	 * Check if we are coming from guest. If yes, then run the normal
	 * exception handler which will take the do_kvm_200->kvmppc_interrupt
	 * branch to deliver the MC event to guest.
	 */
	lbz	r11,HSTATE_IN_GUEST(r13)
	cmpwi	r11,0			/* Check if coming from guest */
	bne	9f			/* continue if we are. */
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
#endif

	/*
	 * Check if we are coming from userspace. If yes, then run the normal
	 * exception handler which will deliver the MC event to this kernel.
	 */
	andi.	r11,r12,MSR_PR		/* See if coming from user. */
	bne	9f			/* continue in V mode if we are. */

	/*
	 * At this point we are not sure about what context we come from.
	 * At this point we are coming from kernel context.
	 * Queue up the MCE event and return from the interrupt.
	 * But before that, check if this is an un-recoverable exception.
	 * If yes, then stay on emergency stack and panic.