Commit 6cc54473 authored by Qiuxu Zhuo's avatar Qiuxu Zhuo Committed by Song, Youquan
Browse files

EDAC/i10nm: Print an extra register set of retry_rd_err_log

mainline inclusion
from mainline-v6.1-rc1
commit d5f5e499
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I5V3SJ


CVE: NA

Intel-SIG: commit d5f5e499 EDAC/i10nm: Print an extra register set of
 retry_rd_err_log.
Backport to add retry_rd_err_log for SPR HBM.

--------------------------------

Sapphire Rapids server adds an extra register set for logging more
retry_rd_err_log data. So add code to print the extra register set.

Signed-off-by: default avatarQiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/all/20220722233338.341567-1-tony.luck@intel.com


Signed-off-by: default avatarYouquan Song <youquan.song@intel.com>
parent b03b70f5
Loading
Loading
Loading
Loading
+70 −11
Original line number Diff line number Diff line
@@ -83,26 +83,38 @@ static u32 offsets_scrub_spr_hbm0[] = {0x2860, 0x2854, 0x2b08, 0x2858, 0x2828,
static u32 offsets_scrub_spr_hbm1[]  = {0x2c60, 0x2c54, 0x2f08, 0x2c58, 0x2c28, 0x0fa8};
static u32 offsets_demand_icx[] = {0x22e54, 0x22e60, 0x22e64, 0x22e58, 0x22e5c, 0x20ee0};
static u32 offsets_demand_spr[] = {0x22e54, 0x22e60, 0x22f10, 0x22e58, 0x22e5c, 0x20ee0};
static u32 offsets_demand2_spr[] = {0x22c70, 0x22d80, 0x22f18, 0x22d58, 0x22c64, 0x20f10};
static u32 offsets_demand_spr_hbm0[] = {0x2a54, 0x2a60, 0x2b10, 0x2a58, 0x2a5c, 0x0ee0};
static u32 offsets_demand_spr_hbm1[] = {0x2e54, 0x2e60, 0x2f10, 0x2e58, 0x2e5c, 0x0fb0};

static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable,
				      u32 *offsets_scrub, u32 *offsets_demand)
				      u32 *offsets_scrub, u32 *offsets_demand,
				      u32 *offsets_demand2)
{
	u32 s, d;
	u32 s, d, d2;

	s = I10NM_GET_REG32(imc, chan, offsets_scrub[0]);
	d = I10NM_GET_REG32(imc, chan, offsets_demand[0]);
	if (offsets_demand2)
		d2 = I10NM_GET_REG32(imc, chan, offsets_demand2[0]);

	if (enable) {
		/* Save default configurations */
		imc->chan[chan].retry_rd_err_log_s = s;
		imc->chan[chan].retry_rd_err_log_d = d;
		if (offsets_demand2)
			imc->chan[chan].retry_rd_err_log_d2 = d2;

		s &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
		s |=  RETRY_RD_ERR_LOG_EN;
		d &= ~RETRY_RD_ERR_LOG_NOOVER_UC;
		d |=  RETRY_RD_ERR_LOG_EN;

		if (offsets_demand2) {
			d2 &= ~RETRY_RD_ERR_LOG_UC;
			d2 |=  RETRY_RD_ERR_LOG_NOOVER;
			d2 |=  RETRY_RD_ERR_LOG_EN;
		}
	} else {
		/* Restore default configurations */
		if (imc->chan[chan].retry_rd_err_log_s & RETRY_RD_ERR_LOG_UC)
@@ -117,10 +129,21 @@ static void __enable_retry_rd_err_log(struct skx_imc *imc, int chan, bool enable
			d |=  RETRY_RD_ERR_LOG_NOOVER;
		if (!(imc->chan[chan].retry_rd_err_log_d & RETRY_RD_ERR_LOG_EN))
			d &= ~RETRY_RD_ERR_LOG_EN;

		if (offsets_demand2) {
			if (imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_UC)
				d2 |=  RETRY_RD_ERR_LOG_UC;
			if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_NOOVER))
				d2 &=  ~RETRY_RD_ERR_LOG_NOOVER;
			if (!(imc->chan[chan].retry_rd_err_log_d2 & RETRY_RD_ERR_LOG_EN))
				d2 &= ~RETRY_RD_ERR_LOG_EN;
		}
	}

	I10NM_SET_REG32(imc, chan, offsets_scrub[0], s);
	I10NM_SET_REG32(imc, chan, offsets_demand[0], d);
	if (offsets_demand2)
		I10NM_SET_REG32(imc, chan, offsets_demand2[0], d2);
}

static void enable_retry_rd_err_log(bool enable)
@@ -141,14 +164,17 @@ static void enable_retry_rd_err_log(bool enable)
				if (imc->hbm_mc) {
					__enable_retry_rd_err_log(imc, j, enable,
								  res_cfg->offsets_scrub_hbm0,
								  res_cfg->offsets_demand_hbm0);
								  res_cfg->offsets_demand_hbm0,
								  NULL);
					__enable_retry_rd_err_log(imc, j, enable,
								  res_cfg->offsets_scrub_hbm1,
								  res_cfg->offsets_demand_hbm1);
								  res_cfg->offsets_demand_hbm1,
								  NULL);
				} else {
					__enable_retry_rd_err_log(imc, j, enable,
								  res_cfg->offsets_scrub,
								  res_cfg->offsets_demand);
								  res_cfg->offsets_demand,
								  res_cfg->offsets_demand2);
				}
			}
	}
