Commit b48aeab6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  amd64_edac: Cleanup return type of amd64_determine_edac_cap()
  amd64_edac: Add a fix for Erratum 505
  EDAC, MCE, AMD: Simplify NB MCE decoder interface
  EDAC, MCE, AMD: Drop local coreid reporting
  EDAC, MCE, AMD: Print valid addr when reporting an error
  EDAC, MCE, AMD: Print CPU number when reporting the error
parents 1bc87b00 1f6189ed
...@@ -114,10 +114,22 @@ static int f10_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, ...@@ -114,10 +114,22 @@ static int f10_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func);
} }
/*
* Select DCT to which PCI cfg accesses are routed
*/
static void f15h_select_dct(struct amd64_pvt *pvt, u8 dct)
{
u32 reg = 0;
amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg);
reg &= 0xfffffffe;
reg |= dct;
amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg);
}
static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
const char *func) const char *func)
{ {
u32 reg = 0;
u8 dct = 0; u8 dct = 0;
if (addr >= 0x140 && addr <= 0x1a0) { if (addr >= 0x140 && addr <= 0x1a0) {
...@@ -125,10 +137,7 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val, ...@@ -125,10 +137,7 @@ static int f15_read_dct_pci_cfg(struct amd64_pvt *pvt, int addr, u32 *val,
addr -= 0x100; addr -= 0x100;
} }
amd64_read_pci_cfg(pvt->F1, DCT_CFG_SEL, &reg); f15h_select_dct(pvt, dct);
reg &= 0xfffffffe;
reg |= dct;
amd64_write_pci_cfg(pvt->F1, DCT_CFG_SEL, reg);
return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func); return __amd64_read_pci_cfg_dword(pvt->F2, addr, val, func);
} }
...@@ -198,6 +207,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw) ...@@ -198,6 +207,10 @@ static int amd64_set_scrub_rate(struct mem_ctl_info *mci, u32 bw)
if (boot_cpu_data.x86 == 0xf) if (boot_cpu_data.x86 == 0xf)
min_scrubrate = 0x0; min_scrubrate = 0x0;
/* F15h Erratum #505 */
if (boot_cpu_data.x86 == 0x15)
f15h_select_dct(pvt, 0);
return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate); return __amd64_set_scrub_rate(pvt->F3, bw, min_scrubrate);
} }
...@@ -207,6 +220,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) ...@@ -207,6 +220,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci)
u32 scrubval = 0; u32 scrubval = 0;
int i, retval = -EINVAL; int i, retval = -EINVAL;
/* F15h Erratum #505 */
if (boot_cpu_data.x86 == 0x15)
f15h_select_dct(pvt, 0);
amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval); amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval);
scrubval = scrubval & 0x001F; scrubval = scrubval & 0x001F;
...@@ -751,10 +768,10 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16); ...@@ -751,10 +768,10 @@ static int get_channel_from_ecc_syndrome(struct mem_ctl_info *, u16);
* Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs * Determine if the DIMMs have ECC enabled. ECC is enabled ONLY if all the DIMMs
* are ECC capable. * are ECC capable.
*/ */
static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) static unsigned long amd64_determine_edac_cap(struct amd64_pvt *pvt)
{ {
u8 bit; u8 bit;
enum dev_type edac_cap = EDAC_FLAG_NONE; unsigned long edac_cap = EDAC_FLAG_NONE;
bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F) bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= K8_REV_F)
? 19 ? 19
...@@ -1953,11 +1970,9 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, ...@@ -1953,11 +1970,9 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
amd64_handle_ue(mci, m); amd64_handle_ue(mci, m);
} }
void amd64_decode_bus_error(int node_id, struct mce *m, u32 nbcfg) void amd64_decode_bus_error(int node_id, struct mce *m)
{ {
struct mem_ctl_info *mci = mcis[node_id]; __amd64_decode_bus_error(mcis[node_id], m);
__amd64_decode_bus_error(mci, m);
} }
/* /*
......
...@@ -9,7 +9,7 @@ static u8 xec_mask = 0xf; ...@@ -9,7 +9,7 @@ static u8 xec_mask = 0xf;
static u8 nb_err_cpumask = 0xf; static u8 nb_err_cpumask = 0xf;
static bool report_gart_errors; static bool report_gart_errors;
static void (*nb_bus_decoder)(int node_id, struct mce *m, u32 nbcfg); static void (*nb_bus_decoder)(int node_id, struct mce *m);
void amd_report_gart_errors(bool v) void amd_report_gart_errors(bool v)
{ {
...@@ -17,13 +17,13 @@ void amd_report_gart_errors(bool v) ...@@ -17,13 +17,13 @@ void amd_report_gart_errors(bool v)
} }
EXPORT_SYMBOL_GPL(amd_report_gart_errors); EXPORT_SYMBOL_GPL(amd_report_gart_errors);
void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32)) void amd_register_ecc_decoder(void (*f)(int, struct mce *))
{ {
nb_bus_decoder = f; nb_bus_decoder = f;
} }
EXPORT_SYMBOL_GPL(amd_register_ecc_decoder); EXPORT_SYMBOL_GPL(amd_register_ecc_decoder);
void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32)) void amd_unregister_ecc_decoder(void (*f)(int, struct mce *))
{ {
if (nb_bus_decoder) { if (nb_bus_decoder) {
WARN_ON(nb_bus_decoder != f); WARN_ON(nb_bus_decoder != f);
...@@ -592,31 +592,14 @@ static bool nb_noop_mce(u16 ec, u8 xec) ...@@ -592,31 +592,14 @@ static bool nb_noop_mce(u16 ec, u8 xec)
return false; return false;
} }
void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg) void amd_decode_nb_mce(struct mce *m)
{ {
struct cpuinfo_x86 *c = &boot_cpu_data; struct cpuinfo_x86 *c = &boot_cpu_data;
u16 ec = EC(m->status); int node_id = amd_get_nb_id(m->extcpu);
u8 xec = XEC(m->status, 0x1f); u16 ec = EC(m->status);
u32 nbsh = (u32)(m->status >> 32); u8 xec = XEC(m->status, 0x1f);
int core = -1;
pr_emerg(HW_ERR "Northbridge Error (node %d", node_id);
/* F10h, revD can disable ErrCpu[3:0] through ErrCpuVal */
if (c->x86 == 0x10 && c->x86_model > 7) {
if (nbsh & NBSH_ERR_CPU_VAL)
core = nbsh & nb_err_cpumask;
} else {
u8 assoc_cpus = nbsh & nb_err_cpumask;
if (assoc_cpus > 0)
core = fls(assoc_cpus) - 1;
}
if (core >= 0) pr_emerg(HW_ERR "Northbridge Error (node %d): ", node_id);
pr_cont(", core %d): ", core);
else
pr_cont("): ");
switch (xec) { switch (xec) {
case 0x2: case 0x2:
...@@ -648,7 +631,7 @@ void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg) ...@@ -648,7 +631,7 @@ void amd_decode_nb_mce(int node_id, struct mce *m, u32 nbcfg)
if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15) if (c->x86 == 0xf || c->x86 == 0x10 || c->x86 == 0x15)
if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder) if ((xec == 0x8 || xec == 0x0) && nb_bus_decoder)
nb_bus_decoder(node_id, m, nbcfg); nb_bus_decoder(node_id, m);
return; return;
...@@ -764,13 +747,13 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ...@@ -764,13 +747,13 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
{ {
struct mce *m = (struct mce *)data; struct mce *m = (struct mce *)data;
struct cpuinfo_x86 *c = &boot_cpu_data; struct cpuinfo_x86 *c = &boot_cpu_data;
int node, ecc; int ecc;
if (amd_filter_mce(m)) if (amd_filter_mce(m))
return NOTIFY_STOP; return NOTIFY_STOP;
pr_emerg(HW_ERR "MC%d_STATUS[%s|%s|%s|%s|%s", pr_emerg(HW_ERR "CPU:%d\tMC%d_STATUS[%s|%s|%s|%s|%s",
m->bank, m->extcpu, m->bank,
((m->status & MCI_STATUS_OVER) ? "Over" : "-"), ((m->status & MCI_STATUS_OVER) ? "Over" : "-"),
((m->status & MCI_STATUS_UC) ? "UE" : "CE"), ((m->status & MCI_STATUS_UC) ? "UE" : "CE"),
((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"), ((m->status & MCI_STATUS_MISCV) ? "MiscV" : "-"),
...@@ -789,6 +772,8 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ...@@ -789,6 +772,8 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
pr_cont("]: 0x%016llx\n", m->status); pr_cont("]: 0x%016llx\n", m->status);
if (m->status & MCI_STATUS_ADDRV)
pr_emerg(HW_ERR "\tMC%d_ADDR: 0x%016llx\n", m->bank, m->addr);
switch (m->bank) { switch (m->bank) {
case 0: case 0:
...@@ -811,8 +796,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data) ...@@ -811,8 +796,7 @@ int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data)
break; break;
case 4: case 4:
node = amd_get_nb_id(m->extcpu); amd_decode_nb_mce(m);
amd_decode_nb_mce(node, m, 0);
break; break;
case 5: case 5:
......
...@@ -86,9 +86,9 @@ struct amd_decoder_ops { ...@@ -86,9 +86,9 @@ struct amd_decoder_ops {
}; };
void amd_report_gart_errors(bool); void amd_report_gart_errors(bool);
void amd_register_ecc_decoder(void (*f)(int, struct mce *, u32)); void amd_register_ecc_decoder(void (*f)(int, struct mce *));
void amd_unregister_ecc_decoder(void (*f)(int, struct mce *, u32)); void amd_unregister_ecc_decoder(void (*f)(int, struct mce *));
void amd_decode_nb_mce(int, struct mce *, u32); void amd_decode_nb_mce(struct mce *);
int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data); int amd_decode_mce(struct notifier_block *nb, unsigned long val, void *data);
#endif /* _EDAC_MCE_AMD_H */ #endif /* _EDAC_MCE_AMD_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment