X86_64: Place pda first in cpu area. If we move the pda to the beginning of the cpu area then the gs segment will also point to the beginning of the cpu area. After this patch we can use gs on any percpu variable to get to the active processors variable (However, we still need to subtract __per_cpu_start from the address of thee variable). Signed-off-by: Christoph Lameter --- arch/x86/kernel/setup64.c | 2 +- include/asm-generic/vmlinux.lds.h | 1 + include/linux/percpu.h | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) Index: linux-2.6/arch/x86/kernel/setup64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup64.c 2007-11-24 23:23:30.116629291 -0800 +++ linux-2.6/arch/x86/kernel/setup64.c 2007-11-24 23:25:29.260350904 -0800 @@ -31,7 +31,7 @@ cpumask_t cpu_initialized __cpuinitdata struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; EXPORT_SYMBOL(_cpu_pda); -DEFINE_PER_CPU(struct x8664_pda, pda); +DEFINE_PER_CPU_FIRST(struct x8664_pda, pda); EXPORT_PER_CPU_SYMBOL(pda); struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; Index: linux-2.6/include/asm-generic/vmlinux.lds.h =================================================================== --- linux-2.6.orig/include/asm-generic/vmlinux.lds.h 2007-11-24 10:25:35.584850671 -0800 +++ linux-2.6/include/asm-generic/vmlinux.lds.h 2007-11-24 23:27:37.344602062 -0800 @@ -259,6 +259,7 @@ . = ALIGN(align); \ __per_cpu_start = .; \ .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \ + *(.data.percpu.first) \ *(.data.percpu) \ *(.data.percpu.shared_aligned) \ } \ Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h 2007-11-24 23:26:16.160113519 -0800 +++ linux-2.6/include/linux/percpu.h 2007-11-24 23:27:17.521100559 -0800 @@ -23,6 +23,10 @@ DEFINE_PER_CPU(type, name) #endif +#define DEFINE_PER_CPU_FIRST(type, name) \ + __attribute__((__section__(".data.percpu.first"))) \ + __typeof__(type) per_cpu__##name + #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)