aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/entry_32.S293
1 files changed, 151 insertions, 142 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index a0b91aac72a1..c461925d3b64 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -101,121 +101,127 @@
101#define resume_userspace_sig resume_userspace 101#define resume_userspace_sig resume_userspace
102#endif 102#endif
103 103
104#define SAVE_ALL \ 104.macro SAVE_ALL
105 cld; \ 105 cld
106 pushl %fs; \ 106 pushl %fs
107 CFI_ADJUST_CFA_OFFSET 4;\ 107 CFI_ADJUST_CFA_OFFSET 4
108 /*CFI_REL_OFFSET fs, 0;*/\ 108 /*CFI_REL_OFFSET fs, 0;*/
109 pushl %es; \ 109 pushl %es
110 CFI_ADJUST_CFA_OFFSET 4;\ 110 CFI_ADJUST_CFA_OFFSET 4
111 /*CFI_REL_OFFSET es, 0;*/\ 111 /*CFI_REL_OFFSET es, 0;*/
112 pushl %ds; \ 112 pushl %ds
113 CFI_ADJUST_CFA_OFFSET 4;\ 113 CFI_ADJUST_CFA_OFFSET 4
114 /*CFI_REL_OFFSET ds, 0;*/\ 114 /*CFI_REL_OFFSET ds, 0;*/
115 pushl %eax; \ 115 pushl %eax
116 CFI_ADJUST_CFA_OFFSET 4;\ 116 CFI_ADJUST_CFA_OFFSET 4
117 CFI_REL_OFFSET eax, 0;\ 117 CFI_REL_OFFSET eax, 0
118 pushl %ebp; \ 118 pushl %ebp
119 CFI_ADJUST_CFA_OFFSET 4;\ 119 CFI_ADJUST_CFA_OFFSET 4
120 CFI_REL_OFFSET ebp, 0;\ 120 CFI_REL_OFFSET ebp, 0
121 pushl %edi; \ 121 pushl %edi
122 CFI_ADJUST_CFA_OFFSET 4;\ 122 CFI_ADJUST_CFA_OFFSET 4
123 CFI_REL_OFFSET edi, 0;\ 123 CFI_REL_OFFSET edi, 0
124 pushl %esi; \ 124 pushl %esi
125 CFI_ADJUST_CFA_OFFSET 4;\ 125 CFI_ADJUST_CFA_OFFSET 4
126 CFI_REL_OFFSET esi, 0;\ 126 CFI_REL_OFFSET esi, 0
127 pushl %edx; \ 127 pushl %edx
128 CFI_ADJUST_CFA_OFFSET 4;\ 128 CFI_ADJUST_CFA_OFFSET 4
129 CFI_REL_OFFSET edx, 0;\ 129 CFI_REL_OFFSET edx, 0
130 pushl %ecx; \ 130 pushl %ecx
131 CFI_ADJUST_CFA_OFFSET 4;\ 131 CFI_ADJUST_CFA_OFFSET 4
132 CFI_REL_OFFSET ecx, 0;\ 132 CFI_REL_OFFSET ecx, 0
133 pushl %ebx; \ 133 pushl %ebx
134 CFI_ADJUST_CFA_OFFSET 4;\ 134 CFI_ADJUST_CFA_OFFSET 4
135 CFI_REL_OFFSET ebx, 0;\ 135 CFI_REL_OFFSET ebx, 0
136 movl $(__USER_DS), %edx; \ 136 movl $(__USER_DS), %edx
137 movl %edx, %ds; \ 137 movl %edx, %ds
138 movl %edx, %es; \ 138 movl %edx, %es
139 movl $(__KERNEL_PERCPU), %edx; \ 139 movl $(__KERNEL_PERCPU), %edx
140 movl %edx, %fs 140 movl %edx, %fs
141.endm
141 142
142#define RESTORE_INT_REGS \ 143.macro RESTORE_INT_REGS
143 popl %ebx; \ 144 popl %ebx
144 CFI_ADJUST_CFA_OFFSET -4;\ 145 CFI_ADJUST_CFA_OFFSET -4
145 CFI_RESTORE ebx;\ 146 CFI_RESTORE ebx
146 popl %ecx; \ 147 popl %ecx
147 CFI_ADJUST_CFA_OFFSET -4;\ 148 CFI_ADJUST_CFA_OFFSET -4
148 CFI_RESTORE ecx;\ 149 CFI_RESTORE ecx
149 popl %edx; \ 150 popl %edx
150 CFI_ADJUST_CFA_OFFSET -4;\ 151 CFI_ADJUST_CFA_OFFSET -4
151 CFI_RESTORE edx;\ 152 CFI_RESTORE edx
152 popl %esi; \ 153 popl %esi
153 CFI_ADJUST_CFA_OFFSET -4;\ 154 CFI_ADJUST_CFA_OFFSET -4
154 CFI_RESTORE esi;\ 155 CFI_RESTORE esi
155 popl %edi; \ 156 popl %edi
156 CFI_ADJUST_CFA_OFFSET -4;\ 157 CFI_ADJUST_CFA_OFFSET -4
157 CFI_RESTORE edi;\ 158 CFI_RESTORE edi
158 popl %ebp; \ 159 popl %ebp
159 CFI_ADJUST_CFA_OFFSET -4;\ 160 CFI_ADJUST_CFA_OFFSET -4
160 CFI_RESTORE ebp;\ 161 CFI_RESTORE ebp
161 popl %eax; \ 162 popl %eax
162 CFI_ADJUST_CFA_OFFSET -4;\ 163 CFI_ADJUST_CFA_OFFSET -4
163 CFI_RESTORE eax 164 CFI_RESTORE eax
165.endm
164 166
165#define RESTORE_REGS \ 167.macro RESTORE_REGS
166 RESTORE_INT_REGS; \ 168 RESTORE_INT_REGS
1671: popl %ds; \ 1691: popl %ds
168 CFI_ADJUST_CFA_OFFSET -4;\ 170 CFI_ADJUST_CFA_OFFSET -4
169 /*CFI_RESTORE ds;*/\ 171 /*CFI_RESTORE ds;*/
1702: popl %es; \ 1722: popl %es
171 CFI_ADJUST_CFA_OFFSET -4;\ 173 CFI_ADJUST_CFA_OFFSET -4
172 /*CFI_RESTORE es;*/\ 174 /*CFI_RESTORE es;*/
1733: popl %fs; \ 1753: popl %fs
174 CFI_ADJUST_CFA_OFFSET -4;\ 176 CFI_ADJUST_CFA_OFFSET -4
175 /*CFI_RESTORE fs;*/\ 177 /*CFI_RESTORE fs;*/
176.pushsection .fixup,"ax"; \ 178.pushsection .fixup, "ax"
1774: movl $0,(%esp); \ 1794: movl $0, (%esp)
178 jmp 1b; \ 180 jmp 1b
1795: movl $0,(%esp); \ 1815: movl $0, (%esp)
180 jmp 2b; \ 182 jmp 2b
1816: movl $0,(%esp); \ 1836: movl $0, (%esp)
182 jmp 3b; \ 184 jmp 3b
183.section __ex_table,"a";\ 185.section __ex_table, "a"
184 .align 4; \ 186 .align 4
185 .long 1b,4b; \ 187 .long 1b, 4b
186 .long 2b,5b; \ 188 .long 2b, 5b
187 .long 3b,6b; \ 189 .long 3b, 6b
188.popsection 190.popsection
191.endm
189 192
190#define RING0_INT_FRAME \ 193.macro RING0_INT_FRAME
191 CFI_STARTPROC simple;\ 194 CFI_STARTPROC simple
192 CFI_SIGNAL_FRAME;\ 195 CFI_SIGNAL_FRAME
193 CFI_DEF_CFA esp, 3*4;\ 196 CFI_DEF_CFA esp, 3*4
194 /*CFI_OFFSET cs, -2*4;*/\ 197 /*CFI_OFFSET cs, -2*4;*/
195 CFI_OFFSET eip, -3*4 198 CFI_OFFSET eip, -3*4
199.endm
196 200
197#define RING0_EC_FRAME \ 201.macro RING0_EC_FRAME
198 CFI_STARTPROC simple;\ 202 CFI_STARTPROC simple
199 CFI_SIGNAL_FRAME;\ 203 CFI_SIGNAL_FRAME
200 CFI_DEF_CFA esp, 4*4;\ 204 CFI_DEF_CFA esp, 4*4
201 /*CFI_OFFSET cs, -2*4;*/\ 205 /*CFI_OFFSET cs, -2*4;*/
202 CFI_OFFSET eip, -3*4 206 CFI_OFFSET eip, -3*4
207.endm
203 208
204#define RING0_PTREGS_FRAME \ 209.macro RING0_PTREGS_FRAME
205 CFI_STARTPROC simple;\ 210 CFI_STARTPROC simple
206 CFI_SIGNAL_FRAME;\ 211 CFI_SIGNAL_FRAME
207 CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\ 212 CFI_DEF_CFA esp, PT_OLDESP-PT_EBX
208 /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\ 213 /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/
209 CFI_OFFSET eip, PT_EIP-PT_OLDESP;\ 214 CFI_OFFSET eip, PT_EIP-PT_OLDESP
210 /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\ 215 /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/
211 /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\ 216 /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/
212 CFI_OFFSET eax, PT_EAX-PT_OLDESP;\ 217 CFI_OFFSET eax, PT_EAX-PT_OLDESP
213 CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\ 218 CFI_OFFSET ebp, PT_EBP-PT_OLDESP
214 CFI_OFFSET edi, PT_EDI-PT_OLDESP;\ 219 CFI_OFFSET edi, PT_EDI-PT_OLDESP
215 CFI_OFFSET esi, PT_ESI-PT_OLDESP;\ 220 CFI_OFFSET esi, PT_ESI-PT_OLDESP
216 CFI_OFFSET edx, PT_EDX-PT_OLDESP;\ 221 CFI_OFFSET edx, PT_EDX-PT_OLDESP
217 CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\ 222 CFI_OFFSET ecx, PT_ECX-PT_OLDESP
218 CFI_OFFSET ebx, PT_EBX-PT_OLDESP 223 CFI_OFFSET ebx, PT_EBX-PT_OLDESP
224.endm
219 225
220ENTRY(ret_from_fork) 226ENTRY(ret_from_fork)
221 CFI_STARTPROC 227 CFI_STARTPROC
@@ -595,28 +601,30 @@ syscall_badsys:
595END(syscall_badsys) 601END(syscall_badsys)
596 CFI_ENDPROC 602 CFI_ENDPROC
597 603
598#define FIXUP_ESPFIX_STACK \ 604.macro FIXUP_ESPFIX_STACK
599 /* since we are on a wrong stack, we cant make it a C code :( */ \ 605 /* since we are on a wrong stack, we cant make it a C code :( */
600 PER_CPU(gdt_page, %ebx); \ 606 PER_CPU(gdt_page, %ebx)
601 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ 607 GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah)
602 addl %esp, %eax; \ 608 addl %esp, %eax
603 pushl $__KERNEL_DS; \ 609 pushl $__KERNEL_DS
604 CFI_ADJUST_CFA_OFFSET 4; \ 610 CFI_ADJUST_CFA_OFFSET 4
605 pushl %eax; \ 611 pushl %eax
606 CFI_ADJUST_CFA_OFFSET 4; \ 612 CFI_ADJUST_CFA_OFFSET 4
607 lss (%esp), %esp; \ 613 lss (%esp), %esp
608 CFI_ADJUST_CFA_OFFSET -8; 614 CFI_ADJUST_CFA_OFFSET -8
609#define UNWIND_ESPFIX_STACK \ 615.endm
610 movl %ss, %eax; \ 616.macro UNWIND_ESPFIX_STACK
611 /* see if on espfix stack */ \ 617 movl %ss, %eax
612 cmpw $__ESPFIX_SS, %ax; \ 618 /* see if on espfix stack */
613 jne 27f; \ 619 cmpw $__ESPFIX_SS, %ax
614 movl $__KERNEL_DS, %eax; \ 620 jne 27f
615 movl %eax, %ds; \ 621 movl $__KERNEL_DS, %eax
616 movl %eax, %es; \ 622 movl %eax, %ds
617 /* switch to normal stack */ \ 623 movl %eax, %es
618 FIXUP_ESPFIX_STACK; \ 624 /* switch to normal stack */
61927:; 625 FIXUP_ESPFIX_STACK
62627:
627.endm
620 628
621/* 629/*
622 * Build the entry stubs and pointer table with some assembler magic. 630 * Build the entry stubs and pointer table with some assembler magic.
@@ -1136,26 +1144,27 @@ END(page_fault)
1136 * by hand onto the new stack - while updating the return eip past 1144 * by hand onto the new stack - while updating the return eip past
1137 * the instruction that would have done it for sysenter. 1145 * the instruction that would have done it for sysenter.
1138 */ 1146 */
1139#define FIX_STACK(offset, ok, label) \ 1147.macro FIX_STACK offset ok label
1140 cmpw $__KERNEL_CS,4(%esp); \ 1148 cmpw $__KERNEL_CS, 4(%esp)
1141 jne ok; \ 1149 jne \ok
1142label: \ 1150\label:
1143 movl TSS_sysenter_sp0+offset(%esp),%esp; \ 1151 movl TSS_sysenter_sp0 + \offset(%esp), %esp
1144 CFI_DEF_CFA esp, 0; \ 1152 CFI_DEF_CFA esp, 0
1145 CFI_UNDEFINED eip; \ 1153 CFI_UNDEFINED eip
1146 pushfl; \ 1154 pushfl
1147 CFI_ADJUST_CFA_OFFSET 4; \ 1155 CFI_ADJUST_CFA_OFFSET 4
1148 pushl $__KERNEL_CS; \ 1156 pushl $__KERNEL_CS
1149 CFI_ADJUST_CFA_OFFSET 4; \ 1157 CFI_ADJUST_CFA_OFFSET 4
1150 pushl $sysenter_past_esp; \ 1158 pushl $sysenter_past_esp
1151 CFI_ADJUST_CFA_OFFSET 4; \ 1159 CFI_ADJUST_CFA_OFFSET 4
1152 CFI_REL_OFFSET eip, 0 1160 CFI_REL_OFFSET eip, 0
1161.endm
1153 1162
1154ENTRY(debug) 1163ENTRY(debug)
1155 RING0_INT_FRAME 1164 RING0_INT_FRAME
1156 cmpl $ia32_sysenter_target,(%esp) 1165 cmpl $ia32_sysenter_target,(%esp)
1157 jne debug_stack_correct 1166 jne debug_stack_correct
1158 FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) 1167 FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn
1159debug_stack_correct: 1168debug_stack_correct:
1160 pushl $-1 # mark this as an int 1169 pushl $-1 # mark this as an int
1161 CFI_ADJUST_CFA_OFFSET 4 1170 CFI_ADJUST_CFA_OFFSET 4
@@ -1213,7 +1222,7 @@ nmi_stack_correct:
1213 1222
1214nmi_stack_fixup: 1223nmi_stack_fixup:
1215 RING0_INT_FRAME 1224 RING0_INT_FRAME
1216 FIX_STACK(12,nmi_stack_correct, 1) 1225 FIX_STACK 12, nmi_stack_correct, 1
1217 jmp nmi_stack_correct 1226 jmp nmi_stack_correct
1218 1227
1219nmi_debug_stack_check: 1228nmi_debug_stack_check:
@@ -1224,7 +1233,7 @@ nmi_debug_stack_check:
1224 jb nmi_stack_correct 1233 jb nmi_stack_correct
1225 cmpl $debug_esp_fix_insn,(%esp) 1234 cmpl $debug_esp_fix_insn,(%esp)
1226 ja nmi_stack_correct 1235 ja nmi_stack_correct
1227 FIX_STACK(24,nmi_stack_correct, 1) 1236 FIX_STACK 24, nmi_stack_correct, 1
1228 jmp nmi_stack_correct 1237 jmp nmi_stack_correct
1229 1238
1230nmi_espfix_stack: 1239nmi_espfix_stack: