Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-block.git] / arch / x86 / kernel / cpu / common.c
index 10e5ccfa9278025c3a04ecbbd94e3e2cfe7a1583..0b99a7fae6be8a7dae6f3c045f3b8f76abaccb86 100644 (file)
@@ -1669,6 +1669,29 @@ static void wait_for_master_cpu(int cpu)
 #endif
 }
 
+#ifdef CONFIG_X86_64
+static void setup_getcpu(int cpu)
+{
+       unsigned long cpudata = vdso_encode_cpunode(cpu, early_cpu_to_node(cpu));
+       struct desc_struct d = { };
+
+       if (static_cpu_has(X86_FEATURE_RDTSCP))
+               write_rdtscp_aux(cpudata);
+
+       /* Store CPU and node number in limit. */
+       d.limit0 = cpudata;
+       d.limit1 = cpudata >> 16;
+
+       d.type = 5;             /* RO data, expand down, accessed */
+       d.dpl = 3;              /* Visible to user code */
+       d.s = 1;                /* Not a system segment */
+       d.p = 1;                /* Present */
+       d.d = 1;                /* 32-bit */
+
+       write_gdt_entry(get_cpu_gdt_rw(cpu), GDT_ENTRY_CPUNODE, &d, DESCTYPE_S);
+}
+#endif
+
 /*
  * cpu_init() initializes state that is per-CPU. Some data is already
  * initialized (naturally) in the bootstrap process, such as the GDT
@@ -1706,6 +1729,7 @@ void cpu_init(void)
            early_cpu_to_node(cpu) != NUMA_NO_NODE)
                set_numa_node(early_cpu_to_node(cpu));
 #endif
+       setup_getcpu(cpu);
 
        me = current;