@@ -160,7 +186,10 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
	struct skx_imc *imc = &res->dev->imc[res->imc];
	u32 log0, log1, log2, log3, log4;
	u32 corr0, corr1, corr2, corr3;
	u32 lxg0, lxg1, lxg3, lxg4;
	u32 *xffsets = NULL;
	u64 log2a, log5;
	u64 lxg2a, lxg5;
	u32 *offsets;
	int n, pch;

@@ -177,8 +206,12 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
			offsets = scrub_err ? res_cfg->offsets_scrub_hbm0 :
					      res_cfg->offsets_demand_hbm0;
	} else {
		offsets = scrub_err ? res_cfg->offsets_scrub :
				      res_cfg->offsets_demand;
		if (scrub_err) {
			offsets = res_cfg->offsets_scrub;
		} else {
			offsets = res_cfg->offsets_demand;
			xffsets = res_cfg->offsets_demand2;
		}
	}

	log0 = I10NM_GET_REG32(imc, res->channel, offsets[0]);
@@ -187,10 +220,28 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
	log4 = I10NM_GET_REG32(imc, res->channel, offsets[4]);
	log5 = I10NM_GET_REG64(imc, res->channel, offsets[5]);

	if (xffsets) {
		lxg0 = I10NM_GET_REG32(imc, res->channel, xffsets[0]);
		lxg1 = I10NM_GET_REG32(imc, res->channel, xffsets[1]);
		lxg3 = I10NM_GET_REG32(imc, res->channel, xffsets[3]);
		lxg4 = I10NM_GET_REG32(imc, res->channel, xffsets[4]);
		lxg5 = I10NM_GET_REG64(imc, res->channel, xffsets[5]);
	}

	if (res_cfg->type == SPR) {
		log2a = I10NM_GET_REG64(imc, res->channel, offsets[2]);
		n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx]",
		n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.16llx %.8x %.8x %.16llx",
			     log0, log1, log2a, log3, log4, log5);

		if (len - n > 0) {
			if (xffsets) {
				lxg2a = I10NM_GET_REG64(imc, res->channel, xffsets[2]);
				n += snprintf(msg + n, len - n, " %.8x %.8x %.16llx %.8x %.8x %.16llx]",
					     lxg0, lxg1, lxg2a, lxg3, lxg4, lxg5);
			} else {
				n += snprintf(msg + n, len - n, "]");
			}
		}
	} else {
		log2 = I10NM_GET_REG32(imc, res->channel, offsets[2]);
		n = snprintf(msg, len, " retry_rd_err_log[%.8x %.8x %.8x %.8x %.8x %.16llx]",
@@ -225,10 +276,17 @@ static void show_retry_rd_err_log(struct decoded_addr *res, char *msg,
			 corr3 & 0xffff, corr3 >> 16);

	/* Clear status bits */
	if (retry_rd_err_log == 2 && (log0 & RETRY_RD_ERR_LOG_OVER_UC_V)) {
	if (retry_rd_err_log == 2) {
		if (log0 & RETRY_RD_ERR_LOG_OVER_UC_V) {
			log0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
			I10NM_SET_REG32(imc, res->channel, offsets[0], log0);
		}

		if (xffsets && (lxg0 & RETRY_RD_ERR_LOG_OVER_UC_V)) {
			lxg0 &= ~RETRY_RD_ERR_LOG_OVER_UC_V;
			I10NM_SET_REG32(imc, res->channel, xffsets[0], lxg0);
		}
	}
}

static struct pci_dev *pci_get_dev_wrapper(int dom, unsigned int bus,
@@ -568,6 +626,7 @@ static struct res_config spr_cfg = {
	.offsets_scrub_hbm0	= offsets_scrub_spr_hbm0,
	.offsets_scrub_hbm1	= offsets_scrub_spr_hbm1,
	.offsets_demand		= offsets_demand_spr,
	.offsets_demand2	= offsets_demand2_spr,
	.offsets_demand_hbm0	= offsets_demand_spr_hbm0,
	.offsets_demand_hbm1	= offsets_demand_spr_hbm1,
};
+2 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ struct skx_dev {
			struct pci_dev	*edev;
			u32 retry_rd_err_log_s;
			u32 retry_rd_err_log_d;
			u32 retry_rd_err_log_d2;
			struct skx_dimm {
				u8 close_pg;
				u8 bank_xor_enable;
@@ -167,6 +168,7 @@ struct res_config {
	u32 *offsets_scrub_hbm0;
	u32 *offsets_scrub_hbm1;
	u32 *offsets_demand;
	u32 *offsets_demand2;
	u32 *offsets_demand_hbm0;
	u32 *offsets_demand_hbm1;
};