|
@@ -638,6 +638,18 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
|
|
|
return regs;
|
|
|
}
|
|
|
|
|
|
+/* Current gdt points %fs at the "master" per-cpu area: after this,
|
|
|
+ * it's on the real one. */
|
|
|
+void switch_to_new_gdt(void)
|
|
|
+{
|
|
|
+ struct Xgt_desc_struct gdt_descr;
|
|
|
+
|
|
|
+ gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
|
|
|
+ gdt_descr.size = GDT_SIZE - 1;
|
|
|
+ load_gdt(&gdt_descr);
|
|
|
+ asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* cpu_init() initializes state that is per-CPU. Some data is already
|
|
|
* initialized (naturally) in the bootstrap process, such as the GDT
|
|
@@ -668,6 +680,7 @@ void __cpuinit cpu_init(void)
|
|
|
}
|
|
|
|
|
|
load_idt(&idt_descr);
|
|
|
+ switch_to_new_gdt();
|
|
|
|
|
|
/*
|
|
|
* Set up and load the per-CPU TSS and LDT
|