aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 21:16:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 21:16:44 -0500
commit340286cd4e9aff841affb897f6d2535ed27605cf (patch)
tree6eb32c966f59bd2958b9d7e83b1199deddee6d5b /drivers/acpi
parent339a4b72c83dc7d8b29f43f7417add791e201ad3 (diff)
parent9ebddac7ea2a1f4b4ce3335a78312a58dfaadb4d (diff)
Merge branch 'x86-mce-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 RAS changes from Ingo Molnar: "The biggest change adds support for Intel 'CPER' (UEFI Common Platform Error Record) error logging, which builds upon an enhanced error logging mechanism available on Xeon processors. Full description is here: http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html This change provides a module (and support code) to check for an extended error log and prints extra details about the error on the console" * 'x86-mce-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: ACPI, x86: Fix extended error log driver to depend on CONFIG_X86_LOCAL_APIC dmi: Avoid unaligned memory access in save_mem_devices() Move cper.c from drivers/acpi/apei to drivers/firmware/efi EDAC, GHES: Update ghes error record info ACPI, APEI, CPER: Cleanup CPER memory error output format ACPI, APEI, CPER: Enhance memory reporting capability ACPI, APEI, CPER: Add UEFI 2.4 support for memory error DMI: Parse memory device (type 17) in SMBIOS ACPI, x86: Extended error log driver for x86 platform bitops: Introduce a more generic BITMASK macro ACPI, CPER: Update cper info ACPI, APEI, CPER: Fix status check during error printing
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig21
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpi_extlog.c327
-rw-r--r--drivers/acpi/apei/Kconfig2
-rw-r--r--drivers/acpi/apei/Makefile2
-rw-r--r--drivers/acpi/apei/apei-internal.h12
-rw-r--r--drivers/acpi/apei/cper.c402
-rw-r--r--drivers/acpi/apei/ghes.c58
-rw-r--r--drivers/acpi/bus.c3
9 files changed, 390 insertions, 439 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 6efe2ac6902f..e11faae81ed9 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -372,4 +372,25 @@ config ACPI_BGRT
372 372
373source "drivers/acpi/apei/Kconfig" 373source "drivers/acpi/apei/Kconfig"
374 374
375config ACPI_EXTLOG
376 tristate "Extended Error Log support"
377 depends on X86_MCE && X86_LOCAL_APIC
378 select EFI
379 select UEFI_CPER
380 default n
381 help
382 Certain usages such as Predictive Failure Analysis (PFA) require
383 more information about the error than what can be described in
384 processor machine check banks. Most server processors log
385 additional information about the error in processor uncore
386 registers. Since the addresses and layout of these registers vary
387 widely from one processor to another, system software cannot
388 readily make use of them. To complicate matters further, some of
389 the additional error information cannot be constructed without
390 detailed knowledge about platform topology.
391
392 Enhanced MCA Logging allows firmware to provide additional error
393 information to system software, synchronous with MCE or CMCI. This
394 driver adds support for that functionality.
395
375endif # ACPI 396endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index cdaf68b58b00..bce34afadcd0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -82,3 +82,5 @@ processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
82obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o 82obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
83 83
84obj-$(CONFIG_ACPI_APEI) += apei/ 84obj-$(CONFIG_ACPI_APEI) += apei/
85
86obj-$(CONFIG_ACPI_EXTLOG) += acpi_extlog.o
diff --git a/drivers/acpi/acpi_extlog.c b/drivers/acpi/acpi_extlog.c
new file mode 100644
index 000000000000..a6869e110ce5
--- /dev/null
+++ b/drivers/acpi/acpi_extlog.c
@@ -0,0 +1,327 @@
1/*
2 * Extended Error Log driver
3 *
4 * Copyright (C) 2013 Intel Corp.
5 * Author: Chen, Gong <gong.chen@intel.com>
6 *
7 * This file is licensed under GPLv2.
8 */
9
10#include <linux/module.h>
11#include <linux/acpi.h>
12#include <acpi/acpi_bus.h>
13#include <linux/cper.h>
14#include <linux/ratelimit.h>
15#include <asm/cpu.h>
16#include <asm/mce.h>
17
18#include "apei/apei-internal.h"
19
20#define EXT_ELOG_ENTRY_MASK GENMASK_ULL(51, 0) /* elog entry address mask */
21
22#define EXTLOG_DSM_REV 0x0
23#define EXTLOG_FN_QUERY 0x0
24#define EXTLOG_FN_ADDR 0x1
25
26#define FLAG_OS_OPTIN BIT(0)
27#define EXTLOG_QUERY_L1_EXIST BIT(1)
28#define ELOG_ENTRY_VALID (1ULL<<63)
29#define ELOG_ENTRY_LEN 0x1000
30
31#define EMCA_BUG \
32 "Can not request iomem region <0x%016llx-0x%016llx> - eMCA disabled\n"
33
34struct extlog_l1_head {
35 u32 ver; /* Header Version */
36 u32 hdr_len; /* Header Length */
37 u64 total_len; /* entire L1 Directory length including this header */
38 u64 elog_base; /* MCA Error Log Directory base address */
39 u64 elog_len; /* MCA Error Log Directory length */
40 u32 flags; /* bit 0 - OS/VMM Opt-in */
41 u8 rev0[12];
42 u32 entries; /* Valid L1 Directory entries per logical processor */
43 u8 rev1[12];
44};
45
46static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295";
47
48/* L1 table related physical address */
49static u64 elog_base;
50static size_t elog_size;
51static u64 l1_dirbase;
52static size_t l1_size;
53
54/* L1 table related virtual address */
55static void __iomem *extlog_l1_addr;
56static void __iomem *elog_addr;
57
58static void *elog_buf;
59
60static u64 *l1_entry_base;
61static u32 l1_percpu_entry;
62
63#define ELOG_IDX(cpu, bank) \
64 (cpu_physical_id(cpu) * l1_percpu_entry + (bank))
65
66#define ELOG_ENTRY_DATA(idx) \
67 (*(l1_entry_base + (idx)))
68
69#define ELOG_ENTRY_ADDR(phyaddr) \
70 (phyaddr - elog_base + (u8 *)elog_addr)
71
72static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
73{
74 int idx;
75 u64 data;
76 struct acpi_generic_status *estatus;
77
78 WARN_ON(cpu < 0);
79 idx = ELOG_IDX(cpu, bank);
80 data = ELOG_ENTRY_DATA(idx);
81 if ((data & ELOG_ENTRY_VALID) == 0)
82 return NULL;
83
84 data &= EXT_ELOG_ENTRY_MASK;
85 estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data);
86
87 /* if no valid data in elog entry, just return */
88 if (estatus->block_status == 0)
89 return NULL;
90
91 return estatus;
92}
93
94static void __print_extlog_rcd(const char *pfx,
95 struct acpi_generic_status *estatus, int cpu)
96{
97 static atomic_t seqno;
98 unsigned int curr_seqno;
99 char pfx_seq[64];
100
101 if (!pfx) {
102 if (estatus->error_severity <= CPER_SEV_CORRECTED)
103 pfx = KERN_INFO;
104 else
105 pfx = KERN_ERR;
106 }
107 curr_seqno = atomic_inc_return(&seqno);
108 snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}", pfx, curr_seqno);
109 printk("%s""Hardware error detected on CPU%d\n", pfx_seq, cpu);
110 cper_estatus_print(pfx_seq, estatus);
111}
112
113static int print_extlog_rcd(const char *pfx,
114 struct acpi_generic_status *estatus, int cpu)
115{
116 /* Not more than 2 messages every 5 seconds */
117 static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
118 static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2);
119 struct ratelimit_state *ratelimit;
120
121 if (estatus->error_severity == CPER_SEV_CORRECTED ||
122 (estatus->error_severity == CPER_SEV_INFORMATIONAL))
123 ratelimit = &ratelimit_corrected;
124 else
125 ratelimit = &ratelimit_uncorrected;
126 if (__ratelimit(ratelimit)) {
127 __print_extlog_rcd(pfx, estatus, cpu);
128 return 0;
129 }
130
131 return 1;
132}
133
134static int extlog_print(struct notifier_block *nb, unsigned long val,
135 void *data)
136{
137 struct mce *mce = (struct mce *)data;
138 int bank = mce->bank;
139 int cpu = mce->extcpu;
140 struct acpi_generic_status *estatus;
141 int rc;
142
143 estatus = extlog_elog_entry_check(cpu, bank);
144 if (estatus == NULL)
145 return NOTIFY_DONE;
146
147 memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN);
148 /* clear record status to enable BIOS to update it again */
149 estatus->block_status = 0;
150
151 rc = print_extlog_rcd(NULL, (struct acpi_generic_status *)elog_buf, cpu);
152
153 return NOTIFY_DONE;
154}
155
156static int extlog_get_dsm(acpi_handle handle, int rev, int func, u64 *ret)
157{
158 struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
159 struct acpi_object_list input;
160 union acpi_object params[4], *obj;
161 u8 uuid[16];
162 int i;
163
164 acpi_str_to_uuid(extlog_dsm_uuid, uuid);
165 input.count = 4;
166 input.pointer = params;
167 params[0].type = ACPI_TYPE_BUFFER;
168 params[0].buffer.length = 16;
169 params[0].buffer.pointer = uuid;
170 params[1].type = ACPI_TYPE_INTEGER;
171 params[1].integer.value = rev;
172 params[2].type = ACPI_TYPE_INTEGER;
173 params[2].integer.value = func;
174 params[3].type = ACPI_TYPE_PACKAGE;
175 params[3].package.count = 0;
176 params[3].package.elements = NULL;
177
178 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DSM", &input, &buf)))
179 return -1;
180
181 *ret = 0;
182 obj = (union acpi_object *)buf.pointer;
183 if (obj->type == ACPI_TYPE_INTEGER) {
184 *ret = obj->integer.value;
185 } else if (obj->type == ACPI_TYPE_BUFFER) {
186 if (obj->buffer.length <= 8) {
187 for (i = 0; i < obj->buffer.length; i++)
188 *ret |= (obj->buffer.pointer[i] << (i * 8));
189 }
190 }
191 kfree(buf.pointer);
192
193 return 0;
194}
195
196static bool extlog_get_l1addr(void)
197{
198 acpi_handle handle;
199 u64 ret;
200
201 if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
202 return false;
203
204 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_QUERY, &ret) ||
205 !(ret & EXTLOG_QUERY_L1_EXIST))
206 return false;
207
208 if (extlog_get_dsm(handle, EXTLOG_DSM_REV, EXTLOG_FN_ADDR, &ret))
209 return false;
210
211 l1_dirbase = ret;
212 /* Spec says L1 directory must be 4K aligned, bail out if it isn't */
213 if (l1_dirbase & ((1 << 12) - 1)) {
214 pr_warn(FW_BUG "L1 Directory is invalid at physical %llx\n",
215 l1_dirbase);
216 return false;
217 }
218
219 return true;
220}
221static struct notifier_block extlog_mce_dec = {
222 .notifier_call = extlog_print,
223};
224
225static int __init extlog_init(void)
226{
227 struct extlog_l1_head *l1_head;
228 void __iomem *extlog_l1_hdr;
229 size_t l1_hdr_size;
230 struct resource *r;
231 u64 cap;
232 int rc;
233
234 rc = -ENODEV;
235
236 rdmsrl(MSR_IA32_MCG_CAP, cap);
237 if (!(cap & MCG_ELOG_P))
238 return rc;
239
240 if (!extlog_get_l1addr())
241 return rc;
242
243 rc = -EINVAL;
244 /* get L1 header to fetch necessary information */
245 l1_hdr_size = sizeof(struct extlog_l1_head);
246 r = request_mem_region(l1_dirbase, l1_hdr_size, "L1 DIR HDR");
247 if (!r) {
248 pr_warn(FW_BUG EMCA_BUG,
249 (unsigned long long)l1_dirbase,
250 (unsigned long long)l1_dirbase + l1_hdr_size);
251 goto err;
252 }
253
254 extlog_l1_hdr = acpi_os_map_memory(l1_dirbase, l1_hdr_size);
255 l1_head = (struct extlog_l1_head *)extlog_l1_hdr;
256 l1_size = l1_head->total_len;
257 l1_percpu_entry = l1_head->entries;
258 elog_base = l1_head->elog_base;
259 elog_size = l1_head->elog_len;
260 acpi_os_unmap_memory(extlog_l1_hdr, l1_hdr_size);
261 release_mem_region(l1_dirbase, l1_hdr_size);
262
263 /* remap L1 header again based on completed information */
264 r = request_mem_region(l1_dirbase, l1_size, "L1 Table");
265 if (!r) {
266 pr_warn(FW_BUG EMCA_BUG,
267 (unsigned long long)l1_dirbase,
268 (unsigned long long)l1_dirbase + l1_size);
269 goto err;
270 }
271 extlog_l1_addr = acpi_os_map_memory(l1_dirbase, l1_size);
272 l1_entry_base = (u64 *)((u8 *)extlog_l1_addr + l1_hdr_size);
273
274 /* remap elog table */
275 r = request_mem_region(elog_base, elog_size, "Elog Table");
276 if (!r) {
277 pr_warn(FW_BUG EMCA_BUG,
278 (unsigned long long)elog_base,
279 (unsigned long long)elog_base + elog_size);
280 goto err_release_l1_dir;
281 }
282 elog_addr = acpi_os_map_memory(elog_base, elog_size);
283
284 rc = -ENOMEM;
285 /* allocate buffer to save elog record */
286 elog_buf = kmalloc(ELOG_ENTRY_LEN, GFP_KERNEL);
287 if (elog_buf == NULL)
288 goto err_release_elog;
289
290 mce_register_decode_chain(&extlog_mce_dec);
291 /* enable OS to be involved to take over management from BIOS */
292 ((struct extlog_l1_head *)extlog_l1_addr)->flags |= FLAG_OS_OPTIN;
293
294 return 0;
295
296err_release_elog:
297 if (elog_addr)
298 acpi_os_unmap_memory(elog_addr, elog_size);
299 release_mem_region(elog_base, elog_size);
300err_release_l1_dir:
301 if (extlog_l1_addr)
302 acpi_os_unmap_memory(extlog_l1_addr, l1_size);
303 release_mem_region(l1_dirbase, l1_size);
304err:
305 pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n");
306 return rc;
307}
308
309static void __exit extlog_exit(void)
310{
311 mce_unregister_decode_chain(&extlog_mce_dec);
312 ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN;
313 if (extlog_l1_addr)
314 acpi_os_unmap_memory(extlog_l1_addr, l1_size);
315 if (elog_addr)
316 acpi_os_unmap_memory(elog_addr, elog_size);
317 release_mem_region(elog_base, elog_size);
318 release_mem_region(l1_dirbase, l1_size);
319 kfree(elog_buf);
320}
321
322module_init(extlog_init);
323module_exit(extlog_exit);
324
325MODULE_AUTHOR("Chen, Gong <gong.chen@intel.com>");
326MODULE_DESCRIPTION("Extended MCA Error Log Driver");
327MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index f0c1ce95a0ec..786294bb682c 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -2,6 +2,8 @@ config ACPI_APEI
2 bool "ACPI Platform Error Interface (APEI)" 2 bool "ACPI Platform Error Interface (APEI)"
3 select MISC_FILESYSTEMS 3 select MISC_FILESYSTEMS
4 select PSTORE 4 select PSTORE
5 select EFI
6 select UEFI_CPER
5 depends on X86 7 depends on X86
6 help 8 help
7 APEI allows to report errors (for example from the chipset) 9 APEI allows to report errors (for example from the chipset)
diff --git a/drivers/acpi/apei/Makefile b/drivers/acpi/apei/Makefile
index d1d1bc0a4ee1..5d575a955940 100644
--- a/drivers/acpi/apei/Makefile
+++ b/drivers/acpi/apei/Makefile
@@ -3,4 +3,4 @@ obj-$(CONFIG_ACPI_APEI_GHES) += ghes.o
3obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o 3obj-$(CONFIG_ACPI_APEI_EINJ) += einj.o
4obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o 4obj-$(CONFIG_ACPI_APEI_ERST_DEBUG) += erst-dbg.o
5 5
6apei-y := apei-base.o hest.o cper.o erst.o 6apei-y := apei-base.o hest.o erst.o
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index f220d642136e..21ba34a73883 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -122,11 +122,11 @@ struct dentry;
122struct dentry *apei_get_debugfs_dir(void); 122struct dentry *apei_get_debugfs_dir(void);
123 123
124#define apei_estatus_for_each_section(estatus, section) \ 124#define apei_estatus_for_each_section(estatus, section) \
125 for (section = (struct acpi_hest_generic_data *)(estatus + 1); \ 125 for (section = (struct acpi_generic_data *)(estatus + 1); \
126 (void *)section - (void *)estatus < estatus->data_length; \ 126 (void *)section - (void *)estatus < estatus->data_length; \
127 section = (void *)(section+1) + section->error_data_length) 127 section = (void *)(section+1) + section->error_data_length)
128 128
129static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) 129static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
130{ 130{
131 if (estatus->raw_data_length) 131 if (estatus->raw_data_length)
132 return estatus->raw_data_offset + \ 132 return estatus->raw_data_offset + \
@@ -135,10 +135,10 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus)
135 return sizeof(*estatus) + estatus->data_length; 135 return sizeof(*estatus) + estatus->data_length;
136} 136}
137 137
138void apei_estatus_print(const char *pfx, 138void cper_estatus_print(const char *pfx,
139 const struct acpi_hest_generic_status *estatus); 139 const struct acpi_generic_status *estatus);
140int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); 140int cper_estatus_check_header(const struct acpi_generic_status *estatus);
141int apei_estatus_check(const struct acpi_hest_generic_status *estatus); 141int cper_estatus_check(const struct acpi_generic_status *estatus);
142 142
143int apei_osc_setup(void); 143int apei_osc_setup(void);
144#endif 144#endif
diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c
deleted file mode 100644
index 33dc6a004802..000000000000
--- a/drivers/acpi/apei/cper.c
+++ /dev/null
@@ -1,402 +0,0 @@
1/*
2 * UEFI Common Platform Error Record (CPER) support
3 *
4 * Copyright (C) 2010, Intel Corp.
5 * Author: Huang Ying <ying.huang@intel.com>
6 *
7 * CPER is the format used to describe platform hardware error by
8 * various APEI tables, such as ERST, BERT and HEST etc.
9 *
10 * For more information about CPER, please refer to Appendix N of UEFI
11 * Specification version 2.3.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License version
15 * 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/time.h>
30#include <linux/cper.h>
31#include <linux/acpi.h>
32#include <linux/pci.h>
33#include <linux/aer.h>
34
35/*
36 * CPER record ID need to be unique even after reboot, because record
37 * ID is used as index for ERST storage, while CPER records from
38 * multiple boot may co-exist in ERST.
39 */
40u64 cper_next_record_id(void)
41{
42 static atomic64_t seq;
43
44 if (!atomic64_read(&seq))
45 atomic64_set(&seq, ((u64)get_seconds()) << 32);
46
47 return atomic64_inc_return(&seq);
48}
49EXPORT_SYMBOL_GPL(cper_next_record_id);
50
51static const char *cper_severity_strs[] = {
52 "recoverable",
53 "fatal",
54 "corrected",
55 "info",
56};
57
58static const char *cper_severity_str(unsigned int severity)
59{
60 return severity < ARRAY_SIZE(cper_severity_strs) ?
61 cper_severity_strs[severity] : "unknown";
62}
63
64/*
65 * cper_print_bits - print strings for set bits
66 * @pfx: prefix for each line, including log level and prefix string
67 * @bits: bit mask
68 * @strs: string array, indexed by bit position
69 * @strs_size: size of the string array: @strs
70 *
71 * For each set bit in @bits, print the corresponding string in @strs.
72 * If the output length is longer than 80, multiple line will be
73 * printed, with @pfx is printed at the beginning of each line.
74 */
75void cper_print_bits(const char *pfx, unsigned int bits,
76 const char *strs[], unsigned int strs_size)
77{
78 int i, len = 0;
79 const char *str;
80 char buf[84];
81
82 for (i = 0; i < strs_size; i++) {
83 if (!(bits & (1U << i)))
84 continue;
85 str = strs[i];
86 if (!str)
87 continue;
88 if (len && len + strlen(str) + 2 > 80) {
89 printk("%s\n", buf);
90 len = 0;
91 }
92 if (!len)
93 len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
94 else
95 len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
96 }
97 if (len)
98 printk("%s\n", buf);
99}
100
101static const char *cper_proc_type_strs[] = {
102 "IA32/X64",
103 "IA64",
104};
105
106static const char *cper_proc_isa_strs[] = {
107 "IA32",
108 "IA64",
109 "X64",
110};
111
112static const char *cper_proc_error_type_strs[] = {
113 "cache error",
114 "TLB error",
115 "bus error",
116 "micro-architectural error",
117};
118
119static const char *cper_proc_op_strs[] = {
120 "unknown or generic",
121 "data read",
122 "data write",
123 "instruction execution",
124};
125
126static const char *cper_proc_flag_strs[] = {
127 "restartable",
128 "precise IP",
129 "overflow",
130 "corrected",
131};
132
133static void cper_print_proc_generic(const char *pfx,
134 const struct cper_sec_proc_generic *proc)
135{
136 if (proc->validation_bits & CPER_PROC_VALID_TYPE)
137 printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
138 proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
139 cper_proc_type_strs[proc->proc_type] : "unknown");
140 if (proc->validation_bits & CPER_PROC_VALID_ISA)
141 printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
142 proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
143 cper_proc_isa_strs[proc->proc_isa] : "unknown");
144 if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
145 printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
146 cper_print_bits(pfx, proc->proc_error_type,
147 cper_proc_error_type_strs,
148 ARRAY_SIZE(cper_proc_error_type_strs));
149 }
150 if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
151 printk("%s""operation: %d, %s\n", pfx, proc->operation,
152 proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
153 cper_proc_op_strs[proc->operation] : "unknown");
154 if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
155 printk("%s""flags: 0x%02x\n", pfx, proc->flags);
156 cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
157 ARRAY_SIZE(cper_proc_flag_strs));
158 }
159 if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
160 printk("%s""level: %d\n", pfx, proc->level);
161 if (proc->validation_bits & CPER_PROC_VALID_VERSION)
162 printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version);
163 if (proc->validation_bits & CPER_PROC_VALID_ID)
164 printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id);
165 if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
166 printk("%s""target_address: 0x%016llx\n",
167 pfx, proc->target_addr);
168 if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
169 printk("%s""requestor_id: 0x%016llx\n",
170 pfx, proc->requestor_id);
171 if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
172 printk("%s""responder_id: 0x%016llx\n",
173 pfx, proc->responder_id);
174 if (proc->validation_bits & CPER_PROC_VALID_IP)
175 printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
176}
177
178static const char *cper_mem_err_type_strs[] = {
179 "unknown",
180 "no error",
181 "single-bit ECC",
182 "multi-bit ECC",
183 "single-symbol chipkill ECC",
184 "multi-symbol chipkill ECC",
185 "master abort",
186 "target abort",
187 "parity error",
188 "watchdog timeout",
189 "invalid address",
190 "mirror Broken",
191 "memory sparing",
192 "scrub corrected error",
193 "scrub uncorrected error",
194};
195
196static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
197{
198 if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
199 printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
200 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)
201 printk("%s""physical_address: 0x%016llx\n",
202 pfx, mem->physical_addr);
203 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK)
204 printk("%s""physical_address_mask: 0x%016llx\n",
205 pfx, mem->physical_addr_mask);
206 if (mem->validation_bits & CPER_MEM_VALID_NODE)
207 printk("%s""node: %d\n", pfx, mem->node);
208 if (mem->validation_bits & CPER_MEM_VALID_CARD)
209 printk("%s""card: %d\n", pfx, mem->card);
210 if (mem->validation_bits & CPER_MEM_VALID_MODULE)
211 printk("%s""module: %d\n", pfx, mem->module);
212 if (mem->validation_bits & CPER_MEM_VALID_BANK)
213 printk("%s""bank: %d\n", pfx, mem->bank);
214 if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
215 printk("%s""device: %d\n", pfx, mem->device);
216 if (mem->validation_bits & CPER_MEM_VALID_ROW)
217 printk("%s""row: %d\n", pfx, mem->row);
218 if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
219 printk("%s""column: %d\n", pfx, mem->column);
220 if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
221 printk("%s""bit_position: %d\n", pfx, mem->bit_pos);
222 if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
223 printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id);
224 if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
225 printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id);
226 if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
227 printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id);
228 if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
229 u8 etype = mem->error_type;
230 printk("%s""error_type: %d, %s\n", pfx, etype,
231 etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
232 cper_mem_err_type_strs[etype] : "unknown");
233 }
234}
235
236static const char *cper_pcie_port_type_strs[] = {
237 "PCIe end point",
238 "legacy PCI end point",
239 "unknown",
240 "unknown",
241 "root port",
242 "upstream switch port",
243 "downstream switch port",
244 "PCIe to PCI/PCI-X bridge",
245 "PCI/PCI-X to PCIe bridge",
246 "root complex integrated endpoint device",
247 "root complex event collector",
248};
249
250static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
251 const struct acpi_hest_generic_data *gdata)
252{
253 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
254 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
255 pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
256 cper_pcie_port_type_strs[pcie->port_type] : "unknown");
257 if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
258 printk("%s""version: %d.%d\n", pfx,
259 pcie->version.major, pcie->version.minor);
260 if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
261 printk("%s""command: 0x%04x, status: 0x%04x\n", pfx,
262 pcie->command, pcie->status);
263 if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
264 const __u8 *p;
265 printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx,
266 pcie->device_id.segment, pcie->device_id.bus,
267 pcie->device_id.device, pcie->device_id.function);
268 printk("%s""slot: %d\n", pfx,
269 pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
270 printk("%s""secondary_bus: 0x%02x\n", pfx,
271 pcie->device_id.secondary_bus);
272 printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
273 pcie->device_id.vendor_id, pcie->device_id.device_id);
274 p = pcie->device_id.class_code;
275 printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
276 }
277 if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
278 printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
279 pcie->serial_number.lower, pcie->serial_number.upper);
280 if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
281 printk(
282 "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
283 pfx, pcie->bridge.secondary_status, pcie->bridge.control);
284}
285
286static const char *apei_estatus_section_flag_strs[] = {
287 "primary",
288 "containment warning",
289 "reset",
290 "threshold exceeded",
291 "resource not accessible",
292 "latent error",
293};
294
295static void apei_estatus_print_section(
296 const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
297{
298 uuid_le *sec_type = (uuid_le *)gdata->section_type;
299 __u16 severity;
300
301 severity = gdata->error_severity;
302 printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
303 cper_severity_str(severity));
304 printk("%s""flags: 0x%02x\n", pfx, gdata->flags);
305 cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs,
306 ARRAY_SIZE(apei_estatus_section_flag_strs));
307 if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
308 printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
309 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
310 printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);
311
312 if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
313 struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
314 printk("%s""section_type: general processor error\n", pfx);
315 if (gdata->error_data_length >= sizeof(*proc_err))
316 cper_print_proc_generic(pfx, proc_err);
317 else
318 goto err_section_too_small;
319 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
320 struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
321 printk("%s""section_type: memory error\n", pfx);
322 if (gdata->error_data_length >= sizeof(*mem_err))
323 cper_print_mem(pfx, mem_err);
324 else
325 goto err_section_too_small;
326 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
327 struct cper_sec_pcie *pcie = (void *)(gdata + 1);
328 printk("%s""section_type: PCIe error\n", pfx);
329 if (gdata->error_data_length >= sizeof(*pcie))
330 cper_print_pcie(pfx, pcie, gdata);
331 else
332 goto err_section_too_small;
333 } else
334 printk("%s""section type: unknown, %pUl\n", pfx, sec_type);
335
336 return;
337
338err_section_too_small:
339 pr_err(FW_WARN "error section length is too small\n");
340}
341
342void apei_estatus_print(const char *pfx,
343 const struct acpi_hest_generic_status *estatus)
344{
345 struct acpi_hest_generic_data *gdata;
346 unsigned int data_len, gedata_len;
347 int sec_no = 0;
348 __u16 severity;
349
350 printk("%s""APEI generic hardware error status\n", pfx);
351 severity = estatus->error_severity;
352 printk("%s""severity: %d, %s\n", pfx, severity,
353 cper_severity_str(severity));
354 data_len = estatus->data_length;
355 gdata = (struct acpi_hest_generic_data *)(estatus + 1);
356 while (data_len > sizeof(*gdata)) {
357 gedata_len = gdata->error_data_length;
358 apei_estatus_print_section(pfx, gdata, sec_no);
359 data_len -= gedata_len + sizeof(*gdata);
360 gdata = (void *)(gdata + 1) + gedata_len;
361 sec_no++;
362 }
363}
364EXPORT_SYMBOL_GPL(apei_estatus_print);
365
366int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
367{
368 if (estatus->data_length &&
369 estatus->data_length < sizeof(struct acpi_hest_generic_data))
370 return -EINVAL;
371 if (estatus->raw_data_length &&
372 estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
373 return -EINVAL;
374
375 return 0;
376}
377EXPORT_SYMBOL_GPL(apei_estatus_check_header);
378
379int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
380{
381 struct acpi_hest_generic_data *gdata;
382 unsigned int data_len, gedata_len;
383 int rc;
384
385 rc = apei_estatus_check_header(estatus);
386 if (rc)
387 return rc;
388 data_len = estatus->data_length;
389 gdata = (struct acpi_hest_generic_data *)(estatus + 1);
390 while (data_len >= sizeof(*gdata)) {
391 gedata_len = gdata->error_data_length;
392 if (gedata_len > data_len - sizeof(*gdata))
393 return -EINVAL;
394 data_len -= gedata_len + sizeof(*gdata);
395 gdata = (void *)(gdata + 1) + gedata_len;
396 }
397 if (data_len)
398 return -EINVAL;
399
400 return 0;
401}
402EXPORT_SYMBOL_GPL(apei_estatus_check);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 8ec37bbdd699..a30bc313787b 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -75,13 +75,13 @@
75#define GHES_ESTATUS_CACHE_LEN(estatus_len) \ 75#define GHES_ESTATUS_CACHE_LEN(estatus_len) \
76 (sizeof(struct ghes_estatus_cache) + (estatus_len)) 76 (sizeof(struct ghes_estatus_cache) + (estatus_len))
77#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ 77#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \
78 ((struct acpi_hest_generic_status *) \ 78 ((struct acpi_generic_status *) \
79 ((struct ghes_estatus_cache *)(estatus_cache) + 1)) 79 ((struct ghes_estatus_cache *)(estatus_cache) + 1))
80 80
81#define GHES_ESTATUS_NODE_LEN(estatus_len) \ 81#define GHES_ESTATUS_NODE_LEN(estatus_len) \
82 (sizeof(struct ghes_estatus_node) + (estatus_len)) 82 (sizeof(struct ghes_estatus_node) + (estatus_len))
83#define GHES_ESTATUS_FROM_NODE(estatus_node) \ 83#define GHES_ESTATUS_FROM_NODE(estatus_node) \
84 ((struct acpi_hest_generic_status *) \ 84 ((struct acpi_generic_status *) \
85 ((struct ghes_estatus_node *)(estatus_node) + 1)) 85 ((struct ghes_estatus_node *)(estatus_node) + 1))
86 86
87bool ghes_disable; 87bool ghes_disable;
@@ -378,17 +378,17 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
378 ghes->flags |= GHES_TO_CLEAR; 378 ghes->flags |= GHES_TO_CLEAR;
379 379
380 rc = -EIO; 380 rc = -EIO;
381 len = apei_estatus_len(ghes->estatus); 381 len = cper_estatus_len(ghes->estatus);
382 if (len < sizeof(*ghes->estatus)) 382 if (len < sizeof(*ghes->estatus))
383 goto err_read_block; 383 goto err_read_block;
384 if (len > ghes->generic->error_block_length) 384 if (len > ghes->generic->error_block_length)
385 goto err_read_block; 385 goto err_read_block;
386 if (apei_estatus_check_header(ghes->estatus)) 386 if (cper_estatus_check_header(ghes->estatus))
387 goto err_read_block; 387 goto err_read_block;
388 ghes_copy_tofrom_phys(ghes->estatus + 1, 388 ghes_copy_tofrom_phys(ghes->estatus + 1,
389 buf_paddr + sizeof(*ghes->estatus), 389 buf_paddr + sizeof(*ghes->estatus),
390 len - sizeof(*ghes->estatus), 1); 390 len - sizeof(*ghes->estatus), 1);
391 if (apei_estatus_check(ghes->estatus)) 391 if (cper_estatus_check(ghes->estatus))
392 goto err_read_block; 392 goto err_read_block;
393 rc = 0; 393 rc = 0;
394 394
@@ -409,7 +409,7 @@ static void ghes_clear_estatus(struct ghes *ghes)
409 ghes->flags &= ~GHES_TO_CLEAR; 409 ghes->flags &= ~GHES_TO_CLEAR;
410} 410}
411 411
412static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) 412static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
413{ 413{
414#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE 414#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
415 unsigned long pfn; 415 unsigned long pfn;
@@ -419,7 +419,7 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
419 419
420 if (sec_sev == GHES_SEV_CORRECTED && 420 if (sec_sev == GHES_SEV_CORRECTED &&
421 (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) && 421 (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) &&
422 (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS)) { 422 (mem_err->validation_bits & CPER_MEM_VALID_PA)) {
423 pfn = mem_err->physical_addr >> PAGE_SHIFT; 423 pfn = mem_err->physical_addr >> PAGE_SHIFT;
424 if (pfn_valid(pfn)) 424 if (pfn_valid(pfn))
425 memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE); 425 memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE);
@@ -430,7 +430,7 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
430 } 430 }
431 if (sev == GHES_SEV_RECOVERABLE && 431 if (sev == GHES_SEV_RECOVERABLE &&
432 sec_sev == GHES_SEV_RECOVERABLE && 432 sec_sev == GHES_SEV_RECOVERABLE &&
433 mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) { 433 mem_err->validation_bits & CPER_MEM_VALID_PA) {
434 pfn = mem_err->physical_addr >> PAGE_SHIFT; 434 pfn = mem_err->physical_addr >> PAGE_SHIFT;
435 memory_failure_queue(pfn, 0, 0); 435 memory_failure_queue(pfn, 0, 0);
436 } 436 }
@@ -438,10 +438,10 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
438} 438}
439 439
440static void ghes_do_proc(struct ghes *ghes, 440static void ghes_do_proc(struct ghes *ghes,
441 const struct acpi_hest_generic_status *estatus) 441 const struct acpi_generic_status *estatus)
442{ 442{
443 int sev, sec_sev; 443 int sev, sec_sev;
444 struct acpi_hest_generic_data *gdata; 444 struct acpi_generic_data *gdata;
445 445
446 sev = ghes_severity(estatus->error_severity); 446 sev = ghes_severity(estatus->error_severity);
447 apei_estatus_for_each_section(estatus, gdata) { 447 apei_estatus_for_each_section(estatus, gdata) {
@@ -496,7 +496,7 @@ static void ghes_do_proc(struct ghes *ghes,
496 496
497static void __ghes_print_estatus(const char *pfx, 497static void __ghes_print_estatus(const char *pfx,
498 const struct acpi_hest_generic *generic, 498 const struct acpi_hest_generic *generic,
499 const struct acpi_hest_generic_status *estatus) 499 const struct acpi_generic_status *estatus)
500{ 500{
501 static atomic_t seqno; 501 static atomic_t seqno;
502 unsigned int curr_seqno; 502 unsigned int curr_seqno;
@@ -513,12 +513,12 @@ static void __ghes_print_estatus(const char *pfx,
513 snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}" HW_ERR, pfx, curr_seqno); 513 snprintf(pfx_seq, sizeof(pfx_seq), "%s{%u}" HW_ERR, pfx, curr_seqno);
514 printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n", 514 printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n",
515 pfx_seq, generic->header.source_id); 515 pfx_seq, generic->header.source_id);
516 apei_estatus_print(pfx_seq, estatus); 516 cper_estatus_print(pfx_seq, estatus);
517} 517}
518 518
519static int ghes_print_estatus(const char *pfx, 519static int ghes_print_estatus(const char *pfx,
520 const struct acpi_hest_generic *generic, 520 const struct acpi_hest_generic *generic,
521 const struct acpi_hest_generic_status *estatus) 521 const struct acpi_generic_status *estatus)
522{ 522{
523 /* Not more than 2 messages every 5 seconds */ 523 /* Not more than 2 messages every 5 seconds */
524 static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); 524 static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
@@ -540,15 +540,15 @@ static int ghes_print_estatus(const char *pfx,
540 * GHES error status reporting throttle, to report more kinds of 540 * GHES error status reporting throttle, to report more kinds of
541 * errors, instead of just most frequently occurred errors. 541 * errors, instead of just most frequently occurred errors.
542 */ 542 */
543static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) 543static int ghes_estatus_cached(struct acpi_generic_status *estatus)
544{ 544{
545 u32 len; 545 u32 len;
546 int i, cached = 0; 546 int i, cached = 0;
547 unsigned long long now; 547 unsigned long long now;
548 struct ghes_estatus_cache *cache; 548 struct ghes_estatus_cache *cache;
549 struct acpi_hest_generic_status *cache_estatus; 549 struct acpi_generic_status *cache_estatus;
550 550
551 len = apei_estatus_len(estatus); 551 len = cper_estatus_len(estatus);
552 rcu_read_lock(); 552 rcu_read_lock();
553 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { 553 for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) {
554 cache = rcu_dereference(ghes_estatus_caches[i]); 554 cache = rcu_dereference(ghes_estatus_caches[i]);
@@ -571,19 +571,19 @@ static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
571 571
572static struct ghes_estatus_cache *ghes_estatus_cache_alloc( 572static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
573 struct acpi_hest_generic *generic, 573 struct acpi_hest_generic *generic,
574 struct acpi_hest_generic_status *estatus) 574 struct acpi_generic_status *estatus)
575{ 575{
576 int alloced; 576 int alloced;
577 u32 len, cache_len; 577 u32 len, cache_len;
578 struct ghes_estatus_cache *cache; 578 struct ghes_estatus_cache *cache;
579 struct acpi_hest_generic_status *cache_estatus; 579 struct acpi_generic_status *cache_estatus;
580 580
581 alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); 581 alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
582 if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { 582 if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
583 atomic_dec(&ghes_estatus_cache_alloced); 583 atomic_dec(&ghes_estatus_cache_alloced);
584 return NULL; 584 return NULL;
585 } 585 }
586 len = apei_estatus_len(estatus); 586 len = cper_estatus_len(estatus);
587 cache_len = GHES_ESTATUS_CACHE_LEN(len); 587 cache_len = GHES_ESTATUS_CACHE_LEN(len);
588 cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len); 588 cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len);
589 if (!cache) { 589 if (!cache) {
@@ -603,7 +603,7 @@ static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache)
603{ 603{
604 u32 len; 604 u32 len;
605 605
606 len = apei_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); 606 len = cper_estatus_len(GHES_ESTATUS_FROM_CACHE(cache));
607 len = GHES_ESTATUS_CACHE_LEN(len); 607 len = GHES_ESTATUS_CACHE_LEN(len);
608 gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); 608 gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len);
609 atomic_dec(&ghes_estatus_cache_alloced); 609 atomic_dec(&ghes_estatus_cache_alloced);
@@ -619,7 +619,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
619 619
620static void ghes_estatus_cache_add( 620static void ghes_estatus_cache_add(
621 struct acpi_hest_generic *generic, 621 struct acpi_hest_generic *generic,
622 struct acpi_hest_generic_status *estatus) 622 struct acpi_generic_status *estatus)
623{ 623{
624 int i, slot = -1, count; 624 int i, slot = -1, count;
625 unsigned long long now, duration, period, max_period = 0; 625 unsigned long long now, duration, period, max_period = 0;
@@ -751,7 +751,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
751 struct llist_node *llnode, *next; 751 struct llist_node *llnode, *next;
752 struct ghes_estatus_node *estatus_node; 752 struct ghes_estatus_node *estatus_node;
753 struct acpi_hest_generic *generic; 753 struct acpi_hest_generic *generic;
754 struct acpi_hest_generic_status *estatus; 754 struct acpi_generic_status *estatus;
755 u32 len, node_len; 755 u32 len, node_len;
756 756
757 llnode = llist_del_all(&ghes_estatus_llist); 757 llnode = llist_del_all(&ghes_estatus_llist);
@@ -765,7 +765,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
765 estatus_node = llist_entry(llnode, struct ghes_estatus_node, 765 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
766 llnode); 766 llnode);
767 estatus = GHES_ESTATUS_FROM_NODE(estatus_node); 767 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
768 len = apei_estatus_len(estatus); 768 len = cper_estatus_len(estatus);
769 node_len = GHES_ESTATUS_NODE_LEN(len); 769 node_len = GHES_ESTATUS_NODE_LEN(len);
770 ghes_do_proc(estatus_node->ghes, estatus); 770 ghes_do_proc(estatus_node->ghes, estatus);
771 if (!ghes_estatus_cached(estatus)) { 771 if (!ghes_estatus_cached(estatus)) {
@@ -784,7 +784,7 @@ static void ghes_print_queued_estatus(void)
784 struct llist_node *llnode; 784 struct llist_node *llnode;
785 struct ghes_estatus_node *estatus_node; 785 struct ghes_estatus_node *estatus_node;
786 struct acpi_hest_generic *generic; 786 struct acpi_hest_generic *generic;
787 struct acpi_hest_generic_status *estatus; 787 struct acpi_generic_status *estatus;
788 u32 len, node_len; 788 u32 len, node_len;
789 789
790 llnode = llist_del_all(&ghes_estatus_llist); 790 llnode = llist_del_all(&ghes_estatus_llist);
@@ -797,7 +797,7 @@ static void ghes_print_queued_estatus(void)
797 estatus_node = llist_entry(llnode, struct ghes_estatus_node, 797 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
798 llnode); 798 llnode);
799 estatus = GHES_ESTATUS_FROM_NODE(estatus_node); 799 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
800 len = apei_estatus_len(estatus); 800 len = cper_estatus_len(estatus);
801 node_len = GHES_ESTATUS_NODE_LEN(len); 801 node_len = GHES_ESTATUS_NODE_LEN(len);
802 generic = estatus_node->generic; 802 generic = estatus_node->generic;
803 ghes_print_estatus(NULL, generic, estatus); 803 ghes_print_estatus(NULL, generic, estatus);
@@ -843,7 +843,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
843#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG 843#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
844 u32 len, node_len; 844 u32 len, node_len;
845 struct ghes_estatus_node *estatus_node; 845 struct ghes_estatus_node *estatus_node;
846 struct acpi_hest_generic_status *estatus; 846 struct acpi_generic_status *estatus;
847#endif 847#endif
848 if (!(ghes->flags & GHES_TO_CLEAR)) 848 if (!(ghes->flags & GHES_TO_CLEAR))
849 continue; 849 continue;
@@ -851,7 +851,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
851 if (ghes_estatus_cached(ghes->estatus)) 851 if (ghes_estatus_cached(ghes->estatus))
852 goto next; 852 goto next;
853 /* Save estatus for further processing in IRQ context */ 853 /* Save estatus for further processing in IRQ context */
854 len = apei_estatus_len(ghes->estatus); 854 len = cper_estatus_len(ghes->estatus);
855 node_len = GHES_ESTATUS_NODE_LEN(len); 855 node_len = GHES_ESTATUS_NODE_LEN(len);
856 estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, 856 estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool,
857 node_len); 857 node_len);
@@ -923,7 +923,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
923 923
924 rc = -EIO; 924 rc = -EIO;
925 if (generic->error_block_length < 925 if (generic->error_block_length <
926 sizeof(struct acpi_hest_generic_status)) { 926 sizeof(struct acpi_generic_status)) {
927 pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", 927 pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
928 generic->error_block_length, 928 generic->error_block_length,
929 generic->header.source_id); 929 generic->header.source_id);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index b587ec8257b2..e1bd9a181117 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -174,7 +174,7 @@ static void acpi_print_osc_error(acpi_handle handle,
174 printk("\n"); 174 printk("\n");
175} 175}
176 176
177static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) 177acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
178{ 178{
179 int i; 179 int i;
180 static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 180 static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
@@ -195,6 +195,7 @@ static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
195 } 195 }
196 return AE_OK; 196 return AE_OK;
197} 197}
198EXPORT_SYMBOL_GPL(acpi_str_to_uuid);
198 199
199acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) 200acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
200{ 201{