]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/entry_64.S
x86: ptrace vs -ENOSYS
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / entry_64.S
index c7341e81941cc0e7d6863e317953316c2f045392..556a8df522a7adcf9583164be4cad60e29b00a97 100644 (file)
@@ -319,19 +319,17 @@ badsys:
        /* Do syscall tracing */
 tracesys:                       
        SAVE_REST
-       movq $-ENOSYS,RAX(%rsp)
+       movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
        FIXUP_TOP_OF_STACK %rdi
        movq %rsp,%rdi
        call syscall_trace_enter
        LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
        RESTORE_REST
        cmpq $__NR_syscall_max,%rax
-       movq $-ENOSYS,%rcx
-       cmova %rcx,%rax
-       ja  1f
+       ja   int_ret_from_sys_call      /* RAX(%rsp) set to -ENOSYS above */
        movq %r10,%rcx  /* fixup for C */
        call *sys_call_table(,%rax,8)
-1:     movq %rax,RAX-ARGOFFSET(%rsp)
+       movq %rax,RAX-ARGOFFSET(%rsp)
        /* Use IRET because user could have changed frame */
                
 /* 
@@ -453,6 +451,7 @@ ENTRY(stub_execve)
        CFI_REGISTER rip, r11
        SAVE_REST
        FIXUP_TOP_OF_STACK %r11
+       movq %rsp, %rcx
        call sys_execve
        RESTORE_TOP_OF_STACK %r11
        movq %rax,RAX(%rsp)
@@ -581,16 +580,24 @@ retint_restore_args:      /* return to kernel space */
         */
        TRACE_IRQS_IRETQ
 restore_args:
-       RESTORE_ARGS 0,8,0                                              
-#ifdef CONFIG_PARAVIRT
+       RESTORE_ARGS 0,8,0
+
+irq_return:
        INTERRUPT_RETURN
-#endif
+
+       .section __ex_table, "a"
+       .quad irq_return, bad_iret
+       .previous
+
+#ifdef CONFIG_PARAVIRT
 ENTRY(native_iret)
        iretq
 
        .section __ex_table,"a"
        .quad native_iret, bad_iret
        .previous
+#endif
+
        .section .fixup,"ax"
 bad_iret:
        /*
@@ -804,7 +811,7 @@ paranoid_swapgs\trace:
        SWAPGS_UNSAFE_STACK
 paranoid_restore\trace:
        RESTORE_ALL 8
-       INTERRUPT_RETURN
+       jmp irq_return
 paranoid_userspace\trace:
        GET_THREAD_INFO(%rcx)
        movl threadinfo_flags(%rcx),%ebx
@@ -919,7 +926,7 @@ error_kernelspace:
           iret run with kernel gs again, so don't set the user space flag.
           B stepping K8s sometimes report an truncated RIP for IRET 
           exceptions returning to compat mode. Check for these here too. */
-       leaq native_iret(%rip),%rbp
+       leaq irq_return(%rip),%rbp
        cmpq %rbp,RIP(%rsp) 
        je   error_swapgs
        movl %ebp,%ebp  /* zero extend */
@@ -1028,15 +1035,16 @@ ENDPROC(child_rip)
  *     rdi: name, rsi: argv, rdx: envp
  *
  * We want to fallback into:
- *     extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs regs)
+ *     extern long sys_execve(char *name, char **argv,char **envp, struct pt_regs *regs)
  *
  * do_sys_execve asm fallback arguments:
- *     rdi: name, rsi: argv, rdx: envp, fake frame on the stack
+ *     rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
  */
 ENTRY(kernel_execve)
        CFI_STARTPROC
        FAKE_STACK_FRAME $0
        SAVE_ALL        
+       movq %rsp,%rcx
        call sys_execve
        movq %rax, RAX(%rsp)    
        RESTORE_REST