powerpc/64s/exception: machine check move unrecoverable handling out of line
Similarly to the previous change, all callers of the unrecoverable handler run relocated so can reach it with a direct branch. This makes it easy to move out of line, which makes the "normal" path less cluttered and easier to follow. MSR[ME] manipulation still requires the rfi, so that is moved out of line to its own function. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190802105709.27696-15-npiggin@gmail.com
This commit is contained in:
parent
296e753fb4
commit
b7d9ccec30
|
@ -992,9 +992,9 @@ EXC_COMMON_BEGIN(machine_check_early_common)
|
|||
bne 1f
|
||||
/* First machine check entry */
|
||||
ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */
|
||||
1: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
|
||||
/* Limit nested MCE to level 4 to avoid stack overflow */
|
||||
bge cr1,2f /* Check if we hit limit of 4 */
|
||||
1: /* Limit nested MCE to level 4 to avoid stack overflow */
|
||||
bgt cr1,unrecoverable_mce /* Check if we hit limit of 4 */
|
||||
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
|
||||
|
||||
EXCEPTION_PROLOG_COMMON_1()
|
||||
/* We don't touch AMR here, we never go to virtual mode */
|
||||
|
@ -1013,21 +1013,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
|||
mtmsrd r10,1
|
||||
b machine_check_handle_early
|
||||
|
||||
2:
|
||||
/* Stack overflow. Stay on emergency stack and panic.
|
||||
* Keep the ME bit off while panic-ing, so that if we hit
|
||||
* another machine check we checkstop.
|
||||
*/
|
||||
addi r1,r1,INT_FRAME_SIZE /* go back to previous stack frame */
|
||||
ld r11,PACAKMSR(r13)
|
||||
LOAD_HANDLER(r12, unrecover_mce)
|
||||
li r10,MSR_ME
|
||||
andc r11,r11,r10 /* Turn off MSR_ME */
|
||||
mtspr SPRN_SRR0,r12
|
||||
mtspr SPRN_SRR1,r11
|
||||
RFI_TO_KERNEL
|
||||
b . /* prevent speculative execution */
|
||||
|
||||
EXC_COMMON_BEGIN(machine_check_common)
|
||||
/*
|
||||
* Machine check is different because we use a different
|
||||
|
@ -1141,32 +1126,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
|
|||
* If yes, then stay on emergency stack and panic.
|
||||
*/
|
||||
andi. r11,r12,MSR_RI
|
||||
bne 2f
|
||||
1: mfspr r11,SPRN_SRR0
|
||||
LOAD_HANDLER(r10,unrecover_mce)
|
||||
mtspr SPRN_SRR0,r10
|
||||
ld r10,PACAKMSR(r13)
|
||||
/*
|
||||
* We are going down. But there are chances that we might get hit by
|
||||
* another MCE during panic path and we may run into unstable state
|
||||
* with no way out. Hence, turn ME bit off while going down, so that
|
||||
* when another MCE is hit during panic path, system will checkstop
|
||||
* and hypervisor will get restarted cleanly by SP.
|
||||
*/
|
||||
li r3,MSR_ME
|
||||
andc r10,r10,r3 /* Turn off MSR_ME */
|
||||
mtspr SPRN_SRR1,r10
|
||||
RFI_TO_KERNEL
|
||||
b .
|
||||
2:
|
||||
beq unrecoverable_mce
|
||||
|
||||
/*
|
||||
* Check if we have successfully handled/recovered from error, if not
|
||||
* then stay on emergency stack and panic.
|
||||
*/
|
||||
ld r3,RESULT(r1) /* Load result */
|
||||
cmpdi r3,0 /* see if we handled MCE successfully */
|
||||
|
||||
beq 1b /* if !handled then panic */
|
||||
beq unrecoverable_mce /* if !handled then panic */
|
||||
|
||||
/*
|
||||
* Return from MC interrupt.
|
||||
|
@ -1189,17 +1157,35 @@ 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(unrecover_mce)
|
||||
EXC_COMMON_BEGIN(unrecoverable_mce)
|
||||
/*
|
||||
* We are going down. But there are chances that we might get hit by
|
||||
* another MCE during panic path and we may run into unstable state
|
||||
* with no way out. Hence, turn ME bit off while going down, so that
|
||||
* when another MCE is hit during panic path, system will checkstop
|
||||
* and hypervisor will get restarted cleanly by SP.
|
||||
*/
|
||||
BEGIN_FTR_SECTION
|
||||
li r10,0 /* clear MSR_RI */
|
||||
mtmsrd r10,1
|
||||
bl disable_machine_check
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
|
||||
ld r10,PACAKMSR(r13)
|
||||
li r3,MSR_ME
|
||||
andc r10,r10,r3
|
||||
mtmsrd r10
|
||||
|
||||
/* Invoke machine_check_exception to print MCE event and panic. */
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl machine_check_exception
|
||||
|
||||
/*
|
||||
* We will not reach here. Even if we did, there is no way out. Call
|
||||
* unrecoverable_exception and die.
|
||||
* We will not reach here. Even if we did, there is no way out.
|
||||
* Call unrecoverable_exception and die.
|
||||
*/
|
||||
1: addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
bl unrecoverable_exception
|
||||
b 1b
|
||||
b .
|
||||
|
||||
|
||||
EXC_REAL_BEGIN(data_access, 0x300, 0x80)
|
||||
|
@ -2282,6 +2268,21 @@ enable_machine_check:
|
|||
1: mtlr r0
|
||||
blr
|
||||
|
||||
/* MSR[RI] should be clear because this uses SRR[01] */
|
||||
disable_machine_check:
|
||||
mflr r0
|
||||
bcl 20,31,$+4
|
||||
0: mflr r3
|
||||
addi r3,r3,(1f - 0b)
|
||||
mtspr SPRN_SRR0,r3
|
||||
mfmsr r3
|
||||
li r4,MSR_ME
|
||||
andc r3,r3,r4
|
||||
mtspr SPRN_SRR1,r3
|
||||
RFI_TO_KERNEL
|
||||
1: mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* Hash table stuff
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue