diff options
Diffstat (limited to 'drivers/edac/skx_edac.c')
-rw-r--r-- | drivers/edac/skx_edac.c | 151 |
1 files changed, 76 insertions, 75 deletions
diff --git a/drivers/edac/skx_edac.c b/drivers/edac/skx_edac.c index a99ea61dad32..93ef161bb5e1 100644 --- a/drivers/edac/skx_edac.c +++ b/drivers/edac/skx_edac.c @@ -209,7 +209,7 @@ static int get_all_bus_mappings(void) d->bus[1] = GET_BITFIELD(reg, 8, 15); d->bus[2] = GET_BITFIELD(reg, 16, 23); d->bus[3] = GET_BITFIELD(reg, 24, 31); - edac_dbg(2, "busses: %x, %x, %x, %x\n", + edac_dbg(2, "busses: 0x%x, 0x%x, 0x%x, 0x%x\n", d->bus[0], d->bus[1], d->bus[2], d->bus[3]); list_add_tail(&d->list, &skx_edac_list); skx_num_sockets++; @@ -245,8 +245,8 @@ static int get_all_munits(const struct munit *m) /* Be sure that the device is enabled */ if (unlikely(pci_enable_device(pdev) < 0)) { - skx_printk(KERN_ERR, - "Couldn't enable %04x:%04x\n", PCI_VENDOR_ID_INTEL, m->did); + skx_printk(KERN_ERR, "Couldn't enable device %04x:%04x\n", + PCI_VENDOR_ID_INTEL, m->did); goto fail; } @@ -323,7 +323,7 @@ static int get_dimm_attr(u32 reg, int lobit, int hibit, int add, int minval, u32 val = GET_BITFIELD(reg, lobit, hibit); if (val < minval || val > maxval) { - edac_dbg(2, "bad %s = %d (raw=%x)\n", name, val, reg); + edac_dbg(2, "bad %s = %d (raw=0x%x)\n", name, val, reg); return -EINVAL; } return val + add; @@ -368,7 +368,7 @@ static int skx_get_hi_lo(void) skx_tohm |= (u64)reg << 32; pci_dev_put(pdev); - edac_dbg(2, "tolm=%llx tohm=%llx\n", skx_tolm, skx_tohm); + edac_dbg(2, "tolm=0x%llx tohm=0x%llx\n", skx_tolm, skx_tohm); return 0; } @@ -389,7 +389,7 @@ static int get_dimm_info(u32 mtr, u32 amap, struct dimm_info *dimm, size = ((1ull << (rows + cols + ranks)) * banks) >> (20 - 3); npages = MiB_TO_PAGES(size); - edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld MiB (%d pages) bank: %d, rank: %d, row: %#x, col: %#x\n", + edac_dbg(0, "mc#%d: channel %d, dimm %d, %lld MiB (%d pages) bank: %d, rank: %d, row: 0x%#x, col: 0x%#x\n", imc->mc, chan, dimmno, size, npages, banks, 1 << ranks, rows, cols); @@ -430,18 +430,18 @@ static int get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc, } if (smbios_handle < 0) { - skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=%x\n", dev_handle); + skx_printk(KERN_ERR, "Can't find handle for NVDIMM ADR=0x%x\n", dev_handle); goto unknown_size; } if (flags & ACPI_NFIT_MEM_MAP_FAILED) { - skx_printk(KERN_ERR, "NVDIMM ADR=%x is not mapped\n", dev_handle); + skx_printk(KERN_ERR, "NVDIMM ADR=0x%x is not mapped\n", dev_handle); goto unknown_size; } size = dmi_memdev_size(smbios_handle); if (size == ~0ull) - skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=%x/SMBIOS=%x\n", + skx_printk(KERN_ERR, "Can't find size for NVDIMM ADR=0x%x/SMBIOS=0x%x\n", dev_handle, smbios_handle); unknown_size: @@ -616,7 +616,7 @@ static bool skx_sad_decode(struct decoded_addr *res) /* Simple sanity check for I/O space or out of range */ if (addr >= skx_tohm || (addr >= skx_tolm && addr < BIT_ULL(32))) { - edac_dbg(0, "Address %llx out of range\n", addr); + edac_dbg(0, "Address 0x%llx out of range\n", addr); return false; } @@ -631,7 +631,7 @@ restart: } prev_limit = limit + 1; } - edac_dbg(0, "No SAD entry for %llx\n", addr); + edac_dbg(0, "No SAD entry for 0x%llx\n", addr); return false; sad_found: @@ -709,7 +709,7 @@ sad_found: res->imc = GET_BITFIELD(d->mcroute, lchan * 3, lchan * 3 + 2); res->channel = GET_BITFIELD(d->mcroute, lchan * 2 + 18, lchan * 2 + 19); - edac_dbg(2, "%llx: socket=%d imc=%d channel=%d\n", + edac_dbg(2, "0x%llx: socket=%d imc=%d channel=%d\n", res->addr, res->socket, res->imc, res->channel); return true; } @@ -756,7 +756,7 @@ static bool skx_tad_decode(struct decoded_addr *res) if (SKX_TAD_BASE(base) <= res->addr && res->addr <= SKX_TAD_LIMIT(wayness)) goto tad_found; } - edac_dbg(0, "No TAD entry for %llx\n", res->addr); + edac_dbg(0, "No TAD entry for 0x%llx\n", res->addr); return false; tad_found: @@ -784,7 +784,7 @@ tad_found: res->chan_addr = channel_addr; - edac_dbg(2, "%llx: chan_addr=%llx sktways=%d chanways=%d\n", + edac_dbg(2, "0x%llx: chan_addr=0x%llx sktways=%d chanways=%d\n", res->addr, res->chan_addr, res->sktways, res->chanways); return true; } @@ -826,7 +826,7 @@ static bool skx_rir_decode(struct decoded_addr *res) } prev_limit = limit; } - edac_dbg(0, "No RIR entry for %llx\n", res->addr); + edac_dbg(0, "No RIR entry for 0x%llx\n", res->addr); return false; rir_found: @@ -845,7 +845,7 @@ rir_found: res->dimm = chan_rank / 4; res->rank = chan_rank % 4; - edac_dbg(2, "%llx: dimm=%d rank=%d chan_rank=%d rank_addr=%llx\n", + edac_dbg(2, "0x%llx: dimm=%d rank=%d chan_rank=%d rank_addr=0x%llx\n", res->addr, res->dimm, res->rank, res->channel_rank, res->rank_address); return true; @@ -908,7 +908,7 @@ static bool skx_mad_decode(struct decoded_addr *r) } r->row &= (1u << dimm->rowbits) - 1; - edac_dbg(2, "%llx: row=%x col=%x bank_addr=%d bank_group=%d\n", + edac_dbg(2, "0x%llx: row=0x%x col=0x%x bank_addr=%d bank_group=%d\n", r->addr, r->row, r->column, r->bank_address, r->bank_group); return true; @@ -921,53 +921,6 @@ static bool skx_decode(struct decoded_addr *res) skx_rir_decode(res) && skx_mad_decode(res); } -#ifdef CONFIG_EDAC_DEBUG -/* - * Debug feature. Make /sys/kernel/debug/skx_edac_test/addr. - * Write an address to this file to exercise the address decode - * logic in this driver. - */ -static struct dentry *skx_test; -static u64 skx_fake_addr; - -static int debugfs_u64_set(void *data, u64 val) -{ - struct decoded_addr res; - - res.addr = val; - skx_decode(&res); - - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); - -static struct dentry *mydebugfs_create(const char *name, umode_t mode, - struct dentry *parent, u64 *value) -{ - return debugfs_create_file(name, mode, parent, value, &fops_u64_wo); -} - -static void setup_skx_debug(void) -{ - skx_test = debugfs_create_dir("skx_edac_test", NULL); - mydebugfs_create("addr", S_IWUSR, skx_test, &skx_fake_addr); -} - -static void teardown_skx_debug(void) -{ - debugfs_remove_recursive(skx_test); -} -#else -static void setup_skx_debug(void) -{ -} - -static void teardown_skx_debug(void) -{ -} -#endif /*CONFIG_EDAC_DEBUG*/ - static bool skx_adxl_decode(struct decoded_addr *res) { @@ -1069,13 +1022,13 @@ static void skx_mce_output_error(struct mem_ctl_info *mci, } } if (adxl_component_count) { - snprintf(skx_msg, MSG_SIZE, "%s%s err_code:%04x:%04x %s", + snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s", overflow ? " OVERFLOW" : "", (uncorrected_error && recoverable) ? " recoverable" : "", mscod, errcode, adxl_msg); } else { snprintf(skx_msg, MSG_SIZE, - "%s%s err_code:%04x:%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:%x col:%x", + "%s%s err_code:0x%04x:0x%04x socket:%d imc:%d rank:%d bg:%d ba:%d row:0x%x col:0x%x", overflow ? " OVERFLOW" : "", (uncorrected_error && recoverable) ? " recoverable" : "", mscod, errcode, @@ -1151,15 +1104,15 @@ static int skx_mce_check_error(struct notifier_block *nb, unsigned long val, skx_mc_printk(mci, KERN_DEBUG, "HANDLING MCE MEMORY ERROR\n"); - skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: %Lx " + skx_mc_printk(mci, KERN_DEBUG, "CPU %d: Machine Check %s: 0x%llx " "Bank %d: %016Lx\n", mce->extcpu, type, mce->mcgstatus, mce->bank, mce->status); - skx_mc_printk(mci, KERN_DEBUG, "TSC %llx ", mce->tsc); - skx_mc_printk(mci, KERN_DEBUG, "ADDR %llx ", mce->addr); - skx_mc_printk(mci, KERN_DEBUG, "MISC %llx ", mce->misc); + skx_mc_printk(mci, KERN_DEBUG, "TSC 0x%llx ", mce->tsc); + skx_mc_printk(mci, KERN_DEBUG, "ADDR 0x%llx ", mce->addr); + skx_mc_printk(mci, KERN_DEBUG, "MISC 0x%llx ", mce->misc); - skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:%x TIME %llu SOCKET " - "%u APIC %x\n", mce->cpuvendor, mce->cpuid, + skx_mc_printk(mci, KERN_DEBUG, "PROCESSOR %u:0x%x TIME %llu SOCKET " + "%u APIC 0x%x\n", mce->cpuvendor, mce->cpuid, mce->time, mce->socketid, mce->apicid); skx_mce_output_error(mci, mce, &res); @@ -1172,6 +1125,54 @@ static struct notifier_block skx_mce_dec = { .priority = MCE_PRIO_EDAC, }; +#ifdef CONFIG_EDAC_DEBUG +/* + * Debug feature. + * Exercise the address decode logic by writing an address to + * /sys/kernel/debug/edac/skx_test/addr. + */ +static struct dentry *skx_test; + +static int debugfs_u64_set(void *data, u64 val) +{ + struct mce m; + + pr_warn_once("Fake error to 0x%llx injected via debugfs\n", val); + + memset(&m, 0, sizeof(m)); + /* ADDRV + MemRd + Unknown channel */ + m.status = MCI_STATUS_ADDRV + 0x90; + /* One corrected error */ + m.status |= BIT_ULL(MCI_STATUS_CEC_SHIFT); + m.addr = val; + skx_mce_check_error(NULL, 0, &m); + + return 0; +} +DEFINE_SIMPLE_ATTRIBUTE(fops_u64_wo, NULL, debugfs_u64_set, "%llu\n"); + +static void setup_skx_debug(void) +{ + skx_test = edac_debugfs_create_dir("skx_test"); + if (!skx_test) + return; + + if (!edac_debugfs_create_file("addr", 0200, skx_test, + NULL, &fops_u64_wo)) { + debugfs_remove(skx_test); + skx_test = NULL; + } +} + +static void teardown_skx_debug(void) +{ + debugfs_remove_recursive(skx_test); +} +#else +static void setup_skx_debug(void) {} +static void teardown_skx_debug(void) {} +#endif /*CONFIG_EDAC_DEBUG*/ + static void skx_remove(void) { int i, j; @@ -1291,7 +1292,7 @@ static int __init skx_init(void) if (rc < 0) goto fail; if (rc != m->per_socket * skx_num_sockets) { - edac_dbg(2, "Expected %d, got %d of %x\n", + edac_dbg(2, "Expected %d, got %d of 0x%x\n", m->per_socket * skx_num_sockets, rc, m->did); rc = -ENODEV; goto fail; @@ -1339,11 +1340,11 @@ static void __exit skx_exit(void) { edac_dbg(2, "\n"); mce_unregister_decode_chain(&skx_mce_dec); - skx_remove(); + teardown_skx_debug(); if (nvdimm_count) skx_adxl_put(); kfree(skx_msg); - teardown_skx_debug(); + skx_remove(); } module_init(skx_init); |