diff options
author | Brian Gerst <brgerst@gmail.com> | 2009-01-18 22:21:28 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-01-19 22:29:20 -0500 |
commit | 947e76cdc34c782fc947313d4331380686eebbad (patch) | |
tree | de5d424c4760269fd7800bc745e48b060c725300 /arch/x86/include | |
parent | 8c7e58e690ae60ab4215b025f433ed4af261e103 (diff) |
x86: move stack_canary into irq_stack
Impact: x86_64 percpu area layout change, irq_stack now at the beginning
Now that the PDA is empty except for the stack canary, it can be removed.
The irqstack is moved to the start of the per-cpu section. If the stack
protector is enabled, the canary overlaps the bottom 48 bytes of the irqstack.
tj: * updated subject
* dropped asm relocation of irq_stack_ptr
* updated comments a bit
* rebased on top of stack canary changes
Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch/x86/include')
-rw-r--r-- | arch/x86/include/asm/pda.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/percpu.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 23 | ||||
-rw-r--r-- | arch/x86/include/asm/stackprotector.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/system.h | 4 |
5 files changed, 27 insertions, 15 deletions
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index b473e952439a..ba46416634f0 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h | |||
@@ -17,9 +17,6 @@ struct x8664_pda { | |||
17 | unsigned long unused4; | 17 | unsigned long unused4; |
18 | int unused5; | 18 | int unused5; |
19 | unsigned int unused6; /* 36 was cpunumber */ | 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 */ | 20 | short in_bootmem; /* pda lives in bootmem */ |
24 | } ____cacheline_aligned_in_smp; | 21 | } ____cacheline_aligned_in_smp; |
25 | 22 | ||
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). */ |
134 | DECLARE_PER_CPU(unsigned long, this_cpu_off); | 134 | DECLARE_PER_CPU(unsigned long, this_cpu_off); |
135 | 135 | ||
136 | #ifdef CONFIG_X86_64 | ||
137 | extern void load_pda_offset(int cpu); | ||
138 | #else | ||
139 | static 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/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 |
380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); | 380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); |
381 | 381 | ||
382 | DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); | 382 | union 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 | |||
395 | DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); | ||
383 | DECLARE_PER_CPU(char *, irq_stack_ptr); | 396 | DECLARE_PER_CPU(char *, irq_stack_ptr); |
397 | |||
398 | static 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 | ||
386 | extern void print_cpu_info(struct cpuinfo_x86 *); | 407 | extern void print_cpu_info(struct cpuinfo_x86 *); |
diff --git a/arch/x86/include/asm/stackprotector.h b/arch/x86/include/asm/stackprotector.h index 2383e5bb475c..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. |
@@ -19,7 +19,7 @@ static __always_inline void boot_init_stack_canary(void) | |||
19 | * Build time only check to make sure the stack_canary is at | 19 | * Build time only check to make sure the stack_canary is at |
20 | * offset 40 in the pda; this is a gcc ABI requirement | 20 | * offset 40 in the pda; this is a gcc ABI requirement |
21 | */ | 21 | */ |
22 | BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); | 22 | BUILD_BUG_ON(offsetof(union irq_stack_union, stack_canary) != 40); |
23 | 23 | ||
24 | /* | 24 | /* |
25 | * 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 |
@@ -32,7 +32,7 @@ static __always_inline void boot_init_stack_canary(void) | |||
32 | canary += tsc + (tsc << 32UL); | 32 | canary += tsc + (tsc << 32UL); |
33 | 33 | ||
34 | current->stack_canary = canary; | 34 | current->stack_canary = canary; |
35 | write_pda(stack_canary, canary); | 35 | percpu_write(irq_stack_union.stack_canary, canary); |
36 | } | 36 | } |
37 | 37 | ||
38 | #endif | 38 | #endif |
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index b77bd8bd3cc2..52eb748a68af 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h | |||
@@ -89,10 +89,10 @@ do { \ | |||
89 | #ifdef CONFIG_CC_STACKPROTECTOR | 89 | #ifdef CONFIG_CC_STACKPROTECTOR |
90 | #define __switch_canary \ | 90 | #define __switch_canary \ |
91 | "movq %P[task_canary](%%rsi),%%r8\n\t" \ | 91 | "movq %P[task_canary](%%rsi),%%r8\n\t" \ |
92 | "movq %%r8,%%gs:%P[pda_canary]\n\t" | 92 | "movq %%r8,%%gs:%P[gs_canary]\n\t" |
93 | #define __switch_canary_param \ | 93 | #define __switch_canary_param \ |
94 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \ | 94 | , [task_canary] "i" (offsetof(struct task_struct, stack_canary)) \ |
95 | , [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary)) | 95 | , [gs_canary] "i" (offsetof(union irq_stack_union, stack_canary)) |
96 | #else /* CC_STACKPROTECTOR */ | 96 | #else /* CC_STACKPROTECTOR */ |
97 | #define __switch_canary | 97 | #define __switch_canary |
98 | #define __switch_canary_param | 98 | #define __switch_canary_param |