[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/3] xen/cpu: Distinguish "cpu already in that state" in cpu_{up, down}()
All methods of querying the online state of a CPU are racy without the hotplug lock held, which can lead to a TOCTOU race trying to online or offline CPUs. Distinguish this case with -EEXIST rather than -EINVAL, so the caller can take other actions if necessary. While adjusting this, rework the code slightly to fold the exit paths, which results in a minor reduction in compiled code size. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/common/cpu.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/xen/common/cpu.c b/xen/common/cpu.c index 836c62f..1829318 100644 --- a/xen/common/cpu.c +++ b/xen/common/cpu.c @@ -94,11 +94,13 @@ int cpu_down(unsigned int cpu) if ( !cpu_hotplug_begin() ) return -EBUSY; - if ( (cpu >= nr_cpu_ids) || (cpu == 0) || !cpu_online(cpu) ) - { - cpu_hotplug_done(); - return -EINVAL; - } + err = -EINVAL; + if ( (cpu >= nr_cpu_ids) || (cpu == 0) ) + goto out; + + err = -EEXIST; + if ( !cpu_online(cpu) ) + goto out; notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, hcpu, &nb); if ( notifier_rc != NOTIFY_DONE ) @@ -125,6 +127,7 @@ int cpu_down(unsigned int cpu) fail: notifier_rc = notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, &nb); BUG_ON(notifier_rc != NOTIFY_DONE); + out: cpu_hotplug_done(); return err; } @@ -138,11 +141,13 @@ int cpu_up(unsigned int cpu) if ( !cpu_hotplug_begin() ) return -EBUSY; - if ( (cpu >= nr_cpu_ids) || cpu_online(cpu) || !cpu_present(cpu) ) - { - cpu_hotplug_done(); - return -EINVAL; - } + err = -EINVAL; + if ( (cpu >= nr_cpu_ids) || !cpu_present(cpu) ) + goto out; + + err = -EEXIST; + if ( cpu_online(cpu) ) + goto out; notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, &nb); if ( notifier_rc != NOTIFY_DONE ) @@ -166,6 +171,7 @@ int cpu_up(unsigned int cpu) fail: notifier_rc = notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu, &nb); BUG_ON(notifier_rc != NOTIFY_DONE); + out: cpu_hotplug_done(); return err; } -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |