The Corrected Machine Check structure (CMC) in HEST has a flag which can be set by the firmware to indicate to the OS that it prefers to process the corrected error events first. In this scenario, the OS is expected to not monitor for corrected errors (through CMCI/polling). Instead, the firmware notifies the OS on corrected error events through GHES. Linux already has support for GHES. This patch adds support for parsing CMC structure and to disable CMCI/polling if the firmware first flag is set. Further, the list of machine check bank structures at the end of CMC is used to determine which MCA banks function in FF mode, so that we continue to monitor error events on the other banks. Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Acked-by: Borislav Petkov <bp@suse.de> Signed-off-by: Tony Luck <tony.luck@intel.com>
66 lines
1.6 KiB
C
66 lines
1.6 KiB
C
#include <linux/device.h>
|
|
#include <asm/mce.h>
|
|
|
|
enum severity_level {
|
|
MCE_NO_SEVERITY,
|
|
MCE_KEEP_SEVERITY,
|
|
MCE_SOME_SEVERITY,
|
|
MCE_AO_SEVERITY,
|
|
MCE_UC_SEVERITY,
|
|
MCE_AR_SEVERITY,
|
|
MCE_PANIC_SEVERITY,
|
|
};
|
|
|
|
#define ATTR_LEN 16
|
|
|
|
/* One object for each MCE bank, shared by all CPUs */
|
|
struct mce_bank {
|
|
u64 ctl; /* subevents to enable */
|
|
unsigned char init; /* initialise bank? */
|
|
struct device_attribute attr; /* device attribute */
|
|
char attrname[ATTR_LEN]; /* attribute name */
|
|
};
|
|
|
|
int mce_severity(struct mce *a, int tolerant, char **msg);
|
|
struct dentry *mce_get_debugfs_dir(void);
|
|
|
|
extern struct mce_bank *mce_banks;
|
|
extern mce_banks_t mce_banks_ce_disabled;
|
|
|
|
#ifdef CONFIG_X86_MCE_INTEL
|
|
unsigned long mce_intel_adjust_timer(unsigned long interval);
|
|
void mce_intel_cmci_poll(void);
|
|
void mce_intel_hcpu_update(unsigned long cpu);
|
|
void cmci_disable_bank(int bank);
|
|
#else
|
|
# define mce_intel_adjust_timer mce_adjust_timer_default
|
|
static inline void mce_intel_cmci_poll(void) { }
|
|
static inline void mce_intel_hcpu_update(unsigned long cpu) { }
|
|
static inline void cmci_disable_bank(int bank) { }
|
|
#endif
|
|
|
|
void mce_timer_kick(unsigned long interval);
|
|
|
|
#ifdef CONFIG_ACPI_APEI
|
|
int apei_write_mce(struct mce *m);
|
|
ssize_t apei_read_mce(struct mce *m, u64 *record_id);
|
|
int apei_check_mce(void);
|
|
int apei_clear_mce(u64 record_id);
|
|
#else
|
|
static inline int apei_write_mce(struct mce *m)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline ssize_t apei_read_mce(struct mce *m, u64 *record_id)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int apei_check_mce(void)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int apei_clear_mce(u64 record_id)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
#endif
|