Commit 7dfc15c4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'edac_updates_for_v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC updates from Borislav Petkov:

 - Drop a now obsolete ppc4xx_edac driver

 - Fix conversion to physical memory addresses on Intel's Elkhart Lake
   and Ice Lake hardware when the system address is above the
   (Top-Of-Memory) TOM address

 - Pay attention to the memory hole on Zynq UltraScale+ MPSoC DDR
   controllers when injecting errors for testing purposes

 - Add support for translating normalized error addresses reported by an
   AMD memory controller into system physical addresses using an UEFI
   mechanism called platform runtime mechanism (PRM).

 - The usual cleanups and fixes

* tag 'edac_updates_for_v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
  EDAC: Drop obsolete PPC4xx driver
  EDAC/sb_edac: Fix the compile warning of large frame size
  EDAC/{skx_common,i10nm}: Remove the AMAP register for determing DDR5
  EDAC/{skx_common,skx,i10nm}: Move the common debug code to skx_common
  EDAC/igen6: Fix conversion of system address to physical memory address
  EDAC/synopsys: Fix error injection on Zynq UltraScale+
  RAS/AMD/ATL: Translate normalized to system physical addresses using PRM
  ACPI: PRM: Add PRM handler direct call support
parents 1636f57c 92f8358b
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -214,6 +214,30 @@ static struct prm_handler_info *find_prm_handler(const guid_t *guid)
#define UPDATE_LOCK_ALREADY_HELD 	4
#define UPDATE_UNLOCK_WITHOUT_LOCK 	5

int acpi_call_prm_handler(guid_t handler_guid, void *param_buffer)
{
	struct prm_handler_info *handler = find_prm_handler(&handler_guid);
	struct prm_module_info *module = find_prm_module(&handler_guid);
	struct prm_context_buffer context;
	efi_status_t status;

	if (!module || !handler)
		return -ENODEV;

	memset(&context, 0, sizeof(context));
	ACPI_COPY_NAMESEG(context.signature, "PRMC");
	context.identifier         = handler->guid;
	context.static_data_buffer = handler->static_data_buffer_addr;
	context.mmio_ranges        = module->mmio_info;

	status = efi_call_acpi_prm_handler(handler->handler_addr,
					   (u64)param_buffer,
					   &context);

	return efi_status_to_err(status);
}
EXPORT_SYMBOL_GPL(acpi_call_prm_handler);

