diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 14:22:36 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-05-08 14:48:03 -0400 |
commit | 968ff9ee56f1e3ed4ff4a6d10185865dc77d8f7e (patch) | |
tree | 203601668b2e0ee01b9acdc19ef4732c46c0fe72 /arch/x86 | |
parent | 056a43a6d3ab903a798d8ee4435ad67d6fccc3e6 (diff) |
x86, realmode: Remove indirect jumps in trampoline_32 and wakeup_asm
Remove indirect jumps in trampoline_32.S and the 32-bit part of
wakeup_asm.S. There exist systems which are known to do weird
things if an SMI comes in right after a mode switch, and the
safest way to deal with it is to always follow with a simple
absolute far jump. In the 64-bit code we then to a register
indirect near jump; follow that pattern for the 32-bit code.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1336501366-28617-14-git-send-email-jarkko.sakkinen@intel.com
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/realmode/rm/trampoline_32.S | 22 | ||||
-rw-r--r-- | arch/x86/realmode/rm/wakeup/wakeup_asm.S | 8 |
2 files changed, 18 insertions, 12 deletions
diff --git a/arch/x86/realmode/rm/trampoline_32.S b/arch/x86/realmode/rm/trampoline_32.S index 1f9e3316f73d..1315ef48dbf1 100644 --- a/arch/x86/realmode/rm/trampoline_32.S +++ b/arch/x86/realmode/rm/trampoline_32.S | |||
@@ -47,24 +47,29 @@ trampoline_data: | |||
47 | 47 | ||
48 | cli # We should be safe anyway | 48 | cli # We should be safe anyway |
49 | 49 | ||
50 | movl startup_32_smp, %eax # where we need to go | ||
51 | |||
50 | movl $0xA5A5A5A5, trampoline_status | 52 | movl $0xA5A5A5A5, trampoline_status |
51 | # write marker for master knows we're running | 53 | # write marker for master knows we're running |
52 | 54 | ||
53 | /* GDT tables in non default location kernel can be beyond 16MB and | 55 | /* |
56 | * GDT tables in non default location kernel can be beyond 16MB and | ||
54 | * lgdt will not be able to load the address as in real mode default | 57 | * lgdt will not be able to load the address as in real mode default |
55 | * operand size is 16bit. Use lgdtl instead to force operand size | 58 | * operand size is 16bit. Use lgdtl instead to force operand size |
56 | * to 32 bit. | 59 | * to 32 bit. |
57 | */ | 60 | */ |
58 | |||
59 | lidtl boot_idt_descr # load idt with 0, 0 | 61 | lidtl boot_idt_descr # load idt with 0, 0 |
60 | lgdtl boot_gdt_descr # load gdt with whatever is appropriate | 62 | lgdtl boot_gdt_descr # load gdt with whatever is appropriate |
61 | 63 | ||
62 | xor %ax, %ax | 64 | movw $1, %dx # protected mode (PE) bit |
63 | inc %ax # protected mode (PE) bit | 65 | lmsw %dx # into protected mode |
64 | lmsw %ax # into protected mode | ||
65 | 66 | ||
66 | # flush prefetch and jump to startup_32_smp in arch/i386/kernel/head.S | 67 | ljmpl $__BOOT_CS, $pa_startup_32 |
67 | ljmpl *(startup_32_smp) | 68 | |
69 | .section ".text32","ax" | ||
70 | .code32 | ||
71 | ENTRY(startup_32) # note: also used from wakeup_asm.S | ||
72 | jmp *%eax | ||
68 | 73 | ||
69 | .data | 74 | .data |
70 | .globl startup_32_smp, boot_gdt, trampoline_status | 75 | .globl startup_32_smp, boot_gdt, trampoline_status |
@@ -82,5 +87,4 @@ trampoline_status: | |||
82 | .long 0 | 87 | .long 0 |
83 | 88 | ||
84 | startup_32_smp: | 89 | startup_32_smp: |
85 | .long 0x00000000 | 90 | .long 0 |
86 | .word __BOOT_CS, 0 | ||
diff --git a/arch/x86/realmode/rm/wakeup/wakeup_asm.S b/arch/x86/realmode/rm/wakeup/wakeup_asm.S index b61126cb599e..4c5c5f2bfbec 100644 --- a/arch/x86/realmode/rm/wakeup/wakeup_asm.S +++ b/arch/x86/realmode/rm/wakeup/wakeup_asm.S | |||
@@ -124,9 +124,11 @@ wakeup_start: | |||
124 | lgdtl pmode_gdt | 124 | lgdtl pmode_gdt |
125 | 125 | ||
126 | /* This really couldn't... */ | 126 | /* This really couldn't... */ |
127 | movl pmode_cr0, %eax | 127 | movl pmode_entry, %eax |
128 | movl %eax, %cr0 | 128 | movl pmode_cr0, %ecx |
129 | ljmpl *pmode_entry | 129 | movl %ecx, %cr0 |
130 | ljmpl $__KERNEL_CS, $pa_startup_32 | ||
131 | /* -> jmp *%eax in trampoline_32.S */ | ||
130 | #else | 132 | #else |
131 | jmp trampoline_data | 133 | jmp trampoline_data |
132 | #endif | 134 | #endif |