lkml.org 
[lkml]   [2020]   [Jan]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 64/78] um: Implement copy_thread_tls
    Date
    From: Amanieu d'Antras <amanieu@gmail.com>

    commit 457677c70c7672a4586b0b8abc396cc1ecdd376d upstream.

    This is required for clone3 which passes the TLS value through a
    struct rather than a register.

    Signed-off-by: Amanieu d'Antras <amanieu@gmail.com>
    Cc: linux-um@lists.infradead.org
    Cc: <stable@vger.kernel.org> # 5.3.x
    Link: https://lore.kernel.org/r/20200104123928.1048822-1-amanieu@gmail.com
    Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/um/Kconfig | 1 +
    arch/um/include/asm/ptrace-generic.h | 2 +-
    arch/um/kernel/process.c | 6 +++---
    arch/x86/um/tls_32.c | 6 ++----
    arch/x86/um/tls_64.c | 7 +++----
    5 files changed, 10 insertions(+), 12 deletions(-)

    --- a/arch/um/Kconfig
    +++ b/arch/um/Kconfig
    @@ -14,6 +14,7 @@ config UML
    select HAVE_FUTEX_CMPXCHG if FUTEX
    select HAVE_DEBUG_KMEMLEAK
    select HAVE_DEBUG_BUGVERBOSE
    + select HAVE_COPY_THREAD_TLS
    select GENERIC_IRQ_SHOW
    select GENERIC_CPU_DEVICES
    select GENERIC_CLOCKEVENTS
    --- a/arch/um/include/asm/ptrace-generic.h
    +++ b/arch/um/include/asm/ptrace-generic.h
    @@ -36,7 +36,7 @@ extern long subarch_ptrace(struct task_s
    extern unsigned long getreg(struct task_struct *child, int regno);
    extern int putreg(struct task_struct *child, int regno, unsigned long value);

    -extern int arch_copy_tls(struct task_struct *new);
    +extern int arch_set_tls(struct task_struct *new, unsigned long tls);
    extern void clear_flushed_tls(struct task_struct *task);
    extern int syscall_trace_enter(struct pt_regs *regs);
    extern void syscall_trace_leave(struct pt_regs *regs);
    --- a/arch/um/kernel/process.c
    +++ b/arch/um/kernel/process.c
    @@ -153,8 +153,8 @@ void fork_handler(void)
    userspace(&current->thread.regs.regs, current_thread_info()->aux_fp_regs);
    }

    -int copy_thread(unsigned long clone_flags, unsigned long sp,
    - unsigned long arg, struct task_struct * p)
    +int copy_thread_tls(unsigned long clone_flags, unsigned long sp,
    + unsigned long arg, struct task_struct * p, unsigned long tls)
    {
    void (*handler)(void);
    int kthread = current->flags & PF_KTHREAD;
    @@ -188,7 +188,7 @@ int copy_thread(unsigned long clone_flag
    * Set a new TLS for the child thread?
    */
    if (clone_flags & CLONE_SETTLS)
    - ret = arch_copy_tls(p);
    + ret = arch_set_tls(p, tls);
    }

    return ret;
    --- a/arch/x86/um/tls_32.c
    +++ b/arch/x86/um/tls_32.c
    @@ -215,14 +215,12 @@ static int set_tls_entry(struct task_str
    return 0;
    }

    -int arch_copy_tls(struct task_struct *new)
    +int arch_set_tls(struct task_struct *new, unsigned long tls)
    {
    struct user_desc info;
    int idx, ret = -EFAULT;

    - if (copy_from_user(&info,
    - (void __user *) UPT_SI(&new->thread.regs.regs),
    - sizeof(info)))
    + if (copy_from_user(&info, (void __user *) tls, sizeof(info)))
    goto out;

    ret = -EINVAL;
    --- a/arch/x86/um/tls_64.c
    +++ b/arch/x86/um/tls_64.c
    @@ -6,14 +6,13 @@ void clear_flushed_tls(struct task_struc
    {
    }

    -int arch_copy_tls(struct task_struct *t)
    +int arch_set_tls(struct task_struct *t, unsigned long tls)
    {
    /*
    * If CLONE_SETTLS is set, we need to save the thread id
    - * (which is argument 5, child_tid, of clone) so it can be set
    - * during context switches.
    + * so it can be set during context switches.
    */
    - t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)];
    + t->thread.arch.fs = tls;

    return 0;
    }

    \
     
     \ /
      Last update: 2020-01-14 11:20    [W:3.769 / U:1.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site