xtensa: Implement copy_thread_tls
authorAmanieu d'Antras <amanieu@gmail.com>
Thu, 2 Jan 2020 17:24:12 +0000 (18:24 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jan 2020 19:08:35 +0000 (20:08 +0100)
commit c346b94f8c5d1b7d637522c908209de93305a8eb 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-xtensa@linux-xtensa.org
Cc: <stable@vger.kernel.org> # 5.3.x
Link: https://lore.kernel.org/r/20200102172413.654385-7-amanieu@gmail.com
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/xtensa/Kconfig
arch/xtensa/kernel/process.c

index a8e7beb6b7b55b941c2a3b0d659ce386bfa11afc..8352037322dfb68edcb0d8847b1a63399d40dbbc 100644 (file)
@@ -22,6 +22,7 @@ config XTENSA
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_ARCH_KASAN if MMU
        select HAVE_ARCH_TRACEHOOK
+       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DMA_CONTIGUOUS
        select HAVE_EXIT_THREAD
index db278a9e80c7e1d3a3f527e98938f58d30cc1da2..7cbf8bd6d9226d7571bef63d8b5dea4dceb94f94 100644 (file)
@@ -202,8 +202,9 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
  * involved.  Much simpler to just not copy those live frames across.
  */
 
-int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
-               unsigned long thread_fn_arg, struct task_struct *p)
+int copy_thread_tls(unsigned long clone_flags, unsigned long usp_thread_fn,
+               unsigned long thread_fn_arg, struct task_struct *p,
+               unsigned long tls)
 {
        struct pt_regs *childregs = task_pt_regs(p);
 
@@ -264,9 +265,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn,
                               &regs->areg[XCHAL_NUM_AREGS - len/4], len);
                }
 
-               /* The thread pointer is passed in the '4th argument' (= a5) */
                if (clone_flags & CLONE_SETTLS)
-                       childregs->threadptr = childregs->areg[5];
+                       childregs->threadptr = tls;
        } else {
                p->thread.ra = MAKE_RA_FOR_CALL(
                                (unsigned long)ret_from_kernel_thread, 1);