forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/arch/powerpc/kernel/mce_power.c
....@@ -1,19 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Machine check exception handling CPU-side for power7 and power8
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License as published by
6
- * the Free Software Foundation; either version 2 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
174 *
185 * Copyright 2013 IBM Corporation
196 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
....@@ -24,21 +11,24 @@
2411
2512 #include <linux/types.h>
2613 #include <linux/ptrace.h>
14
+#include <linux/extable.h>
15
+#include <linux/pgtable.h>
2716 #include <asm/mmu.h>
2817 #include <asm/mce.h>
2918 #include <asm/machdep.h>
30
-#include <asm/pgtable.h>
3119 #include <asm/pte-walk.h>
3220 #include <asm/sstep.h>
3321 #include <asm/exception-64s.h>
22
+#include <asm/extable.h>
23
+#include <asm/inst.h>
3424
3525 /*
3626 * Convert an address related to an mm to a PFN. NOTE: we are in real
3727 * mode, we could potentially race with page table updates.
3828 */
39
-static unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
29
+unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
4030 {
41
- pte_t *ptep;
31
+ pte_t *ptep, pte;
4232 unsigned int shift;
4333 unsigned long pfn, flags;
4434 struct mm_struct *mm;
....@@ -50,19 +40,23 @@
5040
5141 local_irq_save(flags);
5242 ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
43
+ if (!ptep) {
44
+ pfn = ULONG_MAX;
45
+ goto out;
46
+ }
47
+ pte = READ_ONCE(*ptep);
5348
54
- if (!ptep || pte_special(*ptep)) {
49
+ if (!pte_present(pte) || pte_special(pte)) {
5550 pfn = ULONG_MAX;
5651 goto out;
5752 }
5853
5954 if (shift <= PAGE_SHIFT)
60
- pfn = pte_pfn(*ptep);
55
+ pfn = pte_pfn(pte);
6156 else {
6257 unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
63
- pfn = pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
58
+ pfn = pte_pfn(__pte(pte_val(pte) | (addr & rpnmask)));
6459 }
65
-
6660 out:
6761 local_irq_restore(flags);
6862 return pfn;
....@@ -70,7 +64,7 @@
7064
7165 /* flush SLBs and reload */
7266 #ifdef CONFIG_PPC_BOOK3S_64
73
-static void flush_and_reload_slb(void)
67
+void flush_and_reload_slb(void)
7468 {
7569 /* Invalidate all SLBs */
7670 slb_flush_all_realmode();
....@@ -105,8 +99,7 @@
10599 return;
106100 }
107101 #endif
108
- /* PPC_INVALIDATE_ERAT can only be used on ISA v3 and newer */
109
- asm volatile(PPC_INVALIDATE_ERAT : : :"memory");
102
+ asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory");
110103 }
111104
112105 #define MCE_FLUSH_SLB 1
....@@ -141,213 +134,311 @@
141134 bool nip_valid; /* nip is a valid indicator of faulting address */
142135 unsigned int error_type;
143136 unsigned int error_subtype;
137
+ unsigned int error_class;
144138 unsigned int initiator;
145139 unsigned int severity;
140
+ bool sync_error;
146141 };
147142
148143 static const struct mce_ierror_table mce_p7_ierror_table[] = {
149144 { 0x00000000001c0000, 0x0000000000040000, true,
150
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH,
151
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
145
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
146
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
152147 { 0x00000000001c0000, 0x0000000000080000, true,
153
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
154
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
148
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
149
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
155150 { 0x00000000001c0000, 0x00000000000c0000, true,
156
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT,
157
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
151
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
152
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
158153 { 0x00000000001c0000, 0x0000000000100000, true,
159154 MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_INDETERMINATE, /* BOTH */
160
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
155
+ MCE_ECLASS_SOFT_INDETERMINATE,
156
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
161157 { 0x00000000001c0000, 0x0000000000140000, true,
162
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
163
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
158
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
159
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
164160 { 0x00000000001c0000, 0x0000000000180000, true,
165
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH,
166
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
161
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
162
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
167163 { 0x00000000001c0000, 0x00000000001c0000, true,
168
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH,
169
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
170
-{ 0, 0, 0, 0, 0, 0 } };
164
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
165
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
166
+{ 0, 0, 0, 0, 0, 0, 0 } };
171167
172168 static const struct mce_ierror_table mce_p8_ierror_table[] = {
173169 { 0x00000000081c0000, 0x0000000000040000, true,
174
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH,
175
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
170
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
171
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
176172 { 0x00000000081c0000, 0x0000000000080000, true,
177
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
178
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
173
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
174
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
179175 { 0x00000000081c0000, 0x00000000000c0000, true,
180
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT,
181
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
176
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
177
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
182178 { 0x00000000081c0000, 0x0000000000100000, true,
183
- MCE_ERROR_TYPE_ERAT,MCE_ERAT_ERROR_MULTIHIT,
184
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
179
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
180
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
185181 { 0x00000000081c0000, 0x0000000000140000, true,
186
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
187
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
182
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
183
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
188184 { 0x00000000081c0000, 0x0000000000180000, true,
189185 MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH,
190
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
186
+ MCE_ECLASS_HARDWARE,
187
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
191188 { 0x00000000081c0000, 0x00000000001c0000, true,
192
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH,
193
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
189
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
190
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
194191 { 0x00000000081c0000, 0x0000000008000000, true,
195
- MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_IFETCH_TIMEOUT,
196
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
192
+ MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_IFETCH_TIMEOUT, MCE_ECLASS_HARDWARE,
193
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
197194 { 0x00000000081c0000, 0x0000000008040000, true,
198195 MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT,
199
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
200
-{ 0, 0, 0, 0, 0, 0 } };
196
+ MCE_ECLASS_HARDWARE,
197
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
198
+{ 0, 0, 0, 0, 0, 0, 0 } };
201199
202200 static const struct mce_ierror_table mce_p9_ierror_table[] = {
203201 { 0x00000000081c0000, 0x0000000000040000, true,
204
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH,
205
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
202
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
203
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
206204 { 0x00000000081c0000, 0x0000000000080000, true,
207
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
208
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
205
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
206
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
209207 { 0x00000000081c0000, 0x00000000000c0000, true,
210
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT,
211
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
208
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
209
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
212210 { 0x00000000081c0000, 0x0000000000100000, true,
213
- MCE_ERROR_TYPE_ERAT,MCE_ERAT_ERROR_MULTIHIT,
214
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
211
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
212
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
215213 { 0x00000000081c0000, 0x0000000000140000, true,
216
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
217
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
214
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
215
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
218216 { 0x00000000081c0000, 0x0000000000180000, true,
219
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH,
220
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
217
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
218
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
221219 { 0x00000000081c0000, 0x00000000001c0000, true,
222
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH_FOREIGN,
223
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
220
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH_FOREIGN, MCE_ECLASS_SOFTWARE,
221
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
224222 { 0x00000000081c0000, 0x0000000008000000, true,
225
- MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_IFETCH_TIMEOUT,
226
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
223
+ MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_IFETCH_TIMEOUT, MCE_ECLASS_HARDWARE,
224
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
227225 { 0x00000000081c0000, 0x0000000008040000, true,
228226 MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT,
229
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
227
+ MCE_ECLASS_HARDWARE,
228
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
230229 { 0x00000000081c0000, 0x00000000080c0000, true,
231
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH,
232
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
230
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH, MCE_ECLASS_SOFTWARE,
231
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
233232 { 0x00000000081c0000, 0x0000000008100000, true,
234
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH,
235
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
233
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_SOFTWARE,
234
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
236235 { 0x00000000081c0000, 0x0000000008140000, false,
237
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_STORE,
238
- MCE_INITIATOR_CPU, MCE_SEV_FATAL, }, /* ASYNC is fatal */
236
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_STORE, MCE_ECLASS_HARDWARE,
237
+ MCE_INITIATOR_CPU, MCE_SEV_FATAL, false }, /* ASYNC is fatal */
239238 { 0x00000000081c0000, 0x0000000008180000, false,
240239 MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_STORE_TIMEOUT,
241
- MCE_INITIATOR_CPU, MCE_SEV_FATAL, }, /* ASYNC is fatal */
242
-{ 0x00000000081c0000, 0x00000000081c0000, true,
240
+ MCE_INITIATOR_CPU, MCE_SEV_FATAL, false }, /* ASYNC is fatal */
241
+{ 0x00000000081c0000, 0x00000000081c0000, true, MCE_ECLASS_HARDWARE,
243242 MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN,
244
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
245
-{ 0, 0, 0, 0, 0, 0 } };
243
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
244
+{ 0, 0, 0, 0, 0, 0, 0 } };
245
+
246
+static const struct mce_ierror_table mce_p10_ierror_table[] = {
247
+{ 0x00000000081c0000, 0x0000000000040000, true,
248
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
249
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
250
+{ 0x00000000081c0000, 0x0000000000080000, true,
251
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
252
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
253
+{ 0x00000000081c0000, 0x00000000000c0000, true,
254
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
255
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
256
+{ 0x00000000081c0000, 0x0000000000100000, true,
257
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
258
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
259
+{ 0x00000000081c0000, 0x0000000000140000, true,
260
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
261
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
262
+{ 0x00000000081c0000, 0x0000000000180000, true,
263
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
264
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
265
+{ 0x00000000081c0000, 0x00000000001c0000, true,
266
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH_FOREIGN, MCE_ECLASS_SOFTWARE,
267
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
268
+{ 0x00000000081c0000, 0x0000000008080000, true,
269
+ MCE_ERROR_TYPE_USER,MCE_USER_ERROR_SCV, MCE_ECLASS_SOFTWARE,
270
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
271
+{ 0x00000000081c0000, 0x00000000080c0000, true,
272
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_IFETCH, MCE_ECLASS_SOFTWARE,
273
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
274
+{ 0x00000000081c0000, 0x0000000008100000, true,
275
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_SOFTWARE,
276
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
277
+{ 0x00000000081c0000, 0x0000000008140000, false,
278
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_STORE, MCE_ECLASS_HARDWARE,
279
+ MCE_INITIATOR_CPU, MCE_SEV_FATAL, false }, /* ASYNC is fatal */
280
+{ 0x00000000081c0000, 0x00000000081c0000, true, MCE_ECLASS_HARDWARE,
281
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN,
282
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
283
+{ 0, 0, 0, 0, 0, 0, 0 } };
246284
247285 struct mce_derror_table {
248286 unsigned long dsisr_value;
249287 bool dar_valid; /* dar is a valid indicator of faulting address */
250288 unsigned int error_type;
251289 unsigned int error_subtype;
290
+ unsigned int error_class;
252291 unsigned int initiator;
253292 unsigned int severity;
293
+ bool sync_error;
254294 };
255295
256296 static const struct mce_derror_table mce_p7_derror_table[] = {
257297 { 0x00008000, false,
258
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE,
259
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
298
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
299
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
260300 { 0x00004000, true,
261301 MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
262
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
302
+ MCE_ECLASS_HARDWARE,
303
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
263304 { 0x00000800, true,
264
- MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT,
265
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
305
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
306
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
266307 { 0x00000400, true,
267
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
268
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
308
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
309
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
269310 { 0x00000080, true,
270
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
271
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
311
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
312
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
272313 { 0x00000100, true,
273
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
274
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
314
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
315
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
275316 { 0x00000040, true,
276317 MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_INDETERMINATE, /* BOTH */
277
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
278
-{ 0, false, 0, 0, 0, 0 } };
318
+ MCE_ECLASS_HARD_INDETERMINATE,
319
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
320
+{ 0, false, 0, 0, 0, 0, 0 } };
279321
280322 static const struct mce_derror_table mce_p8_derror_table[] = {
281323 { 0x00008000, false,
282
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE,
283
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
324
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
325
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
284326 { 0x00004000, true,
285327 MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
286
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
328
+ MCE_ECLASS_HARDWARE,
329
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
287330 { 0x00002000, true,
288
- MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT,
289
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
331
+ MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT, MCE_ECLASS_HARDWARE,
332
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
290333 { 0x00001000, true,
291334 MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT,
292
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
335
+ MCE_ECLASS_HARDWARE,
336
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
293337 { 0x00000800, true,
294
- MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT,
295
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
338
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
339
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
296340 { 0x00000400, true,
297
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
298
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
341
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
342
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
299343 { 0x00000200, true,
300344 MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, /* SECONDARY ERAT */
301
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
345
+ MCE_ECLASS_SOFT_INDETERMINATE,
346
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
302347 { 0x00000080, true,
303348 MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
304
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
349
+ MCE_ECLASS_SOFT_INDETERMINATE,
350
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
305351 { 0x00000100, true,
306
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
307
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
308
-{ 0, false, 0, 0, 0, 0 } };
352
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
353
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
354
+{ 0, false, 0, 0, 0, 0, 0 } };
309355
310356 static const struct mce_derror_table mce_p9_derror_table[] = {
311357 { 0x00008000, false,
312
- MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE,
313
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
358
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
359
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
314360 { 0x00004000, true,
315361 MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
316
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
362
+ MCE_ECLASS_HARDWARE,
363
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
317364 { 0x00002000, true,
318
- MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT,
319
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
365
+ MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT, MCE_ECLASS_HARDWARE,
366
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
320367 { 0x00001000, true,
321368 MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT,
322
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
369
+ MCE_ECLASS_HARDWARE,
370
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
323371 { 0x00000800, true,
324
- MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT,
325
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
372
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
373
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
326374 { 0x00000400, true,
327
- MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT,
328
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
375
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
376
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
329377 { 0x00000200, false,
330
- MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE,
331
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
378
+ MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE, MCE_ECLASS_SOFTWARE,
379
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
332380 { 0x00000080, true,
333381 MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
334
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
382
+ MCE_ECLASS_SOFT_INDETERMINATE,
383
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
335384 { 0x00000100, true,
336
- MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY,
337
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
385
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
386
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
338387 { 0x00000040, true,
339
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD,
340
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
388
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD, MCE_ECLASS_HARDWARE,
389
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
341390 { 0x00000020, false,
342391 MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
343
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
392
+ MCE_ECLASS_HARDWARE,
393
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
344394 { 0x00000010, false,
345395 MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN,
346
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
396
+ MCE_ECLASS_HARDWARE,
397
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
347398 { 0x00000008, false,
348
- MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD_STORE_FOREIGN,
349
- MCE_INITIATOR_CPU, MCE_SEV_ERROR_SYNC, },
350
-{ 0, false, 0, 0, 0, 0 } };
399
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD_STORE_FOREIGN, MCE_ECLASS_HARDWARE,
400
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
401
+{ 0, false, 0, 0, 0, 0, 0 } };
402
+
403
+static const struct mce_derror_table mce_p10_derror_table[] = {
404
+{ 0x00008000, false,
405
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
406
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
407
+{ 0x00004000, true,
408
+ MCE_ERROR_TYPE_UE, MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
409
+ MCE_ECLASS_HARDWARE,
410
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
411
+{ 0x00000800, true,
412
+ MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
413
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
414
+{ 0x00000400, true,
415
+ MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
416
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
417
+{ 0x00000200, false,
418
+ MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE, MCE_ECLASS_SOFTWARE,
419
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
420
+{ 0x00000080, true,
421
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, /* Before PARITY */
422
+ MCE_ECLASS_SOFT_INDETERMINATE,
423
+ MCE_INITIATOR_CPU, MCE_SEV_WARNING, true },
424
+{ 0x00000100, true,
425
+ MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
426
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
427
+{ 0x00000040, true,
428
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD, MCE_ECLASS_HARDWARE,
429
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
430
+{ 0x00000020, false,
431
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
432
+ MCE_ECLASS_HARDWARE,
433
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
434
+{ 0x00000010, false,
435
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN,
436
+ MCE_ECLASS_HARDWARE,
437
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
438
+{ 0x00000008, false,
439
+ MCE_ERROR_TYPE_RA, MCE_RA_ERROR_LOAD_STORE_FOREIGN, MCE_ECLASS_HARDWARE,
440
+ MCE_INITIATOR_CPU, MCE_SEV_SEVERE, true },
441
+{ 0, false, 0, 0, 0, 0, 0 } };
351442
352443 static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
353444 uint64_t *phys_addr)
....@@ -358,7 +449,7 @@
358449 * in real-mode is tricky and can lead to recursive
359450 * faults
360451 */
361
- int instr;
452
+ struct ppc_inst instr;
362453 unsigned long pfn, instr_addr;
363454 struct instruction_op op;
364455 struct pt_regs tmp = *regs;
....@@ -366,7 +457,7 @@
366457 pfn = addr_to_pfn(regs, regs->nip);
367458 if (pfn != ULONG_MAX) {
368459 instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
369
- instr = *(unsigned int *)(instr_addr);
460
+ instr = ppc_inst_read((struct ppc_inst *)instr_addr);
370461 if (!analyse_instr(&op, &tmp, instr)) {
371462 pfn = addr_to_pfn(regs, op.ea);
372463 *addr = op.ea;
....@@ -384,12 +475,11 @@
384475 return -1;
385476 }
386477
387
-static int mce_handle_ierror(struct pt_regs *regs,
478
+static int mce_handle_ierror(struct pt_regs *regs, unsigned long srr1,
388479 const struct mce_ierror_table table[],
389480 struct mce_error_info *mce_err, uint64_t *addr,
390481 uint64_t *phys_addr)
391482 {
392
- uint64_t srr1 = regs->msr;
393483 int handled = 0;
394484 int i;
395485
....@@ -402,6 +492,8 @@
402492 /* attempt to correct the error */
403493 switch (table[i].error_type) {
404494 case MCE_ERROR_TYPE_SLB:
495
+ if (local_paca->in_mce == 1)
496
+ slb_save_contents(local_paca->mce_faulty_slbs);
405497 handled = mce_flush(MCE_FLUSH_SLB);
406498 break;
407499 case MCE_ERROR_TYPE_ERAT:
....@@ -414,6 +506,7 @@
414506
415507 /* now fill in mce_error_info */
416508 mce_err->error_type = table[i].error_type;
509
+ mce_err->error_class = table[i].error_class;
417510 switch (table[i].error_type) {
418511 case MCE_ERROR_TYPE_UE:
419512 mce_err->u.ue_error_type = table[i].error_subtype;
....@@ -437,11 +530,12 @@
437530 mce_err->u.link_error_type = table[i].error_subtype;
438531 break;
439532 }
533
+ mce_err->sync_error = table[i].sync_error;
440534 mce_err->severity = table[i].severity;
441535 mce_err->initiator = table[i].initiator;
442536 if (table[i].nip_valid) {
443537 *addr = regs->nip;
444
- if (mce_err->severity == MCE_SEV_ERROR_SYNC &&
538
+ if (mce_err->sync_error &&
445539 table[i].error_type == MCE_ERROR_TYPE_UE) {
446540 unsigned long pfn;
447541
....@@ -458,8 +552,10 @@
458552 }
459553
460554 mce_err->error_type = MCE_ERROR_TYPE_UNKNOWN;
461
- mce_err->severity = MCE_SEV_ERROR_SYNC;
555
+ mce_err->error_class = MCE_ECLASS_UNKNOWN;
556
+ mce_err->severity = MCE_SEV_SEVERE;
462557 mce_err->initiator = MCE_INITIATOR_CPU;
558
+ mce_err->sync_error = true;
463559
464560 return 0;
465561 }
....@@ -483,6 +579,8 @@
483579 /* attempt to correct the error */
484580 switch (table[i].error_type) {
485581 case MCE_ERROR_TYPE_SLB:
582
+ if (local_paca->in_mce == 1)
583
+ slb_save_contents(local_paca->mce_faulty_slbs);
486584 if (mce_flush(MCE_FLUSH_SLB))
487585 handled = 1;
488586 break;
....@@ -506,6 +604,7 @@
506604
507605 /* now fill in mce_error_info */
508606 mce_err->error_type = table[i].error_type;
607
+ mce_err->error_class = table[i].error_class;
509608 switch (table[i].error_type) {
510609 case MCE_ERROR_TYPE_UE:
511610 mce_err->u.ue_error_type = table[i].error_subtype;
....@@ -529,11 +628,12 @@
529628 mce_err->u.link_error_type = table[i].error_subtype;
530629 break;
531630 }
631
+ mce_err->sync_error = table[i].sync_error;
532632 mce_err->severity = table[i].severity;
533633 mce_err->initiator = table[i].initiator;
534634 if (table[i].dar_valid)
535635 *addr = regs->dar;
536
- else if (mce_err->severity == MCE_SEV_ERROR_SYNC &&
636
+ else if (mce_err->sync_error &&
537637 table[i].error_type == MCE_ERROR_TYPE_UE) {
538638 /*
539639 * We do a maximum of 4 nested MCE calls, see
....@@ -550,15 +650,22 @@
550650 return handled;
551651
552652 mce_err->error_type = MCE_ERROR_TYPE_UNKNOWN;
553
- mce_err->severity = MCE_SEV_ERROR_SYNC;
653
+ mce_err->error_class = MCE_ECLASS_UNKNOWN;
654
+ mce_err->severity = MCE_SEV_SEVERE;
554655 mce_err->initiator = MCE_INITIATOR_CPU;
656
+ mce_err->sync_error = true;
555657
556658 return 0;
557659 }
558660
559
-static long mce_handle_ue_error(struct pt_regs *regs)
661
+static long mce_handle_ue_error(struct pt_regs *regs,
662
+ struct mce_error_info *mce_err)
560663 {
561664 long handled = 0;
665
+
666
+ mce_common_process_ue(regs, mce_err);
667
+ if (mce_err->ignore_event)
668
+ return 1;
562669
563670 /*
564671 * On specific SCOM read via MMIO we may get a machine check
....@@ -575,23 +682,23 @@
575682 }
576683
577684 static long mce_handle_error(struct pt_regs *regs,
685
+ unsigned long srr1,
578686 const struct mce_derror_table dtable[],
579687 const struct mce_ierror_table itable[])
580688 {
581689 struct mce_error_info mce_err = { 0 };
582690 uint64_t addr, phys_addr = ULONG_MAX;
583
- uint64_t srr1 = regs->msr;
584691 long handled;
585692
586693 if (SRR1_MC_LOADSTORE(srr1))
587694 handled = mce_handle_derror(regs, dtable, &mce_err, &addr,
588695 &phys_addr);
589696 else
590
- handled = mce_handle_ierror(regs, itable, &mce_err, &addr,
697
+ handled = mce_handle_ierror(regs, srr1, itable, &mce_err, &addr,
591698 &phys_addr);
592699
593700 if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE)
594
- handled = mce_handle_ue_error(regs);
701
+ handled = mce_handle_ue_error(regs, &mce_err);
595702
596703 save_mce_event(regs, handled, &mce_err, regs->nip, addr, phys_addr);
597704
....@@ -603,16 +710,20 @@
603710 /* P7 DD1 leaves top bits of DSISR undefined */
604711 regs->dsisr &= 0x0000ffff;
605712
606
- return mce_handle_error(regs, mce_p7_derror_table, mce_p7_ierror_table);
713
+ return mce_handle_error(regs, regs->msr,
714
+ mce_p7_derror_table, mce_p7_ierror_table);
607715 }
608716
609717 long __machine_check_early_realmode_p8(struct pt_regs *regs)
610718 {
611
- return mce_handle_error(regs, mce_p8_derror_table, mce_p8_ierror_table);
719
+ return mce_handle_error(regs, regs->msr,
720
+ mce_p8_derror_table, mce_p8_ierror_table);
612721 }
613722
614723 long __machine_check_early_realmode_p9(struct pt_regs *regs)
615724 {
725
+ unsigned long srr1 = regs->msr;
726
+
616727 /*
617728 * On POWER9 DD2.1 and below, it's possible to get a machine check
618729 * caused by a paste instruction where only DSISR bit 25 is set. This
....@@ -626,5 +737,39 @@
626737 if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000)
627738 return 1;
628739
629
- return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
740
+ /*
741
+ * Async machine check due to bad real address from store or foreign
742
+ * link time out comes with the load/store bit (PPC bit 42) set in
743
+ * SRR1, but the cause comes in SRR1 not DSISR. Clear bit 42 so we're
744
+ * directed to the ierror table so it will find the cause (which
745
+ * describes it correctly as a store error).
746
+ */
747
+ if (SRR1_MC_LOADSTORE(srr1) &&
748
+ ((srr1 & 0x081c0000) == 0x08140000 ||
749
+ (srr1 & 0x081c0000) == 0x08180000)) {
750
+ srr1 &= ~PPC_BIT(42);
751
+ }
752
+
753
+ return mce_handle_error(regs, srr1,
754
+ mce_p9_derror_table, mce_p9_ierror_table);
755
+}
756
+
757
+long __machine_check_early_realmode_p10(struct pt_regs *regs)
758
+{
759
+ unsigned long srr1 = regs->msr;
760
+
761
+ /*
762
+ * Async machine check due to bad real address from store comes with
763
+ * the load/store bit (PPC bit 42) set in SRR1, but the cause comes in
764
+ * SRR1 not DSISR. Clear bit 42 so we're directed to the ierror table
765
+ * so it will find the cause (which describes it correctly as a store
766
+ * error).
767
+ */
768
+ if (SRR1_MC_LOADSTORE(srr1) &&
769
+ (srr1 & 0x081c0000) == 0x08140000) {
770
+ srr1 &= ~PPC_BIT(42);
771
+ }
772
+
773
+ return mce_handle_error(regs, srr1,
774
+ mce_p10_derror_table, mce_p10_ierror_table);
630775 }