Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
262e6811 BP |
2 | #ifndef __X86_MCE_INTERNAL_H__ |
3 | #define __X86_MCE_INTERNAL_H__ | |
4 | ||
3bfaf95c BP |
5 | #undef pr_fmt |
6 | #define pr_fmt(fmt) "mce: " fmt | |
7 | ||
8a25a2fd | 8 | #include <linux/device.h> |
817f32d0 AK |
9 | #include <asm/mce.h> |
10 | ||
11 | enum severity_level { | |
12 | MCE_NO_SEVERITY, | |
e3480271 CY |
13 | MCE_DEFERRED_SEVERITY, |
14 | MCE_UCNA_SEVERITY = MCE_DEFERRED_SEVERITY, | |
ed7290d0 | 15 | MCE_KEEP_SEVERITY, |
817f32d0 | 16 | MCE_SOME_SEVERITY, |
ed7290d0 | 17 | MCE_AO_SEVERITY, |
817f32d0 | 18 | MCE_UC_SEVERITY, |
ed7290d0 | 19 | MCE_AR_SEVERITY, |
817f32d0 AK |
20 | MCE_PANIC_SEVERITY, |
21 | }; | |
22 | ||
0dc9c639 | 23 | extern struct blocking_notifier_head x86_mce_decoder_chain; |
648ed940 | 24 | |
3f2f0680 | 25 | #define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */ |
cebe1820 | 26 | |
648ed940 CG |
27 | struct mce_evt_llist { |
28 | struct llist_node llnode; | |
29 | struct mce mce; | |
30 | }; | |
31 | ||
cff4c039 | 32 | void mce_gen_pool_process(struct work_struct *__unused); |
648ed940 CG |
33 | bool mce_gen_pool_empty(void); |
34 | int mce_gen_pool_add(struct mce *mce); | |
35 | int mce_gen_pool_init(void); | |
5541c93c | 36 | struct llist_node *mce_gen_pool_prepare_records(void); |
648ed940 | 37 | |
43eaa2a1 | 38 | extern int (*mce_severity)(struct mce *a, int tolerant, char **msg, bool is_excp); |
5be9ed25 | 39 | struct dentry *mce_get_debugfs_dir(void); |
ed7290d0 | 40 | |
c3d1fb56 | 41 | extern mce_banks_t mce_banks_ce_disabled; |
cebe1820 | 42 | |
55babd8f | 43 | #ifdef CONFIG_X86_MCE_INTEL |
3f2f0680 BP |
44 | unsigned long cmci_intel_adjust_timer(unsigned long interval); |
45 | bool mce_intel_cmci_poll(void); | |
55babd8f | 46 | void mce_intel_hcpu_update(unsigned long cpu); |
c3d1fb56 | 47 | void cmci_disable_bank(int bank); |
5a3d56a0 | 48 | void intel_init_cmci(void); |
70f0c230 TW |
49 | void intel_init_lmce(void); |
50 | void intel_clear_lmce(void); | |
2976908e | 51 | bool intel_filter_mce(struct mce *m); |
55babd8f | 52 | #else |
3f2f0680 BP |
53 | # define cmci_intel_adjust_timer mce_adjust_timer_default |
54 | static inline bool mce_intel_cmci_poll(void) { return false; } | |
55babd8f | 55 | static inline void mce_intel_hcpu_update(unsigned long cpu) { } |
c3d1fb56 | 56 | static inline void cmci_disable_bank(int bank) { } |
5a3d56a0 | 57 | static inline void intel_init_cmci(void) { } |
70f0c230 TW |
58 | static inline void intel_init_lmce(void) { } |
59 | static inline void intel_clear_lmce(void) { } | |
2976908e | 60 | static inline bool intel_filter_mce(struct mce *m) { return false; }; |
55babd8f CG |
61 | #endif |
62 | ||
63 | void mce_timer_kick(unsigned long interval); | |
64 | ||
482908b4 HY |
65 | #ifdef CONFIG_ACPI_APEI |
66 | int apei_write_mce(struct mce *m); | |
67 | ssize_t apei_read_mce(struct mce *m, u64 *record_id); | |
68 | int apei_check_mce(void); | |
69 | int apei_clear_mce(u64 record_id); | |
70 | #else | |
71 | static inline int apei_write_mce(struct mce *m) | |
72 | { | |
73 | return -EINVAL; | |
74 | } | |
75 | static inline ssize_t apei_read_mce(struct mce *m, u64 *record_id) | |
76 | { | |
77 | return 0; | |
78 | } | |
79 | static inline int apei_check_mce(void) | |
80 | { | |
81 | return 0; | |
82 | } | |
83 | static inline int apei_clear_mce(u64 record_id) | |
84 | { | |
85 | return -EINVAL; | |
86 | } | |
87 | #endif | |
a79da384 | 88 | |
5541c93c TL |
89 | /* |
90 | * We consider records to be equivalent if bank+status+addr+misc all match. | |
91 | * This is only used when the system is going down because of a fatal error | |
92 | * to avoid cluttering the console log with essentially repeated information. | |
93 | * In normal processing all errors seen are logged. | |
94 | */ | |
95 | static inline bool mce_cmp(struct mce *m1, struct mce *m2) | |
96 | { | |
97 | return m1->bank != m2->bank || | |
98 | m1->status != m2->status || | |
99 | m1->addr != m2->addr || | |
100 | m1->misc != m2->misc; | |
101 | } | |
5de97c9f TL |
102 | |
103 | extern struct device_attribute dev_attr_trigger; | |
104 | ||
105 | #ifdef CONFIG_X86_MCELOG_LEGACY | |
fbe9ff9e BP |
106 | void mce_work_trigger(void); |
107 | void mce_register_injector_chain(struct notifier_block *nb); | |
108 | void mce_unregister_injector_chain(struct notifier_block *nb); | |
5de97c9f TL |
109 | #else |
110 | static inline void mce_work_trigger(void) { } | |
fbe9ff9e BP |
111 | static inline void mce_register_injector_chain(struct notifier_block *nb) { } |
112 | static inline void mce_unregister_injector_chain(struct notifier_block *nb) { } | |
5de97c9f | 113 | #endif |
262e6811 | 114 | |
a189c032 BP |
115 | struct mca_config { |
116 | bool dont_log_ce; | |
117 | bool cmci_disabled; | |
a189c032 | 118 | bool ignore_ce; |
09933946 BP |
119 | |
120 | __u64 lmce_disabled : 1, | |
121 | disabled : 1, | |
122 | ser : 1, | |
123 | recovery : 1, | |
124 | bios_cmci_threshold : 1, | |
125 | __reserved : 59; | |
126 | ||
a189c032 BP |
127 | s8 bootlog; |
128 | int tolerant; | |
129 | int monarch_timeout; | |
130 | int panic_timeout; | |
131 | u32 rip_msr; | |
132 | }; | |
133 | ||
134 | extern struct mca_config mca_cfg; | |
c7d314f3 | 135 | DECLARE_PER_CPU_READ_MOSTLY(unsigned int, mce_num_banks); |
a189c032 BP |
136 | |
137 | struct mce_vendor_flags { | |
138 | /* | |
139 | * Indicates that overflow conditions are not fatal, when set. | |
140 | */ | |
141 | __u64 overflow_recov : 1, | |
142 | ||
143 | /* | |
144 | * (AMD) SUCCOR stands for S/W UnCorrectable error COntainment and | |
145 | * Recovery. It indicates support for data poisoning in HW and deferred | |
146 | * error interrupts. | |
147 | */ | |
148 | succor : 1, | |
149 | ||
150 | /* | |
151 | * (AMD) SMCA: This bit indicates support for Scalable MCA which expands | |
152 | * the register space for each MCA bank and also increases number of | |
153 | * banks. Also, to accommodate the new banks and registers, the MCA | |
154 | * register space is moved to a new MSR range. | |
155 | */ | |
156 | smca : 1, | |
157 | ||
158 | __reserved_0 : 61; | |
159 | }; | |
160 | ||
161 | extern struct mce_vendor_flags mce_flags; | |
162 | ||
163 | struct mca_msr_regs { | |
164 | u32 (*ctl) (int bank); | |
165 | u32 (*status) (int bank); | |
166 | u32 (*addr) (int bank); | |
167 | u32 (*misc) (int bank); | |
168 | }; | |
169 | ||
170 | extern struct mca_msr_regs msr_ops; | |
171 | ||
45d4b7b9 YG |
172 | /* Decide whether to add MCE record to MCE event pool or filter it out. */ |
173 | extern bool filter_mce(struct mce *m); | |
174 | ||
71a84402 YG |
175 | #ifdef CONFIG_X86_MCE_AMD |
176 | extern bool amd_filter_mce(struct mce *m); | |
177 | #else | |
178 | static inline bool amd_filter_mce(struct mce *m) { return false; }; | |
179 | #endif | |
180 | ||
262e6811 | 181 | #endif /* __X86_MCE_INTERNAL_H__ */ |