Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86 microcode: revert some work_on_cpu

Revert part of af5c820a3169e81af869c113e18ec7588836cd50 ("x86: cpumask:
use work_on_cpu in arch/x86/kernel/microcode_core.c")

That change is causing only one Intel CPU's microcode to be updated e.g.
microcode: CPU3 updated from revision 0x9 to 0x17, date = 2005-04-22
where before it announced that also for CPU0 and CPU1 and CPU2.

We cannot use work_on_cpu() in the CONFIG_MICROCODE_OLD_INTERFACE code,
because Intel's request_microcode_user() involves a copy_from_user() from
/sbin/microcode_ctl, which therefore needs to be on that CPU at the time.

Signed-off-by: Hugh Dickins <hugh@veritas.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Hugh Dickins and committed by
Linus Torvalds
6f66cbc6 610f26e7

+11 -22
+11 -22
arch/x86/kernel/microcode_core.c
··· 108 108 EXPORT_SYMBOL_GPL(ucode_cpu_info); 109 109 110 110 #ifdef CONFIG_MICROCODE_OLD_INTERFACE 111 - struct update_for_cpu { 112 - const void __user *buf; 113 - size_t size; 114 - }; 115 - 116 - static long update_for_cpu(void *_ufc) 117 - { 118 - struct update_for_cpu *ufc = _ufc; 119 - int error; 120 - 121 - error = microcode_ops->request_microcode_user(smp_processor_id(), 122 - ufc->buf, ufc->size); 123 - if (error < 0) 124 - return error; 125 - if (!error) 126 - microcode_ops->apply_microcode(smp_processor_id()); 127 - return error; 128 - } 129 - 130 111 static int do_microcode_update(const void __user *buf, size_t size) 131 112 { 113 + cpumask_t old; 132 114 int error = 0; 133 115 int cpu; 134 - struct update_for_cpu ufc = { .buf = buf, .size = size }; 116 + 117 + old = current->cpus_allowed; 135 118 136 119 for_each_online_cpu(cpu) { 137 120 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 138 121 139 122 if (!uci->valid) 140 123 continue; 141 - error = work_on_cpu(cpu, update_for_cpu, &ufc); 124 + 125 + set_cpus_allowed_ptr(current, &cpumask_of_cpu(cpu)); 126 + error = microcode_ops->request_microcode_user(cpu, buf, size); 142 127 if (error < 0) 143 - break; 128 + goto out; 129 + if (!error) 130 + microcode_ops->apply_microcode(cpu); 144 131 } 132 + out: 133 + set_cpus_allowed_ptr(current, &old); 145 134 return error; 146 135 } 147 136