#include <linux/aer.h>
#include <linux/nmi.h>
#include <linux/sched/clock.h>
+#include <linux/uuid.h>
+#include <linux/ras.h>
#include <acpi/actbl1.h>
#include <acpi/ghes.h>
#include <acpi/apei.h>
#include <asm/tlbflush.h>
+#include <ras/ras_event.h>
#include "apei-internal.h"
int sev, sec_sev;
struct acpi_hest_generic_data *gdata;
guid_t *sec_type;
+ guid_t *fru_id = &NULL_UUID_LE;
+ char *fru_text = "";
sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) {
sec_type = (guid_t *)gdata->section_type;
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)) {
struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata);
}
#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);
+ }
}
}
#include <linux/init.h>
#include <linux/ras.h>
+#include <linux/uuid.h>
#define CREATE_TRACE_POINTS
#define TRACE_INCLUDE_PATH ../../include/ras
#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)
{
int rc = 0;
EXPORT_TRACEPOINT_SYMBOL_GPL(extlog_mem_event);
#endif
EXPORT_TRACEPOINT_SYMBOL_GPL(mc_event);
-
+EXPORT_TRACEPOINT_SYMBOL_GPL(non_standard_event);
int __init parse_ras_param(char *str)
{
#define __RAS_H__
#include <asm/errno.h>
+#include <linux/uuid.h>
#ifdef CONFIG_DEBUG_FS
int ras_userspace_consumers(void);
static inline int cec_add_elem(u64 pfn) { return -ENODEV; }
#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__ */
#include <uapi/linux/uuid.h>
+#define UUID_SIZE 16
+
typedef struct {
- __u8 b[16];
+ __u8 b[UUID_SIZE];
} uuid_t;
#define UUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
__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
*