mce_power.c 26 KB

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