i386: fix regression, endless loop in ptrace singlestep over an int80
[sfrench/cifs-2.6.git] / arch / i386 / kernel / entry.S
index 5e47683fc63ae736e25d30e83aef093965cdc17d..3c3c220488c93fe20bd0a26d0553cc941ac7d81f 100644 (file)
@@ -15,7 +15,7 @@
  * I changed all the .align's to 4 (16 byte alignment), as that's faster
  * on a 486.
  *
- * Stack layout in 'ret_from_system_call':
+ * Stack layout in 'syscall_exit':
  *     ptrace needs to have all regs on the stack.
  *     if the order here is changed, it needs to be
  *     updated in fork.c:copy_process, signal.c:do_signal,
@@ -30,7 +30,7 @@
  *     18(%esp) - %eax
  *     1C(%esp) - %ds
  *     20(%esp) - %es
- *     24(%esp) - %gs
+ *     24(%esp) - %fs
  *     28(%esp) - orig_eax
  *     2C(%esp) - %eip
  *     30(%esp) - %cs
@@ -99,9 +99,9 @@ VM_MASK               = 0x00020000
 
 #define SAVE_ALL \
        cld; \
-       pushl %gs; \
+       pushl %fs; \
        CFI_ADJUST_CFA_OFFSET 4;\
-       /*CFI_REL_OFFSET gs, 0;*/\
+       /*CFI_REL_OFFSET fs, 0;*/\
        pushl %es; \
        CFI_ADJUST_CFA_OFFSET 4;\
        /*CFI_REL_OFFSET es, 0;*/\
@@ -132,8 +132,8 @@ VM_MASK             = 0x00020000
        movl $(__USER_DS), %edx; \
        movl %edx, %ds; \
        movl %edx, %es; \
-       movl $(__KERNEL_PDA), %edx; \
-       movl %edx, %gs
+       movl $(__KERNEL_PERCPU), %edx; \
+       movl %edx, %fs
 
 #define RESTORE_INT_REGS \
        popl %ebx;      \
@@ -166,9 +166,9 @@ VM_MASK             = 0x00020000
 2:     popl %es;       \
        CFI_ADJUST_CFA_OFFSET -4;\
        /*CFI_RESTORE es;*/\
-3:     popl %gs;       \
+3:     popl %fs;       \
        CFI_ADJUST_CFA_OFFSET -4;\
-       /*CFI_RESTORE gs;*/\
+       /*CFI_RESTORE fs;*/\
 .pushsection .fixup,"ax";      \
 4:     movl $0,(%esp); \
        jmp 1b;         \
@@ -227,6 +227,7 @@ ENTRY(ret_from_fork)
        CFI_ADJUST_CFA_OFFSET -4
        jmp syscall_exit
        CFI_ENDPROC
+END(ret_from_fork)
 
 /*
  * Return to user mode is not as complex as all this looks,
@@ -258,6 +259,7 @@ ENTRY(resume_userspace)
                                        # int/exception return?
        jne work_pending
        jmp restore_all
+END(ret_from_exception)
 
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
@@ -272,6 +274,7 @@ need_resched:
        jz restore_all
        call preempt_schedule_irq
        jmp need_resched
+END(resume_kernel)
 #endif
        CFI_ENDPROC
 
@@ -302,16 +305,12 @@ sysenter_past_esp:
        pushl $(__USER_CS)
        CFI_ADJUST_CFA_OFFSET 4
        /*CFI_REL_OFFSET cs, 0*/
-#ifndef CONFIG_COMPAT_VDSO
        /*
         * Push current_thread_info()->sysenter_return to the stack.
         * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
         * pushed above; +8 corresponds to copy_thread's esp0 setting.
         */
        pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
-#else
-       pushl $SYSENTER_RETURN
-#endif
        CFI_ADJUST_CFA_OFFSET 4
        CFI_REL_OFFSET eip, 0
 
@@ -339,7 +338,7 @@ sysenter_past_esp:
        jae syscall_badsys
        call *sys_call_table(,%eax,4)
        movl %eax,PT_EAX(%esp)
-       DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX)
+       DISABLE_INTERRUPTS(CLBR_ANY)
        TRACE_IRQS_OFF
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx
@@ -349,16 +348,17 @@ sysenter_past_esp:
        movl PT_OLDESP(%esp), %ecx
        xorl %ebp,%ebp
        TRACE_IRQS_ON
-1:     mov  PT_GS(%esp), %gs
+1:     mov  PT_FS(%esp), %fs
        ENABLE_INTERRUPTS_SYSEXIT
        CFI_ENDPROC
 .pushsection .fixup,"ax"
-2:     movl $0,PT_GS(%esp)
+2:     movl $0,PT_FS(%esp)
        jmp 1b
 .section __ex_table,"a"
        .align 4
        .long 1b,2b
 .popsection
