aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/microcode
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2016-09-07 12:45:23 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-19 15:44:27 -0400
commit29bd7fbc071598e939526f782293dbe137be3768 (patch)
tree6545bc71f1e17acf4088c95deb83ffb048fcd597 /arch/x86/kernel/cpu/microcode
parent515332336be71d014bca1d29369c5d72baa38f71 (diff)
x86/microcode: Convert to hotplug state machine
Install the callbacks via the state machine. CPU_UP_CANCELED_FROZEN() is not preserved: It is only there to free memory in an error case because it is assumed if the CPU does show up on resume it won't be seen ever again. As per Borislav: |IOW, you don't need mc_cpu_dead(). Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Borislav Petkov <bp@alien8.de> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160907164523.46a2xnffha4bv63g@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/cpu/microcode')
-rw-r--r--arch/x86/kernel/cpu/microcode/core.c52
1 files changed, 17 insertions, 35 deletions
diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
index df04b2d033f6..5ce5155f0695 100644
--- a/arch/x86/kernel/cpu/microcode/core.c
+++ b/arch/x86/kernel/cpu/microcode/core.c
@@ -558,55 +558,36 @@ static struct syscore_ops mc_syscore_ops = {
558 .resume = mc_bp_resume, 558 .resume = mc_bp_resume,
559}; 559};
560 560
561static int 561static int mc_cpu_online(unsigned int cpu)
562mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
563{ 562{
564 unsigned int cpu = (unsigned long)hcpu;
565 struct device *dev; 563 struct device *dev;
566 564
567 dev = get_cpu_device(cpu); 565 dev = get_cpu_device(cpu);
566 microcode_update_cpu(cpu);
567 pr_debug("CPU%d added\n", cpu);
568 568
569 switch (action & ~CPU_TASKS_FROZEN) { 569 if (sysfs_create_group(&dev->kobj, &mc_attr_group))
570 case CPU_ONLINE: 570 pr_err("Failed to create group for CPU%d\n", cpu);
571 microcode_update_cpu(cpu); 571 return 0;
572 pr_debug("CPU%d added\n", cpu); 572}
573 /*
574 * "break" is missing on purpose here because we want to fall
575 * through in order to create the sysfs group.
576 */
577
578 case CPU_DOWN_FAILED:
579 if (sysfs_create_group(&dev->kobj, &mc_attr_group))
580 pr_err("Failed to create group for CPU%d\n", cpu);
581 break;
582 573
583 case CPU_DOWN_PREPARE: 574static int mc_cpu_down_prep(unsigned int cpu)
584 /* Suspend is in progress, only remove the interface */ 575{
585 sysfs_remove_group(&dev->kobj, &mc_attr_group); 576 struct device *dev;
586 pr_debug("CPU%d removed\n", cpu);
587 break;
588 577
578 dev = get_cpu_device(cpu);
579 /* Suspend is in progress, only remove the interface */
580 sysfs_remove_group(&dev->kobj, &mc_attr_group);
581 pr_debug("CPU%d removed\n", cpu);
589 /* 582 /*
590 * case CPU_DEAD:
591 *
592 * When a CPU goes offline, don't free up or invalidate the copy of 583 * When a CPU goes offline, don't free up or invalidate the copy of
593 * the microcode in kernel memory, so that we can reuse it when the 584 * the microcode in kernel memory, so that we can reuse it when the
594 * CPU comes back online without unnecessarily requesting the userspace 585 * CPU comes back online without unnecessarily requesting the userspace
595 * for it again. 586 * for it again.
596 */ 587 */
597 } 588 return 0;
598
599 /* The CPU refused to come up during a system resume */
600 if (action == CPU_UP_CANCELED_FROZEN)
601 microcode_fini_cpu(cpu);
602
603 return NOTIFY_OK;
604} 589}
605 590
606static struct notifier_block mc_cpu_notifier = {
607 .notifier_call = mc_cpu_callback,
608};
609
610static struct attribute *cpu_root_microcode_attrs[] = { 591static struct attribute *cpu_root_microcode_attrs[] = {
611 &dev_attr_reload.attr, 592 &dev_attr_reload.attr,
612 NULL 593 NULL
@@ -665,7 +646,8 @@ int __init microcode_init(void)
665 goto out_ucode_group; 646 goto out_ucode_group;
666 647
667 register_syscore_ops(&mc_syscore_ops); 648 register_syscore_ops(&mc_syscore_ops);
668 register_hotcpu_notifier(&mc_cpu_notifier); 649 cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online",
650 mc_cpu_online, mc_cpu_down_prep);
669 651
670 pr_info("Microcode Update Driver: v" MICROCODE_VERSION 652 pr_info("Microcode Update Driver: v" MICROCODE_VERSION
671 " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n"); 653 " <tigran@aivazian.fsnet.co.uk>, Peter Oruba\n");