diff options
author | Andi Kleen <ak@suse.de> | 2005-04-16 18:25:03 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:25:03 -0400 |
commit | 6fefb0d17599d63e9d30c23bcbe2d4e06477cd55 (patch) | |
tree | d513ab7e0edfb2ee74adf15f2c7714ccdb179978 /arch/x86_64/kernel/entry.S | |
parent | 11b854b2f10f398f9a18c65e202853f929dd3185 (diff) |
[PATCH] x86_64: Regularize exception stack handling
This fixes various issues in the return path for "paranoid"
handlers (= running on a private exception stack that act like NMIs).
Generalize previous hack to switch back to process stack for
scheduling/signal handling purposes.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/entry.S')
-rw-r--r-- | arch/x86_64/kernel/entry.S | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 12a307100929..3e888c2e5a06 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -579,6 +579,7 @@ ENTRY(spurious_interrupt) | |||
579 | movq ORIG_RAX(%rsp),%rsi | 579 | movq ORIG_RAX(%rsp),%rsi |
580 | movq $-1,ORIG_RAX(%rsp) | 580 | movq $-1,ORIG_RAX(%rsp) |
581 | call \sym | 581 | call \sym |
582 | cli | ||
582 | .endm | 583 | .endm |
583 | 584 | ||
584 | /* | 585 | /* |
@@ -794,10 +795,6 @@ ENTRY(debug) | |||
794 | pushq $0 | 795 | pushq $0 |
795 | CFI_ADJUST_CFA_OFFSET 8 | 796 | CFI_ADJUST_CFA_OFFSET 8 |
796 | paranoidentry do_debug | 797 | paranoidentry do_debug |
797 | /* switch back to process stack to restore the state ptrace touched */ | ||
798 | movq %rax,%rsp | ||
799 | testl $3,CS(%rsp) | ||
800 | jnz paranoid_userspace | ||
801 | jmp paranoid_exit | 798 | jmp paranoid_exit |
802 | CFI_ENDPROC | 799 | CFI_ENDPROC |
803 | 800 | ||
@@ -807,35 +804,49 @@ ENTRY(nmi) | |||
807 | pushq $-1 | 804 | pushq $-1 |
808 | CFI_ADJUST_CFA_OFFSET 8 | 805 | CFI_ADJUST_CFA_OFFSET 8 |
809 | paranoidentry do_nmi | 806 | paranoidentry do_nmi |
807 | /* | ||
808 | * "Paranoid" exit path from exception stack. | ||
809 | * Paranoid because this is used by NMIs and cannot take | ||
810 | * any kernel state for granted. | ||
811 | * We don't do kernel preemption checks here, because only | ||
812 | * NMI should be common and it does not enable IRQs and | ||
813 | * cannot get reschedule ticks. | ||
814 | */ | ||
810 | /* ebx: no swapgs flag */ | 815 | /* ebx: no swapgs flag */ |
811 | paranoid_exit: | 816 | paranoid_exit: |
812 | testl %ebx,%ebx /* swapgs needed? */ | 817 | testl %ebx,%ebx /* swapgs needed? */ |
813 | jnz paranoid_restore | 818 | jnz paranoid_restore |
819 | testl $3,CS(%rsp) | ||
820 | jnz paranoid_userspace | ||
814 | paranoid_swapgs: | 821 | paranoid_swapgs: |
815 | cli | ||
816 | swapgs | 822 | swapgs |
817 | paranoid_restore: | 823 | paranoid_restore: |
818 | RESTORE_ALL 8 | 824 | RESTORE_ALL 8 |
819 | iretq | 825 | iretq |
820 | paranoid_userspace: | 826 | paranoid_userspace: |
821 | cli | ||
822 | GET_THREAD_INFO(%rcx) | 827 | GET_THREAD_INFO(%rcx) |
823 | movl threadinfo_flags(%rcx),%edx | 828 | movl threadinfo_flags(%rcx),%ebx |
824 | testl $_TIF_WORK_MASK,%edx | 829 | andl $_TIF_WORK_MASK,%ebx |
825 | jz paranoid_swapgs | 830 | jz paranoid_swapgs |
826 | testl $_TIF_NEED_RESCHED,%edx | 831 | movq %rsp,%rdi /* &pt_regs */ |
827 | jnz paranoid_resched | 832 | call sync_regs |
833 | movq %rax,%rsp /* switch stack for scheduling */ | ||
834 | testl $_TIF_NEED_RESCHED,%ebx | ||
835 | jnz paranoid_schedule | ||
836 | movl %ebx,%edx /* arg3: thread flags */ | ||
828 | sti | 837 | sti |
829 | xorl %esi,%esi /* oldset */ | 838 | xorl %esi,%esi /* arg2: oldset */ |
830 | movq %rsp,%rdi /* &pt_regs */ | 839 | movq %rsp,%rdi /* arg1: &pt_regs */ |
831 | call do_notify_resume | 840 | call do_notify_resume |
832 | jmp paranoid_exit | 841 | cli |
833 | paranoid_resched: | 842 | jmp paranoid_userspace |
843 | paranoid_schedule: | ||
834 | sti | 844 | sti |
835 | call schedule | 845 | call schedule |
836 | jmp paranoid_exit | 846 | cli |
847 | jmp paranoid_userspace | ||
837 | CFI_ENDPROC | 848 | CFI_ENDPROC |
838 | 849 | ||
839 | ENTRY(int3) | 850 | ENTRY(int3) |
840 | zeroentry do_int3 | 851 | zeroentry do_int3 |
841 | 852 | ||
@@ -858,9 +869,6 @@ ENTRY(reserved) | |||
858 | ENTRY(double_fault) | 869 | ENTRY(double_fault) |
859 | CFI_STARTPROC | 870 | CFI_STARTPROC |
860 | paranoidentry do_double_fault | 871 | paranoidentry do_double_fault |
861 | movq %rax,%rsp | ||
862 | testl $3,CS(%rsp) | ||
863 | jnz paranoid_userspace | ||
864 | jmp paranoid_exit | 872 | jmp paranoid_exit |
865 | CFI_ENDPROC | 873 | CFI_ENDPROC |
866 | 874 | ||
@@ -874,9 +882,6 @@ ENTRY(segment_not_present) | |||
874 | ENTRY(stack_segment) | 882 | ENTRY(stack_segment) |
875 | CFI_STARTPROC | 883 | CFI_STARTPROC |
876 | paranoidentry do_stack_segment | 884 | paranoidentry do_stack_segment |
877 | movq %rax,%rsp | ||
878 | testl $3,CS(%rsp) | ||
879 | jnz paranoid_userspace | ||
880 | jmp paranoid_exit | 885 | jmp paranoid_exit |
881 | CFI_ENDPROC | 886 | CFI_ENDPROC |
882 | 887 | ||