Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / arch / powerpc / kernel / mce_power.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Machine check exception handling CPU-side for power7 and power8
4  *
5  * Copyright 2013 IBM Corporation
6  * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
7  */
8
9 #undef DEBUG
10 #define pr_fmt(fmt) "mce_power: " fmt
11
12 #include <linux/types.h>
13 #include <linux/ptrace.h>
14 #include <linux/extable.h>
15 #include <asm/mmu.h>
16 #include <asm/mce.h>
17 #include <asm/machdep.h>
18 #include <asm/pgtable.h>
19 #include <asm/pte-walk.h>
20 #include <asm/sstep.h>
21 #include <asm/exception-64s.h>
22 #include <asm/extable.h>
23
24 /*
25  * Convert an address related to an mm to a PFN. NOTE: we are in real
26  * mode, we could potentially race with page table updates.
27  */
28 unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr)
29 {
30         pte_t *ptep;
31         unsigned int shift;
32         unsigned long pfn, flags;
33         struct mm_struct *mm;
34
35         if (user_mode(regs))
36                 mm = current->mm;
37         else
38                 mm = &init_mm;
39
40         local_irq_save(flags);
41         ptep = __find_linux_pte(mm->pgd, addr, NULL, &shift);
42
43         if (!ptep || pte_special(*ptep)) {
44                 pfn = ULONG_MAX;
45                 goto out;
46         }
47
48         if (shift <= PAGE_SHIFT)
49                 pfn = pte_pfn(*ptep);
50         else {
51                 unsigned long rpnmask = (1ul << shift) - PAGE_SIZE;
52                 pfn = pte_pfn(__pte(pte_val(*ptep) | (addr & rpnmask)));
53         }
54
55 out:
56         local_irq_restore(flags);
57         return pfn;
58 }
59
60 /* flush SLBs and reload */
61 #ifdef CONFIG_PPC_BOOK3S_64
62 void flush_and_reload_slb(void)
63 {
64         /* Invalidate all SLBs */
65         slb_flush_all_realmode();
66
67 #ifdef CONFIG_KVM_BOOK3S_HANDLER
68         /*
69          * If machine check is hit when in guest or in transition, we will
70          * only flush the SLBs and continue.
71          */
72         if (get_paca()->kvm_hstate.in_guest)
73                 return;
74 #endif
75         if (early_radix_enabled())
76                 return;
77
78         /*
79          * This probably shouldn't happen, but it may be possible it's
80          * called in early boot before SLB shadows are allocated.
81          */
82         if (!get_slb_shadow())
83                 return;
84
85         slb_restore_bolted_realmode();
86 }
87 #endif
88
89 static void flush_erat(void)
90 {
91 #ifdef CONFIG_PPC_BOOK3S_64
92         if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
93                 flush_and_reload_slb();
94                 return;
95         }
96 #endif
97         asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory");
98 }
99
100 #define MCE_FLUSH_SLB 1
101 #define MCE_FLUSH_TLB 2
102 #define MCE_FLUSH_ERAT 3
103
104 static int mce_flush(int what)
105 {
106 #ifdef CONFIG_PPC_BOOK3S_64
107         if (what == MCE_FLUSH_SLB) {
108                 flush_and_reload_slb();
109                 return 1;
110         }
111 #endif
112         if (what == MCE_FLUSH_ERAT) {
113                 flush_erat();
114                 return 1;
115         }
116         if (what == MCE_FLUSH_TLB) {
117                 tlbiel_all();
118                 return 1;
119         }
120
121         return 0;
122 }
123
124 #define SRR1_MC_LOADSTORE(srr1) ((srr1) & PPC_BIT(42))
125
126 struct mce_ierror_table {
127         unsigned long srr1_mask;
128         unsigned long srr1_value;
129         bool nip_valid; /* nip is a valid indicator of faulting address */
130         unsigned int error_type;
131         unsigned int error_subtype;
132         unsigned int error_class;
133         unsigned int initiator;
134         unsigned int severity;
135         bool sync_error;
136 };
137
138 static const struct mce_ierror_table mce_p7_ierror_table[] = {
139 { 0x00000000001c0000, 0x0000000000040000, true,
140   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
141   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
142 { 0x00000000001c0000, 0x0000000000080000, true,
143   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
144   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
145 { 0x00000000001c0000, 0x00000000000c0000, true,
146   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
147   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
148 { 0x00000000001c0000, 0x0000000000100000, true,
149   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_INDETERMINATE, /* BOTH */
150   MCE_ECLASS_SOFT_INDETERMINATE,
151   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
152 { 0x00000000001c0000, 0x0000000000140000, true,
153   MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
154   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
155 { 0x00000000001c0000, 0x0000000000180000, true,
156   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
157   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
158 { 0x00000000001c0000, 0x00000000001c0000, true,
159   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
160   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
161 { 0, 0, 0, 0, 0, 0, 0 } };
162
163 static const struct mce_ierror_table mce_p8_ierror_table[] = {
164 { 0x00000000081c0000, 0x0000000000040000, true,
165   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
166   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
167 { 0x00000000081c0000, 0x0000000000080000, true,
168   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
169   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
170 { 0x00000000081c0000, 0x00000000000c0000, true,
171   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
172   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
173 { 0x00000000081c0000, 0x0000000000100000, true,
174   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
175   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
176 { 0x00000000081c0000, 0x0000000000140000, true,
177   MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
178   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
179 { 0x00000000081c0000, 0x0000000000180000, true,
180   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH,
181   MCE_ECLASS_HARDWARE,
182   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
183 { 0x00000000081c0000, 0x00000000001c0000, true,
184   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
185   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
186 { 0x00000000081c0000, 0x0000000008000000, true,
187   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_IFETCH_TIMEOUT, MCE_ECLASS_HARDWARE,
188   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
189 { 0x00000000081c0000, 0x0000000008040000, true,
190   MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT,
191   MCE_ECLASS_HARDWARE,
192   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
193 { 0, 0, 0, 0, 0, 0, 0 } };
194
195 static const struct mce_ierror_table mce_p9_ierror_table[] = {
196 { 0x00000000081c0000, 0x0000000000040000, true,
197   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_IFETCH, MCE_ECLASS_HARDWARE,
198   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
199 { 0x00000000081c0000, 0x0000000000080000, true,
200   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
201   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
202 { 0x00000000081c0000, 0x00000000000c0000, true,
203   MCE_ERROR_TYPE_SLB, MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
204   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
205 { 0x00000000081c0000, 0x0000000000100000, true,
206   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
207   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
208 { 0x00000000081c0000, 0x0000000000140000, true,
209   MCE_ERROR_TYPE_TLB, MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
210   MCE_INITIATOR_CPU,  MCE_SEV_WARNING, true },
211 { 0x00000000081c0000, 0x0000000000180000, true,
212   MCE_ERROR_TYPE_UE,  MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_HARDWARE,
213   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
214 { 0x00000000081c0000, 0x00000000001c0000, true,
215   MCE_ERROR_TYPE_RA,  MCE_RA_ERROR_IFETCH_FOREIGN, MCE_ECLASS_SOFTWARE,
216   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
217 { 0x00000000081c0000, 0x0000000008000000, true,
218   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_IFETCH_TIMEOUT, MCE_ECLASS_HARDWARE,
219   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
220 { 0x00000000081c0000, 0x0000000008040000, true,
221   MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT,
222   MCE_ECLASS_HARDWARE,
223   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
224 { 0x00000000081c0000, 0x00000000080c0000, true,
225   MCE_ERROR_TYPE_RA,  MCE_RA_ERROR_IFETCH, MCE_ECLASS_SOFTWARE,
226   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
227 { 0x00000000081c0000, 0x0000000008100000, true,
228   MCE_ERROR_TYPE_RA,  MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH, MCE_ECLASS_SOFTWARE,
229   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
230 { 0x00000000081c0000, 0x0000000008140000, false,
231   MCE_ERROR_TYPE_RA,  MCE_RA_ERROR_STORE, MCE_ECLASS_HARDWARE,
232   MCE_INITIATOR_CPU,  MCE_SEV_FATAL, false }, /* ASYNC is fatal */
233 { 0x00000000081c0000, 0x0000000008180000, false,
234   MCE_ERROR_TYPE_LINK,MCE_LINK_ERROR_STORE_TIMEOUT,
235   MCE_INITIATOR_CPU,  MCE_SEV_FATAL, false }, /* ASYNC is fatal */
236 { 0x00000000081c0000, 0x00000000081c0000, true, MCE_ECLASS_HARDWARE,
237   MCE_ERROR_TYPE_RA,  MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN,
238   MCE_INITIATOR_CPU,  MCE_SEV_SEVERE, true },
239 { 0, 0, 0, 0, 0, 0, 0 } };
240
241 struct mce_derror_table {
242         unsigned long dsisr_value;
243         bool dar_valid; /* dar is a valid indicator of faulting address */
244         unsigned int error_type;
245         unsigned int error_subtype;
246         unsigned int error_class;
247         unsigned int initiator;
248         unsigned int severity;
249         bool sync_error;
250 };
251
252 static const struct mce_derror_table mce_p7_derror_table[] = {
253 { 0x00008000, false,
254   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
255   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
256 { 0x00004000, true,
257   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
258   MCE_ECLASS_HARDWARE,
259   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
260 { 0x00000800, true,
261   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
262   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
263 { 0x00000400, true,
264   MCE_ERROR_TYPE_TLB,  MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
265   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
266 { 0x00000080, true,
267   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
268   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
269 { 0x00000100, true,
270   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
271   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
272 { 0x00000040, true,
273   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_INDETERMINATE, /* BOTH */
274   MCE_ECLASS_HARD_INDETERMINATE,
275   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
276 { 0, false, 0, 0, 0, 0, 0 } };
277
278 static const struct mce_derror_table mce_p8_derror_table[] = {
279 { 0x00008000, false,
280   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
281   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
282 { 0x00004000, true,
283   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
284   MCE_ECLASS_HARDWARE,
285   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
286 { 0x00002000, true,
287   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT, MCE_ECLASS_HARDWARE,
288   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
289 { 0x00001000, true,
290   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT,
291   MCE_ECLASS_HARDWARE,
292   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
293 { 0x00000800, true,
294   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
295   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
296 { 0x00000400, true,
297   MCE_ERROR_TYPE_TLB,  MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
298   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
299 { 0x00000200, true,
300   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, /* SECONDARY ERAT */
301   MCE_ECLASS_SOFT_INDETERMINATE,
302   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
303 { 0x00000080, true,
304   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_MULTIHIT,  /* Before PARITY */
305   MCE_ECLASS_SOFT_INDETERMINATE,
306   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
307 { 0x00000100, true,
308   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
309   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
310 { 0, false, 0, 0, 0, 0, 0 } };
311
312 static const struct mce_derror_table mce_p9_derror_table[] = {
313 { 0x00008000, false,
314   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_LOAD_STORE, MCE_ECLASS_HARDWARE,
315   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
316 { 0x00004000, true,
317   MCE_ERROR_TYPE_UE,   MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
318   MCE_ECLASS_HARDWARE,
319   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
320 { 0x00002000, true,
321   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_LOAD_TIMEOUT, MCE_ECLASS_HARDWARE,
322   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
323 { 0x00001000, true,
324   MCE_ERROR_TYPE_LINK, MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT,
325   MCE_ECLASS_HARDWARE,
326   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
327 { 0x00000800, true,
328   MCE_ERROR_TYPE_ERAT, MCE_ERAT_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
329   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
330 { 0x00000400, true,
331   MCE_ERROR_TYPE_TLB,  MCE_TLB_ERROR_MULTIHIT, MCE_ECLASS_SOFT_INDETERMINATE,
332   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
333 { 0x00000200, false,
334   MCE_ERROR_TYPE_USER, MCE_USER_ERROR_TLBIE, MCE_ECLASS_SOFTWARE,
335   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
336 { 0x00000080, true,
337   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_MULTIHIT,  /* Before PARITY */
338   MCE_ECLASS_SOFT_INDETERMINATE,
339   MCE_INITIATOR_CPU,   MCE_SEV_WARNING, true },
340 { 0x00000100, true,
341   MCE_ERROR_TYPE_SLB,  MCE_SLB_ERROR_PARITY, MCE_ECLASS_HARD_INDETERMINATE,
342   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
343 { 0x00000040, true,
344   MCE_ERROR_TYPE_RA,   MCE_RA_ERROR_LOAD, MCE_ECLASS_HARDWARE,
345   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
346 { 0x00000020, false,
347   MCE_ERROR_TYPE_RA,   MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE,
348   MCE_ECLASS_HARDWARE,
349   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
350 { 0x00000010, false,
351   MCE_ERROR_TYPE_RA,   MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN,
352   MCE_ECLASS_HARDWARE,
353   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
354 { 0x00000008, false,
355   MCE_ERROR_TYPE_RA,   MCE_RA_ERROR_LOAD_STORE_FOREIGN, MCE_ECLASS_HARDWARE,
356   MCE_INITIATOR_CPU,   MCE_SEV_SEVERE, true },
357 { 0, false, 0, 0, 0, 0, 0 } };
358
359 static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr,
360                                         uint64_t *phys_addr)
361 {
362         /*
363          * Carefully look at the NIP to determine
364          * the instruction to analyse. Reading the NIP
365          * in real-mode is tricky and can lead to recursive
366          * faults
367          */
368         int instr;
369         unsigned long pfn, instr_addr;
370         struct instruction_op op;
371         struct pt_regs tmp = *regs;
372
373         pfn = addr_to_pfn(regs, regs->nip);
374         if (pfn != ULONG_MAX) {
375                 instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK);
376                 instr = *(unsigned int *)(instr_addr);
377                 if (!analyse_instr(&op, &tmp, instr)) {
378                         pfn = addr_to_pfn(regs, op.ea);
379                         *addr = op.ea;
380                         *phys_addr = (pfn << PAGE_SHIFT);
381                         return 0;
382                 }
383                 /*
384                  * analyse_instr() might fail if the instruction
385                  * is not a load/store, although this is unexpected
386                  * for load/store errors or if we got the NIP
387                  * wrong
388                  */
389         }
390         *addr = 0;
391         return -1;
392 }
393
394 static int mce_handle_ierror(struct pt_regs *regs,
395                 const struct mce_ierror_table table[],
396                 struct mce_error_info *mce_err, uint64_t *addr,
397                 uint64_t *phys_addr)
398 {
399         uint64_t srr1 = regs->msr;
400         int handled = 0;
401         int i;
402
403         *addr = 0;
404
405         for (i = 0; table[i].srr1_mask; i++) {
406                 if ((srr1 & table[i].srr1_mask) != table[i].srr1_value)
407                         continue;
408
409                 /* attempt to correct the error */
410                 switch (table[i].error_type) {
411                 case MCE_ERROR_TYPE_SLB:
412                         if (local_paca->in_mce == 1)
413                                 slb_save_contents(local_paca->mce_faulty_slbs);
414                         handled = mce_flush(MCE_FLUSH_SLB);
415                         break;
416                 case MCE_ERROR_TYPE_ERAT:
417                         handled = mce_flush(MCE_FLUSH_ERAT);
418                         break;
419                 case MCE_ERROR_TYPE_TLB:
420                         handled = mce_flush(MCE_FLUSH_TLB);
421                         break;
422                 }
423
424                 /* now fill in mce_error_info */
425                 mce_err->error_type = table[i].error_type;
426                 mce_err->error_class = table[i].error_class;
427                 switch (table[i].error_type) {
428                 case MCE_ERROR_TYPE_UE:
429                         mce_err->u.ue_error_type = table[i].error_subtype;
430                         break;
431                 case MCE_ERROR_TYPE_SLB:
432                         mce_err->u.slb_error_type = table[i].error_subtype;
433                         break;
434                 case MCE_ERROR_TYPE_ERAT:
435                         mce_err->u.erat_error_type = table[i].error_subtype;
436                         break;
437                 case MCE_ERROR_TYPE_TLB:
438                         mce_err->u.tlb_error_type = table[i].error_subtype;
439                         break;
440                 case MCE_ERROR_TYPE_USER:
441                         mce_err->u.user_error_type = table[i].error_subtype;
442                         break;
443                 case MCE_ERROR_TYPE_RA:
444                         mce_err->u.ra_error_type = table[i].error_subtype;
445                         break;
446                 case MCE_ERROR_TYPE_LINK:
447                         mce_err->u.link_error_type = table[i].error_subtype;
448                         break;
449                 }
450                 mce_err->sync_error = table[i].sync_error;
451                 mce_err->severity = table[i].severity;
452                 mce_err->initiator = table[i].initiator;
453                 if (table[i].nip_valid) {
454                         *addr = regs->nip;
455                         if (mce_err->sync_error &&
456                                 table[i].error_type == MCE_ERROR_TYPE_UE) {
457                                 unsigned long pfn;
458
459                                 if (get_paca()->in_mce < MAX_MCE_DEPTH) {
460                                         pfn = addr_to_pfn(regs, regs->nip);
461                                         if (pfn != ULONG_MAX) {
462                                                 *phys_addr =
463                                                         (pfn << PAGE_SHIFT);
464                                         }
465                                 }
466                         }
467                 }
468                 return handled;
469         }
470
471         mce_err->error_type = MCE_ERROR_TYPE_UNKNOWN;
472         mce_err->error_class = MCE_ECLASS_UNKNOWN;
473         mce_err->severity = MCE_SEV_SEVERE;
474         mce_err->initiator = MCE_INITIATOR_CPU;
475         mce_err->sync_error = true;
476
477         return 0;
478 }
479
480 static int mce_handle_derror(struct pt_regs *regs,
481                 const struct mce_derror_table table[],
482                 struct mce_error_info *mce_err, uint64_t *addr,
483                 uint64_t *phys_addr)
484 {
485         uint64_t dsisr = regs->dsisr;
486         int handled = 0;
487         int found = 0;
488         int i;
489
490         *addr = 0;
491
492         for (i = 0; table[i].dsisr_value; i++) {
493                 if (!(dsisr & table[i].dsisr_value))
494                         continue;
495
496                 /* attempt to correct the error */
497                 switch (table[i].error_type) {
498                 case MCE_ERROR_TYPE_SLB:
499                         if (local_paca->in_mce == 1)
500                                 slb_save_contents(local_paca->mce_faulty_slbs);
501                         if (mce_flush(MCE_FLUSH_SLB))
502                                 handled = 1;
503                         break;
504                 case MCE_ERROR_TYPE_ERAT:
505                         if (mce_flush(MCE_FLUSH_ERAT))
506                                 handled = 1;
507                         break;
508                 case MCE_ERROR_TYPE_TLB:
509                         if (mce_flush(MCE_FLUSH_TLB))
510                                 handled = 1;
511                         break;
512                 }
513
514                 /*
515                  * Attempt to handle multiple conditions, but only return
516                  * one. Ensure uncorrectable errors are first in the table
517                  * to match.
518                  */
519                 if (found)
520                         continue;
521
522                 /* now fill in mce_error_info */
523                 mce_err->error_type = table[i].error_type;
524                 mce_err->error_class = table[i].error_class;
525                 switch (table[i].error_type) {
526                 case MCE_ERROR_TYPE_UE:
527                         mce_err->u.ue_error_type = table[i].error_subtype;
528                         break;
529                 case MCE_ERROR_TYPE_SLB:
530                         mce_err->u.slb_error_type = table[i].error_subtype;
531                         break;
532                 case MCE_ERROR_TYPE_ERAT:
533                         mce_err->u.erat_error_type = table[i].error_subtype;
534                         break;
535                 case MCE_ERROR_TYPE_TLB:
536                         mce_err->u.tlb_error_type = table[i].error_subtype;
537                         break;
538                 case MCE_ERROR_TYPE_USER:
539                         mce_err->u.user_error_type = table[i].error_subtype;
540                         break;
541                 case MCE_ERROR_TYPE_RA:
542                         mce_err->u.ra_error_type = table[i].error_subtype;
543                         break;
544                 case MCE_ERROR_TYPE_LINK:
545                         mce_err->u.link_error_type = table[i].error_subtype;
546                         break;
547                 }
548                 mce_err->sync_error = table[i].sync_error;
549                 mce_err->severity = table[i].severity;
550                 mce_err->initiator = table[i].initiator;
551                 if (table[i].dar_valid)
552                         *addr = regs->dar;
553                 else if (mce_err->sync_error &&
554                                 table[i].error_type == MCE_ERROR_TYPE_UE) {
555                         /*
556                          * We do a maximum of 4 nested MCE calls, see
557                          * kernel/exception-64s.h
558                          */
559                         if (get_paca()->in_mce < MAX_MCE_DEPTH)
560                                 mce_find_instr_ea_and_phys(regs, addr,
561                                                            phys_addr);
562                 }
563                 found = 1;
564         }
565
566         if (found)
567                 return handled;
568
569         mce_err->error_type = MCE_ERROR_TYPE_UNKNOWN;
570         mce_err->error_class = MCE_ECLASS_UNKNOWN;
571         mce_err->severity = MCE_SEV_SEVERE;
572         mce_err->initiator = MCE_INITIATOR_CPU;
573         mce_err->sync_error = true;
574
575         return 0;
576 }
577
578 static long mce_handle_ue_error(struct pt_regs *regs,
579                                 struct mce_error_info *mce_err)
580 {
581         long handled = 0;
582         const struct exception_table_entry *entry;
583
584         entry = search_kernel_exception_table(regs->nip);
585         if (entry) {
586                 mce_err->ignore_event = true;
587                 regs->nip = extable_fixup(entry);
588                 return 1;
589         }
590
591         /*
592          * On specific SCOM read via MMIO we may get a machine check
593          * exception with SRR0 pointing inside opal. If that is the
594          * case OPAL may have recovery address to re-read SCOM data in
595          * different way and hence we can recover from this MC.
596          */
597
598         if (ppc_md.mce_check_early_recovery) {
599                 if (ppc_md.mce_check_early_recovery(regs))
600                         handled = 1;
601         }
602         return handled;
603 }
604
605 static long mce_handle_error(struct pt_regs *regs,
606                 const struct mce_derror_table dtable[],
607                 const struct mce_ierror_table itable[])
608 {
609         struct mce_error_info mce_err = { 0 };
610         uint64_t addr, phys_addr = ULONG_MAX;
611         uint64_t srr1 = regs->msr;
612         long handled;
613
614         if (SRR1_MC_LOADSTORE(srr1))
615                 handled = mce_handle_derror(regs, dtable, &mce_err, &addr,
616                                 &phys_addr);
617         else
618                 handled = mce_handle_ierror(regs, itable, &mce_err, &addr,
619                                 &phys_addr);
620
621         if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE)
622                 handled = mce_handle_ue_error(regs, &mce_err);
623
624         save_mce_event(regs, handled, &mce_err, regs->nip, addr, phys_addr);
625
626         return handled;
627 }
628
629 long __machine_check_early_realmode_p7(struct pt_regs *regs)
630 {
631         /* P7 DD1 leaves top bits of DSISR undefined */
632         regs->dsisr &= 0x0000ffff;
633
634         return mce_handle_error(regs, mce_p7_derror_table, mce_p7_ierror_table);
635 }
636
637 long __machine_check_early_realmode_p8(struct pt_regs *regs)
638 {
639         return mce_handle_error(regs, mce_p8_derror_table, mce_p8_ierror_table);
640 }
641
642 long __machine_check_early_realmode_p9(struct pt_regs *regs)
643 {
644         /*
645          * On POWER9 DD2.1 and below, it's possible to get a machine check
646          * caused by a paste instruction where only DSISR bit 25 is set. This
647          * will result in the MCE handler seeing an unknown event and the kernel
648          * crashing. An MCE that occurs like this is spurious, so we don't need
649          * to do anything in terms of servicing it. If there is something that
650          * needs to be serviced, the CPU will raise the MCE again with the
651          * correct DSISR so that it can be serviced properly. So detect this
652          * case and mark it as handled.
653          */
654         if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000)
655                 return 1;
656
657         return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table);
658 }