Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

EDAC, amd64: Fix channel decode on Fam15hMod60h systems

Fam15hMod60h systems are using the channel decode of Fam15hMod30h which
gives incorrect results. Fam15hMod60h systems should use the generic
channel decode method plus a couple more cases.

Signed-off-by: Yazen Ghannam <Yazen.Ghannam@amd.com>
Cc: Aravind Gopalakrishnan <aravindksg.lkml@gmail.com>
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/1470236355-30039-1-git-send-email-Yazen.Ghannam@amd.com
Signed-off-by: Borislav Petkov <bp@suse.de>

authored by

Yazen Ghannam and committed by
Borislav Petkov
dc0a50a8 7c51d98d

+12 -3
+12 -3
drivers/edac/amd64_edac.c
··· 1425 1425 1426 1426 if (intlv_addr & 0x2) { 1427 1427 u8 shift = intlv_addr & 0x1 ? 9 : 6; 1428 - u32 temp = hweight_long((u32) ((sys_addr >> 16) & 0x1F)) % 2; 1428 + u32 temp = hweight_long((u32) ((sys_addr >> 16) & 0x1F)) & 1; 1429 1429 1430 1430 return ((sys_addr >> shift) & 1) ^ temp; 1431 + } 1432 + 1433 + if (intlv_addr & 0x4) { 1434 + u8 shift = intlv_addr & 0x1 ? 9 : 8; 1435 + 1436 + return (sys_addr >> shift) & 1; 1431 1437 } 1432 1438 1433 1439 return (sys_addr >> (12 + hweight8(intlv_en))) & 1; ··· 1732 1726 if (!(num_dcts_intlv % 2 == 0) || (num_dcts_intlv > 4)) 1733 1727 return -EINVAL; 1734 1728 1735 - channel = f15_m30h_determine_channel(pvt, sys_addr, intlv_en, 1736 - num_dcts_intlv, dct_sel); 1729 + if (pvt->model >= 0x60) 1730 + channel = f1x_determine_channel(pvt, sys_addr, false, intlv_en); 1731 + else 1732 + channel = f15_m30h_determine_channel(pvt, sys_addr, intlv_en, 1733 + num_dcts_intlv, dct_sel); 1737 1734 1738 1735 /* Verify we stay within the MAX number of channels allowed */ 1739 1736 if (channel > 3)