diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 20:11:38 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-12 20:11:38 -0700 |
commit | b7c8c1945cfbcfb9d60f5be957b4339c6eee4201 (patch) | |
tree | ef27f4b91fc98fcea70b8ef2b7d917c9814a0fbb /arch/powerpc/kernel/exceptions-64s.S | |
parent | 88bbfb4a6267ff90a466ade9762d9a8fff2bb1bb (diff) | |
parent | ad718622ab6d500c870772b1b8dda46fa2195e6d (diff) |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull more powerpc updates from Ben Herrenschmidt:
"Here are the remaining bits I was mentioning earlier. Mostly bug
fixes and new selftests from Michael (yay !). He also removed the WSP
platform and A2 core support which were dead before release, so less
clutter.
One little "feature" I snuck in is the doorbell IPI support for
non-virtualized P8 which speeds up IPIs significantly between threads
of a core"
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (34 commits)
powerpc/book3s: Fix some ABIv2 issues in machine check code
powerpc/book3s: Fix guest MC delivery mechanism to avoid soft lockups in guest.
powerpc/book3s: Increment the mce counter during machine_check_early call.
powerpc/book3s: Add stack overflow check in machine check handler.
powerpc/book3s: Fix machine check handling for unhandled errors
powerpc/eeh: Dump PE location code
powerpc/powernv: Enable POWER8 doorbell IPIs
powerpc/cpuidle: Only clear LPCR decrementer wakeup bit on fast sleep entry
powerpc/powernv: Fix killed EEH event
powerpc: fix typo 'CONFIG_PMAC'
powerpc: fix typo 'CONFIG_PPC_CPU'
powerpc/powernv: Don't escalate non-existing frozen PE
powerpc/eeh: Report frozen parent PE prior to child PE
powerpc/eeh: Clear frozen state for child PE
powerpc/powernv: Reduce panic timeout from 180s to 10s
powerpc/xmon: avoid format string leaking to printk
selftests/powerpc: Add tests of PMU EBBs
selftests/powerpc: Add support for skipping tests
selftests/powerpc: Put the test in a separate process group
selftests/powerpc: Fix instruction loop for ABIv2 (LE)
...
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64s.S')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64s.S | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 20f11eb4dff..a7d36b19221 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -439,9 +439,9 @@ BEGIN_FTR_SECTION * R9 = CR * Original R9 to R13 is saved on PACA_EXMC * - * Switch to mc_emergency stack and handle re-entrancy (though we - * currently don't test for overflow). Save MCE registers srr1, - * srr0, dar and dsisr and then set ME=1 + * Switch to mc_emergency stack and handle re-entrancy (we limit + * the nested MCE upto level 4 to avoid stack overflow). + * Save MCE registers srr1, srr0, dar and dsisr and then set ME=1 * * We use paca->in_mce to check whether this is the first entry or * nested machine check. We increment paca->in_mce to track nested @@ -464,6 +464,9 @@ BEGIN_FTR_SECTION 0: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ addi r10,r10,1 /* increment paca->in_mce */ sth r10,PACA_IN_MCE(r13) + /* Limit nested MCE to level 4 to avoid stack overflow */ + cmpwi r10,4 + bgt 2f /* Check if we hit limit of 4 */ std r11,GPR1(r1) /* Save r1 on the stack. */ std r11,0(r1) /* make stack chain pointer */ mfspr r11,SPRN_SRR0 /* Save SRR0 */ @@ -482,10 +485,23 @@ BEGIN_FTR_SECTION ori r11,r11,MSR_RI /* turn on RI bit */ ld r12,PACAKBASE(r13) /* get high part of &label */ LOAD_HANDLER(r12, machine_check_handle_early) - mtspr SPRN_SRR0,r12 +1: mtspr SPRN_SRR0,r12 mtspr SPRN_SRR1,r11 rfid b . /* prevent speculative execution */ +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) + ld r12,PACAKBASE(r13) + LOAD_HANDLER(r12, unrecover_mce) + li r10,MSR_ME + andc r11,r11,r10 /* Turn off MSR_ME */ + b 1b + b . /* prevent speculative execution */ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) machine_check_pSeries: @@ -1389,6 +1405,7 @@ machine_check_handle_early: bl save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl machine_check_early + std r3,RESULT(r1) /* Save result */ ld r12,_MSR(r1) #ifdef CONFIG_PPC_P7_NAP /* @@ -1443,11 +1460,33 @@ machine_check_handle_early: */ andi. r11,r12,MSR_RI bne 2f -1: addi r3,r1,STACK_FRAME_OVERHEAD - bl unrecoverable_exception - b 1b +1: mfspr r11,SPRN_SRR0 + ld r10,PACAKBASE(r13) + 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 + rfid + b . 2: /* + * 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 */ + /* * Return from MC interrupt. * Queue up the MCE event so that we can log it later, while * returning from kernel or opal call. @@ -1460,6 +1499,17 @@ machine_check_handle_early: MACHINE_CHECK_HANDLER_WINDUP b machine_check_pSeries +unrecover_mce: + /* 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. + */ +1: addi r3,r1,STACK_FRAME_OVERHEAD + bl unrecoverable_exception + b 1b /* * r13 points to the PACA, r9 contains the saved CR, * r12 contain the saved SRR1, SRR0 is still ready for return |