Skip to content

Commit b5dcd4a

Browse files
vineetgarcgregkh
authored andcommitted
ARC: clone syscall to setp r25 as thread pointer
commit c58a584 upstream. Per ARC TLS ABI, r25 is designated TP (thread pointer register). However so far kernel didn't do any special treatment, like setting up usermode r25, even for CLONE_SETTLS. We instead relied on libc runtime to do this, in say clone libc wrapper [1]. This was deliberate to keep kernel ABI agnostic (userspace could potentially change TP, specially for different ARC ISA say ARCompact vs. ARCv2 with different spare registers etc) However userspace setting up r25, after clone syscall opens a race, if child is not scheduled and gets a signal instead. It starts off in userspace not in clone but in a signal handler and anything TP sepcific there such as pthread_self() fails which showed up with uClibc testsuite nptl/tst-kill6 [2] Fix this by having kernel populate r25 to TP value. So this locks in ABI, but it was not going to change anyways, and fwiw is same for both ARCompact (arc700 core) and ARCvs (HS3x cores) [1] https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/sysdeps/linux/arc/clone.S [2] https://github.com/wbx-github/uclibc-ng-test/blob/master/test/nptl/tst-kill6.c Fixes: ARC STAR 9001378481 Cc: [email protected] Reported-by: Nikita Sobolev <[email protected]> Signed-off-by: Vineet Gupta <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent af1a810 commit b5dcd4a

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

arch/arc/kernel/process.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,26 @@ int copy_thread(unsigned long clone_flags,
241241
task_thread_info(current)->thr_ptr;
242242
}
243243

244+
245+
/*
246+
* setup usermode thread pointer #1:
247+
* when child is picked by scheduler, __switch_to() uses @c_callee to
248+
* populate usermode callee regs: this works (despite being in a kernel
249+
* function) since special return path for child @ret_from_fork()
250+
* ensures those regs are not clobbered all the way to RTIE to usermode
251+
*/
252+
c_callee->r25 = task_thread_info(p)->thr_ptr;
253+
254+
#ifdef CONFIG_ARC_CURR_IN_REG
255+
/*
256+
* setup usermode thread pointer #2:
257+
* however for this special use of r25 in kernel, __switch_to() sets
258+
* r25 for kernel needs and only in the final return path is usermode
259+
* r25 setup, from pt_regs->user_r25. So set that up as well
260+
*/
261+
c_regs->user_r25 = c_callee->r25;
262+
#endif
263+
244264
return 0;
245265
}
246266

0 commit comments

Comments
 (0)