aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/vmlinux_64.lds.S
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-01-13 06:41:35 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-16 08:19:14 -0500
commit3e5d8f978435bb9ba4dfe3f4514e65e7885db1a9 (patch)
tree1ce55b2ec16a0bd59a29857e05215960d463a1d8 /arch/x86/kernel/vmlinux_64.lds.S
parenta698c823e15149941b0f0281527d0c0d1daf2639 (diff)
x86: make percpu symbols zerobased on SMP
[ Based on original patch from Christoph Lameter and Mike Travis. ] This patch makes percpu symbols zerobased on x86_64 SMP by adding PERCPU_VADDR() to vmlinux.lds.h which helps setting explicit vaddr on the percpu output section and using it in vmlinux_64.lds.S. A new PHDR is added as existing ones cannot contain sections near address zero. PERCPU_VADDR() also adds a new symbol __per_cpu_load which always points to the vaddr of the loaded percpu data.init region. The following adjustments have been made to accomodate the address change. * code to locate percpu gdt_page in head_64.S is updated to add the load address to the gdt_page offset. * __per_cpu_load is used in places where access to the init data area is necessary. * pda->data_offset is initialized soon after C code is entered as zero value doesn't work anymore. This patch is mostly taken from Mike Travis' "x86_64: Base percpu variables at zero" patch. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/vmlinux_64.lds.S')
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S17
1 files changed, 16 insertions, 1 deletions
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 1a614c0e6bef..f50280db0dfe 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -19,6 +19,9 @@ PHDRS {
19 data PT_LOAD FLAGS(7); /* RWE */ 19 data PT_LOAD FLAGS(7); /* RWE */
20 user PT_LOAD FLAGS(7); /* RWE */ 20 user PT_LOAD FLAGS(7); /* RWE */
21 data.init PT_LOAD FLAGS(7); /* RWE */ 21 data.init PT_LOAD FLAGS(7); /* RWE */
22#ifdef CONFIG_SMP
23 percpu PT_LOAD FLAGS(7); /* RWE */
24#endif
22 note PT_NOTE FLAGS(0); /* ___ */ 25 note PT_NOTE FLAGS(0); /* ___ */
23} 26}
24SECTIONS 27SECTIONS
@@ -208,14 +211,26 @@ SECTIONS
208 __initramfs_end = .; 211 __initramfs_end = .;
209#endif 212#endif
210 213
214#ifdef CONFIG_SMP
215 /*
216 * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
217 * output PHDR, so the next output section - __data_nosave - should
218 * switch it back to data.init.
219 */
220 . = ALIGN(PAGE_SIZE);
221 PERCPU_VADDR(0, :percpu)
222#else
211 PERCPU(PAGE_SIZE) 223 PERCPU(PAGE_SIZE)
224#endif
212 225
213 . = ALIGN(PAGE_SIZE); 226 . = ALIGN(PAGE_SIZE);
214 __init_end = .; 227 __init_end = .;
215 228
216 . = ALIGN(PAGE_SIZE); 229 . = ALIGN(PAGE_SIZE);
217 __nosave_begin = .; 230 __nosave_begin = .;
218 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } 231 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
232 *(.data.nosave)
233 } :data.init /* switch back to data.init, see PERCPU_VADDR() above */
219 . = ALIGN(PAGE_SIZE); 234 . = ALIGN(PAGE_SIZE);
220 __nosave_end = .; 235 __nosave_end = .;
221 236