/*
 * This is the PlatformRtMechanism opregion space handler.
 * @function: indicates the read/write. In fact as the PlatformRtMechanism
+0 −9
Original line number Diff line number Diff line
@@ -311,15 +311,6 @@ config EDAC_CELL
	  Cell Broadband Engine internal memory controller
	  on platform without a hypervisor

config EDAC_PPC4XX
	tristate "PPC4xx IBM DDR2 Memory Controller"
	depends on 4xx
	help
	  This enables support for EDAC on the ECC memory used
	  with the IBM DDR2 memory controller found in various
	  PowerPC 4xx embedded processors such as the 405EX[r],
	  440SP, 440SPe, 460EX, 460GT and 460SX.

config EDAC_AMD8131
	tristate "AMD8131 HyperTransport PCI-X Tunnel"
	depends on PCI && PPC_MAPLE
+0 −1
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ i10nm_edac-y := i10nm_base.o
obj-$(CONFIG_EDAC_I10NM)		+= i10nm_edac.o skx_edac_common.o

obj-$(CONFIG_EDAC_CELL)			+= cell_edac.o
obj-$(CONFIG_EDAC_PPC4XX)		+= ppc4xx_edac.o
obj-$(CONFIG_EDAC_AMD8111)		+= amd8111_edac.o
obj-$(CONFIG_EDAC_AMD8131)		+= amd8131_edac.o

+4 −57
Original line number Diff line number Diff line
@@ -47,10 +47,6 @@
	readl((m)->mbase + ((m)->hbm_mc ? 0xef8 :	\
	(res_cfg->type == GNR ? 0xaf8 : 0x20ef8)) +	\
	(i) * (m)->chan_mmio_sz)
#define I10NM_GET_AMAP(m, i)		\
	readl((m)->mbase + ((m)->hbm_mc ? 0x814 :	\
	(res_cfg->type == GNR ? 0xc14 : 0x20814)) +	\
	(i) * (m)->chan_mmio_sz)
#define I10NM_GET_REG32(m, i, offset)	\
	readl((m)->mbase + (i) * (m)->chan_mmio_sz + (offset))
#define I10NM_GET_REG64(m, i, offset)	\
@@ -971,7 +967,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
{
	struct skx_pvt *pvt = mci->pvt_info;
	struct skx_imc *imc = pvt->imc;
	u32 mtr, amap, mcddrtcfg = 0;
	u32 mtr, mcddrtcfg = 0;
	struct dimm_info *dimm;
	int i, j, ndimms;

@@ -980,7 +976,6 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
			continue;

		ndimms = 0;
		amap = I10NM_GET_AMAP(imc, i);

		if (res_cfg->type != GNR)
			mcddrtcfg = I10NM_GET_MCDDRTCFG(imc, i);
@@ -992,7 +987,7 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci,
				 mtr, mcddrtcfg, imc->mc, i, j);

			if (IS_DIMM_PRESENT(mtr))
				ndimms += skx_get_dimm_info(mtr, 0, amap, dimm,
				ndimms += skx_get_dimm_info(mtr, 0, 0, dimm,
							    imc, i, j, cfg);
			else if (IS_NVDIMM_PRESENT(mcddrtcfg, j))
				ndimms += skx_get_nvdimm_info(dimm, imc, i, j,
@@ -1013,54 +1008,6 @@ static struct notifier_block i10nm_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/i10nm_test/addr.
 */
static struct dentry *i10nm_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_i10nm_debug(void)
{
	i10nm_test = edac_debugfs_create_dir("i10nm_test");
	if (!i10nm_test)
		return;

	if (!edac_debugfs_create_file("addr", 0200, i10nm_test,
				      NULL, &fops_u64_wo)) {
		debugfs_remove(i10nm_test);
		i10nm_test = NULL;
	}
}

static void teardown_i10nm_debug(void)
{
	debugfs_remove_recursive(i10nm_test);
}
#else
static inline void setup_i10nm_debug(void) {}
static inline void teardown_i10nm_debug(void) {}
#endif /*CONFIG_EDAC_DEBUG*/

static int __init i10nm_init(void)
{
	u8 mc = 0, src_id = 0, node_id = 0;
@@ -1159,7 +1106,7 @@ static int __init i10nm_init(void)

	opstate_init();
	mce_register_decode_chain(&i10nm_mce_dec);
	setup_i10nm_debug();
	skx_setup_debug("i10nm_test");

	if (retry_rd_err_log && res_cfg->offsets_scrub && res_cfg->offsets_demand) {
		skx_set_decode(i10nm_mc_decode, show_retry_rd_err_log);
@@ -1187,7 +1134,7 @@ static void __exit i10nm_exit(void)
			enable_retry_rd_err_log(false);
	}

	teardown_i10nm_debug();
	skx_teardown_debug();
	mce_unregister_decode_chain(&i10nm_mce_dec);
	skx_adxl_put();
	skx_remove();
+1 −1
Original line number Diff line number Diff line
@@ -316,7 +316,7 @@ static u64 ehl_err_addr_to_imc_addr(u64 eaddr, int mc)
	if (igen6_tom <= _4GB)
		return eaddr + igen6_tolud - _4GB;

	if (eaddr < _4GB)
	if (eaddr >= igen6_tom)
		return eaddr + igen6_tolud - igen6_tom;

	return eaddr;
Loading