Commit d7223aed authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull EDAC updates from Borislav Petkov:

 - i10nm:
     - switch to using scnprintf()
     - Add Granite Rapids-D support

 - synopsys: Make sure ECC error and counter registers are cleared
   during init/probing to avoid reporting stale errors

 - igen6: Add Wildcat Lake SoCs support

 - Make sure scrub features sysfs attributes are initialized properly

 - Allocate memory repair sysfs attributes statically to reduce stack
   usage

 - Fix DIMM module size computation for DIMMs with total capacity which
   is a non power-of-two number, in amd64_edac

 - Do not be too dramatic when reporting disabled memory controllers in
   igen6_edac

 - Add support to ie31200_edac for the following SoCs:
     - Core i5-14[67]00
     - Bartless Lake-S SoCs
     - Raptor Lake-HX

* tag 'edac_updates_for_v6.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
  EDAC/{skx_common,i10nm}: Use scnprintf() for safer buffer handling
  EDAC/synopsys: Clear the ECC counters on init
  EDAC/ie31200: Add Intel Raptor Lake-HX SoCs support
  EDAC/igen6: Add Intel Wildcat Lake SoCs support
  EDAC/i10nm: Add Intel Granite Rapids-D support
  EDAC/mem_repair: Reduce stack usage in edac_mem_repair_get_desc()
  EDAC/igen6: Reduce log level to debug for absent memory controllers
  EDAC/ie31200: Document which CPUs correspond to each Raptor Lake-S device ID
  EDAC/ie31200: Enable support for Core i5-14600 and i7-14700
  ie31200/EDAC: Add Intel Bartlett Lake-S SoCs support
parents 909d2bb0 35928bc3
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
	((GET_BITFIELD(reg, 0, 10) << 12) + 0x140000)

