summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
authorJarkko Sakkinen <jarkko.sakkinen@intel.com>2012-05-08 21:22:43 +0300
committerH. Peter Anvin <hpa@linux.intel.com>2012-05-08 11:48:45 -0700
commitf37240f16bec91f15ce564515f70a6ca9715ce96 (patch)
treed1e98241650bfed0d87f60e3e71a8ad716782f6d /arch/x86/kernel
parentc4845474a01f699966272536e8416222e3f2d2cb (diff)
downloadlinux-f37240f16bec91f15ce564515f70a6ca9715ce96.tar.gz
linux-f37240f16bec91f15ce564515f70a6ca9715ce96.tar.bz2
linux-f37240f16bec91f15ce564515f70a6ca9715ce96.zip
x86, realmode: header for trampoline code
Added header for trampoline code that can be used to supply input data to it. This makes interface between real mode code and kernel cleaner and simpler. Replaced two confusing pointers to level4 pgt in trampoline_64.S with a single pointer to the beginning of the page table. Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@intel.com> Link: http://lkml.kernel.org/r/1336501366-28617-21-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/realmode.c27
-rw-r--r--arch/x86/kernel/smpboot.c2
2 files changed, 16 insertions, 13 deletions
diff --git a/arch/x86/kernel/realmode.c b/arch/x86/kernel/realmode.c
index 632c810ec8ea..712fba8fd774 100644
--- a/arch/x86/kernel/realmode.c
+++ b/arch/x86/kernel/realmode.c
@@ -17,8 +17,11 @@ void __init setup_real_mode(void)
u16 *seg;
int i;
unsigned char *base;
-
+ struct trampoline_header *trampoline_header;
size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob);
+#ifdef CONFIG_X86_64
+ u64 *trampoline_pgd;
+#endif
/* Has to be in very low memory so we can execute real-mode AP code. */
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
@@ -28,7 +31,6 @@ void __init setup_real_mode(void)
base = __va(mem);
memblock_reserve(mem, size);
real_mode_header = (struct real_mode_header *) base;
-
printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
base, (unsigned long long)mem, size);
@@ -53,18 +55,19 @@ void __init setup_real_mode(void)
*ptr += __pa(base);
}
+ /* Must be perfomed *after* relocation. */
+ trampoline_header = (struct trampoline_header *)
+ __va(real_mode_header->trampoline_header);
+
#ifdef CONFIG_X86_32
- *((u32 *)__va(real_mode_header->startup_32_smp)) = __pa(startup_32_smp);
- *((u32 *)__va(real_mode_header->boot_gdt)) = __pa(boot_gdt);
+ trampoline_header->start = __pa(startup_32_smp);
+ trampoline_header->gdt_limit = __BOOT_DS + 7;
+ trampoline_header->gdt_base = __pa(boot_gdt);
#else
- *((u64 *) __va(real_mode_header->startup_64_smp)) =
- (u64)secondary_startup_64;
-
- *((u64 *) __va(real_mode_header->level3_ident_pgt)) =
- __pa(level3_ident_pgt) + _KERNPG_TABLE;
-
- *((u64 *) __va(real_mode_header->level3_kernel_pgt)) =
- __pa(level3_kernel_pgt) + _KERNPG_TABLE;
+ trampoline_header->start = (u64) secondary_startup_64;
+ trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd);
+ trampoline_pgd[0] = __pa(level3_ident_pgt) + _KERNPG_TABLE;
+ trampoline_pgd[511] = __pa(level3_kernel_pgt) + _KERNPG_TABLE;
#endif
}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index b8c0661e2341..757c4b1d0a02 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -667,7 +667,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
volatile u32 *trampoline_status =
(volatile u32 *) __va(real_mode_header->trampoline_status);
/* start_ip had better be page-aligned! */
- unsigned long start_ip = real_mode_header->trampoline_data;
+ unsigned long start_ip = real_mode_header->trampoline_start;
unsigned long boot_error = 0;
int timeout;