diff options
author | Borislav Petkov <bp@suse.de> | 2017-01-23 13:35:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-01-24 03:14:54 -0500 |
commit | 669c00f09935fc7a22297eadee04536af141595b (patch) | |
tree | 9b2f73f39e9aa3e35162f32bdb356df975bb7c4b | |
parent | 0b737a9c2af85cc8295f9308d9250f9111bbf94d (diff) |
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: Borislav 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: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce-apei.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd.c | 3 |
3 files changed, 9 insertions, 11 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-apei.c b/arch/x86/kernel/cpu/mcheck/mce-apei.c index 83f1a98d37db..2eee85379689 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-apei.c +++ b/arch/x86/kernel/cpu/mcheck/mce-apei.c | |||
@@ -52,8 +52,11 @@ void apei_mce_report_mem_error(int severity, struct cper_sec_mem_err *mem_err) | |||
52 | 52 | ||
53 | if (severity >= GHES_SEV_RECOVERABLE) | 53 | if (severity >= GHES_SEV_RECOVERABLE) |
54 | m.status |= MCI_STATUS_UC; | 54 | m.status |= MCI_STATUS_UC; |
55 | if (severity >= GHES_SEV_PANIC) | 55 | |
56 | if (severity >= GHES_SEV_PANIC) { | ||
56 | m.status |= MCI_STATUS_PCC; | 57 | m.status |= MCI_STATUS_PCC; |
58 | m.tsc = rdtsc(); | ||
59 | } | ||
57 | 60 | ||
58 | m.addr = mem_err->physical_addr; | 61 | m.addr = mem_err->physical_addr; |
59 | mce_log(&m); | 62 | mce_log(&m); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 6eef6fde0f02..ca15a7e1f97d 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -128,7 +128,6 @@ void mce_setup(struct mce *m) | |||
128 | { | 128 | { |
129 | memset(m, 0, sizeof(struct mce)); | 129 | memset(m, 0, sizeof(struct mce)); |
130 | m->cpu = m->extcpu = smp_processor_id(); | 130 | m->cpu = m->extcpu = smp_processor_id(); |
131 | m->tsc = rdtsc(); | ||
132 | /* We hope get_seconds stays lockless */ | 131 | /* We hope get_seconds stays lockless */ |
133 | m->time = get_seconds(); | 132 | m->time = get_seconds(); |
134 | m->cpuvendor = boot_cpu_data.x86_vendor; | 133 | m->cpuvendor = boot_cpu_data.x86_vendor; |
@@ -710,14 +709,8 @@ bool machine_check_poll(enum mcp_flags flags, mce_banks_t *b) | |||
710 | 709 | ||
711 | mce_gather_info(&m, NULL); | 710 | mce_gather_info(&m, NULL); |
712 | 711 | ||
713 | /* | 712 | if (flags & MCP_TIMESTAMP) |
714 | * m.tsc was set in mce_setup(). Clear it if not requested. | 713 | m.tsc = rdtsc(); |
715 | * | ||
716 | * FIXME: Propagate @flags to mce_gather_info/mce_setup() to avoid | ||
717 | * that dance. | ||
718 | */ | ||
719 | if (!(flags & MCP_TIMESTAMP)) | ||
720 | m.tsc = 0; | ||
721 | 714 | ||
722 | for (i = 0; i < mca_cfg.banks; i++) { | 715 | for (i = 0; i < mca_cfg.banks; i++) { |
723 | if (!mce_banks[i].ctl || !test_bit(i, *b)) | 716 | if (!mce_banks[i].ctl || !test_bit(i, *b)) |
@@ -1156,6 +1149,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
1156 | goto out; | 1149 | goto out; |
1157 | 1150 | ||
1158 | mce_gather_info(&m, regs); | 1151 | mce_gather_info(&m, regs); |
1152 | m.tsc = rdtsc(); | ||
1159 | 1153 | ||
1160 | final = this_cpu_ptr(&mces_seen); | 1154 | final = this_cpu_ptr(&mces_seen); |
1161 | *final = m; | 1155 | *final = m; |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c index 776379e4a39c..9e5427df3243 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c | |||
@@ -778,7 +778,8 @@ __log_error(unsigned int bank, bool deferred_err, bool threshold_err, u64 misc) | |||
778 | mce_setup(&m); | 778 | mce_setup(&m); |
779 | 779 | ||
780 | m.status = status; | 780 | m.status = status; |
781 | m.bank = bank; | 781 | m.bank = bank; |
782 | m.tsc = rdtsc(); | ||
782 | 783 | ||
783 | if (threshold_err) | 784 | if (threshold_err) |
784 | m.misc = misc; | 785 | m.misc = misc; |