Skip to content
  • Josh Triplett's avatar
    clone: support passing tls argument via C rather than pt_regs magic · 3033f14a
    Josh Triplett authored
    
    
    clone has some of the quirkiest syscall handling in the kernel, with a
    pile of special cases, historical curiosities, and architecture-specific
    calling conventions.  In particular, clone with CLONE_SETTLS accepts a
    parameter "tls" that the C entry point completely ignores and some
    assembly entry points overwrite; instead, the low-level arch-specific
    code pulls the tls parameter out of the arch-specific register captured
    as part of pt_regs on entry to the kernel.  That's a massive hack, and
    it makes the arch-specific code only work when called via the specific
    existing syscall entry points; because of this hack, any new clone-like
    system call would have to accept an identical tls argument in exactly
    the same arch-specific position, rather than providing a unified system
    call entry point across architectures.
    
    The first patch allows architectures to handle the tls argument via
    normal C parameter passing, if they opt in by selecting
    HAVE_COPY_THREAD_TLS.  The second patch makes 32-bit and 64-bit x86 opt
    into this.
    
    These two patches came out of the clone4 series, which isn't ready for
    this merge window, but these first two cleanup patches were entirely
    uncontroversial and have acks.  I'd like to go ahead and submit these
    two so that other architectures can begin building on top of this and
    opting into HAVE_COPY_THREAD_TLS.  However, I'm also happy to wait and
    send these through the next merge window (along with v3 of clone4) if
    anyone would prefer that.
    
    This patch (of 2):
    
    clone with CLONE_SETTLS accepts an argument to set the thread-local
    storage area for the new thread.  sys_clone declares an int argument
    tls_val in the appropriate point in the argument list (based on the
    various CLONE_BACKWARDS variants), but doesn't actually use or pass along
    that argument.  Instead, sys_clone calls do_fork, which calls
    copy_process, which calls the arch-specific copy_thread, and copy_thread
    pulls the corresponding syscall argument out of the pt_regs captured at
    kernel entry (knowing what argument of clone that architecture passes tls
    in).
    
    Apart from being awful and inscrutable, that also only works because only
    one code path into copy_thread can pass the CLONE_SETTLS flag, and that
    code path comes from sys_clone with its architecture-specific
    argument-passing order.  This prevents introducing a new version of the
    clone system call without propagating the same architecture-specific
    position of the tls argument.
    
    However, there's no reason to pull the argument out of pt_regs when
    sys_clone could just pass it down via C function call arguments.
    
    Introduce a new CONFIG_HAVE_COPY_THREAD_TLS for architectures to opt into,
    and a new copy_thread_tls that accepts the tls parameter as an additional
    unsigned long (syscall-argument-sized) argument.  Change sys_clone's tls
    argument to an unsigned long (which does not change the ABI), and pass
    that down to copy_thread_tls.
    
    Architectures that don't opt into copy_thread_tls will continue to ignore
    the C argument to sys_clone in favor of the pt_regs captured at kernel
    entry, and thus will be unable to introduce new versions of the clone
    syscall.
    
    Patch co-authored by Josh Triplett and Thiago Macieira.
    
    Signed-off-by: default avatarJosh Triplett <josh@joshtriplett.org>
    Acked-by: default avatarAndy Lutomirski <luto@kernel.org>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Thiago Macieira <thiago.macieira@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    3033f14a