]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
um: Implement copy_thread_tls
authorAmanieu d'Antras <amanieu@gmail.com>
Sat, 4 Jan 2020 12:39:30 +0000 (13:39 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Tue, 7 Jan 2020 12:31:29 +0000 (13:31 +0100)
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>
arch/um/Kconfig
arch/um/include/asm/ptrace-generic.h
arch/um/kernel/process.c
arch/x86/um/tls_32.c
arch/x86/um/tls_64.c

index 2a6d04fcb3e91c7e191cec43b7d1e2d6d832819b..6f0edd0c0220f40dac6fd3c89309458e9f0981e6 100644 (file)
@@ -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
index 81c647ef9c6c8df98ae917178318a61647d9391e..adf91ef553ae91f215dcf1c457fcf258e8065423 100644 (file)
@@ -36,7 +36,7 @@ extern long subarch_ptrace(struct task_struct *child, long request,
 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);
index 263a8f06913341d1b0a9d013d89f12971e928391..17045e7211bfd461d9a055fcee9b0cb1f3ac6fed 100644 (file)
@@ -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_flags, unsigned long sp,
                 * 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;
index 5bd949da7a4a5deb659f19e849dcd6036a2843ac..ac8eee093f9cd0fa112fe89e945202eb60203a84 100644 (file)
@@ -215,14 +215,12 @@ static int set_tls_entry(struct task_struct* task, struct user_desc *info,
        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;
index 3a621e0d39253aa30a7d5eadb523cd4a2e1315cb..ebd3855d9b132379b7065222316a948e06b2b72e 100644 (file)
@@ -6,14 +6,13 @@ void clear_flushed_tls(struct task_struct *task)
 {
 }
 
-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;
 }