+ENDPROC(sysenter_entry)
 
        # system call handler stub
 ENTRY(system_call)
@@ -367,10 +367,6 @@ ENTRY(system_call)
        CFI_ADJUST_CFA_OFFSET 4
        SAVE_ALL
        GET_THREAD_INFO(%ebp)
-       testl $TF_MASK,PT_EFLAGS(%esp)
-       jz no_singlestep
-       orl $_TIF_SINGLESTEP,TI_flags(%ebp)
-no_singlestep:
                                        # system call tracing in operation / emulation
        /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
        testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
@@ -385,6 +381,10 @@ syscall_exit:
                                        # setting need_resched or sigpending
                                        # between sampling and the iret
        TRACE_IRQS_OFF
+       testl $TF_MASK,PT_EFLAGS(%esp)  # If tracing set singlestep flag on exit
+       jz no_singlestep
+       orl $_TIF_SINGLESTEP,TI_flags(%ebp)
+no_singlestep:
        movl TI_flags(%ebp), %ecx
        testw $_TIF_ALLWORK_MASK, %cx   # current->work
        jne syscall_exit_work
@@ -459,6 +459,7 @@ ldt_ss:
        CFI_ADJUST_CFA_OFFSET -8
        jmp restore_nocheck
        CFI_ENDPROC
+ENDPROC(system_call)
 
        # perform work that needs to be done immediately before resumption
        ALIGN
@@ -504,6 +505,7 @@ work_notifysig_v86:
        xorl %edx, %edx
        call do_notify_resume
        jmp resume_userspace_sig
+END(work_pending)
 
        # perform syscall exit tracing
        ALIGN
@@ -519,6 +521,7 @@ syscall_trace_entry:
        cmpl $(nr_syscalls), %eax
        jnae syscall_call
        jmp syscall_exit
+END(syscall_trace_entry)
 
        # perform syscall exit tracing
        ALIGN
@@ -532,6 +535,7 @@ syscall_exit_work:
        movl $1, %edx
        call do_syscall_trace
        jmp resume_userspace
+END(syscall_exit_work)
        CFI_ENDPROC
 
        RING0_INT_FRAME                 # can't unwind into user space anyway
@@ -542,17 +546,17 @@ syscall_fault:
        GET_THREAD_INFO(%ebp)
        movl $-EFAULT,PT_EAX(%esp)
        jmp resume_userspace
+END(syscall_fault)
 
 syscall_badsys:
        movl $-ENOSYS,PT_EAX(%esp)
        jmp resume_userspace
+END(syscall_badsys)
        CFI_ENDPROC
 
 #define FIXUP_ESPFIX_STACK \
        /* since we are on a wrong stack, we cant make it a C code :( */ \
-       movl %gs:PDA_cpu, %ebx; \
-       PER_CPU(cpu_gdt_descr, %ebx); \
-       movl GDS_address(%ebx), %ebx; \
+       PER_CPU(gdt_page, %ebx); \
        GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
        addl %esp, %eax; \
        pushl $__KERNEL_DS; \
@@ -581,9 +585,9 @@ syscall_badsys:
 ENTRY(interrupt)
 .text
 
-vector=0
 ENTRY(irq_entries_start)
        RING0_INT_FRAME
+vector=0
 .rept NR_IRQS
        ALIGN
  .if vector
@@ -592,11 +596,16 @@ ENTRY(irq_entries_start)
 1:     pushl $~(vector)
        CFI_ADJUST_CFA_OFFSET 4
        jmp common_interrupt
-.data
+ .previous
        .long 1b
-.text
+ .text
 vector=vector+1
 .endr
+END(irq_entries_start)
+
+.previous
+END(interrupt)
+.previous
 
 /*
  * the CPU automatically disables interrupts when executing an IRQ vector,
@@ -609,6 +618,7 @@ common_interrupt:
        movl %esp,%eax
        call do_IRQ
        jmp ret_from_intr
+ENDPROC(common_interrupt)
        CFI_ENDPROC
 
 #define BUILD_INTERRUPT(name, nr)      \
@@ -619,9 +629,10 @@ ENTRY(name)                                \
        SAVE_ALL;                       \
        TRACE_IRQS_OFF                  \
        movl %esp,%eax;                 \
-       call smp_/**/name;              \
+       call smp_##name;                \
        jmp ret_from_intr;              \
-       CFI_ENDPROC
+       CFI_ENDPROC;                    \
+ENDPROC(name)
 
 /* The include is where all of the SMP etc. interrupts come from */
 #include "entry_arch.h"
@@ -632,7 +643,7 @@ KPROBE_ENTRY(page_fault)
        CFI_ADJUST_CFA_OFFSET 4
        ALIGN
 error_code:
