aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/microcode_intel.c
diff options
context:
space:
mode:
authorPeter Oruba <peter.oruba@amd.com>2008-07-28 12:44:21 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-28 13:57:57 -0400
commit8d86f390d9bb5b39f0a315838d1616de6363e1b9 (patch)
treef3857d76d029b87571ac5cb4e3c1bd9965c859f8 /arch/x86/kernel/microcode_intel.c
parent26bf7a48c33906cc3415a4492aa9ead7a75f1353 (diff)
x86: major refactoring
Refactored code by introducing a two-module solution. There is one general module in which vendor specific modules can hook into. However, that is exclusive, there is only one vendor specific module allowed at a time. A CPU vendor check makes sure only the correct module for the underlying system gets called. Functinally in terms of patch loading itself there are no changes. This refactoring provides a basis for future implementations of other vendors' patch loaders. Signed-off-by: Peter Oruba <peter.oruba@amd.com> Cc: Tigran Aivazian <tigran@aivazian.fsnet.co.uk> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/microcode_intel.c')
-rw-r--r--arch/x86/kernel/microcode_intel.c50
1 files changed, 40 insertions, 10 deletions
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index ca9861bf067e..831db5363dba 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -127,7 +127,7 @@ extern struct mutex microcode_mutex;
127 127
128extern struct ucode_cpu_info ucode_cpu_info[NR_CPUS]; 128extern struct ucode_cpu_info ucode_cpu_info[NR_CPUS];
129 129
130void collect_cpu_info(int cpu_num) 130static void collect_cpu_info(int cpu_num)
131{ 131{
132 struct cpuinfo_x86 *c = &cpu_data(cpu_num); 132 struct cpuinfo_x86 *c = &cpu_data(cpu_num);
133 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 133 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
@@ -175,7 +175,7 @@ static inline int microcode_update_match(int cpu_num,
175 return 1; 175 return 1;
176} 176}
177 177
178int microcode_sanity_check(void *mc) 178static int microcode_sanity_check(void *mc)
179{ 179{
180 struct microcode_header_intel *mc_header = mc; 180 struct microcode_header_intel *mc_header = mc;
181 struct extended_sigtable *ext_header = NULL; 181 struct extended_sigtable *ext_header = NULL;
@@ -259,7 +259,7 @@ int microcode_sanity_check(void *mc)
259 * return 1 - found update 259 * return 1 - found update
260 * return < 0 - error 260 * return < 0 - error
261 */ 261 */
262int get_matching_microcode(void *mc, int cpu) 262static int get_matching_microcode(void *mc, int cpu)
263{ 263{
264 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 264 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
265 struct microcode_header_intel *mc_header = mc; 265 struct microcode_header_intel *mc_header = mc;
@@ -288,7 +288,8 @@ int get_matching_microcode(void *mc, int cpu)
288 return 0; 288 return 0;
289find: 289find:
290 pr_debug("microcode: CPU%d found a matching microcode update with" 290 pr_debug("microcode: CPU%d found a matching microcode update with"
291 " version 0x%x (current=0x%x)\n", cpu, mc_header->rev, uci->rev); 291 " version 0x%x (current=0x%x)\n",
292 cpu, mc_header->rev, uci->rev);
292 new_mc = vmalloc(total_size); 293 new_mc = vmalloc(total_size);
293 if (!new_mc) { 294 if (!new_mc) {
294 printk(KERN_ERR "microcode: error! Can not allocate memory\n"); 295 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
@@ -303,7 +304,7 @@ find:
303 return 1; 304 return 1;
304} 305}
305 306
306void apply_microcode(int cpu) 307static void apply_microcode(int cpu)
307{ 308{
308 unsigned long flags; 309 unsigned long flags;
309 unsigned int val[2]; 310 unsigned int val[2];
@@ -347,7 +348,7 @@ void apply_microcode(int cpu)
347extern void __user *user_buffer; /* user area microcode data buffer */ 348extern void __user *user_buffer; /* user area microcode data buffer */
348extern unsigned int user_buffer_size; /* it's size */ 349extern unsigned int user_buffer_size; /* it's size */
349 350
350long get_next_ucode(void **mc, long offset) 351static long get_next_ucode(void **mc, long offset)
351{ 352{
352 struct microcode_header_intel mc_header; 353 struct microcode_header_intel mc_header;
353 unsigned long total_size; 354 unsigned long total_size;
@@ -406,7 +407,7 @@ static long get_next_ucode_from_buffer(void **mc, const u8 *buf,
406/* fake device for request_firmware */ 407/* fake device for request_firmware */
407extern struct platform_device *microcode_pdev; 408extern struct platform_device *microcode_pdev;
408 409
409int cpu_request_microcode(int cpu) 410static int cpu_request_microcode(int cpu)
410{ 411{
411 char name[30]; 412 char name[30];
412 struct cpuinfo_x86 *c = &cpu_data(cpu); 413 struct cpuinfo_x86 *c = &cpu_data(cpu);
@@ -455,7 +456,7 @@ int cpu_request_microcode(int cpu)
455 return error; 456 return error;
456} 457}
457 458
458int apply_microcode_check_cpu(int cpu) 459static int apply_microcode_check_cpu(int cpu)
459{ 460{
460 struct cpuinfo_x86 *c = &cpu_data(cpu); 461 struct cpuinfo_x86 *c = &cpu_data(cpu);
461 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 462 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
@@ -504,13 +505,42 @@ int apply_microcode_check_cpu(int cpu)
504 return err; 505 return err;
505} 506}
506 507
507void microcode_fini_cpu(int cpu) 508static void microcode_fini_cpu(int cpu)
508{ 509{
509 struct ucode_cpu_info *uci = ucode_cpu_info + cpu; 510 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
510 511
511 mutex_lock(&microcode_mutex); 512 mutex_lock(&microcode_mutex);
512 uci->valid = 0; 513 uci->valid = 0;
513 kfree(uci->mc.mc_intel); 514 vfree(uci->mc.mc_intel);
514 uci->mc.mc_intel = NULL; 515 uci->mc.mc_intel = NULL;
515 mutex_unlock(&microcode_mutex); 516 mutex_unlock(&microcode_mutex);
516} 517}
518
519static struct microcode_ops microcode_intel_ops = {
520 .get_next_ucode = get_next_ucode,
521 .get_matching_microcode = get_matching_microcode,
522 .microcode_sanity_check = microcode_sanity_check,
523 .apply_microcode_check_cpu = apply_microcode_check_cpu,
524 .cpu_request_microcode = cpu_request_microcode,
525 .collect_cpu_info = collect_cpu_info,
526 .apply_microcode = apply_microcode,
527 .microcode_fini_cpu = microcode_fini_cpu,
528};
529
530static int __init microcode_intel_module_init(void)
531{
532 struct cpuinfo_x86 *c = &cpu_data(get_cpu());
533
534 if (c->x86_vendor == X86_VENDOR_INTEL)
535 return microcode_init(&microcode_intel_ops, THIS_MODULE);
536 else
537 return -ENODEV;
538}
539
540static void __exit microcode_intel_module_exit(void)
541{
542 microcode_exit();
543}
544
545module_init(microcode_intel_module_init)
546module_exit(microcode_intel_module_exit)