]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/linux/linux_fork.c
Merge clang trunk r338150, and resolve conflicts.
[FreeBSD/FreeBSD.git] / sys / compat / linux / linux_fork.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2004 Tim J. Robbins
5  * Copyright (c) 2002 Doug Rabson
6  * Copyright (c) 2000 Marcel Moolenaar
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer
14  *    in this position and unchanged.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include "opt_compat.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/imgact.h>
39 #include <sys/ktr.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/proc.h>
43 #include <sys/ptrace.h>
44 #include <sys/racct.h>
45 #include <sys/sched.h>
46 #include <sys/syscallsubr.h>
47 #include <sys/sx.h>
48 #include <sys/umtx.h>
49 #include <sys/unistd.h>
50 #include <sys/wait.h>
51
52 #include <vm/vm.h>
53 #include <vm/pmap.h>
54 #include <vm/vm_map.h>
55
56 #ifdef COMPAT_LINUX32
57 #include <machine/../linux32/linux.h>
58 #include <machine/../linux32/linux32_proto.h>
59 #else
60 #include <machine/../linux/linux.h>
61 #include <machine/../linux/linux_proto.h>
62 #endif
63 #include <compat/linux/linux_emul.h>
64 #include <compat/linux/linux_futex.h>
65 #include <compat/linux/linux_misc.h>
66 #include <compat/linux/linux_util.h>
67
68 #ifdef LINUX_LEGACY_SYSCALLS
69 int
70 linux_fork(struct thread *td, struct linux_fork_args *args)
71 {
72         struct fork_req fr;
73         int error;
74         struct proc *p2;
75         struct thread *td2;
76
77 #ifdef DEBUG
78         if (ldebug(fork))
79                 printf(ARGS(fork, ""));
80 #endif
81
82         bzero(&fr, sizeof(fr));
83         fr.fr_flags = RFFDG | RFPROC | RFSTOPPED;
84         fr.fr_procp = &p2;
85         if ((error = fork1(td, &fr)) != 0)
86                 return (error);
87
88         td2 = FIRST_THREAD_IN_PROC(p2);
89
90         linux_proc_init(td, td2, 0);
91
92         td->td_retval[0] = p2->p_pid;
93
94         /*
95          * Make this runnable after we are finished with it.
96          */
97         thread_lock(td2);
98         TD_SET_CAN_RUN(td2);
99         sched_add(td2, SRQ_BORING);
100         thread_unlock(td2);
101
102         return (0);
103 }
104
105 int
106 linux_vfork(struct thread *td, struct linux_vfork_args *args)
107 {
108         struct fork_req fr;
109         int error;
110         struct proc *p2;
111         struct thread *td2;
112
113 #ifdef DEBUG
114         if (ldebug(vfork))
115                 printf(ARGS(vfork, ""));
116 #endif
117
118         bzero(&fr, sizeof(fr));
119         fr.fr_flags = RFFDG | RFPROC | RFMEM | RFPPWAIT | RFSTOPPED;
120         fr.fr_procp = &p2;
121         if ((error = fork1(td, &fr)) != 0)
122                 return (error);
123
124         td2 = FIRST_THREAD_IN_PROC(p2);
125
126         linux_proc_init(td, td2, 0);
127
128         td->td_retval[0] = p2->p_pid;
129
130         /*
131          * Make this runnable after we are finished with it.
132          */
133         thread_lock(td2);
134         TD_SET_CAN_RUN(td2);
135         sched_add(td2, SRQ_BORING);
136         thread_unlock(td2);
137
138         return (0);
139 }
140 #endif
141
142 static int
143 linux_clone_proc(struct thread *td, struct linux_clone_args *args)
144 {
145         struct fork_req fr;
146         int error, ff = RFPROC | RFSTOPPED;
147         struct proc *p2;
148         struct thread *td2;
149         int exit_signal;
150         struct linux_emuldata *em;
151
152 #ifdef DEBUG
153         if (ldebug(clone)) {
154                 printf(ARGS(clone, "flags %x, stack %p, parent tid: %p, "
155                     "child tid: %p"), (unsigned)args->flags,
156                     args->stack, args->parent_tidptr, args->child_tidptr);
157         }
158 #endif
159
160         exit_signal = args->flags & 0x000000ff;
161         if (LINUX_SIG_VALID(exit_signal)) {
162                 exit_signal = linux_to_bsd_signal(exit_signal);
163         } else if (exit_signal != 0)
164                 return (EINVAL);
165
166         if (args->flags & LINUX_CLONE_VM)
167                 ff |= RFMEM;
168         if (args->flags & LINUX_CLONE_SIGHAND)
169                 ff |= RFSIGSHARE;
170         /*
171          * XXX: In Linux, sharing of fs info (chroot/cwd/umask)
172          * and open files is independent.  In FreeBSD, its in one
173          * structure but in reality it does not cause any problems
174          * because both of these flags are usually set together.
175          */
176         if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
177                 ff |= RFFDG;
178
179         if (args->flags & LINUX_CLONE_PARENT_SETTID)
180                 if (args->parent_tidptr == NULL)
181                         return (EINVAL);
182
183         if (args->flags & LINUX_CLONE_VFORK)
184                 ff |= RFPPWAIT;
185
186         bzero(&fr, sizeof(fr));
187         fr.fr_flags = ff;
188         fr.fr_procp = &p2;
189         error = fork1(td, &fr);
190         if (error)
191                 return (error);
192
193         td2 = FIRST_THREAD_IN_PROC(p2);
194
195         /* create the emuldata */
196         linux_proc_init(td, td2, args->flags);
197
198         em = em_find(td2);
199         KASSERT(em != NULL, ("clone_proc: emuldata not found.\n"));
200
201         if (args->flags & LINUX_CLONE_CHILD_SETTID)
202                 em->child_set_tid = args->child_tidptr;
203         else
204                 em->child_set_tid = NULL;
205
206         if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
207                 em->child_clear_tid = args->child_tidptr;
208         else
209                 em->child_clear_tid = NULL;
210
211         if (args->flags & LINUX_CLONE_PARENT_SETTID) {
212                 error = copyout(&p2->p_pid, args->parent_tidptr,
213                     sizeof(p2->p_pid));
214                 if (error)
215                         printf(LMSG("copyout failed!"));
216         }
217
218         PROC_LOCK(p2);
219         p2->p_sigparent = exit_signal;
220         PROC_UNLOCK(p2);
221         /*
222          * In a case of stack = NULL, we are supposed to COW calling process
223          * stack. This is what normal fork() does, so we just keep tf_rsp arg
224          * intact.
225          */
226         linux_set_upcall_kse(td2, PTROUT(args->stack));
227
228         if (args->flags & LINUX_CLONE_SETTLS)
229                 linux_set_cloned_tls(td2, args->tls);
230
231         /*
232          * If CLONE_PARENT is set, then the parent of the new process will be
233          * the same as that of the calling process.
234          */
235         if (args->flags & LINUX_CLONE_PARENT) {
236                 sx_xlock(&proctree_lock);
237                 PROC_LOCK(p2);
238                 proc_reparent(p2, td->td_proc->p_pptr);
239                 PROC_UNLOCK(p2);
240                 sx_xunlock(&proctree_lock);
241         }
242
243 #ifdef DEBUG
244         if (ldebug(clone))
245                 printf(LMSG("clone: successful rfork to %d, "
246                     "stack %p sig = %d"), (int)p2->p_pid, args->stack,
247                     exit_signal);
248 #endif
249
250         /*
251          * Make this runnable after we are finished with it.
252          */
253         thread_lock(td2);
254         TD_SET_CAN_RUN(td2);
255         sched_add(td2, SRQ_BORING);
256         thread_unlock(td2);
257
258         td->td_retval[0] = p2->p_pid;
259
260         return (0);
261 }
262
263 static int
264 linux_clone_thread(struct thread *td, struct linux_clone_args *args)
265 {
266         struct linux_emuldata *em;
267         struct thread *newtd;
268         struct proc *p;
269         int error;
270
271 #ifdef DEBUG
272         if (ldebug(clone)) {
273                 printf(ARGS(clone, "thread: flags %x, stack %p, parent tid: %p, "
274                     "child tid: %p"), (unsigned)args->flags,
275                     args->stack, args->parent_tidptr, args->child_tidptr);
276         }
277 #endif
278
279         LINUX_CTR4(clone_thread, "thread(%d) flags %x ptid %p ctid %p",
280             td->td_tid, (unsigned)args->flags,
281             args->parent_tidptr, args->child_tidptr);
282
283         if (args->flags & LINUX_CLONE_PARENT_SETTID)
284                 if (args->parent_tidptr == NULL)
285                         return (EINVAL);
286
287         /* Threads should be created with own stack */
288         if (args->stack == NULL)
289                 return (EINVAL);
290
291         p = td->td_proc;
292
293 #ifdef RACCT
294         if (racct_enable) {
295                 PROC_LOCK(p);
296                 error = racct_add(p, RACCT_NTHR, 1);
297                 PROC_UNLOCK(p);
298                 if (error != 0)
299                         return (EPROCLIM);
300         }
301 #endif
302
303         /* Initialize our td */
304         error = kern_thr_alloc(p, 0, &newtd);
305         if (error)
306                 goto fail;
307
308         cpu_copy_thread(newtd, td);
309
310         bzero(&newtd->td_startzero,
311             __rangeof(struct thread, td_startzero, td_endzero));
312         bcopy(&td->td_startcopy, &newtd->td_startcopy,
313             __rangeof(struct thread, td_startcopy, td_endcopy));
314
315         newtd->td_proc = p;
316         thread_cow_get(newtd, td);
317
318         /* create the emuldata */
319         linux_proc_init(td, newtd, args->flags);
320
321         em = em_find(newtd);
322         KASSERT(em != NULL, ("clone_thread: emuldata not found.\n"));
323
324         if (args->flags & LINUX_CLONE_SETTLS)
325                 linux_set_cloned_tls(newtd, args->tls);
326
327         if (args->flags & LINUX_CLONE_CHILD_SETTID)
328                 em->child_set_tid = args->child_tidptr;
329         else
330                 em->child_set_tid = NULL;
331
332         if (args->flags & LINUX_CLONE_CHILD_CLEARTID)
333                 em->child_clear_tid = args->child_tidptr;
334         else
335                 em->child_clear_tid = NULL;
336
337         cpu_thread_clean(newtd);
338
339         linux_set_upcall_kse(newtd, PTROUT(args->stack));
340
341         PROC_LOCK(p);
342         p->p_flag |= P_HADTHREADS;
343         bcopy(p->p_comm, newtd->td_name, sizeof(newtd->td_name));
344
345         if (args->flags & LINUX_CLONE_PARENT)
346                 thread_link(newtd, p->p_pptr);
347         else
348                 thread_link(newtd, p);
349
350         thread_lock(td);
351         /* let the scheduler know about these things. */
352         sched_fork_thread(td, newtd);
353         thread_unlock(td);
354         if (P_SHOULDSTOP(p))
355                 newtd->td_flags |= TDF_ASTPENDING | TDF_NEEDSUSPCHK;
356         
357         if (p->p_ptevents & PTRACE_LWP)
358                 newtd->td_dbgflags |= TDB_BORN;
359         PROC_UNLOCK(p);
360
361         tidhash_add(newtd);
362
363 #ifdef DEBUG
364         if (ldebug(clone))
365                 printf(ARGS(clone, "successful clone to %d, stack %p"),
366                 (int)newtd->td_tid, args->stack);
367 #endif
368
369         LINUX_CTR2(clone_thread, "thread(%d) successful clone to %d",
370             td->td_tid, newtd->td_tid);
371
372         if (args->flags & LINUX_CLONE_PARENT_SETTID) {
373                 error = copyout(&newtd->td_tid, args->parent_tidptr,
374                     sizeof(newtd->td_tid));
375                 if (error)
376                         printf(LMSG("clone_thread: copyout failed!"));
377         }
378
379         /*
380          * Make this runnable after we are finished with it.
381          */
382         thread_lock(newtd);
383         TD_SET_CAN_RUN(newtd);
384         sched_add(newtd, SRQ_BORING);
385         thread_unlock(newtd);
386
387         td->td_retval[0] = newtd->td_tid;
388
389         return (0);
390
391 fail:
392 #ifdef RACCT
393         if (racct_enable) {
394                 PROC_LOCK(p);
395                 racct_sub(p, RACCT_NTHR, 1);
396                 PROC_UNLOCK(p);
397         }
398 #endif
399         return (error);
400 }
401
402 int
403 linux_clone(struct thread *td, struct linux_clone_args *args)
404 {
405
406         if (args->flags & LINUX_CLONE_THREAD)
407                 return (linux_clone_thread(td, args));
408         else
409                 return (linux_clone_proc(td, args));
410 }
411
412 int
413 linux_exit(struct thread *td, struct linux_exit_args *args)
414 {
415         struct linux_emuldata *em;
416
417         em = em_find(td);
418         KASSERT(em != NULL, ("exit: emuldata not found.\n"));
419
420         LINUX_CTR2(exit, "thread(%d) (%d)", em->em_tid, args->rval);
421
422         umtx_thread_exit(td);
423
424         linux_thread_detach(td);
425
426         /*
427          * XXX. When the last two threads of a process
428          * exit via pthread_exit() try thr_exit() first.
429          */
430         kern_thr_exit(td);
431         exit1(td, args->rval, 0);
432                 /* NOTREACHED */
433 }
434
435 int
436 linux_set_tid_address(struct thread *td, struct linux_set_tid_address_args *args)
437 {
438         struct linux_emuldata *em;
439
440         em = em_find(td);
441         KASSERT(em != NULL, ("set_tid_address: emuldata not found.\n"));
442
443         em->child_clear_tid = args->tidptr;
444
445         td->td_retval[0] = em->em_tid;
446
447         LINUX_CTR3(set_tid_address, "tidptr(%d) %p, returns %d",
448             em->em_tid, args->tidptr, td->td_retval[0]);
449
450         return (0);
451 }
452
453 void
454 linux_thread_detach(struct thread *td)
455 {
456         struct linux_sys_futex_args cup;
457         struct linux_emuldata *em;
458         int *child_clear_tid;
459         int error;
460
461         em = em_find(td);
462         KASSERT(em != NULL, ("thread_detach: emuldata not found.\n"));
463
464         LINUX_CTR1(thread_detach, "thread(%d)", em->em_tid);
465
466         release_futexes(td, em);
467
468         child_clear_tid = em->child_clear_tid;
469
470         if (child_clear_tid != NULL) {
471
472                 LINUX_CTR2(thread_detach, "thread(%d) %p",
473                     em->em_tid, child_clear_tid);
474
475                 error = suword32(child_clear_tid, 0);
476                 if (error != 0)
477                         return;
478
479                 cup.uaddr = child_clear_tid;
480                 cup.op = LINUX_FUTEX_WAKE;
481                 cup.val = 1;            /* wake one */
482                 cup.timeout = NULL;
483                 cup.uaddr2 = NULL;
484                 cup.val3 = 0;
485                 error = linux_sys_futex(td, &cup);
486                 /*
487                  * this cannot happen at the moment and if this happens it
488                  * probably means there is a user space bug
489                  */
490                 if (error != 0)
491                         linux_msg(td, "futex stuff in thread_detach failed.");
492         }
493 }