aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-10-26 06:05:11 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-26 06:08:29 -0400
commitd69525789e3256968a3867f70015903523c195e3 (patch)
tree658053ea4a9537f1361212ed34fa25bd28b797c3
parent88829dfe4b6ea0c1c24d415668b3bfa78e5a5b16 (diff)
parent56507694de3453076d73e0e9813349586ee67e59 (diff)
Merge tag 'please-pull-eMCA-fix' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras into x86/mce
Pull MCE updates from Tony Luck: "There is a enhanced error logging mechanism for Xeon processors. Full description is here: http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html This patch series provides a module (and support code) to check for an extended error log and print extra details about the error on the console. " Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/ia64/kernel/setup.c1
-rw-r--r--arch/x86/include/asm/mce.h1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-apei.c3
-rw-r--r--arch/x86/kernel/setup.c1
-rw-r--r--drivers/acpi/Kconfig19
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/acpi_extlog.c327
-rw-r--r--drivers/acpi/apei/apei-internal.h12
-rw-r--r--drivers/acpi/apei/cper.c132
-rw-r--r--drivers/acpi/apei/ghes.c58
-rw-r--r--drivers/acpi/bus.c3
-rw-r--r--drivers/edac/amd64_edac.c46
-rw-r--r--drivers/edac/amd64_edac.h8
-rw-r--r--drivers/edac/ghes_edac.c16
-rw-r--r--drivers/edac/sb_edac.c2
-rw-r--r--drivers/firmware/dmi_scan.c60
-rw-r--r--drivers/video/sis/init.c5
-rw-r--r--include/acpi/actbl1.h14
-rw-r--r--include/acpi/ghes.h2
-rw-r--r--include/linux/acpi.h1
-rw-r--r--include/linux/bitops.h8
-rw-r--r--include/linux/cper.h13
-rw-r--r--include/linux/dmi.h5
-rw-r--r--include/linux/edac.h2
24 files changed, 592 insertions, 149 deletions
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 4fc2e9569bb2..d86669bcdfb2 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -1063,6 +1063,7 @@ check_bugs (void)
1063static int __init run_dmi_scan(void) 1063static int __init run_dmi_scan(void)
1064{ 1064{
1065 dmi_scan_machine(); 1065 dmi_scan_machine();
1066 dmi_memdev_walk();
1066 dmi_set_dump_stack_arch_desc(); 1067 dmi_set_dump_stack_arch_desc();
1067 return 0; 1068 return 0;
1068} 1069}
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index cbe6b9e404ce..c696a8687567 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -16,6 +16,7 @@
16#define MCG_EXT_CNT_SHIFT 16 16#define MCG_EXT_CNT_SHIFT 16
17#define MCG_EXT_CNT(c) (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT) 17#define MCG_EXT_CNT(c) (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)
18#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */ 18#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
19#define MCG_ELOG_P (1ULL<<26) /* Extended error log supported */
19 20
20/* MCG_STATUS register defines */ 21/* MCG_STATUS register defines */
21#define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */ 22#define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c
index cd8b166a1735..de8b60a53f69 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-apei.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c
@@ -42,8 +42,7 @@ void apei_mce_report_mem_error(int corrected, struct cper_sec_mem_err *mem_err)
42 struct mce m; 42 struct mce m;
43 43
44 /* Only corrected MC is reported */ 44 /* Only corrected MC is reported */
45 if (!corrected || !(mem_err->validation_bits & 45 if (!corrected || !(mem_err->validation_bits & CPER_MEM_VALID_PA))
46 CPER_MEM_VALID_PHYSICAL_ADDRESS))
47 return; 46 return;
48 47
49 mce_setup(&m); 48 mce_setup(&m);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index f0de6294b955..918d489fa53d 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -993,6 +993,7 @@ void __init setup_arch(char **cmdline_p)
993 efi_init(); 993 efi_init();
994 994
995 dmi_scan_machine(); 995 dmi_scan_machine();
996 dmi_memdev_walk();
996 dmi_set_dump_stack_arch_desc(); 997 dmi_set_dump_stack_arch_desc();
997 998
998 /* 999 /*
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 6efe2ac6902f..252f0e818a49 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -372,4 +372,23 @@ 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 && ACPI_APEI
378 default n
379 help
380 Certain usages such as Predictive Failure Analysis (PFA) require
381 more information about the error than what can be described in
382 processor machine check banks. Most server processors log
383 additional information about the error in processor uncore
384 registers. Since the addresses and layout of these registers vary
385 widely from one processor to another, system software cannot
386 readily make use of them. To complicate matters further, some of
387 the additional error information cannot be constructed without
388 detailed knowledge about platform topology.
389
390 Enhanced MCA Logging allows firmware to provide additional error
391 information to system software, synchronous with MCE or CMCI. This
392 driver adds support for that functionality.
393
375endif # ACPI 394endif # 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/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
index 33dc6a004802..1491dd4f08f9 100644
--- a/drivers/acpi/apei/cper.c
+++ b/drivers/acpi/apei/cper.c
@@ -5,10 +5,10 @@
5 * Author: Huang Ying <ying.huang@intel.com> 5 * Author: Huang Ying <ying.huang@intel.com>
6 * 6 *
7 * CPER is the format used to describe platform hardware error by 7 * CPER is the format used to describe platform hardware error by
8 * various APEI tables, such as ERST, BERT and HEST etc. 8 * various tables, such as ERST, BERT and HEST etc.
9 * 9 *
10 * For more information about CPER, please refer to Appendix N of UEFI 10 * For more information about CPER, please refer to Appendix N of UEFI
11 * Specification version 2.3. 11 * Specification version 2.4.
12 * 12 *
13 * This program is free software; you can redistribute it and/or 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 14 * modify it under the terms of the GNU General Public License version
@@ -28,10 +28,12 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/cper.h> 30#include <linux/cper.h>
31#include <linux/dmi.h>
31#include <linux/acpi.h> 32#include <linux/acpi.h>
32#include <linux/pci.h> 33#include <linux/pci.h>
33#include <linux/aer.h> 34#include <linux/aer.h>
34 35
36#define INDENT_SP " "
35/* 37/*
36 * CPER record ID need to be unique even after reboot, because record 38 * 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 39 * ID is used as index for ERST storage, while CPER records from
@@ -73,7 +75,7 @@ static const char *cper_severity_str(unsigned int severity)
73 * printed, with @pfx is printed at the beginning of each line. 75 * printed, with @pfx is printed at the beginning of each line.
74 */ 76 */
75void cper_print_bits(const char *pfx, unsigned int bits, 77void cper_print_bits(const char *pfx, unsigned int bits,
76 const char *strs[], unsigned int strs_size) 78 const char * const strs[], unsigned int strs_size)
77{ 79{
78 int i, len = 0; 80 int i, len = 0;
79 const char *str; 81 const char *str;
@@ -98,32 +100,32 @@ void cper_print_bits(const char *pfx, unsigned int bits,
98 printk("%s\n", buf); 100 printk("%s\n", buf);
99} 101}
100 102
101static const char *cper_proc_type_strs[] = { 103static const char * const cper_proc_type_strs[] = {
102 "IA32/X64", 104 "IA32/X64",
103 "IA64", 105 "IA64",
104}; 106};
105 107
106static const char *cper_proc_isa_strs[] = { 108static const char * const cper_proc_isa_strs[] = {
107 "IA32", 109 "IA32",
108 "IA64", 110 "IA64",
109 "X64", 111 "X64",
110}; 112};
111 113
112static const char *cper_proc_error_type_strs[] = { 114static const char * const cper_proc_error_type_strs[] = {
113 "cache error", 115 "cache error",
114 "TLB error", 116 "TLB error",
115 "bus error", 117 "bus error",
116 "micro-architectural error", 118 "micro-architectural error",
117}; 119};
118 120
119static const char *cper_proc_op_strs[] = { 121static const char * const cper_proc_op_strs[] = {
120 "unknown or generic", 122 "unknown or generic",
121 "data read", 123 "data read",
122 "data write", 124 "data write",
123 "instruction execution", 125 "instruction execution",
124}; 126};
125 127
126static const char *cper_proc_flag_strs[] = { 128static const char * const cper_proc_flag_strs[] = {
127 "restartable", 129 "restartable",
128 "precise IP", 130 "precise IP",
129 "overflow", 131 "overflow",
@@ -191,46 +193,58 @@ static const char *cper_mem_err_type_strs[] = {
191 "memory sparing", 193 "memory sparing",
192 "scrub corrected error", 194 "scrub corrected error",
193 "scrub uncorrected error", 195 "scrub uncorrected error",
196 "physical memory map-out event",
194}; 197};
195 198
196static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) 199static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
197{ 200{
198 if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS) 201 if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
199 printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status); 202 printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
200 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) 203 if (mem->validation_bits & CPER_MEM_VALID_PA)
201 printk("%s""physical_address: 0x%016llx\n", 204 printk("%s""physical_address: 0x%016llx\n",
202 pfx, mem->physical_addr); 205 pfx, mem->physical_addr);
203 if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) 206 if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
204 printk("%s""physical_address_mask: 0x%016llx\n", 207 printk("%s""physical_address_mask: 0x%016llx\n",
205 pfx, mem->physical_addr_mask); 208 pfx, mem->physical_addr_mask);
206 if (mem->validation_bits & CPER_MEM_VALID_NODE) 209 if (mem->validation_bits & CPER_MEM_VALID_NODE)
207 printk("%s""node: %d\n", pfx, mem->node); 210 pr_debug("node: %d\n", mem->node);
208 if (mem->validation_bits & CPER_MEM_VALID_CARD) 211 if (mem->validation_bits & CPER_MEM_VALID_CARD)
209 printk("%s""card: %d\n", pfx, mem->card); 212 pr_debug("card: %d\n", mem->card);
210 if (mem->validation_bits & CPER_MEM_VALID_MODULE) 213 if (mem->validation_bits & CPER_MEM_VALID_MODULE)
211 printk("%s""module: %d\n", pfx, mem->module); 214 pr_debug("module: %d\n", mem->module);
215 if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
216 pr_debug("rank: %d\n", mem->rank);
212 if (mem->validation_bits & CPER_MEM_VALID_BANK) 217 if (mem->validation_bits & CPER_MEM_VALID_BANK)
213 printk("%s""bank: %d\n", pfx, mem->bank); 218 pr_debug("bank: %d\n", mem->bank);
214 if (mem->validation_bits & CPER_MEM_VALID_DEVICE) 219 if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
215 printk("%s""device: %d\n", pfx, mem->device); 220 pr_debug("device: %d\n", mem->device);
216 if (mem->validation_bits & CPER_MEM_VALID_ROW) 221 if (mem->validation_bits & CPER_MEM_VALID_ROW)
217 printk("%s""row: %d\n", pfx, mem->row); 222 pr_debug("row: %d\n", mem->row);
218 if (mem->validation_bits & CPER_MEM_VALID_COLUMN) 223 if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
219 printk("%s""column: %d\n", pfx, mem->column); 224 pr_debug("column: %d\n", mem->column);
220 if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION) 225 if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
221 printk("%s""bit_position: %d\n", pfx, mem->bit_pos); 226 pr_debug("bit_position: %d\n", mem->bit_pos);
222 if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID) 227 if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
223 printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id); 228 pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
224 if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID) 229 if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
225 printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id); 230 pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
226 if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID) 231 if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
227 printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id); 232 pr_debug("target_id: 0x%016llx\n", mem->target_id);
228 if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) { 233 if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
229 u8 etype = mem->error_type; 234 u8 etype = mem->error_type;
230 printk("%s""error_type: %d, %s\n", pfx, etype, 235 printk("%s""error_type: %d, %s\n", pfx, etype,
231 etype < ARRAY_SIZE(cper_mem_err_type_strs) ? 236 etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
232 cper_mem_err_type_strs[etype] : "unknown"); 237 cper_mem_err_type_strs[etype] : "unknown");
233 } 238 }
239 if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
240 const char *bank = NULL, *device = NULL;
241 dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
242 if (bank != NULL && device != NULL)
243 printk("%s""DIMM location: %s %s", pfx, bank, device);
244 else
245 printk("%s""DIMM DMI handle: 0x%.4x",
246 pfx, mem->mem_dev_handle);
247 }
234} 248}
235 249
236static const char *cper_pcie_port_type_strs[] = { 250static const char *cper_pcie_port_type_strs[] = {
@@ -248,7 +262,7 @@ static const char *cper_pcie_port_type_strs[] = {
248}; 262};
249 263
250static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, 264static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
251 const struct acpi_hest_generic_data *gdata) 265 const struct acpi_generic_data *gdata)
252{ 266{
253 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) 267 if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
254 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, 268 printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
@@ -283,55 +297,45 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
283 pfx, pcie->bridge.secondary_status, pcie->bridge.control); 297 pfx, pcie->bridge.secondary_status, pcie->bridge.control);
284} 298}
285 299
286static const char *apei_estatus_section_flag_strs[] = { 300static void cper_estatus_print_section(
287 "primary", 301 const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
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{ 302{
298 uuid_le *sec_type = (uuid_le *)gdata->section_type; 303 uuid_le *sec_type = (uuid_le *)gdata->section_type;
299 __u16 severity; 304 __u16 severity;
305 char newpfx[64];
300 306
301 severity = gdata->error_severity; 307 severity = gdata->error_severity;
302 printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity, 308 printk("%s""Error %d, type: %s\n", pfx, sec_no,
303 cper_severity_str(severity)); 309 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) 310 if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
308 printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id); 311 printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
309 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) 312 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
310 printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); 313 printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);
311 314
315 snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
312 if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) { 316 if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
313 struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1); 317 struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
314 printk("%s""section_type: general processor error\n", pfx); 318 printk("%s""section_type: general processor error\n", newpfx);
315 if (gdata->error_data_length >= sizeof(*proc_err)) 319 if (gdata->error_data_length >= sizeof(*proc_err))
316 cper_print_proc_generic(pfx, proc_err); 320 cper_print_proc_generic(newpfx, proc_err);
317 else 321 else
318 goto err_section_too_small; 322 goto err_section_too_small;
319 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) { 323 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
320 struct cper_sec_mem_err *mem_err = (void *)(gdata + 1); 324 struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
321 printk("%s""section_type: memory error\n", pfx); 325 printk("%s""section_type: memory error\n", newpfx);
322 if (gdata->error_data_length >= sizeof(*mem_err)) 326 if (gdata->error_data_length >= sizeof(*mem_err))
323 cper_print_mem(pfx, mem_err); 327 cper_print_mem(newpfx, mem_err);
324 else 328 else
325 goto err_section_too_small; 329 goto err_section_too_small;
326 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) { 330 } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
327 struct cper_sec_pcie *pcie = (void *)(gdata + 1); 331 struct cper_sec_pcie *pcie = (void *)(gdata + 1);
328 printk("%s""section_type: PCIe error\n", pfx); 332 printk("%s""section_type: PCIe error\n", newpfx);
329 if (gdata->error_data_length >= sizeof(*pcie)) 333 if (gdata->error_data_length >= sizeof(*pcie))
330 cper_print_pcie(pfx, pcie, gdata); 334 cper_print_pcie(newpfx, pcie, gdata);
331 else 335 else
332 goto err_section_too_small; 336 goto err_section_too_small;
333 } else 337 } else
334 printk("%s""section type: unknown, %pUl\n", pfx, sec_type); 338 printk("%s""section type: unknown, %pUl\n", newpfx, sec_type);
335 339
336 return; 340 return;
337 341
@@ -339,34 +343,38 @@ err_section_too_small:
339 pr_err(FW_WARN "error section length is too small\n"); 343 pr_err(FW_WARN "error section length is too small\n");
340} 344}
341 345
342void apei_estatus_print(const char *pfx, 346void cper_estatus_print(const char *pfx,
343 const struct acpi_hest_generic_status *estatus) 347 const struct acpi_generic_status *estatus)
344{ 348{
345 struct acpi_hest_generic_data *gdata; 349 struct acpi_generic_data *gdata;
346 unsigned int data_len, gedata_len; 350 unsigned int data_len, gedata_len;
347 int sec_no = 0; 351 int sec_no = 0;
352 char newpfx[64];
348 __u16 severity; 353 __u16 severity;
349 354
350 printk("%s""APEI generic hardware error status\n", pfx);
351 severity = estatus->error_severity; 355 severity = estatus->error_severity;
352 printk("%s""severity: %d, %s\n", pfx, severity, 356 if (severity == CPER_SEV_CORRECTED)
353 cper_severity_str(severity)); 357 printk("%s%s\n", pfx,
358 "It has been corrected by h/w "
359 "and requires no further action");
360 printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
354 data_len = estatus->data_length; 361 data_len = estatus->data_length;
355 gdata = (struct acpi_hest_generic_data *)(estatus + 1); 362 gdata = (struct acpi_generic_data *)(estatus + 1);
356 while (data_len > sizeof(*gdata)) { 363 snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
364 while (data_len >= sizeof(*gdata)) {
357 gedata_len = gdata->error_data_length; 365 gedata_len = gdata->error_data_length;
358 apei_estatus_print_section(pfx, gdata, sec_no); 366 cper_estatus_print_section(newpfx, gdata, sec_no);
359 data_len -= gedata_len + sizeof(*gdata); 367 data_len -= gedata_len + sizeof(*gdata);
360 gdata = (void *)(gdata + 1) + gedata_len; 368 gdata = (void *)(gdata + 1) + gedata_len;
361 sec_no++; 369 sec_no++;
362 } 370 }
363} 371}
364EXPORT_SYMBOL_GPL(apei_estatus_print); 372EXPORT_SYMBOL_GPL(cper_estatus_print);
365 373
366int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) 374int cper_estatus_check_header(const struct acpi_generic_status *estatus)
367{ 375{
368 if (estatus->data_length && 376 if (estatus->data_length &&
369 estatus->data_length < sizeof(struct acpi_hest_generic_data)) 377 estatus->data_length < sizeof(struct acpi_generic_data))
370 return -EINVAL; 378 return -EINVAL;
371 if (estatus->raw_data_length && 379 if (estatus->raw_data_length &&
372 estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) 380 estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
@@ -374,19 +382,19 @@ int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus)
374 382
375 return 0; 383 return 0;
376} 384}
377EXPORT_SYMBOL_GPL(apei_estatus_check_header); 385EXPORT_SYMBOL_GPL(cper_estatus_check_header);
378 386
379int apei_estatus_check(const struct acpi_hest_generic_status *estatus) 387int cper_estatus_check(const struct acpi_generic_status *estatus)
380{ 388{
381 struct acpi_hest_generic_data *gdata; 389 struct acpi_generic_data *gdata;
382 unsigned int data_len, gedata_len; 390 unsigned int data_len, gedata_len;
383 int rc; 391 int rc;
384 392
385 rc = apei_estatus_check_header(estatus); 393 rc = cper_estatus_check_header(estatus);
386 if (rc) 394 if (rc)
387 return rc; 395 return rc;
388 data_len = estatus->data_length; 396 data_len = estatus->data_length;
389 gdata = (struct acpi_hest_generic_data *)(estatus + 1); 397 gdata = (struct acpi_generic_data *)(estatus + 1);
390 while (data_len >= sizeof(*gdata)) { 398 while (data_len >= sizeof(*gdata)) {
391 gedata_len = gdata->error_data_length; 399 gedata_len = gdata->error_data_length;
392 if (gedata_len > data_len - sizeof(*gdata)) 400 if (gedata_len > data_len - sizeof(*gdata))
@@ -399,4 +407,4 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
399 407
400 return 0; 408 return 0;
401} 409}
402EXPORT_SYMBOL_GPL(apei_estatus_check); 410EXPORT_SYMBOL_GPL(cper_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{
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 3c9e4e98c651..b53d0de17e15 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -339,8 +339,8 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
339 if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) { 339 if (pvt->fam == 0xf && pvt->ext_model < K8_REV_F) {
340 csbase = pvt->csels[dct].csbases[csrow]; 340 csbase = pvt->csels[dct].csbases[csrow];
341 csmask = pvt->csels[dct].csmasks[csrow]; 341 csmask = pvt->csels[dct].csmasks[csrow];
342 base_bits = GENMASK(21, 31) | GENMASK(9, 15); 342 base_bits = GENMASK_ULL(31, 21) | GENMASK_ULL(15, 9);
343 mask_bits = GENMASK(21, 29) | GENMASK(9, 15); 343 mask_bits = GENMASK_ULL(29, 21) | GENMASK_ULL(15, 9);
344 addr_shift = 4; 344 addr_shift = 4;
345 345
346 /* 346 /*
@@ -352,16 +352,16 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
352 csbase = pvt->csels[dct].csbases[csrow]; 352 csbase = pvt->csels[dct].csbases[csrow];
353 csmask = pvt->csels[dct].csmasks[csrow >> 1]; 353 csmask = pvt->csels[dct].csmasks[csrow >> 1];
354 354
355 *base = (csbase & GENMASK(5, 15)) << 6; 355 *base = (csbase & GENMASK_ULL(15, 5)) << 6;
356 *base |= (csbase & GENMASK(19, 30)) << 8; 356 *base |= (csbase & GENMASK_ULL(30, 19)) << 8;
357 357
358 *mask = ~0ULL; 358 *mask = ~0ULL;
359 /* poke holes for the csmask */ 359 /* poke holes for the csmask */
360 *mask &= ~((GENMASK(5, 15) << 6) | 360 *mask &= ~((GENMASK_ULL(15, 5) << 6) |
361 (GENMASK(19, 30) << 8)); 361 (GENMASK_ULL(30, 19) << 8));
362 362
363 *mask |= (csmask & GENMASK(5, 15)) << 6; 363 *mask |= (csmask & GENMASK_ULL(15, 5)) << 6;
364 *mask |= (csmask & GENMASK(19, 30)) << 8; 364 *mask |= (csmask & GENMASK_ULL(30, 19)) << 8;
365 365
366 return; 366 return;
367 } else { 367 } else {
@@ -370,9 +370,11 @@ static void get_cs_base_and_mask(struct amd64_pvt *pvt, int csrow, u8 dct,
370 addr_shift = 8; 370 addr_shift = 8;
371 371
372 if (pvt->fam == 0x15) 372 if (pvt->fam == 0x15)
373 base_bits = mask_bits = GENMASK(19,30) | GENMASK(5,13); 373 base_bits = mask_bits =
374 GENMASK_ULL(30,19) | GENMASK_ULL(13,5);
374 else 375 else
375 base_bits = mask_bits = GENMASK(19,28) | GENMASK(5,13); 376 base_bits = mask_bits =
377 GENMASK_ULL(28,19) | GENMASK_ULL(13,5);
376 } 378 }
377 379
378 *base = (csbase & base_bits) << addr_shift; 380 *base = (csbase & base_bits) << addr_shift;
@@ -561,7 +563,7 @@ static u64 sys_addr_to_dram_addr(struct mem_ctl_info *mci, u64 sys_addr)
561 * section 3.4.2 of AMD publication 24592: AMD x86-64 Architecture 563 * section 3.4.2 of AMD publication 24592: AMD x86-64 Architecture
562 * Programmer's Manual Volume 1 Application Programming. 564 * Programmer's Manual Volume 1 Application Programming.
563 */ 565 */
564 dram_addr = (sys_addr & GENMASK(0, 39)) - dram_base; 566 dram_addr = (sys_addr & GENMASK_ULL(39, 0)) - dram_base;
565 567
566 edac_dbg(2, "using DRAM Base register to translate SysAddr 0x%lx to DramAddr 0x%lx\n", 568 edac_dbg(2, "using DRAM Base register to translate SysAddr 0x%lx to DramAddr 0x%lx\n",
567 (unsigned long)sys_addr, (unsigned long)dram_addr); 569 (unsigned long)sys_addr, (unsigned long)dram_addr);
@@ -597,7 +599,7 @@ static u64 dram_addr_to_input_addr(struct mem_ctl_info *mci, u64 dram_addr)
597 * concerning translating a DramAddr to an InputAddr. 599 * concerning translating a DramAddr to an InputAddr.
598 */ 600 */
599 intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0)); 601 intlv_shift = num_node_interleave_bits(dram_intlv_en(pvt, 0));
600 input_addr = ((dram_addr >> intlv_shift) & GENMASK(12, 35)) + 602 input_addr = ((dram_addr >> intlv_shift) & GENMASK_ULL(35, 12)) +
601 (dram_addr & 0xfff); 603 (dram_addr & 0xfff);
602 604
603 edac_dbg(2, " Intlv Shift=%d DramAddr=0x%lx maps to InputAddr=0x%lx\n", 605 edac_dbg(2, " Intlv Shift=%d DramAddr=0x%lx maps to InputAddr=0x%lx\n",
@@ -849,7 +851,7 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
849 end_bit = 39; 851 end_bit = 39;
850 } 852 }
851 853
852 addr = m->addr & GENMASK(start_bit, end_bit); 854 addr = m->addr & GENMASK_ULL(end_bit, start_bit);
853 855
854 /* 856 /*
855 * Erratum 637 workaround 857 * Erratum 637 workaround
@@ -861,7 +863,7 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
861 u16 mce_nid; 863 u16 mce_nid;
862 u8 intlv_en; 864 u8 intlv_en;
863 865
864 if ((addr & GENMASK(24, 47)) >> 24 != 0x00fdf7) 866 if ((addr & GENMASK_ULL(47, 24)) >> 24 != 0x00fdf7)
865 return addr; 867 return addr;
866 868
867 mce_nid = amd_get_nb_id(m->extcpu); 869 mce_nid = amd_get_nb_id(m->extcpu);
@@ -871,7 +873,7 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
871 intlv_en = tmp >> 21 & 0x7; 873 intlv_en = tmp >> 21 & 0x7;
872 874
873 /* add [47:27] + 3 trailing bits */ 875 /* add [47:27] + 3 trailing bits */
874 cc6_base = (tmp & GENMASK(0, 20)) << 3; 876 cc6_base = (tmp & GENMASK_ULL(20, 0)) << 3;
875 877
876 /* reverse and add DramIntlvEn */ 878 /* reverse and add DramIntlvEn */
877 cc6_base |= intlv_en ^ 0x7; 879 cc6_base |= intlv_en ^ 0x7;
@@ -880,18 +882,18 @@ static u64 get_error_address(struct amd64_pvt *pvt, struct mce *m)
880 cc6_base <<= 24; 882 cc6_base <<= 24;
881 883
882 if (!intlv_en) 884 if (!intlv_en)
883 return cc6_base | (addr & GENMASK(0, 23)); 885 return cc6_base | (addr & GENMASK_ULL(23, 0));
884 886
885 amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp); 887 amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp);
886 888
887 /* faster log2 */ 889 /* faster log2 */
888 tmp_addr = (addr & GENMASK(12, 23)) << __fls(intlv_en + 1); 890 tmp_addr = (addr & GENMASK_ULL(23, 12)) << __fls(intlv_en + 1);
889 891
890 /* OR DramIntlvSel into bits [14:12] */ 892 /* OR DramIntlvSel into bits [14:12] */
891 tmp_addr |= (tmp & GENMASK(21, 23)) >> 9; 893 tmp_addr |= (tmp & GENMASK_ULL(23, 21)) >> 9;
892 894
893 /* add remaining [11:0] bits from original MC4_ADDR */ 895 /* add remaining [11:0] bits from original MC4_ADDR */
894 tmp_addr |= addr & GENMASK(0, 11); 896 tmp_addr |= addr & GENMASK_ULL(11, 0);
895 897
896 return cc6_base | tmp_addr; 898 return cc6_base | tmp_addr;
897 } 899 }
@@ -952,12 +954,12 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range)
952 954
953 amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim); 955 amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim);
954 956
955 pvt->ranges[range].lim.lo &= GENMASK(0, 15); 957 pvt->ranges[range].lim.lo &= GENMASK_ULL(15, 0);
956 958
957 /* {[39:27],111b} */ 959 /* {[39:27],111b} */
958 pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16; 960 pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16;
959 961
960 pvt->ranges[range].lim.hi &= GENMASK(0, 7); 962 pvt->ranges[range].lim.hi &= GENMASK_ULL(7, 0);
961 963
962 /* [47:40] */ 964 /* [47:40] */
963 pvt->ranges[range].lim.hi |= llim >> 13; 965 pvt->ranges[range].lim.hi |= llim >> 13;
@@ -1330,7 +1332,7 @@ static u64 f1x_get_norm_dct_addr(struct amd64_pvt *pvt, u8 range,
1330 chan_off = dram_base; 1332 chan_off = dram_base;
1331 } 1333 }
1332 1334
1333 return (sys_addr & GENMASK(6,47)) - (chan_off & GENMASK(23,47)); 1335 return (sys_addr & GENMASK_ULL(47,6)) - (chan_off & GENMASK_ULL(47,23));
1334} 1336}
1335 1337
1336/* 1338/*
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index d2443cfa0698..6dc1fcc25afb 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -160,14 +160,6 @@
160#define OFF false 160#define OFF false
161 161
162/* 162/*
163 * Create a contiguous bitmask starting at bit position @lo and ending at
164 * position @hi. For example
165 *
166 * GENMASK(21, 39) gives us the 64bit vector 0x000000ffffe00000.
167 */
168#define GENMASK(lo, hi) (((1ULL << ((hi) - (lo) + 1)) - 1) << (lo))
169
170/*
171 * PCI-defined configuration space registers 163 * PCI-defined configuration space registers
172 */ 164 */
173#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b 165#define PCI_DEVICE_ID_AMD_15H_M30H_NB_F1 0x141b
diff --git a/drivers/edac/ghes_edac.c b/drivers/edac/ghes_edac.c
index bb534670ec02..d5a98a45c062 100644
--- a/drivers/edac/ghes_edac.c
+++ b/drivers/edac/ghes_edac.c
@@ -297,15 +297,14 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
297 } 297 }
298 298
299 /* Error address */ 299 /* Error address */
300 if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) { 300 if (mem_err->validation_bits & CPER_MEM_VALID_PA) {
301 e->page_frame_number = mem_err->physical_addr >> PAGE_SHIFT; 301 e->page_frame_number = mem_err->physical_addr >> PAGE_SHIFT;
302 e->offset_in_page = mem_err->physical_addr & ~PAGE_MASK; 302 e->offset_in_page = mem_err->physical_addr & ~PAGE_MASK;
303 } 303 }
304 304
305 /* Error grain */ 305 /* Error grain */
306 if (mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) { 306 if (mem_err->validation_bits & CPER_MEM_VALID_PA_MASK)
307 e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK); 307 e->grain = ~(mem_err->physical_addr_mask & ~PAGE_MASK);
308 }
309 308
310 /* Memory error location, mapped on e->location */ 309 /* Memory error location, mapped on e->location */
311 p = e->location; 310 p = e->location;
@@ -315,6 +314,8 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
315 p += sprintf(p, "card:%d ", mem_err->card); 314 p += sprintf(p, "card:%d ", mem_err->card);
316 if (mem_err->validation_bits & CPER_MEM_VALID_MODULE) 315 if (mem_err->validation_bits & CPER_MEM_VALID_MODULE)
317 p += sprintf(p, "module:%d ", mem_err->module); 316 p += sprintf(p, "module:%d ", mem_err->module);
317 if (mem_err->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
318 p += sprintf(p, "rank:%d ", mem_err->rank);
318 if (mem_err->validation_bits & CPER_MEM_VALID_BANK) 319 if (mem_err->validation_bits & CPER_MEM_VALID_BANK)
319 p += sprintf(p, "bank:%d ", mem_err->bank); 320 p += sprintf(p, "bank:%d ", mem_err->bank);
320 if (mem_err->validation_bits & CPER_MEM_VALID_ROW) 321 if (mem_err->validation_bits & CPER_MEM_VALID_ROW)
@@ -323,6 +324,15 @@ void ghes_edac_report_mem_error(struct ghes *ghes, int sev,
323 p += sprintf(p, "col:%d ", mem_err->column); 324 p += sprintf(p, "col:%d ", mem_err->column);
324 if (mem_err->validation_bits & CPER_MEM_VALID_BIT_POSITION) 325 if (mem_err->validation_bits & CPER_MEM_VALID_BIT_POSITION)
325 p += sprintf(p, "bit_pos:%d ", mem_err->bit_pos); 326 p += sprintf(p, "bit_pos:%d ", mem_err->bit_pos);
327 if (mem_err->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
328 const char *bank = NULL, *device = NULL;
329 dmi_memdev_name(mem_err->mem_dev_handle, &bank, &device);
330 if (bank != NULL && device != NULL)
331 p += sprintf(p, "DIMM location:%s %s ", bank, device);
332 else
333 p += sprintf(p, "DIMM DMI handle: 0x%.4x ",
334 mem_err->mem_dev_handle);
335 }
326 if (p > e->location) 336 if (p > e->location)
327 *(p - 1) = '\0'; 337 *(p - 1) = '\0';
328 338
diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
index e04462b60756..88f60c5fecbc 100644
--- a/drivers/edac/sb_edac.c
+++ b/drivers/edac/sb_edac.c
@@ -50,7 +50,7 @@ static int probed;
50 * Get a bit field at register value <v>, from bit <lo> to bit <hi> 50 * Get a bit field at register value <v>, from bit <lo> to bit <hi>
51 */ 51 */
52#define GET_BITFIELD(v, lo, hi) \ 52#define GET_BITFIELD(v, lo, hi) \
53 (((v) & ((1ULL << ((hi) - (lo) + 1)) - 1) << (lo)) >> (lo)) 53 (((v) & GENMASK_ULL(hi, lo)) >> (lo))
54 54
55/* 55/*
56 * sbridge Memory Controller Registers 56 * sbridge Memory Controller Registers
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index fa0affb699b4..59579a744d58 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -25,6 +25,13 @@ static int dmi_initialized;
25/* DMI system identification string used during boot */ 25/* DMI system identification string used during boot */
26static char dmi_ids_string[128] __initdata; 26static char dmi_ids_string[128] __initdata;
27 27
28static struct dmi_memdev_info {
29 const char *device;
30 const char *bank;
31 u16 handle;
32} *dmi_memdev;
33static int dmi_memdev_nr;
34
28static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) 35static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
29{ 36{
30 const u8 *bp = ((u8 *) dm) + dm->length; 37 const u8 *bp = ((u8 *) dm) + dm->length;
@@ -322,6 +329,42 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
322 dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1))); 329 dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
323} 330}
324 331
332static void __init count_mem_devices(const struct dmi_header *dm, void *v)
333{
334 if (dm->type != DMI_ENTRY_MEM_DEVICE)
335 return;
336 dmi_memdev_nr++;
337}
338
339static void __init save_mem_devices(const struct dmi_header *dm, void *v)
340{
341 const char *d = (const char *)dm;
342 static int nr;
343
344 if (dm->type != DMI_ENTRY_MEM_DEVICE)
345 return;
346 if (nr >= dmi_memdev_nr) {
347 pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n");
348 return;
349 }
350 dmi_memdev[nr].handle = dm->handle;
351 dmi_memdev[nr].device = dmi_string(dm, d[0x10]);
352 dmi_memdev[nr].bank = dmi_string(dm, d[0x11]);
353 nr++;
354}
355
356void __init dmi_memdev_walk(void)
357{
358 if (!dmi_available)
359 return;
360
361 if (dmi_walk_early(count_mem_devices) == 0 && dmi_memdev_nr) {
362 dmi_memdev = dmi_alloc(sizeof(*dmi_memdev) * dmi_memdev_nr);
363 if (dmi_memdev)
364 dmi_walk_early(save_mem_devices);
365 }
366}
367
325/* 368/*
326 * Process a DMI table entry. Right now all we care about are the BIOS 369 * Process a DMI table entry. Right now all we care about are the BIOS
327 * and machine entries. For 2.5 we should pull the smbus controller info 370 * and machine entries. For 2.5 we should pull the smbus controller info
@@ -815,3 +858,20 @@ bool dmi_match(enum dmi_field f, const char *str)
815 return !strcmp(info, str); 858 return !strcmp(info, str);
816} 859}
817EXPORT_SYMBOL_GPL(dmi_match); 860EXPORT_SYMBOL_GPL(dmi_match);
861
862void dmi_memdev_name(u16 handle, const char **bank, const char **device)
863{
864 int n;
865
866 if (dmi_memdev == NULL)
867 return;
868
869 for (n = 0; n < dmi_memdev_nr; n++) {
870 if (handle == dmi_memdev[n].handle) {
871 *bank = dmi_memdev[n].bank;
872 *device = dmi_memdev[n].device;
873 break;
874 }
875 }
876}
877EXPORT_SYMBOL_GPL(dmi_memdev_name);
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index f082ae55c0c9..4f26bc28e60b 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/sis/init.c
@@ -3320,9 +3320,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
3320} 3320}
3321 3321
3322#ifndef GETBITSTR 3322#ifndef GETBITSTR
3323#define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) 3323#define GENBITSMASK(mask) GENMASK(1?mask,0?mask)
3324#define GENMASK(mask) BITMASK(1?mask,0?mask) 3324#define GETBITS(var,mask) (((var) & GENBITSMASK(mask)) >> (0?mask))
3325#define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask))
3326#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) 3325#define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to))
3327#endif 3326#endif
3328 3327
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 0bd750ebeb49..556c83ee6b42 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -596,7 +596,7 @@ struct acpi_hest_generic {
596 596
597/* Generic Error Status block */ 597/* Generic Error Status block */
598 598
599struct acpi_hest_generic_status { 599struct acpi_generic_status {
600 u32 block_status; 600 u32 block_status;
601 u32 raw_data_offset; 601 u32 raw_data_offset;
602 u32 raw_data_length; 602 u32 raw_data_length;
@@ -606,15 +606,15 @@ struct acpi_hest_generic_status {
606 606
607/* Values for block_status flags above */ 607/* Values for block_status flags above */
608 608
609#define ACPI_HEST_UNCORRECTABLE (1) 609#define ACPI_GEN_ERR_UC BIT(0)
610#define ACPI_HEST_CORRECTABLE (1<<1) 610#define ACPI_GEN_ERR_CE BIT(1)
611#define ACPI_HEST_MULTIPLE_UNCORRECTABLE (1<<2) 611#define ACPI_GEN_ERR_MULTI_UC BIT(2)
612#define ACPI_HEST_MULTIPLE_CORRECTABLE (1<<3) 612#define ACPI_GEN_ERR_MULTI_CE BIT(3)
613#define ACPI_HEST_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ 613#define ACPI_GEN_ERR_COUNT_SHIFT (0xFF<<4) /* 8 bits, error count */
614 614
615/* Generic Error Data entry */ 615/* Generic Error Data entry */
616 616
617struct acpi_hest_generic_data { 617struct acpi_generic_data {
618 u8 section_type[16]; 618 u8 section_type[16];
619 u32 error_severity; 619 u32 error_severity;
620 u16 revision; 620 u16 revision;
diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h
index 720446cb243e..dfd60d0bfd27 100644
--- a/include/acpi/ghes.h
+++ b/include/acpi/ghes.h
@@ -14,7 +14,7 @@
14 14
15struct ghes { 15struct ghes {
16 struct acpi_hest_generic *generic; 16 struct acpi_hest_generic *generic;
17 struct acpi_hest_generic_status *estatus; 17 struct acpi_generic_status *estatus;
18 u64 buffer_paddr; 18 u64 buffer_paddr;
19 unsigned long flags; 19 unsigned long flags;
20 union { 20 union {
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index a5db4aeefa36..c30bac8503bc 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -311,6 +311,7 @@ struct acpi_osc_context {
311#define OSC_INVALID_REVISION_ERROR 8 311#define OSC_INVALID_REVISION_ERROR 8
312#define OSC_CAPABILITIES_MASK_ERROR 16 312#define OSC_CAPABILITIES_MASK_ERROR 16
313 313
314acpi_status acpi_str_to_uuid(char *str, u8 *uuid);
314acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); 315acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
315 316
316/* platform-wide _OSC bits */ 317/* platform-wide _OSC bits */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index a3b6b82108b9..bd0c4598d03b 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -10,6 +10,14 @@
10#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 10#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
11#endif 11#endif
12 12
13/*
14 * Create a contiguous bitmask starting at bit position @l and ending at
15 * position @h. For example
16 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
17 */
18#define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l))
19#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
20
13extern unsigned int __sw_hweight8(unsigned int w); 21extern unsigned int __sw_hweight8(unsigned int w);
14extern unsigned int __sw_hweight16(unsigned int w); 22extern unsigned int __sw_hweight16(unsigned int w);
15extern unsigned int __sw_hweight32(unsigned int w); 23extern unsigned int __sw_hweight32(unsigned int w);
diff --git a/include/linux/cper.h b/include/linux/cper.h
index c23049496531..2fc0ec3d89cc 100644
--- a/include/linux/cper.h
+++ b/include/linux/cper.h
@@ -218,8 +218,8 @@ enum {
218#define CPER_PROC_VALID_IP 0x1000 218#define CPER_PROC_VALID_IP 0x1000
219 219
220#define CPER_MEM_VALID_ERROR_STATUS 0x0001 220#define CPER_MEM_VALID_ERROR_STATUS 0x0001
221#define CPER_MEM_VALID_PHYSICAL_ADDRESS 0x0002 221#define CPER_MEM_VALID_PA 0x0002
222#define CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK 0x0004 222#define CPER_MEM_VALID_PA_MASK 0x0004
223#define CPER_MEM_VALID_NODE 0x0008 223#define CPER_MEM_VALID_NODE 0x0008
224#define CPER_MEM_VALID_CARD 0x0010 224#define CPER_MEM_VALID_CARD 0x0010
225#define CPER_MEM_VALID_MODULE 0x0020 225#define CPER_MEM_VALID_MODULE 0x0020
@@ -232,6 +232,9 @@ enum {
232#define CPER_MEM_VALID_RESPONDER_ID 0x1000 232#define CPER_MEM_VALID_RESPONDER_ID 0x1000
233#define CPER_MEM_VALID_TARGET_ID 0x2000 233#define CPER_MEM_VALID_TARGET_ID 0x2000
234#define CPER_MEM_VALID_ERROR_TYPE 0x4000 234#define CPER_MEM_VALID_ERROR_TYPE 0x4000
235#define CPER_MEM_VALID_RANK_NUMBER 0x8000
236#define CPER_MEM_VALID_CARD_HANDLE 0x10000
237#define CPER_MEM_VALID_MODULE_HANDLE 0x20000
235 238
236#define CPER_PCIE_VALID_PORT_TYPE 0x0001 239#define CPER_PCIE_VALID_PORT_TYPE 0x0001
237#define CPER_PCIE_VALID_VERSION 0x0002 240#define CPER_PCIE_VALID_VERSION 0x0002
@@ -347,6 +350,10 @@ struct cper_sec_mem_err {
347 __u64 responder_id; 350 __u64 responder_id;
348 __u64 target_id; 351 __u64 target_id;
349 __u8 error_type; 352 __u8 error_type;
353 __u8 reserved;
354 __u16 rank;
355 __u16 mem_array_handle; /* card handle in UEFI 2.4 */
356 __u16 mem_dev_handle; /* module handle in UEFI 2.4 */
350}; 357};
351 358
352struct cper_sec_pcie { 359struct cper_sec_pcie {
@@ -389,6 +396,6 @@ struct cper_sec_pcie {
389 396
390u64 cper_next_record_id(void); 397u64 cper_next_record_id(void);
391void cper_print_bits(const char *prefix, unsigned int bits, 398void cper_print_bits(const char *prefix, unsigned int bits,
392 const char *strs[], unsigned int strs_size); 399 const char * const strs[], unsigned int strs_size);
393 400
394#endif 401#endif
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index b6eb7a05d58e..f820f0a336c9 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -99,6 +99,7 @@ extern const char * dmi_get_system_info(int field);
99extern const struct dmi_device * dmi_find_device(int type, const char *name, 99extern const struct dmi_device * dmi_find_device(int type, const char *name,
100 const struct dmi_device *from); 100 const struct dmi_device *from);
101extern void dmi_scan_machine(void); 101extern void dmi_scan_machine(void);
102extern void dmi_memdev_walk(void);
102extern void dmi_set_dump_stack_arch_desc(void); 103extern void dmi_set_dump_stack_arch_desc(void);
103extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); 104extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
104extern int dmi_name_in_vendors(const char *str); 105extern int dmi_name_in_vendors(const char *str);
@@ -107,6 +108,7 @@ extern int dmi_available;
107extern int dmi_walk(void (*decode)(const struct dmi_header *, void *), 108extern int dmi_walk(void (*decode)(const struct dmi_header *, void *),
108 void *private_data); 109 void *private_data);
109extern bool dmi_match(enum dmi_field f, const char *str); 110extern bool dmi_match(enum dmi_field f, const char *str);
111extern void dmi_memdev_name(u16 handle, const char **bank, const char **device);
110 112
111#else 113#else
112 114
@@ -115,6 +117,7 @@ static inline const char * dmi_get_system_info(int field) { return NULL; }
115static inline const struct dmi_device * dmi_find_device(int type, const char *name, 117static inline const struct dmi_device * dmi_find_device(int type, const char *name,
116 const struct dmi_device *from) { return NULL; } 118 const struct dmi_device *from) { return NULL; }
117static inline void dmi_scan_machine(void) { return; } 119static inline void dmi_scan_machine(void) { return; }
120static inline void dmi_memdev_walk(void) { }
118static inline void dmi_set_dump_stack_arch_desc(void) { } 121static inline void dmi_set_dump_stack_arch_desc(void) { }
119static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) 122static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
120{ 123{
@@ -133,6 +136,8 @@ static inline int dmi_walk(void (*decode)(const struct dmi_header *, void *),
133 void *private_data) { return -1; } 136 void *private_data) { return -1; }
134static inline bool dmi_match(enum dmi_field f, const char *str) 137static inline bool dmi_match(enum dmi_field f, const char *str)
135 { return false; } 138 { return false; }
139static inline void dmi_memdev_name(u16 handle, const char **bank,
140 const char **device) { }
136static inline const struct dmi_system_id * 141static inline const struct dmi_system_id *
137 dmi_first_match(const struct dmi_system_id *list) { return NULL; } 142 dmi_first_match(const struct dmi_system_id *list) { return NULL; }
138 143
diff --git a/include/linux/edac.h b/include/linux/edac.h
index 5c6d7fbaf89e..dbdffe8d4469 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -51,7 +51,7 @@ static inline void opstate_init(void)
51#define EDAC_MC_LABEL_LEN 31 51#define EDAC_MC_LABEL_LEN 31
52 52
53/* Maximum size of the location string */ 53/* Maximum size of the location string */
54#define LOCATION_SIZE 80 54#define LOCATION_SIZE 256
55 55
56/* Defines the maximum number of labels that can be reported */ 56/* Defines the maximum number of labels that can be reported */
57#define EDAC_MAX_LABELS 8 57#define EDAC_MAX_LABELS 8