Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db819d60 authored by Yazen Ghannam's avatar Yazen Ghannam Committed by Thomas Gleixner
Browse files

x86/mce: Add support for new MCA_SYND register



Syndrome information is no longer contained in MCA_STATUS for SMCA
systems but in a new register - MCA_SYND.

Add a synd field to struct mce to hold MCA_SYND register value. Add it
to the end of struct mce to maintain compatibility with old versions of
mcelog. Also, add it to the respective tracepoint.

Signed-off-by: default avatarYazen Ghannam <Yazen.Ghannam@amd.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1467633035-32080-1-git-send-email-Yazen.Ghannam@amd.com


Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 74ab0e7a
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -40,9 +40,10 @@
#define MCI_STATUS_AR	 (1ULL<<55)  /* Action required */

/* AMD-specific bits */
#define MCI_STATUS_TCC		(1ULL<<55)  /* Task context corrupt */
#define MCI_STATUS_SYNDV	(1ULL<<53)  /* synd reg. valid */
#define MCI_STATUS_DEFERRED	(1ULL<<44)  /* uncorrected error, deferred exception */
#define MCI_STATUS_POISON	(1ULL<<43)  /* access poisonous data */
#define MCI_STATUS_TCC		(1ULL<<55)  /* Task context corrupt */

/*
 * McaX field if set indicates a given bank supports MCA extensions:
@@ -110,6 +111,7 @@
#define MSR_AMD64_SMCA_MC0_MISC0	0xc0002003
#define MSR_AMD64_SMCA_MC0_CONFIG	0xc0002004
#define MSR_AMD64_SMCA_MC0_IPID		0xc0002005
#define MSR_AMD64_SMCA_MC0_SYND		0xc0002006
#define MSR_AMD64_SMCA_MC0_DESTAT	0xc0002008
#define MSR_AMD64_SMCA_MC0_DEADDR	0xc0002009
#define MSR_AMD64_SMCA_MC0_MISC1	0xc000200a
@@ -119,6 +121,7 @@
#define MSR_AMD64_SMCA_MCx_MISC(x)	(MSR_AMD64_SMCA_MC0_MISC0 + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_CONFIG(x)	(MSR_AMD64_SMCA_MC0_CONFIG + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_IPID(x)	(MSR_AMD64_SMCA_MC0_IPID + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_SYND(x)	(MSR_AMD64_SMCA_MC0_SYND + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_DESTAT(x)	(MSR_AMD64_SMCA_MC0_DESTAT + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_DEADDR(x)	(MSR_AMD64_SMCA_MC0_DEADDR + 0x10*(x))
#define MSR_AMD64_SMCA_MCx_MISCy(x, y)	((MSR_AMD64_SMCA_MC0_MISC1 + y) + (0x10*(x)))
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ struct mce {
	__u32 socketid;	/* CPU socket ID */
	__u32 apicid;	/* CPU initial apic ID */
	__u64 mcgcap;	/* MCGCAP MSR: machine check capabilities of CPU */
	__u64 synd;	/* MCA_SYND MSR: only valid on SMCA systems */
};

#define MCE_GET_RECORD_LEN   _IOR('M', 1, int)
+4 −0
Original line number Diff line number Diff line
@@ -569,6 +569,7 @@ static void mce_read_aux(struct mce *m, int i)
{
	if (m->status & MCI_STATUS_MISCV)
		m->misc = mce_rdmsrl(msr_ops.misc(i));

	if (m->status & MCI_STATUS_ADDRV) {
		m->addr = mce_rdmsrl(msr_ops.addr(i));

@@ -581,6 +582,9 @@ static void mce_read_aux(struct mce *m, int i)
			m->addr <<= shift;
		}
	}

	if (mce_flags.smca && (m->status & MCI_STATUS_SYNDV))
		m->synd = mce_rdmsrl(MSR_AMD64_SMCA_MCx_SYND(i));
}

static bool memory_error(struct mce *m)
+3 −0
Original line number Diff line number Diff line
@@ -479,6 +479,9 @@ __log_error(unsigned int bank, bool deferred_err, bool threshold_err, u64 misc)
	if (m.status & MCI_STATUS_ADDRV)
		rdmsrl(msr_addr, m.addr);

	if (mce_flags.smca && (m.status & MCI_STATUS_SYNDV))
		rdmsrl(MSR_AMD64_SMCA_MCx_SYND(bank), m.synd);

	mce_log(&m);

	wrmsrl(msr_status, 0);
+4 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ TRACE_EVENT(mce_record,
		__field(	u64,		status		)
		__field(	u64,		addr		)
		__field(	u64,		misc		)
		__field(	u64,		synd		)
		__field(	u64,		ip		)
		__field(	u64,		tsc		)
		__field(	u64,		walltime	)
@@ -38,6 +39,7 @@ TRACE_EVENT(mce_record,
		__entry->status		= m->status;
		__entry->addr		= m->addr;
		__entry->misc		= m->misc;
		__entry->synd		= m->synd;
		__entry->ip		= m->ip;
		__entry->tsc		= m->tsc;
		__entry->walltime	= m->time;
@@ -50,11 +52,11 @@ TRACE_EVENT(mce_record,
		__entry->cpuvendor	= m->cpuvendor;
	),

	TP_printk("CPU: %d, MCGc/s: %llx/%llx, MC%d: %016Lx, ADDR/MISC: %016Lx/%016Lx, RIP: %02x:<%016Lx>, TSC: %llx, PROCESSOR: %u:%x, TIME: %llu, SOCKET: %u, APIC: %x",
	TP_printk("CPU: %d, MCGc/s: %llx/%llx, MC%d: %016Lx, ADDR/MISC/SYND: %016Lx/%016Lx/%016Lx, RIP: %02x:<%016Lx>, TSC: %llx, PROCESSOR: %u:%x, TIME: %llu, SOCKET: %u, APIC: %x",
		__entry->cpu,
		__entry->mcgcap, __entry->mcgstatus,
		__entry->bank, __entry->status,
		__entry->addr, __entry->misc,
		__entry->addr, __entry->misc, __entry->synd,
		__entry->cs, __entry->ip,
		__entry->tsc,
		__entry->cpuvendor, __entry->cpuid,