Commit 297b64c7 authored by Tyler Baicar's avatar Tyler Baicar Committed by Will Deacon

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: default avatarTyler Baicar <tbaicar@codeaurora.org>
CC: Jonathan (Zhixiong) Zhang <zjzhang@codeaurora.org>
Tested-by: default avatarShiju Jose <shiju.jose@huawei.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 0fc300f4
...@@ -45,11 +45,14 @@ ...@@ -45,11 +45,14 @@
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/nmi.h> #include <linux/nmi.h>
#include <linux/sched/clock.h> #include <linux/sched/clock.h>
#include <linux/uuid.h>
#include <linux/ras.h>
#include <acpi/actbl1.h> #include <acpi/actbl1.h>
#include <acpi/ghes.h> #include <acpi/ghes.h>
#include <acpi/apei.h> #include <acpi/apei.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <ras/ras_event.h>
#include "apei-internal.h" #include "apei-internal.h"
...@@ -461,11 +464,19 @@ static void ghes_do_proc(struct ghes *ghes, ...@@ -461,11 +464,19 @@ static void ghes_do_proc(struct ghes *ghes,
int sev, sec_sev; int sev, sec_sev;
struct acpi_hest_generic_data *gdata; struct acpi_hest_generic_data *gdata;
guid_t *sec_type; guid_t *sec_type;
guid_t *fru_id = &NULL_UUID_LE;
char *fru_text = "";
sev = ghes_severity(estatus->error_severity); sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) { apei_estatus_for_each_section(estatus, gdata) {
sec_type = (guid_t *)gdata->section_type; sec_type = (guid_t *)gdata->section_type;
sec_sev = ghes_severity(gdata->error_severity); sec_sev = ghes_severity(gdata->error_severity);
if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
fru_id = (guid_t *)gdata->fru_id;
if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
fru_text = gdata->fru_text;
if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) { if (guid_equal(sec_type, &CPER_SEC_PLATFORM_MEM)) {
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
...@@ -506,6 +517,13 @@ static void ghes_do_proc(struct ghes *ghes, ...@@ -506,6 +517,13 @@ static void ghes_do_proc(struct ghes *ghes,
} }
#endif #endif
else {
void *err = acpi_hest_get_payload(gdata);
log_non_standard_event(sec_type, fru_id, fru_text,
sec_sev, err,
gdata->error_data_length);
}
} }
} }
......
...@@ -7,11 +7,19 @@ ...@@ -7,11 +7,19 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ras.h> #include <linux/ras.h>
#include <linux/uuid.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH ../../include/ras #define TRACE_INCLUDE_PATH ../../include/ras
#include <ras/ras_event.h> #include <ras/ras_event.h>
void log_non_standard_event(const uuid_le *sec_type, const uuid_le *fru_id,
const char *fru_text, const u8 sev, const u8 *err,
const u32 len)
{
trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len);
}
static int __init ras_init(void) static int __init ras_init(void)
{ {
int rc = 0; int rc = 0;
...@@ -27,7 +35,7 @@ subsys_initcall(ras_init); ...@@ -27,7 +35,7 @@ subsys_initcall(ras_init);
EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event); EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
#endif #endif
EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event); EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(non_standard_event);
int __init parse_ras_param(char *str) int __init parse_ras_param(char *str)
{ {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define __RAS_H__ #define __RAS_H__
#include <asm/errno.h> #include <asm/errno.h>
#include <linux/uuid.h>
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
int ras_userspace_consumers(void); int ras_userspace_consumers(void);
...@@ -22,4 +23,15 @@ static inline void __init cec_init(void) { } ...@@ -22,4 +23,15 @@ static inline void __init cec_init(void) { }
static inline int cec_add_elem(u64 pfn) { return -ENODEV; } static inline int cec_add_elem(u64 pfn) { return -ENODEV; }
#endif #endif
#ifdef CONFIG_RAS
void log_non_standard_event(const guid_t *sec_type,
const guid_t *fru_id, const char *fru_text,
const u8 sev, const u8 *err, const u32 len);
#else
static void log_non_standard_event(const guid_t *sec_type,
const guid_t *fru_id, const char *fru_text,
const u8 sev, const u8 *err,
const u32 len) { return; }
#endif
#endif /* __RAS_H__ */ #endif /* __RAS_H__ */
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
#include <uapi/linux/uuid.h> #include <uapi/linux/uuid.h>
#define UUID_SIZE 16
typedef struct { typedef struct {
__u8 b[16]; __u8 b[UUID_SIZE];
} uuid_t; } uuid_t;
#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \ #define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
......
...@@ -161,6 +161,51 @@ TRACE_EVENT(mc_event, ...@@ -161,6 +161,51 @@ TRACE_EVENT(mc_event,
__get_str(driver_detail)) __get_str(driver_detail))
); );
/*
* Non-Standard Section Report
*
* This event is generated when hardware detected a hardware
* error event, which may be of non-standard section as defined
* in UEFI spec appendix "Common Platform Error Record", or may
* be of sections for which TRACE_EVENT is not defined.
*
*/
TRACE_EVENT(non_standard_event,
TP_PROTO(const uuid_le *sec_type,
const uuid_le *fru_id,
const char *fru_text,
const u8 sev,
const u8 *err,
const u32 len),
TP_ARGS(sec_type, fru_id, fru_text, sev, err, len),
TP_STRUCT__entry(
__array(char, sec_type, UUID_SIZE)
__array(char, fru_id, UUID_SIZE)
__string(fru_text, fru_text)
__field(u8, sev)
__field(u32, len)
__dynamic_array(u8, buf, len)
),
TP_fast_assign(
memcpy(__entry->sec_type, sec_type, UUID_SIZE);
memcpy(__entry->fru_id, fru_id, UUID_SIZE);
__assign_str(fru_text, fru_text);
__entry->sev = sev;
__entry->len = len;
memcpy(__get_dynamic_array(buf), err, len);
),
TP_printk("severity: %d; sec type:%pU; FRU: %pU %s; data len:%d; raw data:%s",
__entry->sev, __entry->sec_type,
__entry->fru_id, __get_str(fru_text),
__entry->len,
__print_hex(__get_dynamic_array(buf), __entry->len))
);
/* /*
* PCIe AER Trace event * PCIe AER Trace event
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment