aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Baicar <tbaicar@codeaurora.org>2017-06-21 14:17:12 -0400
committerWill Deacon <will.deacon@arm.com>2017-06-22 13:22:04 -0400
commit297b64c74385fc7ea5dfff66105ab6465f2df49a (patch)
tree15a8b282ffd961212f834930c246cbdfa2b39f01
parent0fc300f414519b10c146fc3329a1b3094e4b6d52 (diff)
ras: acpi / apei: generate trace event for unrecognized CPER section
The UEFI spec includes non-standard section type support in the Common Platform Error Record. This is defined in section N.2.3 of UEFI version 2.5. Currently if the CPER section's type (UUID) does not match any section type that the kernel knows how to parse, a trace event is not generated. Generate a trace event which contains the raw error data for non-standard section type error records. Signed-off-by: Tyler Baicar <tbaicar@codeaurora.org> CC: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org> Tested-by: Shiju Jose <shiju.jose@huawei.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--drivers/acpi/apei/ghes.c18
-rw-r--r--drivers/ras/ras.c10
-rw-r--r--include/linux/ras.h12
-rw-r--r--include/linux/uuid.h4
-rw-r--r--include/ras/ras_event.h45
5 files changed, 87 insertions, 2 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 7a91ac7d6b75..ab36ad628c68 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -45,11 +45,14 @@
45#include <linux/aer.h> 45#include <linux/aer.h>
46#include <linux/nmi.h> 46#include <linux/nmi.h>
47#include <linux/sched/clock.h> 47#include <linux/sched/clock.h>
48#include <linux/uuid.h>
49#include <linux/ras.h>
48 50
49#include <acpi/actbl1.h> 51#include <acpi/actbl1.h>
50#include <acpi/ghes.h> 52#include <acpi/ghes.h>
51#include <acpi/apei.h> 53#include <acpi/apei.h>
52#include <asm/tlbflush.h> 54#include <asm/tlbflush.h>
55#include <ras/ras_event.h>
53 56
54#include "apei-internal.h" 57#include "apei-internal.h"
55 58
@@ -461,11 +464,19 @@ static void ghes_do_proc(struct ghes *ghes,
461 int sev, sec_sev; 464 int sev, sec_sev;
462 struct acpi_hest_generic_data *gdata; 465 struct acpi_hest_generic_data *gdata;
463 guid_t *sec_type; 466 guid_t *sec_type;
467 guid_t *fru_id = &NULL_UUID_LE;
468 char *fru_text = "";
464 469
465 sev = ghes_severity(estatus->error_severity); 470 sev = ghes_severity(estatus->error_severity);
466 apei_estatus_for_each_section(estatus, gdata) { 471 apei_estatus_for_each_section(estatus, gdata) {
467 sec_type = (guid_t *)gdata->section_type; 472 sec_type = (guid_t *)gdata->section_type;
468 sec_sev = ghes_severity(gdata->error_severity); 473 sec_sev = ghes_severity(gdata->error_severity);
474 if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
475 fru_id = (guid_t *)gdata->fru_id;
476
477 if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
478 fru_text = gdata->fru_text;
479
469 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { 480 if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
470 struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); 481 struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
471 482
@@ -506,6 +517,13 @@ static void ghes_do_proc(struct ghes *ghes,
506 517
507 } 518 }
508#endif 519#endif
520 else {
521 void *err = acpi_hest_get_payload(gdata);
522
523 log_non_standard_event(sec_type, fru_id, fru_text,
524 sec_sev, err,
525 gdata->error_data_length);
526 }
509 } 527 }
510} 528}
511 529
diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c
index 94f8038864b4..e87fd9e32ee2 100644
--- a/drivers/ras/ras.c
+++ b/drivers/ras/ras.c
@@ -7,11 +7,19 @@
7 7
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/ras.h> 9#include <linux/ras.h>
10#include <linux/uuid.h>
10 11
11#define CREATE_TRACE_POINTS 12#define CREATE_TRACE_POINTS
12#define TRACE_INCLUDE_PATH ../../include/ras 13#define TRACE_INCLUDE_PATH ../../include/ras
13#include <ras/ras_event.h> 14#include <ras/ras_event.h>
14 15
16void log_non_standard_event(const uuid_le *sec_type, const uuid_le *fru_id,
17 const char *fru_text, const u8 sev, const u8 *err,
18 const u32 len)
19{
20 trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len);
21}
22
15static int __init ras_init(void) 23static int __init ras_init(void)
16{ 24{
17 int rc = 0; 25 int rc = 0;
@@ -27,7 +35,7 @@ subsys_initcall(ras_init);
27EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event); 35EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
28#endif 36#endif
29EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event); 37EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
30 38EXPORT_TRACEPOINT_SYMBOL_GPL(non_standard_event);
31 39
32int __init parse_ras_param(char *str) 40int __init parse_ras_param(char *str)
33{ 41{
diff --git a/include/linux/ras.h b/include/linux/ras.h
index ffb147185e8d..62fac3042dce 100644
--- a/include/linux/ras.h
+++ b/include/linux/ras.h
@@ -2,6 +2,7 @@
2#define __RAS_H__ 2#define __RAS_H__
3 3
4#include <asm/errno.h> 4#include <asm/errno.h>
5#include <linux/uuid.h>
5 6
6#ifdef CONFIG_DEBUG_FS 7#ifdef CONFIG_DEBUG_FS
7int ras_userspace_consumers(void); 8int ras_userspace_consumers(void);
@@ -22,4 +23,15 @@ static inline void __init cec_init(void) { }
22static inline int cec_add_elem(u64 pfn) { return -ENODEV; } 23static inline int cec_add_elem(u64 pfn) { return -ENODEV; }
23#endif 24#endif
24 25
26#ifdef CONFIG_RAS
27void log_non_standard_event(const guid_t *sec_type,
28 const guid_t *fru_id, const char *fru_text,
29 const u8 sev, const u8 *err, const u32 len);
30#else
31static void log_non_standard_event(const guid_t *sec_type,
32 const guid_t *fru_id, const char *fru_text,
33 const u8 sev, const u8 *err,
34 const u32 len) { return; }
35#endif
36
25#endif /* __RAS_H__ */ 37#endif /* __RAS_H__ */
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 75f7182d5360..61641faca38b 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -18,8 +18,10 @@
18 18
19#include <uapi/linux/uuid.h> 19#include <uapi/linux/uuid.h>
20 20
21#define UUID_SIZE 16
22
21typedef struct { 23typedef struct {
22 __u8 b[16]; 24 __u8 b[UUID_SIZE];
23} uuid_t; 25} uuid_t;
24 26
25#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ 27#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 1791a12cfa85..4f79ba94fa6b 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -162,6 +162,51 @@ TRACE_EVENT(mc_event,
162); 162);
163 163
164/* 164/*
165 * Non-Standard Section Report
166 *
167 * This event is generated when hardware detected a hardware
168 * error event, which may be of non-standard section as defined
169 * in UEFI spec appendix "Common Platform Error Record", or may
170 * be of sections for which TRACE_EVENT is not defined.
171 *
172 */
173TRACE_EVENT(non_standard_event,
174
175 TP_PROTO(const uuid_le *sec_type,
176 const uuid_le *fru_id,
177 const char *fru_text,
178 const u8 sev,
179 const u8 *err,
180 const u32 len),
181
182 TP_ARGS(sec_type, fru_id, fru_text, sev, err, len),
183
184 TP_STRUCT__entry(
185 __array(char, sec_type, UUID_SIZE)
186 __array(char, fru_id, UUID_SIZE)
187 __string(fru_text, fru_text)
188 __field(u8, sev)
189 __field(u32, len)
190 __dynamic_array(u8, buf, len)
191 ),
192
193 TP_fast_assign(
194 memcpy(__entry->sec_type, sec_type, UUID_SIZE);
195 memcpy(__entry->fru_id, fru_id, UUID_SIZE);
196 __assign_str(fru_text, fru_text);
197 __entry->sev = sev;
198 __entry->len = len;
199 memcpy(__get_dynamic_array(buf), err, len);
200 ),
201
202 TP_printk("severity: %d; sec type:%pU; FRU: %pU %s; data len:%d; raw data:%s",
203 __entry->sev, __entry->sec_type,
204 __entry->fru_id, __get_str(fru_text),
205 __entry->len,
206 __print_hex(__get_dynamic_array(buf), __entry->len))
207);
208
209/*
165 * PCIe AER Trace event 210 * PCIe AER Trace event
166 * 211 *
167 * These events are generated when hardware detects a corrected or 212 * These events are generated when hardware detects a corrected or