aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/common.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-02-09 06:16:59 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-09 06:16:59 -0500
commiteca217b36e5d7d4377493d5cedd89105e66a5a72 (patch)
tree71f0ecd5225c3033d509b77a23ad7bc576cf0ab6 /arch/x86/kernel/cpu/common.c
parent54a353a0f845c1dad5fc8183872e750d667838ac (diff)
parente4d0407185cdbdcfd99fc23bde2e5454bbc46329 (diff)
Merge branch 'x86/paravirt' into x86/apic
Conflicts: arch/x86/mach-voyager/voyager_smp.c
Diffstat (limited to 'arch/x86/kernel/cpu/common.c')
-rw-r--r--arch/x86/kernel/cpu/common.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index c4bdc7f00207..cbcdb796d47f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -296,23 +296,28 @@ static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c)
296 296
297__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata; 297__u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
298 298
299void load_percpu_segment(int cpu)
300{
301#ifdef CONFIG_X86_32
302 loadsegment(fs, __KERNEL_PERCPU);
303#else
304 loadsegment(gs, 0);
305 wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
306#endif
307}
308
299/* Current gdt points %fs at the "master" per-cpu area: after this, 309/* Current gdt points %fs at the "master" per-cpu area: after this,
300 * it's on the real one. */ 310 * it's on the real one. */
301void switch_to_new_gdt(void) 311void switch_to_new_gdt(int cpu)
302{ 312{
303 struct desc_ptr gdt_descr; 313 struct desc_ptr gdt_descr;
304 int cpu = smp_processor_id();
305 314
306 gdt_descr.address = (long)get_cpu_gdt_table(cpu); 315 gdt_descr.address = (long)get_cpu_gdt_table(cpu);
307 gdt_descr.size = GDT_SIZE - 1; 316 gdt_descr.size = GDT_SIZE - 1;
308 load_gdt(&gdt_descr); 317 load_gdt(&gdt_descr);
309 /* Reload the per-cpu base */ 318 /* Reload the per-cpu base */
310#ifdef CONFIG_X86_32 319
311 loadsegment(fs, __KERNEL_PERCPU); 320 load_percpu_segment(cpu);
312#else
313 loadsegment(gs, 0);
314 wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
315#endif
316} 321}
317 322
318static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {}; 323static struct cpu_dev *cpu_devs[X86_VENDOR_NUM] = {};
@@ -1029,7 +1034,7 @@ void __cpuinit cpu_init(void)
1029 * and set up the GDT descriptor: 1034 * and set up the GDT descriptor:
1030 */ 1035 */
1031 1036
1032 switch_to_new_gdt(); 1037 switch_to_new_gdt(cpu);
1033 loadsegment(fs, 0); 1038 loadsegment(fs, 0);
1034 1039
1035 load_idt((const struct desc_ptr *)&idt_descr); 1040 load_idt((const struct desc_ptr *)&idt_descr);
@@ -1131,7 +1136,7 @@ void __cpuinit cpu_init(void)
1131 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); 1136 clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
1132 1137
1133 load_idt(&idt_descr); 1138 load_idt(&idt_descr);
1134 switch_to_new_gdt(); 1139 switch_to_new_gdt(cpu);
1135 1140
1136 /* 1141 /*
1137 * Set up and load the per-CPU TSS and LDT 1142 * Set up and load the per-CPU TSS and LDT