x86/entry/32: Switch INT80 to the new C syscall path
[linux-2.6-block.git] / arch / x86 / entry / entry_32.S
index b2909bf8cf7029b17f6457edcd86b6e04395e94b..02881e528945449676c6a8d8231d8eb4f17c3857 100644 (file)
@@ -3,7 +3,7 @@
  *
  * entry_32.S contains the system-call and low-level fault and trap handling routines.
  *
- * Stack layout in 'syscall_exit':
+ * Stack layout while running C code:
  *     ptrace needs to have all registers on the stack.
  *     If the order here is changed, it needs to be
  *     updated in fork.c:copy_process(), signal.c:do_signal(),
 
 #endif /* CONFIG_X86_32_LAZY_GS */
 
-.macro SAVE_ALL
+.macro SAVE_ALL pt_regs_ax=%eax
        cld
        PUSH_GS
        pushl   %fs
        pushl   %es
        pushl   %ds
-       pushl   %eax
+       pushl   \pt_regs_ax
        pushl   %ebp
        pushl   %edi
        pushl   %esi
@@ -211,7 +211,11 @@ ENTRY(ret_from_fork)
        popl    %eax
        pushl   $0x0202                         # Reset kernel eflags
        popfl
-       jmp     syscall_exit
+
+       /* When we fork, we trace the syscall return in the child, too. */
+       movl    %esp, %eax
+       call    syscall_return_slowpath
+       jmp     restore_all
 END(ret_from_fork)
 
 ENTRY(ret_from_kernel_thread)
@@ -224,7 +228,15 @@ ENTRY(ret_from_kernel_thread)
        movl    PT_EBP(%esp), %eax
        call    *PT_EBX(%esp)
        movl    $0, PT_EAX(%esp)
-       jmp     syscall_exit
+
+       /*
+        * Kernel threads return to userspace as if returning from a syscall.
+        * We should check whether anything actually uses this path and, if so,
+        * consider switching it over to ret_from_fork.
+        */
+       movl    %esp, %eax
+       call    syscall_return_slowpath
+       jmp     restore_all
 ENDPROC(ret_from_kernel_thread)
 
 /*
@@ -255,7 +267,6 @@ ret_from_intr:
        jb      resume_kernel                   # not returning to v8086 or userspace
 
 ENTRY(resume_userspace)
-       LOCKDEP_SYS_EXIT
        DISABLE_INTERRUPTS(CLBR_ANY)
        TRACE_IRQS_OFF
        movl    %esp, %eax
@@ -359,21 +370,17 @@ ENDPROC(entry_SYSENTER_32)
        # system call handler stub
 ENTRY(entry_INT80_32)
        ASM_CLAC
-       pushl   %eax                            # save orig_eax
-       SAVE_ALL
-       GET_THREAD_INFO(%ebp)
-                                               # system call tracing in operation / emulation
-       testl   $_TIF_WORK_SYSCALL_ENTRY, TI_flags(%ebp)
-       jnz     syscall_trace_entry
-       cmpl    $(NR_syscalls), %eax
-       jae     syscall_badsys
-syscall_call:
-       call    *sys_call_table(, %eax, 4)
-syscall_after_call:
-       movl    %eax, PT_EAX(%esp)              # store the return value
-syscall_exit:
-       LOCKDEP_SYS_EXIT
-       jmp     syscall_exit_work
+       pushl   %eax                    /* pt_regs->orig_ax */
+       SAVE_ALL pt_regs_ax=$-ENOSYS    /* save rest, load -ENOSYS into ax */
+
+       /*
+        * User mode is traced as though IRQs are on, and the interrupt gate
+        * turned them off.
+        */
+       TRACE_IRQS_OFF
+
+       movl    %esp, %eax
+       call    do_int80_syscall_32
 
 restore_all:
        TRACE_IRQS_IRET
@@ -481,11 +488,6 @@ syscall_fault:
        jmp     resume_userspace
 END(syscall_fault)
 
-syscall_badsys:
-       movl    $-ENOSYS, %eax
-       jmp     syscall_after_call
-END(syscall_badsys)
-
 sysenter_badsys:
        movl    $-ENOSYS, %eax
        jmp     sysenter_after_call