diff options
Diffstat (limited to 'arch/x86/kernel/vmlinux_64.lds.S')
| -rw-r--r-- | arch/x86/kernel/vmlinux_64.lds.S | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S index 1a614c0e6bef..fbfced6f6800 100644 --- a/arch/x86/kernel/vmlinux_64.lds.S +++ b/arch/x86/kernel/vmlinux_64.lds.S | |||
| @@ -5,7 +5,8 @@ | |||
| 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/page.h> | 8 | #include <asm/asm-offsets.h> |
| 9 | #include <asm/page_types.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 */ |
| 11 | 12 | ||
| @@ -13,12 +14,15 @@ 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 | ||
| 25 | data.init2 PT_LOAD FLAGS(7); /* RWE */ | ||
| 22 | note PT_NOTE FLAGS(0); /* ___ */ | 26 | note PT_NOTE FLAGS(0); /* ___ */ |
| 23 | } | 27 | } |
| 24 | SECTIONS | 28 | SECTIONS |
| @@ -208,14 +212,28 @@ SECTIONS | |||
| 208 | __initramfs_end = .; | 212 | __initramfs_end = .; |
| 209 | #endif | 213 | #endif |
| 210 | 214 | ||
| 215 | #ifdef CONFIG_SMP | ||
| 216 | /* | ||
| 217 | * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the | ||
| 218 | * output PHDR, so the next output section - __data_nosave - should | ||
| 219 | * start another section data.init2. Also, pda should be at the head of | ||
| 220 | * percpu area. Preallocate it and define the percpu offset symbol | ||
| 221 | * so that it can be accessed as a percpu variable. | ||
| 222 | */ | ||
| 223 | . = ALIGN(PAGE_SIZE); | ||
| 224 | PERCPU_VADDR(0, :percpu) | ||
| 225 | #else | ||
| 211 | PERCPU(PAGE_SIZE) | 226 | PERCPU(PAGE_SIZE) |
| 227 | #endif | ||
| 212 | 228 | ||
| 213 | . = ALIGN(PAGE_SIZE); | 229 | . = ALIGN(PAGE_SIZE); |
| 214 | __init_end = .; | 230 | __init_end = .; |
| 215 | 231 | ||
| 216 | . = ALIGN(PAGE_SIZE); | 232 | . = ALIGN(PAGE_SIZE); |
| 217 | __nosave_begin = .; | 233 | __nosave_begin = .; |
| 218 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } | 234 | .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { |
| 235 | *(.data.nosave) | ||
| 236 | } :data.init2 /* use another section data.init2, see PERCPU_VADDR() above */ | ||
| 219 | . = ALIGN(PAGE_SIZE); | 237 | . = ALIGN(PAGE_SIZE); |
| 220 | __nosave_end = .; | 238 | __nosave_end = .; |
| 221 | 239 | ||
| @@ -239,8 +257,21 @@ SECTIONS | |||
| 239 | DWARF_DEBUG | 257 | DWARF_DEBUG |
| 240 | } | 258 | } |
| 241 | 259 | ||
| 260 | /* | ||
| 261 | * Per-cpu symbols which need to be offset from __per_cpu_load | ||
| 262 | * for the boot processor. | ||
| 263 | */ | ||
| 264 | #define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load | ||
| 265 | INIT_PER_CPU(gdt_page); | ||
| 266 | INIT_PER_CPU(irq_stack_union); | ||
| 267 | |||
| 242 | /* | 268 | /* |
| 243 | * Build-time check on the image size: | 269 | * Build-time check on the image size: |
| 244 | */ | 270 | */ |
| 245 | ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), | 271 | ASSERT((_end - _text <= KERNEL_IMAGE_SIZE), |
| 246 | "kernel image bigger than KERNEL_IMAGE_SIZE") | 272 | "kernel image bigger than KERNEL_IMAGE_SIZE") |
| 273 | |||
| 274 | #ifdef CONFIG_SMP | ||
| 275 | ASSERT((per_cpu__irq_stack_union == 0), | ||
| 276 | "irq_stack_union is not at start of per-cpu area"); | ||
| 277 | #endif | ||
