diff options
author | Michael Neuling <mikey@neuling.org> | 2018-05-17 21:37:42 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-05-18 02:05:15 -0400 |
commit | faf37c44a105f3608115785f17cbbf3500f8bc71 (patch) | |
tree | 5d7a9292192cb0936af35357aa5f007640b95f85 | |
parent | c1d2a31397ec51f0370f6bd17b19b39152c263cb (diff) |
powerpc/64s: Clear PCR on boot
Clear the PCR (Processor Compatibility Register) on boot to ensure we
are not running in a compatibility mode.
We've seen this cause problems when a crash (and kdump) occurs while
running compat mode guests. The kdump kernel then runs with the PCR
set and causes problems. The symptom in the kdump kernel (also seen in
petitboot after fast-reboot) is early userspace programs taking
sigills on newer instructions (seen in libc).
Signed-off-by: Michael Neuling <mikey@neuling.org>
Cc: stable@vger.kernel.org
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.S | 6 | ||||
-rw-r--r-- | arch/powerpc/kernel/dt_cpu_ftrs.c | 1 |
2 files changed, 7 insertions, 0 deletions
diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 3f30c994e931..458b928dbd84 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S | |||
@@ -28,6 +28,7 @@ _GLOBAL(__setup_cpu_power7) | |||
28 | beqlr | 28 | beqlr |
29 | li r0,0 | 29 | li r0,0 |
30 | mtspr SPRN_LPID,r0 | 30 | mtspr SPRN_LPID,r0 |
31 | mtspr SPRN_PCR,r0 | ||
31 | mfspr r3,SPRN_LPCR | 32 | mfspr r3,SPRN_LPCR |
32 | li r4,(LPCR_LPES1 >> LPCR_LPES_SH) | 33 | li r4,(LPCR_LPES1 >> LPCR_LPES_SH) |
33 | bl __init_LPCR_ISA206 | 34 | bl __init_LPCR_ISA206 |
@@ -41,6 +42,7 @@ _GLOBAL(__restore_cpu_power7) | |||
41 | beqlr | 42 | beqlr |
42 | li r0,0 | 43 | li r0,0 |
43 | mtspr SPRN_LPID,r0 | 44 | mtspr SPRN_LPID,r0 |
45 | mtspr SPRN_PCR,r0 | ||
44 | mfspr r3,SPRN_LPCR | 46 | mfspr r3,SPRN_LPCR |
45 | li r4,(LPCR_LPES1 >> LPCR_LPES_SH) | 47 | li r4,(LPCR_LPES1 >> LPCR_LPES_SH) |
46 | bl __init_LPCR_ISA206 | 48 | bl __init_LPCR_ISA206 |
@@ -57,6 +59,7 @@ _GLOBAL(__setup_cpu_power8) | |||
57 | beqlr | 59 | beqlr |
58 | li r0,0 | 60 | li r0,0 |
59 | mtspr SPRN_LPID,r0 | 61 | mtspr SPRN_LPID,r0 |
62 | mtspr SPRN_PCR,r0 | ||
60 | mfspr r3,SPRN_LPCR | 63 | mfspr r3,SPRN_LPCR |
61 | ori r3, r3, LPCR_PECEDH | 64 | ori r3, r3, LPCR_PECEDH |
62 | li r4,0 /* LPES = 0 */ | 65 | li r4,0 /* LPES = 0 */ |
@@ -78,6 +81,7 @@ _GLOBAL(__restore_cpu_power8) | |||
78 | beqlr | 81 | beqlr |
79 | li r0,0 | 82 | li r0,0 |
80 | mtspr SPRN_LPID,r0 | 83 | mtspr SPRN_LPID,r0 |
84 | mtspr SPRN_PCR,r0 | ||
81 | mfspr r3,SPRN_LPCR | 85 | mfspr r3,SPRN_LPCR |
82 | ori r3, r3, LPCR_PECEDH | 86 | ori r3, r3, LPCR_PECEDH |
83 | li r4,0 /* LPES = 0 */ | 87 | li r4,0 /* LPES = 0 */ |
@@ -99,6 +103,7 @@ _GLOBAL(__setup_cpu_power9) | |||
99 | mtspr SPRN_PSSCR,r0 | 103 | mtspr SPRN_PSSCR,r0 |
100 | mtspr SPRN_LPID,r0 | 104 | mtspr SPRN_LPID,r0 |
101 | mtspr SPRN_PID,r0 | 105 | mtspr SPRN_PID,r0 |
106 | mtspr SPRN_PCR,r0 | ||
102 | mfspr r3,SPRN_LPCR | 107 | mfspr r3,SPRN_LPCR |
103 | LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) | 108 | LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) |
104 | or r3, r3, r4 | 109 | or r3, r3, r4 |
@@ -123,6 +128,7 @@ _GLOBAL(__restore_cpu_power9) | |||
123 | mtspr SPRN_PSSCR,r0 | 128 | mtspr SPRN_PSSCR,r0 |
124 | mtspr SPRN_LPID,r0 | 129 | mtspr SPRN_LPID,r0 |
125 | mtspr SPRN_PID,r0 | 130 | mtspr SPRN_PID,r0 |
131 | mtspr SPRN_PCR,r0 | ||
126 | mfspr r3,SPRN_LPCR | 132 | mfspr r3,SPRN_LPCR |
127 | LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) | 133 | LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE | LPCR_HEIC) |
128 | or r3, r3, r4 | 134 | or r3, r3, r4 |
diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index 8ab51f6ca03a..c904477abaf3 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c | |||
@@ -101,6 +101,7 @@ static void __restore_cpu_cpufeatures(void) | |||
101 | if (hv_mode) { | 101 | if (hv_mode) { |
102 | mtspr(SPRN_LPID, 0); | 102 | mtspr(SPRN_LPID, 0); |
103 | mtspr(SPRN_HFSCR, system_registers.hfscr); | 103 | mtspr(SPRN_HFSCR, system_registers.hfscr); |
104 | mtspr(SPRN_PCR, 0); | ||
104 | } | 105 | } |
105 | mtspr(SPRN_FSCR, system_registers.fscr); | 106 | mtspr(SPRN_FSCR, system_registers.fscr); |
106 | 107 | ||