diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a32da804252e..34826934d4a7 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -122,8 +122,9 @@ static void smp_callin(void) | |||
122 | * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. | 122 | * Since CPU0 is not wakened up by INIT, it doesn't wait for the IPI. |
123 | */ | 123 | */ |
124 | cpuid = smp_processor_id(); | 124 | cpuid = smp_processor_id(); |
125 | if (apic->wait_for_init_deassert && cpuid != 0) | 125 | if (apic->wait_for_init_deassert && cpuid) |
126 | apic->wait_for_init_deassert(&init_deasserted); | 126 | while (!atomic_read(&init_deasserted)) |
127 | cpu_relax(); | ||
127 | 128 | ||
128 | /* | 129 | /* |
129 | * (This works even if the APIC is not enabled.) | 130 | * (This works even if the APIC is not enabled.) |
@@ -701,11 +702,15 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, | |||
701 | int id; | 702 | int id; |
702 | int boot_error; | 703 | int boot_error; |
703 | 704 | ||
705 | preempt_disable(); | ||
706 | |||
704 | /* | 707 | /* |
705 | * Wake up AP by INIT, INIT, STARTUP sequence. | 708 | * Wake up AP by INIT, INIT, STARTUP sequence. |
706 | */ | 709 | */ |
707 | if (cpu) | 710 | if (cpu) { |
708 | return wakeup_secondary_cpu_via_init(apicid, start_ip); | 711 | boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); |
712 | goto out; | ||
713 | } | ||
709 | 714 | ||
710 | /* | 715 | /* |
711 | * Wake up BSP by nmi. | 716 | * Wake up BSP by nmi. |
@@ -725,6 +730,9 @@ wakeup_cpu_via_init_nmi(int cpu, unsigned long start_ip, int apicid, | |||
725 | boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); | 730 | boot_error = wakeup_secondary_cpu_via_nmi(id, start_ip); |
726 | } | 731 | } |
727 | 732 | ||
733 | out: | ||
734 | preempt_enable(); | ||
735 | |||
728 | return boot_error; | 736 | return boot_error; |
729 | } | 737 | } |
730 | 738 | ||
@@ -758,10 +766,10 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle) | |||
758 | #else | 766 | #else |
759 | clear_tsk_thread_flag(idle, TIF_FORK); | 767 | clear_tsk_thread_flag(idle, TIF_FORK); |
760 | initial_gs = per_cpu_offset(cpu); | 768 | initial_gs = per_cpu_offset(cpu); |
769 | #endif | ||
761 | per_cpu(kernel_stack, cpu) = | 770 | per_cpu(kernel_stack, cpu) = |
762 | (unsigned long)task_stack_page(idle) - | 771 | (unsigned long)task_stack_page(idle) - |
763 | KERNEL_STACK_OFFSET + THREAD_SIZE; | 772 | KERNEL_STACK_OFFSET + THREAD_SIZE; |
764 | #endif | ||
765 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 773 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
766 | initial_code = (unsigned long)start_secondary; | 774 | initial_code = (unsigned long)start_secondary; |
767 | stack_start = idle->thread.sp; | 775 | stack_start = idle->thread.sp; |
@@ -1379,7 +1387,7 @@ static inline void mwait_play_dead(void) | |||
1379 | 1387 | ||
1380 | if (!this_cpu_has(X86_FEATURE_MWAIT)) | 1388 | if (!this_cpu_has(X86_FEATURE_MWAIT)) |
1381 | return; | 1389 | return; |
1382 | if (!this_cpu_has(X86_FEATURE_CLFLSH)) | 1390 | if (!this_cpu_has(X86_FEATURE_CLFLUSH)) |
1383 | return; | 1391 | return; |
1384 | if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF) | 1392 | if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF) |
1385 | return; | 1393 | return; |