diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-10-26 06:05:11 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-10-26 06:08:29 -0400 |
commit | d69525789e3256968a3867f70015903523c195e3 (patch) | |
tree | 658053ea4a9537f1361212ed34fa25bd28b797c3 | |
parent | 88829dfe4b6ea0c1c24d415668b3bfa78e5a5b16 (diff) | |
parent | 56507694de3453076d73e0e9813349586ee67e59 (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.c | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/mce.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-apei.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 1 | ||||
-rw-r--r-- | drivers/acpi/Kconfig | 19 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/acpi_extlog.c | 327 | ||||
-rw-r--r-- | drivers/acpi/apei/apei-internal.h | 12 | ||||
-rw-r--r-- | drivers/acpi/apei/cper.c | 132 | ||||
-rw-r--r-- | drivers/acpi/apei/ghes.c | 58 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 3 | ||||
-rw-r--r-- | drivers/edac/amd64_edac.c | 46 | ||||
-rw-r--r-- | drivers/edac/amd64_edac.h | 8 | ||||
-rw-r--r-- | drivers/edac/ghes_edac.c | 16 | ||||
-rw-r--r-- | drivers/edac/sb_edac.c | 2 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 60 | ||||
-rw-r--r-- | drivers/video/sis/init.c | 5 | ||||
-rw-r--r-- | include/acpi/actbl1.h | 14 | ||||
-rw-r--r-- | include/acpi/ghes.h | 2 | ||||
-rw-r--r-- | include/linux/acpi.h | 1 | ||||
-rw-r--r-- | include/linux/bitops.h | 8 | ||||
-rw-r--r-- | include/linux/cper.h | 13 | ||||
-rw-r--r-- | include/linux/dmi.h | 5 | ||||
-rw-r--r-- | include/linux/edac.h | 2 |
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) | |||
1063 | static int __init run_dmi_scan(void) | 1063 | static 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 | ||
373 | source "drivers/acpi/apei/Kconfig" | 373 | source "drivers/acpi/apei/Kconfig" |
374 | 374 | ||
375 | config 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 | |||
375 | endif # ACPI | 394 | endif # 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 | |||
82 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o | 82 | obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o |
83 | 83 | ||
84 | obj-$(CONFIG_ACPI_APEI) += apei/ | 84 | obj-$(CONFIG_ACPI_APEI) += apei/ |
85 | |||
86 | obj-$(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 | |||
34 | struct 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 | |||
46 | static u8 extlog_dsm_uuid[] = "663E35AF-CC10-41A4-88EA-5470AF055295"; | ||
47 | |||
48 | /* L1 table related physical address */ | ||
49 | static u64 elog_base; | ||
50 | static size_t elog_size; | ||
51 | static u64 l1_dirbase; | ||
52 | static size_t l1_size; | ||
53 | |||
54 | /* L1 table related virtual address */ | ||
55 | static void __iomem *extlog_l1_addr; | ||
56 | static void __iomem *elog_addr; | ||
57 | |||
58 | static void *elog_buf; | ||
59 | |||
60 | static u64 *l1_entry_base; | ||
61 | static 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 | |||
72 | static 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 | |||
94 | static 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 | |||
113 | static 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 | |||
134 | static 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 | |||
156 | static 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 | |||
196 | static 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 | } | ||
221 | static struct notifier_block extlog_mce_dec = { | ||
222 | .notifier_call = extlog_print, | ||
223 | }; | ||
224 | |||
225 | static 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 | |||
296 | err_release_elog: | ||
297 | if (elog_addr) | ||
298 | acpi_os_unmap_memory(elog_addr, elog_size); | ||
299 | release_mem_region(elog_base, elog_size); | ||
300 | err_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); | ||
304 | err: | ||
305 | pr_warn(FW_BUG "Extended error log disabled because of problems parsing f/w tables\n"); | ||
306 | return rc; | ||
307 | } | ||
308 | |||
309 | static 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 | |||
322 | module_init(extlog_init); | ||
323 | module_exit(extlog_exit); | ||
324 | |||
325 | MODULE_AUTHOR("Chen, Gong <gong.chen@intel.com>"); | ||
326 | MODULE_DESCRIPTION("Extended MCA Error Log Driver"); | ||
327 | MODULE_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; | |||
122 | struct dentry *apei_get_debugfs_dir(void); | 122 | struct 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 | ||
129 | static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) | 129 | static 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 | ||
138 | void apei_estatus_print(const char *pfx, | 138 | void cper_estatus_print(const char *pfx, |
139 | const struct acpi_hest_generic_status *estatus); | 139 | const struct acpi_generic_status *estatus); |
140 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); | 140 | int cper_estatus_check_header(const struct acpi_generic_status *estatus); |
141 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus); | 141 | int cper_estatus_check(const struct acpi_generic_status *estatus); |
142 | 142 | ||
143 | int apei_osc_setup(void); | 143 | int 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 | */ |
75 | void cper_print_bits(const char *pfx, unsigned int bits, | 77 | void 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 | ||
101 | static const char *cper_proc_type_strs[] = { | 103 | static const char * const cper_proc_type_strs[] = { |
102 | "IA32/X64", | 104 | "IA32/X64", |
103 | "IA64", | 105 | "IA64", |
104 | }; | 106 | }; |
105 | 107 | ||
106 | static const char *cper_proc_isa_strs[] = { | 108 | static const char * const cper_proc_isa_strs[] = { |
107 | "IA32", | 109 | "IA32", |
108 | "IA64", | 110 | "IA64", |
109 | "X64", | 111 | "X64", |
110 | }; | 112 | }; |
111 | 113 | ||
112 | static const char *cper_proc_error_type_strs[] = { | 114 | static 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 | ||
119 | static const char *cper_proc_op_strs[] = { | 121 | static 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 | ||
126 | static const char *cper_proc_flag_strs[] = { | 128 | static 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 | ||
196 | static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) | 199 | static 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 | ||
236 | static const char *cper_pcie_port_type_strs[] = { | 250 | static const char *cper_pcie_port_type_strs[] = { |
@@ -248,7 +262,7 @@ static const char *cper_pcie_port_type_strs[] = { | |||
248 | }; | 262 | }; |
249 | 263 | ||
250 | static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, | 264 | static 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 | ||
286 | static const char *apei_estatus_section_flag_strs[] = { | 300 | static 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 | |||
295 | static 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 | ||
342 | void apei_estatus_print(const char *pfx, | 346 | void 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 | } |
364 | EXPORT_SYMBOL_GPL(apei_estatus_print); | 372 | EXPORT_SYMBOL_GPL(cper_estatus_print); |
365 | 373 | ||
366 | int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) | 374 | int 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 | } |
377 | EXPORT_SYMBOL_GPL(apei_estatus_check_header); | 385 | EXPORT_SYMBOL_GPL(cper_estatus_check_header); |
378 | 386 | ||
379 | int apei_estatus_check(const struct acpi_hest_generic_status *estatus) | 387 | int 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 | } |
402 | EXPORT_SYMBOL_GPL(apei_estatus_check); | 410 | EXPORT_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 | ||
87 | bool ghes_disable; | 87 | bool 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 | ||
412 | static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev) | 412 | static 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 | ||
440 | static void ghes_do_proc(struct ghes *ghes, | 440 | static 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 | ||
497 | static void __ghes_print_estatus(const char *pfx, | 497 | static 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 | ||
519 | static int ghes_print_estatus(const char *pfx, | 519 | static 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 | */ |
543 | static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) | 543 | static 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 | ||
572 | static struct ghes_estatus_cache *ghes_estatus_cache_alloc( | 572 | static 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 | ||
620 | static void ghes_estatus_cache_add( | 620 | static 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 | ||
177 | static acpi_status acpi_str_to_uuid(char *str, u8 *uuid) | 177 | acpi_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 | } |
198 | EXPORT_SYMBOL_GPL(acpi_str_to_uuid); | ||
198 | 199 | ||
199 | acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) | 200 | acpi_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 */ |
26 | static char dmi_ids_string[128] __initdata; | 26 | static char dmi_ids_string[128] __initdata; |
27 | 27 | ||
28 | static struct dmi_memdev_info { | ||
29 | const char *device; | ||
30 | const char *bank; | ||
31 | u16 handle; | ||
32 | } *dmi_memdev; | ||
33 | static int dmi_memdev_nr; | ||
34 | |||
28 | static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) | 35 | static 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 | ||
332 | static 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 | |||
339 | static 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 | |||
356 | void __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 | } |
817 | EXPORT_SYMBOL_GPL(dmi_match); | 860 | EXPORT_SYMBOL_GPL(dmi_match); |
861 | |||
862 | void 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 | } | ||
877 | EXPORT_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 | ||
599 | struct acpi_hest_generic_status { | 599 | struct 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 | ||
617 | struct acpi_hest_generic_data { | 617 | struct 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 | ||
15 | struct ghes { | 15 | struct 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 | ||
314 | acpi_status acpi_str_to_uuid(char *str, u8 *uuid); | ||
314 | acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); | 315 | acpi_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 | |||
13 | extern unsigned int __sw_hweight8(unsigned int w); | 21 | extern unsigned int __sw_hweight8(unsigned int w); |
14 | extern unsigned int __sw_hweight16(unsigned int w); | 22 | extern unsigned int __sw_hweight16(unsigned int w); |
15 | extern unsigned int __sw_hweight32(unsigned int w); | 23 | extern 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 | ||
352 | struct cper_sec_pcie { | 359 | struct cper_sec_pcie { |
@@ -389,6 +396,6 @@ struct cper_sec_pcie { | |||
389 | 396 | ||
390 | u64 cper_next_record_id(void); | 397 | u64 cper_next_record_id(void); |
391 | void cper_print_bits(const char *prefix, unsigned int bits, | 398 | void 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); | |||
99 | extern const struct dmi_device * dmi_find_device(int type, const char *name, | 99 | extern const struct dmi_device * dmi_find_device(int type, const char *name, |
100 | const struct dmi_device *from); | 100 | const struct dmi_device *from); |
101 | extern void dmi_scan_machine(void); | 101 | extern void dmi_scan_machine(void); |
102 | extern void dmi_memdev_walk(void); | ||
102 | extern void dmi_set_dump_stack_arch_desc(void); | 103 | extern void dmi_set_dump_stack_arch_desc(void); |
103 | extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); | 104 | extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); |
104 | extern int dmi_name_in_vendors(const char *str); | 105 | extern int dmi_name_in_vendors(const char *str); |
@@ -107,6 +108,7 @@ extern int dmi_available; | |||
107 | extern int dmi_walk(void (*decode)(const struct dmi_header *, void *), | 108 | extern int dmi_walk(void (*decode)(const struct dmi_header *, void *), |
108 | void *private_data); | 109 | void *private_data); |
109 | extern bool dmi_match(enum dmi_field f, const char *str); | 110 | extern bool dmi_match(enum dmi_field f, const char *str); |
111 | extern 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; } | |||
115 | static inline const struct dmi_device * dmi_find_device(int type, const char *name, | 117 | static 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; } |
117 | static inline void dmi_scan_machine(void) { return; } | 119 | static inline void dmi_scan_machine(void) { return; } |
120 | static inline void dmi_memdev_walk(void) { } | ||
118 | static inline void dmi_set_dump_stack_arch_desc(void) { } | 121 | static inline void dmi_set_dump_stack_arch_desc(void) { } |
119 | static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) | 122 | static 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; } |
134 | static inline bool dmi_match(enum dmi_field f, const char *str) | 137 | static inline bool dmi_match(enum dmi_field f, const char *str) |
135 | { return false; } | 138 | { return false; } |
139 | static inline void dmi_memdev_name(u16 handle, const char **bank, | ||
140 | const char **device) { } | ||
136 | static inline const struct dmi_system_id * | 141 | static 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 |