diff options
Diffstat (limited to 'drivers/acpi/acpi_extlog.c')
-rw-r--r-- | drivers/acpi/acpi_extlog.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c index 185334114d71..e61da957f30f 100644 --- a/drivers/acpi/acpi_extlog.c +++ b/drivers/acpi/acpi_extlog.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/mce.h> | 16 | #include <asm/mce.h> |
17 | 17 | ||
18 | #include "apei/apei-internal.h" | 18 | #include "apei/apei-internal.h" |
19 | #include <ras/ras_event.h> | ||
19 | 20 | ||
20 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ | 21 | #define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */ |
21 | 22 | ||
@@ -137,8 +138,12 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
137 | struct mce *mce = (struct mce *)data; | 138 | struct mce *mce = (struct mce *)data; |
138 | int bank = mce->bank; | 139 | int bank = mce->bank; |
139 | int cpu = mce->extcpu; | 140 | int cpu = mce->extcpu; |
140 | struct acpi_generic_status *estatus; | 141 | struct acpi_generic_status *estatus, *tmp; |
141 | int rc; | 142 | struct acpi_generic_data *gdata; |
143 | const uuid_le *fru_id = &NULL_UUID_LE; | ||
144 | char *fru_text = ""; | ||
145 | uuid_le *sec_type; | ||
146 | static u32 err_seq; | ||
142 | 147 | ||
143 | estatus = extlog_elog_entry_check(cpu, bank); | 148 | estatus = extlog_elog_entry_check(cpu, bank); |
144 | if (estatus == NULL) | 149 | if (estatus == NULL) |
@@ -148,7 +153,23 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, | |||
148 | /* clear record status to enable BIOS to update it again */ | 153 | /* clear record status to enable BIOS to update it again */ |
149 | estatus->block_status = 0; | 154 | estatus->block_status = 0; |
150 | 155 | ||
151 | rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu); | 156 | tmp = (struct acpi_generic_status *)elog_buf; |
157 | print_extlog_rcd(NULL, tmp, cpu); | ||
158 | |||
159 | /* log event via trace */ | ||
160 | err_seq++; | ||
161 | gdata = (struct acpi_generic_data *)(tmp + 1); | ||
162 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) | ||
163 | fru_id = (uuid_le *)gdata->fru_id; | ||
164 | if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) | ||
165 | fru_text = gdata->fru_text; | ||
166 | sec_type = (uuid_le *)gdata->section_type; | ||
167 | if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) { | ||
168 | struct cper_sec_mem_err *mem = (void *)(gdata + 1); | ||
169 | if (gdata->error_data_length >= sizeof(*mem)) | ||
170 | trace_extlog_mem_event(mem, err_seq, fru_id, fru_text, | ||
171 | (u8)gdata->error_severity); | ||
172 | } | ||
152 | 173 | ||
153 | return NOTIFY_STOP; | 174 | return NOTIFY_STOP; |
154 | } | 175 | } |