|
19 | 19 | #include <linux/adxl.h> |
20 | 20 | #include <acpi/nfit.h> |
21 | 21 | #include <asm/mce.h> |
| 22 | +#include <asm/uv/uv.h> |
22 | 23 | #include "edac_module.h" |
23 | 24 | #include "skx_common.h" |
24 | 25 |
|
@@ -221,33 +222,51 @@ void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) |
221 | 222 | } |
222 | 223 | EXPORT_SYMBOL_GPL(skx_set_decode); |
223 | 224 |
|
224 | | -int skx_get_src_id(struct skx_dev *d, int off, u8 *id) |
| 225 | +static int skx_get_pkg_id(struct skx_dev *d, u8 *id) |
225 | 226 | { |
226 | | - u32 reg; |
| 227 | + int node; |
| 228 | + int cpu; |
227 | 229 |
|
228 | | - if (pci_read_config_dword(d->util_all, off, ®)) { |
229 | | - skx_printk(KERN_ERR, "Failed to read src id\n"); |
230 | | - return -ENODEV; |
| 230 | + node = pcibus_to_node(d->util_all->bus); |
| 231 | + if (numa_valid_node(node)) { |
| 232 | + for_each_cpu(cpu, cpumask_of_pcibus(d->util_all->bus)) { |
| 233 | + struct cpuinfo_x86 *c = &cpu_data(cpu); |
| 234 | + |
| 235 | + if (c->initialized && cpu_to_node(cpu) == node) { |
| 236 | + *id = c->topo.pkg_id; |
| 237 | + return 0; |
| 238 | + } |
| 239 | + } |
231 | 240 | } |
232 | 241 |
|
233 | | - *id = GET_BITFIELD(reg, 12, 14); |
234 | | - return 0; |
| 242 | + skx_printk(KERN_ERR, "Failed to get package ID from NUMA information\n"); |
| 243 | + return -ENODEV; |
235 | 244 | } |
236 | | -EXPORT_SYMBOL_GPL(skx_get_src_id); |
237 | 245 |
|
238 | | -int skx_get_node_id(struct skx_dev *d, u8 *id) |
| 246 | +int skx_get_src_id(struct skx_dev *d, int off, u8 *id) |
239 | 247 | { |
240 | 248 | u32 reg; |
241 | 249 |
|
242 | | - if (pci_read_config_dword(d->util_all, 0xf4, ®)) { |
243 | | - skx_printk(KERN_ERR, "Failed to read node id\n"); |
| 250 | + /* |
| 251 | + * The 3-bit source IDs in PCI configuration space registers are limited |
| 252 | + * to 8 unique IDs, and each ID is local to a UPI/QPI domain. |
| 253 | + * |
| 254 | + * Source IDs cannot be used to map devices to sockets on UV systems |
| 255 | + * because they can exceed 8 sockets and have multiple UPI/QPI domains |
| 256 | + * with identical, repeating source IDs. |
| 257 | + */ |
| 258 | + if (is_uv_system()) |
| 259 | + return skx_get_pkg_id(d, id); |
| 260 | + |
| 261 | + if (pci_read_config_dword(d->util_all, off, ®)) { |
| 262 | + skx_printk(KERN_ERR, "Failed to read src id\n"); |
244 | 263 | return -ENODEV; |
245 | 264 | } |
246 | 265 |
|
247 | | - *id = GET_BITFIELD(reg, 0, 2); |
| 266 | + *id = GET_BITFIELD(reg, 12, 14); |
248 | 267 | return 0; |
249 | 268 | } |
250 | | -EXPORT_SYMBOL_GPL(skx_get_node_id); |
| 269 | +EXPORT_SYMBOL_GPL(skx_get_src_id); |
251 | 270 |
|
252 | 271 | static int get_width(u32 mtr) |
253 | 272 | { |
@@ -507,7 +526,7 @@ int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev, |
507 | 526 | pvt->imc = imc; |
508 | 527 |
|
509 | 528 | mci->ctl_name = kasprintf(GFP_KERNEL, "%s#%d IMC#%d", ctl_name, |
510 | | - imc->node_id, imc->lmc); |
| 529 | + imc->src_id, imc->lmc); |
511 | 530 | if (!mci->ctl_name) { |
512 | 531 | rc = -ENOMEM; |
513 | 532 | goto fail0; |
|
0 commit comments