Skip to content

Commit

Permalink
x86: load pointer to pda into %gs while brining up a CPU
Browse files Browse the repository at this point in the history
[ 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>
  • Loading branch information
Tejun Heo authored and Ingo Molnar committed Jan 16, 2009
1 parent 3e5d8f9 commit f32ff53
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 7 deletions.
1 change: 1 addition & 0 deletions arch/x86/include/asm/trampoline.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ extern unsigned char *trampoline_base;

extern unsigned long init_rsp;
extern unsigned long initial_code;
extern unsigned long initial_gs;

#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
#define TRAMPOLINE_BASE 0x6000
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/acpi/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ int acpi_save_state_mem(void)
stack_start.sp = temp_stack + sizeof(temp_stack);
early_gdt_descr.address =
(unsigned long)get_cpu_gdt_table(smp_processor_id());
initial_gs = (unsigned long)cpu_pda(smp_processor_id());
#endif
initial_code = (unsigned long)wakeup_long64;
saved_magic = 0x123456789abcdef0;
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/head64.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
#include <asm/bios_ebda.h>
#include <asm/trampoline.h>

/* boot cpu pda */
static struct x8664_pda _boot_cpu_pda;
/* boot cpu pda, referenced by head_64.S to initialize %gs for boot CPU */
struct x8664_pda _boot_cpu_pda;

#ifdef CONFIG_SMP
/*
Expand Down
15 changes: 10 additions & 5 deletions arch/x86/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,15 @@ ENTRY(secondary_startup_64)
movl %eax,%fs
movl %eax,%gs

/*
* Setup up a dummy PDA. this is just for some early bootup code
* that does in_interrupt()
*/
/* Set up %gs.
*
* %gs should point to the pda. For initial boot, make %gs point
* to the _boot_cpu_pda in data section. For a secondary CPU,
* initial_gs should be set to its pda address before the CPU runs
* this code.
*/
movl $MSR_GS_BASE,%ecx
movq $empty_zero_page,%rax
movq initial_gs(%rip),%rax
movq %rax,%rdx
shrq $32,%rdx
wrmsr
Expand All @@ -274,6 +277,8 @@ ENTRY(secondary_startup_64)
.align 8
ENTRY(initial_code)
.quad x86_64_start_kernel
ENTRY(initial_gs)
.quad _boot_cpu_pda
__FINITDATA

ENTRY(stack_start)
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
#else
cpu_pda(cpu)->pcurrent = c_idle.idle;
clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
initial_gs = (unsigned long)cpu_pda(cpu);
#endif
early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
initial_code = (unsigned long)start_secondary;
Expand Down

0 comments on commit f32ff53

Please sign in to comment.