*/
#include <string.h>
+#include <stdio.h>
#include "ras-mce-handler.h"
#define MCE_THERMAL_BANK (MCE_EXTENDED_BANK + 0)
#define MCE_TIMEOUT_BANK (MCE_EXTENDED_BANK + 90)
+static decode_termal_bank(struct mce_event *e)
+{
+ if (e->status & 1)
+ sprintf(e->error_msg, "Processor %d heated above trip temperature. Throttling enabled. Please check your system cooling. Performance will be impacted", e->cpu);
+ else
+ sprintf(e->error_msg, "Processor %d below trip temperature. Throttling disabled", e->cpu);
+}
+
+static void decode_mcg(struct mce_event *e)
+{
+ int n, len = sizeof(e->mcgstatus_msg);
+ uint64_t mcgstatus = e->mcgstatus;
+ char *p = e->mcgstatus_msg;
+
+ n = snprintf(p, len, "mcgstatus= %d ", e->mcgstatus);
+
+ if (mcgstatus & MCG_STATUS_RIPV) {
+ n = snprintf(p, len, " RIPV");
+ p += n;
+ len -= n;
+ }
+ if (mcgstatus & MCG_STATUS_EIPV) {
+ n = snprintf(p, len, " EIPV");
+ p += n;
+ len -= n;
+ }
+ if (mcgstatus & MCG_STATUS_MCIP) {
+ n = snprintf(p, len, " MCIP");
+ p += n;
+ len -= n;
+ }
+}
+
static void bank_name(struct mce_event *e)
{
char *buf = e->bank_name;
{
bank_name(e);
+ if (e->bank == MCE_THERMAL_BANK) {
+ decode_termal_bank(e);
+ return 0;
+ }
+ decode_mcg(e);
+
return 0;
}
else
trace_seq_printf(s, "bank=%x", e->bank);
- trace_seq_printf(s, ", status= %d ", e->status);
+ trace_seq_printf(s, ", status= %d", e->status);
if (*e->error_msg)
- trace_seq_printf(s, ", %s ", e->error_msg);
+ trace_seq_printf(s, ", %s", e->error_msg);
#if 0
/*
* decode/print it, if we already got the uptime from the
* tracing event? Let's just discard it for now.
*/
- trace_seq_printf(s, ", tsc= %d ", e->tsc);
- trace_seq_printf(s, ", walltime= %d ", e->walltime);
+ trace_seq_printf(s, ", tsc= %d", e->tsc);
+ trace_seq_printf(s, ", walltime= %d", e->walltime);
#endif
- trace_seq_printf(s, "CPU: %s, ", cputype_name[mce->cputype]);
- trace_seq_printf(s, ", cpu= %d ", e->cpu);
- trace_seq_printf(s, ", socketid= %d ", e->socketid);
+ trace_seq_printf(s, ", CPU: %s,", cputype_name[mce->cputype]);
+ trace_seq_printf(s, ", cpu= %d", e->cpu);
+ trace_seq_printf(s, ", socketid= %d", e->socketid);
#if 0
/*
* The CPU vendor is already reported from mce->cputype
*/
trace_seq_printf(s, ", cpuvendor= %d", e->cpuvendor);
- trace_seq_printf(s, ", cpuid= %d ", e->cpuid);
+ trace_seq_printf(s, ", cpuid= %d", e->cpuid);
#endif
if (e->ip)
- trace_seq_printf(s, ", ip= %d%s ",
+ trace_seq_printf(s, ", ip= %d%s",
!(e->mcgstatus & MCG_STATUS_EIPV) ? " (INEXACT)" : "",
e->ip);
if (e->cs)
- trace_seq_printf(s, ", cs= %d ", e->cs);
+ trace_seq_printf(s, ", cs= %d", e->cs);
if (e->status & MCI_STATUS_MISCV)
- trace_seq_printf(s, ", misc= %d ", e->misc);
+ trace_seq_printf(s, ", misc= %d", e->misc);
if (e->status & MCI_STATUS_ADDRV)
- trace_seq_printf(s, ", addr= %d ", e->addr);
+ trace_seq_printf(s, ", addr= %d", e->addr);
- trace_seq_printf(s, ", mcgstatus= %d ", e->mcgstatus);
+ if (e->mcgstatus_msg)
+ trace_seq_printf(s, ", %s", e->mcgstatus_msg);
+ else
+ trace_seq_printf(s, ", mcgstatus= %d", e->mcgstatus);
if (e->mcgcap)
- trace_seq_printf(s, ", mcgcap= %d ", e->mcgcap);
+ trace_seq_printf(s, ", mcgcap= %d", e->mcgcap);
- trace_seq_printf(s, ", apicid= %d ", e->apicid);
+ trace_seq_printf(s, ", apicid= %d", e->apicid);
/*
* FIXME: The original mcelog userspace tool uses DMI to map from