x86/entry/64/compat: Set up full pt_regs for all compat syscalls
authorAndy Lutomirski <luto@kernel.org>
Tue, 6 Oct 2015 00:48:05 +0000 (17:48 -0700)
committerIngo Molnar <mingo@kernel.org>
Fri, 9 Oct 2015 07:41:07 +0000 (09:41 +0200)
This is conceptually simpler.  More importantly, it eliminates
the PTREGSCALL and execve stubs, which were not compatible with
the C ABI.  This means that C code can call through the compat
syscall table.

The execve stubs are a bit subtle.  They did two things: they
cleared some registers and they forced slow-path return.
Neither is necessary any more: elf_common_init clears the extra
registers and start_thread calls force_iret().

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Link: http://lkml.kernel.org/r/f95b7f7dfaacf88a8cae85bb06226cae53769287.1444091584.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/entry/entry_64.S
arch/x86/entry/entry_64_compat.S
arch/x86/entry/syscalls/syscall_32.tbl

index 7dc285036b6d45d111e9848b8002b5cacb9e5889..83ad95877570c1f3f469e39f9ca1e5f9dd9be1ea 100644 (file)
@@ -391,20 +391,16 @@ GLOBAL(stub_execveat)
        jmp     return_from_execve
 END(stub_execveat)
 
-#if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION)
+#if defined(CONFIG_X86_X32_ABI)
        .align  8
 GLOBAL(stub_x32_execve)
-GLOBAL(stub32_execve)
        call    compat_sys_execve
        jmp     return_from_execve
-END(stub32_execve)
 END(stub_x32_execve)
        .align  8
 GLOBAL(stub_x32_execveat)
-GLOBAL(stub32_execveat)
        call    compat_sys_execveat
        jmp     return_from_execve
-END(stub32_execveat)
 END(stub_x32_execveat)
 #endif
 
index 3216e60723120b71f637093a2c064115a036c306..2c2aac577b3ccc61af94f3b2c9a778b3b33befea 100644 (file)
@@ -219,12 +219,18 @@ ENTRY(entry_INT80_compat)
        pushq   %rdx                    /* pt_regs->dx */
        pushq   %rcx                    /* pt_regs->cx */
        pushq   $-ENOSYS                /* pt_regs->ax */
-       pushq   $0                      /* pt_regs->r8 */
-       pushq   $0                      /* pt_regs->r9 */
-       pushq   $0                      /* pt_regs->r10 */
-       pushq   $0                      /* pt_regs->r11 */
+       xorq    %r8,%r8
+       pushq   %r8                     /* pt_regs->r8  = 0 */
+       pushq   %r8                     /* pt_regs->r9  = 0 */
+       pushq   %r8                     /* pt_regs->r10 = 0 */
+       pushq   %r8                     /* pt_regs->r11 = 0 */
+       pushq   %rbx                    /* pt_regs->rbx */
+       pushq   %rbp                    /* pt_regs->rbp */
+       pushq   %r12                    /* pt_regs->r12 */
+       pushq   %r13                    /* pt_regs->r13 */
+       pushq   %r14                    /* pt_regs->r14 */
+       pushq   %r15                    /* pt_regs->r15 */
        cld
-       sub     $(6*8), %rsp /* pt_regs->bp, bx, r12-15 not saved */
 
        orl     $TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS)
        testl   $_TIF_WORK_SYSCALL_ENTRY, ASM_THREAD_INFO(TI_flags, %rsp, SIZEOF_PTREGS)
@@ -243,10 +249,10 @@ ia32_do_call:
        call    *ia32_sys_call_table(, %rax, 8)
        movq    %rax, RAX(%rsp)
 1:
+       RESTORE_EXTRA_REGS
        jmp     int_ret_from_sys_call
 
 ia32_tracesys:
-       SAVE_EXTRA_REGS
        movq    %rsp, %rdi                      /* &pt_regs -> arg1 */
        call    syscall_trace_enter
        /*
@@ -261,25 +267,11 @@ ia32_tracesys:
        movl    RSI(%rsp), %esi
        movl    RDI(%rsp), %edi
        movl    %eax, %eax              /* zero extension */
-       RESTORE_EXTRA_REGS
        jmp     ia32_do_call
 END(entry_INT80_compat)
 
