EDAC/skx: Use the mcmtr register to retrieve close_pg/bank_xor_enable
The skx_edac driver wrongly uses the mtr register to retrieve two fields close_pg and bank_xor_enable. Fix it by using the correct mcmtr register to get the two fields. Cc: <stable@vger.kernel.org> Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com> Reported-by: Matthew Riley <mattdr@google.com> Acked-by: Aristeu Rozanski <aris@redhat.com> Signed-off-by: Tony Luck <tony.luck@intel.com> Link: https://lore.kernel.org/r/20200515210146.1337-1-tony.luck@intel.com
This commit is contained in:
@@ -163,27 +163,23 @@ static const struct x86_cpu_id skx_cpuids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
|
||||
|
||||
#define SKX_GET_MTMTR(dev, reg) \
|
||||
pci_read_config_dword((dev), 0x87c, &(reg))
|
||||
|
||||
static bool skx_check_ecc(struct pci_dev *pdev)
|
||||
static bool skx_check_ecc(u32 mcmtr)
|
||||
{
|
||||
u32 mtmtr;
|
||||
|
||||
SKX_GET_MTMTR(pdev, mtmtr);
|
||||
|
||||
return !!GET_BITFIELD(mtmtr, 2, 2);
|
||||
return !!GET_BITFIELD(mcmtr, 2, 2);
|
||||
}
|
||||
|
||||
static int skx_get_dimm_config(struct mem_ctl_info *mci)
|
||||
{
|
||||
struct skx_pvt *pvt = mci->pvt_info;
|
||||
u32 mtr, mcmtr, amap, mcddrtcfg;
|
||||
struct skx_imc *imc = pvt->imc;
|
||||
u32 mtr, amap, mcddrtcfg;
|
||||
struct dimm_info *dimm;
|
||||
int i, j;
|
||||
int ndimms;
|
||||
|
||||
/* Only the mcmtr on the first channel is effective */
|
||||
pci_read_config_dword(imc->chan[0].cdev, 0x87c, &mcmtr);
|
||||
|
||||
for (i = 0; i < SKX_NUM_CHANNELS; i++) {
|
||||
ndimms = 0;
|
||||
pci_read_config_dword(imc->chan[i].cdev, 0x8C, &amap);
|
||||
@@ -193,14 +189,14 @@ static int skx_get_dimm_config(struct mem_ctl_info *mci)
|
||||
pci_read_config_dword(imc->chan[i].cdev,
|
||||
0x80 + 4 * j, &mtr);
|
||||
if (IS_DIMM_PRESENT(mtr)) {
|
||||
ndimms += skx_get_dimm_info(mtr, amap, dimm, imc, i, j);
|
||||
ndimms += skx_get_dimm_info(mtr, mcmtr, amap, dimm, imc, i, j);
|
||||
} else if (IS_NVDIMM_PRESENT(mcddrtcfg, j)) {
|
||||
ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
|
||||
EDAC_MOD_STR);
|
||||
nvdimm_count++;
|
||||
}
|
||||
}
|
||||
if (ndimms && !skx_check_ecc(imc->chan[0].cdev)) {
|
||||
if (ndimms && !skx_check_ecc(mcmtr)) {
|
||||
skx_printk(KERN_ERR, "ECC is disabled on imc %d\n", imc->mc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
Fai riferimento in un nuovo problema
Block a user