If a cpu hotplug callback fails on CPU_UP_PREPARE, all callbacks will be called with CPU_UP_CANCELED. A few of these callbacks assume that on CPU_UP_PREPARE a pointer to task has been stored in a percpu array. This assumption is not true if CPU_UP_PREPARE fails and the following calls to kthread_bind() in CPU_UP_CANCELED will cause an addressing exception because of passing a NULL pointer.
Showing the changes to kernel/workqueue.c (1 of 4 files). Show all
Unified · Split
| @@ -590,6 +590,8 @@ static int workqueue_cpu_callback(struct notifier_block *nfb, · 589 unmodified lines | |||
| 590 | 590 | ||
| 591 | case CPU_UP_CANCELED: | 591 | case CPU_UP_CANCELED: |
| 592 | list_for_each_entry(wq, &workqueues, list) { | 592 | list_for_each_entry(wq, &workqueues, list) { |
| 593 | if (!per_cpu_ptr(wq->cpu_wq, hotcpu)->thread) | ||
| 594 | continue; | ||
| 593 | /* Unbind so it can run. */ | 595 | /* Unbind so it can run. */ |
| 594 | kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread, | 596 | kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread, |
| 595 | any_online_cpu(cpu_online_map)); | 597 | any_online_cpu(cpu_online_map)); |