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

Merge tag 'ras_core_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull RAS updates from Borislav Petkov:
 "A relatively big amount of movements in RAS-land this time around:

   - First part of a series to move the AMD address translation code
     from arch/x86/ to amd64_edac as that is its only user anyway

   - Some MCE error injection improvements to the AMD side

   - Reorganization of the #MC handler code and the facilities it calls
     to make it noinstr-safe

   - Add support for new AMD MCA bank types and non-uniform banks layout

   - The usual set of cleanups and fixes"

* tag 'ras_core_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
  x86/mce: Reduce number of machine checks taken during recovery
  x86/mce/inject: Avoid out-of-bounds write when setting flags
  x86/MCE/AMD, EDAC/mce_amd: Support non-uniform MCA bank type enumeration
  x86/MCE/AMD, EDAC/mce_amd: Add new SMCA bank types
  x86/mce: Check regs before accessing it
  x86/mce: Mark mce_start() noinstr
  x86/mce: Mark mce_timed_out() noinstr
  x86/mce: Move the tainting outside of the noinstr region
  x86/mce: Mark mce_read_aux() noinstr
  x86/mce: Mark mce_end() noinstr
  x86/mce: Mark mce_panic() noinstr
  x86/mce: Prevent severity computation from being instrumented
  x86/mce: Allow instrumentation during task work queueing
  x86/mce: Remove noinstr annotation from mce_setup()
  x86/mce: Use mce_rdmsrl() in severity checking code
  x86/mce: Remove function-local cpus variables
  x86/mce: Do not use memset to clear the banks bitmaps
  x86/mce/inject: Set the valid bit in MCA_STATUS before error injection
  x86/mce/inject: Check if a bank is populated before injecting
  x86/mce: Get rid of cpu_missing
  ...
parents 48a60bdb 33761363
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ extern int amd_set_subcaches(int, unsigned long);

extern int amd_smn_read(u16 node, u32 address, u32 *value);
extern int amd_smn_write(u16 node, u32 address, u32 value);
extern int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo);

struct amd_l3_cache {
	unsigned indices;
+8 −20
Original line number Diff line number Diff line
@@ -313,31 +313,22 @@ enum smca_bank_types {
	SMCA_SMU,	/* System Management Unit */
	SMCA_SMU_V2,
	SMCA_MP5,	/* Microprocessor 5 Unit */
	SMCA_MPDMA,	/* MPDMA Unit */
	SMCA_NBIO,	/* Northbridge IO Unit */
	SMCA_PCIE,	/* PCI Express Unit */
	SMCA_PCIE_V2,
	SMCA_XGMI_PCS,	/* xGMI PCS Unit */
	SMCA_NBIF,	/* NBIF Unit */
	SMCA_SHUB,	/* System HUB Unit */
	SMCA_SATA,	/* SATA Unit */
	SMCA_USB,	/* USB Unit */
	SMCA_GMI_PCS,	/* GMI PCS Unit */
	SMCA_XGMI_PHY,	/* xGMI PHY Unit */
	SMCA_WAFL_PHY,	/* WAFL PHY Unit */
	SMCA_GMI_PHY,	/* GMI PHY Unit */
	N_SMCA_BANK_TYPES
};

#define HWID_MCATYPE(hwid, mcatype) (((hwid) << 16) | (mcatype))

struct smca_hwid {
	unsigned int bank_type;	/* Use with smca_bank_types for easy indexing. */
	u32 hwid_mcatype;	/* (hwid,mcatype) tuple */
	u8 count;		/* Number of instances. */
};

struct smca_bank {
	struct smca_hwid *hwid;
	u32 id;			/* Value of MCA_IPID[InstanceId]. */
	u8 sysfs_id;		/* Value used for sysfs name. */
};

extern struct smca_bank smca_banks[MAX_NR_BANKS];

extern const char *smca_get_long_name(enum smca_bank_types t);
extern bool amd_mce_is_memory_error(struct mce *m);

@@ -345,16 +336,13 @@ extern int mce_threshold_create_device(unsigned int cpu);
extern int mce_threshold_remove_device(unsigned int cpu);

void mce_amd_feature_init(struct cpuinfo_x86 *c);
int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr);
enum smca_bank_types smca_get_bank_type(unsigned int bank);
enum smca_bank_types smca_get_bank_type(unsigned int cpu, unsigned int bank);
#else

