diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 225 |
1 files changed, 43 insertions, 182 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index bb1a3b1fc87f..ef7d10170c30 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * x86 SMP booting functions | 2 | * x86 SMP booting functions |
3 | * | 3 | * |
4 | * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk> | 4 | * (c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk> |
5 | * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com> | 5 | * (c) 1998, 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com> |
6 | * Copyright 2001 Andi Kleen, SuSE Labs. | 6 | * Copyright 2001 Andi Kleen, SuSE Labs. |
7 | * | 7 | * |
8 | * Much of the core SMP work is based on previous work by Thomas Radke, to | 8 | * Much of the core SMP work is based on previous work by Thomas Radke, to |
@@ -53,7 +53,6 @@ | |||
53 | #include <asm/nmi.h> | 53 | #include <asm/nmi.h> |
54 | #include <asm/irq.h> | 54 | #include <asm/irq.h> |
55 | #include <asm/idle.h> | 55 | #include <asm/idle.h> |
56 | #include <asm/smp.h> | ||
57 | #include <asm/trampoline.h> | 56 | #include <asm/trampoline.h> |
58 | #include <asm/cpu.h> | 57 | #include <asm/cpu.h> |
59 | #include <asm/numa.h> | 58 | #include <asm/numa.h> |
@@ -61,13 +60,12 @@ | |||
61 | #include <asm/tlbflush.h> | 60 | #include <asm/tlbflush.h> |
62 | #include <asm/mtrr.h> | 61 | #include <asm/mtrr.h> |
63 | #include <asm/vmi.h> | 62 | #include <asm/vmi.h> |
64 | #include <asm/genapic.h> | 63 | #include <asm/apic.h> |
65 | #include <asm/setup.h> | 64 | #include <asm/setup.h> |
65 | #include <asm/uv/uv.h> | ||
66 | #include <linux/mc146818rtc.h> | 66 | #include <linux/mc146818rtc.h> |
67 | 67 | ||
68 | #include <mach_apic.h> | 68 | #include <asm/smpboot_hooks.h> |
69 | #include <mach_wakecpu.h> | ||
70 | #include <smpboot_hooks.h> | ||
71 | 69 | ||
72 | #ifdef CONFIG_X86_32 | 70 | #ifdef CONFIG_X86_32 |
73 | u8 apicid_2_node[MAX_APICID]; | 71 | u8 apicid_2_node[MAX_APICID]; |
@@ -114,11 +112,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); | |||
114 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); | 112 | DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info); |
115 | EXPORT_PER_CPU_SYMBOL(cpu_info); | 113 | EXPORT_PER_CPU_SYMBOL(cpu_info); |
116 | 114 | ||
117 | static atomic_t init_deasserted; | 115 | atomic_t init_deasserted; |
118 | |||
119 | |||
120 | /* Set if we find a B stepping CPU */ | ||
121 | static int __cpuinitdata smp_b_stepping; | ||
122 | 116 | ||
123 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) | 117 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_32) |
124 | 118 | ||
@@ -163,7 +157,7 @@ static void map_cpu_to_logical_apicid(void) | |||
163 | { | 157 | { |
164 | int cpu = smp_processor_id(); | 158 | int cpu = smp_processor_id(); |
165 | int apicid = logical_smp_processor_id(); | 159 | int apicid = logical_smp_processor_id(); |
166 | int node = apicid_to_node(apicid); | 160 | int node = apic->apicid_to_node(apicid); |
167 | 161 | ||
168 | if (!node_online(node)) | 162 | if (!node_online(node)) |
169 | node = first_online_node; | 163 | node = first_online_node; |
@@ -196,7 +190,8 @@ static void __cpuinit smp_callin(void) | |||
196 | * our local APIC. We have to wait for the IPI or we'll | 190 | * our local APIC. We have to wait for the IPI or we'll |
197 | * lock up on an APIC access. | 191 | * lock up on an APIC access. |
198 | */ | 192 | */ |
199 | wait_for_init_deassert(&init_deasserted); | 193 | if (apic->wait_for_init_deassert) |
194 | apic->wait_for_init_deassert(&init_deasserted); | ||
200 | 195 | ||
201 | /* | 196 | /* |
202 | * (This works even if the APIC is not enabled.) | 197 | * (This works even if the APIC is not enabled.) |
@@ -243,7 +238,8 @@ static void __cpuinit smp_callin(void) | |||
243 | */ | 238 | */ |
244 | 239 | ||
245 | pr_debug("CALLIN, before setup_local_APIC().\n"); | 240 | pr_debug("CALLIN, before setup_local_APIC().\n"); |
246 | smp_callin_clear_local_apic(); | 241 | if (apic->smp_callin_clear_local_apic) |
242 | apic->smp_callin_clear_local_apic(); | ||
247 | setup_local_APIC(); | 243 | setup_local_APIC(); |
248 | end_local_APIC_setup(); | 244 | end_local_APIC_setup(); |
249 | map_cpu_to_logical_apicid(); | 245 | map_cpu_to_logical_apicid(); |
@@ -271,8 +267,6 @@ static void __cpuinit smp_callin(void) | |||
271 | cpumask_set_cpu(cpuid, cpu_callin_mask); | 267 | cpumask_set_cpu(cpuid, cpu_callin_mask); |
272 | } | 268 | } |
273 | 269 | ||
274 | static int __cpuinitdata unsafe_smp; | ||
275 | |||
276 | /* | 270 | /* |
277 | * Activate a secondary processor. | 271 | * Activate a secondary processor. |
278 | */ | 272 | */ |
@@ -340,76 +334,6 @@ notrace static void __cpuinit start_secondary(void *unused) | |||
340 | cpu_idle(); | 334 | cpu_idle(); |
341 | } | 335 | } |
342 | 336 | ||
343 | static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c) | ||
344 | { | ||
345 | /* | ||
346 | * Mask B, Pentium, but not Pentium MMX | ||
347 | */ | ||
348 | if (c->x86_vendor == X86_VENDOR_INTEL && | ||
349 | c->x86 == 5 && | ||
350 | c->x86_mask >= 1 && c->x86_mask <= 4 && | ||
351 | c->x86_model <= 3) | ||
352 | /* | ||
353 | * Remember we have B step Pentia with bugs | ||
354 | */ | ||
355 | smp_b_stepping = 1; | ||
356 | |||
357 | /* | ||
358 | * Certain Athlons might work (for various values of 'work') in SMP | ||
359 | * but they are not certified as MP capable. | ||
360 | */ | ||
361 | if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { | ||
362 | |||
363 | if (num_possible_cpus() == 1) | ||
364 | goto valid_k7; | ||
365 | |||
366 | /* Athlon 660/661 is valid. */ | ||
367 | if ((c->x86_model == 6) && ((c->x86_mask == 0) || | ||
368 | (c->x86_mask == 1))) | ||
369 | goto valid_k7; | ||
370 | |||
371 | /* Duron 670 is valid */ | ||
372 | if ((c->x86_model == 7) && (c->x86_mask == 0)) | ||
373 | goto valid_k7; | ||
374 | |||
375 | /* | ||
376 | * Athlon 662, Duron 671, and Athlon >model 7 have capability | ||
377 | * bit. It's worth noting that the A5 stepping (662) of some | ||
378 | * Athlon XP's have the MP bit set. | ||
379 | * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for | ||
380 | * more. | ||
381 | */ | ||
382 | if (((c->x86_model == 6) && (c->x86_mask >= 2)) || | ||
383 | ((c->x86_model == 7) && (c->x86_mask >= 1)) || | ||
384 | (c->x86_model > 7)) | ||
385 | if (cpu_has_mp) | ||
386 | goto valid_k7; | ||
387 | |||
388 | /* If we get here, not a certified SMP capable AMD system. */ | ||
389 | unsafe_smp = 1; | ||
390 | } | ||
391 | |||
392 | valid_k7: | ||
393 | ; | ||
394 | } | ||
395 | |||
396 | static void __cpuinit smp_checks(void) | ||
397 | { | ||
398 | if (smp_b_stepping) | ||
399 | printk(KERN_WARNING "WARNING: SMP operation may be unreliable" | ||
400 | "with B stepping processors.\n"); | ||
401 | |||
402 | /* | ||
403 | * Don't taint if we are running SMP kernel on a single non-MP | ||
404 | * approved Athlon | ||
405 | */ | ||
406 | if (unsafe_smp && num_online_cpus() > 1) { | ||
407 | printk(KERN_INFO "WARNING: This combination of AMD" | ||
408 | "processors is not suitable for SMP.\n"); | ||
409 | add_taint(TAINT_UNSAFE_SMP); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | /* | 337 | /* |
414 | * The bootstrap kernel entry code has set these up. Save them for | 338 | * The bootstrap kernel entry code has set these up. Save them for |
415 | * a given CPU | 339 | * a given CPU |
@@ -423,7 +347,6 @@ void __cpuinit smp_store_cpu_info(int id) | |||
423 | c->cpu_index = id; | 347 | c->cpu_index = id; |
424 | if (id != 0) | 348 | if (id != 0) |
425 | identify_secondary_cpu(c); | 349 | identify_secondary_cpu(c); |
426 | smp_apply_quirks(c); | ||
427 | } | 350 | } |
428 | 351 | ||
429 | 352 | ||
@@ -583,7 +506,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip) | |||
583 | /* Target chip */ | 506 | /* Target chip */ |
584 | /* Boot on the stack */ | 507 | /* Boot on the stack */ |
585 | /* Kick the second */ | 508 | /* Kick the second */ |
586 | apic_icr_write(APIC_DM_NMI | APIC_DEST_LOGICAL, logical_apicid); | 509 | apic_icr_write(APIC_DM_NMI | apic->dest_logical, logical_apicid); |
587 | 510 | ||
588 | pr_debug("Waiting for send to finish...\n"); | 511 | pr_debug("Waiting for send to finish...\n"); |
589 | send_status = safe_apic_wait_icr_idle(); | 512 | send_status = safe_apic_wait_icr_idle(); |
@@ -614,12 +537,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip) | |||
614 | unsigned long send_status, accept_status = 0; | 537 | unsigned long send_status, accept_status = 0; |
615 | int maxlvt, num_starts, j; | 538 | int maxlvt, num_starts, j; |
616 | 539 | ||
617 | if (get_uv_system_type() == UV_NON_UNIQUE_APIC) { | ||
618 | send_status = uv_wakeup_secondary(phys_apicid, start_eip); | ||
619 | atomic_set(&init_deasserted, 1); | ||
620 | return send_status; | ||
621 | } | ||
622 | |||
623 | maxlvt = lapic_get_maxlvt(); | 540 | maxlvt = lapic_get_maxlvt(); |
624 | 541 | ||
625 | /* | 542 | /* |
@@ -745,78 +662,23 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
745 | complete(&c_idle->done); | 662 | complete(&c_idle->done); |
746 | } | 663 | } |
747 | 664 | ||
748 | #ifdef CONFIG_X86_64 | ||
749 | |||
750 | /* __ref because it's safe to call free_bootmem when after_bootmem == 0. */ | ||
751 | static void __ref free_bootmem_pda(struct x8664_pda *oldpda) | ||
752 | { | ||
753 | if (!after_bootmem) | ||
754 | free_bootmem((unsigned long)oldpda, sizeof(*oldpda)); | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * Allocate node local memory for the AP pda. | ||
759 | * | ||
760 | * Must be called after the _cpu_pda pointer table is initialized. | ||
761 | */ | ||
762 | int __cpuinit get_local_pda(int cpu) | ||
763 | { | ||
764 | struct x8664_pda *oldpda, *newpda; | ||
765 | unsigned long size = sizeof(struct x8664_pda); | ||
766 | int node = cpu_to_node(cpu); | ||
767 | |||
768 | if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem) | ||
769 | return 0; | ||
770 | |||
771 | oldpda = cpu_pda(cpu); | ||
772 | newpda = kmalloc_node(size, GFP_ATOMIC, node); | ||
773 | if (!newpda) { | ||
774 | printk(KERN_ERR "Could not allocate node local PDA " | ||
775 | "for CPU %d on node %d\n", cpu, node); | ||
776 | |||
777 | if (oldpda) | ||
778 | return 0; /* have a usable pda */ | ||
779 | else | ||
780 | return -1; | ||
781 | } | ||
782 | |||
783 | if (oldpda) { | ||
784 | memcpy(newpda, oldpda, size); | ||
785 | free_bootmem_pda(oldpda); | ||
786 | } | ||
787 | |||
788 | newpda->in_bootmem = 0; | ||
789 | cpu_pda(cpu) = newpda; | ||
790 | return 0; | ||
791 | } | ||
792 | #endif /* CONFIG_X86_64 */ | ||
793 | |||
794 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | ||
795 | /* | 665 | /* |
796 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 666 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
797 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. | 667 | * (ie clustered apic addressing mode), this is a LOGICAL apic ID. |
798 | * Returns zero if CPU booted OK, else error code from wakeup_secondary_cpu. | 668 | * Returns zero if CPU booted OK, else error code from |
669 | * ->wakeup_secondary_cpu. | ||
799 | */ | 670 | */ |
671 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | ||
800 | { | 672 | { |
801 | unsigned long boot_error = 0; | 673 | unsigned long boot_error = 0; |
802 | int timeout; | ||
803 | unsigned long start_ip; | 674 | unsigned long start_ip; |
804 | unsigned short nmi_high = 0, nmi_low = 0; | 675 | int timeout; |
805 | struct create_idle c_idle = { | 676 | struct create_idle c_idle = { |
806 | .cpu = cpu, | 677 | .cpu = cpu, |
807 | .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), | 678 | .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), |
808 | }; | 679 | }; |
809 | INIT_WORK(&c_idle.work, do_fork_idle); | ||
810 | 680 | ||
811 | #ifdef CONFIG_X86_64 | 681 | INIT_WORK(&c_idle.work, do_fork_idle); |
812 | /* Allocate node local memory for AP pdas */ | ||
813 | if (cpu > 0) { | ||
814 | boot_error = get_local_pda(cpu); | ||
815 | if (boot_error) | ||
816 | goto restore_state; | ||
817 | /* if can't get pda memory, can't start cpu */ | ||
818 | } | ||
819 | #endif | ||
820 | 682 | ||
821 | alternatives_smp_switch(1); | 683 | alternatives_smp_switch(1); |
822 | 684 | ||
@@ -847,14 +709,16 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
847 | 709 | ||
848 | set_idle_for_cpu(cpu, c_idle.idle); | 710 | set_idle_for_cpu(cpu, c_idle.idle); |
849 | do_rest: | 711 | do_rest: |
850 | #ifdef CONFIG_X86_32 | ||
851 | per_cpu(current_task, cpu) = c_idle.idle; | 712 | per_cpu(current_task, cpu) = c_idle.idle; |
852 | init_gdt(cpu); | 713 | #ifdef CONFIG_X86_32 |
853 | /* Stack for startup_32 can be just as for start_secondary onwards */ | 714 | /* Stack for startup_32 can be just as for start_secondary onwards */ |
854 | irq_ctx_init(cpu); | 715 | irq_ctx_init(cpu); |
855 | #else | 716 | #else |
856 | cpu_pda(cpu)->pcurrent = c_idle.idle; | ||
857 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); | 717 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
718 | initial_gs = per_cpu_offset(cpu); | ||
719 | per_cpu(kernel_stack, cpu) = | ||
720 | (unsigned long)task_stack_page(c_idle.idle) - | ||
721 | KERNEL_STACK_OFFSET + THREAD_SIZE; | ||
858 | #endif | 722 | #endif |
859 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 723 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
860 | initial_code = (unsigned long)start_secondary; | 724 | initial_code = (unsigned long)start_secondary; |
@@ -878,8 +742,6 @@ do_rest: | |||
878 | 742 | ||
879 | pr_debug("Setting warm reset code and vector.\n"); | 743 | pr_debug("Setting warm reset code and vector.\n"); |
880 | 744 | ||
881 | store_NMI_vector(&nmi_high, &nmi_low); | ||
882 | |||
883 | smpboot_setup_warm_reset_vector(start_ip); | 745 | smpboot_setup_warm_reset_vector(start_ip); |
884 | /* | 746 | /* |
885 | * Be paranoid about clearing APIC errors. | 747 | * Be paranoid about clearing APIC errors. |
@@ -891,9 +753,13 @@ do_rest: | |||
891 | } | 753 | } |
892 | 754 | ||
893 | /* | 755 | /* |
894 | * Starting actual IPI sequence... | 756 | * Kick the secondary CPU. Use the method in the APIC driver |
757 | * if it's defined - or use an INIT boot APIC message otherwise: | ||
895 | */ | 758 | */ |
896 | boot_error = wakeup_secondary_cpu(apicid, start_ip); | 759 | if (apic->wakeup_secondary_cpu) |
760 | boot_error = apic->wakeup_secondary_cpu(apicid, start_ip); | ||
761 | else | ||
762 | boot_error = wakeup_secondary_cpu_via_init(apicid, start_ip); | ||
897 | 763 | ||
898 | if (!boot_error) { | 764 | if (!boot_error) { |
899 | /* | 765 | /* |
@@ -927,13 +793,11 @@ do_rest: | |||
927 | else | 793 | else |
928 | /* trampoline code not run */ | 794 | /* trampoline code not run */ |
929 | printk(KERN_ERR "Not responding.\n"); | 795 | printk(KERN_ERR "Not responding.\n"); |
930 | if (get_uv_system_type() != UV_NON_UNIQUE_APIC) | 796 | if (apic->inquire_remote_apic) |
931 | inquire_remote_apic(apicid); | 797 | apic->inquire_remote_apic(apicid); |
932 | } | 798 | } |
933 | } | 799 | } |
934 | #ifdef CONFIG_X86_64 | 800 | |
935 | restore_state: | ||
936 | #endif | ||
937 | if (boot_error) { | 801 | if (boot_error) { |
938 | /* Try to put things back the way they were before ... */ | 802 | /* Try to put things back the way they were before ... */ |
939 | numa_remove_cpu(cpu); /* was set by numa_add_cpu */ | 803 | numa_remove_cpu(cpu); /* was set by numa_add_cpu */ |
@@ -961,7 +825,7 @@ restore_state: | |||
961 | 825 | ||
962 | int __cpuinit native_cpu_up(unsigned int cpu) | 826 | int __cpuinit native_cpu_up(unsigned int cpu) |
963 | { | 827 | { |
964 | int apicid = cpu_present_to_apicid(cpu); | 828 | int apicid = apic->cpu_present_to_apicid(cpu); |
965 | unsigned long flags; | 829 | unsigned long flags; |
966 | int err; | 830 | int err; |
967 | 831 | ||
@@ -1054,14 +918,14 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
1054 | { | 918 | { |
1055 | preempt_disable(); | 919 | preempt_disable(); |
1056 | 920 | ||
1057 | #if defined(CONFIG_X86_PC) && defined(CONFIG_X86_32) | 921 | #if !defined(CONFIG_X86_BIGSMP) && defined(CONFIG_X86_32) |
1058 | if (def_to_bigsmp && nr_cpu_ids > 8) { | 922 | if (def_to_bigsmp && nr_cpu_ids > 8) { |
1059 | unsigned int cpu; | 923 | unsigned int cpu; |
1060 | unsigned nr; | 924 | unsigned nr; |
1061 | 925 | ||
1062 | printk(KERN_WARNING | 926 | printk(KERN_WARNING |
1063 | "More than 8 CPUs detected - skipping them.\n" | 927 | "More than 8 CPUs detected - skipping them.\n" |
1064 | "Use CONFIG_X86_GENERICARCH and CONFIG_X86_BIGSMP.\n"); | 928 | "Use CONFIG_X86_BIGSMP.\n"); |
1065 | 929 | ||
1066 | nr = 0; | 930 | nr = 0; |
1067 | for_each_present_cpu(cpu) { | 931 | for_each_present_cpu(cpu) { |
@@ -1107,7 +971,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
1107 | * Should not be necessary because the MP table should list the boot | 971 | * Should not be necessary because the MP table should list the boot |
1108 | * CPU too, but we do it for the sake of robustness anyway. | 972 | * CPU too, but we do it for the sake of robustness anyway. |
1109 | */ | 973 | */ |
1110 | if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { | 974 | if (!apic->check_phys_apicid_present(boot_cpu_physical_apicid)) { |
1111 | printk(KERN_NOTICE | 975 | printk(KERN_NOTICE |
1112 | "weird, boot CPU (#%d) not listed by the BIOS.\n", | 976 | "weird, boot CPU (#%d) not listed by the BIOS.\n", |
1113 | boot_cpu_physical_apicid); | 977 | boot_cpu_physical_apicid); |
@@ -1125,6 +989,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
1125 | printk(KERN_ERR "... forcing use of dummy APIC emulation." | 989 | printk(KERN_ERR "... forcing use of dummy APIC emulation." |
1126 | "(tell your hw vendor)\n"); | 990 | "(tell your hw vendor)\n"); |
1127 | smpboot_clear_io_apic(); | 991 | smpboot_clear_io_apic(); |
992 | arch_disable_smp_support(); | ||
1128 | return -1; | 993 | return -1; |
1129 | } | 994 | } |
1130 | 995 | ||
@@ -1181,9 +1046,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1181 | current_thread_info()->cpu = 0; /* needed? */ | 1046 | current_thread_info()->cpu = 0; /* needed? */ |
1182 | set_cpu_sibling_map(0); | 1047 | set_cpu_sibling_map(0); |
1183 | 1048 | ||
1184 | #ifdef CONFIG_X86_64 | ||
1185 | enable_IR_x2apic(); | 1049 | enable_IR_x2apic(); |
1186 | setup_apic_routing(); | 1050 | #ifdef CONFIG_X86_64 |
1051 | default_setup_apic_routing(); | ||
1187 | #endif | 1052 | #endif |
1188 | 1053 | ||
1189 | if (smp_sanity_check(max_cpus) < 0) { | 1054 | if (smp_sanity_check(max_cpus) < 0) { |
@@ -1207,18 +1072,18 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
1207 | */ | 1072 | */ |
1208 | setup_local_APIC(); | 1073 | setup_local_APIC(); |
1209 | 1074 | ||
1210 | #ifdef CONFIG_X86_64 | ||
1211 | /* | 1075 | /* |
1212 | * Enable IO APIC before setting up error vector | 1076 | * Enable IO APIC before setting up error vector |
1213 | */ | 1077 | */ |
1214 | if (!skip_ioapic_setup && nr_ioapics) | 1078 | if (!skip_ioapic_setup && nr_ioapics) |
1215 | enable_IO_APIC(); | 1079 | enable_IO_APIC(); |
1216 | #endif | 1080 | |
1217 | end_local_APIC_setup(); | 1081 | end_local_APIC_setup(); |
1218 | 1082 | ||
1219 | map_cpu_to_logical_apicid(); | 1083 | map_cpu_to_logical_apicid(); |
1220 | 1084 | ||
1221 | setup_portio_remap(); | 1085 | if (apic->setup_portio_remap) |
1086 | apic->setup_portio_remap(); | ||
1222 | 1087 | ||
1223 | smpboot_setup_io_apic(); | 1088 | smpboot_setup_io_apic(); |
1224 | /* | 1089 | /* |
@@ -1240,10 +1105,7 @@ out: | |||
1240 | void __init native_smp_prepare_boot_cpu(void) | 1105 | void __init native_smp_prepare_boot_cpu(void) |
1241 | { | 1106 | { |
1242 | int me = smp_processor_id(); | 1107 | int me = smp_processor_id(); |
1243 | #ifdef CONFIG_X86_32 | 1108 | switch_to_new_gdt(me); |
1244 | init_gdt(me); | ||
1245 | #endif | ||
1246 | switch_to_new_gdt(); | ||
1247 | /* already set me in cpu_online_mask in boot_cpu_init() */ | 1109 | /* already set me in cpu_online_mask in boot_cpu_init() */ |
1248 | cpumask_set_cpu(me, cpu_callout_mask); | 1110 | cpumask_set_cpu(me, cpu_callout_mask); |
1249 | per_cpu(cpu_state, me) = CPU_ONLINE; | 1111 | per_cpu(cpu_state, me) = CPU_ONLINE; |
@@ -1254,7 +1116,6 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | |||
1254 | pr_debug("Boot done.\n"); | 1116 | pr_debug("Boot done.\n"); |
1255 | 1117 | ||
1256 | impress_friends(); | 1118 | impress_friends(); |
1257 | smp_checks(); | ||
1258 | #ifdef CONFIG_X86_IO_APIC | 1119 | #ifdef CONFIG_X86_IO_APIC |
1259 | setup_ioapic_dest(); | 1120 | setup_ioapic_dest(); |
1260 | #endif | 1121 | #endif |