Commit c2df436b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'edac_for_3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp

Pull EDAC changes from Borislav Petkov:
 "EDAC queue for 3.17:

   - One new edac driver for Intel E3-12xx DRAM controllers.

   - Out-of-subsystem changes are making the non-atomic iomem 64-bit
     accessors' naming explicit to show both exact order of the 32-bit
     accesses and the non-atomicity of the 64-bit access.

     Usage locations are more verbose now as to what access is exactly
     being done vs having a not-very telling "readq" there, for example.

     This is needed by E3-12xx hardware where certain mmapped registers
     cannot be accessed with requests crossing a dword boundary.

     From Jason Baron.

   - Extending AMD MCE signatures to a new model 60h in family 15h, from
     Aravind Gopalakrishnan.

   - An unsigned check cleanup, from Fabian Frederick"

* tag 'edac_for_3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp:
  EDAC, MCE, AMD: Add MCE decoding for F15h M60h
  MAINTAINERS: add ie31200_edac entry
  ie31200_edac: Allocate mci and map mchbar first
  ie31200_edac: Introduce the driver
  x38_edac: make use of lo_hi_readq()
  readq/writeq: Add explicit lo_hi_[read|write]_q and hi_lo_[read|write]_q
  EDAC, edac_module.c: Remove unnecessary test on unsigned value
