hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/acpi/apei/hest.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * APEI Hardware Error Souce Table support
34 *
....@@ -12,15 +13,6 @@
1213 *
1314 * Copyright 2009 Intel Corp.
1415 * Author: Huang Ying <ying.huang@intel.com>
15
- *
16
- * This program is free software; you can redistribute it and/or
17
- * modify it under the terms of the GNU General Public License version
18
- * 2 as published by the Free Software Foundation;
19
- *
20
- * This program is distributed in the hope that it will be useful,
21
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
- * GNU General Public License for more details.
2416 */
2517
2618 #include <linux/kernel.h>
....@@ -32,6 +24,7 @@
3224 #include <linux/io.h>
3325 #include <linux/platform_device.h>
3426 #include <acpi/apei.h>
27
+#include <acpi/ghes.h>
3528
3629 #include "apei-internal.h"
3730
....@@ -53,6 +46,7 @@
5346 [ACPI_HEST_TYPE_AER_BRIDGE] = sizeof(struct acpi_hest_aer_bridge),
5447 [ACPI_HEST_TYPE_GENERIC_ERROR] = sizeof(struct acpi_hest_generic),
5548 [ACPI_HEST_TYPE_GENERIC_ERROR_V2] = sizeof(struct acpi_hest_generic_v2),
49
+ [ACPI_HEST_TYPE_IA32_DEFERRED_CHECK] = -1,
5650 };
5751
5852 static int hest_esrc_len(struct acpi_hest_header *hest_hdr)
....@@ -75,6 +69,11 @@
7569 mc = (struct acpi_hest_ia_machine_check *)hest_hdr;
7670 len = sizeof(*mc) + mc->num_hardware_banks *
7771 sizeof(struct acpi_hest_ia_error_bank);
72
+ } else if (hest_type == ACPI_HEST_TYPE_IA32_DEFERRED_CHECK) {
73
+ struct acpi_hest_ia_deferred_check *mc;
74
+ mc = (struct acpi_hest_ia_deferred_check *)hest_hdr;
75
+ len = sizeof(*mc) + mc->num_hardware_banks *
76
+ sizeof(struct acpi_hest_ia_error_bank);
7877 }
7978 BUG_ON(len == -1);
8079
....@@ -93,15 +92,15 @@
9392 for (i = 0; i < hest_tab->error_source_count; i++) {
9493 len = hest_esrc_len(hest_hdr);
9594 if (!len) {
96
- pr_warning(FW_WARN HEST_PFX
97
- "Unknown or unused hardware error source "
98
- "type: %d for hardware error source: %d.\n",
99
- hest_hdr->type, hest_hdr->source_id);
95
+ pr_warn(FW_WARN HEST_PFX
96
+ "Unknown or unused hardware error source "
97
+ "type: %d for hardware error source: %d.\n",
98
+ hest_hdr->type, hest_hdr->source_id);
10099 return -EINVAL;
101100 }
102101 if ((void *)hest_hdr + len >
103102 (void *)hest_tab + hest_tab->header.length) {
104
- pr_warning(FW_BUG HEST_PFX
103
+ pr_warn(FW_BUG HEST_PFX
105104 "Table contents overflow for hardware error source: %d.\n",
106105 hest_hdr->source_id);
107106 return -EINVAL;
....@@ -165,8 +164,8 @@
165164 ghes_dev = ghes_arr->ghes_devs[i];
166165 hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data;
167166 if (hdr->source_id == hest_hdr->source_id) {
168
- pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n",
169
- hdr->source_id);
167
+ pr_warn(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n",
168
+ hdr->source_id);
170169 return -EIO;
171170 }
172171 }
....@@ -203,6 +202,11 @@
203202 rc = apei_hest_parse(hest_parse_ghes, &ghes_arr);
204203 if (rc)
205204 goto err;
205
+
206
+ rc = ghes_estatus_pool_init(ghes_count);
207
+ if (rc)
208
+ goto err;
209
+
206210 out:
207211 kfree(ghes_arr.ghes_devs);
208212 return rc;
....@@ -215,7 +219,7 @@
215219 static int __init setup_hest_disable(char *str)
216220 {
217221 hest_disable = HEST_DISABLED;
218
- return 0;
222
+ return 1;
219223 }
220224
221225 __setup("hest_disable", setup_hest_disable);
....@@ -223,7 +227,7 @@
223227 void __init acpi_hest_init(void)
224228 {
225229 acpi_status status;
226
- int rc = -ENODEV;
230
+ int rc;
227231 unsigned int ghes_count = 0;
228232
229233 if (hest_disable) {
....@@ -239,8 +243,8 @@
239243 } else if (ACPI_FAILURE(status)) {
240244 const char *msg = acpi_format_exception(status);
241245 pr_err(HEST_PFX "Failed to get table, %s\n", msg);
242
- rc = -EINVAL;
243
- goto err;
246
+ hest_disable = HEST_DISABLED;
247
+ return;
244248 }
245249
246250 rc = apei_hest_parse(hest_parse_cmc, NULL);
....@@ -251,7 +255,9 @@
251255 rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
252256 if (rc)
253257 goto err;
254
- rc = hest_ghes_dev_register(ghes_count);
258
+
259
+ if (ghes_count)
260
+ rc = hest_ghes_dev_register(ghes_count);
255261 if (rc)
256262 goto err;
257263 }
....@@ -260,4 +266,5 @@
260266 return;
261267 err:
262268 hest_disable = HEST_DISABLED;
269
+ acpi_put_table((struct acpi_table_header *)hest_tab);
263270 }