sb_edac: Avoid overflow errors at memory size calculation
Sandy bridge EDAC is calculating the memory size with overflow. Basically, the size field and the integer calculation is using 32 bits. More bits are needed, when the DIMM memories have high density. The net result is that memories are improperly reported there, when high-density DIMMs are used: EDAC DEBUG: in drivers/edac/sb_edac.c, line at 591: mc#0: channel 0, dimm 0, -16384 Mb (-4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 EDAC DEBUG: in drivers/edac/sb_edac.c, line at 591: mc#0: channel 1, dimm 0, -16384 Mb (-4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 As the number of pages value is handled at the EDAC core as unsigned ints, the driver shows the 16 GB memories at sysfs interface as 16760832 MB! The fix is simple: calculate the number of pages as unsigned 64-bits integer. After the patch, the memory size (16 GB) is properly detected: EDAC DEBUG: in drivers/edac/sb_edac.c, line at 592: mc#0: channel 0, dimm 0, 16384 Mb (4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 EDAC DEBUG: in drivers/edac/sb_edac.c, line at 592: mc#0: channel 1, dimm 0, 16384 Mb (4194304 pages) bank: 8, rank: 2, row: 0x10000, col: 0x800 Cc: stable@kernel.org Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
b70f833377
commit
deb09ddaff
|
@ -513,7 +513,8 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
|||
{
|
||||
struct sbridge_pvt *pvt = mci->pvt_info;
|
||||
struct dimm_info *dimm;
|
||||
int i, j, banks, ranks, rows, cols, size, npages;
|
||||
unsigned i, j, banks, ranks, rows, cols, npages;
|
||||
u64 size;
|
||||
u32 reg;
|
||||
enum edac_type mode;
|
||||
enum mem_type mtype;
|
||||
|
@ -585,10 +586,10 @@ static int get_dimm_config(struct mem_ctl_info *mci)
|
|||
cols = numcol(mtr);
|
||||
|
||||
/* DDR3 has 8 I/O banks */
|
||||
size = (rows * cols * banks * ranks) >> (20 - 3);
|
||||
size = ((u64)rows * cols * banks * ranks) >> (20 - 3);
|
||||
npages = MiB_TO_PAGES(size);
|
||||
|
||||
edac_dbg(0, "mc#%d: channel %d, dimm %d, %d Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
|
||||
edac_dbg(0, "mc#%d: channel %d, dimm %d, %Ld Mb (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n",
|
||||
pvt->sbridge_dev->mc, i, j,
|
||||
size, npages,
|
||||
banks, ranks, rows, cols);
|
||||
|
|
Loading…
Reference in New Issue