kernel: Remove some unused variables in the rest of the kernel tree.
[dragonfly.git] / sys / emulation / linux / i386 / linux_machdep.c
1 /*-
2  * Copyright (c) 2000 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer 
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
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  * $FreeBSD: src/sys/i386/linux/linux_machdep.c,v 1.6.2.4 2001/11/05 19:08:23 marcel Exp $
29  */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/imgact.h>
34 #include <sys/kern_syscall.h>
35 #include <sys/lock.h>
36 #include <sys/mman.h>
37 #include <sys/nlookup.h>
38 #include <sys/proc.h>
39 #include <sys/priv.h>
40 #include <sys/resource.h>
41 #include <sys/resourcevar.h>
42 #include <sys/ptrace.h>
43 #include <sys/sysproto.h>
44 #include <sys/thread2.h>
45 #include <sys/unistd.h>
46 #include <sys/wait.h>
47
48 #include <machine/frame.h>
49 #include <machine/psl.h>
50 #include <machine/segments.h>
51 #include <machine/sysarch.h>
52
53 #include <vm/vm.h>
54 #include <vm/pmap.h>
55 #include <vm/vm_map.h>
56
57 #include <sys/mplock2.h>
58
59 #include "linux.h"
60 #include "linux_proto.h"
61 #include "../linux_ipc.h"
62 #include "../linux_signal.h"
63 #include "../linux_util.h"
64 #include "../linux_emuldata.h"
65
66 struct l_descriptor {
67         l_uint          entry_number;
68         l_ulong         base_addr;
69         l_uint          limit;
70         l_uint          seg_32bit:1;
71         l_uint          contents:2;
72         l_uint          read_exec_only:1;
73         l_uint          limit_in_pages:1;
74         l_uint          seg_not_present:1;
75         l_uint          useable:1;
76 };
77
78 struct l_old_select_argv {
79         l_int           nfds;
80         l_fd_set        *readfds;
81         l_fd_set        *writefds;
82         l_fd_set        *exceptfds;
83         struct l_timeval        *timeout;
84 };
85
86 int
87 linux_to_bsd_sigaltstack(int lsa)
88 {
89         int bsa = 0;
90
91         if (lsa & LINUX_SS_DISABLE)
92                 bsa |= SS_DISABLE;
93         if (lsa & LINUX_SS_ONSTACK)
94                 bsa |= SS_ONSTACK;
95         return (bsa);
96 }
97
98 int
99 bsd_to_linux_sigaltstack(int bsa)
100 {
101         int lsa = 0;
102
103         if (bsa & SS_DISABLE)
104                 lsa |= LINUX_SS_DISABLE;
105         if (bsa & SS_ONSTACK)
106                 lsa |= LINUX_SS_ONSTACK;
107         return (lsa);
108 }
109
110 /*
111  * MPALMOSTSAFE
112  */
113 int
114 sys_linux_execve(struct linux_execve_args *args)
115 {
116         struct nlookupdata nd;
117         struct image_args exec_args;
118         char *path;
119         int error;
120
121         error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
122         if (error)
123                 return (error);
124 #ifdef DEBUG
125         if (ldebug(execve))
126                 kprintf(ARGS(execve, "%s"), path);
127 #endif
128         get_mplock();
129         error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
130         bzero(&exec_args, sizeof(exec_args));
131         if (error == 0) {
132                 error = exec_copyin_args(&exec_args, path, PATH_SYSSPACE,
133                                         args->argp, args->envp);
134         }
135         if (error == 0)
136                 error = kern_execve(&nd, &exec_args);
137         nlookup_done(&nd);
138
139         /*
140          * The syscall result is returned in registers to the new program.
141          * Linux will register %edx as an atexit function and we must be
142          * sure to set it to 0.  XXX
143          */
144         if (error == 0) {
145                 args->sysmsg_result64 = 0;
146                 if (curproc->p_sysent == &elf_linux_sysvec)
147                         error = emuldata_init(curproc, NULL, 0);
148         }
149
150         exec_free_args(&exec_args);
151         linux_free_path(&path);
152
153         if (error < 0) {
154                 /* We hit a lethal error condition.  Let's die now. */
155                 exit1(W_EXITCODE(0, SIGABRT));
156                 /* NOTREACHED */
157         }
158         rel_mplock();
159
160         return(error);
161 }
162
163 struct l_ipc_kludge {
164         struct l_msgbuf *msgp;
165         l_long msgtyp;
166 };
167
168 /*
169  * MPALMOSTSAFE
170  */
171 int
172 sys_linux_ipc(struct linux_ipc_args *args)
173 {
174         int error = 0;
175
176         get_mplock();
177
178         switch (args->what & 0xFFFF) {
179         case LINUX_SEMOP: {
180                 struct linux_semop_args a;
181
182                 a.semid = args->arg1;
183                 a.tsops = args->ptr;
184                 a.nsops = args->arg2;
185                 a.sysmsg_lresult = 0;
186                 error = linux_semop(&a);
187                 args->sysmsg_lresult = a.sysmsg_lresult;
188                 break;
189         }
190         case LINUX_SEMGET: {
191                 struct linux_semget_args a;
192
193                 a.key = args->arg1;
194                 a.nsems = args->arg2;
195                 a.semflg = args->arg3;
196                 a.sysmsg_lresult = 0;
197                 error = linux_semget(&a);
198                 args->sysmsg_lresult = a.sysmsg_lresult;
199                 break;
200         }
201         case LINUX_SEMCTL: {
202                 struct linux_semctl_args a;
203                 int error;
204
205                 a.semid = args->arg1;
206                 a.semnum = args->arg2;
207                 a.cmd = args->arg3;
208                 a.sysmsg_lresult = 0;
209                 error = copyin((caddr_t)args->ptr, &a.arg, sizeof(a.arg));
210                 if (error)
211                         break;
212                 error = linux_semctl(&a);
213                 args->sysmsg_lresult = a.sysmsg_lresult;
214                 break;
215         }
216         case LINUX_MSGSND: {
217                 struct linux_msgsnd_args a;
218
219                 a.msqid = args->arg1;
220                 a.msgp = args->ptr;
221                 a.msgsz = args->arg2;
222                 a.msgflg = args->arg3;
223                 a.sysmsg_lresult = 0;
224                 error = linux_msgsnd(&a);
225                 args->sysmsg_lresult = a.sysmsg_lresult;
226                 break;
227         }
228         case LINUX_MSGRCV: {
229                 struct linux_msgrcv_args a;
230
231                 a.msqid = args->arg1;
232                 a.msgsz = args->arg2;
233                 if (a.msgsz < 0) {
234                         error = EINVAL;
235                         break;
236                 }
237                 a.msgflg = args->arg3;
238                 a.sysmsg_lresult = 0;
239                 if ((args->what >> 16) == 0) {
240                         struct l_ipc_kludge tmp;
241                         int error;
242
243                         if (args->ptr == NULL) {
244                                 error = EINVAL;
245                                 break;
246                         }
247                         error = copyin((caddr_t)args->ptr, &tmp, sizeof(tmp));
248                         if (error)
249                                 break;
250                         a.msgp = tmp.msgp;
251                         a.msgtyp = tmp.msgtyp;
252                 } else {
253                         a.msgp = args->ptr;
254                         a.msgtyp = args->arg5;
255                 }
256                 error = linux_msgrcv(&a);
257                 args->sysmsg_lresult = a.sysmsg_lresult;
258                 break;
259         }
260         case LINUX_MSGGET: {
261                 struct linux_msgget_args a;
262
263                 a.key = args->arg1;
264                 a.msgflg = args->arg2;
265                 a.sysmsg_lresult = 0;
266                 error = linux_msgget(&a);
267                 args->sysmsg_lresult = a.sysmsg_lresult;
268                 break;
269         }
270         case LINUX_MSGCTL: {
271                 struct linux_msgctl_args a;
272
273                 a.msqid = args->arg1;
274                 a.cmd = args->arg2;
275                 a.buf = args->ptr;
276                 a.sysmsg_lresult = 0;
277                 error = linux_msgctl(&a);
278                 args->sysmsg_lresult = a.sysmsg_lresult;
279                 break;
280         }
281         case LINUX_SHMAT: {
282                 struct linux_shmat_args a;
283
284                 a.shmid = args->arg1;
285                 a.shmaddr = args->ptr;
286                 a.shmflg = args->arg2;
287                 a.raddr = (l_ulong *)args->arg3;
288                 a.sysmsg_lresult = 0;
289                 error = linux_shmat(&a);
290                 args->sysmsg_lresult = a.sysmsg_lresult;
291                 break;
292         }
293         case LINUX_SHMDT: {
294                 struct linux_shmdt_args a;
295
296                 a.shmaddr = args->ptr;
297                 a.sysmsg_lresult = 0;
298                 error = linux_shmdt(&a);
299                 args->sysmsg_lresult = a.sysmsg_lresult;
300                 break;
301         }
302         case LINUX_SHMGET: {
303                 struct linux_shmget_args a;
304
305                 a.key = args->arg1;
306                 a.size = args->arg2;
307                 a.shmflg = args->arg3;
308                 a.sysmsg_lresult = 0;
309                 error = linux_shmget(&a);
310                 args->sysmsg_lresult = a.sysmsg_lresult;
311                 break;
312         }
313         case LINUX_SHMCTL: {
314                 struct linux_shmctl_args a;
315
316                 a.shmid = args->arg1;
317                 a.cmd = args->arg2;
318                 a.buf = args->ptr;
319                 a.sysmsg_lresult = 0;
320                 error = linux_shmctl(&a);
321                 args->sysmsg_lresult = a.sysmsg_lresult;
322                 break;
323         }
324         default:
325                 error = EINVAL;
326                 break;
327         }
328         rel_mplock();
329         return(error);
330 }
331
332 /*
333  * MPSAFE
334  */
335 int
336 sys_linux_old_select(struct linux_old_select_args *args)
337 {
338         struct l_old_select_argv linux_args;
339         struct linux_select_args newsel;
340         int error;
341
342 #ifdef DEBUG
343         if (ldebug(old_select))
344                 kprintf(ARGS(old_select, "%p"), args->ptr);
345 #endif
346
347         error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args));
348         if (error)
349                 return (error);
350
351         newsel.sysmsg_iresult = 0;
352         newsel.nfds = linux_args.nfds;
353         newsel.readfds = linux_args.readfds;
354         newsel.writefds = linux_args.writefds;
355         newsel.exceptfds = linux_args.exceptfds;
356         newsel.timeout = linux_args.timeout;
357         error = sys_linux_select(&newsel);
358         args->sysmsg_iresult = newsel.sysmsg_iresult;
359         return(error);
360 }
361
362 /*
363  * MPSAFE
364  */
365 int
366 sys_linux_fork(struct linux_fork_args *args)
367 {
368         struct lwp *lp = curthread->td_lwp;
369         struct proc *p2;
370         int error;
371
372         get_mplock();
373         error = fork1(lp, RFFDG | RFPROC | RFPGLOCK, &p2);
374         if (error == 0) {
375                 emuldata_init(curproc, p2, 0);
376
377                 start_forked_proc(lp, p2);
378                 args->sysmsg_fds[0] = p2->p_pid;
379                 args->sysmsg_fds[1] = 0;
380         }
381         rel_mplock();
382
383         /* Are we the child? */
384         if (args->sysmsg_iresult == 1)
385                 args->sysmsg_iresult = 0;
386
387         return (error);
388 }
389
390 /*
391  * MPALMOSTSAFE
392  */
393 int
394 sys_linux_exit_group(struct linux_exit_group_args *args)
395 {
396         struct linux_emuldata *em, *e;
397         int rval;
398
399         rval = args->rval;
400         EMUL_LOCK();
401
402         em = emuldata_get(curproc);
403
404         if (em->s->refs == 1) {
405                 EMUL_UNLOCK();
406                 exit1(W_EXITCODE(rval, 0));
407                 /* NOTREACHED */
408                 return (0);
409         }
410         KKASSERT(em->proc == curproc);
411         em->flags |= EMUL_DIDKILL;
412         em->s->flags |= LINUX_LES_INEXITGROUP;
413         em->s->xstat = W_EXITCODE(rval, 0);
414
415         LIST_REMOVE(em, threads);
416         LIST_INSERT_HEAD(&em->s->threads, em, threads);
417
418         while ((e = LIST_NEXT(em, threads)) != NULL) {
419                 LIST_REMOVE(em, threads);
420                 LIST_INSERT_AFTER(e, em, threads);
421                 if ((e->flags & EMUL_DIDKILL) == 0) {
422                         e->flags |= EMUL_DIDKILL;
423                         lwkt_gettoken(&proc_token);
424                         KKASSERT(pfindn(e->proc->p_pid) == e->proc);
425                         ksignal(e->proc, SIGKILL);
426                         lwkt_reltoken(&proc_token);
427                 }
428         }
429
430         EMUL_UNLOCK();
431         exit1(W_EXITCODE(rval, 0));
432         /* NOTREACHED */
433
434         return (0);
435 }
436
437 /*
438  * MPSAFE
439  */
440 int
441 sys_linux_vfork(struct linux_vfork_args *args)
442 {
443         struct lwp *lp = curthread->td_lwp;
444         struct proc *p2;
445         int error;
446
447         get_mplock();
448         error = fork1(lp, RFFDG | RFPROC | RFPPWAIT | RFMEM | RFPGLOCK, &p2);
449         if (error == 0) {
450                 emuldata_init(curproc, p2, 0);
451
452                 start_forked_proc(lp, p2);
453                 args->sysmsg_fds[0] = p2->p_pid;
454                 args->sysmsg_fds[1] = 0;
455         }
456         rel_mplock();
457
458         if (args->sysmsg_iresult == 1)
459                 args->sysmsg_iresult = 0;
460
461         return (error);
462 }
463
464 /*
465  * MPALMOSTSAFE
466  */
467 int
468 sys_linux_clone(struct linux_clone_args *args)
469 {
470         struct segment_descriptor *desc;
471         struct l_user_desc info;
472         int idx;
473         int a[2];
474
475         struct lwp *lp = curthread->td_lwp;
476         int error, ff = RFPROC;
477         struct proc *p2 = NULL;
478         int exit_signal;
479
480         exit_signal = args->flags & 0x000000ff;
481         if (exit_signal >= LINUX_NSIG)
482                 return (EINVAL);
483         if (exit_signal <= LINUX_SIGTBLSZ)
484                 exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)];
485
486         if (args->flags & LINUX_CLONE_VM)
487                 ff |= RFMEM;
488         if (args->flags & LINUX_CLONE_SIGHAND)
489                 ff |= RFSIGSHARE;
490         if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS)))
491                 ff |= RFFDG;
492         if ((args->flags & 0xffffff00) == LINUX_THREADING_FLAGS)
493                 ff |= RFTHREAD;
494         if (args->flags & LINUX_CLONE_VFORK)
495                 ff |= RFPPWAIT;
496         if (args->flags & LINUX_CLONE_PARENT_SETTID) {
497                 if (args->parent_tidptr == NULL)
498                         return (EINVAL);
499         }
500
501         error = 0;
502
503         get_mplock();
504         error = fork1(lp, ff | RFPGLOCK, &p2);
505         if (error) {
506                 rel_mplock();
507                 return error;
508         }
509
510         args->sysmsg_fds[0] = p2 ? p2->p_pid : 0;
511         args->sysmsg_fds[1] = 0;
512         
513         if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) {
514                 lwkt_gettoken(&curproc->p_token);
515                 while (p2->p_pptr != curproc->p_pptr)
516                         proc_reparent(p2, curproc->p_pptr);
517                 lwkt_reltoken(&curproc->p_token);
518         }
519
520         emuldata_init(curproc, p2, args->flags);
521         linux_proc_fork(p2, curproc, args->child_tidptr);
522         /*
523          * XXX: this can't happen, p2 is never NULL, or else we'd have
524          *      other problems, too (see p2->p_sigparent == ...,
525          *      linux_proc_fork and emuldata_init.
526          */
527         if (p2 == NULL) {
528                 error = ESRCH;
529         } else {
530                 if (args->flags & LINUX_CLONE_PARENT_SETTID) {
531                         error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid));
532                 }
533         }
534
535         p2->p_sigparent = exit_signal;
536         if (args->stack) {
537                 ONLY_LWP_IN_PROC(p2)->lwp_md.md_regs->tf_esp =
538                                         (unsigned long)args->stack;
539         }
540
541         if (args->flags & LINUX_CLONE_SETTLS) {
542                 error = copyin((void *)curthread->td_lwp->lwp_md.md_regs->tf_esi, &info, sizeof(struct l_user_desc));
543                 if (error) {
544                         kprintf("copyin of tf_esi to info failed\n");
545                 } else {
546                         idx = info.entry_number;
547                         /*
548                          * We understand both our own entries such as the ones
549                          * we provide on linux_set_thread_area, as well as the
550                          * linux-type entries 6-8.
551                          */
552                         if ((idx < 6 || idx > 8) && (idx < GTLS_START)) {
553                                 kprintf("LINUX_CLONE_SETTLS, invalid idx requested: %d\n", idx);
554                                 goto out;
555                         }
556                         if (idx < GTLS_START) {
557                                 idx -= 6;
558                         } else {
559 #if 0 /* was SMP */
560                                 idx -= (GTLS_START + mycpu->gd_cpuid * NGDT);
561 #endif
562                                 idx -= GTLS_START;
563                         }
564                         KKASSERT(idx >= 0);
565
566                         a[0] = LINUX_LDT_entry_a(&info);
567                         a[1] = LINUX_LDT_entry_b(&info);
568                         if (p2) {
569                                 desc = &FIRST_LWP_IN_PROC(p2)->lwp_thread->td_tls.tls[idx];
570                                 memcpy(desc, &a, sizeof(a));
571                         } else {
572                                 kprintf("linux_clone... we don't have a p2\n");
573                         }
574                 }
575         }
576 out:
577         if (p2)
578                 start_forked_proc(lp, p2);
579
580         rel_mplock();
581 #ifdef DEBUG
582         if (ldebug(clone))
583                 kprintf(LMSG("clone: successful rfork to %ld"),
584                     (long)p2->p_pid);
585 #endif
586
587         return (error);
588 }
589
590 /* XXX move */
591 struct l_mmap_argv {
592         l_caddr_t       addr;
593         l_int           len;
594         l_int           prot;
595         l_int           flags;
596         l_int           fd;
597         l_int           pos;
598 };
599
600 #define STACK_SIZE  (2 * 1024 * 1024)
601 #define GUARD_SIZE  (4 * PAGE_SIZE)
602
603 /*
604  * MPALMOSTSAFE
605  */
606 static int
607 linux_mmap_common(caddr_t linux_addr, size_t linux_len, int linux_prot,
608                   int linux_flags, int linux_fd, off_t pos, void **res)
609 {
610         struct thread *td = curthread;
611         struct proc *p = td->td_proc;
612         caddr_t addr;
613         void *new;
614         int error, flags, len, prot, fd;
615
616         flags = 0;
617         if (linux_flags & LINUX_MAP_SHARED)
618                 flags |= MAP_SHARED;
619         if (linux_flags & LINUX_MAP_PRIVATE)
620                 flags |= MAP_PRIVATE;
621         if (linux_flags & LINUX_MAP_FIXED)
622                 flags |= MAP_FIXED;
623         if (linux_flags & LINUX_MAP_ANON) {
624                 flags |= MAP_ANON;
625         } else {
626                 flags |= MAP_NOSYNC;
627         }
628
629         lwkt_gettoken(&curproc->p_vmspace->vm_map.token);
630
631         if (linux_flags & LINUX_MAP_GROWSDOWN) {
632                 flags |= MAP_STACK;
633                 /* The linux MAP_GROWSDOWN option does not limit auto
634                  * growth of the region.  Linux mmap with this option
635                  * takes as addr the inital BOS, and as len, the initial
636                  * region size.  It can then grow down from addr without
637                  * limit.  However, linux threads has an implicit internal
638                  * limit to stack size of STACK_SIZE.  Its just not
639                  * enforced explicitly in linux.  But, here we impose
640                  * a limit of (STACK_SIZE - GUARD_SIZE) on the stack
641                  * region, since we can do this with our mmap.
642                  *
643                  * Our mmap with MAP_STACK takes addr as the maximum
644                  * downsize limit on BOS, and as len the max size of
645                  * the region.  It them maps the top SGROWSIZ bytes,
646                  * and autgrows the region down, up to the limit
647                  * in addr.
648                  *
649                  * If we don't use the MAP_STACK option, the effect
650                  * of this code is to allocate a stack region of a
651                  * fixed size of (STACK_SIZE - GUARD_SIZE).
652                  */
653
654                 /* This gives us TOS */
655                 addr = linux_addr + linux_len;
656
657                 if (addr > p->p_vmspace->vm_maxsaddr) {
658                         /* Some linux apps will attempt to mmap
659                          * thread stacks near the top of their
660                          * address space.  If their TOS is greater
661                          * than vm_maxsaddr, vm_map_growstack()
662                          * will confuse the thread stack with the
663                          * process stack and deliver a SEGV if they
664                          * attempt to grow the thread stack past their
665                          * current stacksize rlimit.  To avoid this,
666                          * adjust vm_maxsaddr upwards to reflect
667                          * the current stacksize rlimit rather
668                          * than the maximum possible stacksize.
669                          * It would be better to adjust the
670                          * mmap'ed region, but some apps do not check
671                          * mmap's return value.
672                          */
673                         p->p_vmspace->vm_maxsaddr = (char *)USRSTACK -
674                             p->p_rlimit[RLIMIT_STACK].rlim_cur;
675                 }
676
677                 /* This gives us our maximum stack size */
678                 if (linux_len > STACK_SIZE - GUARD_SIZE) {
679                         len = linux_len;
680                 } else {
681                         len = STACK_SIZE - GUARD_SIZE;
682                 }
683                 /* This gives us a new BOS.  If we're using VM_STACK, then
684                  * mmap will just map the top SGROWSIZ bytes, and let
685                  * the stack grow down to the limit at BOS.  If we're
686                  * not using VM_STACK we map the full stack, since we
687                  * don't have a way to autogrow it.
688                  */
689                 addr -= len;
690         } else {
691                 addr = linux_addr;
692                 len = linux_len;
693         }
694
695         prot = linux_prot;
696
697         if (prot & (PROT_READ | PROT_WRITE | PROT_EXEC))
698                 prot |= PROT_READ | PROT_EXEC;
699
700         if (linux_flags & LINUX_MAP_ANON) {
701                 fd = -1;
702         } else {
703                 fd = linux_fd;
704         }
705         
706 #ifdef DEBUG
707         if (ldebug(mmap) || ldebug(mmap2))
708                 kprintf("-> (%p, %d, %d, 0x%08x, %d, %lld)\n",
709                     addr, len, prot, flags, fd, pos);
710 #endif
711         error = kern_mmap(curproc->p_vmspace, addr, len,
712                           prot, flags, fd, pos, &new);
713
714         lwkt_reltoken(&curproc->p_vmspace->vm_map.token);
715
716         if (error == 0)
717                 *res = new;
718         return (error);
719 }
720
721 /*
722  * MPSAFE
723  */
724 int
725 sys_linux_mmap(struct linux_mmap_args *args)
726 {
727         struct l_mmap_argv linux_args;
728         int error;
729
730         error = copyin((caddr_t)args->ptr, &linux_args, sizeof(linux_args));
731         if (error)
732                 return (error);
733
734 #ifdef DEBUG
735         if (ldebug(mmap))
736                 kprintf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"),
737                     (void *)linux_args.addr, linux_args.len, linux_args.prot,
738                     linux_args.flags, linux_args.fd, linux_args.pos);
739 #endif
740         error = linux_mmap_common(linux_args.addr, linux_args.len,
741             linux_args.prot, linux_args.flags, linux_args.fd,
742             linux_args.pos, &args->sysmsg_resultp);
743 #ifdef DEBUG
744         if (ldebug(mmap))
745                 kprintf("-> %p\n", args->sysmsg_resultp);
746 #endif
747         return(error);
748 }
749
750 /*
751  * MPSAFE
752  */
753 int
754 sys_linux_mmap2(struct linux_mmap2_args *args)
755 {
756         int error;
757
758 #ifdef DEBUG
759         if (ldebug(mmap2))
760                 kprintf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"),
761                     (void *)args->addr, args->len, args->prot, args->flags,
762                     args->fd, args->pgoff);
763 #endif
764         error = linux_mmap_common((void *)args->addr, args->len, args->prot,
765             args->flags, args->fd, args->pgoff * PAGE_SIZE,
766             &args->sysmsg_resultp);
767 #ifdef DEBUG
768         if (ldebug(mmap2))
769                 kprintf("-> %p\n", args->sysmsg_resultp);
770 #endif
771         return (error);
772 }
773
774 /*
775  * MPSAFE
776  */
777 int
778 sys_linux_pipe(struct linux_pipe_args *args)
779 {
780         int error;
781         int reg_edx;
782         struct pipe_args bsd_args;
783
784 #ifdef DEBUG
785         if (ldebug(pipe))
786                 kprintf(ARGS(pipe, "*"));
787 #endif
788
789         reg_edx = args->sysmsg_fds[1];
790         error = sys_pipe(&bsd_args);
791         if (error) {
792                 args->sysmsg_fds[1] = reg_edx;
793                 return (error);
794         }
795
796         error = copyout(bsd_args.sysmsg_fds, args->pipefds, 2*sizeof(int));
797         if (error) {
798                 args->sysmsg_fds[1] = reg_edx;
799                 return (error);
800         }
801
802         args->sysmsg_fds[1] = reg_edx;
803         args->sysmsg_fds[0] = 0;
804         return (0);
805 }
806
807 /*
808  * XXX: Preliminary
809  */
810 int
811 sys_linux_pipe2(struct linux_pipe2_args *args)
812 {
813         struct thread *td = curthread;
814         int error;
815         int reg_edx;
816         struct pipe_args bsd_args;
817         union fcntl_dat dat;
818
819         reg_edx = args->sysmsg_fds[1];
820         error = sys_pipe(&bsd_args);
821         if (error) {
822                 args->sysmsg_fds[1] = reg_edx;
823                 return (error);
824         }
825
826 //      if (args->flags & LINUX_O_CLOEXEC) {
827 //      }
828
829         if (args->flags & LINUX_O_NONBLOCK) {
830                 dat.fc_flags = O_NONBLOCK;
831                 kern_fcntl(bsd_args.sysmsg_fds[0], F_SETFL, &dat, td->td_ucred);
832                 kern_fcntl(bsd_args.sysmsg_fds[1], F_SETFL, &dat, td->td_ucred);
833         }
834
835         error = copyout(bsd_args.sysmsg_fds, args->pipefds, 2*sizeof(int));
836         if (error) {
837                 args->sysmsg_fds[1] = reg_edx;
838                 return (error);
839         }
840
841         args->sysmsg_fds[1] = reg_edx;
842         args->sysmsg_fds[0] = 0;
843         return (0);
844 }
845
846 /*
847  * MPSAFE
848  */
849 int
850 sys_linux_ioperm(struct linux_ioperm_args *args)
851 {
852         struct sysarch_args sa;
853         struct i386_ioperm_args *iia;
854         caddr_t sg;
855         int error;
856
857         sg = stackgap_init();
858         iia = stackgap_alloc(&sg, sizeof(struct i386_ioperm_args));
859         iia->start = args->start;
860         iia->length = args->length;
861         iia->enable = args->enable;
862         sa.sysmsg_resultp = NULL;
863         sa.op = I386_SET_IOPERM;
864         sa.parms = (char *)iia;
865         error = sys_sysarch(&sa);
866         args->sysmsg_resultp = sa.sysmsg_resultp;
867         return(error);
868 }
869
870 /*
871  * MPSAFE
872  */
873 int
874 sys_linux_iopl(struct linux_iopl_args *args)
875 {
876         struct thread *td = curthread;
877         struct lwp *lp = td->td_lwp;
878         int error;
879
880         if (args->level < 0 || args->level > 3)
881                 return (EINVAL);
882         if ((error = priv_check(td, PRIV_ROOT)) != 0)
883                 return (error);
884         if (securelevel > 0)
885                 return (EPERM);
886         lp->lwp_md.md_regs->tf_eflags =
887             (lp->lwp_md.md_regs->tf_eflags & ~PSL_IOPL) |
888             (args->level * (PSL_IOPL / 3));
889         return (0);
890 }
891
892 /*
893  * MPSAFE
894  */
895 int
896 sys_linux_modify_ldt(struct linux_modify_ldt_args *uap)
897 {
898         int error;
899         caddr_t sg;
900         struct sysarch_args args;
901         struct i386_ldt_args *ldt;
902         struct l_descriptor ld;
903         union descriptor *desc;
904         int size, written;
905
906         sg = stackgap_init();
907
908         if (uap->ptr == NULL)
909                 return (EINVAL);
910
911         switch (uap->func) {
912         case 0x00: /* read_ldt */
913                 ldt = stackgap_alloc(&sg, sizeof(*ldt));
914                 ldt->start = 0;
915                 ldt->descs = uap->ptr;
916                 ldt->num = uap->bytecount / sizeof(union descriptor);
917                 args.op = I386_GET_LDT;
918                 args.parms = (char*)ldt;
919                 args.sysmsg_iresult = 0;
920                 error = sys_sysarch(&args);
921                 uap->sysmsg_iresult = args.sysmsg_iresult *
922                                       sizeof(union descriptor);
923                 break;
924         case 0x02: /* read_default_ldt = 0 */
925                 size = 5*sizeof(struct l_desc_struct);
926                 if (size > uap->bytecount)
927                         size = uap->bytecount;
928                 for (written = error = 0; written < size && error == 0; written++)
929                         error = subyte((char *)uap->ptr + written, 0);
930                 uap->sysmsg_iresult = written;
931                 break;
932         case 0x01: /* write_ldt */
933         case 0x11: /* write_ldt */
934                 if (uap->bytecount != sizeof(ld))
935                         return (EINVAL);
936
937                 error = copyin(uap->ptr, &ld, sizeof(ld));
938                 if (error)
939                         return (error);
940
941                 ldt = stackgap_alloc(&sg, sizeof(*ldt));
942                 desc = stackgap_alloc(&sg, sizeof(*desc));
943                 ldt->start = ld.entry_number;
944                 ldt->descs = desc;
945                 ldt->num = 1;
946                 desc->sd.sd_lolimit = (ld.limit & 0x0000ffff);
947                 desc->sd.sd_hilimit = (ld.limit & 0x000f0000) >> 16;
948                 desc->sd.sd_lobase = (ld.base_addr & 0x00ffffff);
949                 desc->sd.sd_hibase = (ld.base_addr & 0xff000000) >> 24;
950                 desc->sd.sd_type = SDT_MEMRO | ((ld.read_exec_only ^ 1) << 1) |
951                         (ld.contents << 2);
952                 desc->sd.sd_dpl = 3;
953                 desc->sd.sd_p = (ld.seg_not_present ^ 1);
954                 desc->sd.sd_xx = 0;
955                 desc->sd.sd_def32 = ld.seg_32bit;
956                 desc->sd.sd_gran = ld.limit_in_pages;
957                 args.op = I386_SET_LDT;
958                 args.parms = (char*)ldt;
959                 args.sysmsg_iresult = 0;
960                 error = sys_sysarch(&args);
961                 uap->sysmsg_iresult = args.sysmsg_iresult;
962                 break;
963         default:
964                 error = EINVAL;
965                 break;
966         }
967
968         return (error);
969 }
970
971 /*
972  * MPALMOSTSAFE
973  */
974 int
975 sys_linux_sigaction(struct linux_sigaction_args *args)
976 {
977         l_osigaction_t osa;
978         l_sigaction_t linux_act, linux_oact;
979         struct sigaction act, oact;
980         int error, sig;
981
982 #ifdef DEBUG
983         if (ldebug(sigaction))
984                 kprintf(ARGS(sigaction, "%d, %p, %p"),
985                     args->sig, (void *)args->nsa, (void *)args->osa);
986 #endif
987
988         if (args->nsa) {
989                 error = copyin(args->nsa, &osa, sizeof(l_osigaction_t));
990                 if (error)
991                         return (error);
992                 linux_act.lsa_handler = osa.lsa_handler;
993                 linux_act.lsa_flags = osa.lsa_flags;
994                 linux_act.lsa_restorer = osa.lsa_restorer;
995                 LINUX_SIGEMPTYSET(linux_act.lsa_mask);
996                 linux_act.lsa_mask.__bits[0] = osa.lsa_mask;
997                 linux_to_bsd_sigaction(&linux_act, &act);
998         }
999
1000         if (args->sig <= LINUX_SIGTBLSZ)
1001                 sig = linux_to_bsd_signal[_SIG_IDX(args->sig)];
1002         else
1003                 sig = args->sig;
1004
1005         get_mplock();
1006         error = kern_sigaction(sig, args->nsa ? &act : NULL,
1007                                args->osa ? &oact : NULL);
1008         rel_mplock();
1009
1010         if (args->osa != NULL && !error) {
1011                 bsd_to_linux_sigaction(&oact, &linux_oact);
1012                 osa.lsa_handler = linux_oact.lsa_handler;
1013                 osa.lsa_flags = linux_oact.lsa_flags;
1014                 osa.lsa_restorer = linux_oact.lsa_restorer;
1015                 osa.lsa_mask = linux_oact.lsa_mask.__bits[0];
1016                 error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
1017         }
1018         return (error);
1019 }
1020
1021 /*
1022  * Linux has two extra args, restart and oldmask.  We dont use these,
1023  * but it seems that "restart" is actually a context pointer that
1024  * enables the signal to happen with a different register set.
1025  *
1026  * MPALMOSTSAFE
1027  */
1028 int
1029 sys_linux_sigsuspend(struct linux_sigsuspend_args *args)
1030 {
1031         l_sigset_t linux_mask;
1032         sigset_t mask;
1033         int error;
1034
1035 #ifdef DEBUG
1036         if (ldebug(sigsuspend))
1037                 kprintf(ARGS(sigsuspend, "%08lx"), (unsigned long)args->mask);
1038 #endif
1039
1040         LINUX_SIGEMPTYSET(mask);
1041         mask.__bits[0] = args->mask;
1042         linux_to_bsd_sigset(&linux_mask, &mask);
1043
1044         get_mplock();
1045         error = kern_sigsuspend(&mask);
1046         rel_mplock();
1047
1048         return(error);
1049 }
1050
1051 /*
1052  * MPALMOSTSAFE
1053  */
1054 int
1055 sys_linux_rt_sigsuspend(struct linux_rt_sigsuspend_args *uap)
1056 {
1057         l_sigset_t linux_mask;
1058         sigset_t mask;
1059         int error;
1060
1061 #ifdef DEBUG
1062         if (ldebug(rt_sigsuspend))
1063                 kprintf(ARGS(rt_sigsuspend, "%p, %d"),
1064                     (void *)uap->newset, uap->sigsetsize);
1065 #endif
1066
1067         if (uap->sigsetsize != sizeof(l_sigset_t))
1068                 return (EINVAL);
1069
1070         error = copyin(uap->newset, &linux_mask, sizeof(l_sigset_t));
1071         if (error)
1072                 return (error);
1073
1074         linux_to_bsd_sigset(&linux_mask, &mask);
1075
1076         get_mplock();
1077         error = kern_sigsuspend(&mask);
1078         rel_mplock();
1079
1080         return(error);
1081 }
1082
1083 /*
1084  * MPALMOSTSAFE
1085  */
1086 int
1087 sys_linux_pause(struct linux_pause_args *args)
1088 {
1089         struct thread *td = curthread;
1090         struct lwp *lp = td->td_lwp;
1091         sigset_t mask;
1092         int error;
1093
1094 #ifdef DEBUG
1095         if (ldebug(pause))
1096                 kprintf(ARGS(pause, ""));
1097 #endif
1098
1099         mask = lp->lwp_sigmask;
1100
1101         get_mplock();
1102         error = kern_sigsuspend(&mask);
1103         rel_mplock();
1104
1105         return(error);
1106 }
1107
1108 /*
1109  * MPALMOSTSAFE
1110  */
1111 int
1112 sys_linux_sigaltstack(struct linux_sigaltstack_args *uap)
1113 {
1114         stack_t ss, oss;
1115         l_stack_t linux_ss;
1116         int error;
1117
1118 #ifdef DEBUG
1119         if (ldebug(sigaltstack))
1120                 kprintf(ARGS(sigaltstack, "%p, %p"), uap->uss, uap->uoss);
1121 #endif
1122
1123         if (uap->uss) {
1124                 error = copyin(uap->uss, &linux_ss, sizeof(l_stack_t));
1125                 if (error)
1126                         return (error);
1127
1128                 ss.ss_sp = linux_ss.ss_sp;
1129                 ss.ss_size = linux_ss.ss_size;
1130                 ss.ss_flags = linux_to_bsd_sigaltstack(linux_ss.ss_flags);
1131         }
1132
1133         get_mplock();
1134         error = kern_sigaltstack(uap->uss ? &ss : NULL,
1135                                  uap->uoss ? &oss : NULL);
1136         rel_mplock();
1137
1138         if (error == 0 && uap->uoss) {
1139                 linux_ss.ss_sp = oss.ss_sp;
1140                 linux_ss.ss_size = oss.ss_size;
1141                 linux_ss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags);
1142                 error = copyout(&linux_ss, uap->uoss, sizeof(l_stack_t));
1143         }
1144
1145         return (error);
1146 }
1147
1148 int
1149 sys_linux_set_thread_area(struct linux_set_thread_area_args *args)
1150 {
1151         struct segment_descriptor *desc;
1152         struct l_user_desc info;
1153         int error;
1154         int idx;
1155         int a[2];
1156         int i;
1157
1158         error = copyin(args->desc, &info, sizeof(struct l_user_desc));
1159         if (error)
1160                 return (EFAULT);
1161
1162 #ifdef DEBUG
1163         if (ldebug(set_thread_area))
1164                 kprintf(ARGS(set_thread_area, "%i, %x, %x, %i, %i, %i, %i, %i, %i\n"),
1165                       info.entry_number,
1166                       info.base_addr,
1167                       info.limit,
1168                       info.seg_32bit,
1169                       info.contents,
1170                       info.read_exec_only,
1171                       info.limit_in_pages,
1172                       info.seg_not_present,
1173                       info.useable);
1174 #endif
1175
1176         idx = info.entry_number;
1177         if (idx != -1 && (idx < 6 || idx > 8))
1178                 return (EINVAL);
1179
1180         if (idx == -1) {
1181                 /* -1 means finding the first free TLS entry */
1182                 for (i = 0; i < NGTLS; i++) {
1183                         /*
1184                          * try to determine if the TLS entry is empty by looking
1185                          * at the lolimit entry.
1186                          */
1187                         if (curthread->td_tls.tls[idx].sd_lolimit == 0) {
1188                                 idx = i;
1189                                 break;
1190                         }
1191                 }
1192
1193                 if (idx == -1) {
1194                         /*
1195                          * By now we should have an index. If not, it means
1196                          * that no entry is free, so return ESRCH.
1197                          */
1198                         return (ESRCH);
1199                 }
1200         } else {
1201                 /* translate the index from Linux to ours */
1202                 idx -= 6;
1203                 KKASSERT(idx >= 0);
1204         }
1205
1206         /* Tell the caller about the allocated entry number */
1207 #if 0 /* was SMP */
1208         info.entry_number = GTLS_START + mycpu->gd_cpuid * NGDT + idx;
1209 #endif
1210         info.entry_number = GTLS_START + idx;
1211
1212
1213         error = copyout(&info, args->desc, sizeof(struct l_user_desc));
1214         if (error)
1215                 return (error);
1216
1217         if (LINUX_LDT_empty(&info)) {
1218                 a[0] = 0;
1219                 a[1] = 0;
1220         } else {
1221                 a[0] = LINUX_LDT_entry_a(&info);
1222                 a[1] = LINUX_LDT_entry_b(&info);
1223         }
1224
1225         /*
1226          * Update the TLS and the TLS entries in the GDT, but hold a critical
1227          * section as required by set_user_TLS().
1228          */
1229         crit_enter();
1230         desc = &curthread->td_tls.tls[idx];
1231         memcpy(desc, &a, sizeof(a));
1232         set_user_TLS();
1233         crit_exit();
1234
1235         return (0);
1236 }
1237
1238 int
1239 sys_linux_get_thread_area(struct linux_get_thread_area_args *args)
1240 {
1241         struct segment_descriptor *sd;
1242         struct l_desc_struct desc;
1243         struct l_user_desc info;
1244         int error;
1245         int idx;
1246
1247 #ifdef DEBUG
1248         if (ldebug(get_thread_area))
1249                 kprintf(ARGS(get_thread_area, "%p"), args->desc);
1250 #endif
1251
1252         error = copyin(args->desc, &info, sizeof(struct l_user_desc));
1253         if (error)
1254                 return (EFAULT);
1255                 
1256         idx = info.entry_number;
1257         if ((idx < 6 || idx > 8) && (idx < GTLS_START)) {
1258                 kprintf("sys_linux_get_thread_area, invalid idx requested: %d\n", idx);
1259                 return (EINVAL);
1260         }
1261
1262         memset(&info, 0, sizeof(info));
1263
1264         /* translate the index from Linux to ours */
1265         info.entry_number = idx;
1266         if (idx < GTLS_START) {
1267                 idx -= 6;
1268         } else {
1269 #if 0 /* was SMP */
1270                 idx -= (GTLS_START + mycpu->gd_cpuid * NGDT);
1271 #endif
1272                 idx -= GTLS_START;
1273
1274         }
1275         KKASSERT(idx >= 0);
1276
1277         sd = &curthread->td_tls.tls[idx];
1278         memcpy(&desc, sd, sizeof(desc));
1279         info.base_addr = LINUX_GET_BASE(&desc);
1280         info.limit = LINUX_GET_LIMIT(&desc);
1281         info.seg_32bit = LINUX_GET_32BIT(&desc);
1282         info.contents = LINUX_GET_CONTENTS(&desc);
1283         info.read_exec_only = !LINUX_GET_WRITABLE(&desc);
1284         info.limit_in_pages = LINUX_GET_LIMIT_PAGES(&desc);
1285         info.seg_not_present = !LINUX_GET_PRESENT(&desc);
1286         info.useable = LINUX_GET_USEABLE(&desc);
1287
1288         error = copyout(&info, args->desc, sizeof(struct l_user_desc));
1289         if (error)
1290                 return (EFAULT);
1291
1292         return (0);
1293 }