diff options
author | Jarkko Sakkinen <jarkko.sakkinen@intel.com> | 2012-05-08 14:22:28 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 14:41:51 -0400 |
commit | 48927bbb97c7d4cf343c05827ab9ac30c60678cb (patch) | |
tree | 715b2efa48c5678ada3d02a73f87e1538fe8c9b2 /arch/x86/kernel | |
parent | 5a8c9aebe04a78b069828d364798d5f24c5a42bd (diff) |
x86, realmode: Move SMP trampoline to unified realmode code
Migrated SMP trampoline code to the real mode blob.
SMP trampoline code is not yet removed from
.x86_trampoline because it is needed by the wakeup
code.
[ hpa: always enable compiling startup_32_smp in head_32.S... it is
only a few instructions which go into .init on UP builds, and it makes
the rest of the code less #ifdef ugly. ]
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-6-git-send-email-jarkko.sakkinen@intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/head_32.S | 5 | ||||
-rw-r--r-- | arch/x86/kernel/head_64.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/realmode.c | 14 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 18 |
4 files changed, 25 insertions, 16 deletions
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index ce0be7cd085..a3c2b4ffebc 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -273,10 +273,7 @@ num_subarch_entries = (. - subarch_entries) / 4 | |||
273 | * If cpu hotplug is not supported then this code can go in init section | 273 | * If cpu hotplug is not supported then this code can go in init section |
274 | * which will be freed later | 274 | * which will be freed later |
275 | */ | 275 | */ |
276 | |||
277 | __CPUINIT | 276 | __CPUINIT |
278 | |||
279 | #ifdef CONFIG_SMP | ||
280 | ENTRY(startup_32_smp) | 277 | ENTRY(startup_32_smp) |
281 | cld | 278 | cld |
282 | movl $(__BOOT_DS),%eax | 279 | movl $(__BOOT_DS),%eax |
@@ -287,7 +284,7 @@ ENTRY(startup_32_smp) | |||
287 | movl pa(stack_start),%ecx | 284 | movl pa(stack_start),%ecx |
288 | movl %eax,%ss | 285 | movl %eax,%ss |
289 | leal -__PAGE_OFFSET(%ecx),%esp | 286 | leal -__PAGE_OFFSET(%ecx),%esp |
290 | #endif /* CONFIG_SMP */ | 287 | |
291 | default_entry: | 288 | default_entry: |
292 | 289 | ||
293 | /* | 290 | /* |
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 40f4eb3766d..d70bc2eb202 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S | |||
@@ -136,10 +136,6 @@ ident_complete: | |||
136 | /* Fixup phys_base */ | 136 | /* Fixup phys_base */ |
137 | addq %rbp, phys_base(%rip) | 137 | addq %rbp, phys_base(%rip) |
138 | 138 | ||
139 | /* Fixup trampoline */ | ||
140 | addq %rbp, trampoline_level4_pgt + 0(%rip) | ||
141 | addq %rbp, trampoline_level4_pgt + (511*8)(%rip) | ||
142 | |||
143 | /* Due to ENTRY(), sometimes the empty space gets filled with | 139 | /* Due to ENTRY(), sometimes the empty space gets filled with |
144 | * zeros. Better take a jmp than relying on empty space being | 140 | * zeros. Better take a jmp than relying on empty space being |
145 | * filled with 0x90 (nop) | 141 | * filled with 0x90 (nop) |
diff --git a/arch/x86/kernel/realmode.c b/arch/x86/kernel/realmode.c index 7415c42547a..a465775b32f 100644 --- a/arch/x86/kernel/realmode.c +++ b/arch/x86/kernel/realmode.c | |||
@@ -58,6 +58,20 @@ void __init setup_real_mode(void) | |||
58 | /* Copied header will contain relocated physical addresses. */ | 58 | /* Copied header will contain relocated physical addresses. */ |
59 | memcpy(&real_mode_header, real_mode_base, | 59 | memcpy(&real_mode_header, real_mode_base, |
60 | sizeof(struct real_mode_header)); | 60 | sizeof(struct real_mode_header)); |
61 | |||
62 | #ifdef CONFIG_X86_32 | ||
63 | *((u32 *)__va(real_mode_header.startup_32_smp)) = __pa(startup_32_smp); | ||
64 | *((u32 *)__va(real_mode_header.boot_gdt)) = __pa(boot_gdt); | ||
65 | #else | ||
66 | *((u64 *) __va(real_mode_header.startup_64_smp)) = | ||
67 | (u64) __pa(secondary_startup_64); | ||
68 | |||
69 | *((u64 *) __va(real_mode_header.level3_ident_pgt)) = | ||
70 | __pa(level3_ident_pgt) + _KERNPG_TABLE; | ||
71 | |||
72 | *((u64 *) __va(real_mode_header.level3_kernel_pgt)) = | ||
73 | __pa(level3_kernel_pgt) + _KERNPG_TABLE; | ||
74 | #endif | ||
61 | } | 75 | } |
62 | 76 | ||
63 | /* | 77 | /* |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 6e1e406038c..c7971ea74bd 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -57,7 +57,7 @@ | |||
57 | #include <asm/nmi.h> | 57 | #include <asm/nmi.h> |
58 | #include <asm/irq.h> | 58 | #include <asm/irq.h> |
59 | #include <asm/idle.h> | 59 | #include <asm/idle.h> |
60 | #include <asm/trampoline.h> | 60 | #include <asm/realmode.h> |
61 | #include <asm/cpu.h> | 61 | #include <asm/cpu.h> |
62 | #include <asm/numa.h> | 62 | #include <asm/numa.h> |
63 | #include <asm/pgtable.h> | 63 | #include <asm/pgtable.h> |
@@ -73,6 +73,8 @@ | |||
73 | #include <asm/smpboot_hooks.h> | 73 | #include <asm/smpboot_hooks.h> |
74 | #include <asm/i8259.h> | 74 | #include <asm/i8259.h> |
75 | 75 | ||
76 | #include <asm/realmode.h> | ||
77 | |||
76 | /* State of each CPU */ | 78 | /* State of each CPU */ |
77 | DEFINE_PER_CPU(int, cpu_state) = { 0 }; | 79 | DEFINE_PER_CPU(int, cpu_state) = { 0 }; |
78 | 80 | ||
@@ -662,8 +664,12 @@ static void __cpuinit announce_cpu(int cpu, int apicid) | |||
662 | */ | 664 | */ |
663 | static int __cpuinit do_boot_cpu(int apicid, int cpu) | 665 | static int __cpuinit do_boot_cpu(int apicid, int cpu) |
664 | { | 666 | { |
667 | volatile u32 *trampoline_status = | ||
668 | (volatile u32 *) __va(real_mode_header.trampoline_status); | ||
669 | /* start_ip had better be page-aligned! */ | ||
670 | unsigned long start_ip = real_mode_header.trampoline_data; | ||
671 | |||
665 | unsigned long boot_error = 0; | 672 | unsigned long boot_error = 0; |
666 | unsigned long start_ip; | ||
667 | int timeout; | 673 | int timeout; |
668 | struct create_idle c_idle = { | 674 | struct create_idle c_idle = { |
669 | .cpu = cpu, | 675 | .cpu = cpu, |
@@ -713,9 +719,6 @@ do_rest: | |||
713 | initial_code = (unsigned long)start_secondary; | 719 | initial_code = (unsigned long)start_secondary; |
714 | stack_start = c_idle.idle->thread.sp; | 720 | stack_start = c_idle.idle->thread.sp; |
715 | 721 | ||
716 | /* start_ip had better be page-aligned! */ | ||
717 | start_ip = trampoline_address(); | ||
718 | |||
719 | /* So we see what's up */ | 722 | /* So we see what's up */ |
720 | announce_cpu(cpu, apicid); | 723 | announce_cpu(cpu, apicid); |
721 | 724 | ||
@@ -778,8 +781,7 @@ do_rest: | |||
778 | pr_debug("CPU%d: has booted.\n", cpu); | 781 | pr_debug("CPU%d: has booted.\n", cpu); |
779 | } else { | 782 | } else { |
780 | boot_error = 1; | 783 | boot_error = 1; |
781 | if (*(volatile u32 *)TRAMPOLINE_SYM(trampoline_status) | 784 | if (*trampoline_status == 0xA5A5A5A5) |
782 | == 0xA5A5A5A5) | ||
783 | /* trampoline started but...? */ | 785 | /* trampoline started but...? */ |
784 | pr_err("CPU%d: Stuck ??\n", cpu); | 786 | pr_err("CPU%d: Stuck ??\n", cpu); |
785 | else | 787 | else |
@@ -805,7 +807,7 @@ do_rest: | |||
805 | } | 807 | } |
806 | 808 | ||
807 | /* mark "stuck" area as not stuck */ | 809 | /* mark "stuck" area as not stuck */ |
808 | *(volatile u32 *)TRAMPOLINE_SYM(trampoline_status) = 0; | 810 | *trampoline_status = 0; |
809 | 811 | ||
810 | if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { | 812 | if (get_uv_system_type() != UV_NON_UNIQUE_APIC) { |
811 | /* | 813 | /* |