提交 5794b291 编写于 作者: Q Qiuxu Zhuo 提交者: Yang Yingliang

Intel: EDAC, {skx,i10nm}: Make some configurations CPU model specific

mainline inclusion
from mainline-v5.8-rc1
commit ee5340ab
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I47H3V
CVE: NA

--------------------------------

commit ee5340ab upstream

Backport summary: Backport to kernel 4.19.57 for ICX EDAC support

The device ID for configuration agent PCI device and the offset for
bus number configuration register can be CPU model specific. So add
a new structure res_config to make them configurable and pass res_config
to {skx,i10nm}_init() and skx_get_all_bus_mappings() for use.
Signed-off-by: NQiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: NTony Luck <tony.luck@intel.com>
Reviewed-by: NBorislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20200427083246.GB11036@zn.tnicSigned-off-by: NYouquan Song <youquan.song@intel.com>
Signed-off-by: NJackie Liu <liuyun01@kylinos.cn>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: NXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 3bedd18c
...@@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void) ...@@ -122,10 +122,16 @@ static int i10nm_get_all_munits(void)
return 0; return 0;
} }
static struct res_config i10nm_cfg = {
.type = I10NM,
.decs_did = 0x3452,
.busno_cfg_offset = 0xcc,
};
static const struct x86_cpu_id i10nm_cpuids[] = { static const struct x86_cpu_id i10nm_cpuids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, (kernel_ulong_t)&i10nm_cfg},
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, (kernel_ulong_t)&i10nm_cfg},
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, (kernel_ulong_t)&i10nm_cfg},
{ } { }
}; };
MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids);
...@@ -235,6 +241,7 @@ static int __init i10nm_init(void) ...@@ -235,6 +241,7 @@ static int __init i10nm_init(void)
{ {
u8 mc = 0, src_id = 0, node_id = 0; u8 mc = 0, src_id = 0, node_id = 0;
const struct x86_cpu_id *id; const struct x86_cpu_id *id;
struct res_config *cfg;
const char *owner; const char *owner;
struct skx_dev *d; struct skx_dev *d;
int rc, i, off[3] = {0xd0, 0xc8, 0xcc}; int rc, i, off[3] = {0xd0, 0xc8, 0xcc};
...@@ -250,11 +257,13 @@ static int __init i10nm_init(void) ...@@ -250,11 +257,13 @@ static int __init i10nm_init(void)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
cfg = (struct res_config *)id->driver_data;
rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm); rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
if (rc) if (rc)
return rc; return rc;
rc = skx_get_all_bus_mappings(0x3452, 0xcc, I10NM, &i10nm_edac_list); rc = skx_get_all_bus_mappings(cfg, &i10nm_edac_list);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
if (rc == 0) { if (rc == 0) {
......
...@@ -157,8 +157,14 @@ static int get_all_munits(const struct munit *m) ...@@ -157,8 +157,14 @@ static int get_all_munits(const struct munit *m)
return -ENODEV; return -ENODEV;
} }
static struct res_config skx_cfg = {
.type = SKX,
.decs_did = 0x2016,
.busno_cfg_offset = 0xcc,
};
static const struct x86_cpu_id skx_cpuids[] = { static const struct x86_cpu_id skx_cpuids[] = {
{ X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X, 0, 0 }, { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_X, 0, (kernel_ulong_t)&skx_cfg},
{ } { }
}; };
MODULE_DEVICE_TABLE(x86cpu, skx_cpuids); MODULE_DEVICE_TABLE(x86cpu, skx_cpuids);
...@@ -642,6 +648,7 @@ static inline void teardown_skx_debug(void) {} ...@@ -642,6 +648,7 @@ static inline void teardown_skx_debug(void) {}
static int __init skx_init(void) static int __init skx_init(void)
{ {
const struct x86_cpu_id *id; const struct x86_cpu_id *id;
struct res_config *cfg;
const struct munit *m; const struct munit *m;
const char *owner; const char *owner;
int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8}; int rc = 0, i, off[3] = {0xd0, 0xd4, 0xd8};
...@@ -658,11 +665,13 @@ static int __init skx_init(void) ...@@ -658,11 +665,13 @@ static int __init skx_init(void)
if (!id) if (!id)
return -ENODEV; return -ENODEV;
cfg = (struct res_config *)id->driver_data;
rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm); rc = skx_get_hi_lo(0x2034, off, &skx_tolm, &skx_tohm);
if (rc) if (rc)
return rc; return rc;
rc = skx_get_all_bus_mappings(0x2016, 0xcc, SKX, &skx_edac_list); rc = skx_get_all_bus_mappings(cfg, &skx_edac_list);
if (rc < 0) if (rc < 0)
goto fail; goto fail;
if (rc == 0) { if (rc == 0) {
......
...@@ -197,12 +197,11 @@ static int get_width(u32 mtr) ...@@ -197,12 +197,11 @@ static int get_width(u32 mtr)
} }
/* /*
* We use the per-socket device @did to count how many sockets are present, * We use the per-socket device @cfg->did to count how many sockets are present,
* and to detemine which PCI buses are associated with each socket. Allocate * and to detemine which PCI buses are associated with each socket. Allocate
* and build the full list of all the skx_dev structures that we need here. * and build the full list of all the skx_dev structures that we need here.
*/ */
int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list)
struct list_head **list)
{ {
struct pci_dev *pdev, *prev; struct pci_dev *pdev, *prev;
struct skx_dev *d; struct skx_dev *d;
...@@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -211,7 +210,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
prev = NULL; prev = NULL;
for (;;) { for (;;) {
pdev = pci_get_device(PCI_VENDOR_ID_INTEL, did, prev); pdev = pci_get_device(PCI_VENDOR_ID_INTEL, cfg->decs_did, prev);
if (!pdev) if (!pdev)
break; break;
ndev++; ndev++;
...@@ -221,7 +220,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -221,7 +220,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
return -ENOMEM; return -ENOMEM;
} }
if (pci_read_config_dword(pdev, off, &reg)) { if (pci_read_config_dword(pdev, cfg->busno_cfg_offset, &reg)) {
kfree(d); kfree(d);
pci_dev_put(pdev); pci_dev_put(pdev);
skx_printk(KERN_ERR, "Failed to read bus idx\n"); skx_printk(KERN_ERR, "Failed to read bus idx\n");
...@@ -230,7 +229,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type, ...@@ -230,7 +229,7 @@ int skx_get_all_bus_mappings(unsigned int did, int off, enum type type,
d->bus[0] = GET_BITFIELD(reg, 0, 7); d->bus[0] = GET_BITFIELD(reg, 0, 7);
d->bus[1] = GET_BITFIELD(reg, 8, 15); d->bus[1] = GET_BITFIELD(reg, 8, 15);
if (type == SKX) { if (cfg->type == SKX) {
d->seg = pci_domain_nr(pdev->bus); d->seg = pci_domain_nr(pdev->bus);
d->bus[2] = GET_BITFIELD(reg, 16, 23); d->bus[2] = GET_BITFIELD(reg, 16, 23);
d->bus[3] = GET_BITFIELD(reg, 24, 31); d->bus[3] = GET_BITFIELD(reg, 24, 31);
......
...@@ -112,6 +112,14 @@ struct decoded_addr { ...@@ -112,6 +112,14 @@ struct decoded_addr {
int bank_group; int bank_group;
}; };
struct res_config {
enum type type;
/* Configuration agent device ID */
unsigned int decs_did;
/* Default bus number configuration register offset */
int busno_cfg_offset;
};
typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci); typedef int (*get_dimm_config_f)(struct mem_ctl_info *mci);
typedef bool (*skx_decode_f)(struct decoded_addr *res); typedef bool (*skx_decode_f)(struct decoded_addr *res);
typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len); typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len);
...@@ -123,8 +131,7 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); ...@@ -123,8 +131,7 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
int skx_get_node_id(struct skx_dev *d, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id);
int skx_get_all_bus_mappings(unsigned int did, int off, enum type, int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list);
struct list_head **list);
int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm); int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册