diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 76 |
1 files changed, 9 insertions, 67 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index bb1a3b1fc87f..612d3c74f6a3 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -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> |
| @@ -63,6 +62,7 @@ | |||
| 63 | #include <asm/vmi.h> | 62 | #include <asm/vmi.h> |
| 64 | #include <asm/genapic.h> | 63 | #include <asm/genapic.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 <mach_apic.h> |
| @@ -745,52 +745,6 @@ static void __cpuinit do_fork_idle(struct work_struct *work) | |||
| 745 | complete(&c_idle->done); | 745 | complete(&c_idle->done); |
| 746 | } | 746 | } |
| 747 | 747 | ||
| 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) | 748 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
| 795 | /* | 749 | /* |
| 796 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad | 750 | * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad |
| @@ -808,16 +762,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
| 808 | }; | 762 | }; |
| 809 | INIT_WORK(&c_idle.work, do_fork_idle); | 763 | INIT_WORK(&c_idle.work, do_fork_idle); |
| 810 | 764 | ||
| 811 | #ifdef CONFIG_X86_64 | ||
| 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 | |||
| 821 | alternatives_smp_switch(1); | 765 | alternatives_smp_switch(1); |
| 822 | 766 | ||
| 823 | c_idle.idle = get_idle_for_cpu(cpu); | 767 | c_idle.idle = get_idle_for_cpu(cpu); |
| @@ -847,14 +791,16 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) | |||
| 847 | 791 | ||
| 848 | set_idle_for_cpu(cpu, c_idle.idle); | 792 | set_idle_for_cpu(cpu, c_idle.idle); |
| 849 | do_rest: | 793 | do_rest: |
| 850 | #ifdef CONFIG_X86_32 | ||
| 851 | per_cpu(current_task, cpu) = c_idle.idle; | 794 | per_cpu(current_task, cpu) = c_idle.idle; |
| 852 | init_gdt(cpu); | 795 | #ifdef CONFIG_X86_32 |
| 853 | /* Stack for startup_32 can be just as for start_secondary onwards */ | 796 | /* Stack for startup_32 can be just as for start_secondary onwards */ |
| 854 | irq_ctx_init(cpu); | 797 | irq_ctx_init(cpu); |
| 855 | #else | 798 | #else |
| 856 | cpu_pda(cpu)->pcurrent = c_idle.idle; | ||
| 857 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); | 799 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
| 800 | initial_gs = per_cpu_offset(cpu); | ||
| 801 | per_cpu(kernel_stack, cpu) = | ||
| 802 | (unsigned long)task_stack_page(c_idle.idle) - | ||
| 803 | KERNEL_STACK_OFFSET + THREAD_SIZE; | ||
| 858 | #endif | 804 | #endif |
| 859 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 805 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
| 860 | initial_code = (unsigned long)start_secondary; | 806 | initial_code = (unsigned long)start_secondary; |
| @@ -931,9 +877,7 @@ do_rest: | |||
| 931 | inquire_remote_apic(apicid); | 877 | inquire_remote_apic(apicid); |
| 932 | } | 878 | } |
| 933 | } | 879 | } |
| 934 | #ifdef CONFIG_X86_64 | 880 | |
| 935 | restore_state: | ||
| 936 | #endif | ||
| 937 | if (boot_error) { | 881 | if (boot_error) { |
| 938 | /* Try to put things back the way they were before ... */ | 882 | /* Try to put things back the way they were before ... */ |
| 939 | numa_remove_cpu(cpu); /* was set by numa_add_cpu */ | 883 | numa_remove_cpu(cpu); /* was set by numa_add_cpu */ |
| @@ -1125,6 +1069,7 @@ static int __init smp_sanity_check(unsigned max_cpus) | |||
| 1125 | printk(KERN_ERR "... forcing use of dummy APIC emulation." | 1069 | printk(KERN_ERR "... forcing use of dummy APIC emulation." |
| 1126 | "(tell your hw vendor)\n"); | 1070 | "(tell your hw vendor)\n"); |
| 1127 | smpboot_clear_io_apic(); | 1071 | smpboot_clear_io_apic(); |
| 1072 | disable_ioapic_setup(); | ||
| 1128 | return -1; | 1073 | return -1; |
| 1129 | } | 1074 | } |
| 1130 | 1075 | ||
| @@ -1240,10 +1185,7 @@ out: | |||
| 1240 | void __init native_smp_prepare_boot_cpu(void) | 1185 | void __init native_smp_prepare_boot_cpu(void) |
| 1241 | { | 1186 | { |
| 1242 | int me = smp_processor_id(); | 1187 | int me = smp_processor_id(); |
| 1243 | #ifdef CONFIG_X86_32 | 1188 | 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() */ | 1189 | /* already set me in cpu_online_mask in boot_cpu_init() */ |
| 1248 | cpumask_set_cpu(me, cpu_callout_mask); | 1190 | cpumask_set_cpu(me, cpu_callout_mask); |
| 1249 | per_cpu(cpu_state, me) = CPU_ONLINE; | 1191 | per_cpu(cpu_state, me) = CPU_ONLINE; |
