aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S24
1 files changed, 20 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 274a86d001c7..8a0292dbb5fc 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -439,9 +439,9 @@ BEGIN_FTR_SECTION
439 * R9 = CR 439 * R9 = CR
440 * Original R9 to R13 is saved on PACA_EXMC 440 * Original R9 to R13 is saved on PACA_EXMC
441 * 441 *
442 * Switch to mc_emergency stack and handle re-entrancy (though we 442 * Switch to mc_emergency stack and handle re-entrancy (we limit
443 * currently don't test for overflow). Save MCE registers srr1, 443 * the nested MCE upto level 4 to avoid stack overflow).
444 * srr0, dar and dsisr and then set ME=1 444 * Save MCE registers srr1, srr0, dar and dsisr and then set ME=1
445 * 445 *
446 * We use paca->in_mce to check whether this is the first entry or 446 * We use paca->in_mce to check whether this is the first entry or
447 * nested machine check. We increment paca->in_mce to track nested 447 * nested machine check. We increment paca->in_mce to track nested
@@ -464,6 +464,9 @@ BEGIN_FTR_SECTION
4640: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ 4640: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
465 addi r10,r10,1 /* increment paca->in_mce */ 465 addi r10,r10,1 /* increment paca->in_mce */
466 sth r10,PACA_IN_MCE(r13) 466 sth r10,PACA_IN_MCE(r13)
467 /* Limit nested MCE to level 4 to avoid stack overflow */
468 cmpwi r10,4
469 bgt 2f /* Check if we hit limit of 4 */
467 std r11,GPR1(r1) /* Save r1 on the stack. */ 470 std r11,GPR1(r1) /* Save r1 on the stack. */
468 std r11,0(r1) /* make stack chain pointer */ 471 std r11,0(r1) /* make stack chain pointer */
469 mfspr r11,SPRN_SRR0 /* Save SRR0 */ 472 mfspr r11,SPRN_SRR0 /* Save SRR0 */
@@ -482,10 +485,23 @@ BEGIN_FTR_SECTION
482 ori r11,r11,MSR_RI /* turn on RI bit */ 485 ori r11,r11,MSR_RI /* turn on RI bit */
483 ld r12,PACAKBASE(r13) /* get high part of &label */ 486 ld r12,PACAKBASE(r13) /* get high part of &label */
484 LOAD_HANDLER(r12, machine_check_handle_early) 487 LOAD_HANDLER(r12, machine_check_handle_early)
485 mtspr SPRN_SRR0,r12 4881: mtspr SPRN_SRR0,r12
486 mtspr SPRN_SRR1,r11 489 mtspr SPRN_SRR1,r11
487 rfid 490 rfid
488 b . /* prevent speculative execution */ 491 b . /* prevent speculative execution */
4922:
493 /* Stack overflow. Stay on emergency stack and panic.
494 * Keep the ME bit off while panic-ing, so that if we hit
495 * another machine check we checkstop.
496 */
497 addi r1,r1,INT_FRAME_SIZE /* go back to previous stack frame */
498 ld r11,PACAKMSR(r13)
499 ld r12,PACAKBASE(r13)
500 LOAD_HANDLER(r12, unrecover_mce)
501 li r10,MSR_ME
502 andc r11,r11,r10 /* Turn off MSR_ME */
503 b 1b
504 b . /* prevent speculative execution */
489END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) 505END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
490 506
491machine_check_pSeries: 507machine_check_pSeries: