diff options
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
-rw-r--r-- | arch/x86/kernel/entry_32.S | 293 |
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 |
167 | 1: popl %ds; \ | 169 | 1: popl %ds |
168 | CFI_ADJUST_CFA_OFFSET -4;\ | 170 | CFI_ADJUST_CFA_OFFSET -4 |
169 | /*CFI_RESTORE ds;*/\ | 171 | /*CFI_RESTORE ds;*/ |
170 | 2: popl %es; \ | 172 | 2: popl %es |
171 | CFI_ADJUST_CFA_OFFSET -4;\ | 173 | CFI_ADJUST_CFA_OFFSET -4 |
172 | /*CFI_RESTORE es;*/\ | 174 | /*CFI_RESTORE es;*/ |
173 | 3: popl %fs; \ | 175 | 3: 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" |
177 | 4: movl $0,(%esp); \ | 179 | 4: movl $0, (%esp) |
178 | jmp 1b; \ | 180 | jmp 1b |
179 | 5: movl $0,(%esp); \ | 181 | 5: movl $0, (%esp) |
180 | jmp 2b; \ | 182 | jmp 2b |
181 | 6: movl $0,(%esp); \ | 183 | 6: 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 | ||
220 | ENTRY(ret_from_fork) | 226 | ENTRY(ret_from_fork) |
221 | CFI_STARTPROC | 227 | CFI_STARTPROC |
@@ -595,28 +601,30 @@ syscall_badsys: | |||
595 | END(syscall_badsys) | 601 | END(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 */ |
619 | 27:; | 625 | FIXUP_ESPFIX_STACK |
626 | 27: | ||
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 |
1142 | label: \ | 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 | ||
1154 | ENTRY(debug) | 1163 | ENTRY(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 |
1159 | debug_stack_correct: | 1168 | debug_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 | ||
1214 | nmi_stack_fixup: | 1223 | nmi_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 | ||
1219 | nmi_debug_stack_check: | 1228 | nmi_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 | ||
1230 | nmi_espfix_stack: | 1239 | nmi_espfix_stack: |