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
mce_run_irq_context_handlers(void)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
mce_init(void)265  static inline void mce_init(void) { };
266  #endif /* CONFIG_PPC_BOOK3S_64 */
267  
268  #endif /* __ASM_PPC64_MCE_H__ */
269