This is a revert of this mainline patch:

From: Andi Kleen <ak@linux.intel.com>
Subject: Remove old xeon75xx aux format support
Git-commit: 3e56df89b275669a03f037abad6881a05cbb001a


Signed-off-by: Thomas Renninger <trenn@suse.de>

The xeon75xx special memory error reporting code
has never been merged into mainline kernels. Remove it from
mcelog too to avoid ABI divergence.

Signed-off-by: Andi Kleen <ak@linux.intel.com>

---
 mcelog.c   |   16 +++++++
 mcelog.h   |    2 
 xeon75xx.c |  131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 147 insertions(+), 2 deletions(-)

Index: mcelog-1.0.2012.11.05/mcelog.c
===================================================================
--- mcelog-1.0.2012.11.05.orig/mcelog.c
+++ mcelog-1.0.2012.11.05/mcelog.c
@@ -446,6 +446,10 @@ static void dump_mce_raw_ascii(struct mc
 	CPRINT("SOCKETID %u", socketid);
 	CPRINT("APICID %u", apicid);
 	CPRINT("MCGCAP %#llx", mcgcap);
+	if (m->aux0)
+		CPRINT("AUX0 %#llx", aux0);
+	if (m->aux1)
+		CPRINT("AUX1 %#llx", aux1);
 #undef CPRINT
 	Wprintf("\n");
 }
@@ -798,6 +802,18 @@ restart:
 				FIELD(cpuvendor);
 			}
 		} 
