diff options
| -rw-r--r-- | arch/x86/kernel/cpu/mce/core.c | 22 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mce/inject.c | 14 | 
2 files changed, 14 insertions, 22 deletions
| diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index e558ca77cfe8..c3498732ba28 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1481,13 +1481,12 @@ EXPORT_SYMBOL_GPL(mce_notify_irq);  static int __mcheck_cpu_mce_banks_init(void)  {  	int i; -	u8 num_banks = mca_cfg.banks; -	mce_banks = kcalloc(num_banks, sizeof(struct mce_bank), GFP_KERNEL); +	mce_banks = kcalloc(MAX_NR_BANKS, sizeof(struct mce_bank), GFP_KERNEL);  	if (!mce_banks)  		return -ENOMEM; -	for (i = 0; i < num_banks; i++) { +	for (i = 0; i < MAX_NR_BANKS; i++) {  		struct mce_bank *b = &mce_banks[i];  		b->ctl = -1ULL; @@ -1501,28 +1500,19 @@ static int __mcheck_cpu_mce_banks_init(void)   */  static int __mcheck_cpu_cap_init(void)  { -	unsigned b;  	u64 cap; +	u8 b;  	rdmsrl(MSR_IA32_MCG_CAP, cap);  	b = cap & MCG_BANKCNT_MASK; -	if (!mca_cfg.banks) -		pr_info("CPU supports %d MCE banks\n", b); - -	if (b > MAX_NR_BANKS) { -		pr_warn("Using only %u machine check banks out of %u\n", -			MAX_NR_BANKS, b); +	if (WARN_ON_ONCE(b > MAX_NR_BANKS))  		b = MAX_NR_BANKS; -	} -	/* Don't support asymmetric configurations today */ -	WARN_ON(mca_cfg.banks != 0 && b != mca_cfg.banks); -	mca_cfg.banks = b; +	mca_cfg.banks = max(mca_cfg.banks, b);  	if (!mce_banks) {  		int err = __mcheck_cpu_mce_banks_init(); -  		if (err)  			return err;  	} @@ -2481,6 +2471,8 @@ EXPORT_SYMBOL_GPL(mcsafe_key);  static int __init mcheck_late_init(void)  { +	pr_info("Using %d MCE banks\n", mca_cfg.banks); +  	if (mca_cfg.recovery)  		static_branch_inc(&mcsafe_key); diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c index 8492ef7d9015..3f82afd0f46f 100644 --- a/arch/x86/kernel/cpu/mce/inject.c +++ b/arch/x86/kernel/cpu/mce/inject.c @@ -46,8 +46,6 @@  static struct mce i_mce;  static struct dentry *dfs_inj; -static u8 n_banks; -  #define MAX_FLAG_OPT_SIZE	4  #define NBCFG			0x44 @@ -570,9 +568,15 @@ err:  static int inj_bank_set(void *data, u64 val)  {  	struct mce *m = (struct mce *)data; +	u8 n_banks; +	u64 cap; + +	/* Get bank count on target CPU so we can handle non-uniform values. */ +	rdmsrl_on_cpu(m->extcpu, MSR_IA32_MCG_CAP, &cap); +	n_banks = cap & MCG_BANKCNT_MASK;  	if (val >= n_banks) { -		pr_err("Non-existent MCE bank: %llu\n", val); +		pr_err("MCA bank %llu non-existent on CPU%d\n", val, m->extcpu);  		return -EINVAL;  	} @@ -665,10 +669,6 @@ static struct dfs_node {  static int __init debugfs_init(void)  {  	unsigned int i; -	u64 cap; - -	rdmsrl(MSR_IA32_MCG_CAP, cap); -	n_banks = cap & MCG_BANKCNT_MASK;  	dfs_inj = debugfs_create_dir("mce-inject", NULL);  	if (!dfs_inj) |