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