#define I10NM_GNR_IMC_MMIO_OFFSET	0x24c000
#define I10NM_GNR_D_IMC_MMIO_OFFSET	0x206000
#define I10NM_GNR_IMC_MMIO_SIZE		0x4000
#define I10NM_HBM_IMC_MMIO_SIZE		0x9000
#define I10NM_DDR_IMC_CH_CNT(reg)	GET_BITFIELD(reg, 21, 24)
@@ -343,7 +344,7 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,

	status_mask = rrl->over_mask | rrl->uc_mask | rrl->v_mask;

	n = snprintf(msg, len, " retry_rd_err_log[");
	n = scnprintf(msg, len, " retry_rd_err_log[");
	for (i = 0; i < rrl->set_num; i++) {
		scrub = (rrl->modes[i] == FRE_SCRUB || rrl->modes[i] == LRE_SCRUB);
		if (scrub_err != scrub)
@@ -355,9 +356,9 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
			log = read_imc_reg(imc, ch, offset, width);

			if (width == 4)
				n += snprintf(msg + n, len - n, "%.8llx ", log);
				n += scnprintf(msg + n, len - n, "%.8llx ", log);
			else
				n += snprintf(msg + n, len - n, "%.16llx ", log);
				n += scnprintf(msg + n, len - n, "%.16llx ", log);

			/* Clear RRL status if RRL in Linux control mode. */
			if (retry_rd_err_log == 2 && !j && (log & status_mask))
@@ -367,10 +368,10 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,

	/* Move back one space. */
	n--;
	n += snprintf(msg + n, len - n, "]");
	n += scnprintf(msg + n, len - n, "]");

	if (len - n > 0) {
		n += snprintf(msg + n, len - n, " correrrcnt[");
		n += scnprintf(msg + n, len - n, " correrrcnt[");
		for (i = 0; i < rrl->cecnt_num && len - n > 0; i++) {
			offset = rrl->cecnt_offsets[i];
			width = rrl->cecnt_widths[i];
@@ -378,20 +379,20 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,

			/* CPUs {ICX,SPR} encode two counters per 4-byte CORRERRCNT register. */
			if (res_cfg->type <= SPR) {
				n += snprintf(msg + n, len - n, "%.4llx %.4llx ",
				n += scnprintf(msg + n, len - n, "%.4llx %.4llx ",
					      corr & 0xffff, corr >> 16);
			} else {
			/* CPUs {GNR} encode one counter per CORRERRCNT register. */
				if (width == 4)
					n += snprintf(msg + n, len - n, "%.8llx ", corr);
					n += scnprintf(msg + n, len - n, "%.8llx ", corr);
				else
					n += snprintf(msg + n, len - n, "%.16llx ", corr);
					n += scnprintf(msg + n, len - n, "%.16llx ", corr);
			}
		}

		/* Move back one space. */
		n--;
		n += snprintf(msg + n, len - n, "]");
		n += scnprintf(msg + n, len - n, "]");
	}
}

@@ -687,6 +688,14 @@ static struct pci_dev *get_gnr_mdev(struct skx_dev *d, int logical_idx, int *phy
	return NULL;
}

static u32 get_gnr_imc_mmio_offset(void)
{
	if (boot_cpu_data.x86_vfm == INTEL_GRANITERAPIDS_D)
		return I10NM_GNR_D_IMC_MMIO_OFFSET;

	return I10NM_GNR_IMC_MMIO_OFFSET;
}

/**
 * get_ddr_munit() - Get the resource of the i-th DDR memory controller.
 *
@@ -715,7 +724,7 @@ static struct pci_dev *get_ddr_munit(struct skx_dev *d, int i, u32 *offset, unsi
			return NULL;

		*offset = I10NM_GET_IMC_MMIO_OFFSET(reg) +
			  I10NM_GNR_IMC_MMIO_OFFSET +
			  get_gnr_imc_mmio_offset() +
			  physical_idx * I10NM_GNR_IMC_MMIO_SIZE;
		*size   = I10NM_GNR_IMC_MMIO_SIZE;

@@ -1030,6 +1039,7 @@ static const struct x86_cpu_id i10nm_cpuids[] = {
	X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &spr_cfg),
	X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X,  &spr_cfg),
	X86_MATCH_VFM(INTEL_GRANITERAPIDS_X,  &gnr_cfg),
	X86_MATCH_VFM(INTEL_GRANITERAPIDS_D,  &gnr_cfg),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &gnr_cfg),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,   &gnr_cfg),
	X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X,  &gnr_cfg),
+34 −4
Original line number Diff line number Diff line
@@ -87,14 +87,31 @@
#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10   0x3eca

/* Raptor Lake-S */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_1	0xa703
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2	0x4640
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3	0x4630
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4	0xa700
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_1	0xa703 /* 8P+8E,  e.g. i7-13700 */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2	0x4640 /* 6P+8E,  e.g. i5-13500, i5-13600, i5-14500 */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3	0x4630 /* 4P+0E,  e.g. i3-13100E */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4	0xa700 /* 8P+16E, e.g. i9-13900, i9-14900 */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_5	0xa740 /* 8P+12E, e.g. i7-14700 */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_S_6	0xa704 /* 6P+8E,  e.g. i5-14600 */

/* Raptor Lake-HX */
#define PCI_DEVICE_ID_INTEL_IE31200_RPL_HX_1	0xa702 /* 8P+16E, e.g. i9-13950HX */

/* Alder Lake-S */
#define PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1	0x4660

/* Bartlett Lake-S */
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_1	0x4639
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_2	0x463c
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_3	0x4642
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_4	0x4643
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_5	0xa731
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_6	0xa732
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_7	0xa733
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_8	0xa741
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_9	0xa744
#define PCI_DEVICE_ID_INTEL_IE31200_BTL_S_10	0xa745

#define IE31200_RANKS_PER_CHANNEL	8
#define IE31200_DIMMS_PER_CHANNEL	2
#define IE31200_CHANNELS		2
@@ -740,7 +757,20 @@ static const struct pci_device_id ie31200_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_2), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_3), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_4), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_5), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_S_6), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_RPL_HX_1), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_ADL_S_1), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_1), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_2), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_3), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_4), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_5), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_6), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_7), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_8), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_9), (kernel_ulong_t)&rpl_s_cfg},
	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IE31200_BTL_S_10), (kernel_ulong_t)&rpl_s_cfg},
	{ 0, } /* 0 terminated list. */
};
MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl);
+16 −1
Original line number Diff line number Diff line
@@ -275,6 +275,9 @@ static struct work_struct ecclog_work;
#define DID_PTL_H_SKU2	0xb001
#define DID_PTL_H_SKU3	0xb002

