All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits
@ 2018-04-05  5:50 Nicholas Piggin
  2018-04-05 14:42 ` Michael Ellerman
  0 siblings, 1 reply; 2+ messages in thread
From: Nicholas Piggin @ 2018-04-05  5:50 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin, stable

Presently the dt_cpu_ftrs restore_cpu will only add bits to the LPCR
for secondaries, but some bits must be removed (e.g., UPRT for HPT).
Not clearing these bits on secondaries causes checkstops when booting
with disable_radix.

restore_cpu can not just set LPCR, because it is also called by the
idle wakeup code which relies on opal_slw_set_reg to restore the value
of LPCR, at least on P8 which does not save LPCR to stack in the idle
code.

Fix this by including a mask of bits to clear from LPCR as well, which
is used by restore_cpu.

This is a little messy now, but it's a minimal fix that can be
backported.  Longer term, the idle SPR save/restore code can be
reworked to completely avoid calls to restore_cpu, then restore_cpu
would be able to unconditionally set LPCR to match boot processor
environment.

Fixes: 5a61ef74f269f ("powerpc/64s: Support new device tree binding for discovering CPU features")
Cc: stable@vger.kernel.org # v4.12+
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---

I tested this fix and it boots a POWER9 with disable_radix, where
previously it checkstopped. Deeper idle states seem to work too,
after they're enabled with a firmware override.


 arch/powerpc/kernel/dt_cpu_ftrs.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c
index 11a3a4fed3fb..ed7605d8fd2d 100644
--- a/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ b/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -83,6 +83,7 @@ static int hv_mode;
 
 static struct {
 	u64	lpcr;
+	u64	lpcr_clear;
 	u64	hfscr;
 	u64	fscr;
 } system_registers;
@@ -91,6 +92,8 @@ static void (*init_pmu_registers)(void);
 
 static void __restore_cpu_cpufeatures(void)
 {
+	u64 lpcr;
+
 	/*
 	 * LPCR is restored by the power on engine already. It can be changed
 	 * after early init e.g., by radix enable, and we have no unified API
@@ -103,8 +106,10 @@ static void __restore_cpu_cpufeatures(void)
 	 * The best we can do to accommodate secondary boot and idle restore
 	 * for now is "or" LPCR with existing.
 	 */
-
-	mtspr(SPRN_LPCR, system_registers.lpcr | mfspr(SPRN_LPCR));
+	lpcr = mfspr(SPRN_LPCR);
+	lpcr |= system_registers.lpcr;
+	lpcr &= ~system_registers.lpcr_clear;
+	mtspr(SPRN_LPCR, lpcr);
 	if (hv_mode) {
 		mtspr(SPRN_LPID, 0);
 		mtspr(SPRN_HFSCR, system_registers.hfscr);
@@ -324,8 +329,9 @@ static int __init feat_enable_mmu_hash_v3(struct dt_cpu_feature *f)
 {
 	u64 lpcr;
 
+	system_registers.lpcr_clear |= (LPCR_ISL | LPCR_UPRT | LPCR_HR);
 	lpcr = mfspr(SPRN_LPCR);
-	lpcr &= ~LPCR_ISL;
+	lpcr &= ~(LPCR_ISL | LPCR_UPRT | LPCR_HR);
 	mtspr(SPRN_LPCR, lpcr);
 
 	cur_cpu_spec->mmu_features |= MMU_FTRS_HASH_BASE;
-- 
2.16.3

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits
  2018-04-05  5:50 [PATCH] powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits Nicholas Piggin
@ 2018-04-05 14:42 ` Michael Ellerman
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Ellerman @ 2018-04-05 14:42 UTC (permalink / raw)
  To: Nicholas Piggin, linuxppc-dev; +Cc: stable, Nicholas Piggin

On Thu, 2018-04-05 at 05:50:49 UTC, Nicholas Piggin wrote:
> Presently the dt_cpu_ftrs restore_cpu will only add bits to the LPCR
> for secondaries, but some bits must be removed (e.g., UPRT for HPT).
> Not clearing these bits on secondaries causes checkstops when booting
> with disable_radix.
> 
> restore_cpu can not just set LPCR, because it is also called by the
> idle wakeup code which relies on opal_slw_set_reg to restore the value
> of LPCR, at least on P8 which does not save LPCR to stack in the idle
> code.
> 
> Fix this by including a mask of bits to clear from LPCR as well, which
> is used by restore_cpu.
> 
> This is a little messy now, but it's a minimal fix that can be
> backported.  Longer term, the idle SPR save/restore code can be
> reworked to completely avoid calls to restore_cpu, then restore_cpu
> would be able to unconditionally set LPCR to match boot processor
> environment.
> 
> Fixes: 5a61ef74f269f ("powerpc/64s: Support new device tree binding for discovering CPU features")
> Cc: stable@vger.kernel.org # v4.12+
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/a57ac411832384eb93df4bfed2bf64

cheers

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2018-04-05 14:42 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-05  5:50 [PATCH] powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits Nicholas Piggin
2018-04-05 14:42 ` Michael Ellerman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.