-       /* the function address is in %gs's slot on the stack */
+       /* the function address is in %fs's slot on the stack */
        pushl %es
        CFI_ADJUST_CFA_OFFSET 4
        /*CFI_REL_OFFSET es, 0*/
@@ -661,20 +672,20 @@ error_code:
        CFI_ADJUST_CFA_OFFSET 4
        CFI_REL_OFFSET ebx, 0
        cld
-       pushl %gs
+       pushl %fs
        CFI_ADJUST_CFA_OFFSET 4
-       /*CFI_REL_OFFSET gs, 0*/
-       movl $(__KERNEL_PDA), %ecx
-       movl %ecx, %gs
+       /*CFI_REL_OFFSET fs, 0*/
+       movl $(__KERNEL_PERCPU), %ecx
+       movl %ecx, %fs
        UNWIND_ESPFIX_STACK
        popl %ecx
        CFI_ADJUST_CFA_OFFSET -4
        /*CFI_REGISTER es, ecx*/
-       movl PT_GS(%esp), %edi          # get the function address
+       movl PT_FS(%esp), %edi          # get the function address
        movl PT_ORIG_EAX(%esp), %edx    # get the error code
        movl $-1, PT_ORIG_EAX(%esp)     # no syscall to restart
-       mov  %ecx, PT_GS(%esp)
-       /*CFI_REL_OFFSET gs, ES*/
+       mov  %ecx, PT_FS(%esp)
+       /*CFI_REL_OFFSET fs, ES*/
        movl $(__USER_DS), %ecx
        movl %ecx, %ds
        movl %ecx, %es
@@ -692,6 +703,7 @@ ENTRY(coprocessor_error)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(coprocessor_error)
 
 ENTRY(simd_coprocessor_error)
        RING0_INT_FRAME
@@ -701,6 +713,7 @@ ENTRY(simd_coprocessor_error)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(simd_coprocessor_error)
 
 ENTRY(device_not_available)
        RING0_INT_FRAME
@@ -721,6 +734,7 @@ device_not_available_emulate:
        CFI_ADJUST_CFA_OFFSET -4
        jmp ret_from_exception
        CFI_ENDPROC
+END(device_not_available)
 
 /*
  * Debug traps and NMI can happen at the one SYSENTER instruction
@@ -864,10 +878,12 @@ ENTRY(native_iret)
        .align 4
        .long 1b,iret_exc
 .previous
+END(native_iret)
 
 ENTRY(native_irq_enable_sysexit)
        sti
        sysexit
+END(native_irq_enable_sysexit)
 #endif
 
 KPROBE_ENTRY(int3)
@@ -890,6 +906,7 @@ ENTRY(overflow)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(overflow)
 
 ENTRY(bounds)
        RING0_INT_FRAME
@@ -899,6 +916,7 @@ ENTRY(bounds)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(bounds)
 
 ENTRY(invalid_op)
        RING0_INT_FRAME
@@ -908,6 +926,7 @@ ENTRY(invalid_op)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(invalid_op)
 
 ENTRY(coprocessor_segment_overrun)
        RING0_INT_FRAME
@@ -917,6 +936,7 @@ ENTRY(coprocessor_segment_overrun)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(coprocessor_segment_overrun)
 
 ENTRY(invalid_TSS)
        RING0_EC_FRAME
@@ -924,6 +944,7 @@ ENTRY(invalid_TSS)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(invalid_TSS)
 
 ENTRY(segment_not_present)
        RING0_EC_FRAME
@@ -931,6 +952,7 @@ ENTRY(segment_not_present)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(segment_not_present)
 
 ENTRY(stack_segment)
        RING0_EC_FRAME
@@ -938,6 +960,7 @@ ENTRY(stack_segment)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(stack_segment)
 
 KPROBE_ENTRY(general_protection)
        RING0_EC_FRAME
@@ -953,6 +976,7 @@ ENTRY(alignment_check)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(alignment_check)
 
 ENTRY(divide_error)
        RING0_INT_FRAME
@@ -962,6 +986,7 @@ ENTRY(divide_error)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(divide_error)
 
 #ifdef CONFIG_X86_MCE
 ENTRY(machine_check)
@@ -972,6 +997,7 @@ ENTRY(machine_check)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(machine_check)
 #endif
 
 ENTRY(spurious_interrupt_bug)
@@ -982,6 +1008,7 @@ ENTRY(spurious_interrupt_bug)
        CFI_ADJUST_CFA_OFFSET 4
        jmp error_code
        CFI_ENDPROC
+END(spurious_interrupt_bug)
 
 ENTRY(kernel_thread_helper)
        pushl $0                # fake return address for unwinder