diff options
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
| -rw-r--r-- | arch/x86/kernel/entry_32.S | 455 |
1 files changed, 290 insertions, 165 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 46469029e9d..899e8938e79 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
| @@ -30,12 +30,13 @@ | |||
| 30 | * 1C(%esp) - %ds | 30 | * 1C(%esp) - %ds |
| 31 | * 20(%esp) - %es | 31 | * 20(%esp) - %es |
| 32 | * 24(%esp) - %fs | 32 | * 24(%esp) - %fs |
| 33 | * 28(%esp) - orig_eax | 33 | * 28(%esp) - %gs saved iff !CONFIG_X86_32_LAZY_GS |
| 34 | * 2C(%esp) - %eip | 34 | * 2C(%esp) - orig_eax |
| 35 | * 30(%esp) - %cs | 35 | * 30(%esp) - %eip |
| 36 | * 34(%esp) - %eflags | 36 | * 34(%esp) - %cs |
| 37 | * 38(%esp) - %oldesp | 37 | * 38(%esp) - %eflags |
| 38 | * 3C(%esp) - %oldss | 38 | * 3C(%esp) - %oldesp |
| 39 | * 40(%esp) - %oldss | ||
| 39 | * | 40 | * |
| 40 | * "current" is in register %ebx during any slow entries. | 41 | * "current" is in register %ebx during any slow entries. |
| 41 | */ | 42 | */ |
| @@ -46,7 +47,7 @@ | |||
| 46 | #include <asm/errno.h> | 47 | #include <asm/errno.h> |
| 47 | #include <asm/segment.h> | 48 | #include <asm/segment.h> |
| 48 | #include <asm/smp.h> | 49 | #include <asm/smp.h> |
| 49 | #include <asm/page.h> | 50 | #include <asm/page_types.h> |
| 50 | #include <asm/desc.h> | 51 | #include <asm/desc.h> |
| 51 | #include <asm/percpu.h> | 52 | #include <asm/percpu.h> |
| 52 | #include <asm/dwarf2.h> | 53 | #include <asm/dwarf2.h> |
| @@ -101,121 +102,221 @@ | |||
| 101 | #define resume_userspace_sig resume_userspace | 102 | #define resume_userspace_sig resume_userspace |
| 102 | #endif | 103 | #endif |
| 103 | 104 | ||
| 104 | #define SAVE_ALL \ | 105 | /* |
| 105 | cld; \ | 106 | * User gs save/restore |
| 106 | pushl %fs; \ | 107 | * |
| 107 | CFI_ADJUST_CFA_OFFSET 4;\ | 108 | * %gs is used for userland TLS and kernel only uses it for stack |
| 108 | /*CFI_REL_OFFSET fs, 0;*/\ | 109 | * canary which is required to be at %gs:20 by gcc. Read the comment |
| 109 | pushl %es; \ | 110 | * at the top of stackprotector.h for more info. |
| 110 | CFI_ADJUST_CFA_OFFSET 4;\ | 111 | * |
| 111 | /*CFI_REL_OFFSET es, 0;*/\ | 112 | * Local labels 98 and 99 are used. |
| 112 | pushl %ds; \ | 113 | */ |
| 113 | CFI_ADJUST_CFA_OFFSET 4;\ | 114 | #ifdef CONFIG_X86_32_LAZY_GS |
| 114 | /*CFI_REL_OFFSET ds, 0;*/\ | 115 | |
| 115 | pushl %eax; \ | 116 | /* unfortunately push/pop can't be no-op */ |
| 116 | CFI_ADJUST_CFA_OFFSET 4;\ | 117 | .macro PUSH_GS |
| 117 | CFI_REL_OFFSET eax, 0;\ | 118 | pushl $0 |
| 118 | pushl %ebp; \ | 119 | CFI_ADJUST_CFA_OFFSET 4 |
| 119 | CFI_ADJUST_CFA_OFFSET 4;\ | 120 | .endm |
| 120 | CFI_REL_OFFSET ebp, 0;\ | 121 | .macro POP_GS pop=0 |
| 121 | pushl %edi; \ | 122 | addl $(4 + \pop), %esp |
| 122 | CFI_ADJUST_CFA_OFFSET 4;\ | 123 | CFI_ADJUST_CFA_OFFSET -(4 + \pop) |
| 123 | CFI_REL_OFFSET edi, 0;\ | 124 | .endm |
| 124 | pushl %esi; \ | 125 | .macro POP_GS_EX |
| 125 | CFI_ADJUST_CFA_OFFSET 4;\ | 126 | .endm |
| 126 | CFI_REL_OFFSET esi, 0;\ | 127 | |
| 127 | pushl %edx; \ | 128 | /* all the rest are no-op */ |
| 128 | CFI_ADJUST_CFA_OFFSET 4;\ | 129 | .macro PTGS_TO_GS |
| 129 | CFI_REL_OFFSET edx, 0;\ | 130 | .endm |
| 130 | pushl %ecx; \ | 131 | .macro PTGS_TO_GS_EX |
| 131 | CFI_ADJUST_CFA_OFFSET 4;\ | 132 | .endm |
| 132 | CFI_REL_OFFSET ecx, 0;\ | 133 | .macro GS_TO_REG reg |
| 133 | pushl %ebx; \ | 134 | .endm |
| 134 | CFI_ADJUST_CFA_OFFSET 4;\ | 135 | .macro REG_TO_PTGS reg |
| 135 | CFI_REL_OFFSET ebx, 0;\ | 136 | .endm |
| 136 | movl $(__USER_DS), %edx; \ | 137 | .macro SET_KERNEL_GS reg |
| 137 | movl %edx, %ds; \ | 138 | .endm |
| 138 | movl %edx, %es; \ | 139 | |
| 139 | movl $(__KERNEL_PERCPU), %edx; \ | 140 | #else /* CONFIG_X86_32_LAZY_GS */ |
| 141 | |||
| 142 | .macro PUSH_GS | ||
| 143 | pushl %gs | ||
| 144 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 145 | /*CFI_REL_OFFSET gs, 0*/ | ||
| 146 | .endm | ||
| 147 | |||
| 148 | .macro POP_GS pop=0 | ||
| 149 | 98: popl %gs | ||
| 150 | CFI_ADJUST_CFA_OFFSET -4 | ||
| 151 | /*CFI_RESTORE gs*/ | ||
| 152 | .if \pop <> 0 | ||
| 153 | add $\pop, %esp | ||
| 154 | CFI_ADJUST_CFA_OFFSET -\pop | ||
| 155 | .endif | ||
| 156 | .endm | ||
| 157 | .macro POP_GS_EX | ||
| 158 | .pushsection .fixup, "ax" | ||
| 159 | 99: movl $0, (%esp) | ||
| 160 | jmp 98b | ||
| 161 | .section __ex_table, "a" | ||
| 162 | .align 4 | ||
| 163 | .long 98b, 99b | ||
| 164 | .popsection | ||
| 165 | .endm | ||
| 166 | |||
| 167 | .macro PTGS_TO_GS | ||
| 168 | 98: mov PT_GS(%esp), %gs | ||
| 169 | .endm | ||
| 170 | .macro PTGS_TO_GS_EX | ||
| 171 | .pushsection .fixup, "ax" | ||
| 172 | 99: movl $0, PT_GS(%esp) | ||
| 173 | jmp 98b | ||
| 174 | .section __ex_table, "a" | ||
| 175 | .align 4 | ||
| 176 | .long 98b, 99b | ||
| 177 | .popsection | ||
| 178 | .endm | ||
| 179 | |||
| 180 | .macro GS_TO_REG reg | ||
| 181 | movl %gs, \reg | ||
| 182 | /*CFI_REGISTER gs, \reg*/ | ||
| 183 | .endm | ||
| 184 | .macro REG_TO_PTGS reg | ||
| 185 | movl \reg, PT_GS(%esp) | ||
| 186 | /*CFI_REL_OFFSET gs, PT_GS*/ | ||
| 187 | .endm | ||
| 188 | .macro SET_KERNEL_GS reg | ||
| 189 | movl $(__KERNEL_STACK_CANARY), \reg | ||
| 190 | movl \reg, %gs | ||
| 191 | .endm | ||
| 192 | |||
| 193 | #endif /* CONFIG_X86_32_LAZY_GS */ | ||
| 194 | |||
| 195 | .macro SAVE_ALL | ||
| 196 | cld | ||
| 197 | PUSH_GS | ||
| 198 | pushl %fs | ||
| 199 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 200 | /*CFI_REL_OFFSET fs, 0;*/ | ||
| 201 | pushl %es | ||
| 202 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 203 | /*CFI_REL_OFFSET es, 0;*/ | ||
| 204 | pushl %ds | ||
| 205 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 206 | /*CFI_REL_OFFSET ds, 0;*/ | ||
| 207 | pushl %eax | ||
| 208 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 209 | CFI_REL_OFFSET eax, 0 | ||
| 210 | pushl %ebp | ||
| 211 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 212 | CFI_REL_OFFSET ebp, 0 | ||
| 213 | pushl %edi | ||
| 214 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 215 | CFI_REL_OFFSET edi, 0 | ||
| 216 | pushl %esi | ||
| 217 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 218 | CFI_REL_OFFSET esi, 0 | ||
| 219 | pushl %edx | ||
| 220 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 221 | CFI_REL_OFFSET edx, 0 | ||
| 222 | pushl %ecx | ||
| 223 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 224 | CFI_REL_OFFSET ecx, 0 | ||
| 225 | pushl %ebx | ||
| 226 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 227 | CFI_REL_OFFSET ebx, 0 | ||
| 228 | movl $(__USER_DS), %edx | ||
| 229 | movl %edx, %ds | ||
| 230 | movl %edx, %es | ||
| 231 | movl $(__KERNEL_PERCPU), %edx | ||
| 140 | movl %edx, %fs | 232 | movl %edx, %fs |
| 233 | SET_KERNEL_GS %edx | ||
| 234 | .endm | ||
| 141 | 235 | ||
| 142 | #define RESTORE_INT_REGS \ | 236 | .macro RESTORE_INT_REGS |
| 143 | popl %ebx; \ | 237 | popl %ebx |
| 144 | CFI_ADJUST_CFA_OFFSET -4;\ | 238 | CFI_ADJUST_CFA_OFFSET -4 |
| 145 | CFI_RESTORE ebx;\ | 239 | CFI_RESTORE ebx |
| 146 | popl %ecx; \ | 240 | popl %ecx |
| 147 | CFI_ADJUST_CFA_OFFSET -4;\ | 241 | CFI_ADJUST_CFA_OFFSET -4 |
| 148 | CFI_RESTORE ecx;\ | 242 | CFI_RESTORE ecx |
| 149 | popl %edx; \ | 243 | popl %edx |
| 150 | CFI_ADJUST_CFA_OFFSET -4;\ | 244 | CFI_ADJUST_CFA_OFFSET -4 |
| 151 | CFI_RESTORE edx;\ | 245 | CFI_RESTORE edx |
| 152 | popl %esi; \ | 246 | popl %esi |
| 153 | CFI_ADJUST_CFA_OFFSET -4;\ | 247 | CFI_ADJUST_CFA_OFFSET -4 |
| 154 | CFI_RESTORE esi;\ | 248 | CFI_RESTORE esi |
| 155 | popl %edi; \ | 249 | popl %edi |
| 156 | CFI_ADJUST_CFA_OFFSET -4;\ | 250 | CFI_ADJUST_CFA_OFFSET -4 |
| 157 | CFI_RESTORE edi;\ | 251 | CFI_RESTORE edi |
| 158 | popl %ebp; \ | 252 | popl %ebp |
| 159 | CFI_ADJUST_CFA_OFFSET -4;\ | 253 | CFI_ADJUST_CFA_OFFSET -4 |
| 160 | CFI_RESTORE ebp;\ | 254 | CFI_RESTORE ebp |
| 161 | popl %eax; \ | 255 | popl %eax |
| 162 | CFI_ADJUST_CFA_OFFSET -4;\ | 256 | CFI_ADJUST_CFA_OFFSET -4 |
| 163 | CFI_RESTORE eax | 257 | CFI_RESTORE eax |
| 258 | .endm | ||
| 164 | 259 | ||
| 165 | #define RESTORE_REGS \ | 260 | .macro RESTORE_REGS pop=0 |
| 166 | RESTORE_INT_REGS; \ | 261 | RESTORE_INT_REGS |
| 167 | 1: popl %ds; \ | 262 | 1: popl %ds |
| 168 | CFI_ADJUST_CFA_OFFSET -4;\ | 263 | CFI_ADJUST_CFA_OFFSET -4 |
| 169 | /*CFI_RESTORE ds;*/\ | 264 | /*CFI_RESTORE ds;*/ |
| 170 | 2: popl %es; \ | 265 | 2: popl %es |
| 171 | CFI_ADJUST_CFA_OFFSET -4;\ | 266 | CFI_ADJUST_CFA_OFFSET -4 |
| 172 | /*CFI_RESTORE es;*/\ | 267 | /*CFI_RESTORE es;*/ |
| 173 | 3: popl %fs; \ | 268 | 3: popl %fs |
| 174 | CFI_ADJUST_CFA_OFFSET -4;\ | 269 | CFI_ADJUST_CFA_OFFSET -4 |
| 175 | /*CFI_RESTORE fs;*/\ | 270 | /*CFI_RESTORE fs;*/ |
| 176 | .pushsection .fixup,"ax"; \ | 271 | POP_GS \pop |
| 177 | 4: movl $0,(%esp); \ | 272 | .pushsection .fixup, "ax" |
| 178 | jmp 1b; \ | 273 | 4: movl $0, (%esp) |
| 179 | 5: movl $0,(%esp); \ | 274 | jmp 1b |
| 180 | jmp 2b; \ | 275 | 5: movl $0, (%esp) |
| 181 | 6: movl $0,(%esp); \ | 276 | jmp 2b |
| 182 | jmp 3b; \ | 277 | 6: movl $0, (%esp) |
| 183 | .section __ex_table,"a";\ | 278 | jmp 3b |
| 184 | .align 4; \ | 279 | .section __ex_table, "a" |
| 185 | .long 1b,4b; \ | 280 | .align 4 |
| 186 | .long 2b,5b; \ | 281 | .long 1b, 4b |
| 187 | .long 3b,6b; \ | 282 | .long 2b, 5b |
| 283 | .long 3b, 6b | ||
| 188 | .popsection | 284 | .popsection |
| 285 | POP_GS_EX | ||
| 286 | .endm | ||
| 189 | 287 | ||
| 190 | #define RING0_INT_FRAME \ | 288 | .macro RING0_INT_FRAME |
| 191 | CFI_STARTPROC simple;\ | 289 | CFI_STARTPROC simple |
| 192 | CFI_SIGNAL_FRAME;\ | 290 | CFI_SIGNAL_FRAME |
| 193 | CFI_DEF_CFA esp, 3*4;\ | 291 | CFI_DEF_CFA esp, 3*4 |
| 194 | /*CFI_OFFSET cs, -2*4;*/\ | 292 | /*CFI_OFFSET cs, -2*4;*/ |
| 195 | CFI_OFFSET eip, -3*4 | 293 | CFI_OFFSET eip, -3*4 |
| 294 | .endm | ||
| 196 | 295 | ||
| 197 | #define RING0_EC_FRAME \ | 296 | .macro RING0_EC_FRAME |
| 198 | CFI_STARTPROC simple;\ | 297 | CFI_STARTPROC simple |
| 199 | CFI_SIGNAL_FRAME;\ | 298 | CFI_SIGNAL_FRAME |
| 200 | CFI_DEF_CFA esp, 4*4;\ | 299 | CFI_DEF_CFA esp, 4*4 |
| 201 | /*CFI_OFFSET cs, -2*4;*/\ | 300 | /*CFI_OFFSET cs, -2*4;*/ |
| 202 | CFI_OFFSET eip, -3*4 | 301 | CFI_OFFSET eip, -3*4 |
| 302 | .endm | ||
| 203 | 303 | ||
| 204 | #define RING0_PTREGS_FRAME \ | 304 | .macro RING0_PTREGS_FRAME |
| 205 | CFI_STARTPROC simple;\ | 305 | CFI_STARTPROC simple |
| 206 | CFI_SIGNAL_FRAME;\ | 306 | CFI_SIGNAL_FRAME |
| 207 | CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\ | 307 | CFI_DEF_CFA esp, PT_OLDESP-PT_EBX |
| 208 | /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\ | 308 | /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/ |
| 209 | CFI_OFFSET eip, PT_EIP-PT_OLDESP;\ | 309 | CFI_OFFSET eip, PT_EIP-PT_OLDESP |
| 210 | /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\ | 310 | /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/ |
| 211 | /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\ | 311 | /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/ |
| 212 | CFI_OFFSET eax, PT_EAX-PT_OLDESP;\ | 312 | CFI_OFFSET eax, PT_EAX-PT_OLDESP |
| 213 | CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\ | 313 | CFI_OFFSET ebp, PT_EBP-PT_OLDESP |
| 214 | CFI_OFFSET edi, PT_EDI-PT_OLDESP;\ | 314 | CFI_OFFSET edi, PT_EDI-PT_OLDESP |
| 215 | CFI_OFFSET esi, PT_ESI-PT_OLDESP;\ | 315 | CFI_OFFSET esi, PT_ESI-PT_OLDESP |
| 216 | CFI_OFFSET edx, PT_EDX-PT_OLDESP;\ | 316 | CFI_OFFSET edx, PT_EDX-PT_OLDESP |
| 217 | CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\ | 317 | CFI_OFFSET ecx, PT_ECX-PT_OLDESP |
| 218 | CFI_OFFSET ebx, PT_EBX-PT_OLDESP | 318 | CFI_OFFSET ebx, PT_EBX-PT_OLDESP |
| 319 | .endm | ||
| 219 | 320 | ||
| 220 | ENTRY(ret_from_fork) | 321 | ENTRY(ret_from_fork) |
| 221 | CFI_STARTPROC | 322 | CFI_STARTPROC |
| @@ -362,6 +463,7 @@ sysenter_exit: | |||
| 362 | xorl %ebp,%ebp | 463 | xorl %ebp,%ebp |
| 363 | TRACE_IRQS_ON | 464 | TRACE_IRQS_ON |
| 364 | 1: mov PT_FS(%esp), %fs | 465 | 1: mov PT_FS(%esp), %fs |
| 466 | PTGS_TO_GS | ||
| 365 | ENABLE_INTERRUPTS_SYSEXIT | 467 | ENABLE_INTERRUPTS_SYSEXIT |
| 366 | 468 | ||
| 367 | #ifdef CONFIG_AUDITSYSCALL | 469 | #ifdef CONFIG_AUDITSYSCALL |
| @@ -410,6 +512,7 @@ sysexit_audit: | |||
| 410 | .align 4 | 512 | .align 4 |
| 411 | .long 1b,2b | 513 | .long 1b,2b |
| 412 | .popsection | 514 | .popsection |
| 515 | PTGS_TO_GS_EX | ||
| 413 | ENDPROC(ia32_sysenter_target) | 516 | ENDPROC(ia32_sysenter_target) |
| 414 | 517 | ||
| 415 | # system call handler stub | 518 | # system call handler stub |
| @@ -452,8 +555,7 @@ restore_all: | |||
| 452 | restore_nocheck: | 555 | restore_nocheck: |
| 453 | TRACE_IRQS_IRET | 556 | TRACE_IRQS_IRET |
| 454 | restore_nocheck_notrace: | 557 | restore_nocheck_notrace: |
| 455 | RESTORE_REGS | 558 | RESTORE_REGS 4 # skip orig_eax/error_code |
| 456 | addl $4, %esp # skip orig_eax/error_code | ||
| 457 | CFI_ADJUST_CFA_OFFSET -4 | 559 | CFI_ADJUST_CFA_OFFSET -4 |
| 458 | irq_return: | 560 | irq_return: |
| 459 | INTERRUPT_RETURN | 561 | INTERRUPT_RETURN |
| @@ -595,28 +697,50 @@ syscall_badsys: | |||
| 595 | END(syscall_badsys) | 697 | END(syscall_badsys) |
| 596 | CFI_ENDPROC | 698 | CFI_ENDPROC |
| 597 | 699 | ||
| 598 | #define FIXUP_ESPFIX_STACK \ | 700 | /* |
| 599 | /* since we are on a wrong stack, we cant make it a C code :( */ \ | 701 | * System calls that need a pt_regs pointer. |
| 600 | PER_CPU(gdt_page, %ebx); \ | 702 | */ |
| 601 | GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ | 703 | #define PTREGSCALL(name) \ |
| 602 | addl %esp, %eax; \ | 704 | ALIGN; \ |
| 603 | pushl $__KERNEL_DS; \ | 705 | ptregs_##name: \ |
| 604 | CFI_ADJUST_CFA_OFFSET 4; \ | 706 | leal 4(%esp),%eax; \ |
| 605 | pushl %eax; \ | 707 | jmp sys_##name; |
| 606 | CFI_ADJUST_CFA_OFFSET 4; \ | 708 | |
| 607 | lss (%esp), %esp; \ | 709 | PTREGSCALL(iopl) |
| 608 | CFI_ADJUST_CFA_OFFSET -8; | 710 | PTREGSCALL(fork) |
| 609 | #define UNWIND_ESPFIX_STACK \ | 711 | PTREGSCALL(clone) |
| 610 | movl %ss, %eax; \ | 712 | PTREGSCALL(vfork) |
| 611 | /* see if on espfix stack */ \ | 713 | PTREGSCALL(execve) |
| 612 | cmpw $__ESPFIX_SS, %ax; \ | 714 | PTREGSCALL(sigaltstack) |
| 613 | jne 27f; \ | 715 | PTREGSCALL(sigreturn) |
| 614 | movl $__KERNEL_DS, %eax; \ | 716 | PTREGSCALL(rt_sigreturn) |
| 615 | movl %eax, %ds; \ | 717 | PTREGSCALL(vm86) |
| 616 | movl %eax, %es; \ | 718 | PTREGSCALL(vm86old) |
| 617 | /* switch to normal stack */ \ | 719 | |
| 618 | FIXUP_ESPFIX_STACK; \ | 720 | .macro FIXUP_ESPFIX_STACK |
| 619 | 27:; | 721 | /* since we are on a wrong stack, we cant make it a C code :( */ |
| 722 | PER_CPU(gdt_page, %ebx) | ||
| 723 | GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) | ||
| 724 | addl %esp, %eax | ||
| 725 | pushl $__KERNEL_DS | ||
| 726 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 727 | pushl %eax | ||
| 728 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 729 | lss (%esp), %esp | ||
| 730 | CFI_ADJUST_CFA_OFFSET -8 | ||
| 731 | .endm | ||
| 732 | .macro UNWIND_ESPFIX_STACK | ||
| 733 | movl %ss, %eax | ||
| 734 | /* see if on espfix stack */ | ||
| 735 | cmpw $__ESPFIX_SS, %ax | ||
| 736 | jne 27f | ||
| 737 | movl $__KERNEL_DS, %eax | ||
| 738 | movl %eax, %ds | ||
| 739 | movl %eax, %es | ||
| 740 | /* switch to normal stack */ | ||
| 741 | FIXUP_ESPFIX_STACK | ||
| 742 | 27: | ||
| 743 | .endm | ||
| 620 | 744 | ||
| 621 | /* | 745 | /* |
| 622 | * Build the entry stubs and pointer table with some assembler magic. | 746 | * Build the entry stubs and pointer table with some assembler magic. |
| @@ -672,7 +796,7 @@ common_interrupt: | |||
| 672 | ENDPROC(common_interrupt) | 796 | ENDPROC(common_interrupt) |
| 673 | CFI_ENDPROC | 797 | CFI_ENDPROC |
| 674 | 798 | ||
| 675 | #define BUILD_INTERRUPT(name, nr) \ | 799 | #define BUILD_INTERRUPT3(name, nr, fn) \ |
| 676 | ENTRY(name) \ | 800 | ENTRY(name) \ |
| 677 | RING0_INT_FRAME; \ | 801 | RING0_INT_FRAME; \ |
| 678 | pushl $~(nr); \ | 802 | pushl $~(nr); \ |
| @@ -680,13 +804,15 @@ ENTRY(name) \ | |||
| 680 | SAVE_ALL; \ | 804 | SAVE_ALL; \ |
| 681 | TRACE_IRQS_OFF \ | 805 | TRACE_IRQS_OFF \ |
| 682 | movl %esp,%eax; \ | 806 | movl %esp,%eax; \ |
| 683 | call smp_##name; \ | 807 | call fn; \ |
| 684 | jmp ret_from_intr; \ | 808 | jmp ret_from_intr; \ |
| 685 | CFI_ENDPROC; \ | 809 | CFI_ENDPROC; \ |
| 686 | ENDPROC(name) | 810 | ENDPROC(name) |
| 687 | 811 | ||
| 812 | #define BUILD_INTERRUPT(name, nr) BUILD_INTERRUPT3(name, nr, smp_##name) | ||
| 813 | |||
| 688 | /* The include is where all of the SMP etc. interrupts come from */ | 814 | /* The include is where all of the SMP etc. interrupts come from */ |
| 689 | #include "entry_arch.h" | 815 | #include <asm/entry_arch.h> |
| 690 | 816 | ||
| 691 | ENTRY(coprocessor_error) | 817 | ENTRY(coprocessor_error) |
| 692 | RING0_INT_FRAME | 818 | RING0_INT_FRAME |
| @@ -1068,7 +1194,10 @@ ENTRY(page_fault) | |||
| 1068 | CFI_ADJUST_CFA_OFFSET 4 | 1194 | CFI_ADJUST_CFA_OFFSET 4 |
| 1069 | ALIGN | 1195 | ALIGN |
| 1070 | error_code: | 1196 | error_code: |
| 1071 | /* the function address is in %fs's slot on the stack */ | 1197 | /* the function address is in %gs's slot on the stack */ |
| 1198 | pushl %fs | ||
| 1199 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 1200 | /*CFI_REL_OFFSET fs, 0*/ | ||
| 1072 | pushl %es | 1201 | pushl %es |
| 1073 | CFI_ADJUST_CFA_OFFSET 4 | 1202 | CFI_ADJUST_CFA_OFFSET 4 |
| 1074 | /*CFI_REL_OFFSET es, 0*/ | 1203 | /*CFI_REL_OFFSET es, 0*/ |
| @@ -1097,20 +1226,15 @@ error_code: | |||
| 1097 | CFI_ADJUST_CFA_OFFSET 4 | 1226 | CFI_ADJUST_CFA_OFFSET 4 |
| 1098 | CFI_REL_OFFSET ebx, 0 | 1227 | CFI_REL_OFFSET ebx, 0 |
| 1099 | cld | 1228 | cld |
| 1100 | pushl %fs | ||
| 1101 | CFI_ADJUST_CFA_OFFSET 4 | ||
| 1102 | /*CFI_REL_OFFSET fs, 0*/ | ||
| 1103 | movl $(__KERNEL_PERCPU), %ecx | 1229 | movl $(__KERNEL_PERCPU), %ecx |
| 1104 | movl %ecx, %fs | 1230 | movl %ecx, %fs |
| 1105 | UNWIND_ESPFIX_STACK | 1231 | UNWIND_ESPFIX_STACK |
| 1106 | popl %ecx | 1232 | GS_TO_REG %ecx |
| 1107 | CFI_ADJUST_CFA_OFFSET -4 | 1233 | movl PT_GS(%esp), %edi # get the function address |
| 1108 | /*CFI_REGISTER es, ecx*/ | ||
| 1109 | movl PT_FS(%esp), %edi # get the function address | ||
| 1110 | movl PT_ORIG_EAX(%esp), %edx # get the error code | 1234 | movl PT_ORIG_EAX(%esp), %edx # get the error code |
| 1111 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart | 1235 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart |
| 1112 | mov %ecx, PT_FS(%esp) | 1236 | REG_TO_PTGS %ecx |
| 1113 | /*CFI_REL_OFFSET fs, ES*/ | 1237 | SET_KERNEL_GS %ecx |
| 1114 | movl $(__USER_DS), %ecx | 1238 | movl $(__USER_DS), %ecx |
| 1115 | movl %ecx, %ds | 1239 | movl %ecx, %ds |
| 1116 | movl %ecx, %es | 1240 | movl %ecx, %es |
| @@ -1134,26 +1258,27 @@ END(page_fault) | |||
| 1134 | * by hand onto the new stack - while updating the return eip past | 1258 | * by hand onto the new stack - while updating the return eip past |
| 1135 | * the instruction that would have done it for sysenter. | 1259 | * the instruction that would have done it for sysenter. |
| 1136 | */ | 1260 | */ |
| 1137 | #define FIX_STACK(offset, ok, label) \ | 1261 | .macro FIX_STACK offset ok label |
| 1138 | cmpw $__KERNEL_CS,4(%esp); \ | 1262 | cmpw $__KERNEL_CS, 4(%esp) |
| 1139 | jne ok; \ | 1263 | jne \ok |
| 1140 | label: \ | 1264 | \label: |
| 1141 | movl TSS_sysenter_sp0+offset(%esp),%esp; \ | 1265 | movl TSS_sysenter_sp0 + \offset(%esp), %esp |
| 1142 | CFI_DEF_CFA esp, 0; \ | 1266 | CFI_DEF_CFA esp, 0 |
| 1143 | CFI_UNDEFINED eip; \ | 1267 | CFI_UNDEFINED eip |
| 1144 | pushfl; \ | 1268 | pushfl |
| 1145 | CFI_ADJUST_CFA_OFFSET 4; \ | 1269 | CFI_ADJUST_CFA_OFFSET 4 |
| 1146 | pushl $__KERNEL_CS; \ | 1270 | pushl $__KERNEL_CS |
| 1147 | CFI_ADJUST_CFA_OFFSET 4; \ | 1271 | CFI_ADJUST_CFA_OFFSET 4 |
| 1148 | pushl $sysenter_past_esp; \ | 1272 | pushl $sysenter_past_esp |
| 1149 | CFI_ADJUST_CFA_OFFSET 4; \ | 1273 | CFI_ADJUST_CFA_OFFSET 4 |
| 1150 | CFI_REL_OFFSET eip, 0 | 1274 | CFI_REL_OFFSET eip, 0 |
| 1275 | .endm | ||
| 1151 | 1276 | ||
| 1152 | ENTRY(debug) | 1277 | ENTRY(debug) |
| 1153 | RING0_INT_FRAME | 1278 | RING0_INT_FRAME |
| 1154 | cmpl $ia32_sysenter_target,(%esp) | 1279 | cmpl $ia32_sysenter_target,(%esp) |
| 1155 | jne debug_stack_correct | 1280 | jne debug_stack_correct |
| 1156 | FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) | 1281 | FIX_STACK 12, debug_stack_correct, debug_esp_fix_insn |
| 1157 | debug_stack_correct: | 1282 | debug_stack_correct: |
| 1158 | pushl $-1 # mark this as an int | 1283 | pushl $-1 # mark this as an int |
| 1159 | CFI_ADJUST_CFA_OFFSET 4 | 1284 | CFI_ADJUST_CFA_OFFSET 4 |
| @@ -1211,7 +1336,7 @@ nmi_stack_correct: | |||
| 1211 | 1336 | ||
| 1212 | nmi_stack_fixup: | 1337 | nmi_stack_fixup: |
| 1213 | RING0_INT_FRAME | 1338 | RING0_INT_FRAME |
| 1214 | FIX_STACK(12,nmi_stack_correct, 1) | 1339 | FIX_STACK 12, nmi_stack_correct, 1 |
| 1215 | jmp nmi_stack_correct | 1340 | jmp nmi_stack_correct |
| 1216 | 1341 | ||
| 1217 | nmi_debug_stack_check: | 1342 | nmi_debug_stack_check: |
| @@ -1222,7 +1347,7 @@ nmi_debug_stack_check: | |||
| 1222 | jb nmi_stack_correct | 1347 | jb nmi_stack_correct |
| 1223 | cmpl $debug_esp_fix_insn,(%esp) | 1348 | cmpl $debug_esp_fix_insn,(%esp) |
| 1224 | ja nmi_stack_correct | 1349 | ja nmi_stack_correct |
| 1225 | FIX_STACK(24,nmi_stack_correct, 1) | 1350 | FIX_STACK 24, nmi_stack_correct, 1 |
| 1226 | jmp nmi_stack_correct | 1351 | jmp nmi_stack_correct |
| 1227 | 1352 | ||
| 1228 | nmi_espfix_stack: | 1353 | nmi_espfix_stack: |
| @@ -1234,7 +1359,7 @@ nmi_espfix_stack: | |||
| 1234 | CFI_ADJUST_CFA_OFFSET 4 | 1359 | CFI_ADJUST_CFA_OFFSET 4 |
| 1235 | pushl %esp | 1360 | pushl %esp |
| 1236 | CFI_ADJUST_CFA_OFFSET 4 | 1361 | CFI_ADJUST_CFA_OFFSET 4 |
| 1237 | addw $4, (%esp) | 1362 | addl $4, (%esp) |
| 1238 | /* copy the iret frame of 12 bytes */ | 1363 | /* copy the iret frame of 12 bytes */ |
| 1239 | .rept 3 | 1364 | .rept 3 |
| 1240 | pushl 16(%esp) | 1365 | pushl 16(%esp) |