-       .macro PTREGSCALL label, func
-       ALIGN
-GLOBAL(\label)
-       leaq    \func(%rip), %rax
-       jmp     ia32_ptregs_common
-       .endm
-
-       PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
-       PTREGSCALL stub32_sigreturn,    sys32_sigreturn
-       PTREGSCALL stub32_fork,         sys_fork
-       PTREGSCALL stub32_vfork,        sys_vfork
-
        ALIGN
 GLOBAL(stub32_clone)
-       leaq    sys_clone(%rip), %rax
        /*
         * The 32-bit clone ABI is: clone(..., int tls_val, int *child_tidptr).
         * The 64-bit clone ABI is: clone(..., int *child_tidptr, int tls_val).
@@ -288,12 +280,4 @@ GLOBAL(stub32_clone)
         * so we need to swap arguments here before calling it:
         */
        xchg    %r8, %rcx
-       jmp     ia32_ptregs_common
-
-       ALIGN
-ia32_ptregs_common:
-       SAVE_EXTRA_REGS 8
-       call    *%rax
-       RESTORE_EXTRA_REGS 8
-       ret
-END(ia32_ptregs_common)
+       jmp     sys_clone
index 7663c455b9f650f67292e5a2c4664606fb1dbacb..caa2c712d1e70c5895d92cf856b91a02d9123083 100644 (file)
@@ -8,7 +8,7 @@
 #
 0      i386    restart_syscall         sys_restart_syscall
 1      i386    exit                    sys_exit
-2      i386    fork                    sys_fork                        stub32_fork
+2      i386    fork                    sys_fork                        sys_fork
 3      i386    read                    sys_read
 4      i386    write                   sys_write
 5      i386    open                    sys_open                        compat_sys_open
@@ -17,7 +17,7 @@
 8      i386    creat                   sys_creat
 9      i386    link                    sys_link
 10     i386    unlink                  sys_unlink
-11     i386    execve                  sys_execve                      stub32_execve
+11     i386    execve                  sys_execve                      compat_sys_execve
 12     i386    chdir                   sys_chdir
 13     i386    time                    sys_time                        compat_sys_time
 14     i386    mknod                   sys_mknod
 116    i386    sysinfo                 sys_sysinfo                     compat_sys_sysinfo
 117    i386    ipc                     sys_ipc                         compat_sys_ipc
 118    i386    fsync                   sys_fsync
-119    i386    sigreturn               sys_sigreturn                   stub32_sigreturn
+119    i386    sigreturn               sys_sigreturn                   sys32_sigreturn
 120    i386    clone                   sys_clone                       stub32_clone
 121    i386    setdomainname           sys_setdomainname
 122    i386    uname                   sys_newuname
 170    i386    setresgid               sys_setresgid16
 171    i386    getresgid               sys_getresgid16
 172    i386    prctl                   sys_prctl
-173    i386    rt_sigreturn            sys_rt_sigreturn                stub32_rt_sigreturn
+173    i386    rt_sigreturn            sys_rt_sigreturn                sys32_rt_sigreturn
 174    i386    rt_sigaction            sys_rt_sigaction                compat_sys_rt_sigaction
 175    i386    rt_sigprocmask          sys_rt_sigprocmask
 176    i386    rt_sigpending           sys_rt_sigpending               compat_sys_rt_sigpending
 187    i386    sendfile                sys_sendfile                    compat_sys_sendfile
 188    i386    getpmsg
 189    i386    putpmsg
-190    i386    vfork                   sys_vfork                       stub32_vfork
+190    i386    vfork                   sys_vfork                       sys_vfork
 191    i386    ugetrlimit              sys_getrlimit                   compat_sys_getrlimit
 192    i386    mmap2                   sys_mmap_pgoff
 193    i386    truncate64              sys_truncate64                  sys32_truncate64
 355    i386    getrandom               sys_getrandom
 356    i386    memfd_create            sys_memfd_create
 357    i386    bpf                     sys_bpf
-358    i386    execveat                sys_execveat                    stub32_execveat
+358    i386    execveat                sys_execveat                    compat_sys_execveat
 359    i386    socket                  sys_socket
 360    i386    socketpair              sys_socketpair
 361    i386    bind                    sys_bind