static inline int mce_threshold_create_device(unsigned int cpu)		{ return 0; };
static inline int mce_threshold_remove_device(unsigned int cpu)		{ return 0; };
static inline bool amd_mce_is_memory_error(struct mce *m)		{ return false; };
static inline void mce_amd_feature_init(struct cpuinfo_x86 *c)		{ }
static inline int
umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)	{ return -EINVAL; };
#endif

static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c)	{ return mce_amd_feature_init(c); }
+1 −48
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@
#define PCI_DEVICE_ID_AMD_19H_M40H_DF_F4 0x167d
#define PCI_DEVICE_ID_AMD_19H_M50H_DF_F4 0x166e

/* Protect the PCI config register pairs used for SMN and DF indirect access. */
/* Protect the PCI config register pairs used for SMN. */
static DEFINE_MUTEX(smn_mutex);

static u32 *flush_words;
@@ -182,53 +182,6 @@ int amd_smn_write(u16 node, u32 address, u32 value)
}
EXPORT_SYMBOL_GPL(amd_smn_write);

/*
 * Data Fabric Indirect Access uses FICAA/FICAD.
 *
 * Fabric Indirect Configuration Access Address (FICAA): Constructed based
 * on the device's Instance Id and the PCI function and register offset of
 * the desired register.
 *
 * Fabric Indirect Configuration Access Data (FICAD): There are FICAD LO
 * and FICAD HI registers but so far we only need the LO register.
 */
int amd_df_indirect_read(u16 node, u8 func, u16 reg, u8 instance_id, u32 *lo)
{
	struct pci_dev *F4;
	u32 ficaa;
	int err = -ENODEV;

	if (node >= amd_northbridges.num)
		goto out;

	F4 = node_to_amd_nb(node)->link;
	if (!F4)
		goto out;

	ficaa  = 1;
	ficaa |= reg & 0x3FC;
	ficaa |= (func & 0x7) << 11;
	ficaa |= instance_id << 16;

	mutex_lock(&smn_mutex);

	err = pci_write_config_dword(F4, 0x5C, ficaa);
	if (err) {
		pr_warn("Error writing DF Indirect FICAA, FICAA=0x%x\n", ficaa);
		goto out_unlock;
	}

	err = pci_read_config_dword(F4, 0x98, lo);
	if (err)
		pr_warn("Error reading DF Indirect FICAD LO, FICAA=0x%x.\n", ficaa);

out_unlock:
	mutex_unlock(&smn_mutex);

out:
	return err;
}
EXPORT_SYMBOL_GPL(amd_df_indirect_read);

