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