mirror of https://gitee.com/openkylin/linux.git
arm64: Implement copy_thread_tls
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-arm-kernel@lists.infradead.org Cc: <stable@vger.kernel.org> # 5.3.x Acked-by: Will Deacon <will@kernel.org> Link: https://lore.kernel.org/r/20200102172413.654385-3-amanieu@gmail.com Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
3e3c8ca5a3
commit
a4376f2fbc
|
@ -138,6 +138,7 @@ config ARM64
|
||||||
select HAVE_CMPXCHG_DOUBLE
|
select HAVE_CMPXCHG_DOUBLE
|
||||||
select HAVE_CMPXCHG_LOCAL
|
select HAVE_CMPXCHG_LOCAL
|
||||||
select HAVE_CONTEXT_TRACKING
|
select HAVE_CONTEXT_TRACKING
|
||||||
|
select HAVE_COPY_THREAD_TLS
|
||||||
select HAVE_DEBUG_BUGVERBOSE
|
select HAVE_DEBUG_BUGVERBOSE
|
||||||
select HAVE_DEBUG_KMEMLEAK
|
select HAVE_DEBUG_KMEMLEAK
|
||||||
select HAVE_DMA_CONTIGUOUS
|
select HAVE_DMA_CONTIGUOUS
|
||||||
|
|
|
@ -360,8 +360,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
|
||||||
|
|
||||||
asmlinkage void ret_from_fork(void) asm("ret_from_fork");
|
asmlinkage void ret_from_fork(void) asm("ret_from_fork");
|
||||||
|
|
||||||
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
int copy_thread_tls(unsigned long clone_flags, unsigned long stack_start,
|
||||||
unsigned long stk_sz, struct task_struct *p)
|
unsigned long stk_sz, struct task_struct *p, unsigned long tls)
|
||||||
{
|
{
|
||||||
struct pt_regs *childregs = task_pt_regs(p);
|
struct pt_regs *childregs = task_pt_regs(p);
|
||||||
|
|
||||||
|
@ -394,11 +394,11 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a TLS pointer was passed to clone (4th argument), use it
|
* If a TLS pointer was passed to clone, use it for the new
|
||||||
* for the new thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
p->thread.uw.tp_value = childregs->regs[3];
|
p->thread.uw.tp_value = tls;
|
||||||
} else {
|
} else {
|
||||||
memset(childregs, 0, sizeof(struct pt_regs));
|
memset(childregs, 0, sizeof(struct pt_regs));
|
||||||
childregs->pstate = PSR_MODE_EL1h;
|
childregs->pstate = PSR_MODE_EL1h;
|
||||||
|
|
Loading…
Reference in New Issue