diff options
Diffstat (limited to 'arch/x86/kernel/head_64.S')
-rw-r--r-- | arch/x86/kernel/head_64.S | 37 |
1 files changed, 13 insertions, 24 deletions
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) | ||
223 | 1: | 219 | 1: |
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 |
432 | early_gdt_descr: | 425 | early_gdt_descr: |
433 | .word GDT_ENTRIES*8-1 | 426 | .word GDT_ENTRIES*8-1 |
434 | #ifdef CONFIG_SMP | ||
435 | early_gdt_descr_base: | 427 | early_gdt_descr_base: |
436 | .quad 0x0000000000000000 | ||
437 | #else | ||
438 | .quad per_cpu__gdt_page | 428 | .quad per_cpu__gdt_page |
439 | #endif | ||
440 | 429 | ||
441 | ENTRY(phys_base) | 430 | ENTRY(phys_base) |
442 | /* This must match the first entry in level2_kernel_pgt */ | 431 | /* This must match the first entry in level2_kernel_pgt */ |