aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-20 02:23:45 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-20 02:23:45 -0500
commit8f5d36ed5bb6e33024619eaee15b7ce2e3d115b3 (patch)
tree1a73934430a84fa926c7a12e1901d7e2639da4ff
parent5cdc5e9e69d4dc3a3630ae1fa666401b2a8dcde6 (diff)
parent6b7c38d55587f43bcd2cbce3a98b1c0826982090 (diff)
Merge branch 'tj-percpu' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc into core/percpu
-rw-r--r--arch/x86/include/asm/pda.h45
-rw-r--r--arch/x86/include/asm/percpu.h6
-rw-r--r--arch/x86/include/asm/pgtable_64.h1
-rw-r--r--arch/x86/include/asm/processor.h23
-rw-r--r--arch/x86/include/asm/smp.h1
-rw-r--r--arch/x86/include/asm/stackprotector.h17
-rw-r--r--arch/x86/include/asm/system.h22
-rw-r--r--arch/x86/kernel/asm-offsets_64.c5
-rw-r--r--arch/x86/kernel/cpu/common.c21
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/head_64.S37
-rw-r--r--arch/x86/kernel/process_64.c8
-rw-r--r--arch/x86/kernel/setup_percpu.c34
-rw-r--r--arch/x86/kernel/traps.c1
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S8
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--include/asm-generic/vmlinux.lds.h46
-rw-r--r--include/linux/percpu.h41
18 files changed, 107 insertions, 212 deletions
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h
deleted file mode 100644
index 5976cd803e9a..000000000000
--- a/arch/x86/include/asm/pda.h
+++ /dev/null
@@ -1,45 +0,0 @@
1#ifndef _ASM_X86_PDA_H
2#define _ASM_X86_PDA_H
3
4#ifndef __ASSEMBLY__
5#include <linux/stddef.h>
6#include <linux/types.h>
7#include <linux/cache.h>
8#include <linux/threads.h>
9#include <asm/page.h>
10#include <asm/percpu.h>
11
12/* Per processor datastructure. %gs points to it while the kernel runs */
13struct x8664_pda {
14 unsigned long unused1;
15 unsigned long unused2;
16 unsigned long unused3;
17 unsigned long unused4;
18 int unused5;
19 unsigned int unused6; /* 36 was cpunumber */
20 unsigned long stack_canary; /* 40 stack canary value */
21 /* gcc-ABI: this canary MUST be at
22 offset 40!!! */
23 short in_bootmem; /* pda lives in bootmem */
24} ____cacheline_aligned_in_smp;
25
26DECLARE_PER_CPU(struct x8664_pda, __pda);
27extern void pda_init(int);
28
29#define cpu_pda(cpu) (&per_cpu(__pda, cpu))
30
31#define read_pda(field) percpu_read(__pda.field)
32#define write_pda(field, val) percpu_write(__pda.field, val)
33#define add_pda(field, val) percpu_add(__pda.field, val)
34#define sub_pda(field, val) percpu_sub(__pda.field, val)
35#define or_pda(field, val) percpu_or(__pda.field, val)
36
37/* This is not atomic against other CPUs -- CPU preemption needs to be off */
38#define test_and_clear_bit_pda(bit, field) \
39 x86_test_and_clear_bit_percpu(bit, __pda.field)
40
41#endif
42
43#define refresh_stack_canary() write_pda(stack_canary, current->stack_canary)
44
45#endif /* _ASM_X86_PDA_H */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index 165d5272ece1..ce980db5e59d 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -133,12 +133,6 @@ do { \
133/* We can use this directly for local CPU (faster). */ 133/* We can use this directly for local CPU (faster). */
134DECLARE_PER_CPU(unsigned long, this_cpu_off); 134DECLARE_PER_CPU(unsigned long, this_cpu_off);
135 135
136#ifdef CONFIG_X86_64
137extern void load_pda_offset(int cpu);
138#else
139static inline void load_pda_offset(int cpu) { }
140#endif
141
142#endif /* !__ASSEMBLY__ */ 136#endif /* !__ASSEMBLY__ */
143 137
144#ifdef CONFIG_SMP 138#ifdef CONFIG_SMP
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index ba09289accaa..1df9637dfda3 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -11,7 +11,6 @@
11#include <asm/processor.h> 11#include <asm/processor.h>
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/threads.h> 13#include <linux/threads.h>
14#include <asm/pda.h>
15 14
16extern pud_t level3_kernel_pgt[512]; 15extern pud_t level3_kernel_pgt[512];
17extern pud_t level3_ident_pgt[512]; 16extern pud_t level3_ident_pgt[512];
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index f511246fa6cd..48676b943b92 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -379,8 +379,29 @@ union thread_xstate {
379#ifdef CONFIG_X86_64 379#ifdef CONFIG_X86_64
380DECLARE_PER_CPU(struct orig_ist, orig_ist); 380DECLARE_PER_CPU(struct orig_ist, orig_ist);
381 381
382DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); 382union irq_stack_union {
383 char irq_stack[IRQ_STACK_SIZE];
384 /*
385 * GCC hardcodes the stack canary as %gs:40. Since the
386 * irq_stack is the object at %gs:0, we reserve the bottom
387 * 48 bytes of the irq stack for the canary.
388 */
389 struct {
390 char gs_base[40];
391 unsigned long stack_canary;
392 };
393};
394
395DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
383DECLARE_PER_CPU(char *, irq_stack_ptr); 396DECLARE_PER_CPU(char *, irq_stack_ptr);
397
398static inline void load_gs_base(int cpu)
399{
400 /* Memory clobbers used to order pda/percpu accesses */
401 mb();
402 wrmsrl(MSR_GS_BASE, (unsigned long)per_cpu(irq_stack_union.gs_base, cpu));
403 mb();
404}
384#endif 405#endif
385 406
386extern void print_cpu_info(struct cpuinfo_x86 *); 407extern void print_cpu_info(struct cpuinfo_x86 *);
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 68636e767a91..45ef8a1b9d7c 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -15,7 +15,6 @@
15# include <asm/io_apic.h> 15# include <asm/io_apic.h>
16# endif 16# endif
17#endif 17#endif
18#include <asm/pda.h>
19#include <asm/thread_info.h> 18#include <asm/thread_info.h>
20#include <asm/cpumask.h> 19#include <asm/cpumask.h>
21 20
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h
index c7f0d10bae7b..36a700acaf2b 100644
--- a/arch/x86/include/asm/stackprotector.h
+++ b/arch/x86/include/asm/stackprotector.h
@@ -2,7 +2,7 @@
2#define _ASM_STACKPROTECTOR_H 1 2#define _ASM_STACKPROTECTOR_H 1
3 3
4#include <asm/tsc.h> 4#include <asm/tsc.h>
5#include <asm/pda.h> 5#include <asm/processor.h>
6 6
7/* 7/*
8 * Initialize the stackprotector canary value. 8 * Initialize the stackprotector canary value.
@@ -16,13 +16,12 @@ static __always_inline void boot_init_stack_canary(void)
16 u64 tsc; 16 u64 tsc;
17 17
18 /* 18 /*
19 * If we're the non-boot CPU, nothing set the PDA stack 19 * Build time only check to make sure the stack_canary is at
20 * canary up for us - and if we are the boot CPU we have 20 * offset 40 in the pda; this is a gcc ABI requirement
21 * a 0 stack canary. This is a good place for updating 21 */
22 * it, as we wont ever return from this function (so the 22 BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40);
23 * invalid canaries already on the stack wont ever 23
24 * trigger). 24 /*
25 *
26 * We both use the random pool and the current TSC as a source 25 * We both use the random pool and the current TSC as a source
27 * of randomness. The TSC only matters for very early init, 26 * of randomness. The TSC only matters for very early init,
28 * there it already has some randomness on most systems. Later 27 * there it already has some randomness on most systems. Later
@@ -33,7 +32,7 @@ static __always_inline void boot_init_stack_canary(void)
33 canary += tsc + (tsc << 32UL); 32 canary += tsc + (tsc << 32UL);
34 33
35 current->stack_canary = canary; 34 current->stack_canary = canary;
36 write_pda(stack_canary, canary); 35 percpu_write(irq_stack_union.stack_canary, canary);
37} 36}
38 37
39#endif 38#endif
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 8cadfe9b1194..52eb748a68af 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -86,17 +86,28 @@ do { \
86 , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \ 86 , "rcx", "rbx", "rdx", "r8", "r9", "r10", "r11", \
87 "r12", "r13", "r14", "r15" 87 "r12", "r13", "r14", "r15"
88 88
89#ifdef CONFIG_CC_STACKPROTECTOR
90#define __switch_canary \
91 "movq %P[task_canary](%%rsi),%%r8\n\t" \
92 "movq %%r8,%%gs:%P[gs_canary]\n\t"
93#define __switch_canary_param \
94 , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \
95 , [gs_canary] "i" (offsetof(union irq_stack_union, stack_canary))
96#else /* CC_STACKPROTECTOR */
97#define __switch_canary
98#define __switch_canary_param
99#endif /* CC_STACKPROTECTOR */
100
89/* Save restore flags to clear handle leaking NT */ 101/* Save restore flags to clear handle leaking NT */
90#define switch_to(prev, next, last) \ 102#define switch_to(prev, next, last) \
91 asm volatile(SAVE_CONTEXT \ 103 asm volatile(SAVE_CONTEXT \
92 "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \ 104 "movq %%rsp,%P[threadrsp](%[prev])\n\t" /* save RSP */ \
93 "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \ 105 "movq %P[threadrsp](%[next]),%%rsp\n\t" /* restore RSP */ \
94 "call __switch_to\n\t" \ 106 "call __switch_to\n\t" \
95 ".globl thread_return\n" \ 107 ".globl thread_return\n" \
96 "thread_return:\n\t" \ 108 "thread_return:\n\t" \
97 "movq "__percpu_arg([current_task])",%%rsi\n\t" \ 109 "movq "__percpu_arg([current_task])",%%rsi\n\t" \
98 "movq %P[task_canary](%%rsi),%%r8\n\t" \ 110 __switch_canary \
99 "movq %%r8,%%gs:%P[pda_canary]\n\t" \
100 "movq %P[thread_info](%%rsi),%%r8\n\t" \ 111 "movq %P[thread_info](%%rsi),%%r8\n\t" \
101 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \ 112 LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
102 "movq %%rax,%%rdi\n\t" \ 113 "movq %%rax,%%rdi\n\t" \
@@ -108,9 +119,8 @@ do { \
108 [ti_flags] "i" (offsetof(struct thread_info, flags)), \ 119 [ti_flags] "i" (offsetof(struct thread_info, flags)), \
109 [tif_fork] "i" (TIF_FORK), \ 120 [tif_fork] "i" (TIF_FORK), \
110 [thread_info] "i" (offsetof(struct task_struct, stack)), \ 121 [thread_info] "i" (offsetof(struct task_struct, stack)), \
111 [task_canary] "i" (offsetof(struct task_struct, stack_canary)),\ 122 [current_task] "m" (per_cpu_var(current_task)) \
112 [current_task] "m" (per_cpu_var(current_task)), \ 123 __switch_canary_param \
113 [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
114 : "memory", "cc" __EXTRA_CLOBBER) 124 : "memory", "cc" __EXTRA_CLOBBER)
115#endif 125#endif
116 126
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 64c834a39aa8..8793ab33e2c1 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -11,7 +11,6 @@
11#include <linux/hardirq.h> 11#include <linux/hardirq.h>
12#include <linux/suspend.h> 12#include <linux/suspend.h>
13#include <linux/kbuild.h> 13#include <linux/kbuild.h>
14#include <asm/pda.h>
15#include <asm/processor.h> 14#include <asm/processor.h>
16#include <asm/segment.h> 15#include <asm/segment.h>
17#include <asm/thread_info.h> 16#include <asm/thread_info.h>
@@ -48,10 +47,6 @@ int main(void)
48#endif 47#endif
49 BLANK(); 48 BLANK();
50#undef ENTRY 49#undef ENTRY
51#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
52 DEFINE(pda_size, sizeof(struct x8664_pda));
53 BLANK();
54#undef ENTRY
55#ifdef CONFIG_PARAVIRT 50#ifdef CONFIG_PARAVIRT
56 BLANK(); 51 BLANK();
57 OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled); 52 OFFSET(PARAVIRT_enabled, pv_info, paravirt_enabled);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 7976a6a0f65c..3887fcf6e519 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -30,7 +30,6 @@
30#include <asm/genapic.h> 30#include <asm/genapic.h>
31#endif 31#endif
32 32
33#include <asm/pda.h>
34#include <asm/pgtable.h> 33#include <asm/pgtable.h>
35#include <asm/processor.h> 34#include <asm/processor.h>
36#include <asm/desc.h> 35#include <asm/desc.h>
@@ -881,12 +880,13 @@ __setup("clearcpuid=", setup_disablecpuid);
881#ifdef CONFIG_X86_64 880#ifdef CONFIG_X86_64
882struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; 881struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
883 882
884DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack); 883DEFINE_PER_CPU_FIRST(union irq_stack_union,
884 irq_stack_union) __aligned(PAGE_SIZE);
885#ifdef CONFIG_SMP 885#ifdef CONFIG_SMP
886DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */ 886DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */
887#else 887#else
888DEFINE_PER_CPU(char *, irq_stack_ptr) = 888DEFINE_PER_CPU(char *, irq_stack_ptr) =
889 per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64; 889 per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64;
890#endif 890#endif
891 891
892DEFINE_PER_CPU(unsigned long, kernel_stack) = 892DEFINE_PER_CPU(unsigned long, kernel_stack) =
@@ -895,15 +895,6 @@ EXPORT_PER_CPU_SYMBOL(kernel_stack);
895 895
896DEFINE_PER_CPU(unsigned int, irq_count) = -1; 896DEFINE_PER_CPU(unsigned int, irq_count) = -1;
897 897
898void __cpuinit pda_init(int cpu)
899{
900 /* Setup up data that may be needed in __get_free_pages early */
901 loadsegment(fs, 0);
902 loadsegment(gs, 0);
903
904 load_pda_offset(cpu);
905}
906
907static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks 898static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
908 [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ]) 899 [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
909 __aligned(PAGE_SIZE); 900 __aligned(PAGE_SIZE);
@@ -967,9 +958,9 @@ void __cpuinit cpu_init(void)
967 struct task_struct *me; 958 struct task_struct *me;
968 int i; 959 int i;
969 960
970 /* CPU 0 is initialised in head64.c */ 961 loadsegment(fs, 0);
971 if (cpu != 0) 962 loadsegment(gs, 0);
972 pda_init(cpu); 963 load_gs_base(cpu);
973 964
974#ifdef CONFIG_NUMA 965#ifdef CONFIG_NUMA
975 if (cpu != 0 && percpu_read(node_number) == 0 && 966 if (cpu != 0 && percpu_read(node_number) == 0 &&
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index af67d3227ea6..f5b272247690 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -91,8 +91,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
91 if (console_loglevel == 10) 91 if (console_loglevel == 10)
92 early_printk("Kernel alive\n"); 92 early_printk("Kernel alive\n");
93 93
94 pda_init(0);
95
96 x86_64_start_reservations(real_mode_data); 94 x86_64_start_reservations(real_mode_data);
97} 95}
98 96
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index c8ace880661b..a0a2b5ca9b7d 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -207,19 +207,15 @@ ENTRY(secondary_startup_64)
207 207
208#ifdef CONFIG_SMP 208#ifdef CONFIG_SMP
209 /* 209 /*
210 * early_gdt_base should point to the gdt_page in static percpu init 210 * Fix up static pointers that need __per_cpu_load added. The assembler
211 * data area. Computing this requires two symbols - __per_cpu_load 211 * is unable to do this directly. This is only needed for the boot cpu.
212 * and per_cpu__gdt_page. As linker can't do no such relocation, do 212 * These values are set up with the correct base addresses by C code for
213 * it by hand. As early_gdt_descr is manipulated by C code for 213 * secondary cpus.
214 * secondary CPUs, this should be done only once for the boot CPU
215 * when early_gdt_descr_base contains zero.
216 */ 214 */
217 movq early_gdt_descr_base(%rip), %rax 215 movq initial_gs(%rip), %rax
218 testq %rax, %rax 216 cmpl $0, per_cpu__cpu_number(%rax)
219 jnz 1f 217 jne 1f
220 movq $__per_cpu_load, %rax 218 addq %rax, early_gdt_descr_base(%rip)
221 addq $per_cpu__gdt_page, %rax
222 movq %rax, early_gdt_descr_base(%rip)
2231: 2191:
224#endif 220#endif
225 /* 221 /*
@@ -246,13 +242,10 @@ ENTRY(secondary_startup_64)
246 242
247 /* Set up %gs. 243 /* Set up %gs.
248 * 244 *
249 * On SMP, %gs should point to the per-cpu area. For initial 245 * The base of %gs always points to the bottom of the irqstack
250 * boot, make %gs point to the init data section. For a 246 * union. If the stack protector canary is enabled, it is
251 * secondary CPU,initial_gs should be set to its pda address 247 * located at %gs:40. Note that, on SMP, the boot cpu uses
252 * before the CPU runs this code. 248 * init data section till per cpu areas are set up.
253 *
254 * On UP, initial_gs points to PER_CPU_VAR(__pda) and doesn't
255 * change.
256 */ 249 */
257 movl $MSR_GS_BASE,%ecx 250 movl $MSR_GS_BASE,%ecx
258 movq initial_gs(%rip),%rax 251 movq initial_gs(%rip),%rax
@@ -285,7 +278,7 @@ ENTRY(secondary_startup_64)
285#ifdef CONFIG_SMP 278#ifdef CONFIG_SMP
286 .quad __per_cpu_load 279 .quad __per_cpu_load
287#else 280#else
288 .quad PER_CPU_VAR(__pda) 281 .quad PER_CPU_VAR(irq_stack_union)
289#endif 282#endif
290 __FINITDATA 283 __FINITDATA
291 284
@@ -431,12 +424,8 @@ NEXT_PAGE(level2_spare_pgt)
431 .globl early_gdt_descr 424 .globl early_gdt_descr
432early_gdt_descr: 425early_gdt_descr:
433 .word GDT_ENTRIES*8-1 426 .word GDT_ENTRIES*8-1
434#ifdef CONFIG_SMP
435early_gdt_descr_base: 427early_gdt_descr_base:
436 .quad 0x0000000000000000
437#else
438 .quad per_cpu__gdt_page 428 .quad per_cpu__gdt_page
439#endif
440 429
441ENTRY(phys_base) 430ENTRY(phys_base)
442 /* This must match the first entry in level2_kernel_pgt */ 431 /* This must match the first entry in level2_kernel_pgt */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index aa89eabf09e0..c422eebb0c58 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -47,7 +47,6 @@
47#include <asm/processor.h> 47#include <asm/processor.h>
48#include <asm/i387.h> 48#include <asm/i387.h>
49#include <asm/mmu_context.h> 49#include <asm/mmu_context.h>
50#include <asm/pda.h>
51#include <asm/prctl.h> 50#include <asm/prctl.h>
52#include <asm/desc.h> 51#include <asm/desc.h>
53#include <asm/proto.h> 52#include <asm/proto.h>
@@ -638,13 +637,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
638 percpu_write(kernel_stack, 637 percpu_write(kernel_stack,
639 (unsigned long)task_stack_page(next_p) + 638 (unsigned long)task_stack_page(next_p) +
640 THREAD_SIZE - KERNEL_STACK_OFFSET); 639 THREAD_SIZE - KERNEL_STACK_OFFSET);
641#ifdef CONFIG_CC_STACKPROTECTOR
642 /*
643 * Build time only check to make sure the stack_canary is at
644 * offset 40 in the pda; this is a gcc ABI requirement
645 */
646 BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
647#endif
648 640
649 /* 641 /*
650 * Now maybe reload the debug registers and handle I/O bitmaps 642 * Now maybe reload the debug registers and handle I/O bitmaps
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index efbafbbff584..90b8e154bb53 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -77,30 +77,6 @@ static void __init setup_node_to_cpumask_map(void);
77static inline void setup_node_to_cpumask_map(void) { } 77static inline void setup_node_to_cpumask_map(void) { }
78#endif 78#endif
79 79
80/*
81 * Define load_pda_offset() and per-cpu __pda for x86_64.
82 * load_pda_offset() is responsible for loading the offset of pda into
83 * %gs.
84 *
85 * On SMP, pda offset also duals as percpu base address and thus it
86 * should be at the start of per-cpu area. To achieve this, it's
87 * preallocated in vmlinux_64.lds.S directly instead of using
88 * DEFINE_PER_CPU().
89 */
90#ifdef CONFIG_X86_64
91void __cpuinit load_pda_offset(int cpu)
92{
93 /* Memory clobbers used to order pda/percpu accesses */
94 mb();
95 wrmsrl(MSR_GS_BASE, cpu_pda(cpu));
96 mb();
97}
98#ifndef CONFIG_SMP
99DEFINE_PER_CPU(struct x8664_pda, __pda);
100#endif
101EXPORT_PER_CPU_SYMBOL(__pda);
102#endif /* CONFIG_SMP && CONFIG_X86_64 */
103
104#ifdef CONFIG_X86_64 80#ifdef CONFIG_X86_64
105 81
106/* correctly size the local cpu masks */ 82/* correctly size the local cpu masks */
@@ -207,15 +183,13 @@ void __init setup_per_cpu_areas(void)
207 per_cpu(cpu_number, cpu) = cpu; 183 per_cpu(cpu_number, cpu) = cpu;
208#ifdef CONFIG_X86_64 184#ifdef CONFIG_X86_64
209 per_cpu(irq_stack_ptr, cpu) = 185 per_cpu(irq_stack_ptr, cpu) =
210 (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64; 186 per_cpu(irq_stack_union.irq_stack, cpu) + IRQ_STACK_SIZE - 64;
211 /* 187 /*
212 * CPU0 modified pda in the init data area, reload pda 188 * Up to this point, CPU0 has been using .data.init
213 * offset for CPU0 and clear the area for others. 189 * area. Reload %gs offset for CPU0.
214 */ 190 */
215 if (cpu == 0) 191 if (cpu == 0)
216 load_pda_offset(0); 192 load_gs_base(cpu);
217 else
218 memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu)));
219#endif 193#endif
220 194
221 DBG("PERCPU: cpu %4d %p\n", cpu, ptr); 195 DBG("PERCPU: cpu %4d %p\n", cpu, ptr);
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 98c2d055284b..ed5aee5f3fcc 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -59,7 +59,6 @@
59#ifdef CONFIG_X86_64 59#ifdef CONFIG_X86_64
60#include <asm/pgalloc.h> 60#include <asm/pgalloc.h>
61#include <asm/proto.h> 61#include <asm/proto.h>
62#include <asm/pda.h>
63#else 62#else
64#include <asm/processor-flags.h> 63#include <asm/processor-flags.h>
65#include <asm/arch_hooks.h> 64#include <asm/arch_hooks.h>
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index a09abb8fb97f..c9740996430a 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -220,8 +220,7 @@ SECTIONS
220 * so that it can be accessed as a percpu variable. 220 * so that it can be accessed as a percpu variable.
221 */ 221 */
222 . = ALIGN(PAGE_SIZE); 222 . = ALIGN(PAGE_SIZE);
223 PERCPU_VADDR_PREALLOC(0, :percpu, pda_size) 223 PERCPU_VADDR(0, :percpu)
224 per_cpu____pda = __per_cpu_start;
225#else 224#else
226 PERCPU(PAGE_SIZE) 225 PERCPU(PAGE_SIZE)
227#endif 226#endif
@@ -262,3 +261,8 @@ SECTIONS
262 */ 261 */
263ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), 262ASSERT((_end - _text <= KERNEL_IMAGE_SIZE),
264 "kernel image bigger than KERNEL_IMAGE_SIZE") 263 "kernel image bigger than KERNEL_IMAGE_SIZE")
264
265#ifdef CONFIG_SMP
266ASSERT((per_cpu__irq_stack_union == 0),
267 "irq_stack_union is not at start of per-cpu area");
268#endif
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 75b94139e1f2..bef941f61451 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1645,7 +1645,6 @@ asmlinkage void __init xen_start_kernel(void)
1645#ifdef CONFIG_X86_64 1645#ifdef CONFIG_X86_64
1646 /* Disable until direct per-cpu data access. */ 1646 /* Disable until direct per-cpu data access. */
1647 have_vcpu_info_placement = 0; 1647 have_vcpu_info_placement = 0;
1648 pda_init(0);
1649#endif 1648#endif
1650 1649
1651 xen_smp_init(); 1650 xen_smp_init();
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index aa6b9b1b30b5..53e21f36a802 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -430,22 +430,10 @@
430 *(.initcall7.init) \ 430 *(.initcall7.init) \
431 *(.initcall7s.init) 431 *(.initcall7s.init)
432 432
433#define PERCPU_PROLOG(vaddr) \
434 VMLINUX_SYMBOL(__per_cpu_load) = .; \
435 .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
436 - LOAD_OFFSET) { \
437 VMLINUX_SYMBOL(__per_cpu_start) = .;
438
439#define PERCPU_EPILOG(phdr) \
440 VMLINUX_SYMBOL(__per_cpu_end) = .; \
441 } phdr \
442 . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
443
444/** 433/**
445 * PERCPU_VADDR_PREALLOC - define output section for percpu area with prealloc 434 * PERCPU_VADDR - define output section for percpu area
446 * @vaddr: explicit base address (optional) 435 * @vaddr: explicit base address (optional)
447 * @phdr: destination PHDR (optional) 436 * @phdr: destination PHDR (optional)
448 * @prealloc: the size of prealloc area
449 * 437 *
450 * Macro which expands to output section for percpu area. If @vaddr 438 * Macro which expands to output section for percpu area. If @vaddr
451 * is not blank, it specifies explicit base address and all percpu 439 * is not blank, it specifies explicit base address and all percpu
@@ -457,39 +445,23 @@
457 * section in the linker script will go there too. @phdr should have 445 * section in the linker script will go there too. @phdr should have
458 * a leading colon. 446 * a leading colon.
459 * 447 *
460 * If @prealloc is non-zero, the specified number of bytes will be
461 * reserved at the start of percpu area. As the prealloc area is
462 * likely to break alignment, this macro puts areas in increasing
463 * alignment order.
464 *
465 * This macro defines three symbols, __per_cpu_load, __per_cpu_start 448 * This macro defines three symbols, __per_cpu_load, __per_cpu_start
466 * and __per_cpu_end. The first one is the vaddr of loaded percpu 449 * and __per_cpu_end. The first one is the vaddr of loaded percpu
467 * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the 450 * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the
468 * end offset. 451 * end offset.
469 */ 452 */
470#define PERCPU_VADDR_PREALLOC(vaddr, segment, prealloc) \
471 PERCPU_PROLOG(vaddr) \
472 . += prealloc; \
473 *(.data.percpu) \
474 *(.data.percpu.shared_aligned) \
475 *(.data.percpu.page_aligned) \
476 PERCPU_EPILOG(segment)
477
478/**
479 * PERCPU_VADDR - define output section for percpu area
480 * @vaddr: explicit base address (optional)
481 * @phdr: destination PHDR (optional)
482 *
483 * Macro which expands to output section for percpu area. Mostly
484 * identical to PERCPU_VADDR_PREALLOC(@vaddr, @phdr, 0) other than
485 * using slighly different layout.
486 */
487#define PERCPU_VADDR(vaddr, phdr) \ 453#define PERCPU_VADDR(vaddr, phdr) \
488 PERCPU_PROLOG(vaddr) \ 454 VMLINUX_SYMBOL(__per_cpu_load) = .; \
455 .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
456 - LOAD_OFFSET) { \
457 VMLINUX_SYMBOL(__per_cpu_start) = .; \
458 *(.data.percpu.first) \
489 *(.data.percpu.page_aligned) \ 459 *(.data.percpu.page_aligned) \
490 *(.data.percpu) \ 460 *(.data.percpu) \
491 *(.data.percpu.shared_aligned) \ 461 *(.data.percpu.shared_aligned) \
492 PERCPU_EPILOG(phdr) 462 VMLINUX_SYMBOL(__per_cpu_end) = .; \
463 } phdr \
464 . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
493 465
494/** 466/**
495 * PERCPU - define output section for percpu area, simple version 467 * PERCPU - define output section for percpu area, simple version
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index 9f2a3751873a..0e24202b5a4e 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -9,34 +9,39 @@
9#include <asm/percpu.h> 9#include <asm/percpu.h>
10 10
11#ifdef CONFIG_SMP 11#ifdef CONFIG_SMP
12#define DEFINE_PER_CPU(type, name) \ 12#define PER_CPU_BASE_SECTION ".data.percpu"
13 __attribute__((__section__(".data.percpu"))) \
14 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
15 13
16#ifdef MODULE 14#ifdef MODULE
17#define SHARED_ALIGNED_SECTION ".data.percpu" 15#define PER_CPU_SHARED_ALIGNED_SECTION ""
18#else 16#else
19#define SHARED_ALIGNED_SECTION ".data.percpu.shared_aligned" 17#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
20#endif 18#endif
19#define PER_CPU_FIRST_SECTION ".first"
21 20
22#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ 21#else
23 __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ 22
24 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ 23#define PER_CPU_BASE_SECTION ".data"
25 ____cacheline_aligned_in_smp 24#define PER_CPU_SHARED_ALIGNED_SECTION ""
25#define PER_CPU_FIRST_SECTION ""
26
27#endif
26 28
27#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ 29#define DEFINE_PER_CPU_SECTION(type, name, section) \
28 __attribute__((__section__(".data.percpu.page_aligned"))) \ 30 __attribute__((__section__(PER_CPU_BASE_SECTION section))) \
29 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name 31 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
30#else 32
31#define DEFINE_PER_CPU(type, name) \ 33#define DEFINE_PER_CPU(type, name) \
32 PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name 34 DEFINE_PER_CPU_SECTION(type, name, "")
33 35
34#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ 36#define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \
35 DEFINE_PER_CPU(type, name) 37 DEFINE_PER_CPU_SECTION(type, name, PER_CPU_SHARED_ALIGNED_SECTION) \
38 ____cacheline_aligned_in_smp
36 39
37#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ 40#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \
38 DEFINE_PER_CPU(type, name) 41 DEFINE_PER_CPU_SECTION(type, name, ".page_aligned")
39#endif 42
43#define DEFINE_PER_CPU_FIRST(type, name) \
44 DEFINE_PER_CPU_SECTION(type, name, PER_CPU_FIRST_SECTION)
40 45
41#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) 46#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
42#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) 47#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)