Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/bp/bp

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp: (21 commits)
  EDAC, MCE: Fix shift warning on 32-bit
  EDAC, MCE: Add a BIT_64() macro
  EDAC, MCE: Enable MCE decoding on F12h
  EDAC, MCE: Add F12h NB MCE decoder
  EDAC, MCE: Add F12h IC MCE decoder
  EDAC, MCE: Add F12h DC MCE decoder
  EDAC, MCE: Add support for F11h MCEs
  EDAC, MCE: Enable MCE decoding on F14h
  EDAC, MCE: Fix FR MCEs decoding
  EDAC, MCE: Complete NB MCE decoders
  EDAC, MCE: Warn about LS MCEs on F14h
  EDAC, MCE: Adjust IC decoders to F14h
  EDAC, MCE: Adjust DC decoders to F14h
  EDAC, MCE: Rename files
  EDAC, MCE: Rework MCE injection
  EDAC: Export edac sysfs class to users.
  EDAC, MCE: Pass complete MCE info to decoders
  EDAC, MCE: Sanitize error codes
  EDAC, MCE: Remove unused function parameter
  EDAC, MCE: Add HW_ERR prefix
  ...
  • Loading branch information
torvalds committed Oct 21, 2010
2 parents a9ccd80 + 525906b commit c029e40
Show file tree
Hide file tree
Showing 16 changed files with 1,018 additions and 758 deletions.
14 changes: 12 additions & 2 deletions drivers/edac/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ config EDAC_DEBUG
there're four debug levels (x=0,1,2,3 from low to high).
Usually you should select 'N'.

config EDAC_DECODE_MCE
config EDAC_DECODE_MCE
tristate "Decode MCEs in human-readable form (only on AMD for now)"
depends on CPU_SUP_AMD && X86_MCE
default y
Expand All @@ -51,6 +51,16 @@ config EDAC_DEBUG
which occur really early upon boot, before the module infrastructure
has been initialized.

config EDAC_MCE_INJ
tristate "Simple MCE injection interface over /sysfs"
depends on EDAC_DECODE_MCE
default n
help
This is a simple interface to inject MCEs over /sysfs and test
the MCE decoding code in EDAC.

This is currently AMD-only.

config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
help
Expand All @@ -72,7 +82,7 @@ config EDAC_AMD64
Families of Memory Controllers (K8, F10h and F11h)

config EDAC_AMD64_ERROR_INJECTION
bool "Sysfs Error Injection facilities"
bool "Sysfs HW Error injection facilities"
depends on EDAC_AMD64
help
Recent Opterons (Family 10h and later) provide for Memory Error
Expand Down
3 changes: 3 additions & 0 deletions drivers/edac/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ ifdef CONFIG_PCI
edac_core-objs += edac_pci.o edac_pci_sysfs.o
endif

obj-$(CONFIG_EDAC_MCE_INJ) += mce_amd_inj.o

edac_mce_amd-objs := mce_amd.o
obj-$(CONFIG_EDAC_DECODE_MCE) += edac_mce_amd.o

obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o
Expand Down
13 changes: 10 additions & 3 deletions drivers/edac/amd64_edac.c
Original file line number Diff line number Diff line change
Expand Up @@ -2073,11 +2073,18 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci,
amd64_handle_ue(mci, info);
}

void amd64_decode_bus_error(int node_id, struct err_regs *regs)
void amd64_decode_bus_error(int node_id, struct mce *m, u32 nbcfg)
{
struct mem_ctl_info *mci = mci_lookup[node_id];
struct err_regs regs;

__amd64_decode_bus_error(mci, regs);
regs.nbsl = (u32) m->status;
regs.nbsh = (u32)(m->status >> 32);
regs.nbeal = (u32) m->addr;
regs.nbeah = (u32)(m->addr >> 32);
regs.nbcfg = nbcfg;

__amd64_decode_bus_error(mci, &regs);

/*
* Check the UE bit of the NB status high register, if set generate some
Expand All @@ -2086,7 +2093,7 @@ void amd64_decode_bus_error(int node_id, struct err_regs *regs)
*
* FIXME: this should go somewhere else, if at all.
*/
if (regs->nbsh & K8_NBSH_UC_ERR && !report_gart_errors)
if (regs.nbsh & K8_NBSH_UC_ERR && !report_gart_errors)
edac_mc_handle_ue_no_info(mci, "UE bit is set");

}
Expand Down
5 changes: 2 additions & 3 deletions drivers/edac/amd64_edac.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
#include <linux/edac.h>
#include <asm/msr.h>
#include "edac_core.h"
#include "edac_mce_amd.h"
#include "mce_amd.h"

#define amd64_printk(level, fmt, arg...) \
edac_printk(level, "amd64", fmt, ##arg)
Expand Down Expand Up @@ -482,11 +482,10 @@ extern const char *rrrr_msgs[16];
extern const char *to_msgs[2];
extern const char *pp_msgs[4];
extern const char *ii_msgs[4];
extern const char *ext_msgs[32];
extern const char *htlink_msgs[8];

#ifdef CONFIG_EDAC_DEBUG
#define NUM_DBG_ATTRS 9
#define NUM_DBG_ATTRS 5
#else
#define NUM_DBG_ATTRS 0
#endif
Expand Down
207 changes: 12 additions & 195 deletions drivers/edac/amd64_edac_dbg.c
Original file line number Diff line number Diff line change
@@ -1,167 +1,16 @@
#include "amd64_edac.h"

/*
* accept a hex value and store it into the virtual error register file, field:
* nbeal and nbeah. Assume virtual error values have already been set for: NBSL,
* NBSH and NBCFG. Then proceed to map the error values to a MC, CSROW and
* CHANNEL
*/
static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data,
size_t count)
{
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long long value;
int ret = 0;

ret = strict_strtoull(data, 16, &value);
if (ret != -EINVAL) {
debugf0("received NBEA= 0x%llx\n", value);

/* place the value into the virtual error packet */
pvt->ctl_error_info.nbeal = (u32) value;
value >>= 32;
pvt->ctl_error_info.nbeah = (u32) value;

/* Process the Mapping request */
/* TODO: Add race prevention */
amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1);

return count;
}
return ret;
}