/* Compute die IDs for Wildcat Lake with IBECC */
#define DID_WCL_SKU1	0xfd00

static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
{
	union  {
@@ -569,6 +572,17 @@ static struct res_config mtl_p_cfg = {
	.err_addr_to_imc_addr	= adl_err_addr_to_imc_addr,
};

static struct res_config wcl_cfg = {
	.machine_check		= true,
	.num_imc		= 1,
	.imc_base		= 0xd800,
	.ibecc_base		= 0xd400,
	.ibecc_error_log_offset	= 0x170,
	.ibecc_available	= mtl_p_ibecc_available,
	.err_addr_to_sys_addr	= adl_err_addr_to_sys_addr,
	.err_addr_to_imc_addr	= adl_err_addr_to_imc_addr,
};

static struct pci_device_id igen6_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, DID_EHL_SKU5), (kernel_ulong_t)&ehl_cfg },
	{ PCI_VDEVICE(INTEL, DID_EHL_SKU6), (kernel_ulong_t)&ehl_cfg },
@@ -622,6 +636,7 @@ static struct pci_device_id igen6_pci_tbl[] = {
	{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&mtl_p_cfg },
	{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&mtl_p_cfg },
	{ PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&mtl_p_cfg },
	{ PCI_VDEVICE(INTEL, DID_WCL_SKU1), (kernel_ulong_t)&wcl_cfg },
	{ },
};
MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
@@ -1351,7 +1366,7 @@ static int igen6_register_mcis(struct pci_dev *pdev, u64 mchbar)
	}

	if (lmc < res_cfg->num_imc) {
		igen6_printk(KERN_WARNING, "Expected %d mcs, but only %d detected.",
		igen6_printk(KERN_DEBUG, "Expected %d mcs, but only %d detected.",
			     res_cfg->num_imc, lmc);
		res_cfg->num_imc = lmc;
	}
+22 −34
Original line number Diff line number Diff line
@@ -286,17 +286,26 @@ static umode_t mem_repair_attr_visible(struct kobject *kobj, struct attribute *a
	return 0;
}

#define MR_ATTR_RO(_name, _instance)       \
	((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_RO(_name), \
					     .instance = _instance })

#define MR_ATTR_WO(_name, _instance)       \
	((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_WO(_name), \
					     .instance = _instance })

#define MR_ATTR_RW(_name, _instance)       \
	((struct edac_mem_repair_dev_attr) { .dev_attr = __ATTR_RW(_name), \
					     .instance = _instance })
static const struct device_attribute mem_repair_dev_attr[] = {
	[MR_TYPE]	  = __ATTR_RO(repair_type),
	[MR_PERSIST_MODE] = __ATTR_RW(persist_mode),
	[MR_SAFE_IN_USE]  = __ATTR_RO(repair_safe_when_in_use),
	[MR_HPA]	  = __ATTR_RW(hpa),
	[MR_MIN_HPA]	  = __ATTR_RO(min_hpa),
	[MR_MAX_HPA]	  = __ATTR_RO(max_hpa),
	[MR_DPA]	  = __ATTR_RW(dpa),
	[MR_MIN_DPA]	  = __ATTR_RO(min_dpa),
	[MR_MAX_DPA]	  = __ATTR_RO(max_dpa),
	[MR_NIBBLE_MASK]  = __ATTR_RW(nibble_mask),
	[MR_BANK_GROUP]   = __ATTR_RW(bank_group),
	[MR_BANK]	  = __ATTR_RW(bank),
	[MR_RANK]	  = __ATTR_RW(rank),
	[MR_ROW]	  = __ATTR_RW(row),
	[MR_COLUMN]	  = __ATTR_RW(column),
	[MR_CHANNEL]	  = __ATTR_RW(channel),
	[MR_SUB_CHANNEL]  = __ATTR_RW(sub_channel),
	[MEM_DO_REPAIR]	  = __ATTR_WO(repair)
};

static int mem_repair_create_desc(struct device *dev,
				  const struct attribute_group **attr_groups,
@@ -305,34 +314,13 @@ static int mem_repair_create_desc(struct device *dev,
	struct edac_mem_repair_context *ctx;
	struct attribute_group *group;
	int i;
	struct edac_mem_repair_dev_attr dev_attr[] = {
		[MR_TYPE]	  = MR_ATTR_RO(repair_type, instance),
		[MR_PERSIST_MODE] = MR_ATTR_RW(persist_mode, instance),
		[MR_SAFE_IN_USE]  = MR_ATTR_RO(repair_safe_when_in_use, instance),
		[MR_HPA]	  = MR_ATTR_RW(hpa, instance),
		[MR_MIN_HPA]	  = MR_ATTR_RO(min_hpa, instance),
		[MR_MAX_HPA]	  = MR_ATTR_RO(max_hpa, instance),
		[MR_DPA]	  = MR_ATTR_RW(dpa, instance),
		[MR_MIN_DPA]	  = MR_ATTR_RO(min_dpa, instance),
		[MR_MAX_DPA]	  = MR_ATTR_RO(max_dpa, instance),
		[MR_NIBBLE_MASK]  = MR_ATTR_RW(nibble_mask, instance),
		[MR_BANK_GROUP]   = MR_ATTR_RW(bank_group, instance),
		[MR_BANK]	  = MR_ATTR_RW(bank, instance),
		[MR_RANK]	  = MR_ATTR_RW(rank, instance),
		[MR_ROW]	  = MR_ATTR_RW(row, instance),
		[MR_COLUMN]	  = MR_ATTR_RW(column, instance),
		[MR_CHANNEL]	  = MR_ATTR_RW(channel, instance),
		[MR_SUB_CHANNEL]  = MR_ATTR_RW(sub_channel, instance),
		[MEM_DO_REPAIR]	  = MR_ATTR_WO(repair, instance)
	};

	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	for (i = 0; i < MR_MAX_ATTRS; i++) {
		memcpy(&ctx->mem_repair_dev_attr[i],
		       &dev_attr[i], sizeof(dev_attr[i]));
		ctx->mem_repair_dev_attr[i].dev_attr = mem_repair_dev_attr[i];
		ctx->mem_repair_dev_attr[i].instance = instance;
		sysfs_attr_init(&ctx->mem_repair_dev_attr[i].dev_attr.attr);
		ctx->mem_repair_attrs[i] =
			&ctx->mem_repair_dev_attr[i].dev_attr.attr;
+2 −2
Original line number Diff line number Diff line
@@ -670,12 +670,12 @@ static void skx_mce_output_error(struct mem_ctl_info *mci,
	}

	if (res->decoded_by_adxl) {
		len = snprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
		len = scnprintf(skx_msg, MSG_SIZE, "%s%s err_code:0x%04x:0x%04x %s",
			 overflow ? " OVERFLOW" : "",
			 (uncorrected_error && recoverable) ? " recoverable" : "",
			 mscod, errcode, adxl_msg);
	} else {
		len = snprintf(skx_msg, MSG_SIZE,
		len = scnprintf(skx_msg, MSG_SIZE,
			 "%s%s err_code:0x%04x:0x%04x ProcessorSocketId:0x%x MemoryControllerId:0x%x PhysicalRankId:0x%x Row:0x%x Column:0x%x Bank:0x%x BankGroup:0x%x",
			 overflow ? " OVERFLOW" : "",
			 (uncorrected_error && recoverable) ? " recoverable" : "",
Loading