aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@in.ibm.com>2006-01-11 21:35:20 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-11 22:09:58 -0500
commit983d5dbdb2b38d024935f560a91cddcf704875f3 (patch)
tree834cda0f26f3902aea74d1cd81a9202f78cc5f14 /arch/x86_64
parent0d9cb75f2f41788a59bcd3dac30b264a4bebaf2e (diff)
[PATCH] x86_64: Fix SMP bootup with CONFIG_KDUMP enabled
o This fix was posted for i386 long back. Posting it for x86_64. http://marc.theaimsgroup.com/?l=linux-kernel&m=110380103229830&w=2 o This patch fixes the problem of secondary cpus boot up. This situation is faced when kernel is built for default locations like 16MB and onwards. In this configuration, only primary cpu (BP) comes and secondary cpus don't boot. o Problem occurs because in trampoline code, lgdt is not able to load the GDT as it happens to be situated beyond 16MB. This is due to the fact that cpu is still in real mode and default operand size is 16bit. o This patch uses lgdtl instead of lgdt to force operand size to 32 instead of 16. Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/kernel/trampoline.S11
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/trampoline.S b/arch/x86_64/kernel/trampoline.S
index 6d9c9a8e7d0e..23a03eb91fc7 100644
--- a/arch/x86_64/kernel/trampoline.S
+++ b/arch/x86_64/kernel/trampoline.S
@@ -42,8 +42,15 @@ r_base = .
42 movl $0xA5A5A5A5, trampoline_data - r_base 42 movl $0xA5A5A5A5, trampoline_data - r_base
43 # write marker for master knows we're running 43 # write marker for master knows we're running
44 44
45 lidt idt_48 - r_base # load idt with 0, 0 45 /*
46 lgdt gdt_48 - r_base # load gdt with whatever is appropriate 46 * GDT tables in non default location kernel can be beyond 16MB and
47 * lgdt will not be able to load the address as in real mode default
48 * operand size is 16bit. Use lgdtl instead to force operand size
49 * to 32 bit.
50 */
51
52 lidtl idt_48 - r_base # load idt with 0, 0
53 lgdtl gdt_48 - r_base # load gdt with whatever is appropriate
47 54
48 xor %ax, %ax 55 xor %ax, %ax
49 inc %ax # protected mode (PE) bit 56 inc %ax # protected mode (PE) bit