aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2012-06-21 08:07:16 -0400
committerH. Peter Anvin <hpa@zytor.com>2012-07-01 13:24:05 -0400
commitc9fc3f778a6a215ace14ee556067c73982b6d40f (patch)
tree588ddfd51b9b2806c5ace340d44f54d144ef8128 /arch/x86/kernel
parent6887a4131da3adaab011613776d865f4bcfb5678 (diff)
x86, microcode: Sanitize per-cpu microcode reloading interface
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. Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Borislav Petkov <borislav.petkov@amd.com> Link: http://lkml.kernel.org/r/1340280437-7718-2-git-send-email-bp@amd64.org Signed-off-by: H. Peter Anvin <hpa@zytor.com> Cc: <stable@vger.kernel.org>
Diffstat (limited to 'arch/x86/kernel')
-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 fbdfc691718..24b852b61be 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -298,19 +298,31 @@ static ssize_t reload_store(struct device *dev,
298 const char *buf, size_t size) 298 const char *buf, size_t size)
299{ 299{
300 unsigned long val; 300 unsigned long val;
301 int cpu = dev->id; 301 int cpu;
302 ssize_t ret = 0; 302 ssize_t ret = 0, tmp_ret;
303
304 /* allow reload only from the BSP */
305 if (boot_cpu_data.cpu_index != dev->id)
306 return -EINVAL;
303 307
304 ret = kstrtoul(buf, 0, &val); 308 ret = kstrtoul(buf, 0, &val);
305 if (ret) 309 if (ret)
306 return ret; 310 return ret;
307 311
308 if (val == 1) { 312 if (val != 1)
309 get_online_cpus(); 313 return size;
310 if (cpu_online(cpu)) 314
311 ret = reload_for_cpu(cpu); 315 get_online_cpus();
312 put_online_cpus(); 316 for_each_online_cpu(cpu) {
317 tmp_ret = reload_for_cpu(cpu);
318 if (tmp_ret != 0)
319 pr_warn("Error reloading microcode on CPU %d\n", cpu);
320
321 /* save retval of the first encountered reload error */
322 if (!ret)
323 ret = tmp_ret;
313 } 324 }
325 put_online_cpus();
314 326
315 if (!ret) 327 if (!ret)
316 ret = size; 328 ret = size;