Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 429893b1 authored by Borislav Petkov's avatar Borislav Petkov Committed by Ingo Molnar
Browse files

x86/mce/AMD: Carve out threshold block preparation



mce_amd_feature_init() was getting pretty fat, carve out the
threshold_block setup into a separate function in order to
simplify flow and make it more understandable.

No functionality change.

Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Cc: Aravind Gopalakrishnan <Aravind.Gopalakrishnan@amd.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Link: http://lkml.kernel.org/r/1453750913-4781-8-git-send-email-bp@alien8.de


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent f57a1f3c
Loading
Loading
Loading
Loading
+49 −38
Original line number Diff line number Diff line
@@ -267,37 +267,13 @@ static void deferred_error_interrupt_enable(struct cpuinfo_x86 *c)
	wrmsr(MSR_CU_DEF_ERR, low, high);
}

/* cpu init entry point, called from mce.c with preempt off */
void mce_amd_feature_init(struct cpuinfo_x86 *c)
static int
prepare_threshold_block(unsigned int bank, unsigned int block, u32 addr,
			int offset, u32 misc_high)
{
	struct threshold_block b;
	unsigned int cpu = smp_processor_id();
	u32 low = 0, high = 0, address = 0;
	unsigned int bank, block;
	int offset = -1, new;

	for (bank = 0; bank < mca_cfg.banks; ++bank) {
		for (block = 0; block < NR_BLOCKS; ++block) {
			if (block == 0)
				address = MSR_IA32_MCx_MISC(bank);
			else if (block == 1) {
				address = (low & MASK_BLKPTR_LO) >> 21;
				if (!address)
					break;

				address += MCG_XBLK_ADDR;
			} else
				++address;

			if (rdmsr_safe(address, &low, &high))
				break;

			if (!(high & MASK_VALID_HI))
				continue;

			if (!(high & MASK_CNTP_HI)  ||
			     (high & MASK_LOCKED_HI))
				continue;
	struct threshold_block b;
	int new;

	if (!block)
		per_cpu(bank_map, cpu) |= (1 << bank);
@@ -306,11 +282,11 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)
	b.cpu			= cpu;
	b.bank			= bank;
	b.block			= block;
			b.address		= address;
			b.interrupt_capable	= lvt_interrupt_supported(bank, high);
	b.address		= addr;
	b.interrupt_capable	= lvt_interrupt_supported(bank, misc_high);

	if (!b.interrupt_capable)
				goto init;
		goto done;

	b.interrupt_enable = 1;

@@ -319,21 +295,56 @@ void mce_amd_feature_init(struct cpuinfo_x86 *c)

		/* Gather LVT offset for thresholding: */
		if (rdmsr_safe(MSR_CU_DEF_ERR, &smca_low, &smca_high))
					break;
			goto out;

		new = (smca_low & SMCA_THR_LVT_OFF) >> 12;
	} else {
				new = (high & MASK_LVTOFF_HI) >> 20;
		new = (misc_high & MASK_LVTOFF_HI) >> 20;
	}

	offset = setup_APIC_mce_threshold(offset, new);

			if ((offset == new) &&
			    (mce_threshold_vector != amd_threshold_interrupt))
	if ((offset == new) && (mce_threshold_vector != amd_threshold_interrupt))
		mce_threshold_vector = amd_threshold_interrupt;

init:
done:
	mce_threshold_block_init(&b, offset);

out:
	return offset;
}

/* cpu init entry point, called from mce.c with preempt off */
void mce_amd_feature_init(struct cpuinfo_x86 *c)
{
	u32 low = 0, high = 0, address = 0;
	unsigned int bank, block;
	int offset = -1;

	for (bank = 0; bank < mca_cfg.banks; ++bank) {
		for (block = 0; block < NR_BLOCKS; ++block) {
			if (block == 0)
				address = MSR_IA32_MCx_MISC(bank);
			else if (block == 1) {
				address = (low & MASK_BLKPTR_LO) >> 21;
				if (!address)
					break;

				address += MCG_XBLK_ADDR;
			} else
				++address;

			if (rdmsr_safe(address, &low, &high))
				break;

			if (!(high & MASK_VALID_HI))
				continue;

			if (!(high & MASK_CNTP_HI)  ||
			     (high & MASK_LOCKED_HI))
				continue;

			offset = prepare_threshold_block(bank, block, address, offset, high);
		}
	}