diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 8689d62abd4adc66729c5a58185612ddfd6271d6..8a8bbdaaf38aba279fa3df1672f05a0cdc5253cb 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -710,11 +710,8 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle) return 1; } -/* Common CPU init for both boot and secondary CPUs */ -static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +void __cpuinit cpu_set_gdt(int cpu) { - struct tss_struct * t = &per_cpu(init_tss, cpu); - struct thread_struct *thread = &curr->thread; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); /* Reinit these anyway, even if they've already been done (on @@ -722,6 +719,13 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) the real ones). */ load_gdt(cpu_gdt_descr); set_kernel_gs(); +} + +/* Common CPU init for both boot and secondary CPUs */ +static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +{ + struct tss_struct * t = &per_cpu(init_tss, cpu); + struct thread_struct *thread = &curr->thread; if (cpu_test_and_set(cpu, cpu_initialized)) { printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); @@ -807,6 +811,7 @@ void __cpuinit cpu_init(void) local_irq_enable(); } + cpu_set_gdt(cpu); _cpu_init(cpu, curr); } diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index dea7ef9d3e82804ea6b87089cafd88c435223113..8c6c8c52b95c0b574b837c279f84647d3b4ba867 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -595,6 +595,12 @@ static void __cpuinit start_secondary(void *unused) */ void __devinit initialize_secondary(void) { + /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. @@ -972,9 +978,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) /* Stack for startup_32 can be just as for start_secondary onwards */ stack_start.esp = (void *) idle->thread.esp; - start_pda = cpu_pda(cpu); - cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu); - irq_ctx_init(cpu); x86_cpu_to_apicid[cpu] = apicid; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index 55428e656a3f9a90bddcb50770e92e7434fab16c..74aeedf277f424896c1beaf01580468ecfbe90b5 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -772,6 +772,12 @@ initialize_secondary(void) set_current(hard_get_current()); #endif + /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index a52d65440429b99520ff6fa355ccd95d92611619..359f10b54f59ba7c99297dac910b73e4c0406796 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -743,6 +743,7 @@ extern void enable_sep_cpu(void); extern int sysenter_setup(void); extern int init_gdt(int cpu, struct task_struct *idle); +extern void cpu_set_gdt(int); extern void secondary_cpu_init(void); #endif /* __ASM_I386_PROCESSOR_H */