Commit 07dccf3344010f9b9df7fe725da7e73bca2992df
Committed by
Linus Torvalds
1 parent
6c2d8b5dca
Exists in
master
and in
4 other branches
[PATCH] check return value of cpu_callback
Spawing ksoftirqd, migration, or watchdog, and calling init_timers_cpu() may fail with small memory. If it happens in initcalls, kernel NULL pointer dereference happens later. This patch makes crash happen immediately in such cases. It seems a bit better than getting kernel NULL pointer dereference later. Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Akinobu Mita <mita@miraclelinux.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 4 changed files with 11 additions and 4 deletions Side-by-side Diff
kernel/sched.c
... | ... | @@ -5272,9 +5272,11 @@ |
5272 | 5272 | int __init migration_init(void) |
5273 | 5273 | { |
5274 | 5274 | void *cpu = (void *)(long)smp_processor_id(); |
5275 | + int err; | |
5275 | 5276 | |
5276 | 5277 | /* Start one for the boot CPU: */ |
5277 | - migration_call(&migration_notifier, CPU_UP_PREPARE, cpu); | |
5278 | + err = migration_call(&migration_notifier, CPU_UP_PREPARE, cpu); | |
5279 | + BUG_ON(err == NOTIFY_BAD); | |
5278 | 5280 | migration_call(&migration_notifier, CPU_ONLINE, cpu); |
5279 | 5281 | register_cpu_notifier(&migration_notifier); |
5280 | 5282 |
kernel/softirq.c
... | ... | @@ -612,7 +612,9 @@ |
612 | 612 | __init int spawn_ksoftirqd(void) |
613 | 613 | { |
614 | 614 | void *cpu = (void *)(long)smp_processor_id(); |
615 | - cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | |
615 | + int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | |
616 | + | |
617 | + BUG_ON(err == NOTIFY_BAD); | |
616 | 618 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
617 | 619 | register_cpu_notifier(&cpu_nfb); |
618 | 620 | return 0; |
kernel/softlockup.c
... | ... | @@ -149,8 +149,9 @@ |
149 | 149 | __init void spawn_softlockup_task(void) |
150 | 150 | { |
151 | 151 | void *cpu = (void *)(long)smp_processor_id(); |
152 | + int err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | |
152 | 153 | |
153 | - cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu); | |
154 | + BUG_ON(err == NOTIFY_BAD); | |
154 | 155 | cpu_callback(&cpu_nfb, CPU_ONLINE, cpu); |
155 | 156 | register_cpu_notifier(&cpu_nfb); |
156 | 157 |
kernel/timer.c
... | ... | @@ -1694,8 +1694,10 @@ |
1694 | 1694 | |
1695 | 1695 | void __init init_timers(void) |
1696 | 1696 | { |
1697 | - timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, | |
1697 | + int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, | |
1698 | 1698 | (void *)(long)smp_processor_id()); |
1699 | + | |
1700 | + BUG_ON(err == NOTIFY_BAD); | |
1699 | 1701 | register_cpu_notifier(&timers_nb); |
1700 | 1702 | open_softirq(TIMER_SOFTIRQ, run_timer_softirq, NULL); |
1701 | 1703 | } |