hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/acpi/acpi_extlog.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Extended Error Log driver
34 *
45 * Copyright (C) 2013 Intel Corp.
56 * Author: Chen, Gong <gong.chen@intel.com>
6
- *
7
- * This file is licensed under GPLv2.
87 */
98
109 #include <linux/module.h>
....@@ -13,6 +12,7 @@
1312 #include <linux/ratelimit.h>
1413 #include <linux/edac.h>
1514 #include <linux/ras.h>
15
+#include <acpi/ghes.h>
1616 #include <asm/cpu.h>
1717 #include <asm/mce.h>
1818
....@@ -42,8 +42,6 @@
4242 u32 entries; /* Valid L1 Directory entries per logical processor */
4343 u8 rev1[12];
4444 };
45
-
46
-static int old_edac_report_status;
4745
4846 static u8 extlog_dsm_uuid[] __initdata = "663E35AF-CC10-41A4-88EA-5470AF055295";
4947
....@@ -141,13 +139,13 @@
141139 int cpu = mce->extcpu;
142140 struct acpi_hest_generic_status *estatus, *tmp;
143141 struct acpi_hest_generic_data *gdata;
144
- const guid_t *fru_id = &guid_null;
145
- char *fru_text = "";
142
+ const guid_t *fru_id;
143
+ char *fru_text;
146144 guid_t *sec_type;
147145 static u32 err_seq;
148146
149147 estatus = extlog_elog_entry_check(cpu, bank);
150
- if (estatus == NULL)
148
+ if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC))
151149 return NOTIFY_DONE;
152150
153151 memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
....@@ -163,21 +161,28 @@
163161
164162 /* log event via trace */
165163 err_seq++;
166
- gdata = (struct acpi_hest_generic_data *)(tmp + 1);
167
- if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
168
- fru_id = (guid_t *)gdata->fru_id;
169
- if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
170
- fru_text = gdata->fru_text;
171
- sec_type = (guid_t *)gdata->section_type;
172
- if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
173
- struct cper_sec_mem_err *mem = (void *)(gdata + 1);
174
- if (gdata->error_data_length >= sizeof(*mem))
175
- trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
176
- (u8)gdata->error_severity);
164
+ apei_estatus_for_each_section(tmp, gdata) {
165
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
166
+ fru_id = (guid_t *)gdata->fru_id;
167
+ else
168
+ fru_id = &guid_null;
169
+ if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
170
+ fru_text = gdata->fru_text;
171
+ else
172
+ fru_text = "";
173
+ sec_type = (guid_t *)gdata->section_type;
174
+ if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
175
+ struct cper_sec_mem_err *mem = (void *)(gdata + 1);
176
+
177
+ if (gdata->error_data_length >= sizeof(*mem))
178
+ trace_extlog_mem_event(mem, err_seq, fru_id, fru_text,
179
+ (u8)gdata->error_severity);
180
+ }
177181 }
178182
179183 out:
180
- return NOTIFY_STOP;
184
+ mce->kflags |= MCE_HANDLED_EXTLOG;
185
+ return NOTIFY_OK;
181186 }
182187
183188 static bool __init extlog_get_l1addr(void)
....@@ -229,11 +234,6 @@
229234 !extlog_get_l1addr())
230235 return -ENODEV;
231236
232
- if (edac_get_report_status() == EDAC_REPORTING_FORCE) {
233
- pr_warn("Not loading eMCA, error reporting force-enabled through EDAC.\n");
234
- return -EPERM;
235
- }
236
-
237237 rc = -EINVAL;
238238 /* get L1 header to fetch necessary information */
239239 l1_hdr_size = sizeof(struct extlog_l1_head);
....@@ -281,12 +281,6 @@
281281 if (elog_buf == NULL)
282282 goto err_release_elog;
283283
284
- /*
285
- * eMCA event report method has higher priority than EDAC method,
286
- * unless EDAC event report method is mandatory.
287
- */
288
- old_edac_report_status = edac_get_report_status();
289
- edac_set_report_status(EDAC_REPORTING_DISABLED);
290284 mce_register_decode_chain(&extlog_mce_dec);
291285 /* enable OS to be involved to take over management from BIOS */
292286 ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN;
....@@ -308,7 +302,6 @@
308302
309303 static void __exit extlog_exit(void)
310304 {
311
- edac_set_report_status(old_edac_report_status);
312305 mce_unregister_decode_chain(&extlog_mce_dec);
313306 ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
314307 if (extlog_l1_addr)