+		else if (!strncmp(s, "AUX0", 4)) {
+			if ((n = sscanf(s, "AUX0 %llx%n", &m.aux0, &next)) != 1)
+				missing++;
+			else
+				FIELD(aux0);
+		}
+		else if (!strncmp(s, "AUX1", 4)) {
+			if ((n = sscanf(s, "AUX1 %llx%n", &m.aux1, &next)) != 1)
+				missing++;
+			else
+				FIELD(aux1);
+		}
 		else if (strstr(s, "HARDWARE ERROR"))
 			disclaimer_seen = 1;
 		else if (!strncmp(s, "(XEN)", 5)) {
Index: mcelog-1.0.2012.11.05/xeon75xx.c
===================================================================
--- mcelog-1.0.2012.11.05.orig/xeon75xx.c
+++ mcelog-1.0.2012.11.05/xeon75xx.c
@@ -25,15 +25,142 @@
 #include "mcelog.h"
 #include "xeon75xx.h"
 
-/* This used to decode the old xeon 75xx memory error aux format. But that has never
-   been merged into mainline kernels, so removed it again. */
+/* DIMM description */
+struct aux_pfa_dimm {
+	u8  fbd_channel_id;
+	u8  ddr_channel_id;
+	u8  ddr_dimm_id;
+	u8  ddr_rank_id;
+	u8  ddr_dimm_bank_id;
+	u8  ddr_dimm_row_id;
+	u8  ddr_dimm_column_id;
+	u8  valid;
+} __attribute__((packed));
+
+enum {
+	MCE_BANK_MBOX0		= 8,
+	MCE_BANK_MBOX1		= 9,
+
+	DIMM_VALID_FBD_CHAN      = (1 << 0),
+	DIMM_VALID_DDR_CHAN      = (1 << 1),
+	DIMM_VALID_DDR_DIMM      = (1 << 2),
+	DIMM_VALID_DDR_RANK      = (1 << 3),
+	DIMM_VALID_DIMM_BANK     = (1 << 4),
+	DIMM_VALID_DIMM_ROW      = (1 << 5),
+	DIMM_VALID_DIMM_COLUMN   = (1 << 6),
+	DIMM_VALID_ALL		 = 0x7f,
+};
+
+static struct id {
+	char *name;
+	unsigned offset;
+	unsigned valid;
+	enum { 
+		NL  = 1<<0,
+		IND = 1<<1,
+	} flags;
+} ids[] = {
+#define V(n,f,b) n, offsetof(struct aux_pfa_dimm, f), b
+	{ V("FBD-Channel", fbd_channel_id,     DIMM_VALID_FBD_CHAN) },
+	{ V("DDR-Channel", ddr_channel_id,     DIMM_VALID_DDR_CHAN) },
+	{ V("DDR-DIMM",    ddr_dimm_id,        DIMM_VALID_DDR_DIMM) }, 
+	{ V("DDR-Rank",    ddr_rank_id,        DIMM_VALID_DDR_RANK) },
+	{ V("DIMM-Bank",   ddr_dimm_bank_id,   DIMM_VALID_DIMM_BANK), NL|IND },
+	{ V("DIMM-Row",    ddr_dimm_row_id,    DIMM_VALID_DIMM_ROW) },
+	{ V("DIMM-Column", ddr_dimm_column_id, DIMM_VALID_DIMM_COLUMN), NL },
+#undef V
+	{}
+};
+
+#if 0
+/* Use for memdb channel output */
+
+static int opt_number(char *buf, int val)
+{
+	if (val == (u8)-1) { 
+		*buf++ = '?';
+		return 1;
+	}
+	return sprintf(buf, "%u", val);
+}
+
+static void print_channel(int channel, char *buf)
+{
+	int n;
+	n = opt_number(buf, ((channel) >> 8) & 0xff);
+	buf[n++] = ':';
+	opt_number(buf + n, channel & 0xff);
+}
+#endif
+
+static void decode_dimm(struct aux_pfa_dimm *d, int *channel, int *dimm)
+{
+	if (d->valid == 0)
+		return;
+	if (d->valid & DIMM_VALID_DDR_DIMM) 
+		*dimm = d->ddr_dimm_id;
+	if (d->valid & (DIMM_VALID_DDR_CHAN|DIMM_VALID_FBD_CHAN)) {
+		int fbd_chan = (d->valid & DIMM_VALID_FBD_CHAN) ? 
+			d->fbd_channel_id : (u8)-1;
+		int ddr_chan = (d->valid & DIMM_VALID_DDR_CHAN) ? 
+			d->ddr_channel_id : (u8)-1;
+		*channel = (fbd_chan << 8) | ddr_chan;
+	}
+}
+
+static void print_dimm(int num, struct aux_pfa_dimm *d)
+{
+	struct id *id;
+	int indent;
+	int k;
+
+	if (d->valid == 0)
+		return;
+
+	k = indent = Wprintf("DIMM %d: ", num);
+	for (id = ids; id->name; id++) {
+		if (d->valid & id->valid) 
+			k += Wprintf("%s %u ", id->name, *((u8*)d + id->offset));
+		if (k > 0) { 
+			if (id->flags & NL) {
+				Wprintf("\n");	
+				k = 0;
+			}
+			if (id->flags & IND)
+				Wprintf("%.*s", indent, "");
+		}
+	}
+}
+
+static int is_mem_err(struct mce *m, unsigned msize)
+{
+	if (msize < offsetof(struct mce, aux1) + sizeof(u64))
+		return 0;
+	if (m->bank != MCE_BANK_MBOX0 && m->bank != MCE_BANK_MBOX1)
+		return 0;
+	return 1;
+}
+
+union d {
+	struct aux_pfa_dimm d;
+	u64 val;
+}; 
 
 void 
 xeon75xx_memory_error(struct mce *m, unsigned msize, int *channel, int *dimm)
 {
+	if (!is_mem_err(m, msize))
+		return;
+
+	decode_dimm(&((union d *)&m->aux0)->d, &channel[0], &dimm[0]);
+	decode_dimm(&((union d *)&m->aux1)->d, &channel[1], &dimm[1]);
 }
 
 
 void xeon75xx_decode_dimm(struct mce *m, unsigned msize)
 {
+	if (!is_mem_err(m, msize))
+		return;
+	print_dimm(0, &((union d *)&m->aux0)->d);
+	print_dimm(1, &((union d *)&m->aux1)->d);
 }
Index: mcelog-1.0.2012.11.05/mcelog.h
===================================================================
--- mcelog-1.0.2012.11.05.orig/mcelog.h
+++ mcelog-1.0.2012.11.05/mcelog.h
@@ -31,6 +31,8 @@ struct mce {
 	__u32 socketid;	/* CPU socket ID */
 	__u32 apicid;	/* CPU initial apic ID */
 	__u64 mcgcap;	/* MCGCAP MSR: machine check capabilities of CPU */
+	__u64 aux0;
+	__u64 aux1;
 };
 
 #define X86_VENDOR_INTEL	0
