Messages in this thread | | | Date | Mon, 13 Aug 2012 09:50:00 -0700 | From | "Paul E. McKenney" <> | Subject | Re: [PATCH 1/4 V2] Use get_online_cpus to avoid races involving CPU hotplug |
| |
On Fri, Aug 03, 2012 at 12:33:27PM -0700, Silas Boyd-Wickizer wrote: > If arch/x86/kernel/msr.c is a module, a CPU might offline or online > between the for_each_online_cpu(i) loop and the call to > register_hotcpu_notifier in msr_init or the call to > unregister_hotcpu_notifier in msr_exit. The potential races can lead > to leaks/duplicates, attempts to destroy non-existant devices, or > random pointer dereferences. > > For example, in msr_init if: > > for_each_online_cpu(i) { > err = msr_device_create(i); > if (err != 0) > goto out_class; > } > <----- CPU offlines > register_hotcpu_notifier(&msr_class_cpu_notifier); > > and the CPU never onlines before msr_exit, then the module will never > call msr_device_destroy for the associated CPU. > > This fix surrounds for_each_online_cpu and register_hotcpu_notifier or > unregister_hotcpu_notifier with get_online_cpus+put_online_cpus. > > Tested on a VM. > > Signed-off-by: Silas Boyd-Wickizer <sbw@mit.edu>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> --- > arch/x86/kernel/msr.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c > index eb11369..a7c5661 100644 > --- a/arch/x86/kernel/msr.c > +++ b/arch/x86/kernel/msr.c > @@ -257,12 +257,14 @@ static int __init msr_init(void) > goto out_chrdev; > } > msr_class->devnode = msr_devnode; > + get_online_cpus(); > for_each_online_cpu(i) { > err = msr_device_create(i); > if (err != 0) > goto out_class; > } > register_hotcpu_notifier(&msr_class_cpu_notifier); > + put_online_cpus(); > > err = 0; > goto out; > @@ -271,6 +273,7 @@ out_class: > i = 0; > for_each_online_cpu(i) > msr_device_destroy(i); > + put_online_cpus(); > class_destroy(msr_class); > out_chrdev: > __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); > @@ -281,11 +284,13 @@ out: > static void __exit msr_exit(void) > { > int cpu = 0; > + get_online_cpus(); > for_each_online_cpu(cpu) > msr_device_destroy(cpu); > class_destroy(msr_class); > __unregister_chrdev(MSR_MAJOR, 0, NR_CPUS, "cpu/msr"); > unregister_hotcpu_notifier(&msr_class_cpu_notifier); > + put_online_cpus(); > } > > module_init(msr_init); > -- > 1.7.10.4 >
| |