diff options
Diffstat (limited to 'arch/x86/kernel/entry_32.S')
| -rw-r--r-- | arch/x86/kernel/entry_32.S | 476 |
1 files changed, 248 insertions, 228 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index f6402c4ba10d..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 |
| @@ -1211,3 +1007,227 @@ END(mcount) | |||
| 1211 | #include "syscall_table_32.S" | 1007 | #include "syscall_table_32.S" |
| 1212 | 1008 | ||
| 1213 | 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 | ||
