diff options
Diffstat (limited to 'arch/x86/kernel/microcode_core.c')
| -rw-r--r-- | arch/x86/kernel/microcode_core.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c index 87af68e0e1e..5ed0ab549eb 100644 --- a/arch/x86/kernel/microcode_core.c +++ b/arch/x86/kernel/microcode_core.c | |||
| @@ -82,6 +82,7 @@ | |||
| 82 | #include <linux/cpu.h> | 82 | #include <linux/cpu.h> |
| 83 | #include <linux/fs.h> | 83 | #include <linux/fs.h> |
| 84 | #include <linux/mm.h> | 84 | #include <linux/mm.h> |
| 85 | #include <linux/syscore_ops.h> | ||
| 85 | 86 | ||
| 86 | #include <asm/microcode.h> | 87 | #include <asm/microcode.h> |
| 87 | #include <asm/processor.h> | 88 | #include <asm/processor.h> |
| @@ -438,33 +439,25 @@ static int mc_sysdev_remove(struct sys_device *sys_dev) | |||
| 438 | return 0; | 439 | return 0; |
| 439 | } | 440 | } |
| 440 | 441 | ||
| 441 | static int mc_sysdev_resume(struct sys_device *dev) | 442 | static struct sysdev_driver mc_sysdev_driver = { |
| 443 | .add = mc_sysdev_add, | ||
| 444 | .remove = mc_sysdev_remove, | ||
| 445 | }; | ||
| 446 | |||
| 447 | /** | ||
| 448 | * mc_bp_resume - Update boot CPU microcode during resume. | ||
| 449 | */ | ||
| 450 | static void mc_bp_resume(void) | ||
| 442 | { | 451 | { |
| 443 | int cpu = dev->id; | 452 | int cpu = smp_processor_id(); |
| 444 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 453 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
| 445 | 454 | ||
| 446 | if (!cpu_online(cpu)) | ||
| 447 | return 0; | ||
| 448 | |||
| 449 | /* | ||
| 450 | * All non-bootup cpus are still disabled, | ||
| 451 | * so only CPU 0 will apply ucode here. | ||
| 452 | * | ||
| 453 | * Moreover, there can be no concurrent | ||
| 454 | * updates from any other places at this point. | ||
| 455 | */ | ||
| 456 | WARN_ON(cpu != 0); | ||
| 457 | |||
| 458 | if (uci->valid && uci->mc) | 455 | if (uci->valid && uci->mc) |
| 459 | microcode_ops->apply_microcode(cpu); | 456 | microcode_ops->apply_microcode(cpu); |
| 460 | |||
| 461 | return 0; | ||
| 462 | } | 457 | } |
| 463 | 458 | ||
| 464 | static struct sysdev_driver mc_sysdev_driver = { | 459 | static struct syscore_ops mc_syscore_ops = { |
| 465 | .add = mc_sysdev_add, | 460 | .resume = mc_bp_resume, |
| 466 | .remove = mc_sysdev_remove, | ||
| 467 | .resume = mc_sysdev_resume, | ||
| 468 | }; | 461 | }; |
| 469 | 462 | ||
| 470 | static __cpuinit int | 463 | static __cpuinit int |
| @@ -542,6 +535,7 @@ static int __init microcode_init(void) | |||
| 542 | if (error) | 535 | if (error) |
| 543 | return error; | 536 | return error; |
| 544 | 537 | ||
| 538 | register_syscore_ops(&mc_syscore_ops); | ||
| 545 | register_hotcpu_notifier(&mc_cpu_notifier); | 539 | register_hotcpu_notifier(&mc_cpu_notifier); |
| 546 | 540 | ||
| 547 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION | 541 | pr_info("Microcode Update Driver: v" MICROCODE_VERSION |
