[patch 02/10] cpu/hotplug: Prevent overwriting of callbacks

From: Thomas Gleixner
Date: Wed Dec 21 2016 - 14:30:55 EST


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 <tglx@xxxxxxxxxxxxx>
---
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;

/*