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
|
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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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:
|
||||||
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
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue