Commit 669c00f0 authored by Borislav Petkov's avatar Borislav Petkov Committed by Ingo Molnar
Browse files

x86/ras: Flip the TSC-adding logic



Add the TSC value to the MCE record only when the MCE being logged is
precise, i.e., it is logged as an exception or an MCE-related interrupt.

So it doesn't look particularly easy to do without touching/changing a
bunch of places. That's why I'm trying tricks first.

For example, the mce-apei.c case I'm addressing by setting ->tsc only
for errors of panic severity. The idea there is, that, panic errors will
have raised an #MC and not polled.

And then instead of propagating a flag to mce_setup(), it seems
easier/less code to set ->tsc depending on the call sites, i.e.,
are we polling or are we preparing an MCE record in an exception
handler/thresholding interrupt.

Signed-off-by: default avatarBorislav Petkov <bp@suse.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>
Cc: Yazen Ghannam <Yazen.Ghannam@amd.com>
Cc: linux-edac <linux-edac@vger.kernel.org>
Link: http://lkml.kernel.org/r/20170123183514.13356-5-bp@alien8.de


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 0b737a9c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -52,8 +52,11 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err)

	if (severity >= GHES_SEV_RECOVERABLE)
		m.status |= MCI_STATUS_UC;
	if (severity >= GHES_SEV_PANIC)

	if (severity >= GHES_SEV_PANIC) {
		m.status |= MCI_STATUS_PCC;
		m.tsc = rdtsc();
	}

	m.addr = mem_err->physical_addr;
	mce_log(&m);
+3 −9
Original line number Diff line number Diff line
@@ -128,7 +128,6 @@ void mce_setup(struct mce *m)
{
	memset(m, 0, sizeof(struct mce));
	m->cpu = m->extcpu = smp_processor_id();
	m->tsc = rdtsc();
	/* We hope get_seconds stays lockless */
	m->time = get_seconds();
	m->cpuvendor = boot_cpu_data.x86_vendor;
@@ -710,14 +709,8 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b)

	mce_gather_info(&m, NULL);

	/*
	 * m.tsc was set in mce_setup(). Clear it if not requested.
	 *
	 * FIXME: Propagate @flags to mce_gather_info/mce_setup() to avoid
	 *	  that dance.
	 */
	if (!(flags & MCP_TIMESTAMP))
		m.tsc = 0;
	if (flags & MCP_TIMESTAMP)
		m.tsc = rdtsc();

	for (i = 0; i < mca_cfg.banks; i++) {
		if (!mce_banks[i].ctl || !test_bit(i, *b))
@@ -1156,6 +1149,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
		goto out;

	mce_gather_info(&m, regs);
	m.tsc = rdtsc();

	final = this_cpu_ptr(&mces_seen);
	*final = m;
+2 −1
Original line number Diff line number Diff line
@@ -779,6 +779,7 @@ __log_error(unsigned int bank, bool deferred_err, bool threshold_err, u64 misc)

	m.status = status;
	m.bank   = bank;
	m.tsc	 = rdtsc();

	if (threshold_err)
		m.misc = misc;