X86_64: Place pda first in per 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 or cpu_alloc pointer from cpu 0 to get to the active processors variable. Signed-off-by: Christoph Lameter --- arch/x86/kernel/setup64.c | 2 +- include/asm-generic/vmlinux.lds.h | 1 + include/asm-x86/percpu_64.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-17 17:51:09.501272488 -0800 +++ linux-2.6/arch/x86/kernel/setup64.c 2007-11-17 17:54:34.364772627 -0800 @@ -31,7 +31,7 @@ cpumask_t cpu_initialized __cpuinitdata struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; EXPORT_SYMBOL(_cpu_pda); -static DEFINE_PER_CPU(struct x8664_pda, pda); +static DEFINE_PER_CPU_FIRST(struct x8664_pda, 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-17 16:47:28.448534465 -0800 +++ linux-2.6/include/asm-generic/vmlinux.lds.h 2007-11-17 17:54:34.380772664 -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/asm-x86/percpu_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/percpu_64.h 2007-11-17 16:47:28.456534566 -0800 +++ linux-2.6/include/asm-x86/percpu_64.h 2007-11-17 17:54:34.413272672 -0800 @@ -25,6 +25,10 @@ __typeof__(type) per_cpu__##name \ ____cacheline_internodealigned_in_smp +#define DEFINE_PER_CPU_FIRST(type, name) \ + __attribute__((__section__(".data.percpu.first"))) \ + __typeof__(type) per_cpu__##name + /* var is in discarded region: offset to particular copy we want */ #define per_cpu(var, cpu) (*({ \ extern int simple_identifier_##var(void); \