/* display back what the last NBEA (MCA NB Address (MC4_ADDR)) was written */
static ssize_t amd64_nbea_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;
u64 value;

value = pvt->ctl_error_info.nbeah;
value <<= 32;
value |= pvt->ctl_error_info.nbeal;

return sprintf(data, "%llx\n", value);
}

/* store the NBSL (MCA NB Status Low (MC4_STATUS)) value user desires */
static ssize_t amd64_nbsl_store(struct mem_ctl_info *mci, const char *data,
size_t count)
{
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
int ret = 0;

ret = strict_strtoul(data, 16, &value);
if (ret != -EINVAL) {
debugf0("received NBSL= 0x%lx\n", value);

pvt->ctl_error_info.nbsl = (u32) value;

return count;
}
return ret;
}

/* display back what the last NBSL value written */
static ssize_t amd64_nbsl_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;
u32 value;

value = pvt->ctl_error_info.nbsl;

return sprintf(data, "%x\n", value);
}

/* store the NBSH (MCA NB Status High) value user desires */
static ssize_t amd64_nbsh_store(struct mem_ctl_info *mci, const char *data,
size_t count)
{
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
int ret = 0;

ret = strict_strtoul(data, 16, &value);
if (ret != -EINVAL) {
debugf0("received NBSH= 0x%lx\n", value);

pvt->ctl_error_info.nbsh = (u32) value;

return count;
}
return ret;
}

/* display back what the last NBSH value written */
static ssize_t amd64_nbsh_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;
u32 value;

value = pvt->ctl_error_info.nbsh;

return sprintf(data, "%x\n", value);
#define EDAC_DCT_ATTR_SHOW(reg) \
static ssize_t amd64_##reg##_show(struct mem_ctl_info *mci, char *data) \
{ \
struct amd64_pvt *pvt = mci->pvt_info; \
return sprintf(data, "0x%016llx\n", (u64)pvt->reg); \
}

/* accept and store the NBCFG (MCA NB Configuration) value user desires */
static ssize_t amd64_nbcfg_store(struct mem_ctl_info *mci,
const char *data, size_t count)
{
struct amd64_pvt *pvt = mci->pvt_info;
unsigned long value;
int ret = 0;

ret = strict_strtoul(data, 16, &value);
if (ret != -EINVAL) {
debugf0("received NBCFG= 0x%lx\n", value);

pvt->ctl_error_info.nbcfg = (u32) value;

return count;
}
return ret;
}

/* various show routines for the controls of a MCI */
static ssize_t amd64_nbcfg_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;

return sprintf(data, "%x\n", pvt->ctl_error_info.nbcfg);
}


static ssize_t amd64_dhar_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;

return sprintf(data, "%x\n", pvt->dhar);
}


static ssize_t amd64_dbam_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;

return sprintf(data, "%x\n", pvt->dbam0);
}


static ssize_t amd64_topmem_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;

return sprintf(data, "%llx\n", pvt->top_mem);
}


static ssize_t amd64_topmem2_show(struct mem_ctl_info *mci, char *data)
{
struct amd64_pvt *pvt = mci->pvt_info;

return sprintf(data, "%llx\n", pvt->top_mem2);
}
EDAC_DCT_ATTR_SHOW(dhar);
EDAC_DCT_ATTR_SHOW(dbam0);
EDAC_DCT_ATTR_SHOW(top_mem);
EDAC_DCT_ATTR_SHOW(top_mem2);

static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data)
{
Expand All @@ -180,38 +29,6 @@ static ssize_t amd64_hole_show(struct mem_ctl_info *mci, char *data)
*/
struct mcidev_sysfs_attribute amd64_dbg_attrs[] = {

{
.attr = {
.name = "nbea_ctl",
.mode = (S_IRUGO | S_IWUSR)
},
.show = amd64_nbea_show,
.store = amd64_nbea_store,
},
{
.attr = {
.name = "nbsl_ctl",
.mode = (S_IRUGO | S_IWUSR)
},
.show = amd64_nbsl_show,
.store = amd64_nbsl_store,
},
{
.attr = {
.name = "nbsh_ctl",
.mode = (S_IRUGO | S_IWUSR)
},
.show = amd64_nbsh_show,
.store = amd64_nbsh_store,
},
{
.attr = {
.name = "nbcfg_ctl",
.mode = (S_IRUGO | S_IWUSR)
},
.show = amd64_nbcfg_show,
.store = amd64_nbcfg_store,
},
{
.attr = {
.name = "dhar",
Expand All @@ -225,23 +42,23 @@ struct mcidev_sysfs_attribute amd64_dbg_attrs[] = {
.name = "dbam",
.mode = (S_IRUGO)
},
.show = amd64_dbam_show,
.show = amd64_dbam0_show,
.store = NULL,
},
{
.attr = {
.name = "topmem",
.mode = (S_IRUGO)
},
.show = amd64_topmem_show,
.show = amd64_top_mem_show,
.store = NULL,
},
{
.attr = {
.name = "topmem2",
.mode = (S_IRUGO)
},
.show = amd64_topmem2_show,
.show = amd64_top_mem2_show,
.store = NULL,
},
{
Expand Down
Loading

0 comments on commit c029e40

Please sign in to comment.