aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/entry.S
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2005-04-16 18:25:03 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:25:03 -0400
commit6fefb0d17599d63e9d30c23bcbe2d4e06477cd55 (patch)
treed513ab7e0edfb2ee74adf15f2c7714ccdb179978 /arch/x86_64/kernel/entry.S
parent11b854b2f10f398f9a18c65e202853f929dd3185 (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.S49
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 */
811paranoid_exit: 816paranoid_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
814paranoid_swapgs: 821paranoid_swapgs:
815 cli
816 swapgs 822 swapgs
817paranoid_restore: 823paranoid_restore:
818 RESTORE_ALL 8 824 RESTORE_ALL 8
819 iretq 825 iretq
820paranoid_userspace: 826paranoid_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
833paranoid_resched: 842 jmp paranoid_userspace
843paranoid_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
839ENTRY(int3) 850ENTRY(int3)
840 zeroentry do_int3 851 zeroentry do_int3
841 852
@@ -858,9 +869,6 @@ ENTRY(reserved)
858ENTRY(double_fault) 869ENTRY(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)
874ENTRY(stack_segment) 882ENTRY(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