aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2018-04-05 02:03:39 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2018-04-05 02:06:25 -0400
commita67cc594dffd29cfe33fbee40932c9d04197ab2f (patch)
treee07dce8a5f9ac9e762fcf0e2f7488fa377c534e3
parent07c3d9eaa4be3a000e2b9386cf678ee78f7f7abb (diff)
Revert "powerpc/64s/idle: POWER9 ESL=0 stop avoid save/restore overhead"
As described in that commit: When stop is executed with EC=ESL=0, it appears to execute like a normal instruction (resuming from NIP when woken by interrupt). So all the save/restore handling can be avoided completely. This is true, except in the case of an NMI interrupt (sreset or machine check) interrupting the instruction. In that case, the NMI gets an "interrupt occurred while the processor was in power-saving mode" indication. The power-save wakeup code uses that bit to decide whether to restore some registers (e.g., LR). Because these are no longer saved, this causes random register corruption. It may be possible to restore this optimisation by detecting the case of no register loss on the wakeup side, and avoid restoring in that case, but that's not a minor fix because the wakeup code itself uses some registers that would be live (e.g., LR). Fixes: b9ee31e100e7 ("powerpc/64s/idle: POWER9 ESL=0 stop avoid save/restore overhead") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/kernel/idle_book3s.S45
1 files changed, 29 insertions, 16 deletions
diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S
index bc4e391d031e..e5cb3eedb564 100644
--- a/arch/powerpc/kernel/idle_book3s.S
+++ b/arch/powerpc/kernel/idle_book3s.S
@@ -324,8 +324,32 @@ enter_winkle:
324/* 324/*
325 * r3 - PSSCR value corresponding to the requested stop state. 325 * r3 - PSSCR value corresponding to the requested stop state.
326 */ 326 */
327power_enter_stop_esl: 327power_enter_stop:
328/*
329 * Check if we are executing the lite variant with ESL=EC=0
330 */
331 andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED
328 clrldi r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */ 332 clrldi r3,r3,60 /* r3 = Bits[60:63] = Requested Level (RL) */
333 bne .Lhandle_esl_ec_set
334 PPC_STOP
335 li r3,0 /* Since we didn't lose state, return 0 */
336 std r3, PACA_REQ_PSSCR(r13)
337
338 /*
339 * pnv_wakeup_noloss() expects r12 to contain the SRR1 value so
340 * it can determine if the wakeup reason is an HMI in
341 * CHECK_HMI_INTERRUPT.
342 *
343 * However, when we wakeup with ESL=0, SRR1 will not contain the wakeup
344 * reason, so there is no point setting r12 to SRR1.
345 *
346 * Further, we clear r12 here, so that we don't accidentally enter the
347 * HMI in pnv_wakeup_noloss() if the value of r12[42:45] == WAKE_HMI.
348 */
349 li r12, 0
350 b pnv_wakeup_noloss
351
352.Lhandle_esl_ec_set:
329BEGIN_FTR_SECTION 353BEGIN_FTR_SECTION
330 /* 354 /*
331 * POWER9 DD2.0 or earlier can incorrectly set PMAO when waking up after 355 * POWER9 DD2.0 or earlier can incorrectly set PMAO when waking up after
@@ -417,32 +441,21 @@ _GLOBAL(power9_offline_stop)
417 /* fall through */ 441 /* fall through */
418 442
419_GLOBAL(power9_idle_stop) 443_GLOBAL(power9_idle_stop)
420 mtspr SPRN_PSSCR,r3
421 /*
422 * The ESL=EC=0 case does not wake up at 0x100, and it does not
423 * allow SMT mode switching, so it does not require PSSCR to be
424 * saved.
425 */
426 andis. r4,r3,PSSCR_EC_ESL_MASK_SHIFTED
427 bne 1f
428 PPC_STOP
429 li r3,0 /* Since we didn't lose state, return 0 */
430 blr
4311:
432 std r3, PACA_REQ_PSSCR(r13) 444 std r3, PACA_REQ_PSSCR(r13)
433#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE 445#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
434BEGIN_FTR_SECTION 446BEGIN_FTR_SECTION
435 sync 447 sync
436 lwz r5, PACA_DONT_STOP(r13) 448 lwz r5, PACA_DONT_STOP(r13)
437 cmpwi r5, 0 449 cmpwi r5, 0
438 bne 2f 450 bne 1f
439END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG) 451END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG)
440#endif 452#endif
441 LOAD_REG_ADDR(r4,power_enter_stop_esl) 453 mtspr SPRN_PSSCR,r3
454 LOAD_REG_ADDR(r4,power_enter_stop)
442 b pnv_powersave_common 455 b pnv_powersave_common
443 /* No return */ 456 /* No return */
444#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE 457#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
4452: 4581:
446 /* 459 /*
447 * We get here when TM / thread reconfiguration bug workaround 460 * We get here when TM / thread reconfiguration bug workaround
448 * code wants to get the CPU into SMT4 mode, and therefore 461 * code wants to get the CPU into SMT4 mode, and therefore