From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1761596AbcLUT2t (ORCPT ); Wed, 21 Dec 2016 14:28:49 -0500 Received: from Galois.linutronix.de ([146.0.238.70]:59998 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752932AbcLUT2q (ORCPT ); Wed, 21 Dec 2016 14:28:46 -0500 Message-Id: <20161221192111.675234535@linutronix.de> User-Agent: quilt/0.63-1 Date: Wed, 21 Dec 2016 20:19:49 +0100 From: Thomas Gleixner To: LKML Cc: Sebastian Siewior , Ingo Molnar , Peter Zijlstra Subject: [patch 02/10] cpu/hotplug: Prevent overwriting of callbacks References: <20161221191947.089046759@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Disposition: inline; filename=cpu-hotplug--Prevent-overwriting-of-callbacks.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Developers manage to overwrite states blindly without thought. That's fatal and hard to debug. Add sanity checks to make it fail. Signed-off-by: Thomas Gleixner --- kernel/cpu.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1432,23 +1432,29 @@ static int cpuhp_cb_check(enum cpuhp_sta return 0; } -static void cpuhp_store_callbacks(enum cpuhp_state state, - const char *name, - int (*startup)(unsigned int cpu), - int (*teardown)(unsigned int cpu), - bool multi_instance) +static int cpuhp_store_callbacks(enum cpuhp_state state, const char *name, + int (*startup)(unsigned int cpu), + int (*teardown)(unsigned int cpu), + bool multi_instance) { /* (Un)Install the callbacks for further cpu hotplug operations */ struct cpuhp_step *sp; + int ret = 0; mutex_lock(&cpuhp_state_mutex); sp = cpuhp_get_step(state); + if (name && sp->name) { + ret = -EBUSY; + goto out; + } sp->startup.single = startup; sp->teardown.single = teardown; sp->name = name; sp->multi_instance = multi_instance; INIT_HLIST_HEAD(&sp->list); +out: mutex_unlock(&cpuhp_state_mutex); + return ret; } static void *cpuhp_get_teardown_cb(enum cpuhp_state state) @@ -1580,11 +1586,13 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_inst /** * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state - * @state: The state to setup - * @invoke: If true, the startup function is invoked for cpus where - * cpu state >= @state - * @startup: startup callback function - * @teardown: teardown callback function + * @state: The state to setup + * @invoke: If true, the startup function is invoked for cpus where + * cpu state >= @state + * @startup: startup callback function + * @teardown: teardown callback function + * @multi_instance: State is set up for multiple instances which get + * added afterwards. * * Returns: * On success: @@ -1615,9 +1623,10 @@ int __cpuhp_setup_state(enum cpuhp_state state = ret; } - cpuhp_store_callbacks(state, name, startup, teardown, multi_instance); + ret = cpuhp_store_callbacks(state, name, startup, teardown, + multi_instance); - if (!invoke || !startup) + if (ret || !invoke || !startup) goto out; /*