aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2012-06-21 08:07:16 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-15 15:04:29 -0400
commitbb014c405d5e6d92fd9617bdfc29b29ad2bf6588 (patch)
tree1ddb37b5bc228912b83bc585fda202e658aea3be /arch
parentd426c78930e6e01373e3007df81161855f5b6ec1 (diff)
x86, microcode: Sanitize per-cpu microcode reloading interface
commit c9fc3f778a6a215ace14ee556067c73982b6d40f upstream. Microcode reloading in a per-core manner is a very bad idea for both major x86 vendors. And the thing is, we have such interface with which we can end up with different microcode versions applied on different cores of an otherwise homogeneous wrt (family,model,stepping) system. So turn off the possibility of doing that per core and allow it only system-wide. This is a minimal fix which we'd like to see in stable too thus the more-or-less arbitrary decision to allow system-wide reloading only on the BSP: $ echo 1 > /sys/devices/system/cpu/cpu0/microcode/reload ... and disable the interface on the other cores: $ echo 1 > /sys/devices/system/cpu/cpu23/microcode/reload -bash: echo: write error: Invalid argument Also, allowing the reload only from one CPU (the BSP in that case) doesn't allow the reload procedure to degenerate into an O(n^2) deal when triggering reloads from all /sys/devices/system/cpu/cpuX/microcode/reload sysfs nodes simultaneously. A more generic fix will follow. Signed-off-by: Borislav Petkov <borislav.petkov@amd.com> Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1340280437-7718-2-git-send-email-bp@amd64.org Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/microcode_core.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index b9e52a53861..c4e246541c5 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -297,19 +297,31 @@ static ssize_t reload_store(struct sys_device *dev,
297 const char *buf, size_t size) 297 const char *buf, size_t size)
298{ 298{
299 unsigned long val; 299 unsigned long val;
300 int cpu = dev->id; 300 int cpu;
301 ssize_t ret = 0; 301 ssize_t ret = 0, tmp_ret;
302
303 /* allow reload only from the BSP */
304 if (boot_cpu_data.cpu_index != dev->id)
305 return -EINVAL;
302 306
303 ret = kstrtoul(buf, 0, &val); 307 ret = kstrtoul(buf, 0, &val);
304 if (ret) 308 if (ret)
305 return ret; 309 return ret;
306 310
307 if (val == 1) { 311 if (val != 1)
308 get_online_cpus(); 312 return size;
309 if (cpu_online(cpu)) 313
310 ret = reload_for_cpu(cpu); 314 get_online_cpus();
311 put_online_cpus(); 315 for_each_online_cpu(cpu) {
316 tmp_ret = reload_for_cpu(cpu);
317 if (tmp_ret != 0)
318 pr_warn("Error reloading microcode on CPU %d\n", cpu);
319
320 /* save retval of the first encountered reload error */
321 if (!ret)
322 ret = tmp_ret;
312 } 323 }
324 put_online_cpus();
313 325
314 if (!ret) 326 if (!ret)
315 ret = size; 327 ret = size;