diff options
Diffstat (limited to 'arch/x86/kernel/vmlinux_64.lds.S')
-rw-r--r-- | arch/x86/kernel/vmlinux_64.lds.S | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 1a614c0e6bef..c9740996430a 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S | |||
@@ -5,6 +5,7 @@ | |||
5 | #define LOAD_OFFSET __START_KERNEL_map | 5 | #define LOAD_OFFSET __START_KERNEL_map |
6 | 6 | ||
7 | #include <asm-generic/vmlinux.lds.h> | 7 | #include <asm-generic/vmlinux.lds.h> |
8 | #include <asm/asm-offsets.h> | ||
8 | #include <asm/page.h> | 9 | #include <asm/page.h> |
9 | 10 | ||
10 | #undef i386 /* in case the preprocessor is a 32bit one */ | 11 | #undef i386 /* in case the preprocessor is a 32bit one */ |
@@ -13,12 +14,14 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") | |||
13 | OUTPUT_ARCH(i386:x86-64) | 14 | OUTPUT_ARCH(i386:x86-64) |
14 | ENTRY(phys_startup_64) | 15 | ENTRY(phys_startup_64) |
15 | jiffies_64 = jiffies; | 16 | jiffies_64 = jiffies; |
16 | _proxy_pda = 1; | ||
17 | PHDRS { | 17 | PHDRS { |
18 | text PT_LOAD FLAGS(5); /* R_E */ | 18 | text PT_LOAD FLAGS(5); /* R_E */ |
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 | } |
24 | SECTIONS | 27 | SECTIONS |
@@ -208,14 +211,28 @@ 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. Also, pda should be at the head of | ||
219 | * percpu area. Preallocate it and define the percpu offset symbol | ||
220 | * so that it can be accessed as a percpu variable. | ||
221 | */ | ||
222 | . = ALIGN(PAGE_SIZE); | ||
223 | PERCPU_VADDR(0, :percpu) | ||
224 | #else | ||
211 | PERCPU(PAGE_SIZE) | 225 | PERCPU(PAGE_SIZE) |
226 | #endif | ||
212 | 227 | ||
213 | . = ALIGN(PAGE_SIZE); | 228 | . = ALIGN(PAGE_SIZE); |
214 | __init_end = .; | 229 | __init_end = .; |
215 | 230 | ||
216 | . = ALIGN(PAGE_SIZE); | 231 | . = ALIGN(PAGE_SIZE); |
217 | __nosave_begin = .; | 232 | __nosave_begin = .; |
218 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } | 233 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { |
234 | *(.data.nosave) | ||
235 | } :data.init /* switch back to data.init, see PERCPU_VADDR() above */ | ||
219 | . = ALIGN(PAGE_SIZE); | 236 | . = ALIGN(PAGE_SIZE); |
220 | __nosave_end = .; | 237 | __nosave_end = .; |
221 | 238 | ||
@@ -244,3 +261,8 @@ SECTIONS | |||
244 | */ | 261 | */ |
245 | ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), | 262 | ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), |
246 | "kernel image bigger than KERNEL_IMAGE_SIZE") | 263 | "kernel image bigger than KERNEL_IMAGE_SIZE") |
264 | |||
265 | #ifdef CONFIG_SMP | ||
266 | ASSERT((per_cpu__irq_stack_union == 0), | ||
267 | "irq_stack_union is not at start of per-cpu area"); | ||
268 | #endif | ||