[PATCH] x86: fix PDA variables to work during boot

The current PDA code, which went in in post 2.6.19 has a flaw in that it
doesn't correctly cycle the GDT and %GS segment through the boot PDA,
the CPU PDA and finally the per-cpu PDA.

The bug generally doesn't show up if the boot CPU id is zero, but
everything falls apart for a non zero boot CPU id. The basically kills
voyager which is perfectly capable of doing non zero CPU id boots, so
voyager currently won't boot without this.

The fix is to be careful and actually do the GDT setups correctly.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by James Bottomley and committed by Linus Torvalds 9ee79a3d ebcccd14

+22 -7
+9 -4
arch/i386/kernel/cpu/common.c
··· 710 710 return 1; 711 711 } 712 712 713 - /* Common CPU init for both boot and secondary CPUs */ 714 - static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) 713 + void __cpuinit cpu_set_gdt(int cpu) 715 714 { 716 - struct tss_struct * t = &per_cpu(init_tss, cpu); 717 - struct thread_struct *thread = &curr->thread; 718 715 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); 719 716 720 717 /* Reinit these anyway, even if they've already been done (on ··· 719 722 the real ones). */ 720 723 load_gdt(cpu_gdt_descr); 721 724 set_kernel_gs(); 725 + } 726 + 727 + /* Common CPU init for both boot and secondary CPUs */ 728 + static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) 729 + { 730 + struct tss_struct * t = &per_cpu(init_tss, cpu); 731 + struct thread_struct *thread = &curr->thread; 722 732 723 733 if (cpu_test_and_set(cpu, cpu_initialized)) { 724 734 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); ··· 811 807 local_irq_enable(); 812 808 } 813 809 810 + cpu_set_gdt(cpu); 814 811 _cpu_init(cpu, curr); 815 812 } 816 813
+6 -3
arch/i386/kernel/smpboot.c
··· 596 596 void __devinit initialize_secondary(void) 597 597 { 598 598 /* 599 + * switch to the per CPU GDT we already set up 600 + * in do_boot_cpu() 601 + */ 602 + cpu_set_gdt(current_thread_info()->cpu); 603 + 604 + /* 599 605 * We don't actually need to load the full TSS, 600 606 * basically just the stack pointer and the eip. 601 607 */ ··· 977 971 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); 978 972 /* Stack for startup_32 can be just as for start_secondary onwards */ 979 973 stack_start.esp = (void *) idle->thread.esp; 980 - 981 - start_pda = cpu_pda(cpu); 982 - cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu); 983 974 984 975 irq_ctx_init(cpu); 985 976
+6
arch/i386/mach-voyager/voyager_smp.c
··· 773 773 #endif 774 774 775 775 /* 776 + * switch to the per CPU GDT we already set up 777 + * in do_boot_cpu() 778 + */ 779 + cpu_set_gdt(current_thread_info()->cpu); 780 + 781 + /* 776 782 * We don't actually need to load the full TSS, 777 783 * basically just the stack pointer and the eip. 778 784 */
+1
include/asm-i386/processor.h
··· 743 743 extern int sysenter_setup(void); 744 744 745 745 extern int init_gdt(int cpu, struct task_struct *idle); 746 + extern void cpu_set_gdt(int); 746 747 extern void secondary_cpu_init(void); 747 748 748 749 #endif /* __ASM_I386_PROCESSOR_H */