Index: linux-2.6/include/asm-x86/current_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/current_64.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/current_64.h 2008-05-23 22:55:59.000000000 -0700 @@ -5,11 +5,11 @@ struct task_struct; #include +#include static inline struct task_struct *get_current(void) { - struct task_struct *t = read_pda(pcurrent); - return t; + return x86_read_percpu(pda.pcurrent); } #define current get_current() Index: linux-2.6/include/asm-x86/hardirq_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/hardirq_64.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/hardirq_64.h 2008-05-23 22:55:59.000000000 -0700 @@ -11,12 +11,12 @@ #define __ARCH_IRQ_STAT 1 -#define local_softirq_pending() read_pda(__softirq_pending) +#define local_softirq_pending() x86_read_percpu(pda.__softirq_pending) #define __ARCH_SET_SOFTIRQ_PENDING 1 -#define set_softirq_pending(x) write_pda(__softirq_pending, (x)) -#define or_softirq_pending(x) or_pda(__softirq_pending, (x)) +#define set_softirq_pending(x) x86_write_percpu(pda.__softirq_pending, (x)) +#define or_softirq_pending(x) x86_or_percpu(pda.__softirq_pending, (x)) extern void ack_bad_irq(unsigned int irq); Index: linux-2.6/include/asm-x86/mmu_context_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/mmu_context_64.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/mmu_context_64.h 2008-05-23 22:55:59.000000000 -0700 @@ -20,8 +20,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { #ifdef CONFIG_SMP - if (read_pda(mmu_state) == TLBSTATE_OK) - write_pda(mmu_state, TLBSTATE_LAZY); + if (x86_read_percpu(pda.mmu_state) == TLBSTATE_OK) + x86_write_percpu(pda.mmu_state, TLBSTATE_LAZY); #endif } @@ -33,8 +33,8 @@ /* stop flush ipis for the previous mm */ cpu_clear(cpu, prev->cpu_vm_mask); #ifdef CONFIG_SMP - write_pda(mmu_state, TLBSTATE_OK); - write_pda(active_mm, next); + x86_write_percpu(pda.mmu_state, TLBSTATE_OK); + x86_write_percpu(pda.active_mm, next); #endif cpu_set(cpu, next->cpu_vm_mask); load_cr3(next->pgd); @@ -44,8 +44,8 @@ } #ifdef CONFIG_SMP else { - write_pda(mmu_state, TLBSTATE_OK); - if (read_pda(active_mm) != next) + x86_write_percpu(pda.mmu_state, TLBSTATE_OK); + if (x86_read_percpu(pda.active_mm) != next) BUG(); if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) { /* We were in lazy tlb mode and leave_mm disabled Index: linux-2.6/include/asm-x86/pda.h =================================================================== --- linux-2.6.orig/include/asm-x86/pda.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/pda.h 2008-05-23 22:55:59.000000000 -0700 @@ -39,95 +39,6 @@ extern void pda_init(int); -/* - * There is no fast way to get the base address of the PDA, all the accesses - * have to mention %fs/%gs. So it needs to be done this Torvaldian way. - */ -extern void __bad_pda_field(void) __attribute__((noreturn)); - -/* - * proxy_pda doesn't actually exist, but tell gcc it is accessed for - * all PDA accesses so it gets read/write dependencies right. - */ -extern struct x8664_pda _proxy_pda; - -#define pda_offset(field) offsetof(struct x8664_pda, field) - -#define pda_to_op(op, field, val) \ -do { \ - typedef typeof(_proxy_pda.field) T__; \ - if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - case 4: \ - asm(op "l %1,%%gs:%c2" : \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i" (pda_offset(field))); \ - break; \ - case 8: \ - asm(op "q %1,%%gs:%c2": \ - "+m" (_proxy_pda.field) : \ - "ri" ((T__)val), \ - "i"(pda_offset(field))); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ -} while (0) - -#define pda_from_op(op, field) \ -({ \ - typeof(_proxy_pda.field) ret__; \ - switch (sizeof(_proxy_pda.field)) { \ - case 2: \ - asm(op "w %%gs:%c1,%0" : \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 4: \ - asm(op "l %%gs:%c1,%0": \ - "=r" (ret__): \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - case 8: \ - asm(op "q %%gs:%c1,%0": \ - "=r" (ret__) : \ - "i" (pda_offset(field)), \ - "m" (_proxy_pda.field)); \ - break; \ - default: \ - __bad_pda_field(); \ - } \ - ret__; \ -}) - -/* - * The pda can be accessed using the standard x86 percpu ops. These definition - * exist only because they are used in header files where percpu.h cannot be - * included. - */ -#define read_pda(field) pda_from_op("mov", field) -#define write_pda(field, val) pda_to_op("mov", field, val) -#define or_pda(field, val) pda_to_op("or", field, val) - -/* This is not atomic against other CPUs -- CPU preemption needs to be off */ -#define test_and_clear_bit_pda(bit, field) \ -({ \ - int old__; \ - asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ - : "=r" (old__), "+m" (_proxy_pda.field) \ - : "dIr" (bit), "i" (pda_offset(field)) : "memory");\ - old__; \ -}) - #endif #define PDA_STACKOFFSET (5*8) Index: linux-2.6/include/asm-x86/smp.h =================================================================== --- linux-2.6.orig/include/asm-x86/smp.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/smp.h 2008-05-23 22:55:59.000000000 -0700 @@ -143,7 +143,7 @@ extern int safe_smp_processor_id(void); #elif defined(CONFIG_X86_64_SMP) -#define raw_smp_processor_id() read_pda(cpunumber) +#define raw_smp_processor_id() x86_read_percpu(pda.cpunumber) #define stack_smp_processor_id() \ ({ \ Index: linux-2.6/include/asm-x86/thread_info_64.h =================================================================== --- linux-2.6.orig/include/asm-x86/thread_info_64.h 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/include/asm-x86/thread_info_64.h 2008-05-23 22:55:59.000000000 -0700 @@ -63,7 +63,7 @@ static inline struct thread_info *current_thread_info(void) { struct thread_info *ti; - ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); + ti = (void *)(x86_read_percpu(pda.kernelstack) + PDA_STACKOFFSET - THREAD_SIZE); return ti; } Index: linux-2.6/arch/x86/kernel/x8664_ksyms_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/x8664_ksyms_64.c 2008-05-23 22:40:42.000000000 -0700 +++ linux-2.6/arch/x86/kernel/x8664_ksyms_64.c 2008-05-23 22:55:59.000000000 -0700 @@ -52,8 +52,6 @@ EXPORT_SYMBOL(init_level4_pgt); EXPORT_SYMBOL(load_gs_index); -EXPORT_SYMBOL(_proxy_pda); - #ifdef CONFIG_PARAVIRT /* Virtualized guests may want to use it */ EXPORT_SYMBOL_GPL(cpu_gdt_descr); Index: linux-2.6/arch/x86/kernel/process_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/process_64.c 2008-05-23 22:55:56.000000000 -0700 +++ linux-2.6/arch/x86/kernel/process_64.c 2008-05-23 22:56:00.000000000 -0700 @@ -80,7 +80,7 @@ static void __exit_idle(void) { - if (test_and_clear_bit_pda(0, isidle) == 0) + if (test_and_clear_bit(0, &per_cpu(pda.isidle, smp_processor_id())) == 0) return; atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); }