Description: Use 64bit types for memory addresses
mcelog reads 64-bit addresses from the MCE, but passes them around with
type unsigned long, which causes mcelog --dmi to give incorrect
results on 32-bit systems with more than 4 GiB of RAM.
Origin: other, http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;bug=437022
Bug-Debian: http://bugs.debian.org/437022
Author: Anders Kaseorg <andersk@MIT.EDU>
Author: Julien BLACHE <jblache@debian.org>
Index: mcelog-1.0~pre1/dimm.c
===================================================================
--- mcelog-1.0~pre1.orig/dimm.c 2009-12-09 16:46:15.000000000 +0100
+++ mcelog-1.0~pre1/dimm.c 2010-03-09 08:41:31.000000000 +0100
@@ -351,14 +351,14 @@
Eprintf("Cannot run error trigger %s for %s\n", trigger, loc);
open_dimm_db(NULL);
}
-void new_error(unsigned long addr, unsigned long max_error, char *trigger)
+void new_error(unsigned long long addr, unsigned long max_error, char *trigger)
{
struct dmi_memdev **devs;
int i;
devs = dmi_find_addr(addr);
if (devs[0] == NULL) {
- Wprintf("No memory found for address %lx\n", addr);
+ Wprintf("No memory found for address %Lx\n", addr);
exit(1);
}
for (i = 0; devs[i]; i++) {
@@ -366,7 +366,7 @@
char *loc = dmi_getstring(&d->header, d->device_locator);
struct group *g = find_entry(dimm_db, NULL, "Locator", loc);
if (!g) { // shouldn't happen
- Eprintf("No record found for %lx\n", addr);
+ Eprintf("No record found for %Lx\n", addr);
return;
}
unsigned long val = inc_val(g, "corrected errors");
Index: mcelog-1.0~pre1/dimm.h
===================================================================
--- mcelog-1.0~pre1.orig/dimm.h 2009-12-09 16:46:15.000000000 +0100
+++ mcelog-1.0~pre1/dimm.h 2010-03-09 08:41:31.000000000 +0100
@@ -1,6 +1,6 @@
void close_dimm_db(void);
int open_dimm_db(char *fn);
-void new_error(unsigned long addr, unsigned long max_error, char *trigger);
+void new_error(unsigned long long addr, unsigned long max_error, char *trigger);
void reset_dimm(char *locator);
void gc_dimms(void);
void dump_all_dimms(void);
Index: mcelog-1.0~pre1/dmi.c
===================================================================
--- mcelog-1.0~pre1.orig/dmi.c 2009-12-09 16:46:15.000000000 +0100
+++ mcelog-1.0~pre1/dmi.c 2010-03-09 08:41:31.000000000 +0100
@@ -244,7 +244,7 @@
Wprintf("%s ", type_details[i]);
}
-static void dump_memdev(struct dmi_memdev *md, unsigned long addr)
+static void dump_memdev(struct dmi_memdev *md, unsigned long long addr)
{
char tmp[20];
char unit[10];
@@ -253,7 +253,7 @@
if (md->header.length <
offsetof(struct dmi_memdev, manufacturer)) {
if (verbose > 0)
- printf("Memory device for address %lx too short %hu\n",
+ printf("Memory device for address %Lx too short %hu\n",
addr, md->header.length);
return;
}
@@ -445,7 +445,7 @@
DMIGET(dmi_dimms[i],device_set));
}
-struct dmi_memdev **dmi_find_addr(unsigned long addr)
+struct dmi_memdev **dmi_find_addr(unsigned long long addr)
{
struct dmi_memdev **devs;
int i, k;
@@ -489,7 +489,7 @@
return devs;
}
-void dmi_decodeaddr(unsigned long addr)
+void dmi_decodeaddr(unsigned long long addr)
{
struct dmi_memdev **devs = dmi_find_addr(addr);
if (devs[0]) {
@@ -498,7 +498,7 @@
for (i = 0; devs[i]; i++)
dump_memdev(devs[i], addr);
} else {
- Wprintf("No DIMM found for %lx in SMBIOS\n", addr);
+ Wprintf("No DIMM found for %Lx in SMBIOS\n", addr);
}
free(devs);
}
Index: mcelog-1.0~pre1/dmi.h
===================================================================
--- mcelog-1.0~pre1.orig/dmi.h 2009-12-09 16:46:15.000000000 +0100
+++ mcelog-1.0~pre1/dmi.h 2010-03-09 08:41:31.000000000 +0100
@@ -62,10 +62,10 @@
} __attribute__((packed));
int opendmi(void);
-void dmi_decodeaddr(unsigned long addr);
+void dmi_decodeaddr(unsigned long long addr);
int dmi_sanity_check(void);
unsigned dmi_dimm_size(unsigned short size, char *unit);
-struct dmi_memdev **dmi_find_addr(unsigned long addr);
+struct dmi_memdev **dmi_find_addr(unsigned long long addr);
void dmi_set_verbosity(int v);
char *dmi_getstring(struct dmi_entry *e, unsigned number);
Index: mcelog-1.0~pre1/mcelog.c
===================================================================
--- mcelog-1.0~pre1.orig/mcelog.c 2009-12-09 16:46:15.000000000 +0100
+++ mcelog-1.0~pre1/mcelog.c 2010-03-09 08:41:31.000000000 +0100
@@ -121,7 +121,7 @@
}
}
-static void resolveaddr(unsigned long addr)
+static void resolveaddr(unsigned long long addr)
{
if (addr && do_dmi && dmi_forced)
dmi_decodeaddr(addr);