Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c029e405 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* '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
  ...
parents a9ccd80a 525906bc
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -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
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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
+10 −3
Original line number Diff line number Diff line
@@ -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
@@ -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");

}
+2 −3
Original line number Diff line number Diff line
@@ -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)
@@ -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
+12 −195
Original line number Diff line number Diff line
#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);
#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);	\
}

/* 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);
}

/* 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)
{
@@ -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",
@@ -225,7 +42,7 @@ struct mcidev_sysfs_attribute amd64_dbg_attrs[] = {
			.name = "dbam",
			.mode = (S_IRUGO)
		},
		.show = amd64_dbam_show,
		.show = amd64_dbam0_show,
		.store = NULL,
	},
	{
@@ -233,7 +50,7 @@ struct mcidev_sysfs_attribute amd64_dbg_attrs[] = {
			.name = "topmem",
			.mode = (S_IRUGO)
		},
		.show = amd64_topmem_show,
		.show = amd64_top_mem_show,
		.store = NULL,
	},
	{
@@ -241,7 +58,7 @@ struct mcidev_sysfs_attribute amd64_dbg_attrs[] = {
			.name = "topmem2",
			.mode = (S_IRUGO)
		},
		.show = amd64_topmem2_show,
		.show = amd64_top_mem2_show,
		.store = NULL,
	},
	{
Loading