提交 fe3f0ee8 编写于 作者: S Shengwei Luo 提交者: Zheng Zengkai

RAS: Report ARM processor information to userspace

kunpeng inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4OUGN?from=project-issue
CVE: NA

The original arm_event trace code only traces out ARM processor error
information data. It's not enough for user to take appropriate action.

According to UEFI_2_9 specification chapter N2.4.4, the ARM processor
error section includes several ARM processor error information, several
ARM processor context information and several vendor specific error
information structures. In addition to these info, there are error
severity and cpu logical index about the event. Report all of these
information to userspace via perf i/f. So that the user can do cpu core
isolation according to error severity and other info.

Original-Author: Jason Tian <jason@os.amperecomputing.com>
Signed-off-by: NShengwei Luo <luoshengwei@huawei.com>
Reviewed-by: NLv Ying <lvying6@huawei.com>
Reviewed-by: NTan Xiaofei <tanxiaofei@huawei.com>
Acked-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 c37700f3
......@@ -493,9 +493,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int s
int sec_sev, i;
char *p;
log_arm_hw_error(err);
sec_sev = ghes_severity(gdata->error_severity);
log_arm_hw_error(err, sec_sev);
if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE)
return false;
......
......@@ -21,9 +21,51 @@ void log_non_standard_event(const guid_t *sec_type, const guid_t *fru_id,
trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len);
}
void log_arm_hw_error(struct cper_sec_proc_arm *err)
void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev)
{
trace_arm_event(err);
u32 pei_len;
u32 ctx_len = 0;
s32 vsei_len;
u8 *pei_err;
u8 *ctx_err;
u8 *ven_err_data;
struct cper_arm_err_info *err_info;
struct cper_arm_ctx_info *ctx_info;
int n, sz;
int cpu;
pei_len = sizeof(struct cper_arm_err_info) * err->err_info_num;
pei_err = (u8 *)err + sizeof(struct cper_sec_proc_arm);
err_info = (struct cper_arm_err_info *)(err + 1);
ctx_info = (struct cper_arm_ctx_info *)(err_info + err->err_info_num);
ctx_err = (u8 *)ctx_info;
for (n = 0; n < err->context_info_num; n++) {
sz = sizeof(struct cper_arm_ctx_info) + ctx_info->size;
ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + sz);
ctx_len += sz;
}
vsei_len = err->section_length - (sizeof(struct cper_sec_proc_arm) +
pei_len + ctx_len);
if (vsei_len < 0) {
pr_warn(FW_BUG
"section length: %d\n", err->section_length);
pr_warn(FW_BUG
"section length is too small\n");
pr_warn(FW_BUG
"firmware-generated error record is incorrect\n");
vsei_len = 0;
}
ven_err_data = (u8 *)ctx_info;
cpu = GET_LOGICAL_INDEX(err->mpidr);
/* when return value is invalid, set cpu index to -1 */
if (cpu < 0)
cpu = -1;
trace_arm_event(err, pei_err, pei_len, ctx_err, ctx_len,
ven_err_data, (u32)vsei_len, sev, cpu);
}
static int __init ras_init(void)
......
......@@ -24,7 +24,7 @@ int __init parse_cec_param(char *str);
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);
void log_arm_hw_error(struct cper_sec_proc_arm *err);
void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev);
#else
static inline void
log_non_standard_event(const guid_t *sec_type,
......@@ -32,7 +32,18 @@ log_non_standard_event(const guid_t *sec_type,
const u8 sev, const u8 *err, const u32 len)
{ return; }
static inline void
log_arm_hw_error(struct cper_sec_proc_arm *err) { return; }
log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; }
#endif
#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
#include <asm/smp_plat.h>
/*
* Include ARM specific SMP header which provides a function mapping mpidr to
* cpu logical index.
*/
#define GET_LOGICAL_INDEX(mpidr) get_logical_index(mpidr & MPIDR_HWID_BITMASK)
#else
#define GET_LOGICAL_INDEX(mpidr) -EINVAL
#endif /* CONFIG_ARM || CONFIG_ARM64 */
#endif /* __RAS_H__ */
......@@ -168,11 +168,24 @@ TRACE_EVENT(mc_event,
* This event is generated when hardware detects an ARM processor error
* has occurred. UEFI 2.6 spec section N.2.4.4.
*/
#define APEIL "ARM Processor Err Info data len"
#define APEID "ARM Processor Err Info raw data"
#define APECIL "ARM Processor Err Context Info data len"
#define APECID "ARM Processor Err Context Info raw data"
#define VSEIL "Vendor Specific Err Info data len"
#define VSEID "Vendor Specific Err Info raw data"
TRACE_EVENT(arm_event,
TP_PROTO(const struct cper_sec_proc_arm *proc),
TP_PROTO(const struct cper_sec_proc_arm *proc, const u8 *pei_err,
const u32 pei_len,
const u8 *ctx_err,
const u32 ctx_len,
const u8 *oem,
const u32 oem_len,
u8 sev,
int cpu),
TP_ARGS(proc),
TP_ARGS(proc, pei_err, pei_len, ctx_err, ctx_len, oem, oem_len, sev, cpu),
TP_STRUCT__entry(
__field(u64, mpidr)
......@@ -180,6 +193,14 @@ TRACE_EVENT(arm_event,
__field(u32, running_state)
__field(u32, psci_state)
__field(u8, affinity)
__field(u32, pei_len)
__dynamic_array(u8, buf, pei_len)
__field(u32, ctx_len)
__dynamic_array(u8, buf1, ctx_len)
__field(u32, oem_len)
__dynamic_array(u8, buf2, oem_len)
__field(u8, sev)
__field(int, cpu)
),
TP_fast_assign(
......@@ -199,12 +220,29 @@ TRACE_EVENT(arm_event,
__entry->running_state = ~0;
__entry->psci_state = ~0;
}
__entry->pei_len = pei_len;
memcpy(__get_dynamic_array(buf), pei_err, pei_len);
__entry->ctx_len = ctx_len;
memcpy(__get_dynamic_array(buf1), ctx_err, ctx_len);
__entry->oem_len = oem_len;
memcpy(__get_dynamic_array(buf2), oem, oem_len);
__entry->sev = sev;
__entry->cpu = cpu;
),
TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
"running state: %d; PSCI state: %d",
TP_printk("cpu: %d; error: %d; affinity level: %d; MPIDR: %016llx; MIDR: %016llx; "
"running state: %d; PSCI state: %d; "
"%s: %d; %s: %s; %s: %d; %s: %s; %s: %d; %s: %s",
__entry->cpu,
__entry->sev,
__entry->affinity, __entry->mpidr, __entry->midr,
__entry->running_state, __entry->psci_state)
__entry->running_state, __entry->psci_state,
APEIL, __entry->pei_len, APEID,
__print_hex(__get_dynamic_array(buf), __entry->pei_len),
APECIL, __entry->ctx_len, APECID,
__print_hex(__get_dynamic_array(buf1), __entry->ctx_len),
VSEIL, __entry->oem_len, VSEID,
__print_hex(__get_dynamic_array(buf2), __entry->oem_len))
);
/*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册