parents f74ad8df eba4bfb3
......@@ -3350,6 +3350,13 @@ W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/i82975x_edac.c
EDAC-IE31200
M: Jason Baron <jbaron@akamai.com>
L: linux-edac@vger.kernel.org
W: bluesmoke.sourceforge.net
S: Maintained
F: drivers/edac/ie31200_edac.c
EDAC-MPC85XX
M: Johannes Thumshirn <johannes.thumshirn@men.de>
L: linux-edac@vger.kernel.org
......
......@@ -186,6 +186,13 @@ config EDAC_I3200
Support for error detection and correction on the Intel
3200 and 3210 server chipsets.
config EDAC_IE31200
tristate "Intel e312xx"
depends on EDAC_MM_EDAC && PCI && X86
help
Support for error detection and correction on the Intel
E3-1200 based DRAM controllers.
config EDAC_X38
tristate "Intel X38"
depends on EDAC_MM_EDAC && PCI && X86
......
......@@ -37,6 +37,7 @@ obj-$(CONFIG_EDAC_I82875P) += i82875p_edac.o
obj-$(CONFIG_EDAC_I82975X) += i82975x_edac.o
obj-$(CONFIG_EDAC_I3000) += i3000_edac.o
obj-$(CONFIG_EDAC_I3200) += i3200_edac.o
obj-$(CONFIG_EDAC_IE31200) += ie31200_edac.o
obj-$(CONFIG_EDAC_X38) += x38_edac.o
obj-$(CONFIG_EDAC_I82860) += i82860_edac.o
obj-$(CONFIG_EDAC_R82600) += r82600_edac.o
......
......@@ -28,7 +28,7 @@ static int edac_set_debug_level(const char *buf, struct kernel_param *kp)
if (ret)
return ret;
if (val < 0 || val > 4)
if (val > 4)
return -EINVAL;
return param_set_int(buf, kp);
......
This diff is collapsed.
......@@ -78,7 +78,8 @@ static const char * const f15h_mc1_mce_desc[] = {
"uop queue",
"insn buffer",
"predecode buffer",
"fetch address FIFO"
"fetch address FIFO",
"dispatch uop queue"
};
static const char * const f15h_mc2_mce_desc[] = {
......@@ -267,6 +268,12 @@ static bool f15h_mc0_mce(u16 ec, u8 xec)
pr_cont("System Read Data Error.\n");
else
pr_cont(" Internal error condition type %d.\n", xec);
} else if (INT_ERROR(ec)) {
if (xec <= 0x1f)
pr_cont("Hardware Assert.\n");
else
ret = false;
} else
ret = false;
......@@ -373,7 +380,7 @@ static bool f15h_mc1_mce(u16 ec, u8 xec)
pr_cont("%s.\n", f15h_mc1_mce_desc[xec-4]);
break;
case 0x11 ... 0x14:
case 0x11 ... 0x15:
pr_cont("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
break;
......@@ -397,10 +404,20 @@ static void decode_mc1_mce(struct mce *m)
bool k8 = (boot_cpu_data.x86 == 0xf && (m->status & BIT_64(58)));
pr_cont("during %s.\n", (k8 ? "system linefill" : "NB data read"));
} else if (INT_ERROR(ec)) {
if (xec <= 0x3f)
pr_cont("Hardware Assert.\n");
else
goto wrong_mc1_mce;
} else if (fam_ops->mc1_mce(ec, xec))
;
else
pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
goto wrong_mc1_mce;
return;
wrong_mc1_mce:
pr_emerg(HW_ERR "Corrupted MC1 MCE info?\n");
}
static bool k8_mc2_mce(u16 ec, u8 xec)
......@@ -468,6 +485,11 @@ static bool f15h_mc2_mce(u16 ec, u8 xec)
default:
ret = false;
}
} else if (INT_ERROR(ec)) {
if (xec <= 0x3f)
pr_cont("Hardware Assert.\n");
else
ret = false;
}
return ret;
......@@ -615,6 +637,7 @@ static void decode_mc4_mce(struct mce *m)
static void decode_mc5_mce(struct mce *m)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
u16 ec = EC(m->status);
u8 xec = XEC(m->status, xec_mask);
if (c->x86 == 0xf || c->x86 == 0x11)
......@@ -622,6 +645,14 @@ static void decode_mc5_mce(struct mce *m)
pr_emerg(HW_ERR "MC5 Error: ");
if (INT_ERROR(ec)) {
if (xec <= 0x1f) {
pr_cont("Hardware Assert.\n");
return;
} else
goto wrong_mc5_mce;
}
if (xec == 0x0 || xec == 0xc)
pr_cont("%s.\n", mc5_mce_desc[xec]);
else if (xec <= 0xd)
......@@ -642,6 +673,10 @@ static void decode_mc6_mce(struct mce *m)
pr_emerg(HW_ERR "MC6 Error: ");
switch (xec) {
case 0x0:
pr_cont("Hardware Assertion");
break;
case 0x1:
pr_cont("Free List");
break;
......@@ -857,7 +892,8 @@ static int __init mce_amd_init(void)
break;
case 0x15:
xec_mask = 0x1f;
xec_mask = c->x86_model == 0x60 ? 0x3f : 0x1f;
fam_ops->mc0_mce = f15h_mc0_mce;
fam_ops->mc1_mce = f15h_mc1_mce;
fam_ops->mc2_mce = f15h_mc2_mce;
......
......@@ -14,6 +14,8 @@
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <linux/edac.h>
#include <asm-generic/io-64-nonatomic-lo-hi.h>
#include "edac_core.h"
#define X38_REVISION "1.1"
......@@ -161,11 +163,6 @@ static void x38_clear_error_info(struct mem_ctl_info *mci)
X38_ERRSTS_BITS);
}
static u64 x38_readq(const void __iomem *addr)
{
return readl(addr) | (((u64)readl(addr + 4)) << 32);
}
static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
struct x38_error_info *info)
{
......@@ -183,9 +180,9 @@ static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
if (!(info->errsts & X38_ERRSTS_BITS))
return;
info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
info->eccerrlog[0] = lo_hi_readq(window + X38_C0ECCERRLOG);
if (x38_channel_num == 2)
info->eccerrlog[1] = x38_readq(window + X38_C1ECCERRLOG);
info->eccerrlog[1] = lo_hi_readq(window + X38_C1ECCERRLOG);
pci_read_config_word(pdev, X38_ERRSTS, &info->errsts2);
......@@ -196,10 +193,10 @@ static void x38_get_and_clear_error_info(struct mem_ctl_info *mci,
* should be UE info.
*/
if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) {
info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG);
info->eccerrlog[0] = lo_hi_readq(window + X38_C0ECCERRLOG);
if (x38_channel_num == 2)
info->eccerrlog[1] =
x38_readq(window + X38_C1ECCERRLOG);
lo_hi_readq(window + X38_C1ECCERRLOG);
}
x38_clear_error_info(mci);
......
......@@ -4,8 +4,7 @@
#include <linux/io.h>
#include <asm-generic/int-ll64.h>
#ifndef readq
static inline __u64 readq(const volatile void __iomem *addr)
static inline __u64 hi_lo_readq(const volatile void __iomem *addr)
{
const volatile u32 __iomem *p = addr;
u32 low, high;
......@@ -15,14 +14,19 @@ static inline __u64 readq(const volatile void __iomem *addr)
return low + ((u64)high << 32);
}
#endif
#ifndef writeq
static inline void writeq(__u64 val, volatile void __iomem *addr)
static inline void hi_lo_writeq(__u64 val, volatile void __iomem *addr)
{
writel(val >> 32, addr + 4);
writel(val, addr);
}
#ifndef readq
#define readq hi_lo_readq
#endif
#ifndef writeq
#define writeq hi_lo_writeq
#endif
#endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */
......@@ -4,8 +4,7 @@
#include <linux/io.h>
#include <asm-generic/int-ll64.h>
#ifndef readq
static inline __u64 readq(const volatile void __iomem *addr)
static inline __u64 lo_hi_readq(const volatile void __iomem *addr)
{
const volatile u32 __iomem *p = addr;
u32 low, high;
......@@ -15,14 +14,19 @@ static inline __u64 readq(const volatile void __iomem *addr)
return low + ((u64)high << 32);
}
#endif
#ifndef writeq
static inline void writeq(__u64 val, volatile void __iomem *addr)
static inline void lo_hi_writeq(__u64 val, volatile void __iomem *addr)
{
writel(val, addr);
writel(val >> 32, addr + 4);
}
#ifndef readq
#define readq lo_hi_readq
#endif
#ifndef writeq
#define writeq lo_hi_writeq
#endif
#endif /* _ASM_IO_64_NONATOMIC_LO_HI_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