diff options
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r-- | arch/i386/kernel/smpboot.c | 146 |
1 files changed, 65 insertions, 81 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 4ff55e675576..a4b7ad283f49 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -53,13 +53,12 @@ | |||
53 | #include <asm/desc.h> | 53 | #include <asm/desc.h> |
54 | #include <asm/arch_hooks.h> | 54 | #include <asm/arch_hooks.h> |
55 | #include <asm/nmi.h> | 55 | #include <asm/nmi.h> |
56 | #include <asm/pda.h> | ||
57 | #include <asm/genapic.h> | ||
58 | 56 | ||
59 | #include <mach_apic.h> | 57 | #include <mach_apic.h> |
60 | #include <mach_wakecpu.h> | 58 | #include <mach_wakecpu.h> |
61 | #include <smpboot_hooks.h> | 59 | #include <smpboot_hooks.h> |
62 | #include <asm/vmi.h> | 60 | #include <asm/vmi.h> |
61 | #include <asm/mtrr.h> | ||
63 | 62 | ||
64 | /* Set if we find a B stepping CPU */ | 63 | /* Set if we find a B stepping CPU */ |
65 | static int __devinitdata smp_b_stepping; | 64 | static int __devinitdata smp_b_stepping; |
@@ -100,6 +99,9 @@ EXPORT_SYMBOL(x86_cpu_to_apicid); | |||
100 | 99 | ||
101 | u8 apicid_2_node[MAX_APICID]; | 100 | u8 apicid_2_node[MAX_APICID]; |
102 | 101 | ||
102 | DEFINE_PER_CPU(unsigned long, this_cpu_off); | ||
103 | EXPORT_PER_CPU_SYMBOL(this_cpu_off); | ||
104 | |||
103 | /* | 105 | /* |
104 | * Trampoline 80x86 program as an array. | 106 | * Trampoline 80x86 program as an array. |
105 | */ | 107 | */ |
@@ -156,7 +158,7 @@ static void __cpuinit smp_store_cpu_info(int id) | |||
156 | 158 | ||
157 | *c = boot_cpu_data; | 159 | *c = boot_cpu_data; |
158 | if (id!=0) | 160 | if (id!=0) |
159 | identify_cpu(c); | 161 | identify_secondary_cpu(c); |
160 | /* | 162 | /* |
161 | * Mask B, Pentium, but not Pentium MMX | 163 | * Mask B, Pentium, but not Pentium MMX |
162 | */ | 164 | */ |
@@ -379,14 +381,14 @@ set_cpu_sibling_map(int cpu) | |||
379 | static void __cpuinit start_secondary(void *unused) | 381 | static void __cpuinit start_secondary(void *unused) |
380 | { | 382 | { |
381 | /* | 383 | /* |
382 | * Don't put *anything* before secondary_cpu_init(), SMP | 384 | * Don't put *anything* before cpu_init(), SMP booting is too |
383 | * booting is too fragile that we want to limit the | 385 | * fragile that we want to limit the things done here to the |
384 | * things done here to the most necessary things. | 386 | * most necessary things. |
385 | */ | 387 | */ |
386 | #ifdef CONFIG_VMI | 388 | #ifdef CONFIG_VMI |
387 | vmi_bringup(); | 389 | vmi_bringup(); |
388 | #endif | 390 | #endif |
389 | secondary_cpu_init(); | 391 | cpu_init(); |
390 | preempt_disable(); | 392 | preempt_disable(); |
391 | smp_callin(); | 393 | smp_callin(); |
392 | while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) | 394 | while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) |
@@ -441,12 +443,6 @@ static void __cpuinit start_secondary(void *unused) | |||
441 | void __devinit initialize_secondary(void) | 443 | void __devinit initialize_secondary(void) |
442 | { | 444 | { |
443 | /* | 445 | /* |
444 | * switch to the per CPU GDT we already set up | ||
445 | * in do_boot_cpu() | ||
446 | */ | ||
447 | cpu_set_gdt(current_thread_info()->cpu); | ||
448 | |||
449 | /* | ||
450 | * We don't actually need to load the full TSS, | 446 | * We don't actually need to load the full TSS, |
451 | * basically just the stack pointer and the eip. | 447 | * basically just the stack pointer and the eip. |
452 | */ | 448 | */ |
@@ -463,7 +459,6 @@ extern struct { | |||
463 | void * esp; | 459 | void * esp; |
464 | unsigned short ss; | 460 | unsigned short ss; |
465 | } stack_start; | 461 | } stack_start; |
466 | extern struct i386_pda *start_pda; | ||
467 | 462 | ||
468 | #ifdef CONFIG_NUMA | 463 | #ifdef CONFIG_NUMA |
469 | 464 | ||
@@ -521,12 +516,12 @@ static void unmap_cpu_to_logical_apicid(int cpu) | |||
521 | unmap_cpu_to_node(cpu); | 516 | unmap_cpu_to_node(cpu); |
522 | } | 517 | } |
523 | 518 | ||
524 | #if APIC_DEBUG | ||
525 | static inline void __inquire_remote_apic(int apicid) | 519 | static inline void __inquire_remote_apic(int apicid) |
526 | { | 520 | { |
527 | int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; | 521 | int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; |
528 | char *names[] = { "ID", "VERSION", "SPIV" }; | 522 | char *names[] = { "ID", "VERSION", "SPIV" }; |
529 | int timeout, status; | 523 | int timeout; |
524 | unsigned long status; | ||
530 | 525 | ||
531 | printk("Inquiring remote APIC #%d...\n", apicid); | 526 | printk("Inquiring remote APIC #%d...\n", apicid); |
532 | 527 | ||
@@ -536,7 +531,9 @@ static inline void __inquire_remote_apic(int apicid) | |||
536 | /* | 531 | /* |
537 | * Wait for idle. | 532 | * Wait for idle. |
538 | */ | 533 | */ |
539 | apic_wait_icr_idle(); | 534 | status = safe_apic_wait_icr_idle(); |
535 | if (status) | ||
536 | printk("a previous APIC delivery may have failed\n"); | ||
540 | 537 | ||
541 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); | 538 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); |
542 | apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); | 539 | apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); |
@@ -550,14 +547,13 @@ static inline void __inquire_remote_apic(int apicid) | |||
550 | switch (status) { | 547 | switch (status) { |
551 | case APIC_ICR_RR_VALID: | 548 | case APIC_ICR_RR_VALID: |
552 | status = apic_read(APIC_RRR); | 549 | status = apic_read(APIC_RRR); |
553 | printk("%08x\n", status); | 550 | printk("%lx\n", status); |
554 | break; | 551 | break; |
555 | default: | 552 | default: |
556 | printk("failed\n"); | 553 | printk("failed\n"); |
557 | } | 554 | } |
558 | } | 555 | } |
559 | } | 556 | } |
560 | #endif | ||
561 | 557 | ||
562 | #ifdef WAKE_SECONDARY_VIA_NMI | 558 | #ifdef WAKE_SECONDARY_VIA_NMI |
563 | /* | 559 | /* |
@@ -568,8 +564,8 @@ static inline void __inquire_remote_apic(int apicid) | |||
568 | static int __devinit | 564 | static int __devinit |
569 | wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | 565 | wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) |
570 | { | 566 | { |
571 | unsigned long send_status = 0, accept_status = 0; | 567 | unsigned long send_status, accept_status = 0; |
572 | int timeout, maxlvt; | 568 | int maxlvt; |
573 | 569 | ||
574 | /* Target chip */ | 570 | /* Target chip */ |
575 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); | 571 | apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); |
@@ -579,12 +575,7 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | |||
579 | apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); | 575 | apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); |
580 | 576 | ||
581 | Dprintk("Waiting for send to finish...\n"); | 577 | Dprintk("Waiting for send to finish...\n"); |
582 | timeout = 0; | 578 | send_status = safe_apic_wait_icr_idle(); |
583 | do { | ||
584 | Dprintk("+"); | ||
585 | udelay(100); | ||
586 | send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; | ||
587 | } while (send_status && (timeout++ < 1000)); | ||
588 | 579 | ||
589 | /* | 580 | /* |
590 | * Give the other CPU some time to accept the IPI. | 581 | * Give the other CPU some time to accept the IPI. |
@@ -614,8 +605,8 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) | |||
614 | static int __devinit | 605 | static int __devinit |
615 | wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | 606 | wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) |
616 | { | 607 | { |
617 | unsigned long send_status = 0, accept_status = 0; | 608 | unsigned long send_status, accept_status = 0; |
618 | int maxlvt, timeout, num_starts, j; | 609 | int maxlvt, num_starts, j; |
619 | 610 | ||
620 | /* | 611 | /* |
621 | * Be paranoid about clearing APIC errors. | 612 | * Be paranoid about clearing APIC errors. |
@@ -640,12 +631,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
640 | | APIC_DM_INIT); | 631 | | APIC_DM_INIT); |
641 | 632 | ||
642 | Dprintk("Waiting for send to finish...\n"); | 633 | Dprintk("Waiting for send to finish...\n"); |
643 | timeout = 0; | 634 | send_status = safe_apic_wait_icr_idle(); |
644 | do { | ||
645 | Dprintk("+"); | ||
646 | udelay(100); | ||
647 | send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; | ||
648 | } while (send_status && (timeout++ < 1000)); | ||
649 | 635 | ||
650 | mdelay(10); | 636 | mdelay(10); |
651 | 637 | ||
@@ -658,12 +644,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
658 | apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); | 644 | apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); |
659 | 645 | ||
660 | Dprintk("Waiting for send to finish...\n"); | 646 | Dprintk("Waiting for send to finish...\n"); |
661 | timeout = 0; | 647 | send_status = safe_apic_wait_icr_idle(); |
662 | do { | ||
663 | Dprintk("+"); | ||
664 | udelay(100); | ||
665 | send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; | ||
666 | } while (send_status && (timeout++ < 1000)); | ||
667 | 648 | ||
668 | atomic_set(&init_deasserted, 1); | 649 | atomic_set(&init_deasserted, 1); |
669 | 650 | ||
@@ -719,12 +700,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | |||
719 | Dprintk("Startup point 1.\n"); | 700 | Dprintk("Startup point 1.\n"); |
720 | 701 | ||
721 | Dprintk("Waiting for send to finish...\n"); | 702 | Dprintk("Waiting for send to finish...\n"); |
722 | timeout = 0; | 703 | send_status = safe_apic_wait_icr_idle(); |
723 | do { | ||
724 | Dprintk("+"); | ||
725 | udelay(100); | ||
726 | send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; | ||
727 | } while (send_status && (timeout++ < 1000)); | ||
728 | 704 | ||
729 | /* | 705 | /* |
730 | * Give the other CPU some time to accept the IPI. | 706 | * Give the other CPU some time to accept the IPI. |
@@ -788,6 +764,25 @@ static inline struct task_struct * alloc_idle_task(int cpu) | |||
788 | #define alloc_idle_task(cpu) fork_idle(cpu) | 764 | #define alloc_idle_task(cpu) fork_idle(cpu) |
789 | #endif | 765 | #endif |
790 | 766 | ||
767 | /* Initialize the CPU's GDT. This is either the boot CPU doing itself | ||
768 | (still using the master per-cpu area), or a CPU doing it for a | ||
769 | secondary which will soon come up. */ | ||
770 | static __cpuinit void init_gdt(int cpu) | ||
771 | { | ||
772 | struct desc_struct *gdt = get_cpu_gdt_table(cpu); | ||
773 | |||
774 | pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, | ||
775 | (u32 *)&gdt[GDT_ENTRY_PERCPU].b, | ||
776 | __per_cpu_offset[cpu], 0xFFFFF, | ||
777 | 0x80 | DESCTYPE_S | 0x2, 0x8); | ||
778 | |||
779 | per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; | ||
780 | per_cpu(cpu_number, cpu) = cpu; | ||
781 | } | ||
782 | |||
783 | /* Defined in head.S */ | ||
784 | extern struct Xgt_desc_struct early_gdt_descr; | ||
785 | |||
791 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | 786 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
792 | /* | 787 | /* |
793 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 788 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
@@ -802,6 +797,12 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
802 | unsigned short nmi_high = 0, nmi_low = 0; | 797 | unsigned short nmi_high = 0, nmi_low = 0; |
803 | 798 | ||
804 | /* | 799 | /* |
800 | * Save current MTRR state in case it was changed since early boot | ||
801 | * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: | ||
802 | */ | ||
803 | mtrr_save_state(); | ||
804 | |||
805 | /* | ||
805 | * We can't use kernel_thread since we must avoid to | 806 | * We can't use kernel_thread since we must avoid to |
806 | * reschedule the child. | 807 | * reschedule the child. |
807 | */ | 808 | */ |
@@ -809,13 +810,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
809 | if (IS_ERR(idle)) | 810 | if (IS_ERR(idle)) |
810 | panic("failed fork for CPU %d", cpu); | 811 | panic("failed fork for CPU %d", cpu); |
811 | 812 | ||
812 | /* Pre-allocate and initialize the CPU's GDT and PDA so it | 813 | init_gdt(cpu); |
813 | doesn't have to do any memory allocation during the | 814 | per_cpu(current_task, cpu) = idle; |
814 | delicate CPU-bringup phase. */ | 815 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
815 | if (!init_gdt(cpu, idle)) { | ||
816 | printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); | ||
817 | return -1; /* ? */ | ||
818 | } | ||
819 | 816 | ||
820 | idle->thread.eip = (unsigned long) start_secondary; | 817 | idle->thread.eip = (unsigned long) start_secondary; |
821 | /* start_eip had better be page-aligned! */ | 818 | /* start_eip had better be page-aligned! */ |
@@ -941,7 +938,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) | |||
941 | DECLARE_COMPLETION_ONSTACK(done); | 938 | DECLARE_COMPLETION_ONSTACK(done); |
942 | struct warm_boot_cpu_info info; | 939 | struct warm_boot_cpu_info info; |
943 | int apicid, ret; | 940 | int apicid, ret; |
944 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
945 | 941 | ||
946 | apicid = x86_cpu_to_apicid[cpu]; | 942 | apicid = x86_cpu_to_apicid[cpu]; |
947 | if (apicid == BAD_APICID) { | 943 | if (apicid == BAD_APICID) { |
@@ -949,18 +945,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) | |||
949 | goto exit; | 945 | goto exit; |
950 | } | 946 | } |
951 | 947 | ||
952 | /* | ||
953 | * the CPU isn't initialized at boot time, allocate gdt table here. | ||
954 | * cpu_init will initialize it | ||
955 | */ | ||
956 | if (!cpu_gdt_descr->address) { | ||
957 | cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); | ||
958 | if (!cpu_gdt_descr->address) | ||
959 | printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); | ||
960 | ret = -ENOMEM; | ||
961 | goto exit; | ||
962 | } | ||
963 | |||
964 | info.complete = &done; | 948 | info.complete = &done; |
965 | info.apicid = apicid; | 949 | info.apicid = apicid; |
966 | info.cpu = cpu; | 950 | info.cpu = cpu; |
@@ -1173,7 +1157,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
1173 | 1157 | ||
1174 | /* These are wrappers to interface to the new boot process. Someone | 1158 | /* These are wrappers to interface to the new boot process. Someone |
1175 | who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ | 1159 | who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ |
1176 | void __init smp_prepare_cpus(unsigned int max_cpus) | 1160 | void __init native_smp_prepare_cpus(unsigned int max_cpus) |
1177 | { | 1161 | { |
1178 | smp_commenced_mask = cpumask_of_cpu(0); | 1162 | smp_commenced_mask = cpumask_of_cpu(0); |
1179 | cpu_callin_map = cpumask_of_cpu(0); | 1163 | cpu_callin_map = cpumask_of_cpu(0); |
@@ -1181,13 +1165,18 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1181 | smp_boot_cpus(max_cpus); | 1165 | smp_boot_cpus(max_cpus); |
1182 | } | 1166 | } |
1183 | 1167 | ||
1184 | void __devinit smp_prepare_boot_cpu(void) | 1168 | void __init native_smp_prepare_boot_cpu(void) |
1185 | { | 1169 | { |
1186 | cpu_set(smp_processor_id(), cpu_online_map); | 1170 | unsigned int cpu = smp_processor_id(); |
1187 | cpu_set(smp_processor_id(), cpu_callout_map); | 1171 | |
1188 | cpu_set(smp_processor_id(), cpu_present_map); | 1172 | init_gdt(cpu); |
1189 | cpu_set(smp_processor_id(), cpu_possible_map); | 1173 | switch_to_new_gdt(); |
1190 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 1174 | |
1175 | cpu_set(cpu, cpu_online_map); | ||
1176 | cpu_set(cpu, cpu_callout_map); | ||
1177 | cpu_set(cpu, cpu_present_map); | ||
1178 | cpu_set(cpu, cpu_possible_map); | ||
1179 | __get_cpu_var(cpu_state) = CPU_ONLINE; | ||
1191 | } | 1180 | } |
1192 | 1181 | ||
1193 | #ifdef CONFIG_HOTPLUG_CPU | 1182 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -1277,7 +1266,7 @@ void __cpu_die(unsigned int cpu) | |||
1277 | } | 1266 | } |
1278 | #endif /* CONFIG_HOTPLUG_CPU */ | 1267 | #endif /* CONFIG_HOTPLUG_CPU */ |
1279 | 1268 | ||
1280 | int __cpuinit __cpu_up(unsigned int cpu) | 1269 | int __cpuinit native_cpu_up(unsigned int cpu) |
1281 | { | 1270 | { |
1282 | unsigned long flags; | 1271 | unsigned long flags; |
1283 | #ifdef CONFIG_HOTPLUG_CPU | 1272 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -1319,15 +1308,10 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
1319 | touch_nmi_watchdog(); | 1308 | touch_nmi_watchdog(); |
1320 | } | 1309 | } |
1321 | 1310 | ||
1322 | #ifdef CONFIG_X86_GENERICARCH | ||
1323 | if (num_online_cpus() > 8 && genapic == &apic_default) | ||
1324 | panic("Default flat APIC routing can't be used with > 8 cpus\n"); | ||
1325 | #endif | ||
1326 | |||
1327 | return 0; | 1311 | return 0; |
1328 | } | 1312 | } |
1329 | 1313 | ||
1330 | void __init smp_cpus_done(unsigned int max_cpus) | 1314 | void __init native_smp_cpus_done(unsigned int max_cpus) |
1331 | { | 1315 | { |
1332 | #ifdef CONFIG_X86_IO_APIC | 1316 | #ifdef CONFIG_X86_IO_APIC |
1333 | setup_ioapic_dest(); | 1317 | setup_ioapic_dest(); |