diff options
author | Tejun Heo <tj@kernel.org> | 2009-01-13 06:41:35 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-16 08:19:26 -0500 |
commit | f32ff5388d86518c0375ccdb330d3b459b9c405e (patch) | |
tree | 8551cb03dcbbfafaac3500aac18fee811b0f1ffe /arch | |
parent | 3e5d8f978435bb9ba4dfe3f4514e65e7885db1a9 (diff) |
x86: load pointer to pda into %gs while brining up a CPU
[ Based on original patch from Christoph Lameter and Mike Travis. ]
CPU startup code in head_64.S loaded address of a zero page into %gs
for temporary use till pda is loaded but address to the actual pda is
available at the point. Load the real address directly instead.
This will help unifying percpu and pda handling later on.
This patch is mostly taken from Mike Travis' "x86_64: Fold pda into
per cpu area" patch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/trampoline.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/head64.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 15 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 1 |
5 files changed, 15 insertions, 7 deletions
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h index 780ba0ab94f9..90f06c25221d 100644 --- a/arch/x86/include/asm/trampoline.h +++ b/arch/x86/include/asm/trampoline.h | |||
@@ -13,6 +13,7 @@ extern unsigned char *trampoline_base; | |||
13 | 13 | ||
14 | extern unsigned long init_rsp; | 14 | extern unsigned long init_rsp; |
15 | extern unsigned long initial_code; | 15 | extern unsigned long initial_code; |
16 | extern unsigned long initial_gs; | ||
16 | 17 | ||
17 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) | 18 | #define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE) |
18 | #define TRAMPOLINE_BASE 0x6000 | 19 | #define TRAMPOLINE_BASE 0x6000 |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 707c1f6f95fa..9ff67f8dc2c0 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -101,6 +101,7 @@ int acpi_save_state_mem(void) | |||
101 | stack_start.sp = temp_stack + sizeof(temp_stack); | 101 | stack_start.sp = temp_stack + sizeof(temp_stack); |
102 | early_gdt_descr.address = | 102 | early_gdt_descr.address = |
103 | (unsigned long)get_cpu_gdt_table(smp_processor_id()); | 103 | (unsigned long)get_cpu_gdt_table(smp_processor_id()); |
104 | initial_gs = (unsigned long)cpu_pda(smp_processor_id()); | ||
104 | #endif | 105 | #endif |
105 | initial_code = (unsigned long)wakeup_long64; | 106 | initial_code = (unsigned long)wakeup_long64; |
106 | saved_magic = 0x123456789abcdef0; | 107 | saved_magic = 0x123456789abcdef0; |
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index bc2900ca82c7..76ffba2aa66d 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -26,8 +26,8 @@ | |||
26 | #include <asm/bios_ebda.h> | 26 | #include <asm/bios_ebda.h> |
27 | #include <asm/trampoline.h> | 27 | #include <asm/trampoline.h> |
28 | 28 | ||
29 | /* boot cpu pda */ | 29 | /* boot cpu pda, referenced by head_64.S to initialize %gs for boot CPU */ |
30 | static struct x8664_pda _boot_cpu_pda; | 30 | struct x8664_pda _boot_cpu_pda; |
31 | 31 | ||
32 | #ifdef CONFIG_SMP | 32 | #ifdef CONFIG_SMP |
33 | /* | 33 | /* |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 7ee0363871e8..2f0ab0089883 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -243,12 +243,15 @@ ENTRY(secondary_startup_64) | |||
243 | movl %eax,%fs | 243 | movl %eax,%fs |
244 | movl %eax,%gs | 244 | movl %eax,%gs |
245 | 245 | ||
246 | /* | 246 | /* Set up %gs. |
247 | * Setup up a dummy PDA. this is just for some early bootup code | 247 | * |
248 | * that does in_interrupt() | 248 | * %gs should point to the pda. For initial boot, make %gs point |
249 | */ | 249 | * to the _boot_cpu_pda in data section. For a secondary CPU, |
250 | * initial_gs should be set to its pda address before the CPU runs | ||
251 | * this code. | ||
252 | */ | ||
250 | movl $MSR_GS_BASE,%ecx | 253 | movl $MSR_GS_BASE,%ecx |
251 | movq $empty_zero_page,%rax | 254 | movq initial_gs(%rip),%rax |
252 | movq %rax,%rdx | 255 | movq %rax,%rdx |
253 | shrq $32,%rdx | 256 | shrq $32,%rdx |
254 | wrmsr | 257 | wrmsr |
@@ -274,6 +277,8 @@ ENTRY(secondary_startup_64) | |||
274 | .align 8 | 277 | .align 8 |
275 | ENTRY(initial_code) | 278 | ENTRY(initial_code) |
276 | .quad x86_64_start_kernel | 279 | .quad x86_64_start_kernel |
280 | ENTRY(initial_gs) | ||
281 | .quad _boot_cpu_pda | ||
277 | __FINITDATA | 282 | __FINITDATA |
278 | 283 | ||
279 | ENTRY(stack_start) | 284 | ENTRY(stack_start) |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 1a712da1dfa0..70d846628bbf 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -854,6 +854,7 @@ do_rest: | |||
854 | #else | 854 | #else |
855 | cpu_pda(cpu)->pcurrent = c_idle.idle; | 855 | cpu_pda(cpu)->pcurrent = c_idle.idle; |
856 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); | 856 | clear_tsk_thread_flag(c_idle.idle, TIF_FORK); |
857 | initial_gs = (unsigned long)cpu_pda(cpu); | ||
857 | #endif | 858 | #endif |
858 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); | 859 | early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
859 | initial_code = (unsigned long)start_secondary; | 860 | initial_code = (unsigned long)start_secondary; |