int amd_cache_northbridges(void)
{
+51 −229
Original line number Diff line number Diff line
@@ -71,6 +71,22 @@ static const char * const smca_umc_block_names[] = {
	"misc_umc"
};

#define HWID_MCATYPE(hwid, mcatype) (((hwid) << 16) | (mcatype))

struct smca_hwid {
	unsigned int bank_type;	/* Use with smca_bank_types for easy indexing. */
	u32 hwid_mcatype;	/* (hwid,mcatype) tuple */
};

struct smca_bank {
	const struct smca_hwid *hwid;
	u32 id;			/* Value of MCA_IPID[InstanceId]. */
	u8 sysfs_id;		/* Value used for sysfs name. */
};

static DEFINE_PER_CPU_READ_MOSTLY(struct smca_bank[MAX_NR_BANKS], smca_banks);
static DEFINE_PER_CPU_READ_MOSTLY(u8[N_SMCA_BANK_TYPES], smca_bank_counts);

struct smca_bank_name {
	const char *name;	/* Short name for sysfs */
	const char *long_name;	/* Long name for pretty-printing */
@@ -95,11 +111,18 @@ static struct smca_bank_name smca_names[] = {
	[SMCA_PSP ... SMCA_PSP_V2]	= { "psp",		"Platform Security Processor" },
	[SMCA_SMU ... SMCA_SMU_V2]	= { "smu",		"System Management Unit" },
	[SMCA_MP5]			= { "mp5",		"Microprocessor 5 Unit" },
	[SMCA_MPDMA]			= { "mpdma",		"MPDMA Unit" },
	[SMCA_NBIO]			= { "nbio",		"Northbridge IO Unit" },
	[SMCA_PCIE ... SMCA_PCIE_V2]	= { "pcie",		"PCI Express Unit" },
	[SMCA_XGMI_PCS]			= { "xgmi_pcs",		"Ext Global Memory Interconnect PCS Unit" },
	[SMCA_NBIF]			= { "nbif",		"NBIF Unit" },
	[SMCA_SHUB]			= { "shub",		"System Hub Unit" },
	[SMCA_SATA]			= { "sata",		"SATA Unit" },
	[SMCA_USB]			= { "usb",		"USB Unit" },
	[SMCA_GMI_PCS]			= { "gmi_pcs",		"Global Memory Interconnect PCS Unit" },
	[SMCA_XGMI_PHY]			= { "xgmi_phy",		"Ext Global Memory Interconnect PHY Unit" },
	[SMCA_WAFL_PHY]			= { "wafl_phy",		"WAFL PHY Unit" },
	[SMCA_GMI_PHY]			= { "gmi_phy",		"Global Memory Interconnect PHY Unit" },
};

static const char *smca_get_name(enum smca_bank_types t)
@@ -119,14 +142,14 @@ const char *smca_get_long_name(enum smca_bank_types t)
}
EXPORT_SYMBOL_GPL(smca_get_long_name);

enum smca_bank_types smca_get_bank_type(unsigned int bank)
enum smca_bank_types smca_get_bank_type(unsigned int cpu, unsigned int bank)
{
	struct smca_bank *b;

	if (bank >= MAX_NR_BANKS)
		return N_SMCA_BANK_TYPES;

	b = &smca_banks[bank];
	b = &per_cpu(smca_banks, cpu)[bank];
	if (!b->hwid)
		return N_SMCA_BANK_TYPES;

@@ -134,7 +157,7 @@ enum smca_bank_types smca_get_bank_type(unsigned int bank)
}
EXPORT_SYMBOL_GPL(smca_get_bank_type);

static struct smca_hwid smca_hwid_mcatypes[] = {
static const struct smca_hwid smca_hwid_mcatypes[] = {
	/* { bank_type, hwid_mcatype } */

	/* Reserved type */
@@ -174,6 +197,9 @@ static struct smca_hwid smca_hwid_mcatypes[] = {
	/* Microprocessor 5 Unit MCA type */
	{ SMCA_MP5,	 HWID_MCATYPE(0x01, 0x2)	},

	/* MPDMA MCA type */
	{ SMCA_MPDMA,	 HWID_MCATYPE(0x01, 0x3)	},

	/* Northbridge IO Unit MCA type */
	{ SMCA_NBIO,	 HWID_MCATYPE(0x18, 0x0)	},

@@ -181,19 +207,17 @@ static struct smca_hwid smca_hwid_mcatypes[] = {
	{ SMCA_PCIE,	 HWID_MCATYPE(0x46, 0x0)	},
	{ SMCA_PCIE_V2,	 HWID_MCATYPE(0x46, 0x1)	},

	/* xGMI PCS MCA type */
	{ SMCA_XGMI_PCS, HWID_MCATYPE(0x50, 0x0)	},

	/* xGMI PHY MCA type */
	{ SMCA_NBIF,	 HWID_MCATYPE(0x6C, 0x0)	},
	{ SMCA_SHUB,	 HWID_MCATYPE(0x80, 0x0)	},
	{ SMCA_SATA,	 HWID_MCATYPE(0xA8, 0x0)	},
	{ SMCA_USB,	 HWID_MCATYPE(0xAA, 0x0)	},
	{ SMCA_GMI_PCS,  HWID_MCATYPE(0x241, 0x0)	},
	{ SMCA_XGMI_PHY, HWID_MCATYPE(0x259, 0x0)	},

	/* WAFL PHY MCA type */
	{ SMCA_WAFL_PHY, HWID_MCATYPE(0x267, 0x0)	},
	{ SMCA_GMI_PHY,	 HWID_MCATYPE(0x269, 0x0)	},
};

struct smca_bank smca_banks[MAX_NR_BANKS];
EXPORT_SYMBOL_GPL(smca_banks);

/*
 * In SMCA enabled processors, we can have multiple banks for a given IP type.
 * So to define a unique name for each bank, we use a temp c-string to append
@@ -249,8 +273,9 @@ static void smca_set_misc_banks_map(unsigned int bank, unsigned int cpu)

static void smca_configure(unsigned int bank, unsigned int cpu)
{
	u8 *bank_counts = this_cpu_ptr(smca_bank_counts);
	const struct smca_hwid *s_hwid;
	unsigned int i, hwid_mcatype;
	struct smca_hwid *s_hwid;
	u32 high, low;
	u32 smca_config = MSR_AMD64_SMCA_MCx_CONFIG(bank);

@@ -286,10 +311,6 @@ static void smca_configure(unsigned int bank, unsigned int cpu)

	smca_set_misc_banks_map(bank, cpu);

	/* Return early if this bank was already initialized. */
	if (smca_banks[bank].hwid && smca_banks[bank].hwid->hwid_mcatype != 0)
		return;

	if (rdmsr_safe(MSR_AMD64_SMCA_MCx_IPID(bank), &low, &high)) {
		pr_warn("Failed to read MCA_IPID for bank %d\n", bank);
		return;
@@ -300,10 +321,11 @@ static void smca_configure(unsigned int bank, unsigned int cpu)

	for (i = 0; i < ARRAY_SIZE(smca_hwid_mcatypes); i++) {
		s_hwid = &smca_hwid_mcatypes[i];

		if (hwid_mcatype == s_hwid->hwid_mcatype) {
			smca_banks[bank].hwid = s_hwid;
			smca_banks[bank].id = low;
			smca_banks[bank].sysfs_id = s_hwid->count++;
			this_cpu_ptr(smca_banks)[bank].hwid = s_hwid;
			this_cpu_ptr(smca_banks)[bank].id = low;
			this_cpu_ptr(smca_banks)[bank].sysfs_id = bank_counts[s_hwid->bank_type]++;
			break;
		}
	}
@@ -589,7 +611,7 @@ prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,

bool amd_filter_mce(struct mce *m)
{
	enum smca_bank_types bank_type = smca_get_bank_type(m->bank);
	enum smca_bank_types bank_type = smca_get_bank_type(m->extcpu, m->bank);
	struct cpuinfo_x86 *c = &boot_cpu_data;

	/* See Family 17h Models 10h-2Fh Erratum #1114. */
@@ -627,7 +649,7 @@ static void disable_err_thresholding(struct cpuinfo_x86 *c, unsigned int bank)
	} else if (c->x86 == 0x17 &&
		   (c->x86_model >= 0x10 && c->x86_model <= 0x2F)) {

		if (smca_get_bank_type(bank) != SMCA_IF)
		if (smca_get_bank_type(smp_processor_id(), bank) != SMCA_IF)
			return;

		msrs[0] = MSR_AMD64_SMCA_MCx_MISC(bank);
@@ -689,213 +711,13 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
		deferred_error_interrupt_enable(c);
}

int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr)
{
	u64 dram_base_addr, dram_limit_addr, dram_hole_base;
	/* We start from the normalized address */
	u64 ret_addr = norm_addr;

	u32 tmp;

	u8 die_id_shift, die_id_mask, socket_id_shift, socket_id_mask;
	u8 intlv_num_dies, intlv_num_chan, intlv_num_sockets;
	u8 intlv_addr_sel, intlv_addr_bit;
	u8 num_intlv_bits, hashed_bit;
	u8 lgcy_mmio_hole_en, base = 0;
	u8 cs_mask, cs_id = 0;
	bool hash_enabled = false;

	/* Read D18F0x1B4 (DramOffset), check if base 1 is used. */
	if (amd_df_indirect_read(nid, 0, 0x1B4, umc, &tmp))
		goto out_err;

	/* Remove HiAddrOffset from normalized address, if enabled: */
	if (tmp & BIT(0)) {
		u64 hi_addr_offset = (tmp & GENMASK_ULL(31, 20)) << 8;

		if (norm_addr >= hi_addr_offset) {
			ret_addr -= hi_addr_offset;
			base = 1;
		}
	}

	/* Read D18F0x110 (DramBaseAddress). */
	if (amd_df_indirect_read(nid, 0, 0x110 + (8 * base), umc, &tmp))
		goto out_err;

	/* Check if address range is valid. */
	if (!(tmp & BIT(0))) {
		pr_err("%s: Invalid DramBaseAddress range: 0x%x.\n",
			__func__, tmp);
		goto out_err;
	}

	lgcy_mmio_hole_en = tmp & BIT(1);
	intlv_num_chan	  = (tmp >> 4) & 0xF;
	intlv_addr_sel	  = (tmp >> 8) & 0x7;
	dram_base_addr	  = (tmp & GENMASK_ULL(31, 12)) << 16;

	/* {0, 1, 2, 3} map to address bits {8, 9, 10, 11} respectively */
	if (intlv_addr_sel > 3) {
		pr_err("%s: Invalid interleave address select %d.\n",
			__func__, intlv_addr_sel);
		goto out_err;
	}

	/* Read D18F0x114 (DramLimitAddress). */
	if (amd_df_indirect_read(nid, 0, 0x114 + (8 * base), umc, &tmp))
		goto out_err;

	intlv_num_sockets = (tmp >> 8) & 0x1;
	intlv_num_dies	  = (tmp >> 10) & 0x3;
	dram_limit_addr	  = ((tmp & GENMASK_ULL(31, 12)) << 16) | GENMASK_ULL(27, 0);

	intlv_addr_bit = intlv_addr_sel + 8;

	/* Re-use intlv_num_chan by setting it equal to log2(#channels) */
	switch (intlv_num_chan) {
	case 0:	intlv_num_chan = 0; break;
	case 1: intlv_num_chan = 1; break;
	case 3: intlv_num_chan = 2; break;
	case 5:	intlv_num_chan = 3; break;
	case 7:	intlv_num_chan = 4; break;

	case 8: intlv_num_chan = 1;
		hash_enabled = true;
		break;
	default:
		pr_err("%s: Invalid number of interleaved channels %d.\n",
			__func__, intlv_num_chan);
		goto out_err;
	}

	num_intlv_bits = intlv_num_chan;

	if (intlv_num_dies > 2) {
		pr_err("%s: Invalid number of interleaved nodes/dies %d.\n",
			__func__, intlv_num_dies);
		goto out_err;
	}

	num_intlv_bits += intlv_num_dies;

	/* Add a bit if sockets are interleaved. */
	num_intlv_bits += intlv_num_sockets;

	/* Assert num_intlv_bits <= 4 */
	if (num_intlv_bits > 4) {
		pr_err("%s: Invalid interleave bits %d.\n",
			__func__, num_intlv_bits);
		goto out_err;
	}

	if (num_intlv_bits > 0) {
		u64 temp_addr_x, temp_addr_i, temp_addr_y;
		u8 die_id_bit, sock_id_bit, cs_fabric_id;

		/*
		 * Read FabricBlockInstanceInformation3_CS[BlockFabricID].
		 * This is the fabric id for this coherent slave. Use
		 * umc/channel# as instance id of the coherent slave
		 * for FICAA.
		 */
		if (amd_df_indirect_read(nid, 0, 0x50, umc, &tmp))
			goto out_err;

		cs_fabric_id = (tmp >> 8) & 0xFF;
		die_id_bit   = 0;

		/* If interleaved over more than 1 channel: */
		if (intlv_num_chan) {
			die_id_bit = intlv_num_chan;
			cs_mask	   = (1 << die_id_bit) - 1;
			cs_id	   = cs_fabric_id & cs_mask;
		}

		sock_id_bit = die_id_bit;

		/* Read D18F1x208 (SystemFabricIdMask). */
		if (intlv_num_dies || intlv_num_sockets)
			if (amd_df_indirect_read(nid, 1, 0x208, umc, &tmp))
				goto out_err;

		/* If interleaved over more than 1 die. */
		if (intlv_num_dies) {
			sock_id_bit  = die_id_bit + intlv_num_dies;
			die_id_shift = (tmp >> 24) & 0xF;
			die_id_mask  = (tmp >> 8) & 0xFF;

			cs_id |= ((cs_fabric_id & die_id_mask) >> die_id_shift) << die_id_bit;
		}

		/* If interleaved over more than 1 socket. */
		if (intlv_num_sockets) {
			socket_id_shift	= (tmp >> 28) & 0xF;
			socket_id_mask	= (tmp >> 16) & 0xFF;

			cs_id |= ((cs_fabric_id & socket_id_mask) >> socket_id_shift) << sock_id_bit;
		}

		/*
		 * The pre-interleaved address consists of XXXXXXIIIYYYYY
		 * where III is the ID for this CS, and XXXXXXYYYYY are the
		 * address bits from the post-interleaved address.
		 * "num_intlv_bits" has been calculated to tell us how many "I"
		 * bits there are. "intlv_addr_bit" tells us how many "Y" bits
		 * there are (where "I" starts).
		 */
		temp_addr_y = ret_addr & GENMASK_ULL(intlv_addr_bit-1, 0);
		temp_addr_i = (cs_id << intlv_addr_bit);
		temp_addr_x = (ret_addr & GENMASK_ULL(63, intlv_addr_bit)) << num_intlv_bits;
		ret_addr    = temp_addr_x | temp_addr_i | temp_addr_y;
	}

	/* Add dram base address */
	ret_addr += dram_base_addr;

	/* If legacy MMIO hole enabled */
	if (lgcy_mmio_hole_en) {
		if (amd_df_indirect_read(nid, 0, 0x104, umc, &tmp))
			goto out_err;

		dram_hole_base = tmp & GENMASK(31, 24);
		if (ret_addr >= dram_hole_base)
			ret_addr += (BIT_ULL(32) - dram_hole_base);
	}

	if (hash_enabled) {
		/* Save some parentheses and grab ls-bit at the end. */
		hashed_bit =	(ret_addr >> 12) ^
				(ret_addr >> 18) ^
				(ret_addr >> 21) ^
				(ret_addr >> 30) ^
				cs_id;

		hashed_bit &= BIT(0);

		if (hashed_bit != ((ret_addr >> intlv_addr_bit) & BIT(0)))
			ret_addr ^= BIT(intlv_addr_bit);
	}

	/* Is calculated system address is above DRAM limit address? */
	if (ret_addr > dram_limit_addr)
		goto out_err;

	*sys_addr = ret_addr;
	return 0;

out_err:
	return -EINVAL;
}
EXPORT_SYMBOL_GPL(umc_normaddr_to_sysaddr);

bool amd_mce_is_memory_error(struct mce *m)
{
	/* ErrCodeExt[20:16] */
	u8 xec = (m->status >> 16) & 0x1f;

	if (mce_flags.smca)
		return smca_get_bank_type(m->bank) == SMCA_UMC && xec == 0x0;
		return smca_get_bank_type(m->extcpu, m->bank) == SMCA_UMC && xec == 0x0;

	return m->bank == 4 && xec == 0x8;
}
@@ -1211,7 +1033,7 @@ static struct kobj_type threshold_ktype = {
	.release		= threshold_block_release,
};

static const char *get_name(unsigned int bank, struct threshold_block *b)
static const char *get_name(unsigned int cpu, unsigned int bank, struct threshold_block *b)
{
	enum smca_bank_types bank_type;

@@ -1222,7 +1044,7 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
		return th_names[bank];
	}

	bank_type = smca_get_bank_type(bank);
	bank_type = smca_get_bank_type(cpu, bank);
	if (bank_type >= N_SMCA_BANK_TYPES)
		return NULL;

@@ -1232,12 +1054,12 @@ static const char *get_name(unsigned int bank, struct threshold_block *b)
		return NULL;
	}

	if (smca_banks[bank].hwid->count == 1)
	if (per_cpu(smca_bank_counts, cpu)[bank_type] == 1)
		return smca_get_name(bank_type);

	snprintf(buf_mcatype, MAX_MCATYPE_NAME_LEN,
		 "%s_%x", smca_get_name(bank_type),
			  smca_banks[bank].sysfs_id);
		 "%s_%u", smca_get_name(bank_type),
			  per_cpu(smca_banks, cpu)[bank].sysfs_id);
	return buf_mcatype;
}

@@ -1293,7 +1115,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb
	else
		tb->blocks = b;

	err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(bank, b));
	err = kobject_init_and_add(&b->kobj, &threshold_ktype, tb->kobj, get_name(cpu, bank, b));
	if (err)
		goto out_free;
recurse:
@@ -1348,7 +1170,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu,
	struct device *dev = this_cpu_read(mce_device);
	struct amd_northbridge *nb = NULL;
	struct threshold_bank *b = NULL;
	const char *name = get_name(bank, NULL);
	const char *name = get_name(cpu, bank, NULL);
	int err = 0;

	if (!dev)
+105 −44

File changed.

Preview size limit exceeded, changes collapsed.

Loading