aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-03-11 17:52:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-03-11 17:52:41 -0400
commitebb3762e8867941d72b5dd1778e7062e53833230 (patch)
treeb58750f7cdc1d22a148ffb1a40e5ecaf29e5e1bc
parent8ad44243509221782168bcf250e8c5a30c00f4c1 (diff)
parentb3b7c4795ccab5be71f080774c45bbbcc75c2aaf (diff)
Merge branch 'ras-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull RAS fixes from Thomas Gleixner: "Two small fixes for RAS/MCE: - Serialize sysfs changes to avoid concurrent modificaiton of underlying data - Add microcode revision to Machine Check records. This should have been there forever, but now with the broken microcode versions in the wild it has become important" * 'ras-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/MCE: Serialize sysfs changes x86/MCE: Save microcode revision in machine check records
-rw-r--r--arch/x86/include/uapi/asm/mce.h1
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c26
2 files changed, 25 insertions, 2 deletions
diff --git a/arch/x86/include/uapi/asm/mce.h b/arch/x86/include/uapi/asm/mce.h
index 91723461dc1f..435db58a7bad 100644
--- a/arch/x86/include/uapi/asm/mce.h
+++ b/arch/x86/include/uapi/asm/mce.h
@@ -30,6 +30,7 @@ struct mce {
30 __u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */ 30 __u64 synd; /* MCA_SYND MSR: only valid on SMCA systems */
31 __u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */ 31 __u64 ipid; /* MCA_IPID MSR: only valid on SMCA systems */
32 __u64 ppin; /* Protected Processor Inventory Number */ 32 __u64 ppin; /* Protected Processor Inventory Number */
33 __u32 microcode;/* Microcode revision */
33}; 34};
34 35
35#define MCE_GET_RECORD_LEN _IOR('M', 1, int) 36#define MCE_GET_RECORD_LEN _IOR('M', 1, int)
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 8ff94d1e2dce..466f47301334 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -56,6 +56,9 @@
56 56
57static DEFINE_MUTEX(mce_log_mutex); 57static DEFINE_MUTEX(mce_log_mutex);
58 58
59/* sysfs synchronization */
60static DEFINE_MUTEX(mce_sysfs_mutex);
61
59#define CREATE_TRACE_POINTS 62#define CREATE_TRACE_POINTS
60#include <trace/events/mce.h> 63#include <trace/events/mce.h>
61 64
@@ -130,6 +133,8 @@ void mce_setup(struct mce *m)
130 133
131 if (this_cpu_has(X86_FEATURE_INTEL_PPIN)) 134 if (this_cpu_has(X86_FEATURE_INTEL_PPIN))
132 rdmsrl(MSR_PPIN, m->ppin); 135 rdmsrl(MSR_PPIN, m->ppin);
136
137 m->microcode = boot_cpu_data.microcode;
133} 138}
134 139
135DEFINE_PER_CPU(struct mce, injectm); 140DEFINE_PER_CPU(struct mce, injectm);
@@ -262,7 +267,7 @@ static void __print_mce(struct mce *m)
262 */ 267 */
263 pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n", 268 pr_emerg(HW_ERR "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x microcode %x\n",
264 m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid, 269 m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid,
265 cpu_data(m->extcpu).microcode); 270 m->microcode);
266} 271}
267 272
268static void print_mce(struct mce *m) 273static void print_mce(struct mce *m)
@@ -2086,6 +2091,7 @@ static ssize_t set_ignore_ce(struct device *s,
2086 if (kstrtou64(buf, 0, &new) < 0) 2091 if (kstrtou64(buf, 0, &new) < 0)
2087 return -EINVAL; 2092 return -EINVAL;
2088 2093
2094 mutex_lock(&mce_sysfs_mutex);
2089 if (mca_cfg.ignore_ce ^ !!new) { 2095 if (mca_cfg.ignore_ce ^ !!new) {
2090 if (new) { 2096 if (new) {
2091 /* disable ce features */ 2097 /* disable ce features */
@@ -2098,6 +2104,8 @@ static ssize_t set_ignore_ce(struct device *s,
2098 on_each_cpu(mce_enable_ce, (void *)1, 1); 2104 on_each_cpu(mce_enable_ce, (void *)1, 1);
2099 } 2105 }
2100 } 2106 }
2107 mutex_unlock(&mce_sysfs_mutex);
2108
2101 return size; 2109 return size;
2102} 2110}
2103 2111
@@ -2110,6 +2118,7 @@ static ssize_t set_cmci_disabled(struct device *s,
2110 if (kstrtou64(buf, 0, &new) < 0) 2118 if (kstrtou64(buf, 0, &new) < 0)
2111 return -EINVAL; 2119 return -EINVAL;
2112 2120
2121 mutex_lock(&mce_sysfs_mutex);
2113 if (mca_cfg.cmci_disabled ^ !!new) { 2122 if (mca_cfg.cmci_disabled ^ !!new) {
2114 if (new) { 2123 if (new) {
2115 /* disable cmci */ 2124 /* disable cmci */
@@ -2121,6 +2130,8 @@ static ssize_t set_cmci_disabled(struct device *s,
2121 on_each_cpu(mce_enable_ce, NULL, 1); 2130 on_each_cpu(mce_enable_ce, NULL, 1);
2122 } 2131 }
2123 } 2132 }
2133 mutex_unlock(&mce_sysfs_mutex);
2134
2124 return size; 2135 return size;
2125} 2136}
2126 2137
@@ -2128,8 +2139,19 @@ static ssize_t store_int_with_restart(struct device *s,
2128 struct device_attribute *attr, 2139 struct device_attribute *attr,
2129 const char *buf, size_t size) 2140 const char *buf, size_t size)
2130{ 2141{
2131 ssize_t ret = device_store_int(s, attr, buf, size); 2142 unsigned long old_check_interval = check_interval;
2143 ssize_t ret = device_store_ulong(s, attr, buf, size);
2144
2145 if (check_interval == old_check_interval)
2146 return ret;
2147
2148 if (check_interval < 1)
2149 check_interval = 1;
2150
2151 mutex_lock(&mce_sysfs_mutex);
2132 mce_restart(); 2152 mce_restart();
2153 mutex_unlock(&mce_sysfs_mutex);
2154
2133 return ret; 2155 return ret;
2134} 2156}
2135 2157