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 ---