aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
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:26 -0500
commitf32ff5388d86518c0375ccdb330d3b459b9c405e (patch)
tree8551cb03dcbbfafaac3500aac18fee811b0f1ffe /arch/x86/kernel
parent3e5d8f978435bb9ba4dfe3f4514e65e7885db1a9 (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/x86/kernel')
-rw-r--r--arch/x86/kernel/acpi/sleep.c1
-rw-r--r--arch/x86/kernel/head64.c4
-rw-r--r--arch/x86/kernel/head_64.S15
-rw-r--r--arch/x86/kernel/smpboot.c1
4 files changed, 14 insertions, 7 deletions
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 */
30static struct x8664_pda _boot_cpu_pda; 30struct 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;