1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Machine check exception header file. 4 * 5 * Copyright 2013 IBM Corporation 6 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> 7 */ 8 9 #ifndef __ASM_PPC64_MCE_H__ 10 #define __ASM_PPC64_MCE_H__ 11 12 #include <linux/bitops.h> 13 14 enum MCE_Version { 15 MCE_V1 = 1, 16 }; 17 18 enum MCE_Severity { 19 MCE_SEV_NO_ERROR = 0, 20 MCE_SEV_WARNING = 1, 21 MCE_SEV_SEVERE = 2, 22 MCE_SEV_FATAL = 3, 23 }; 24 25 enum MCE_Disposition { 26 MCE_DISPOSITION_RECOVERED = 0, 27 MCE_DISPOSITION_NOT_RECOVERED = 1, 28 }; 29 30 enum MCE_Initiator { 31 MCE_INITIATOR_UNKNOWN = 0, 32 MCE_INITIATOR_CPU = 1, 33 MCE_INITIATOR_PCI = 2, 34 MCE_INITIATOR_ISA = 3, 35 MCE_INITIATOR_MEMORY= 4, 36 MCE_INITIATOR_POWERMGM = 5, 37 }; 38 39 enum MCE_ErrorType { 40 MCE_ERROR_TYPE_UNKNOWN = 0, 41 MCE_ERROR_TYPE_UE = 1, 42 MCE_ERROR_TYPE_SLB = 2, 43 MCE_ERROR_TYPE_ERAT = 3, 44 MCE_ERROR_TYPE_TLB = 4, 45 MCE_ERROR_TYPE_USER = 5, 46 MCE_ERROR_TYPE_RA = 6, 47 MCE_ERROR_TYPE_LINK = 7, 48 MCE_ERROR_TYPE_DCACHE = 8, 49 MCE_ERROR_TYPE_ICACHE = 9, 50 }; 51 52 enum MCE_ErrorClass { 53 MCE_ECLASS_UNKNOWN = 0, 54 MCE_ECLASS_HARDWARE, 55 MCE_ECLASS_HARD_INDETERMINATE, 56 MCE_ECLASS_SOFTWARE, 57 MCE_ECLASS_SOFT_INDETERMINATE, 58 }; 59 60 enum MCE_UeErrorType { 61 MCE_UE_ERROR_INDETERMINATE = 0, 62 MCE_UE_ERROR_IFETCH = 1, 63 MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2, 64 MCE_UE_ERROR_LOAD_STORE = 3, 65 MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4, 66 }; 67 68 enum MCE_SlbErrorType { 69 MCE_SLB_ERROR_INDETERMINATE = 0, 70 MCE_SLB_ERROR_PARITY = 1, 71 MCE_SLB_ERROR_MULTIHIT = 2, 72 }; 73 74 enum MCE_EratErrorType { 75 MCE_ERAT_ERROR_INDETERMINATE = 0, 76 MCE_ERAT_ERROR_PARITY = 1, 77 MCE_ERAT_ERROR_MULTIHIT = 2, 78 }; 79 80 enum MCE_TlbErrorType { 81 MCE_TLB_ERROR_INDETERMINATE = 0, 82 MCE_TLB_ERROR_PARITY = 1, 83 MCE_TLB_ERROR_MULTIHIT = 2, 84 }; 85 86 enum MCE_UserErrorType { 87 MCE_USER_ERROR_INDETERMINATE = 0, 88 MCE_USER_ERROR_TLBIE = 1, 89 MCE_USER_ERROR_SCV = 2, 90 }; 91 92 enum MCE_RaErrorType { 93 MCE_RA_ERROR_INDETERMINATE = 0, 94 MCE_RA_ERROR_IFETCH = 1, 95 MCE_RA_ERROR_IFETCH_FOREIGN = 2, 96 MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH = 3, 97 MCE_RA_ERROR_PAGE_TABLE_WALK_IFETCH_FOREIGN = 4, 98 MCE_RA_ERROR_LOAD = 5, 99 MCE_RA_ERROR_STORE = 6, 100 MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 7, 101 MCE_RA_ERROR_PAGE_TABLE_WALK_LOAD_STORE_FOREIGN = 8, 102 MCE_RA_ERROR_LOAD_STORE_FOREIGN = 9, 103 }; 104 105 enum MCE_LinkErrorType { 106 MCE_LINK_ERROR_INDETERMINATE = 0, 107 MCE_LINK_ERROR_IFETCH_TIMEOUT = 1, 108 MCE_LINK_ERROR_PAGE_TABLE_WALK_IFETCH_TIMEOUT = 2, 109 MCE_LINK_ERROR_LOAD_TIMEOUT = 3, 110 MCE_LINK_ERROR_STORE_TIMEOUT = 4, 111 MCE_LINK_ERROR_PAGE_TABLE_WALK_LOAD_STORE_TIMEOUT = 5, 112 }; 113 114 struct machine_check_event { 115 enum MCE_Version version:8; 116 u8 in_use; 117 enum MCE_Severity severity:8; 118 enum MCE_Initiator initiator:8; 119 enum MCE_ErrorType error_type:8; 120 enum MCE_ErrorClass error_class:8; 121 enum MCE_Disposition disposition:8; 122 bool sync_error; 123 u16 cpu; 124 u64 gpr3; 125 u64 srr0; 126 u64 srr1; 127 union { 128 struct { 129 enum MCE_UeErrorType ue_error_type:8; 130 u8 effective_address_provided; 131 u8 physical_address_provided; 132 u8 ignore_event; 133 u8 reserved_1[4]; 134 u64 effective_address; 135 u64 physical_address; 136 u8 reserved_2[8]; 137 } ue_error; 138 139 struct { 140 enum MCE_SlbErrorType slb_error_type:8; 141 u8 effective_address_provided; 142 u8 reserved_1[6]; 143 u64 effective_address; 144 u8 reserved_2[16]; 145 } slb_error; 146 147 struct { 148 enum MCE_EratErrorType erat_error_type:8; 149 u8 effective_address_provided; 150 u8 reserved_1[6]; 151 u64 effective_address; 152 u8 reserved_2[16]; 153 } erat_error; 154 155 struct { 156 enum MCE_TlbErrorType tlb_error_type:8; 157 u8 effective_address_provided; 158 u8 reserved_1[6]; 159 u64 effective_address; 160 u8 reserved_2[16]; 161 } tlb_error; 162 163 struct { 164 enum MCE_UserErrorType user_error_type:8; 165 u8 effective_address_provided; 166 u8 reserved_1[6]; 167 u64 effective_address; 168 u8 reserved_2[16]; 169 } user_error; 170 171 struct { 172 enum MCE_RaErrorType ra_error_type:8; 173 u8 effective_address_provided; 174 u8 reserved_1[6]; 175 u64 effective_address; 176 u8 reserved_2[16]; 177 } ra_error; 178 179 struct { 180 enum MCE_LinkErrorType link_error_type:8; 181 u8 effective_address_provided; 182 u8 reserved_1[6]; 183 u64 effective_address; 184 u8 reserved_2[16]; 185 } link_error; 186 } u; 187 }; 188 189 struct mce_error_info { 190 enum MCE_ErrorType error_type:8; 191 union { 192 enum MCE_UeErrorType ue_error_type:8; 193 enum MCE_SlbErrorType slb_error_type:8; 194 enum MCE_EratErrorType erat_error_type:8; 195 enum MCE_TlbErrorType tlb_error_type:8; 196 enum MCE_UserErrorType user_error_type:8; 197 enum MCE_RaErrorType ra_error_type:8; 198 enum MCE_LinkErrorType link_error_type:8; 199 } u; 200 enum MCE_Severity severity:8; 201 enum MCE_Initiator initiator:8; 202 enum MCE_ErrorClass error_class:8; 203 bool sync_error; 204 bool ignore_event; 205 }; 206 207 #define MAX_MC_EVT 10 208 209 struct mce_info { 210 int mce_nest_count; 211 struct machine_check_event mce_event[MAX_MC_EVT]; 212 /* Queue for delayed MCE events. */ 213 int mce_queue_count; 214 struct machine_check_event mce_event_queue[MAX_MC_EVT]; 215 /* Queue for delayed MCE UE events. */ 216 int mce_ue_count; 217 struct machine_check_event mce_ue_event_queue[MAX_MC_EVT]; 218 }; 219 220 /* Release flags for get_mce_event() */ 221 #define MCE_EVENT_RELEASE true 222 #define MCE_EVENT_DONTRELEASE false 223 224 struct pt_regs; 225 struct notifier_block; 226 227 extern void save_mce_event(struct pt_regs *regs, long handled, 228 struct mce_error_info *mce_err, uint64_t nip, 229 uint64_t addr, uint64_t phys_addr); 230 extern int get_mce_event(struct machine_check_event *mce, bool release); 231 extern void release_mce_event(void); 232 extern void machine_check_queue_event(void); 233 extern void machine_check_print_event_info(struct machine_check_event *evt, 234 bool user_mode, bool in_guest); 235 unsigned long addr_to_pfn(struct pt_regs *regs, unsigned long addr); 236 extern void mce_common_process_ue(struct pt_regs *regs, 237 struct mce_error_info *mce_err); 238 void mce_irq_work_queue(void); 239 int mce_register_notifier(struct notifier_block *nb); 240 int mce_unregister_notifier(struct notifier_block *nb); 241 242 #ifdef CONFIG_PPC_BOOK3S_64 243 void mce_run_irq_context_handlers(void); 244 #else 245 static inline void mce_run_irq_context_handlers(void) { }; 246 #endif /* CONFIG_PPC_BOOK3S_64 */ 247 248 #ifdef CONFIG_PPC_BOOK3S_64 249 void set_mce_pending_irq_work(void); 250 void clear_mce_pending_irq_work(void); 251 #endif /* CONFIG_PPC_BOOK3S_64 */ 252 253 #ifdef CONFIG_PPC_BOOK3S_64 254 void flush_and_reload_slb(void); 255 void flush_erat(void); 256 long __machine_check_early_realmode_p7(struct pt_regs *regs); 257 long __machine_check_early_realmode_p8(struct pt_regs *regs); 258 long __machine_check_early_realmode_p9(struct pt_regs *regs); 259 long __machine_check_early_realmode_p10(struct pt_regs *regs); 260 #endif /* CONFIG_PPC_BOOK3S_64 */ 261 262 #ifdef CONFIG_PPC_BOOK3S_64 263 void mce_init(void); 264 #else 265 static inline void mce_init(void) { }; 266 #endif /* CONFIG_PPC_BOOK3S_64 */ 267 268 #endif /* __ASM_PPC64_MCE_H__ */ 269