]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.18.14/arc-clone-syscall-to-setp-r25-as-thread-pointer.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.18.14 / arc-clone-syscall-to-setp-r25-as-thread-pointer.patch
1 From c58a584f05e35d1d4342923cd7aac07d9c3d3d16 Mon Sep 17 00:00:00 2001
2 From: Vineet Gupta <vgupta@synopsys.com>
3 Date: Fri, 5 Oct 2018 12:48:48 -0700
4 Subject: ARC: clone syscall to setp r25 as thread pointer
5
6 From: Vineet Gupta <vgupta@synopsys.com>
7
8 commit c58a584f05e35d1d4342923cd7aac07d9c3d3d16 upstream.
9
10 Per ARC TLS ABI, r25 is designated TP (thread pointer register).
11 However so far kernel didn't do any special treatment, like setting up
12 usermode r25, even for CLONE_SETTLS. We instead relied on libc runtime
13 to do this, in say clone libc wrapper [1]. This was deliberate to keep
14 kernel ABI agnostic (userspace could potentially change TP, specially
15 for different ARC ISA say ARCompact vs. ARCv2 with different spare
16 registers etc)
17
18 However userspace setting up r25, after clone syscall opens a race, if
19 child is not scheduled and gets a signal instead. It starts off in
20 userspace not in clone but in a signal handler and anything TP sepcific
21 there such as pthread_self() fails which showed up with uClibc
22 testsuite nptl/tst-kill6 [2]
23
24 Fix this by having kernel populate r25 to TP value. So this locks in
25 ABI, but it was not going to change anyways, and fwiw is same for both
26 ARCompact (arc700 core) and ARCvs (HS3x cores)
27
28 [1] https://cgit.uclibc-ng.org/cgi/cgit/uclibc-ng.git/tree/libc/sysdeps/linux/arc/clone.S
29 [2] https://github.com/wbx-github/uclibc-ng-test/blob/master/test/nptl/tst-kill6.c
30
31 Fixes: ARC STAR 9001378481
32 Cc: stable@vger.kernel.org
33 Reported-by: Nikita Sobolev <sobolev@synopsys.com>
34 Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
35 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
36
37 ---
38 arch/arc/kernel/process.c | 20 ++++++++++++++++++++
39 1 file changed, 20 insertions(+)
40
41 --- a/arch/arc/kernel/process.c
42 +++ b/arch/arc/kernel/process.c
43 @@ -241,6 +241,26 @@ int copy_thread(unsigned long clone_flag
44 task_thread_info(current)->thr_ptr;
45 }
46
47 +
48 + /*
49 + * setup usermode thread pointer #1:
50 + * when child is picked by scheduler, __switch_to() uses @c_callee to
51 + * populate usermode callee regs: this works (despite being in a kernel
52 + * function) since special return path for child @ret_from_fork()
53 + * ensures those regs are not clobbered all the way to RTIE to usermode
54 + */
55 + c_callee->r25 = task_thread_info(p)->thr_ptr;
56 +
57 +#ifdef CONFIG_ARC_CURR_IN_REG
58 + /*
59 + * setup usermode thread pointer #2:
60 + * however for this special use of r25 in kernel, __switch_to() sets
61 + * r25 for kernel needs and only in the final return path is usermode
62 + * r25 setup, from pt_regs->user_r25. So set that up as well
63 + */
64 + c_regs->user_r25 = c_callee->r25;
65 +#endif
66 +
67 return 0;
68 }
69