1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __X86_MCE_INTERNAL_H__
3 #define __X86_MCE_INTERNAL_H__
5 #include <linux/device.h>
10 MCE_DEFERRED_SEVERITY
,
11 MCE_UCNA_SEVERITY
= MCE_DEFERRED_SEVERITY
,
20 extern struct blocking_notifier_head x86_mce_decoder_chain
;
23 #define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */
25 /* One object for each MCE bank, shared by all CPUs */
27 u64 ctl
; /* subevents to enable */
28 unsigned char init
; /* initialise bank? */
29 struct device_attribute attr
; /* device attribute */
30 char attrname
[ATTR_LEN
]; /* attribute name */
33 struct mce_evt_llist
{
34 struct llist_node llnode
;
38 void mce_gen_pool_process(struct work_struct
*__unused
);
39 bool mce_gen_pool_empty(void);
40 int mce_gen_pool_add(struct mce
*mce
);
41 int mce_gen_pool_init(void);
42 struct llist_node
*mce_gen_pool_prepare_records(void);
44 extern int (*mce_severity
)(struct mce
*a
, int tolerant
, char **msg
, bool is_excp
);
45 struct dentry
*mce_get_debugfs_dir(void);
47 extern struct mce_bank
*mce_banks
;
48 extern mce_banks_t mce_banks_ce_disabled
;
50 #ifdef CONFIG_X86_MCE_INTEL
51 unsigned long cmci_intel_adjust_timer(unsigned long interval
);
52 bool mce_intel_cmci_poll(void);
53 void mce_intel_hcpu_update(unsigned long cpu
);
54 void cmci_disable_bank(int bank
);
56 # define cmci_intel_adjust_timer mce_adjust_timer_default
57 static inline bool mce_intel_cmci_poll(void) { return false; }
58 static inline void mce_intel_hcpu_update(unsigned long cpu
) { }
59 static inline void cmci_disable_bank(int bank
) { }
62 void mce_timer_kick(unsigned long interval
);
64 #ifdef CONFIG_ACPI_APEI
65 int apei_write_mce(struct mce
*m
);
66 ssize_t
apei_read_mce(struct mce
*m
, u64
*record_id
);
67 int apei_check_mce(void);
68 int apei_clear_mce(u64 record_id
);
70 static inline int apei_write_mce(struct mce
*m
)
74 static inline ssize_t
apei_read_mce(struct mce
*m
, u64
*record_id
)
78 static inline int apei_check_mce(void)
82 static inline int apei_clear_mce(u64 record_id
)
88 void mce_inject_log(struct mce
*m
);
91 * We consider records to be equivalent if bank+status+addr+misc all match.
92 * This is only used when the system is going down because of a fatal error
93 * to avoid cluttering the console log with essentially repeated information.
94 * In normal processing all errors seen are logged.
96 static inline bool mce_cmp(struct mce
*m1
, struct mce
*m2
)
98 return m1
->bank
!= m2
->bank
||
99 m1
->status
!= m2
->status
||
100 m1
->addr
!= m2
->addr
||
101 m1
->misc
!= m2
->misc
;
104 extern struct device_attribute dev_attr_trigger
;
106 #ifdef CONFIG_X86_MCELOG_LEGACY
107 void mce_work_trigger(void);
108 void mce_register_injector_chain(struct notifier_block
*nb
);
109 void mce_unregister_injector_chain(struct notifier_block
*nb
);
111 static inline void mce_work_trigger(void) { }
112 static inline void mce_register_injector_chain(struct notifier_block
*nb
) { }
113 static inline void mce_unregister_injector_chain(struct notifier_block
*nb
) { }
116 extern struct mca_config mca_cfg
;
118 #ifndef CONFIG_X86_64
120 * On 32-bit systems it would be difficult to safely unmap a poison page
121 * from the kernel 1:1 map because there are no non-canonical addresses that
122 * we can use to refer to the address without risking a speculative access.
123 * However, this isn't much of an issue because:
124 * 1) Few unmappable pages are in the 1:1 map. Most are in HIGHMEM which
125 * are only mapped into the kernel as needed
126 * 2) Few people would run a 32-bit kernel on a machine that supports
127 * recoverable errors because they have too much memory to boot 32-bit.
129 static inline void mce_unmap_kpfn(unsigned long pfn
) {}
130 #define mce_unmap_kpfn mce_unmap_kpfn
133 #endif /* __X86_MCE_INTERNAL_H__ */