--- arch/x86/kernel/setup64.c | 4 ++-- arch/x86/kernel/vmlinux_64.lds.S | 2 +- include/asm-x86/percpu_64.h | 5 ++++- include/linux/percpu.h | 9 +++++---- mm/cpu_alloc.c | 13 ++++++------- 5 files changed, 18 insertions(+), 15 deletions(-) Index: linux-2.6/arch/x86/kernel/vmlinux_64.lds.S =================================================================== --- linux-2.6.orig/arch/x86/kernel/vmlinux_64.lds.S 2007-11-18 09:20:11.281533168 -0800 +++ linux-2.6/arch/x86/kernel/vmlinux_64.lds.S 2007-11-18 09:20:25.861311037 -0800 @@ -205,7 +205,7 @@ SECTIONS __initramfs_end = .; #endif - FIXED_ADDR_PERCPU(CPU_AREA_BASE, 4096) + FIXED_ADDR_PERCPU(0, 4096) . = ALIGN(4096); __init_end = .; Index: linux-2.6/include/linux/percpu.h =================================================================== --- linux-2.6.orig/include/linux/percpu.h 2007-11-18 09:20:11.285533096 -0800 +++ linux-2.6/include/linux/percpu.h 2007-11-18 09:20:25.861311037 -0800 @@ -66,18 +66,19 @@ DECLARE_PER_CPU(cpumask_t, cpu_mask); * handled from an interrupt context). */ +#define __CPU_OFFSET(__cpu) \ + (CPU_AREA_BASE + ((unsigned long)(__cpu) << (CONFIG_CPU_AREA_ORDER + PAGE_SHIFT))) + #ifdef CONFIG_DEBUG_VM #define CPU_OFFSET(__cpu) ({ \ BUG_ON(!cpu_isset((__cpu), cpu_possible_map)); \ if (system_state == SYSTEM_RUNNING) \ WARN_ON(!cpu_isset((__cpu), cpu_online_map)); \ - (((unsigned long)(__cpu) << \ - (CONFIG_CPU_AREA_ORDER + PAGE_SHIFT))); \ + (__CPU_OFFSET(__cpu)); \ }) #else -#define CPU_OFFSET(__cpu) \ - ((unsigned long)(__cpu) << (CONFIG_CPU_AREA_ORDER + PAGE_SHIFT)) +#define CPU_OFFSET(__cpu) __CPU_OFFSET(__cpu) #endif #define CPU_PTR(__p, __cpu) ((__typeof__(__p))((void *)(__p) + \ Index: linux-2.6/mm/cpu_alloc.c =================================================================== --- linux-2.6.orig/mm/cpu_alloc.c 2007-11-18 09:20:11.301533687 -0800 +++ linux-2.6/mm/cpu_alloc.c 2007-11-18 09:20:25.861311037 -0800 @@ -210,8 +210,7 @@ static int expand_cpu_area(gfp_t flags) map_order = get_order(DIV_ROUND_UP(bits, 8)); BUG_ON(map_order >= MAX_ORDER); - start = cpu_area + \ - (blocks << (PAGE_SHIFT + CONFIG_CPU_AREA_ALLOC_ORDER)); + start = (void *)(blocks << (PAGE_SHIFT + CONFIG_CPU_AREA_ALLOC_ORDER)); for_each_possible_cpu(cpu) { err = cpu_area_populate(CPU_PTR(start, cpu), ALLOC_SIZE, @@ -285,7 +284,7 @@ void * __init boot_cpu_alloc(unsigned lo expand_cpu_area(BOOT_ALLOC); units_reserved += units; spin_unlock_irqrestore(&cpu_alloc_map_lock, flags); - return cpu_area + x * UNIT_SIZE; + return (void *)(x * UNIT_SIZE); } #else @@ -408,7 +407,7 @@ restart: spin_unlock_irqrestore(&cpu_alloc_map_lock, flags); - ptr = cpu_area + (start + units_reserved) * UNIT_SIZE; + ptr = (void *)((start + units_reserved) * UNIT_SIZE); if (gfpflags & __GFP_ZERO) { int cpu; @@ -433,11 +432,11 @@ void cpu_free(void *start, unsigned long { int units = size_to_units(size); int index; - u8 *p = start; + unsigned long p = (unsigned long)start; unsigned long flags; - BUG_ON(p < (cpu_area + units_reserved * UNIT_SIZE)); - index = (p - cpu_area) / UNIT_SIZE - units_reserved; + BUG_ON(p < units_reserved * UNIT_SIZE); + index = p / UNIT_SIZE - units_reserved; BUG_ON(!test_bit(index, cpu_alloc_map) || index >= units_total - units_reserved); Index: linux-2.6/include/asm-x86/percpu_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/percpu_64.h 2007-11-18 09:20:11.293533464 -0800 +++ linux-2.6/include/asm-x86/percpu_64.h 2007-11-18 09:20:25.886533044 -0800 @@ -33,7 +33,10 @@ THIS_CPU(&per_cpu__##var); })) #define __raw_get_cpu_var(var) (*({ \ extern int simple_identifier_##var(void); \ - THIS_CPU(&per_cpu__##var); })) + __THIS_CPU(&per_cpu__##var); })) +#define cpu_var_offset(var) (*({ \ + extern int simple_identifier_##var(void); \ + &per_cpu__##var; })) /* A macro to avoid #include hell... */ #define percpu_modcopy(pcpudst, src, size) \ Index: linux-2.6/arch/x86/kernel/setup64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup64.c 2007-11-18 09:20:24.753850550 -0800 +++ linux-2.6/arch/x86/kernel/setup64.c 2007-11-18 09:21:04.905283098 -0800 @@ -96,8 +96,8 @@ void __init setup_per_cpu_areas(void) /* Copy section for each CPU (we discard the original) */ base = boot_cpu_alloc(PERCPU_ENOUGH_ROOM); - if (!base) - panic("Cannot allocate cpu data\n"); + if (base) + panic("Cannot allocate cpu data at offset 0\n"); printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", PERCPU_ENOUGH_ROOM);