mce_power.c 19 KB

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