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

powerpc/64s/exception: untangle early machine check handler branch



machine_check_early_common now branches to machine_check_handle_early
which is its only caller.

Move interleaving code out of the way, and remove the branch.

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-16-npiggin@gmail.com
parent b7d9ccec
Loading
Loading
Loading
Loading
+62 −67
Original line number Diff line number Diff line
@@ -956,6 +956,16 @@ TRAMP_REAL_BEGIN(machine_check_fwnmi)

TRAMP_KVM_SKIP(PACA_EXMC, 0x200)

#define MACHINE_CHECK_HANDLER_WINDUP			\
	/* Clear MSR_RI before setting SRR0 and SRR1. */\
	li	r9,0;					\
	mtmsrd	r9,1;		/* Clear MSR_RI */	\
	/* Decrement paca->in_mce now RI is clear. */	\
	lhz	r12,PACA_IN_MCE(r13);			\
	subi	r12,r12,1;				\
	sth	r12,PACA_IN_MCE(r13);			\
	EXCEPTION_RESTORE_REGS EXC_STD

EXC_COMMON_BEGIN(machine_check_early_common)
	mtctr	r10			/* Restore ctr */
	mfspr	r11,SPRN_SRR0
@@ -1011,74 +1021,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
	li	r10,MSR_RI
	mtmsrd	r10,1
	b	machine_check_handle_early

EXC_COMMON_BEGIN(machine_check_common)
	/*
	 * Machine check is different because we use a different
	 * save area: PACA_EXMC instead of PACA_EXGEN.
	 */
	EXCEPTION_COMMON(PACA_EXMC, 0x200)
	FINISH_NAP
	RECONCILE_IRQ_STATE(r10, r11)
	ld	r3,PACA_EXMC+EX_DAR(r13)
	lwz	r4,PACA_EXMC+EX_DSISR(r13)
	/* Enable MSR_RI when finished with PACA_EXMC */
	li	r10,MSR_RI
	mtmsrd 	r10,1
	std	r3,_DAR(r1)
	std	r4,_DSISR(r1)
	bl	save_nvgprs
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	machine_check_exception
	b	ret_from_except

#define MACHINE_CHECK_HANDLER_WINDUP			\
	/* Clear MSR_RI before setting SRR0 and SRR1. */\
	li	r9,0;					\
	mtmsrd	r9,1;		/* Clear MSR_RI */	\
	/* Decrement paca->in_mce now RI is clear. */	\
	lhz	r12,PACA_IN_MCE(r13);			\
	subi	r12,r12,1;				\
	sth	r12,PACA_IN_MCE(r13);			\
	EXCEPTION_RESTORE_REGS EXC_STD

#ifdef CONFIG_PPC_P7_NAP
/*
 * This is an idle wakeup. Low level machine check has already been
 * done. Queue the event then call the idle code to do the wake up.
 */
EXC_COMMON_BEGIN(machine_check_idle_common)
	bl	machine_check_queue_event

	/*
	 * We have not used any non-volatile GPRs here, and as a rule
	 * most exception code including machine check does not.
	 * Therefore PACA_NAPSTATELOST does not need to be set. Idle
	 * wakeup will restore volatile registers.
	 *
	 * Load the original SRR1 into r3 for pnv_powersave_wakeup_mce.
	 *
	 * Then decrement MCE nesting after finishing with the stack.
	 */
	ld	r3,_MSR(r1)
	ld	r4,_LINK(r1)

	lhz	r11,PACA_IN_MCE(r13)
	subi	r11,r11,1
	sth	r11,PACA_IN_MCE(r13)

	mtlr	r4
	rlwinm	r10,r3,47-31,30,31
	cmpwi	cr1,r10,2
	bltlr	cr1	/* no state loss, return to idle caller */
	b	idle_return_gpr_loss
#endif
	/*
	 * Handle machine check early in real mode. We come here with
	 * ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack.
	 */
EXC_COMMON_BEGIN(machine_check_handle_early)
	bl	save_nvgprs
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	machine_check_early
@@ -1157,6 +1100,58 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
	EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
	EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0

EXC_COMMON_BEGIN(machine_check_common)
	/*
	 * Machine check is different because we use a different
	 * save area: PACA_EXMC instead of PACA_EXGEN.
	 */
	EXCEPTION_COMMON(PACA_EXMC, 0x200)
	FINISH_NAP
	RECONCILE_IRQ_STATE(r10, r11)
	ld	r3,PACA_EXMC+EX_DAR(r13)
	lwz	r4,PACA_EXMC+EX_DSISR(r13)
	/* Enable MSR_RI when finished with PACA_EXMC */
	li	r10,MSR_RI
	mtmsrd 	r10,1
	std	r3,_DAR(r1)
	std	r4,_DSISR(r1)
	bl	save_nvgprs
	addi	r3,r1,STACK_FRAME_OVERHEAD
	bl	machine_check_exception
	b	ret_from_except

#ifdef CONFIG_PPC_P7_NAP
/*
 * This is an idle wakeup. Low level machine check has already been
 * done. Queue the event then call the idle code to do the wake up.
 */
EXC_COMMON_BEGIN(machine_check_idle_common)
	bl	machine_check_queue_event

	/*
	 * We have not used any non-volatile GPRs here, and as a rule
	 * most exception code including machine check does not.
	 * Therefore PACA_NAPSTATELOST does not need to be set. Idle
	 * wakeup will restore volatile registers.
	 *
	 * Load the original SRR1 into r3 for pnv_powersave_wakeup_mce.
	 *
	 * Then decrement MCE nesting after finishing with the stack.
	 */
	ld	r3,_MSR(r1)
	ld	r4,_LINK(r1)

	lhz	r11,PACA_IN_MCE(r13)
	subi	r11,r11,1
	sth	r11,PACA_IN_MCE(r13)

	mtlr	r4
	rlwinm	r10,r3,47-31,30,31
	cmpwi	cr1,r10,2
	bltlr	cr1	/* no state loss, return to idle caller */
	b	idle_return_gpr_loss
#endif

EXC_COMMON_BEGIN(unrecoverable_mce)
	/*
	 * We are going down. But there are chances that we might get hit by