From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S938617AbcIFRGJ (ORCPT ); Tue, 6 Sep 2016 13:06:09 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:36750 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933172AbcIFRGG (ORCPT ); Tue, 6 Sep 2016 13:06:06 -0400 From: Sebastian Andrzej Siewior To: linux-kernel@vger.kernel.org Cc: Peter Zijlstra , Ingo Molnar , rt@linutronix.de, tglx@linutronix.de, Sebastian Andrzej Siewior , Borislav Petkov Subject: [PATCH 06/21] x86: microcode: Convert to hotplug state machine Date: Tue, 6 Sep 2016 19:04:42 +0200 Message-Id: <20160906170457.32393-7-bigeasy@linutronix.de> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20160906170457.32393-1-bigeasy@linutronix.de> References: <20160906170457.32393-1-bigeasy@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Install the callbacks via the state machine. There is little hackery with mc_cpu_dead() which should only be called if CPU_UP failed durin resume. This change may not fully represent the current behaviour. The current code also behaves different if the CPU does not come up in the _cpu_up() state vs one of the CPU_ONLINE notifier returned an error. Not sure what kind of a problem is solved here. Cc: Borislav Petkov Signed-off-by: Sebastian Andrzej Siewior --- arch/x86/kernel/cpu/microcode/core.c | 71 +++++++++++++++-----------------= ---- include/linux/cpuhotplug.h | 1 + 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/mic= rocode/core.c index df04b2d033f6..4fc67b51e22e 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -558,54 +558,38 @@ static struct syscore_ops mc_syscore_ops =3D { .resume =3D mc_bp_resume, }; =20 -static int -mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcp= u) +static int mc_cpu_online(unsigned int cpu) { - unsigned int cpu =3D (unsigned long)hcpu; struct device *dev; =20 dev =3D get_cpu_device(cpu); + microcode_update_cpu(cpu); + pr_debug("CPU%d added\n", cpu); =20 - switch (action & ~CPU_TASKS_FROZEN) { - case CPU_ONLINE: - microcode_update_cpu(cpu); - pr_debug("CPU%d added\n", cpu); - /* - * "break" is missing on purpose here because we want to fall - * through in order to create the sysfs group. - */ - - case CPU_DOWN_FAILED: - if (sysfs_create_group(&dev->kobj, &mc_attr_group)) - pr_err("Failed to create group for CPU%d\n", cpu); - break; - - case CPU_DOWN_PREPARE: - /* Suspend is in progress, only remove the interface */ - sysfs_remove_group(&dev->kobj, &mc_attr_group); - pr_debug("CPU%d removed\n", cpu); - break; - - /* - * case CPU_DEAD: - * - * When a CPU goes offline, don't free up or invalidate the copy of - * the microcode in kernel memory, so that we can reuse it when the - * CPU comes back online without unnecessarily requesting the userspace - * for it again. - */ - } - - /* The CPU refused to come up during a system resume */ - if (action =3D=3D CPU_UP_CANCELED_FROZEN) - microcode_fini_cpu(cpu); - - return NOTIFY_OK; + if (sysfs_create_group(&dev->kobj, &mc_attr_group)) + pr_err("Failed to create group for CPU%d\n", cpu); + return 0; } =20 -static struct notifier_block mc_cpu_notifier =3D { - .notifier_call =3D mc_cpu_callback, -}; +static int mc_cpu_down_prep(unsigned int cpu) +{ + struct device *dev; + + dev =3D get_cpu_device(cpu); + /* Suspend is in progress, only remove the interface */ + sysfs_remove_group(&dev->kobj, &mc_attr_group); + pr_debug("CPU%d removed\n", cpu); + return 0; +} + +static int mc_cpu_dead(unsigned int cpu) +{ +#ifdef CONFIG_SMP + if (cpuhp_tasks_frozen) + microcode_fini_cpu(cpu); +#endif + return 0; +} =20 static struct attribute *cpu_root_microcode_attrs[] =3D { &dev_attr_reload.attr, @@ -665,7 +649,10 @@ int __init microcode_init(void) goto out_ucode_group; =20 register_syscore_ops(&mc_syscore_ops); - register_hotcpu_notifier(&mc_cpu_notifier); + cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", + mc_cpu_online, mc_cpu_down_prep); + cpuhp_setup_state_nocalls(CPUHP_X86_MICRCODE_PREPARE, + "x86/microcode:prepare", NULL, mc_cpu_dead); =20 pr_info("Microcode Update Driver: v" MICROCODE_VERSION " , Peter Oruba\n"); diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 8dec2a236af3..4ca7551b902f 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -38,6 +38,7 @@ enum cpuhp_state { CPUHP_NOTIFY_PREPARE, CPUHP_ARM_SHMOBILE_SCU_PREPARE, CPUHP_SH_SH3X_PREPARE, + CPUHP_X86_MICRCODE_PREPARE, CPUHP_TIMERS_DEAD, CPUHP_BRINGUP_CPU, CPUHP_AP_IDLE_DEAD, --=20 2.9.3