Commit 4bae1967357bfc78a2fad1be5e81a4b868980ae6

Authored by Ingo Molnar
1 parent af5c820a31

x86: microcode: cleanup

Impact: cleanup

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Dmitry Adamushko <dmitry.adamushko@gmail.com>
Cc: Peter Oruba <peter.oruba@amd.com>
LKML-Reference: <200903111632.37279.rusty@rustcorp.com.au>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Showing 3 changed files with 97 additions and 87 deletions Inline Diff

arch/x86/kernel/microcode_amd.c
1 /* 1 /*
2 * AMD CPU Microcode Update Driver for Linux 2 * AMD CPU Microcode Update Driver for Linux
3 * Copyright (C) 2008 Advanced Micro Devices Inc. 3 * Copyright (C) 2008 Advanced Micro Devices Inc.
4 * 4 *
5 * Author: Peter Oruba <peter.oruba@amd.com> 5 * Author: Peter Oruba <peter.oruba@amd.com>
6 * 6 *
7 * Based on work by: 7 * Based on work by:
8 * Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 8 * Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
9 * 9 *
10 * This driver allows to upgrade microcode on AMD 10 * This driver allows to upgrade microcode on AMD
11 * family 0x10 and 0x11 processors. 11 * family 0x10 and 0x11 processors.
12 * 12 *
13 * Licensed under the terms of the GNU General Public 13 * Licensed under the terms of the GNU General Public
14 * License version 2. See file COPYING for details. 14 * License version 2. See file COPYING for details.
15 */ 15 */
16 16 #include <linux/platform_device.h>
17 #include <linux/capability.h> 17 #include <linux/capability.h>
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/sched.h>
21 #include <linux/cpumask.h>
22 #include <linux/module.h>
23 #include <linux/slab.h>
24 #include <linux/vmalloc.h>
25 #include <linux/miscdevice.h> 18 #include <linux/miscdevice.h>
19 #include <linux/firmware.h>
26 #include <linux/spinlock.h> 20 #include <linux/spinlock.h>
27 #include <linux/mm.h> 21 #include <linux/cpumask.h>
28 #include <linux/fs.h> 22 #include <linux/pci_ids.h>
23 #include <linux/uaccess.h>
24 #include <linux/vmalloc.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
29 #include <linux/mutex.h> 27 #include <linux/mutex.h>
28 #include <linux/sched.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
30 #include <linux/cpu.h> 31 #include <linux/cpu.h>
31 #include <linux/firmware.h>
32 #include <linux/platform_device.h>
33 #include <linux/pci.h> 32 #include <linux/pci.h>
34 #include <linux/pci_ids.h> 33 #include <linux/fs.h>
35 #include <linux/uaccess.h> 34 #include <linux/mm.h>
36 35
37 #include <asm/msr.h>
38 #include <asm/processor.h>
39 #include <asm/microcode.h> 36 #include <asm/microcode.h>
37 #include <asm/processor.h>
38 #include <asm/msr.h>
40 39
41 MODULE_DESCRIPTION("AMD Microcode Update Driver"); 40 MODULE_DESCRIPTION("AMD Microcode Update Driver");
42 MODULE_AUTHOR("Peter Oruba"); 41 MODULE_AUTHOR("Peter Oruba");
43 MODULE_LICENSE("GPL v2"); 42 MODULE_LICENSE("GPL v2");
44 43
45 #define UCODE_MAGIC 0x00414d44 44 #define UCODE_MAGIC 0x00414d44
46 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 45 #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000
47 #define UCODE_UCODE_TYPE 0x00000001 46 #define UCODE_UCODE_TYPE 0x00000001
48 47
49 struct equiv_cpu_entry { 48 struct equiv_cpu_entry {
50 u32 installed_cpu; 49 u32 installed_cpu;
51 u32 fixed_errata_mask; 50 u32 fixed_errata_mask;
52 u32 fixed_errata_compare; 51 u32 fixed_errata_compare;
53 u16 equiv_cpu; 52 u16 equiv_cpu;
54 u16 res; 53 u16 res;
55 } __attribute__((packed)); 54 } __attribute__((packed));
56 55
57 struct microcode_header_amd { 56 struct microcode_header_amd {
58 u32 data_code; 57 u32 data_code;
59 u32 patch_id; 58 u32 patch_id;
60 u16 mc_patch_data_id; 59 u16 mc_patch_data_id;
61 u8 mc_patch_data_len; 60 u8 mc_patch_data_len;
62 u8 init_flag; 61 u8 init_flag;
63 u32 mc_patch_data_checksum; 62 u32 mc_patch_data_checksum;
64 u32 nb_dev_id; 63 u32 nb_dev_id;
65 u32 sb_dev_id; 64 u32 sb_dev_id;
66 u16 processor_rev_id; 65 u16 processor_rev_id;
67 u8 nb_rev_id; 66 u8 nb_rev_id;
68 u8 sb_rev_id; 67 u8 sb_rev_id;
69 u8 bios_api_rev; 68 u8 bios_api_rev;
70 u8 reserved1[3]; 69 u8 reserved1[3];
71 u32 match_reg[8]; 70 u32 match_reg[8];
72 } __attribute__((packed)); 71 } __attribute__((packed));
73 72
74 struct microcode_amd { 73 struct microcode_amd {
75 struct microcode_header_amd hdr; 74 struct microcode_header_amd hdr;
76 unsigned int mpb[0]; 75 unsigned int mpb[0];
77 }; 76 };
78 77
79 #define UCODE_MAX_SIZE 2048 78 #define UCODE_MAX_SIZE 2048
80 #define UCODE_CONTAINER_SECTION_HDR 8 79 #define UCODE_CONTAINER_SECTION_HDR 8
81 #define UCODE_CONTAINER_HEADER_SIZE 12 80 #define UCODE_CONTAINER_HEADER_SIZE 12
82 81
83 /* serialize access to the physical write */ 82 /* serialize access to the physical write */
84 static DEFINE_SPINLOCK(microcode_update_lock); 83 static DEFINE_SPINLOCK(microcode_update_lock);
85 84
86 static struct equiv_cpu_entry *equiv_cpu_table; 85 static struct equiv_cpu_entry *equiv_cpu_table;
87 86
88 static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) 87 static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
89 { 88 {
90 struct cpuinfo_x86 *c = &cpu_data(cpu); 89 struct cpuinfo_x86 *c = &cpu_data(cpu);
91 u32 dummy; 90 u32 dummy;
92 91
93 memset(csig, 0, sizeof(*csig)); 92 memset(csig, 0, sizeof(*csig));
94 if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { 93 if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) {
95 printk(KERN_WARNING "microcode: CPU%d: AMD CPU family 0x%x not " 94 printk(KERN_WARNING "microcode: CPU%d: AMD CPU family 0x%x not "
96 "supported\n", cpu, c->x86); 95 "supported\n", cpu, c->x86);
97 return -1; 96 return -1;
98 } 97 }
99 rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy); 98 rdmsr(MSR_AMD64_PATCH_LEVEL, csig->rev, dummy);
100 printk(KERN_INFO "microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev); 99 printk(KERN_INFO "microcode: CPU%d: patch_level=0x%x\n", cpu, csig->rev);
101 return 0; 100 return 0;
102 } 101 }
103 102
104 static int get_matching_microcode(int cpu, void *mc, int rev) 103 static int get_matching_microcode(int cpu, void *mc, int rev)
105 { 104 {
106 struct microcode_header_amd *mc_header = mc; 105 struct microcode_header_amd *mc_header = mc;
107 unsigned int current_cpu_id; 106 unsigned int current_cpu_id;
108 u16 equiv_cpu_id = 0; 107 u16 equiv_cpu_id = 0;
109 unsigned int i = 0; 108 unsigned int i = 0;
110 109
111 BUG_ON(equiv_cpu_table == NULL); 110 BUG_ON(equiv_cpu_table == NULL);
112 current_cpu_id = cpuid_eax(0x00000001); 111 current_cpu_id = cpuid_eax(0x00000001);
113 112
114 while (equiv_cpu_table[i].installed_cpu != 0) { 113 while (equiv_cpu_table[i].installed_cpu != 0) {
115 if (current_cpu_id == equiv_cpu_table[i].installed_cpu) { 114 if (current_cpu_id == equiv_cpu_table[i].installed_cpu) {
116 equiv_cpu_id = equiv_cpu_table[i].equiv_cpu; 115 equiv_cpu_id = equiv_cpu_table[i].equiv_cpu;
117 break; 116 break;
118 } 117 }
119 i++; 118 i++;
120 } 119 }
121 120
122 if (!equiv_cpu_id) { 121 if (!equiv_cpu_id) {
123 printk(KERN_WARNING "microcode: CPU%d: cpu revision " 122 printk(KERN_WARNING "microcode: CPU%d: cpu revision "
124 "not listed in equivalent cpu table\n", cpu); 123 "not listed in equivalent cpu table\n", cpu);
125 return 0; 124 return 0;
126 } 125 }
127 126
128 if (mc_header->processor_rev_id != equiv_cpu_id) { 127 if (mc_header->processor_rev_id != equiv_cpu_id) {
129 printk(KERN_ERR "microcode: CPU%d: patch mismatch " 128 printk(KERN_ERR "microcode: CPU%d: patch mismatch "
130 "(processor_rev_id: %x, equiv_cpu_id: %x)\n", 129 "(processor_rev_id: %x, equiv_cpu_id: %x)\n",
131 cpu, mc_header->processor_rev_id, equiv_cpu_id); 130 cpu, mc_header->processor_rev_id, equiv_cpu_id);
132 return 0; 131 return 0;
133 } 132 }
134 133
135 /* ucode might be chipset specific -- currently we don't support this */ 134 /* ucode might be chipset specific -- currently we don't support this */
136 if (mc_header->nb_dev_id || mc_header->sb_dev_id) { 135 if (mc_header->nb_dev_id || mc_header->sb_dev_id) {
137 printk(KERN_ERR "microcode: CPU%d: loading of chipset " 136 printk(KERN_ERR "microcode: CPU%d: loading of chipset "
138 "specific code not yet supported\n", cpu); 137 "specific code not yet supported\n", cpu);
139 return 0; 138 return 0;
140 } 139 }
141 140
142 if (mc_header->patch_id <= rev) 141 if (mc_header->patch_id <= rev)
143 return 0; 142 return 0;
144 143
145 return 1; 144 return 1;
146 } 145 }
147 146
148 static void apply_microcode_amd(int cpu) 147 static void apply_microcode_amd(int cpu)
149 { 148 {
150 unsigned long flags; 149 unsigned long flags;
151 u32 rev, dummy; 150 u32 rev, dummy;
152 int cpu_num = raw_smp_processor_id(); 151 int cpu_num = raw_smp_processor_id();
153 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 152 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
154 struct microcode_amd *mc_amd = uci->mc; 153 struct microcode_amd *mc_amd = uci->mc;
155 154
156 /* We should bind the task to the CPU */ 155 /* We should bind the task to the CPU */
157 BUG_ON(cpu_num != cpu); 156 BUG_ON(cpu_num != cpu);
158 157
159 if (mc_amd == NULL) 158 if (mc_amd == NULL)
160 return; 159 return;
161 160
162 spin_lock_irqsave(&microcode_update_lock, flags); 161 spin_lock_irqsave(&microcode_update_lock, flags);
163 wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code); 162 wrmsrl(MSR_AMD64_PATCH_LOADER, (u64)(long)&mc_amd->hdr.data_code);
164 /* get patch id after patching */ 163 /* get patch id after patching */
165 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); 164 rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
166 spin_unlock_irqrestore(&microcode_update_lock, flags); 165 spin_unlock_irqrestore(&microcode_update_lock, flags);
167 166
168 /* check current patch id and patch's id for match */ 167 /* check current patch id and patch's id for match */
169 if (rev != mc_amd->hdr.patch_id) { 168 if (rev != mc_amd->hdr.patch_id) {
170 printk(KERN_ERR "microcode: CPU%d: update failed " 169 printk(KERN_ERR "microcode: CPU%d: update failed "
171 "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id); 170 "(for patch_level=0x%x)\n", cpu, mc_amd->hdr.patch_id);
172 return; 171 return;
173 } 172 }
174 173
175 printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n", 174 printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n",
176 cpu, rev); 175 cpu, rev);
177 176
178 uci->cpu_sig.rev = rev; 177 uci->cpu_sig.rev = rev;
179 } 178 }
180 179
181 static int get_ucode_data(void *to, const u8 *from, size_t n) 180 static int get_ucode_data(void *to, const u8 *from, size_t n)
182 { 181 {
183 memcpy(to, from, n); 182 memcpy(to, from, n);
184 return 0; 183 return 0;
185 } 184 }
186 185
187 static void *get_next_ucode(const u8 *buf, unsigned int size, 186 static void *
188 unsigned int *mc_size) 187 get_next_ucode(const u8 *buf, unsigned int size, unsigned int *mc_size)
189 { 188 {
190 unsigned int total_size; 189 unsigned int total_size;
191 u8 section_hdr[UCODE_CONTAINER_SECTION_HDR]; 190 u8 section_hdr[UCODE_CONTAINER_SECTION_HDR];
192 void *mc; 191 void *mc;
193 192
194 if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR)) 193 if (get_ucode_data(section_hdr, buf, UCODE_CONTAINER_SECTION_HDR))
195 return NULL; 194 return NULL;
196 195
197 if (section_hdr[0] != UCODE_UCODE_TYPE) { 196 if (section_hdr[0] != UCODE_UCODE_TYPE) {
198 printk(KERN_ERR "microcode: error: invalid type field in " 197 printk(KERN_ERR "microcode: error: invalid type field in "
199 "container file section header\n"); 198 "container file section header\n");
200 return NULL; 199 return NULL;
201 } 200 }
202 201
203 total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8)); 202 total_size = (unsigned long) (section_hdr[4] + (section_hdr[5] << 8));
204 203
205 printk(KERN_DEBUG "microcode: size %u, total_size %u\n", 204 printk(KERN_DEBUG "microcode: size %u, total_size %u\n",
206 size, total_size); 205 size, total_size);
207 206
208 if (total_size > size || total_size > UCODE_MAX_SIZE) { 207 if (total_size > size || total_size > UCODE_MAX_SIZE) {
209 printk(KERN_ERR "microcode: error: size mismatch\n"); 208 printk(KERN_ERR "microcode: error: size mismatch\n");
210 return NULL; 209 return NULL;
211 } 210 }
212 211
213 mc = vmalloc(UCODE_MAX_SIZE); 212 mc = vmalloc(UCODE_MAX_SIZE);
214 if (mc) { 213 if (mc) {
215 memset(mc, 0, UCODE_MAX_SIZE); 214 memset(mc, 0, UCODE_MAX_SIZE);
216 if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR, 215 if (get_ucode_data(mc, buf + UCODE_CONTAINER_SECTION_HDR,
217 total_size)) { 216 total_size)) {
218 vfree(mc); 217 vfree(mc);
219 mc = NULL; 218 mc = NULL;
220 } else 219 } else
221 *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR; 220 *mc_size = total_size + UCODE_CONTAINER_SECTION_HDR;
222 } 221 }
223 return mc; 222 return mc;
224 } 223 }
225
226 224
227 static int install_equiv_cpu_table(const u8 *buf) 225 static int install_equiv_cpu_table(const u8 *buf)
228 { 226 {
229 u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE]; 227 u8 *container_hdr[UCODE_CONTAINER_HEADER_SIZE];
230 unsigned int *buf_pos = (unsigned int *)container_hdr; 228 unsigned int *buf_pos = (unsigned int *)container_hdr;
231 unsigned long size; 229 unsigned long size;
232 230
233 if (get_ucode_data(&container_hdr, buf, UCODE_CONTAINER_HEADER_SIZE)) 231 if (get_ucode_data(&container_hdr, buf, UCODE_CONTAINER_HEADER_SIZE))
234 return 0; 232 return 0;
235 233
236 size = buf_pos[2]; 234 size = buf_pos[2];
237 235
238 if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) { 236 if (buf_pos[1] != UCODE_EQUIV_CPU_TABLE_TYPE || !size) {
239 printk(KERN_ERR "microcode: error: invalid type field in " 237 printk(KERN_ERR "microcode: error: invalid type field in "
240 "container file section header\n"); 238 "container file section header\n");
241 return 0; 239 return 0;
242 } 240 }
243 241
244 equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size); 242 equiv_cpu_table = (struct equiv_cpu_entry *) vmalloc(size);
245 if (!equiv_cpu_table) { 243 if (!equiv_cpu_table) {
246 printk(KERN_ERR "microcode: failed to allocate " 244 printk(KERN_ERR "microcode: failed to allocate "
247 "equivalent CPU table\n"); 245 "equivalent CPU table\n");
248 return 0; 246 return 0;
249 } 247 }
250 248
251 buf += UCODE_CONTAINER_HEADER_SIZE; 249 buf += UCODE_CONTAINER_HEADER_SIZE;
252 if (get_ucode_data(equiv_cpu_table, buf, size)) { 250 if (get_ucode_data(equiv_cpu_table, buf, size)) {
253 vfree(equiv_cpu_table); 251 vfree(equiv_cpu_table);
254 return 0; 252 return 0;
255 } 253 }
256 254
257 return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */ 255 return size + UCODE_CONTAINER_HEADER_SIZE; /* add header length */
258 } 256 }
259 257
260 static void free_equiv_cpu_table(void) 258 static void free_equiv_cpu_table(void)
261 { 259 {
262 if (equiv_cpu_table) { 260 if (equiv_cpu_table) {
263 vfree(equiv_cpu_table); 261 vfree(equiv_cpu_table);
264 equiv_cpu_table = NULL; 262 equiv_cpu_table = NULL;
265 } 263 }
266 } 264 }
267 265
268 static int generic_load_microcode(int cpu, const u8 *data, size_t size) 266 static int generic_load_microcode(int cpu, const u8 *data, size_t size)
269 { 267 {
270 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 268 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
271 const u8 *ucode_ptr = data; 269 const u8 *ucode_ptr = data;
272 void *new_mc = NULL; 270 void *new_mc = NULL;
273 void *mc; 271 void *mc;
274 int new_rev = uci->cpu_sig.rev; 272 int new_rev = uci->cpu_sig.rev;
275 unsigned int leftover; 273 unsigned int leftover;
276 unsigned long offset; 274 unsigned long offset;
277 275
278 offset = install_equiv_cpu_table(ucode_ptr); 276 offset = install_equiv_cpu_table(ucode_ptr);
279 if (!offset) { 277 if (!offset) {
280 printk(KERN_ERR "microcode: failed to create " 278 printk(KERN_ERR "microcode: failed to create "
281 "equivalent cpu table\n"); 279 "equivalent cpu table\n");
282 return -EINVAL; 280 return -EINVAL;
283 } 281 }
284 282
285 ucode_ptr += offset; 283 ucode_ptr += offset;
286 leftover = size - offset; 284 leftover = size - offset;
287 285
288 while (leftover) { 286 while (leftover) {
289 unsigned int uninitialized_var(mc_size); 287 unsigned int uninitialized_var(mc_size);
290 struct microcode_header_amd *mc_header; 288 struct microcode_header_amd *mc_header;
291 289
292 mc = get_next_ucode(ucode_ptr, leftover, &mc_size); 290 mc = get_next_ucode(ucode_ptr, leftover, &mc_size);
293 if (!mc) 291 if (!mc)
294 break; 292 break;
295 293
296 mc_header = (struct microcode_header_amd *)mc; 294 mc_header = (struct microcode_header_amd *)mc;
297 if (get_matching_microcode(cpu, mc, new_rev)) { 295 if (get_matching_microcode(cpu, mc, new_rev)) {
298 if (new_mc) 296 if (new_mc)
299 vfree(new_mc); 297 vfree(new_mc);
300 new_rev = mc_header->patch_id; 298 new_rev = mc_header->patch_id;
301 new_mc = mc; 299 new_mc = mc;
302 } else 300 } else
303 vfree(mc); 301 vfree(mc);
304 302
305 ucode_ptr += mc_size; 303 ucode_ptr += mc_size;
306 leftover -= mc_size; 304 leftover -= mc_size;
307 } 305 }
308 306
309 if (new_mc) { 307 if (new_mc) {
310 if (!leftover) { 308 if (!leftover) {
311 if (uci->mc) 309 if (uci->mc)
312 vfree(uci->mc); 310 vfree(uci->mc);
313 uci->mc = new_mc; 311 uci->mc = new_mc;
314 pr_debug("microcode: CPU%d found a matching microcode " 312 pr_debug("microcode: CPU%d found a matching microcode "
315 "update with version 0x%x (current=0x%x)\n", 313 "update with version 0x%x (current=0x%x)\n",
316 cpu, new_rev, uci->cpu_sig.rev); 314 cpu, new_rev, uci->cpu_sig.rev);
317 } else 315 } else
318 vfree(new_mc); 316 vfree(new_mc);
319 } 317 }
320 318
321 free_equiv_cpu_table(); 319 free_equiv_cpu_table();
322 320
323 return (int)leftover; 321 return (int)leftover;
324 } 322 }
325 323
326 static int request_microcode_fw(int cpu, struct device *device) 324 static int request_microcode_fw(int cpu, struct device *device)
327 { 325 {
328 const char *fw_name = "amd-ucode/microcode_amd.bin"; 326 const char *fw_name = "amd-ucode/microcode_amd.bin";
329 const struct firmware *firmware; 327 const struct firmware *firmware;
330 int ret; 328 int ret;
331 329
332 /* We should bind the task to the CPU */ 330 /* We should bind the task to the CPU */
333 BUG_ON(cpu != raw_smp_processor_id()); 331 BUG_ON(cpu != raw_smp_processor_id());
334 332
335 ret = request_firmware(&firmware, fw_name, device); 333 ret = request_firmware(&firmware, fw_name, device);
336 if (ret) { 334 if (ret) {
337 printk(KERN_ERR "microcode: failed to load file %s\n", fw_name); 335 printk(KERN_ERR "microcode: failed to load file %s\n", fw_name);
338 return ret; 336 return ret;
339 } 337 }
340 338
341 ret = generic_load_microcode(cpu, firmware->data, firmware->size); 339 ret = generic_load_microcode(cpu, firmware->data, firmware->size);
342 340
343 release_firmware(firmware); 341 release_firmware(firmware);
344 342
345 return ret; 343 return ret;
346 } 344 }
347 345
348 static int request_microcode_user(int cpu, const void __user *buf, size_t size) 346 static int request_microcode_user(int cpu, const void __user *buf, size_t size)
349 { 347 {
350 printk(KERN_INFO "microcode: AMD microcode update via " 348 printk(KERN_INFO "microcode: AMD microcode update via "
351 "/dev/cpu/microcode not supported\n"); 349 "/dev/cpu/microcode not supported\n");
352 return -1; 350 return -1;
353 } 351 }
354 352
355 static void microcode_fini_cpu_amd(int cpu) 353 static void microcode_fini_cpu_amd(int cpu)
356 { 354 {
357 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 355 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
358 356
359 vfree(uci->mc); 357 vfree(uci->mc);
360 uci->mc = NULL; 358 uci->mc = NULL;
361 } 359 }
362 360
363 static struct microcode_ops microcode_amd_ops = { 361 static struct microcode_ops microcode_amd_ops = {
364 .request_microcode_user = request_microcode_user, 362 .request_microcode_user = request_microcode_user,
365 .request_microcode_fw = request_microcode_fw, 363 .request_microcode_fw = request_microcode_fw,
366 .collect_cpu_info = collect_cpu_info_amd, 364 .collect_cpu_info = collect_cpu_info_amd,
arch/x86/kernel/microcode_core.c
1 /* 1 /*
2 * Intel CPU Microcode Update Driver for Linux 2 * Intel CPU Microcode Update Driver for Linux
3 * 3 *
4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5 * 2006 Shaohua Li <shaohua.li@intel.com> 5 * 2006 Shaohua Li <shaohua.li@intel.com>
6 * 6 *
7 * This driver allows to upgrade microcode on Intel processors 7 * This driver allows to upgrade microcode on Intel processors
8 * belonging to IA-32 family - PentiumPro, Pentium II, 8 * belonging to IA-32 family - PentiumPro, Pentium II,
9 * Pentium III, Xeon, Pentium 4, etc. 9 * Pentium III, Xeon, Pentium 4, etc.
10 * 10 *
11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
12 * Software Developer's Manual 12 * Software Developer's Manual
13 * Order Number 253668 or free download from: 13 * Order Number 253668 or free download from:
14 * 14 *
15 * http://developer.intel.com/design/pentium4/manuals/253668.htm 15 * http://developer.intel.com/design/pentium4/manuals/253668.htm
16 * 16 *
17 * For more information, go to http://www.urbanmyth.org/microcode 17 * For more information, go to http://www.urbanmyth.org/microcode
18 * 18 *
19 * This program is free software; you can redistribute it and/or 19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License 20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version. 22 * 2 of the License, or (at your option) any later version.
23 * 23 *
24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> 24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>
25 * Initial release. 25 * Initial release.
26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> 26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>
27 * Added read() support + cleanups. 27 * Added read() support + cleanups.
28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> 28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>
29 * Added 'device trimming' support. open(O_WRONLY) zeroes 29 * Added 'device trimming' support. open(O_WRONLY) zeroes
30 * and frees the saved copy of applied microcode. 30 * and frees the saved copy of applied microcode.
31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> 31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>
32 * Made to use devfs (/dev/cpu/microcode) + cleanups. 32 * Made to use devfs (/dev/cpu/microcode) + cleanups.
33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> 33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>
34 * Added misc device support (now uses both devfs and misc). 34 * Added misc device support (now uses both devfs and misc).
35 * Added MICROCODE_IOCFREE ioctl to clear memory. 35 * Added MICROCODE_IOCFREE ioctl to clear memory.
36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> 36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>
37 * Messages for error cases (non Intel & no suitable microcode). 37 * Messages for error cases (non Intel & no suitable microcode).
38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> 38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>
39 * Removed ->release(). Removed exclusive open and status bitmap. 39 * Removed ->release(). Removed exclusive open and status bitmap.
40 * Added microcode_rwsem to serialize read()/write()/ioctl(). 40 * Added microcode_rwsem to serialize read()/write()/ioctl().
41 * Removed global kernel lock usage. 41 * Removed global kernel lock usage.
42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> 42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>
43 * Write 0 to 0x8B msr and then cpuid before reading revision, 43 * Write 0 to 0x8B msr and then cpuid before reading revision,
44 * so that it works even if there were no update done by the 44 * so that it works even if there were no update done by the
45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened 45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened
46 * to be 0 on my machine which is why it worked even when I 46 * to be 0 on my machine which is why it worked even when I
47 * disabled update by the BIOS) 47 * disabled update by the BIOS)
48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. 48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.
49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and 49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and
50 * Tigran Aivazian <tigran@veritas.com> 50 * Tigran Aivazian <tigran@veritas.com>
51 * Intel Pentium 4 processor support and bugfixes. 51 * Intel Pentium 4 processor support and bugfixes.
52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> 52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>
53 * Bugfix for HT (Hyper-Threading) enabled processors 53 * Bugfix for HT (Hyper-Threading) enabled processors
54 * whereby processor resources are shared by all logical processors 54 * whereby processor resources are shared by all logical processors
55 * in a single CPU package. 55 * in a single CPU package.
56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and 56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
57 * Tigran Aivazian <tigran@veritas.com>, 57 * Tigran Aivazian <tigran@veritas.com>,
58 * Serialize updates as required on HT processors due to 58 * Serialize updates as required on HT processors due to
59 * speculative nature of implementation. 59 * speculative nature of implementation.
60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
61 * Fix the panic when writing zero-length microcode chunk. 61 * Fix the panic when writing zero-length microcode chunk.
62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,
63 * Jun Nakajima <jun.nakajima@intel.com> 63 * Jun Nakajima <jun.nakajima@intel.com>
64 * Support for the microcode updates in the new format. 64 * Support for the microcode updates in the new format.
65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
67 * because we no longer hold a copy of applied microcode 67 * because we no longer hold a copy of applied microcode
68 * in kernel memory. 68 * in kernel memory.
69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
70 * Fix sigmatch() macro to handle old CPUs with pf == 0. 70 * Fix sigmatch() macro to handle old CPUs with pf == 0.
71 * Thanks to Stuart Swales for pointing out this bug. 71 * Thanks to Stuart Swales for pointing out this bug.
72 */ 72 */
73 #include <linux/platform_device.h>
73 #include <linux/capability.h> 74 #include <linux/capability.h>
74 #include <linux/kernel.h> 75 #include <linux/miscdevice.h>
75 #include <linux/init.h> 76 #include <linux/firmware.h>
76 #include <linux/sched.h>
77 #include <linux/smp_lock.h> 77 #include <linux/smp_lock.h>
78 #include <linux/spinlock.h>
78 #include <linux/cpumask.h> 79 #include <linux/cpumask.h>
79 #include <linux/module.h> 80 #include <linux/uaccess.h>
80 #include <linux/slab.h>
81 #include <linux/vmalloc.h> 81 #include <linux/vmalloc.h>
82 #include <linux/miscdevice.h> 82 #include <linux/kernel.h>
83 #include <linux/spinlock.h> 83 #include <linux/module.h>
84 #include <linux/mm.h>
85 #include <linux/fs.h>
86 #include <linux/mutex.h> 84 #include <linux/mutex.h>
85 #include <linux/sched.h>
86 #include <linux/init.h>
87 #include <linux/slab.h>
87 #include <linux/cpu.h> 88 #include <linux/cpu.h>
88 #include <linux/firmware.h> 89 #include <linux/fs.h>
89 #include <linux/platform_device.h> 90 #include <linux/mm.h>
90 91
91 #include <asm/msr.h>
92 #include <asm/uaccess.h>
93 #include <asm/processor.h>
94 #include <asm/microcode.h> 92 #include <asm/microcode.h>
93 #include <asm/processor.h>
94 #include <asm/msr.h>
95 95
96 MODULE_DESCRIPTION("Microcode Update Driver"); 96 MODULE_DESCRIPTION("Microcode Update Driver");
97 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 97 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
98 MODULE_LICENSE("GPL"); 98 MODULE_LICENSE("GPL");
99 99
100 #define MICROCODE_VERSION "2.00" 100 #define MICROCODE_VERSION "2.00"
101 101
102 static struct microcode_ops *microcode_ops; 102 static struct microcode_ops *microcode_ops;
103 103
104 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ 104 /* no concurrent ->write()s are allowed on /dev/cpu/microcode */
105 static DEFINE_MUTEX(microcode_mutex); 105 static DEFINE_MUTEX(microcode_mutex);
106 106
107 struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 107 struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
108 EXPORT_SYMBOL_GPL(ucode_cpu_info); 108 EXPORT_SYMBOL_GPL(ucode_cpu_info);
109 109
110 #ifdef CONFIG_MICROCODE_OLD_INTERFACE 110 #ifdef CONFIG_MICROCODE_OLD_INTERFACE
111 struct update_for_cpu { 111 struct update_for_cpu {
112 const void __user *buf; 112 const void __user *buf;
113 size_t size; 113 size_t size;
114 }; 114 };
115 115
116 static long update_for_cpu(void *_ufc) 116 static long update_for_cpu(void *_ufc)
117 { 117 {
118 struct update_for_cpu *ufc = _ufc; 118 struct update_for_cpu *ufc = _ufc;
119 int error; 119 int error;
120 120
121 error = microcode_ops->request_microcode_user(smp_processor_id(), 121 error = microcode_ops->request_microcode_user(smp_processor_id(),
122 ufc->buf, ufc->size); 122 ufc->buf, ufc->size);
123 if (error < 0) 123 if (error < 0)
124 return error; 124 return error;
125 if (!error) 125 if (!error)
126 microcode_ops->apply_microcode(smp_processor_id()); 126 microcode_ops->apply_microcode(smp_processor_id());
127 return error; 127 return error;
128 } 128 }
129 129
130 static int do_microcode_update(const void __user *buf, size_t size) 130 static int do_microcode_update(const void __user *buf, size_t size)
131 { 131 {
132 int error = 0; 132 int error = 0;
133 int cpu; 133 int cpu;
134 struct update_for_cpu ufc = { .buf = buf, .size = size }; 134 struct update_for_cpu ufc = { .buf = buf, .size = size };
135 135
136 for_each_online_cpu(cpu) { 136 for_each_online_cpu(cpu) {
137 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 137 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
138 138
139 if (!uci->valid) 139 if (!uci->valid)
140 continue; 140 continue;
141 error = work_on_cpu(cpu, update_for_cpu, &ufc); 141 error = work_on_cpu(cpu, update_for_cpu, &ufc);
142 if (error < 0) 142 if (error < 0)
143 break; 143 break;
144 } 144 }
145 return error; 145 return error;
146 } 146 }
147 147
148 static int microcode_open(struct inode *unused1, struct file *unused2) 148 static int microcode_open(struct inode *unused1, struct file *unused2)
149 { 149 {
150 cycle_kernel_lock(); 150 cycle_kernel_lock();
151 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; 151 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
152 } 152 }
153 153
154 static ssize_t microcode_write(struct file *file, const char __user *buf, 154 static ssize_t microcode_write(struct file *file, const char __user *buf,
155 size_t len, loff_t *ppos) 155 size_t len, loff_t *ppos)
156 { 156 {
157 ssize_t ret; 157 ssize_t ret;
158 158
159 if ((len >> PAGE_SHIFT) > num_physpages) { 159 if ((len >> PAGE_SHIFT) > num_physpages) {
160 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", 160 printk(KERN_ERR "microcode: too much data (max %ld pages)\n",
161 num_physpages); 161 num_physpages);
162 return -EINVAL; 162 return -EINVAL;
163 } 163 }
164 164
165 get_online_cpus(); 165 get_online_cpus();
166 mutex_lock(&microcode_mutex); 166 mutex_lock(&microcode_mutex);
167 167
168 ret = do_microcode_update(buf, len); 168 ret = do_microcode_update(buf, len);
169 if (!ret) 169 if (!ret)
170 ret = (ssize_t)len; 170 ret = (ssize_t)len;
171 171
172 mutex_unlock(&microcode_mutex); 172 mutex_unlock(&microcode_mutex);
173 put_online_cpus(); 173 put_online_cpus();
174 174
175 return ret; 175 return ret;
176 } 176 }
177 177
178 static const struct file_operations microcode_fops = { 178 static const struct file_operations microcode_fops = {
179 .owner = THIS_MODULE, 179 .owner = THIS_MODULE,
180 .write = microcode_write, 180 .write = microcode_write,
181 .open = microcode_open, 181 .open = microcode_open,
182 }; 182 };
183 183
184 static struct miscdevice microcode_dev = { 184 static struct miscdevice microcode_dev = {
185 .minor = MICROCODE_MINOR, 185 .minor = MICROCODE_MINOR,
186 .name = "microcode", 186 .name = "microcode",
187 .fops = &microcode_fops, 187 .fops = &microcode_fops,
188 }; 188 };
189 189
190 static int __init microcode_dev_init(void) 190 static int __init microcode_dev_init(void)
191 { 191 {
192 int error; 192 int error;
193 193
194 error = misc_register(&microcode_dev); 194 error = misc_register(&microcode_dev);
195 if (error) { 195 if (error) {
196 printk(KERN_ERR 196 printk(KERN_ERR
197 "microcode: can't misc_register on minor=%d\n", 197 "microcode: can't misc_register on minor=%d\n",
198 MICROCODE_MINOR); 198 MICROCODE_MINOR);
199 return error; 199 return error;
200 } 200 }
201 201
202 return 0; 202 return 0;
203 } 203 }
204 204
205 static void microcode_dev_exit(void) 205 static void microcode_dev_exit(void)
206 { 206 {
207 misc_deregister(&microcode_dev); 207 misc_deregister(&microcode_dev);
208 } 208 }
209 209
210 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); 210 MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
211 #else 211 #else
212 #define microcode_dev_init() 0 212 #define microcode_dev_init() 0
213 #define microcode_dev_exit() do { } while (0) 213 #define microcode_dev_exit() do { } while (0)
214 #endif 214 #endif
215 215
216 /* fake device for request_firmware */ 216 /* fake device for request_firmware */
217 static struct platform_device *microcode_pdev; 217 static struct platform_device *microcode_pdev;
218 218
219 static long reload_for_cpu(void *unused) 219 static long reload_for_cpu(void *unused)
220 { 220 {
221 struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id(); 221 struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
222 int err = 0; 222 int err = 0;
223 223
224 mutex_lock(&microcode_mutex); 224 mutex_lock(&microcode_mutex);
225 if (uci->valid) { 225 if (uci->valid) {
226 err = microcode_ops->request_microcode_fw(smp_processor_id(), 226 err = microcode_ops->request_microcode_fw(smp_processor_id(),
227 &microcode_pdev->dev); 227 &microcode_pdev->dev);
228 if (!err) 228 if (!err)
229 microcode_ops->apply_microcode(smp_processor_id()); 229 microcode_ops->apply_microcode(smp_processor_id());
230 } 230 }
231 mutex_unlock(&microcode_mutex); 231 mutex_unlock(&microcode_mutex);
232 return err; 232 return err;
233 } 233 }
234 234
235 static ssize_t reload_store(struct sys_device *dev, 235 static ssize_t reload_store(struct sys_device *dev,
236 struct sysdev_attribute *attr, 236 struct sysdev_attribute *attr,
237 const char *buf, size_t sz) 237 const char *buf, size_t sz)
238 { 238 {
239 char *end; 239 char *end;
240 unsigned long val = simple_strtoul(buf, &end, 0); 240 unsigned long val = simple_strtoul(buf, &end, 0);
241 int err = 0; 241 int err = 0;
242 int cpu = dev->id; 242 int cpu = dev->id;
243 243
244 if (end == buf) 244 if (end == buf)
245 return -EINVAL; 245 return -EINVAL;
246 if (val == 1) { 246 if (val == 1) {
247 get_online_cpus(); 247 get_online_cpus();
248 if (cpu_online(cpu)) 248 if (cpu_online(cpu))
249 err = work_on_cpu(cpu, reload_for_cpu, NULL); 249 err = work_on_cpu(cpu, reload_for_cpu, NULL);
250 put_online_cpus(); 250 put_online_cpus();
251 } 251 }
252 if (err) 252 if (err)
253 return err; 253 return err;
254 return sz; 254 return sz;
255 } 255 }
256 256
257 static ssize_t version_show(struct sys_device *dev, 257 static ssize_t version_show(struct sys_device *dev,
258 struct sysdev_attribute *attr, char *buf) 258 struct sysdev_attribute *attr, char *buf)
259 { 259 {
260 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 260 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
261 261
262 return sprintf(buf, "0x%x\n", uci->cpu_sig.rev); 262 return sprintf(buf, "0x%x\n", uci->cpu_sig.rev);
263 } 263 }
264 264
265 static ssize_t pf_show(struct sys_device *dev, 265 static ssize_t pf_show(struct sys_device *dev,
266 struct sysdev_attribute *attr, char *buf) 266 struct sysdev_attribute *attr, char *buf)
267 { 267 {
268 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; 268 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
269 269
270 return sprintf(buf, "0x%x\n", uci->cpu_sig.pf); 270 return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
271 } 271 }
272 272
273 static SYSDEV_ATTR(reload, 0200, NULL, reload_store); 273 static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
274 static SYSDEV_ATTR(version, 0400, version_show, NULL); 274 static SYSDEV_ATTR(version, 0400, version_show, NULL);
275 static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL); 275 static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
276 276
277 static struct attribute *mc_default_attrs[] = { 277 static struct attribute *mc_default_attrs[] = {
278 &attr_reload.attr, 278 &attr_reload.attr,
279 &attr_version.attr, 279 &attr_version.attr,
280 &attr_processor_flags.attr, 280 &attr_processor_flags.attr,
281 NULL 281 NULL
282 }; 282 };
283 283
284 static struct attribute_group mc_attr_group = { 284 static struct attribute_group mc_attr_group = {
285 .attrs = mc_default_attrs, 285 .attrs = mc_default_attrs,
286 .name = "microcode", 286 .name = "microcode",
287 }; 287 };
288 288
289 static void __microcode_fini_cpu(int cpu) 289 static void __microcode_fini_cpu(int cpu)
290 { 290 {
291 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 291 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
292 292
293 microcode_ops->microcode_fini_cpu(cpu); 293 microcode_ops->microcode_fini_cpu(cpu);
294 uci->valid = 0; 294 uci->valid = 0;
295 } 295 }
296 296
297 static void microcode_fini_cpu(int cpu) 297 static void microcode_fini_cpu(int cpu)
298 { 298 {
299 mutex_lock(&microcode_mutex); 299 mutex_lock(&microcode_mutex);
300 __microcode_fini_cpu(cpu); 300 __microcode_fini_cpu(cpu);
301 mutex_unlock(&microcode_mutex); 301 mutex_unlock(&microcode_mutex);
302 } 302 }
303 303
304 static void collect_cpu_info(int cpu) 304 static void collect_cpu_info(int cpu)
305 { 305 {
306 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 306 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
307 307
308 memset(uci, 0, sizeof(*uci)); 308 memset(uci, 0, sizeof(*uci));
309 if (!microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig)) 309 if (!microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig))
310 uci->valid = 1; 310 uci->valid = 1;
311 } 311 }
312 312
313 static int microcode_resume_cpu(int cpu) 313 static int microcode_resume_cpu(int cpu)
314 { 314 {
315 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 315 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
316 struct cpu_signature nsig; 316 struct cpu_signature nsig;
317 317
318 pr_debug("microcode: CPU%d resumed\n", cpu); 318 pr_debug("microcode: CPU%d resumed\n", cpu);
319 319
320 if (!uci->mc) 320 if (!uci->mc)
321 return 1; 321 return 1;
322 322
323 /* 323 /*
324 * Let's verify that the 'cached' ucode does belong 324 * Let's verify that the 'cached' ucode does belong
325 * to this cpu (a bit of paranoia): 325 * to this cpu (a bit of paranoia):
326 */ 326 */
327 if (microcode_ops->collect_cpu_info(cpu, &nsig)) { 327 if (microcode_ops->collect_cpu_info(cpu, &nsig)) {
328 __microcode_fini_cpu(cpu); 328 __microcode_fini_cpu(cpu);
329 printk(KERN_ERR "failed to collect_cpu_info for resuming cpu #%d\n", 329 printk(KERN_ERR "failed to collect_cpu_info for resuming cpu #%d\n",
330 cpu); 330 cpu);
331 return -1; 331 return -1;
332 } 332 }
333 333
334 if ((nsig.sig != uci->cpu_sig.sig) || (nsig.pf != uci->cpu_sig.pf)) { 334 if ((nsig.sig != uci->cpu_sig.sig) || (nsig.pf != uci->cpu_sig.pf)) {
335 __microcode_fini_cpu(cpu); 335 __microcode_fini_cpu(cpu);
336 printk(KERN_ERR "cached ucode doesn't match the resuming cpu #%d\n", 336 printk(KERN_ERR "cached ucode doesn't match the resuming cpu #%d\n",
337 cpu); 337 cpu);
338 /* Should we look for a new ucode here? */ 338 /* Should we look for a new ucode here? */
339 return 1; 339 return 1;
340 } 340 }
341 341
342 return 0; 342 return 0;
343 } 343 }
344 344
345 static long microcode_update_cpu(void *unused) 345 static long microcode_update_cpu(void *unused)
346 { 346 {
347 struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id(); 347 struct ucode_cpu_info *uci = ucode_cpu_info + smp_processor_id();
348 int err = 0; 348 int err = 0;
349 349
350 /* 350 /*
351 * Check if the system resume is in progress (uci->valid != NULL), 351 * Check if the system resume is in progress (uci->valid != NULL),
352 * otherwise just request a firmware: 352 * otherwise just request a firmware:
353 */ 353 */
354 if (uci->valid) { 354 if (uci->valid) {
355 err = microcode_resume_cpu(smp_processor_id()); 355 err = microcode_resume_cpu(smp_processor_id());
356 } else { 356 } else {
357 collect_cpu_info(smp_processor_id()); 357 collect_cpu_info(smp_processor_id());
358 if (uci->valid && system_state == SYSTEM_RUNNING) 358 if (uci->valid && system_state == SYSTEM_RUNNING)
359 err = microcode_ops->request_microcode_fw( 359 err = microcode_ops->request_microcode_fw(
360 smp_processor_id(), 360 smp_processor_id(),
361 &microcode_pdev->dev); 361 &microcode_pdev->dev);
362 } 362 }
363 if (!err) 363 if (!err)
364 microcode_ops->apply_microcode(smp_processor_id()); 364 microcode_ops->apply_microcode(smp_processor_id());
365 return err; 365 return err;
366 } 366 }
367 367
368 static int microcode_init_cpu(int cpu) 368 static int microcode_init_cpu(int cpu)
369 { 369 {
370 int err; 370 int err;
371 mutex_lock(&microcode_mutex); 371 mutex_lock(&microcode_mutex);
372 err = work_on_cpu(cpu, microcode_update_cpu, NULL); 372 err = work_on_cpu(cpu, microcode_update_cpu, NULL);
373 mutex_unlock(&microcode_mutex); 373 mutex_unlock(&microcode_mutex);
374 374
375 return err; 375 return err;
376 } 376 }
377 377
378 static int mc_sysdev_add(struct sys_device *sys_dev) 378 static int mc_sysdev_add(struct sys_device *sys_dev)
379 { 379 {
380 int err, cpu = sys_dev->id; 380 int err, cpu = sys_dev->id;
381 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 381 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
382 382
383 if (!cpu_online(cpu)) 383 if (!cpu_online(cpu))
384 return 0; 384 return 0;
385 385
386 pr_debug("microcode: CPU%d added\n", cpu); 386 pr_debug("microcode: CPU%d added\n", cpu);
387 memset(uci, 0, sizeof(*uci)); 387 memset(uci, 0, sizeof(*uci));
388 388
389 err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group); 389 err = sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
390 if (err) 390 if (err)
391 return err; 391 return err;
392 392
393 err = microcode_init_cpu(cpu); 393 err = microcode_init_cpu(cpu);
394 if (err) 394 if (err)
395 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); 395 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
396 396
397 return err; 397 return err;
398 } 398 }
399 399
400 static int mc_sysdev_remove(struct sys_device *sys_dev) 400 static int mc_sysdev_remove(struct sys_device *sys_dev)
401 { 401 {
402 int cpu = sys_dev->id; 402 int cpu = sys_dev->id;
403 403
404 if (!cpu_online(cpu)) 404 if (!cpu_online(cpu))
405 return 0; 405 return 0;
406 406
407 pr_debug("microcode: CPU%d removed\n", cpu); 407 pr_debug("microcode: CPU%d removed\n", cpu);
408 microcode_fini_cpu(cpu); 408 microcode_fini_cpu(cpu);
409 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); 409 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
410 return 0; 410 return 0;
411 } 411 }
412 412
413 static int mc_sysdev_resume(struct sys_device *dev) 413 static int mc_sysdev_resume(struct sys_device *dev)
414 { 414 {
415 int cpu = dev->id; 415 int cpu = dev->id;
416 416
417 if (!cpu_online(cpu)) 417 if (!cpu_online(cpu))
418 return 0; 418 return 0;
419 419
420 /* only CPU 0 will apply ucode here */ 420 /* only CPU 0 will apply ucode here */
421 microcode_update_cpu(NULL); 421 microcode_update_cpu(NULL);
422 return 0; 422 return 0;
423 } 423 }
424 424
425 static struct sysdev_driver mc_sysdev_driver = { 425 static struct sysdev_driver mc_sysdev_driver = {
426 .add = mc_sysdev_add, 426 .add = mc_sysdev_add,
427 .remove = mc_sysdev_remove, 427 .remove = mc_sysdev_remove,
428 .resume = mc_sysdev_resume, 428 .resume = mc_sysdev_resume,
429 }; 429 };
430 430
431 static __cpuinit int 431 static __cpuinit int
432 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) 432 mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
433 { 433 {
434 unsigned int cpu = (unsigned long)hcpu; 434 unsigned int cpu = (unsigned long)hcpu;
435 struct sys_device *sys_dev; 435 struct sys_device *sys_dev;
436 436
437 sys_dev = get_cpu_sysdev(cpu); 437 sys_dev = get_cpu_sysdev(cpu);
438 switch (action) { 438 switch (action) {
439 case CPU_ONLINE: 439 case CPU_ONLINE:
440 case CPU_ONLINE_FROZEN: 440 case CPU_ONLINE_FROZEN:
441 if (microcode_init_cpu(cpu)) 441 if (microcode_init_cpu(cpu))
442 printk(KERN_ERR "microcode: failed to init CPU%d\n", 442 printk(KERN_ERR "microcode: failed to init CPU%d\n",
443 cpu); 443 cpu);
444 case CPU_DOWN_FAILED: 444 case CPU_DOWN_FAILED:
445 case CPU_DOWN_FAILED_FROZEN: 445 case CPU_DOWN_FAILED_FROZEN:
446 pr_debug("microcode: CPU%d added\n", cpu); 446 pr_debug("microcode: CPU%d added\n", cpu);
447 if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group)) 447 if (sysfs_create_group(&sys_dev->kobj, &mc_attr_group))
448 printk(KERN_ERR "microcode: Failed to create the sysfs " 448 printk(KERN_ERR "microcode: Failed to create the sysfs "
449 "group for CPU%d\n", cpu); 449 "group for CPU%d\n", cpu);
450 break; 450 break;
451 case CPU_DOWN_PREPARE: 451 case CPU_DOWN_PREPARE:
452 case CPU_DOWN_PREPARE_FROZEN: 452 case CPU_DOWN_PREPARE_FROZEN:
453 /* Suspend is in progress, only remove the interface */ 453 /* Suspend is in progress, only remove the interface */
454 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); 454 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
455 pr_debug("microcode: CPU%d removed\n", cpu); 455 pr_debug("microcode: CPU%d removed\n", cpu);
456 break; 456 break;
457 case CPU_DEAD: 457 case CPU_DEAD:
458 case CPU_UP_CANCELED_FROZEN: 458 case CPU_UP_CANCELED_FROZEN:
459 /* The CPU refused to come up during a system resume */ 459 /* The CPU refused to come up during a system resume */
460 microcode_fini_cpu(cpu); 460 microcode_fini_cpu(cpu);
461 break; 461 break;
462 } 462 }
463 return NOTIFY_OK; 463 return NOTIFY_OK;
464 } 464 }
465 465
466 static struct notifier_block __refdata mc_cpu_notifier = { 466 static struct notifier_block __refdata mc_cpu_notifier = {
467 .notifier_call = mc_cpu_callback, 467 .notifier_call = mc_cpu_callback,
468 }; 468 };
469 469
470 static int __init microcode_init(void) 470 static int __init microcode_init(void)
471 { 471 {
472 struct cpuinfo_x86 *c = &cpu_data(0); 472 struct cpuinfo_x86 *c = &cpu_data(0);
473 int error; 473 int error;
474 474
475 if (c->x86_vendor == X86_VENDOR_INTEL) 475 if (c->x86_vendor == X86_VENDOR_INTEL)
476 microcode_ops = init_intel_microcode(); 476 microcode_ops = init_intel_microcode();
477 else if (c->x86_vendor == X86_VENDOR_AMD) 477 else if (c->x86_vendor == X86_VENDOR_AMD)
478 microcode_ops = init_amd_microcode(); 478 microcode_ops = init_amd_microcode();
479 479
480 if (!microcode_ops) { 480 if (!microcode_ops) {
481 printk(KERN_ERR "microcode: no support for this CPU vendor\n"); 481 printk(KERN_ERR "microcode: no support for this CPU vendor\n");
482 return -ENODEV; 482 return -ENODEV;
483 } 483 }
484 484
485 error = microcode_dev_init(); 485 error = microcode_dev_init();
486 if (error) 486 if (error)
487 return error; 487 return error;
488 microcode_pdev = platform_device_register_simple("microcode", -1, 488 microcode_pdev = platform_device_register_simple("microcode", -1,
489 NULL, 0); 489 NULL, 0);
490 if (IS_ERR(microcode_pdev)) { 490 if (IS_ERR(microcode_pdev)) {
491 microcode_dev_exit(); 491 microcode_dev_exit();
492 return PTR_ERR(microcode_pdev); 492 return PTR_ERR(microcode_pdev);
493 } 493 }
494 494
495 get_online_cpus(); 495 get_online_cpus();
496 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver); 496 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
497 put_online_cpus(); 497 put_online_cpus();
498 if (error) { 498 if (error) {
499 microcode_dev_exit(); 499 microcode_dev_exit();
500 platform_device_unregister(microcode_pdev); 500 platform_device_unregister(microcode_pdev);
501 return error; 501 return error;
502 } 502 }
503 503
504 register_hotcpu_notifier(&mc_cpu_notifier); 504 register_hotcpu_notifier(&mc_cpu_notifier);
505 505
506 printk(KERN_INFO 506 printk(KERN_INFO
507 "Microcode Update Driver: v" MICROCODE_VERSION 507 "Microcode Update Driver: v" MICROCODE_VERSION
508 " <tigran@aivazian.fsnet.co.uk>," 508 " <tigran@aivazian.fsnet.co.uk>,"
509 " Peter Oruba\n"); 509 " Peter Oruba\n");
510 510
511 return 0; 511 return 0;
512 } 512 }
513 513
514 static void __exit microcode_exit(void) 514 static void __exit microcode_exit(void)
515 { 515 {
516 microcode_dev_exit(); 516 microcode_dev_exit();
517 517
518 unregister_hotcpu_notifier(&mc_cpu_notifier); 518 unregister_hotcpu_notifier(&mc_cpu_notifier);
519 519
520 get_online_cpus(); 520 get_online_cpus();
521 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver); 521 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
522 put_online_cpus(); 522 put_online_cpus();
523 523
524 platform_device_unregister(microcode_pdev); 524 platform_device_unregister(microcode_pdev);
525 525
526 microcode_ops = NULL; 526 microcode_ops = NULL;
527 527
arch/x86/kernel/microcode_intel.c
1 /* 1 /*
2 * Intel CPU Microcode Update Driver for Linux 2 * Intel CPU Microcode Update Driver for Linux
3 * 3 *
4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk> 4 * Copyright (C) 2000-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5 * 2006 Shaohua Li <shaohua.li@intel.com> 5 * 2006 Shaohua Li <shaohua.li@intel.com>
6 * 6 *
7 * This driver allows to upgrade microcode on Intel processors 7 * This driver allows to upgrade microcode on Intel processors
8 * belonging to IA-32 family - PentiumPro, Pentium II, 8 * belonging to IA-32 family - PentiumPro, Pentium II,
9 * Pentium III, Xeon, Pentium 4, etc. 9 * Pentium III, Xeon, Pentium 4, etc.
10 * 10 *
11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture 11 * Reference: Section 8.11 of Volume 3a, IA-32 Intel? Architecture
12 * Software Developer's Manual 12 * Software Developer's Manual
13 * Order Number 253668 or free download from: 13 * Order Number 253668 or free download from:
14 * 14 *
15 * http://developer.intel.com/design/pentium4/manuals/253668.htm 15 * http://developer.intel.com/design/pentium4/manuals/253668.htm
16 * 16 *
17 * For more information, go to http://www.urbanmyth.org/microcode 17 * For more information, go to http://www.urbanmyth.org/microcode
18 * 18 *
19 * This program is free software; you can redistribute it and/or 19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License 20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 21 * as published by the Free Software Foundation; either version
22 * 2 of the License, or (at your option) any later version. 22 * 2 of the License, or (at your option) any later version.
23 * 23 *
24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com> 24 * 1.0 16 Feb 2000, Tigran Aivazian <tigran@sco.com>
25 * Initial release. 25 * Initial release.
26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com> 26 * 1.01 18 Feb 2000, Tigran Aivazian <tigran@sco.com>
27 * Added read() support + cleanups. 27 * Added read() support + cleanups.
28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com> 28 * 1.02 21 Feb 2000, Tigran Aivazian <tigran@sco.com>
29 * Added 'device trimming' support. open(O_WRONLY) zeroes 29 * Added 'device trimming' support. open(O_WRONLY) zeroes
30 * and frees the saved copy of applied microcode. 30 * and frees the saved copy of applied microcode.
31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com> 31 * 1.03 29 Feb 2000, Tigran Aivazian <tigran@sco.com>
32 * Made to use devfs (/dev/cpu/microcode) + cleanups. 32 * Made to use devfs (/dev/cpu/microcode) + cleanups.
33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com> 33 * 1.04 06 Jun 2000, Simon Trimmer <simon@veritas.com>
34 * Added misc device support (now uses both devfs and misc). 34 * Added misc device support (now uses both devfs and misc).
35 * Added MICROCODE_IOCFREE ioctl to clear memory. 35 * Added MICROCODE_IOCFREE ioctl to clear memory.
36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com> 36 * 1.05 09 Jun 2000, Simon Trimmer <simon@veritas.com>
37 * Messages for error cases (non Intel & no suitable microcode). 37 * Messages for error cases (non Intel & no suitable microcode).
38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com> 38 * 1.06 03 Aug 2000, Tigran Aivazian <tigran@veritas.com>
39 * Removed ->release(). Removed exclusive open and status bitmap. 39 * Removed ->release(). Removed exclusive open and status bitmap.
40 * Added microcode_rwsem to serialize read()/write()/ioctl(). 40 * Added microcode_rwsem to serialize read()/write()/ioctl().
41 * Removed global kernel lock usage. 41 * Removed global kernel lock usage.
42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com> 42 * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>
43 * Write 0 to 0x8B msr and then cpuid before reading revision, 43 * Write 0 to 0x8B msr and then cpuid before reading revision,
44 * so that it works even if there were no update done by the 44 * so that it works even if there were no update done by the
45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened 45 * BIOS. Otherwise, reading from 0x8B gives junk (which happened
46 * to be 0 on my machine which is why it worked even when I 46 * to be 0 on my machine which is why it worked even when I
47 * disabled update by the BIOS) 47 * disabled update by the BIOS)
48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix. 48 * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.
49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and 49 * 1.08 11 Dec 2000, Richard Schaal <richard.schaal@intel.com> and
50 * Tigran Aivazian <tigran@veritas.com> 50 * Tigran Aivazian <tigran@veritas.com>
51 * Intel Pentium 4 processor support and bugfixes. 51 * Intel Pentium 4 processor support and bugfixes.
52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com> 52 * 1.09 30 Oct 2001, Tigran Aivazian <tigran@veritas.com>
53 * Bugfix for HT (Hyper-Threading) enabled processors 53 * Bugfix for HT (Hyper-Threading) enabled processors
54 * whereby processor resources are shared by all logical processors 54 * whereby processor resources are shared by all logical processors
55 * in a single CPU package. 55 * in a single CPU package.
56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and 56 * 1.10 28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
57 * Tigran Aivazian <tigran@veritas.com>, 57 * Tigran Aivazian <tigran@veritas.com>,
58 * Serialize updates as required on HT processors due to 58 * Serialize updates as required on HT processors due to
59 * speculative nature of implementation. 59 * speculative nature of implementation.
60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com> 60 * 1.11 22 Mar 2002 Tigran Aivazian <tigran@veritas.com>
61 * Fix the panic when writing zero-length microcode chunk. 61 * Fix the panic when writing zero-length microcode chunk.
62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>, 62 * 1.12 29 Sep 2003 Nitin Kamble <nitin.a.kamble@intel.com>,
63 * Jun Nakajima <jun.nakajima@intel.com> 63 * Jun Nakajima <jun.nakajima@intel.com>
64 * Support for the microcode updates in the new format. 64 * Support for the microcode updates in the new format.
65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com> 65 * 1.13 10 Oct 2003 Tigran Aivazian <tigran@veritas.com>
66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl 66 * Removed ->read() method and obsoleted MICROCODE_IOCFREE ioctl
67 * because we no longer hold a copy of applied microcode 67 * because we no longer hold a copy of applied microcode
68 * in kernel memory. 68 * in kernel memory.
69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com> 69 * 1.14 25 Jun 2004 Tigran Aivazian <tigran@veritas.com>
70 * Fix sigmatch() macro to handle old CPUs with pf == 0. 70 * Fix sigmatch() macro to handle old CPUs with pf == 0.
71 * Thanks to Stuart Swales for pointing out this bug. 71 * Thanks to Stuart Swales for pointing out this bug.
72 */ 72 */
73 #include <linux/platform_device.h>
73 #include <linux/capability.h> 74 #include <linux/capability.h>
74 #include <linux/kernel.h> 75 #include <linux/miscdevice.h>
75 #include <linux/init.h> 76 #include <linux/firmware.h>
76 #include <linux/sched.h>
77 #include <linux/smp_lock.h> 77 #include <linux/smp_lock.h>
78 #include <linux/spinlock.h>
78 #include <linux/cpumask.h> 79 #include <linux/cpumask.h>
79 #include <linux/module.h> 80 #include <linux/uaccess.h>
80 #include <linux/slab.h>
81 #include <linux/vmalloc.h> 81 #include <linux/vmalloc.h>
82 #include <linux/miscdevice.h> 82 #include <linux/kernel.h>
83 #include <linux/spinlock.h> 83 #include <linux/module.h>
84 #include <linux/mm.h>
85 #include <linux/fs.h>
86 #include <linux/mutex.h> 84 #include <linux/mutex.h>
85 #include <linux/sched.h>
86 #include <linux/init.h>
87 #include <linux/slab.h>
87 #include <linux/cpu.h> 88 #include <linux/cpu.h>
88 #include <linux/firmware.h> 89 #include <linux/fs.h>
89 #include <linux/platform_device.h> 90 #include <linux/mm.h>
90 #include <linux/uaccess.h>
91 91
92 #include <asm/msr.h>
93 #include <asm/processor.h>
94 #include <asm/microcode.h> 92 #include <asm/microcode.h>
93 #include <asm/processor.h>
94 #include <asm/msr.h>
95 95
96 MODULE_DESCRIPTION("Microcode Update Driver"); 96 MODULE_DESCRIPTION("Microcode Update Driver");
97 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>"); 97 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
98 MODULE_LICENSE("GPL"); 98 MODULE_LICENSE("GPL");
99 99
100 struct microcode_header_intel { 100 struct microcode_header_intel {
101 unsigned int hdrver; 101 unsigned int hdrver;
102 unsigned int rev; 102 unsigned int rev;
103 unsigned int date; 103 unsigned int date;
104 unsigned int sig; 104 unsigned int sig;
105 unsigned int cksum; 105 unsigned int cksum;
106 unsigned int ldrver; 106 unsigned int ldrver;
107 unsigned int pf; 107 unsigned int pf;
108 unsigned int datasize; 108 unsigned int datasize;
109 unsigned int totalsize; 109 unsigned int totalsize;
110 unsigned int reserved[3]; 110 unsigned int reserved[3];
111 }; 111 };
112 112
113 struct microcode_intel { 113 struct microcode_intel {
114 struct microcode_header_intel hdr; 114 struct microcode_header_intel hdr;
115 unsigned int bits[0]; 115 unsigned int bits[0];
116 }; 116 };
117 117
118 /* microcode format is extended from prescott processors */ 118 /* microcode format is extended from prescott processors */
119 struct extended_signature { 119 struct extended_signature {
120 unsigned int sig; 120 unsigned int sig;
121 unsigned int pf; 121 unsigned int pf;
122 unsigned int cksum; 122 unsigned int cksum;
123 }; 123 };
124 124
125 struct extended_sigtable { 125 struct extended_sigtable {
126 unsigned int count; 126 unsigned int count;
127 unsigned int cksum; 127 unsigned int cksum;
128 unsigned int reserved[3]; 128 unsigned int reserved[3];
129 struct extended_signature sigs[0]; 129 struct extended_signature sigs[0];
130 }; 130 };
131 131
132 #define DEFAULT_UCODE_DATASIZE (2000) 132 #define DEFAULT_UCODE_DATASIZE (2000)
133 #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) 133 #define MC_HEADER_SIZE (sizeof(struct microcode_header_intel))
134 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) 134 #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE)
135 #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable)) 135 #define EXT_HEADER_SIZE (sizeof(struct extended_sigtable))
136 #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature)) 136 #define EXT_SIGNATURE_SIZE (sizeof(struct extended_signature))
137 #define DWSIZE (sizeof(u32)) 137 #define DWSIZE (sizeof(u32))
138
138 #define get_totalsize(mc) \ 139 #define get_totalsize(mc) \
139 (((struct microcode_intel *)mc)->hdr.totalsize ? \ 140 (((struct microcode_intel *)mc)->hdr.totalsize ? \
140 ((struct microcode_intel *)mc)->hdr.totalsize : \ 141 ((struct microcode_intel *)mc)->hdr.totalsize : \
141 DEFAULT_UCODE_TOTALSIZE) 142 DEFAULT_UCODE_TOTALSIZE)
142 143
143 #define get_datasize(mc) \ 144 #define get_datasize(mc) \
144 (((struct microcode_intel *)mc)->hdr.datasize ? \ 145 (((struct microcode_intel *)mc)->hdr.datasize ? \
145 ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE) 146 ((struct microcode_intel *)mc)->hdr.datasize : DEFAULT_UCODE_DATASIZE)
146 147
147 #define sigmatch(s1, s2, p1, p2) \ 148 #define sigmatch(s1, s2, p1, p2) \
148 (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0)))) 149 (((s1) == (s2)) && (((p1) & (p2)) || (((p1) == 0) && ((p2) == 0))))
149 150
150 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE) 151 #define exttable_size(et) ((et)->count * EXT_SIGNATURE_SIZE + EXT_HEADER_SIZE)
151 152
152 /* serialize access to the physical write to MSR 0x79 */ 153 /* serialize access to the physical write to MSR 0x79 */
153 static DEFINE_SPINLOCK(microcode_update_lock); 154 static DEFINE_SPINLOCK(microcode_update_lock);
154 155
155 static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) 156 static int collect_cpu_info(int cpu_num, struct cpu_signature *csig)
156 { 157 {
157 struct cpuinfo_x86 *c = &cpu_data(cpu_num); 158 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
158 unsigned long flags; 159 unsigned long flags;
159 unsigned int val[2]; 160 unsigned int val[2];
160 161
161 memset(csig, 0, sizeof(*csig)); 162 memset(csig, 0, sizeof(*csig));
162 163
163 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 164 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
164 cpu_has(c, X86_FEATURE_IA64)) { 165 cpu_has(c, X86_FEATURE_IA64)) {
165 printk(KERN_ERR "microcode: CPU%d not a capable Intel " 166 printk(KERN_ERR "microcode: CPU%d not a capable Intel "
166 "processor\n", cpu_num); 167 "processor\n", cpu_num);
167 return -1; 168 return -1;
168 } 169 }
169 170
170 csig->sig = cpuid_eax(0x00000001); 171 csig->sig = cpuid_eax(0x00000001);
171 172
172 if ((c->x86_model >= 5) || (c->x86 > 6)) { 173 if ((c->x86_model >= 5) || (c->x86 > 6)) {
173 /* get processor flags from MSR 0x17 */ 174 /* get processor flags from MSR 0x17 */
174 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 175 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
175 csig->pf = 1 << ((val[1] >> 18) & 7); 176 csig->pf = 1 << ((val[1] >> 18) & 7);
176 } 177 }
177 178
178 /* serialize access to the physical write to MSR 0x79 */ 179 /* serialize access to the physical write to MSR 0x79 */
179 spin_lock_irqsave(&microcode_update_lock, flags); 180 spin_lock_irqsave(&microcode_update_lock, flags);
180 181
181 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 182 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
182 /* see notes above for revision 1.07. Apparent chip bug */ 183 /* see notes above for revision 1.07. Apparent chip bug */
183 sync_core(); 184 sync_core();
184 /* get the current revision from MSR 0x8B */ 185 /* get the current revision from MSR 0x8B */
185 rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev); 186 rdmsr(MSR_IA32_UCODE_REV, val[0], csig->rev);
186 spin_unlock_irqrestore(&microcode_update_lock, flags); 187 spin_unlock_irqrestore(&microcode_update_lock, flags);
187 188
188 pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n", 189 pr_debug("microcode: collect_cpu_info : sig=0x%x, pf=0x%x, rev=0x%x\n",
189 csig->sig, csig->pf, csig->rev); 190 csig->sig, csig->pf, csig->rev);
190 191
191 return 0; 192 return 0;
192 } 193 }
193 194
194 static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf) 195 static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)
195 { 196 {
196 return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1; 197 return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1;
197 } 198 }
198 199
199 static inline int 200 static inline int
200 update_match_revision(struct microcode_header_intel *mc_header, int rev) 201 update_match_revision(struct microcode_header_intel *mc_header, int rev)
201 { 202 {
202 return (mc_header->rev <= rev) ? 0 : 1; 203 return (mc_header->rev <= rev) ? 0 : 1;
203 } 204 }
204 205
205 static int microcode_sanity_check(void *mc) 206 static int microcode_sanity_check(void *mc)
206 { 207 {
208 unsigned long total_size, data_size, ext_table_size;
207 struct microcode_header_intel *mc_header = mc; 209 struct microcode_header_intel *mc_header = mc;
208 struct extended_sigtable *ext_header = NULL; 210 struct extended_sigtable *ext_header = NULL;
209 struct extended_signature *ext_sig;
210 unsigned long total_size, data_size, ext_table_size;
211 int sum, orig_sum, ext_sigcount = 0, i; 211 int sum, orig_sum, ext_sigcount = 0, i;
212 struct extended_signature *ext_sig;
212 213
213 total_size = get_totalsize(mc_header); 214 total_size = get_totalsize(mc_header);
214 data_size = get_datasize(mc_header); 215 data_size = get_datasize(mc_header);
216
215 if (data_size + MC_HEADER_SIZE > total_size) { 217 if (data_size + MC_HEADER_SIZE > total_size) {
216 printk(KERN_ERR "microcode: error! " 218 printk(KERN_ERR "microcode: error! "
217 "Bad data size in microcode data file\n"); 219 "Bad data size in microcode data file\n");
218 return -EINVAL; 220 return -EINVAL;
219 } 221 }
220 222
221 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { 223 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
222 printk(KERN_ERR "microcode: error! " 224 printk(KERN_ERR "microcode: error! "
223 "Unknown microcode update format\n"); 225 "Unknown microcode update format\n");
224 return -EINVAL; 226 return -EINVAL;
225 } 227 }
226 ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 228 ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
227 if (ext_table_size) { 229 if (ext_table_size) {
228 if ((ext_table_size < EXT_HEADER_SIZE) 230 if ((ext_table_size < EXT_HEADER_SIZE)
229 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 231 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
230 printk(KERN_ERR "microcode: error! " 232 printk(KERN_ERR "microcode: error! "
231 "Small exttable size in microcode data file\n"); 233 "Small exttable size in microcode data file\n");
232 return -EINVAL; 234 return -EINVAL;
233 } 235 }
234 ext_header = mc + MC_HEADER_SIZE + data_size; 236 ext_header = mc + MC_HEADER_SIZE + data_size;
235 if (ext_table_size != exttable_size(ext_header)) { 237 if (ext_table_size != exttable_size(ext_header)) {
236 printk(KERN_ERR "microcode: error! " 238 printk(KERN_ERR "microcode: error! "
237 "Bad exttable size in microcode data file\n"); 239 "Bad exttable size in microcode data file\n");
238 return -EFAULT; 240 return -EFAULT;
239 } 241 }
240 ext_sigcount = ext_header->count; 242 ext_sigcount = ext_header->count;
241 } 243 }
242 244
243 /* check extended table checksum */ 245 /* check extended table checksum */
244 if (ext_table_size) { 246 if (ext_table_size) {
245 int ext_table_sum = 0; 247 int ext_table_sum = 0;
246 int *ext_tablep = (int *)ext_header; 248 int *ext_tablep = (int *)ext_header;
247 249
248 i = ext_table_size / DWSIZE; 250 i = ext_table_size / DWSIZE;
249 while (i--) 251 while (i--)
250 ext_table_sum += ext_tablep[i]; 252 ext_table_sum += ext_tablep[i];
251 if (ext_table_sum) { 253 if (ext_table_sum) {
252 printk(KERN_WARNING "microcode: aborting, " 254 printk(KERN_WARNING "microcode: aborting, "
253 "bad extended signature table checksum\n"); 255 "bad extended signature table checksum\n");
254 return -EINVAL; 256 return -EINVAL;
255 } 257 }
256 } 258 }
257 259
258 /* calculate the checksum */ 260 /* calculate the checksum */
259 orig_sum = 0; 261 orig_sum = 0;
260 i = (MC_HEADER_SIZE + data_size) / DWSIZE; 262 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
261 while (i--) 263 while (i--)
262 orig_sum += ((int *)mc)[i]; 264 orig_sum += ((int *)mc)[i];
263 if (orig_sum) { 265 if (orig_sum) {
264 printk(KERN_ERR "microcode: aborting, bad checksum\n"); 266 printk(KERN_ERR "microcode: aborting, bad checksum\n");
265 return -EINVAL; 267 return -EINVAL;
266 } 268 }
267 if (!ext_table_size) 269 if (!ext_table_size)
268 return 0; 270 return 0;
269 /* check extended signature checksum */ 271 /* check extended signature checksum */
270 for (i = 0; i < ext_sigcount; i++) { 272 for (i = 0; i < ext_sigcount; i++) {
271 ext_sig = (void *)ext_header + EXT_HEADER_SIZE + 273 ext_sig = (void *)ext_header + EXT_HEADER_SIZE +
272 EXT_SIGNATURE_SIZE * i; 274 EXT_SIGNATURE_SIZE * i;
273 sum = orig_sum 275 sum = orig_sum
274 - (mc_header->sig + mc_header->pf + mc_header->cksum) 276 - (mc_header->sig + mc_header->pf + mc_header->cksum)
275 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); 277 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
276 if (sum) { 278 if (sum) {
277 printk(KERN_ERR "microcode: aborting, bad checksum\n"); 279 printk(KERN_ERR "microcode: aborting, bad checksum\n");
278 return -EINVAL; 280 return -EINVAL;
279 } 281 }
280 } 282 }
281 return 0; 283 return 0;
282 } 284 }
283 285
284 /* 286 /*
285 * return 0 - no update found 287 * return 0 - no update found
286 * return 1 - found update 288 * return 1 - found update
287 */ 289 */
288 static int 290 static int
289 get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev) 291 get_matching_microcode(struct cpu_signature *cpu_sig, void *mc, int rev)
290 { 292 {
291 struct microcode_header_intel *mc_header = mc; 293 struct microcode_header_intel *mc_header = mc;
292 struct extended_sigtable *ext_header; 294 struct extended_sigtable *ext_header;
293 unsigned long total_size = get_totalsize(mc_header); 295 unsigned long total_size = get_totalsize(mc_header);
294 int ext_sigcount, i; 296 int ext_sigcount, i;
295 struct extended_signature *ext_sig; 297 struct extended_signature *ext_sig;
296 298
297 if (!update_match_revision(mc_header, rev)) 299 if (!update_match_revision(mc_header, rev))
298 return 0; 300 return 0;
299 301
300 if (update_match_cpu(cpu_sig, mc_header->sig, mc_header->pf)) 302 if (update_match_cpu(cpu_sig, mc_header->sig, mc_header->pf))
301 return 1; 303 return 1;
302 304
303 /* Look for ext. headers: */ 305 /* Look for ext. headers: */
304 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) 306 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
305 return 0; 307 return 0;
306 308
307 ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE; 309 ext_header = mc + get_datasize(mc_header) + MC_HEADER_SIZE;
308 ext_sigcount = ext_header->count; 310 ext_sigcount = ext_header->count;
309 ext_sig = (void *)ext_header + EXT_HEADER_SIZE; 311 ext_sig = (void *)ext_header + EXT_HEADER_SIZE;
310 312
311 for (i = 0; i < ext_sigcount; i++) { 313 for (i = 0; i < ext_sigcount; i++) {
312 if (update_match_cpu(cpu_sig, ext_sig->sig, ext_sig->pf)) 314 if (update_match_cpu(cpu_sig, ext_sig->sig, ext_sig->pf))
313 return 1; 315 return 1;
314 ext_sig++; 316 ext_sig++;
315 } 317 }
316 return 0; 318 return 0;
317 } 319 }
318 320
319 static void apply_microcode(int cpu) 321 static void apply_microcode(int cpu)
320 { 322 {
323 struct microcode_intel *mc_intel;
324 struct ucode_cpu_info *uci;
321 unsigned long flags; 325 unsigned long flags;
322 unsigned int val[2]; 326 unsigned int val[2];
323 int cpu_num = raw_smp_processor_id(); 327 int cpu_num;
324 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
325 struct microcode_intel *mc_intel = uci->mc;
326 328
329 cpu_num = raw_smp_processor_id();
330 uci = ucode_cpu_info + cpu;
331 mc_intel = uci->mc;
332
327 /* We should bind the task to the CPU */ 333 /* We should bind the task to the CPU */
328 BUG_ON(cpu_num != cpu); 334 BUG_ON(cpu_num != cpu);
329 335
330 if (mc_intel == NULL) 336 if (mc_intel == NULL)
331 return; 337 return;
332 338
333 /* serialize access to the physical write to MSR 0x79 */ 339 /* serialize access to the physical write to MSR 0x79 */
334 spin_lock_irqsave(&microcode_update_lock, flags); 340 spin_lock_irqsave(&microcode_update_lock, flags);
335 341
336 /* write microcode via MSR 0x79 */ 342 /* write microcode via MSR 0x79 */
337 wrmsr(MSR_IA32_UCODE_WRITE, 343 wrmsr(MSR_IA32_UCODE_WRITE,
338 (unsigned long) mc_intel->bits, 344 (unsigned long) mc_intel->bits,
339 (unsigned long) mc_intel->bits >> 16 >> 16); 345 (unsigned long) mc_intel->bits >> 16 >> 16);
340 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 346 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
341 347
342 /* see notes above for revision 1.07. Apparent chip bug */ 348 /* see notes above for revision 1.07. Apparent chip bug */
343 sync_core(); 349 sync_core();
344 350
345 /* get the current revision from MSR 0x8B */ 351 /* get the current revision from MSR 0x8B */
346 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 352 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
347 353
348 spin_unlock_irqrestore(&microcode_update_lock, flags); 354 spin_unlock_irqrestore(&microcode_update_lock, flags);
349 if (val[1] != mc_intel->hdr.rev) { 355 if (val[1] != mc_intel->hdr.rev) {
350 printk(KERN_ERR "microcode: CPU%d update from revision " 356 printk(KERN_ERR "microcode: CPU%d update from revision "
351 "0x%x to 0x%x failed\n", cpu_num, uci->cpu_sig.rev, val[1]); 357 "0x%x to 0x%x failed\n",
358 cpu_num, uci->cpu_sig.rev, val[1]);
352 return; 359 return;
353 } 360 }
354 printk(KERN_INFO "microcode: CPU%d updated from revision " 361 printk(KERN_INFO "microcode: CPU%d updated from revision "
355 "0x%x to 0x%x, date = %04x-%02x-%02x \n", 362 "0x%x to 0x%x, date = %04x-%02x-%02x \n",
356 cpu_num, uci->cpu_sig.rev, val[1], 363 cpu_num, uci->cpu_sig.rev, val[1],
357 mc_intel->hdr.date & 0xffff, 364 mc_intel->hdr.date & 0xffff,
358 mc_intel->hdr.date >> 24, 365 mc_intel->hdr.date >> 24,
359 (mc_intel->hdr.date >> 16) & 0xff); 366 (mc_intel->hdr.date >> 16) & 0xff);
367
360 uci->cpu_sig.rev = val[1]; 368 uci->cpu_sig.rev = val[1];
361 } 369 }
362 370
363 static int generic_load_microcode(int cpu, void *data, size_t size, 371 static int generic_load_microcode(int cpu, void *data, size_t size,
364 int (*get_ucode_data)(void *, const void *, size_t)) 372 int (*get_ucode_data)(void *, const void *, size_t))
365 { 373 {
366 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 374 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
367 u8 *ucode_ptr = data, *new_mc = NULL, *mc; 375 u8 *ucode_ptr = data, *new_mc = NULL, *mc;
368 int new_rev = uci->cpu_sig.rev; 376 int new_rev = uci->cpu_sig.rev;
369 unsigned int leftover = size; 377 unsigned int leftover = size;
370 378
371 while (leftover) { 379 while (leftover) {
372 struct microcode_header_intel mc_header; 380 struct microcode_header_intel mc_header;
373 unsigned int mc_size; 381 unsigned int mc_size;
374 382
375 if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header))) 383 if (get_ucode_data(&mc_header, ucode_ptr, sizeof(mc_header)))
376 break; 384 break;
377 385
378 mc_size = get_totalsize(&mc_header); 386 mc_size = get_totalsize(&mc_header);
379 if (!mc_size || mc_size > leftover) { 387 if (!mc_size || mc_size > leftover) {
380 printk(KERN_ERR "microcode: error!" 388 printk(KERN_ERR "microcode: error!"
381 "Bad data in microcode data file\n"); 389 "Bad data in microcode data file\n");
382 break; 390 break;
383 } 391 }
384 392
385 mc = vmalloc(mc_size); 393 mc = vmalloc(mc_size);
386 if (!mc) 394 if (!mc)
387 break; 395 break;
388 396
389 if (get_ucode_data(mc, ucode_ptr, mc_size) || 397 if (get_ucode_data(mc, ucode_ptr, mc_size) ||
390 microcode_sanity_check(mc) < 0) { 398 microcode_sanity_check(mc) < 0) {
391 vfree(mc); 399 vfree(mc);
392 break; 400 break;
393 } 401 }
394 402
395 if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) { 403 if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
396 if (new_mc) 404 if (new_mc)
397 vfree(new_mc); 405 vfree(new_mc);
398 new_rev = mc_header.rev; 406 new_rev = mc_header.rev;
399 new_mc = mc; 407 new_mc = mc;
400 } else 408 } else
401 vfree(mc); 409 vfree(mc);
402 410
403 ucode_ptr += mc_size; 411 ucode_ptr += mc_size;
404 leftover -= mc_size; 412 leftover -= mc_size;
405 } 413 }
406 414
407 if (new_mc) { 415 if (!new_mc)
408 if (!leftover) { 416 goto out;
409 if (uci->mc) 417
410 vfree(uci->mc); 418 if (leftover) {
411 uci->mc = (struct microcode_intel *)new_mc; 419 vfree(new_mc);
412 pr_debug("microcode: CPU%d found a matching microcode update with" 420 goto out;
413 " version 0x%x (current=0x%x)\n",
414 cpu, new_rev, uci->cpu_sig.rev);
415 } else
416 vfree(new_mc);
417 } 421 }
418 422
423 if (uci->mc)
424 vfree(uci->mc);
425 uci->mc = (struct microcode_intel *)new_mc;
426
427 pr_debug("microcode: CPU%d found a matching microcode update with"
428 " version 0x%x (current=0x%x)\n",
429 cpu, new_rev, uci->cpu_sig.rev);
430
431 out:
419 return (int)leftover; 432 return (int)leftover;
420 } 433 }
421 434
422 static int get_ucode_fw(void *to, const void *from, size_t n) 435 static int get_ucode_fw(void *to, const void *from, size_t n)
423 { 436 {
424 memcpy(to, from, n); 437 memcpy(to, from, n);
425 return 0; 438 return 0;
426 } 439 }
427 440
428 static int request_microcode_fw(int cpu, struct device *device) 441 static int request_microcode_fw(int cpu, struct device *device)
429 { 442 {
430 char name[30]; 443 char name[30];
431 struct cpuinfo_x86 *c = &cpu_data(cpu); 444 struct cpuinfo_x86 *c = &cpu_data(cpu);
432 const struct firmware *firmware; 445 const struct firmware *firmware;
433 int ret; 446 int ret;
434 447
435 /* We should bind the task to the CPU */ 448 /* We should bind the task to the CPU */
436 BUG_ON(cpu != raw_smp_processor_id()); 449 BUG_ON(cpu != raw_smp_processor_id());
437 sprintf(name, "intel-ucode/%02x-%02x-%02x", 450 sprintf(name, "intel-ucode/%02x-%02x-%02x",
438 c->x86, c->x86_model, c->x86_mask); 451 c->x86, c->x86_model, c->x86_mask);
439 ret = request_firmware(&firmware, name, device); 452 ret = request_firmware(&firmware, name, device);
440 if (ret) { 453 if (ret) {
441 pr_debug("microcode: data file %s load failed\n", name); 454 pr_debug("microcode: data file %s load failed\n", name);
442 return ret; 455 return ret;
443 } 456 }
444 457
445 ret = generic_load_microcode(cpu, (void *)firmware->data, 458 ret = generic_load_microcode(cpu, (void *)firmware->data,
446 firmware->size, &get_ucode_fw); 459 firmware->size, &get_ucode_fw);
447 460
448 release_firmware(firmware); 461 release_firmware(firmware);
449 462
450 return ret; 463 return ret;
451 } 464 }
452 465
453 static int get_ucode_user(void *to, const void *from, size_t n) 466 static int get_ucode_user(void *to, const void *from, size_t n)
454 { 467 {
455 return copy_from_user(to, from, n); 468 return copy_from_user(to, from, n);
456 } 469 }
457 470
458 static int request_microcode_user(int cpu, const void __user *buf, size_t size) 471 static int request_microcode_user(int cpu, const void __user *buf, size_t size)
459 { 472 {
460 /* We should bind the task to the CPU */ 473 /* We should bind the task to the CPU */
461 BUG_ON(cpu != raw_smp_processor_id()); 474 BUG_ON(cpu != raw_smp_processor_id());
462 475
463 return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user); 476 return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
464 } 477 }
465 478
466 static void microcode_fini_cpu(int cpu) 479 static void microcode_fini_cpu(int cpu)
467 { 480 {
468 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 481 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
469 482
470 vfree(uci->mc); 483 vfree(uci->mc);
471 uci->mc = NULL; 484 uci->mc = NULL;
472 } 485 }