Commit b7d9ccec authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman

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: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190802105709.27696-15-npiggin@gmail.com
parent 296e753f
...@@ -992,9 +992,9 @@ EXC_COMMON_BEGIN(machine_check_early_common) ...@@ -992,9 +992,9 @@ EXC_COMMON_BEGIN(machine_check_early_common)
bne 1f bne 1f
/* First machine check entry */ /* First machine check entry */
ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */ ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */
1: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ 1: /* Limit nested MCE to level 4 to avoid stack overflow */
/* Limit nested MCE to level 4 to avoid stack overflow */ bgt cr1,unrecoverable_mce /* Check if we hit limit of 4 */
bge cr1,2f /* Check if we hit limit of 4 */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
EXCEPTION_PROLOG_COMMON_1() EXCEPTION_PROLOG_COMMON_1()
/* We don't touch AMR here, we never go to virtual mode */ /* We don't touch AMR here, we never go to virtual mode */
...@@ -1013,21 +1013,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) ...@@ -1013,21 +1013,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
mtmsrd r10,1 mtmsrd r10,1
b machine_check_handle_early 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) EXC_COMMON_BEGIN(machine_check_common)
/* /*
* Machine check is different because we use a different * Machine check is different because we use a different
...@@ -1141,32 +1126,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) ...@@ -1141,32 +1126,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
* If yes, then stay on emergency stack and panic. * If yes, then stay on emergency stack and panic.
*/ */
andi. r11,r12,MSR_RI andi. r11,r12,MSR_RI
bne 2f beq unrecoverable_mce
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:
/* /*
* Check if we have successfully handled/recovered from error, if not * Check if we have successfully handled/recovered from error, if not
* then stay on emergency stack and panic. * then stay on emergency stack and panic.
*/ */
ld r3,RESULT(r1) /* Load result */ ld r3,RESULT(r1) /* Load result */
cmpdi r3,0 /* see if we handled MCE successfully */ cmpdi r3,0 /* see if we handled MCE successfully */
beq unrecoverable_mce /* if !handled then panic */
beq 1b /* if !handled then panic */
/* /*
* Return from MC interrupt. * Return from MC interrupt.
...@@ -1189,17 +1157,35 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR) ...@@ -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_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0
EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 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. */ /* Invoke machine_check_exception to print MCE event and panic. */
addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl machine_check_exception bl machine_check_exception
/* /*
* We will not reach here. Even if we did, there is no way out. Call * We will not reach here. Even if we did, there is no way out.
* unrecoverable_exception and die. * Call unrecoverable_exception and die.
*/ */
1: addi r3,r1,STACK_FRAME_OVERHEAD addi r3,r1,STACK_FRAME_OVERHEAD
bl unrecoverable_exception bl unrecoverable_exception
b 1b b .
EXC_REAL_BEGIN(data_access, 0x300, 0x80) EXC_REAL_BEGIN(data_access, 0x300, 0x80)
...@@ -2282,6 +2268,21 @@ enable_machine_check: ...@@ -2282,6 +2268,21 @@ enable_machine_check:
1: mtlr r0 1: mtlr r0
blr 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 * Hash table stuff
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment