diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 8689d62abd4ad..8a8bbdaaf38ab 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 dea7ef9d3e828..8c6c8c52b95c0 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 55428e656a3f9..74aeedf277f42 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 a52d65440429b..359f10b54f59b 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 */