entry_32.S (4d516f41704055710da872b62ddc4b6d23248984) | entry_32.S (946c191161cef10c667b5ee3179db1714fa5b7c0) |
---|---|
1/* 2 * Copyright (C) 1991,1992 Linus Torvalds 3 * 4 * entry_32.S contains the system-call and low-level fault and trap handling routines. 5 * 6 * Stack layout while running C code: 7 * ptrace needs to have all registers on the stack. 8 * If the order here is changed, it needs to be --- 162 unchanged lines hidden (view full) --- 171 movl $(__USER_DS), %edx 172 movl %edx, %ds 173 movl %edx, %es 174 movl $(__KERNEL_PERCPU), %edx 175 movl %edx, %fs 176 SET_KERNEL_GS %edx 177.endm 178 | 1/* 2 * Copyright (C) 1991,1992 Linus Torvalds 3 * 4 * entry_32.S contains the system-call and low-level fault and trap handling routines. 5 * 6 * Stack layout while running C code: 7 * ptrace needs to have all registers on the stack. 8 * If the order here is changed, it needs to be --- 162 unchanged lines hidden (view full) --- 171 movl $(__USER_DS), %edx 172 movl %edx, %ds 173 movl %edx, %es 174 movl $(__KERNEL_PERCPU), %edx 175 movl %edx, %fs 176 SET_KERNEL_GS %edx 177.endm 178 |
179/* 180 * This is a sneaky trick to help the unwinder find pt_regs on the stack. The 181 * frame pointer is replaced with an encoded pointer to pt_regs. The encoding 182 * is just setting the LSB, which makes it an invalid stack address and is also 183 * a signal to the unwinder that it's a pt_regs pointer in disguise. 184 * 185 * NOTE: This macro must be used *after* SAVE_ALL because it corrupts the 186 * original rbp. 187 */ 188.macro ENCODE_FRAME_POINTER 189#ifdef CONFIG_FRAME_POINTER 190 mov %esp, %ebp 191 orl $0x1, %ebp 192#endif 193.endm 194 |
|
179.macro RESTORE_INT_REGS 180 popl %ebx 181 popl %ecx 182 popl %edx 183 popl %esi 184 popl %edi 185 popl %ebp 186 popl %eax --- 449 unchanged lines hidden (view full) --- 636 * the CPU automatically disables interrupts when executing an IRQ vector, 637 * so IRQ-flags tracing has to follow that: 638 */ 639 .p2align CONFIG_X86_L1_CACHE_SHIFT 640common_interrupt: 641 ASM_CLAC 642 addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */ 643 SAVE_ALL | 195.macro RESTORE_INT_REGS 196 popl %ebx 197 popl %ecx 198 popl %edx 199 popl %esi 200 popl %edi 201 popl %ebp 202 popl %eax --- 449 unchanged lines hidden (view full) --- 652 * the CPU automatically disables interrupts when executing an IRQ vector, 653 * so IRQ-flags tracing has to follow that: 654 */ 655 .p2align CONFIG_X86_L1_CACHE_SHIFT 656common_interrupt: 657 ASM_CLAC 658 addl $-0x80, (%esp) /* Adjust vector into the [-256, -1] range */ 659 SAVE_ALL |
660 ENCODE_FRAME_POINTER |
|
644 TRACE_IRQS_OFF 645 movl %esp, %eax 646 call do_IRQ 647 jmp ret_from_intr 648ENDPROC(common_interrupt) 649 650#define BUILD_INTERRUPT3(name, nr, fn) \ 651ENTRY(name) \ 652 ASM_CLAC; \ 653 pushl $~(nr); \ 654 SAVE_ALL; \ | 661 TRACE_IRQS_OFF 662 movl %esp, %eax 663 call do_IRQ 664 jmp ret_from_intr 665ENDPROC(common_interrupt) 666 667#define BUILD_INTERRUPT3(name, nr, fn) \ 668ENTRY(name) \ 669 ASM_CLAC; \ 670 pushl $~(nr); \ 671 SAVE_ALL; \ |
672 ENCODE_FRAME_POINTER; \ |
|
655 TRACE_IRQS_OFF \ 656 movl %esp, %eax; \ 657 call fn; \ 658 jmp ret_from_intr; \ 659ENDPROC(name) 660 661 662#ifdef CONFIG_TRACING --- 118 unchanged lines hidden (view full) --- 781 pushl $do_spurious_interrupt_bug 782 jmp common_exception 783END(spurious_interrupt_bug) 784 785#ifdef CONFIG_XEN 786ENTRY(xen_hypervisor_callback) 787 pushl $-1 /* orig_ax = -1 => not a system call */ 788 SAVE_ALL | 673 TRACE_IRQS_OFF \ 674 movl %esp, %eax; \ 675 call fn; \ 676 jmp ret_from_intr; \ 677ENDPROC(name) 678 679 680#ifdef CONFIG_TRACING --- 118 unchanged lines hidden (view full) --- 799 pushl $do_spurious_interrupt_bug 800 jmp common_exception 801END(spurious_interrupt_bug) 802 803#ifdef CONFIG_XEN 804ENTRY(xen_hypervisor_callback) 805 pushl $-1 /* orig_ax = -1 => not a system call */ 806 SAVE_ALL |
807 ENCODE_FRAME_POINTER |
|
789 TRACE_IRQS_OFF 790 791 /* 792 * Check to see if we got the event in the critical 793 * region in xen_iret_direct, after we've reenabled 794 * events and checked for pending events. This simulates 795 * iret instruction's behaviour where it delivers a 796 * pending interrupt when enabling interrupts: --- 38 unchanged lines hidden (view full) --- 835 EAX != 0 => Category 2 (Bad IRET) */ 836 testl %eax, %eax 837 popl %eax 838 lea 16(%esp), %esp 839 jz 5f 840 jmp iret_exc 8415: pushl $-1 /* orig_ax = -1 => not a system call */ 842 SAVE_ALL | 808 TRACE_IRQS_OFF 809 810 /* 811 * Check to see if we got the event in the critical 812 * region in xen_iret_direct, after we've reenabled 813 * events and checked for pending events. This simulates 814 * iret instruction's behaviour where it delivers a 815 * pending interrupt when enabling interrupts: --- 38 unchanged lines hidden (view full) --- 854 EAX != 0 => Category 2 (Bad IRET) */ 855 testl %eax, %eax 856 popl %eax 857 lea 16(%esp), %esp 858 jz 5f 859 jmp iret_exc 8605: pushl $-1 /* orig_ax = -1 => not a system call */ 861 SAVE_ALL |
862 ENCODE_FRAME_POINTER |
|
843 jmp ret_from_exception 844 845.section .fixup, "ax" 8466: xorl %eax, %eax 847 movl %eax, 4(%esp) 848 jmp 1b 8497: xorl %eax, %eax 850 movl %eax, 8(%esp) --- 211 unchanged lines hidden (view full) --- 1062 pushl %ds 1063 pushl %eax 1064 pushl %ebp 1065 pushl %edi 1066 pushl %esi 1067 pushl %edx 1068 pushl %ecx 1069 pushl %ebx | 863 jmp ret_from_exception 864 865.section .fixup, "ax" 8666: xorl %eax, %eax 867 movl %eax, 4(%esp) 868 jmp 1b 8697: xorl %eax, %eax 870 movl %eax, 8(%esp) --- 211 unchanged lines hidden (view full) --- 1082 pushl %ds 1083 pushl %eax 1084 pushl %ebp 1085 pushl %edi 1086 pushl %esi 1087 pushl %edx 1088 pushl %ecx 1089 pushl %ebx |
1090 ENCODE_FRAME_POINTER |
|
1070 cld 1071 movl $(__KERNEL_PERCPU), %ecx 1072 movl %ecx, %fs 1073 UNWIND_ESPFIX_STACK 1074 GS_TO_REG %ecx 1075 movl PT_GS(%esp), %edi # get the function address 1076 movl PT_ORIG_EAX(%esp), %edx # get the error code 1077 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart --- 16 unchanged lines hidden (view full) --- 1094 * need to detect this condition and switch to the thread 1095 * stack before calling any C code at all. 1096 * 1097 * If you edit this code, keep in mind that NMIs can happen in here. 1098 */ 1099 ASM_CLAC 1100 pushl $-1 # mark this as an int 1101 SAVE_ALL | 1091 cld 1092 movl $(__KERNEL_PERCPU), %ecx 1093 movl %ecx, %fs 1094 UNWIND_ESPFIX_STACK 1095 GS_TO_REG %ecx 1096 movl PT_GS(%esp), %edi # get the function address 1097 movl PT_ORIG_EAX(%esp), %edx # get the error code 1098 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart --- 16 unchanged lines hidden (view full) --- 1115 * need to detect this condition and switch to the thread 1116 * stack before calling any C code at all. 1117 * 1118 * If you edit this code, keep in mind that NMIs can happen in here. 1119 */ 1120 ASM_CLAC 1121 pushl $-1 # mark this as an int 1122 SAVE_ALL |
1123 ENCODE_FRAME_POINTER |
|
1102 xorl %edx, %edx # error code 0 1103 movl %esp, %eax # pt_regs pointer 1104 1105 /* Are we currently on the SYSENTER stack? */ 1106 PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) 1107 subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ 1108 cmpl $SIZEOF_SYSENTER_stack, %ecx 1109 jb .Ldebug_from_sysenter_stack 1110 1111 TRACE_IRQS_OFF 1112 call do_debug 1113 jmp ret_from_exception 1114 1115.Ldebug_from_sysenter_stack: 1116 /* We're on the SYSENTER stack. Switch off. */ | 1124 xorl %edx, %edx # error code 0 1125 movl %esp, %eax # pt_regs pointer 1126 1127 /* Are we currently on the SYSENTER stack? */ 1128 PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) 1129 subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ 1130 cmpl $SIZEOF_SYSENTER_stack, %ecx 1131 jb .Ldebug_from_sysenter_stack 1132 1133 TRACE_IRQS_OFF 1134 call do_debug 1135 jmp ret_from_exception 1136 1137.Ldebug_from_sysenter_stack: 1138 /* We're on the SYSENTER stack. Switch off. */ |
1117 movl %esp, %ebp | 1139 movl %esp, %ebx |
1118 movl PER_CPU_VAR(cpu_current_top_of_stack), %esp 1119 TRACE_IRQS_OFF 1120 call do_debug | 1140 movl PER_CPU_VAR(cpu_current_top_of_stack), %esp 1141 TRACE_IRQS_OFF 1142 call do_debug |
1121 movl %ebp, %esp | 1143 movl %ebx, %esp |
1122 jmp ret_from_exception 1123END(debug) 1124 1125/* 1126 * NMI is doubly nasty. It can happen on the first instruction of 1127 * entry_SYSENTER_32 (just like #DB), but it can also interrupt the beginning 1128 * of the #DB handler even if that #DB in turn hit before entry_SYSENTER_32 1129 * switched stacks. We handle both conditions by simply checking whether we --- 6 unchanged lines hidden (view full) --- 1136 movl %ss, %eax 1137 cmpw $__ESPFIX_SS, %ax 1138 popl %eax 1139 je .Lnmi_espfix_stack 1140#endif 1141 1142 pushl %eax # pt_regs->orig_ax 1143 SAVE_ALL | 1144 jmp ret_from_exception 1145END(debug) 1146 1147/* 1148 * NMI is doubly nasty. It can happen on the first instruction of 1149 * entry_SYSENTER_32 (just like #DB), but it can also interrupt the beginning 1150 * of the #DB handler even if that #DB in turn hit before entry_SYSENTER_32 1151 * switched stacks. We handle both conditions by simply checking whether we --- 6 unchanged lines hidden (view full) --- 1158 movl %ss, %eax 1159 cmpw $__ESPFIX_SS, %ax 1160 popl %eax 1161 je .Lnmi_espfix_stack 1162#endif 1163 1164 pushl %eax # pt_regs->orig_ax 1165 SAVE_ALL |
1166 ENCODE_FRAME_POINTER |
|
1144 xorl %edx, %edx # zero error code 1145 movl %esp, %eax # pt_regs pointer 1146 1147 /* Are we currently on the SYSENTER stack? */ 1148 PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) 1149 subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ 1150 cmpl $SIZEOF_SYSENTER_stack, %ecx 1151 jb .Lnmi_from_sysenter_stack 1152 1153 /* Not on SYSENTER stack. */ 1154 call do_nmi 1155 jmp .Lrestore_all_notrace 1156 1157.Lnmi_from_sysenter_stack: 1158 /* 1159 * We're on the SYSENTER stack. Switch off. No one (not even debug) 1160 * is using the thread stack right now, so it's safe for us to use it. 1161 */ | 1167 xorl %edx, %edx # zero error code 1168 movl %esp, %eax # pt_regs pointer 1169 1170 /* Are we currently on the SYSENTER stack? */ 1171 PER_CPU(cpu_tss + CPU_TSS_SYSENTER_stack + SIZEOF_SYSENTER_stack, %ecx) 1172 subl %eax, %ecx /* ecx = (end of SYSENTER_stack) - esp */ 1173 cmpl $SIZEOF_SYSENTER_stack, %ecx 1174 jb .Lnmi_from_sysenter_stack 1175 1176 /* Not on SYSENTER stack. */ 1177 call do_nmi 1178 jmp .Lrestore_all_notrace 1179 1180.Lnmi_from_sysenter_stack: 1181 /* 1182 * We're on the SYSENTER stack. Switch off. No one (not even debug) 1183 * is using the thread stack right now, so it's safe for us to use it. 1184 */ |
1162 movl %esp, %ebp | 1185 movl %esp, %ebx |
1163 movl PER_CPU_VAR(cpu_current_top_of_stack), %esp 1164 call do_nmi | 1186 movl PER_CPU_VAR(cpu_current_top_of_stack), %esp 1187 call do_nmi |
1165 movl %ebp, %esp | 1188 movl %ebx, %esp |
1166 jmp .Lrestore_all_notrace 1167 1168#ifdef CONFIG_X86_ESPFIX32 1169.Lnmi_espfix_stack: 1170 /* 1171 * create the pointer to lss back 1172 */ 1173 pushl %ss 1174 pushl %esp 1175 addl $4, (%esp) 1176 /* copy the iret frame of 12 bytes */ 1177 .rept 3 1178 pushl 16(%esp) 1179 .endr 1180 pushl %eax 1181 SAVE_ALL | 1189 jmp .Lrestore_all_notrace 1190 1191#ifdef CONFIG_X86_ESPFIX32 1192.Lnmi_espfix_stack: 1193 /* 1194 * create the pointer to lss back 1195 */ 1196 pushl %ss 1197 pushl %esp 1198 addl $4, (%esp) 1199 /* copy the iret frame of 12 bytes */ 1200 .rept 3 1201 pushl 16(%esp) 1202 .endr 1203 pushl %eax 1204 SAVE_ALL |
1205 ENCODE_FRAME_POINTER |
|
1182 FIXUP_ESPFIX_STACK # %eax == %esp 1183 xorl %edx, %edx # zero error code 1184 call do_nmi 1185 RESTORE_REGS 1186 lss 12+4(%esp), %esp # back to espfix stack 1187 jmp .Lirq_return 1188#endif 1189END(nmi) 1190 1191ENTRY(int3) 1192 ASM_CLAC 1193 pushl $-1 # mark this as an int 1194 SAVE_ALL | 1206 FIXUP_ESPFIX_STACK # %eax == %esp 1207 xorl %edx, %edx # zero error code 1208 call do_nmi 1209 RESTORE_REGS 1210 lss 12+4(%esp), %esp # back to espfix stack 1211 jmp .Lirq_return 1212#endif 1213END(nmi) 1214 1215ENTRY(int3) 1216 ASM_CLAC 1217 pushl $-1 # mark this as an int 1218 SAVE_ALL |
1219 ENCODE_FRAME_POINTER |
|
1195 TRACE_IRQS_OFF 1196 xorl %edx, %edx # zero error code 1197 movl %esp, %eax # pt_regs pointer 1198 call do_int3 1199 jmp ret_from_exception 1200END(int3) 1201 1202ENTRY(general_protection) --- 22 unchanged lines hidden --- | 1220 TRACE_IRQS_OFF 1221 xorl %edx, %edx # zero error code 1222 movl %esp, %eax # pt_regs pointer 1223 call do_int3 1224 jmp ret_from_exception 1225END(int3) 1226 1227ENTRY(general_protection) --- 22 unchanged lines hidden --- |