diff options
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
-rw-r--r-- | arch/x86/kernel/entry_32.S | 477 |
1 files changed, 249 insertions, 228 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 28b597ef9ca1..fe7014176eb0 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -619,28 +619,37 @@ END(syscall_badsys) | |||
619 | 27:; | 619 | 27:; |
620 | 620 | ||
621 | /* | 621 | /* |
622 | * Build the entry stubs and pointer table with | 622 | * Build the entry stubs and pointer table with some assembler magic. |
623 | * some assembler magic. | 623 | * We pack 7 stubs into a single 32-byte chunk, which will fit in a |
624 | * single cache line on all modern x86 implementations. | ||
624 | */ | 625 | */ |
625 | .section .rodata,"a" | 626 | .section .init.rodata,"a" |
626 | ENTRY(interrupt) | 627 | ENTRY(interrupt) |
627 | .text | 628 | .text |
628 | 629 | .p2align 5 | |
630 | .p2align CONFIG_X86_L1_CACHE_SHIFT | ||
629 | ENTRY(irq_entries_start) | 631 | ENTRY(irq_entries_start) |
630 | RING0_INT_FRAME | 632 | RING0_INT_FRAME |
631 | vector=0 | 633 | vector=FIRST_EXTERNAL_VECTOR |
632 | .rept NR_VECTORS | 634 | .rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 |
633 | ALIGN | 635 | .balign 32 |
634 | .if vector | 636 | .rept 7 |
637 | .if vector < NR_VECTORS | ||
638 | .if vector <> FIRST_EXTERNAL_VECTOR | ||
635 | CFI_ADJUST_CFA_OFFSET -4 | 639 | CFI_ADJUST_CFA_OFFSET -4 |
636 | .endif | 640 | .endif |
637 | 1: pushl $~(vector) | 641 | 1: pushl $(~vector+0x80) /* Note: always in signed byte range */ |
638 | CFI_ADJUST_CFA_OFFSET 4 | 642 | CFI_ADJUST_CFA_OFFSET 4 |
639 | jmp common_interrupt | 643 | .if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6 |
640 | .previous | 644 | jmp 2f |
645 | .endif | ||
646 | .previous | ||
641 | .long 1b | 647 | .long 1b |
642 | .text | 648 | .text |
643 | vector=vector+1 | 649 | vector=vector+1 |
650 | .endif | ||
651 | .endr | ||
652 | 2: jmp common_interrupt | ||
644 | .endr | 653 | .endr |
645 | END(irq_entries_start) | 654 | END(irq_entries_start) |
646 | 655 | ||
@@ -652,8 +661,9 @@ END(interrupt) | |||
652 | * the CPU automatically disables interrupts when executing an IRQ vector, | 661 | * the CPU automatically disables interrupts when executing an IRQ vector, |
653 | * so IRQ-flags tracing has to follow that: | 662 | * so IRQ-flags tracing has to follow that: |
654 | */ | 663 | */ |
655 | ALIGN | 664 | .p2align CONFIG_X86_L1_CACHE_SHIFT |
656 | common_interrupt: | 665 | common_interrupt: |
666 | addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */ | ||
657 | SAVE_ALL | 667 | SAVE_ALL |
658 | TRACE_IRQS_OFF | 668 | TRACE_IRQS_OFF |
659 | movl %esp,%eax | 669 | movl %esp,%eax |
@@ -678,65 +688,6 @@ ENDPROC(name) | |||
678 | /* The include is where all of the SMP etc. interrupts come from */ | 688 | /* The include is where all of the SMP etc. interrupts come from */ |
679 | #include "entry_arch.h" | 689 | #include "entry_arch.h" |
680 | 690 | ||
681 | KPROBE_ENTRY(page_fault) | ||
682 | RING0_EC_FRAME | ||
683 | pushl $do_page_fault | ||
684 | CFI_ADJUST_CFA_OFFSET 4 | ||
685 | ALIGN | ||
686 | error_code: | ||
687 | /* the function address is in %fs's slot on the stack */ | ||
688 | pushl %es | ||
689 | CFI_ADJUST_CFA_OFFSET 4 | ||
690 | /*CFI_REL_OFFSET es, 0*/ | ||
691 | pushl %ds | ||
692 | CFI_ADJUST_CFA_OFFSET 4 | ||
693 | /*CFI_REL_OFFSET ds, 0*/ | ||
694 | pushl %eax | ||
695 | CFI_ADJUST_CFA_OFFSET 4 | ||
696 | CFI_REL_OFFSET eax, 0 | ||
697 | pushl %ebp | ||
698 | CFI_ADJUST_CFA_OFFSET 4 | ||
699 | CFI_REL_OFFSET ebp, 0 | ||
700 | pushl %edi | ||
701 | CFI_ADJUST_CFA_OFFSET 4 | ||
702 | CFI_REL_OFFSET edi, 0 | ||
703 | pushl %esi | ||
704 | CFI_ADJUST_CFA_OFFSET 4 | ||
705 | CFI_REL_OFFSET esi, 0 | ||
706 | pushl %edx | ||
707 | CFI_ADJUST_CFA_OFFSET 4 | ||
708 | CFI_REL_OFFSET edx, 0 | ||
709 | pushl %ecx | ||
710 | CFI_ADJUST_CFA_OFFSET 4 | ||
711 | CFI_REL_OFFSET ecx, 0 | ||
712 | pushl %ebx | ||
713 | CFI_ADJUST_CFA_OFFSET 4 | ||
714 | CFI_REL_OFFSET ebx, 0 | ||
715 | cld | ||
716 | pushl %fs | ||
717 | CFI_ADJUST_CFA_OFFSET 4 | ||
718 | /*CFI_REL_OFFSET fs, 0*/ | ||
719 | movl $(__KERNEL_PERCPU), %ecx | ||
720 | movl %ecx, %fs | ||
721 | UNWIND_ESPFIX_STACK | ||
722 | popl %ecx | ||
723 | CFI_ADJUST_CFA_OFFSET -4 | ||
724 | /*CFI_REGISTER es, ecx*/ | ||
725 | movl PT_FS(%esp), %edi # get the function address | ||
726 | movl PT_ORIG_EAX(%esp), %edx # get the error code | ||
727 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart | ||
728 | mov %ecx, PT_FS(%esp) | ||
729 | /*CFI_REL_OFFSET fs, ES*/ | ||
730 | movl $(__USER_DS), %ecx | ||
731 | movl %ecx, %ds | ||
732 | movl %ecx, %es | ||
733 | TRACE_IRQS_OFF | ||
734 | movl %esp,%eax # pt_regs pointer | ||
735 | call *%edi | ||
736 | jmp ret_from_exception | ||
737 | CFI_ENDPROC | ||
738 | KPROBE_END(page_fault) | ||
739 | |||
740 | ENTRY(coprocessor_error) | 691 | ENTRY(coprocessor_error) |
741 | RING0_INT_FRAME | 692 | RING0_INT_FRAME |
742 | pushl $0 | 693 | pushl $0 |
@@ -767,140 +718,6 @@ ENTRY(device_not_available) | |||
767 | CFI_ENDPROC | 718 | CFI_ENDPROC |
768 | END(device_not_available) | 719 | END(device_not_available) |
769 | 720 | ||
770 | /* | ||
771 | * Debug traps and NMI can happen at the one SYSENTER instruction | ||
772 | * that sets up the real kernel stack. Check here, since we can't | ||
773 | * allow the wrong stack to be used. | ||
774 | * | ||
775 | * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have | ||
776 | * already pushed 3 words if it hits on the sysenter instruction: | ||
777 | * eflags, cs and eip. | ||
778 | * | ||
779 | * We just load the right stack, and push the three (known) values | ||
780 | * by hand onto the new stack - while updating the return eip past | ||
781 | * the instruction that would have done it for sysenter. | ||
782 | */ | ||
783 | #define FIX_STACK(offset, ok, label) \ | ||
784 | cmpw $__KERNEL_CS,4(%esp); \ | ||
785 | jne ok; \ | ||
786 | label: \ | ||
787 | movl TSS_sysenter_sp0+offset(%esp),%esp; \ | ||
788 | CFI_DEF_CFA esp, 0; \ | ||
789 | CFI_UNDEFINED eip; \ | ||
790 | pushfl; \ | ||
791 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
792 | pushl $__KERNEL_CS; \ | ||
793 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
794 | pushl $sysenter_past_esp; \ | ||
795 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
796 | CFI_REL_OFFSET eip, 0 | ||
797 | |||
798 | KPROBE_ENTRY(debug) | ||
799 | RING0_INT_FRAME | ||
800 | cmpl $ia32_sysenter_target,(%esp) | ||
801 | jne debug_stack_correct | ||
802 | FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) | ||
803 | debug_stack_correct: | ||
804 | pushl $-1 # mark this as an int | ||
805 | CFI_ADJUST_CFA_OFFSET 4 | ||
806 | SAVE_ALL | ||
807 | TRACE_IRQS_OFF | ||
808 | xorl %edx,%edx # error code 0 | ||
809 | movl %esp,%eax # pt_regs pointer | ||
810 | call do_debug | ||
811 | jmp ret_from_exception | ||
812 | CFI_ENDPROC | ||
813 | KPROBE_END(debug) | ||
814 | |||
815 | /* | ||
816 | * NMI is doubly nasty. It can happen _while_ we're handling | ||
817 | * a debug fault, and the debug fault hasn't yet been able to | ||
818 | * clear up the stack. So we first check whether we got an | ||
819 | * NMI on the sysenter entry path, but after that we need to | ||
820 | * check whether we got an NMI on the debug path where the debug | ||
821 | * fault happened on the sysenter path. | ||
822 | */ | ||
823 | KPROBE_ENTRY(nmi) | ||
824 | RING0_INT_FRAME | ||
825 | pushl %eax | ||
826 | CFI_ADJUST_CFA_OFFSET 4 | ||
827 | movl %ss, %eax | ||
828 | cmpw $__ESPFIX_SS, %ax | ||
829 | popl %eax | ||
830 | CFI_ADJUST_CFA_OFFSET -4 | ||
831 | je nmi_espfix_stack | ||
832 | cmpl $ia32_sysenter_target,(%esp) | ||
833 | je nmi_stack_fixup | ||
834 | pushl %eax | ||
835 | CFI_ADJUST_CFA_OFFSET 4 | ||
836 | movl %esp,%eax | ||
837 | /* Do not access memory above the end of our stack page, | ||
838 | * it might not exist. | ||
839 | */ | ||
840 | andl $(THREAD_SIZE-1),%eax | ||
841 | cmpl $(THREAD_SIZE-20),%eax | ||
842 | popl %eax | ||
843 | CFI_ADJUST_CFA_OFFSET -4 | ||
844 | jae nmi_stack_correct | ||
845 | cmpl $ia32_sysenter_target,12(%esp) | ||
846 | je nmi_debug_stack_check | ||
847 | nmi_stack_correct: | ||
848 | /* We have a RING0_INT_FRAME here */ | ||
849 | pushl %eax | ||
850 | CFI_ADJUST_CFA_OFFSET 4 | ||
851 | SAVE_ALL | ||
852 | TRACE_IRQS_OFF | ||
853 | xorl %edx,%edx # zero error code | ||
854 | movl %esp,%eax # pt_regs pointer | ||
855 | call do_nmi | ||
856 | jmp restore_nocheck_notrace | ||
857 | CFI_ENDPROC | ||
858 | |||
859 | nmi_stack_fixup: | ||
860 | RING0_INT_FRAME | ||
861 | FIX_STACK(12,nmi_stack_correct, 1) | ||
862 | jmp nmi_stack_correct | ||
863 | |||
864 | nmi_debug_stack_check: | ||
865 | /* We have a RING0_INT_FRAME here */ | ||
866 | cmpw $__KERNEL_CS,16(%esp) | ||
867 | jne nmi_stack_correct | ||
868 | cmpl $debug,(%esp) | ||
869 | jb nmi_stack_correct | ||
870 | cmpl $debug_esp_fix_insn,(%esp) | ||
871 | ja nmi_stack_correct | ||
872 | FIX_STACK(24,nmi_stack_correct, 1) | ||
873 | jmp nmi_stack_correct | ||
874 | |||
875 | nmi_espfix_stack: | ||
876 | /* We have a RING0_INT_FRAME here. | ||
877 | * | ||
878 | * create the pointer to lss back | ||
879 | */ | ||
880 | pushl %ss | ||
881 | CFI_ADJUST_CFA_OFFSET 4 | ||
882 | pushl %esp | ||
883 | CFI_ADJUST_CFA_OFFSET 4 | ||
884 | addw $4, (%esp) | ||
885 | /* copy the iret frame of 12 bytes */ | ||
886 | .rept 3 | ||
887 | pushl 16(%esp) | ||
888 | CFI_ADJUST_CFA_OFFSET 4 | ||
889 | .endr | ||
890 | pushl %eax | ||
891 | CFI_ADJUST_CFA_OFFSET 4 | ||
892 | SAVE_ALL | ||
893 | TRACE_IRQS_OFF | ||
894 | FIXUP_ESPFIX_STACK # %eax == %esp | ||
895 | xorl %edx,%edx # zero error code | ||
896 | call do_nmi | ||
897 | RESTORE_REGS | ||
898 | lss 12+4(%esp), %esp # back to espfix stack | ||
899 | CFI_ADJUST_CFA_OFFSET -24 | ||
900 | jmp irq_return | ||
901 | CFI_ENDPROC | ||
902 | KPROBE_END(nmi) | ||
903 | |||
904 | #ifdef CONFIG_PARAVIRT | 721 | #ifdef CONFIG_PARAVIRT |
905 | ENTRY(native_iret) | 722 | ENTRY(native_iret) |
906 | iret | 723 | iret |
@@ -916,19 +733,6 @@ ENTRY(native_irq_enable_sysexit) | |||
916 | END(native_irq_enable_sysexit) | 733 | END(native_irq_enable_sysexit) |
917 | #endif | 734 | #endif |
918 | 735 | ||
919 | KPROBE_ENTRY(int3) | ||
920 | RING0_INT_FRAME | ||
921 | pushl $-1 # mark this as an int | ||
922 | CFI_ADJUST_CFA_OFFSET 4 | ||
923 | SAVE_ALL | ||
924 | TRACE_IRQS_OFF | ||
925 | xorl %edx,%edx # zero error code | ||
926 | movl %esp,%eax # pt_regs pointer | ||
927 | call do_int3 | ||
928 | jmp ret_from_exception | ||
929 | CFI_ENDPROC | ||
930 | KPROBE_END(int3) | ||
931 | |||
932 | ENTRY(overflow) | 736 | ENTRY(overflow) |
933 | RING0_INT_FRAME | 737 | RING0_INT_FRAME |
934 | pushl $0 | 738 | pushl $0 |
@@ -993,14 +797,6 @@ ENTRY(stack_segment) | |||
993 | CFI_ENDPROC | 797 | CFI_ENDPROC |
994 | END(stack_segment) | 798 | END(stack_segment) |
995 | 799 | ||
996 | KPROBE_ENTRY(general_protection) | ||
997 | RING0_EC_FRAME | ||
998 | pushl $do_general_protection | ||
999 | CFI_ADJUST_CFA_OFFSET 4 | ||
1000 | jmp error_code | ||
1001 | CFI_ENDPROC | ||
1002 | KPROBE_END(general_protection) | ||
1003 | |||
1004 | ENTRY(alignment_check) | 800 | ENTRY(alignment_check) |
1005 | RING0_EC_FRAME | 801 | RING0_EC_FRAME |
1006 | pushl $do_alignment_check | 802 | pushl $do_alignment_check |
@@ -1051,6 +847,7 @@ ENTRY(kernel_thread_helper) | |||
1051 | push %eax | 847 | push %eax |
1052 | CFI_ADJUST_CFA_OFFSET 4 | 848 | CFI_ADJUST_CFA_OFFSET 4 |
1053 | call do_exit | 849 | call do_exit |
850 | ud2 # padding for call trace | ||
1054 | CFI_ENDPROC | 851 | CFI_ENDPROC |
1055 | ENDPROC(kernel_thread_helper) | 852 | ENDPROC(kernel_thread_helper) |
1056 | 853 | ||
@@ -1210,3 +1007,227 @@ END(mcount) | |||
1210 | #include "syscall_table_32.S" | 1007 | #include "syscall_table_32.S" |
1211 | 1008 | ||
1212 | syscall_table_size=(.-sys_call_table) | 1009 | syscall_table_size=(.-sys_call_table) |
1010 | |||
1011 | /* | ||
1012 | * Some functions should be protected against kprobes | ||
1013 | */ | ||
1014 | .pushsection .kprobes.text, "ax" | ||
1015 | |||
1016 | ENTRY(page_fault) | ||
1017 | RING0_EC_FRAME | ||
1018 | pushl $do_page_fault | ||
1019 | CFI_ADJUST_CFA_OFFSET 4 | ||
1020 | ALIGN | ||
1021 | error_code: | ||
1022 | /* the function address is in %fs's slot on the stack */ | ||
1023 | pushl %es | ||
1024 | CFI_ADJUST_CFA_OFFSET 4 | ||
1025 | /*CFI_REL_OFFSET es, 0*/ | ||
1026 | pushl %ds | ||
1027 | CFI_ADJUST_CFA_OFFSET 4 | ||
1028 | /*CFI_REL_OFFSET ds, 0*/ | ||
1029 | pushl %eax | ||
1030 | CFI_ADJUST_CFA_OFFSET 4 | ||
1031 | CFI_REL_OFFSET eax, 0 | ||
1032 | pushl %ebp | ||
1033 | CFI_ADJUST_CFA_OFFSET 4 | ||
1034 | CFI_REL_OFFSET ebp, 0 | ||
1035 | pushl %edi | ||
1036 | CFI_ADJUST_CFA_OFFSET 4 | ||
1037 | CFI_REL_OFFSET edi, 0 | ||
1038 | pushl %esi | ||
1039 | CFI_ADJUST_CFA_OFFSET 4 | ||
1040 | CFI_REL_OFFSET esi, 0 | ||
1041 | pushl %edx | ||
1042 | CFI_ADJUST_CFA_OFFSET 4 | ||
1043 | CFI_REL_OFFSET edx, 0 | ||
1044 | pushl %ecx | ||
1045 | CFI_ADJUST_CFA_OFFSET 4 | ||
1046 | CFI_REL_OFFSET ecx, 0 | ||
1047 | pushl %ebx | ||
1048 | CFI_ADJUST_CFA_OFFSET 4 | ||
1049 | CFI_REL_OFFSET ebx, 0 | ||
1050 | cld | ||
1051 | pushl %fs | ||
1052 | CFI_ADJUST_CFA_OFFSET 4 | ||
1053 | /*CFI_REL_OFFSET fs, 0*/ | ||
1054 | movl $(__KERNEL_PERCPU), %ecx | ||
1055 | movl %ecx, %fs | ||
1056 | UNWIND_ESPFIX_STACK | ||
1057 | popl %ecx | ||
1058 | CFI_ADJUST_CFA_OFFSET -4 | ||
1059 | /*CFI_REGISTER es, ecx*/ | ||
1060 | movl PT_FS(%esp), %edi # get the function address | ||
1061 | movl PT_ORIG_EAX(%esp), %edx # get the error code | ||
1062 | movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart | ||
1063 | mov %ecx, PT_FS(%esp) | ||
1064 | /*CFI_REL_OFFSET fs, ES*/ | ||
1065 | movl $(__USER_DS), %ecx | ||
1066 | movl %ecx, %ds | ||
1067 | movl %ecx, %es | ||
1068 | TRACE_IRQS_OFF | ||
1069 | movl %esp,%eax # pt_regs pointer | ||
1070 | call *%edi | ||
1071 | jmp ret_from_exception | ||
1072 | CFI_ENDPROC | ||
1073 | END(page_fault) | ||
1074 | |||
1075 | /* | ||
1076 | * Debug traps and NMI can happen at the one SYSENTER instruction | ||
1077 | * that sets up the real kernel stack. Check here, since we can't | ||
1078 | * allow the wrong stack to be used. | ||
1079 | * | ||
1080 | * "TSS_sysenter_sp0+12" is because the NMI/debug handler will have | ||
1081 | * already pushed 3 words if it hits on the sysenter instruction: | ||
1082 | * eflags, cs and eip. | ||
1083 | * | ||
1084 | * We just load the right stack, and push the three (known) values | ||
1085 | * by hand onto the new stack - while updating the return eip past | ||
1086 | * the instruction that would have done it for sysenter. | ||
1087 | */ | ||
1088 | #define FIX_STACK(offset, ok, label) \ | ||
1089 | cmpw $__KERNEL_CS,4(%esp); \ | ||
1090 | jne ok; \ | ||
1091 | label: \ | ||
1092 | movl TSS_sysenter_sp0+offset(%esp),%esp; \ | ||
1093 | CFI_DEF_CFA esp, 0; \ | ||
1094 | CFI_UNDEFINED eip; \ | ||
1095 | pushfl; \ | ||
1096 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
1097 | pushl $__KERNEL_CS; \ | ||
1098 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
1099 | pushl $sysenter_past_esp; \ | ||
1100 | CFI_ADJUST_CFA_OFFSET 4; \ | ||
1101 | CFI_REL_OFFSET eip, 0 | ||
1102 | |||
1103 | ENTRY(debug) | ||
1104 | RING0_INT_FRAME | ||
1105 | cmpl $ia32_sysenter_target,(%esp) | ||
1106 | jne debug_stack_correct | ||
1107 | FIX_STACK(12, debug_stack_correct, debug_esp_fix_insn) | ||
1108 | debug_stack_correct: | ||
1109 | pushl $-1 # mark this as an int | ||
1110 | CFI_ADJUST_CFA_OFFSET 4 | ||
1111 | SAVE_ALL | ||
1112 | TRACE_IRQS_OFF | ||
1113 | xorl %edx,%edx # error code 0 | ||
1114 | movl %esp,%eax # pt_regs pointer | ||
1115 | call do_debug | ||
1116 | jmp ret_from_exception | ||
1117 | CFI_ENDPROC | ||
1118 | END(debug) | ||
1119 | |||
1120 | /* | ||
1121 | * NMI is doubly nasty. It can happen _while_ we're handling | ||
1122 | * a debug fault, and the debug fault hasn't yet been able to | ||
1123 | * clear up the stack. So we first check whether we got an | ||
1124 | * NMI on the sysenter entry path, but after that we need to | ||
1125 | * check whether we got an NMI on the debug path where the debug | ||
1126 | * fault happened on the sysenter path. | ||
1127 | */ | ||
1128 | ENTRY(nmi) | ||
1129 | RING0_INT_FRAME | ||
1130 | pushl %eax | ||
1131 | CFI_ADJUST_CFA_OFFSET 4 | ||
1132 | movl %ss, %eax | ||
1133 | cmpw $__ESPFIX_SS, %ax | ||
1134 | popl %eax | ||
1135 | CFI_ADJUST_CFA_OFFSET -4 | ||
1136 | je nmi_espfix_stack | ||
1137 | cmpl $ia32_sysenter_target,(%esp) | ||
1138 | je nmi_stack_fixup | ||
1139 | pushl %eax | ||
1140 | CFI_ADJUST_CFA_OFFSET 4 | ||
1141 | movl %esp,%eax | ||
1142 | /* Do not access memory above the end of our stack page, | ||
1143 | * it might not exist. | ||
1144 | */ | ||
1145 | andl $(THREAD_SIZE-1),%eax | ||
1146 | cmpl $(THREAD_SIZE-20),%eax | ||
1147 | popl %eax | ||
1148 | CFI_ADJUST_CFA_OFFSET -4 | ||
1149 | jae nmi_stack_correct | ||
1150 | cmpl $ia32_sysenter_target,12(%esp) | ||
1151 | je nmi_debug_stack_check | ||
1152 | nmi_stack_correct: | ||
1153 | /* We have a RING0_INT_FRAME here */ | ||
1154 | pushl %eax | ||
1155 | CFI_ADJUST_CFA_OFFSET 4 | ||
1156 | SAVE_ALL | ||
1157 | TRACE_IRQS_OFF | ||
1158 | xorl %edx,%edx # zero error code | ||
1159 | movl %esp,%eax # pt_regs pointer | ||
1160 | call do_nmi | ||
1161 | jmp restore_nocheck_notrace | ||
1162 | CFI_ENDPROC | ||
1163 | |||
1164 | nmi_stack_fixup: | ||
1165 | RING0_INT_FRAME | ||
1166 | FIX_STACK(12,nmi_stack_correct, 1) | ||
1167 | jmp nmi_stack_correct | ||
1168 | |||
1169 | nmi_debug_stack_check: | ||
1170 | /* We have a RING0_INT_FRAME here */ | ||
1171 | cmpw $__KERNEL_CS,16(%esp) | ||
1172 | jne nmi_stack_correct | ||
1173 | cmpl $debug,(%esp) | ||
1174 | jb nmi_stack_correct | ||
1175 | cmpl $debug_esp_fix_insn,(%esp) | ||
1176 | ja nmi_stack_correct | ||
1177 | FIX_STACK(24,nmi_stack_correct, 1) | ||
1178 | jmp nmi_stack_correct | ||
1179 | |||
1180 | nmi_espfix_stack: | ||
1181 | /* We have a RING0_INT_FRAME here. | ||
1182 | * | ||
1183 | * create the pointer to lss back | ||
1184 | */ | ||
1185 | pushl %ss | ||
1186 | CFI_ADJUST_CFA_OFFSET 4 | ||
1187 | pushl %esp | ||
1188 | CFI_ADJUST_CFA_OFFSET 4 | ||
1189 | addw $4, (%esp) | ||
1190 | /* copy the iret frame of 12 bytes */ | ||
1191 | .rept 3 | ||
1192 | pushl 16(%esp) | ||
1193 | CFI_ADJUST_CFA_OFFSET 4 | ||
1194 | .endr | ||
1195 | pushl %eax | ||
1196 | CFI_ADJUST_CFA_OFFSET 4 | ||
1197 | SAVE_ALL | ||
1198 | TRACE_IRQS_OFF | ||
1199 | FIXUP_ESPFIX_STACK # %eax == %esp | ||
1200 | xorl %edx,%edx # zero error code | ||
1201 | call do_nmi | ||
1202 | RESTORE_REGS | ||
1203 | lss 12+4(%esp), %esp # back to espfix stack | ||
1204 | CFI_ADJUST_CFA_OFFSET -24 | ||
1205 | jmp irq_return | ||
1206 | CFI_ENDPROC | ||
1207 | END(nmi) | ||
1208 | |||
1209 | ENTRY(int3) | ||
1210 | RING0_INT_FRAME | ||
1211 | pushl $-1 # mark this as an int | ||
1212 | CFI_ADJUST_CFA_OFFSET 4 | ||
1213 | SAVE_ALL | ||
1214 | TRACE_IRQS_OFF | ||
1215 | xorl %edx,%edx # zero error code | ||
1216 | movl %esp,%eax # pt_regs pointer | ||
1217 | call do_int3 | ||
1218 | jmp ret_from_exception | ||
1219 | CFI_ENDPROC | ||
1220 | END(int3) | ||
1221 | |||
1222 | ENTRY(general_protection) | ||
1223 | RING0_EC_FRAME | ||
1224 | pushl $do_general_protection | ||
1225 | CFI_ADJUST_CFA_OFFSET 4 | ||
1226 | jmp error_code | ||
1227 | CFI_ENDPROC | ||
1228 | END(general_protection) | ||
1229 | |||
1230 | /* | ||
1231 | * End of kprobes section | ||
1232 | */ | ||
1233 | .popsection | ||