758d844fe061ed6f42686c363fbb58ebfc34cb88
[dragonfly.git] / sys / vm / vm_mmap.c
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1991, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
39  *
40  *      @(#)vm_mmap.c   8.4 (Berkeley) 1/12/94
41  * $FreeBSD: src/sys/vm/vm_mmap.c,v 1.108.2.6 2002/07/02 20:06:19 dillon Exp $
42  * $DragonFly: src/sys/vm/vm_mmap.c,v 1.39 2007/04/30 07:18:57 dillon Exp $
43  */
44
45 /*
46  * Mapped file (mmap) interface to VM
47  */
48
49 #include <sys/param.h>
50 #include <sys/kernel.h>
51 #include <sys/systm.h>
52 #include <sys/sysproto.h>
53 #include <sys/filedesc.h>
54 #include <sys/kern_syscall.h>
55 #include <sys/proc.h>
56 #include <sys/resource.h>
57 #include <sys/resourcevar.h>
58 #include <sys/vnode.h>
59 #include <sys/fcntl.h>
60 #include <sys/file.h>
61 #include <sys/mman.h>
62 #include <sys/conf.h>
63 #include <sys/stat.h>
64 #include <sys/vmmeter.h>
65 #include <sys/sysctl.h>
66
67 #include <vm/vm.h>
68 #include <vm/vm_param.h>
69 #include <sys/lock.h>
70 #include <vm/pmap.h>
71 #include <vm/vm_map.h>
72 #include <vm/vm_object.h>
73 #include <vm/vm_page.h>
74 #include <vm/vm_pager.h>
75 #include <vm/vm_pageout.h>
76 #include <vm/vm_extern.h>
77 #include <vm/vm_page.h>
78 #include <vm/vm_kern.h>
79
80 #include <sys/file2.h>
81 #include <sys/thread2.h>
82
83 static int max_proc_mmap;
84 SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0, "");
85 int vkernel_enable;
86 SYSCTL_INT(_vm, OID_AUTO, vkernel_enable, CTLFLAG_RW, &vkernel_enable, 0, "");
87
88 /*
89  * Set the maximum number of vm_map_entry structures per process.  Roughly
90  * speaking vm_map_entry structures are tiny, so allowing them to eat 1/100
91  * of our KVM malloc space still results in generous limits.  We want a 
92  * default that is good enough to prevent the kernel running out of resources
93  * if attacked from compromised user account but generous enough such that
94  * multi-threaded processes are not unduly inconvenienced.
95  */
96
97 static void vmmapentry_rsrc_init (void *);
98 SYSINIT(vmmersrc, SI_BOOT1_POST, SI_ORDER_ANY, vmmapentry_rsrc_init, NULL)
99
100 static void
101 vmmapentry_rsrc_init(void *dummy)
102 {
103     max_proc_mmap = KvaSize / sizeof(struct vm_map_entry);
104     max_proc_mmap /= 100;
105 }
106
107 /* ARGSUSED */
108 int
109 sys_sbrk(struct sbrk_args *uap)
110 {
111         /* Not yet implemented */
112         return (EOPNOTSUPP);
113 }
114
115 /*
116  * sstk_args(int incr)
117  */
118 /* ARGSUSED */
119 int
120 sys_sstk(struct sstk_args *uap)
121 {
122         /* Not yet implemented */
123         return (EOPNOTSUPP);
124 }
125
126 /* 
127  * mmap_args(void *addr, size_t len, int prot, int flags, int fd,
128  *              long pad, off_t pos)
129  *
130  * Memory Map (mmap) system call.  Note that the file offset
131  * and address are allowed to be NOT page aligned, though if
132  * the MAP_FIXED flag it set, both must have the same remainder
133  * modulo the PAGE_SIZE (POSIX 1003.1b).  If the address is not
134  * page-aligned, the actual mapping starts at trunc_page(addr)
135  * and the return value is adjusted up by the page offset.
136  *
137  * Generally speaking, only character devices which are themselves
138  * memory-based, such as a video framebuffer, can be mmap'd.  Otherwise
139  * there would be no cache coherency between a descriptor and a VM mapping
140  * both to the same character device.
141  *
142  * Block devices can be mmap'd no matter what they represent.  Cache coherency
143  * is maintained as long as you do not write directly to the underlying
144  * character device.
145  */
146
147 int
148 kern_mmap(struct vmspace *vms, caddr_t uaddr, size_t ulen,
149           int uprot, int uflags, int fd, off_t upos, void **res)
150 {
151         struct thread *td = curthread;
152         struct proc *p = td->td_proc;
153         struct file *fp = NULL;
154         struct vnode *vp;
155         vm_offset_t addr;
156         vm_size_t size, pageoff;
157         vm_prot_t prot, maxprot;
158         void *handle;
159         int flags, error;
160         int disablexworkaround;
161         off_t pos;
162         vm_object_t obj;
163
164         KKASSERT(p);
165
166         addr = (vm_offset_t) uaddr;
167         size = ulen;
168         prot = uprot & VM_PROT_ALL;
169         flags = uflags;
170         pos = upos;
171
172         /* make sure mapping fits into numeric range etc */
173         if ((ssize_t) ulen < 0 || ((flags & MAP_ANON) && fd != -1))
174                 return (EINVAL);
175
176         if (flags & MAP_STACK) {
177                 if ((fd != -1) ||
178                     ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)))
179                         return (EINVAL);
180                 flags |= MAP_ANON;
181                 pos = 0;
182         }
183
184         /*
185          * Virtual page tables cannot be used with MAP_STACK.  Apart from
186          * it not making any sense, the aux union is used by both
187          * types.
188          *
189          * Because the virtual page table is stored in the backing object
190          * and might be updated by the kernel, the mapping must be R+W.
191          */
192         if (flags & MAP_VPAGETABLE) {
193                 if (vkernel_enable == 0)
194                         return (EOPNOTSUPP);
195                 if (flags & MAP_STACK)
196                         return (EINVAL);
197                 if ((prot & (PROT_READ|PROT_WRITE)) != (PROT_READ|PROT_WRITE))
198                         return (EINVAL);
199         }
200
201         /*
202          * Align the file position to a page boundary,
203          * and save its page offset component.
204          */
205         pageoff = (pos & PAGE_MASK);
206         pos -= pageoff;
207
208         /* Adjust size for rounding (on both ends). */
209         size += pageoff;                        /* low end... */
210         size = (vm_size_t) round_page(size);    /* hi end */
211
212         /*
213          * Check for illegal addresses.  Watch out for address wrap... Note
214          * that VM_*_ADDRESS are not constants due to casts (argh).
215          */
216         if (flags & MAP_FIXED) {
217                 /*
218                  * The specified address must have the same remainder
219                  * as the file offset taken modulo PAGE_SIZE, so it
220                  * should be aligned after adjustment by pageoff.
221                  */
222                 addr -= pageoff;
223                 if (addr & PAGE_MASK)
224                         return (EINVAL);
225                 /* Address range must be all in user VM space. */
226                 if (VM_MAX_USER_ADDRESS > 0 && addr + size > VM_MAX_USER_ADDRESS)
227                         return (EINVAL);
228                 if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS)
229                         return (EINVAL);
230                 if (addr + size < addr)
231                         return (EINVAL);
232         } else if ((flags & MAP_TRYFIXED) == 0) {
233                 /*
234                  * XXX for non-fixed mappings where no hint is provided or
235                  * the hint would fall in the potential heap space,
236                  * place it after the end of the largest possible heap.
237                  *
238                  * There should really be a pmap call to determine a reasonable
239                  * location.
240                  */
241                 if (addr == 0 ||
242                     (addr >= round_page((vm_offset_t)vms->vm_taddr) &&
243                      addr < round_page((vm_offset_t)vms->vm_daddr + maxdsiz)))
244                         addr = round_page((vm_offset_t)vms->vm_daddr + maxdsiz);
245         }
246
247         if (flags & MAP_ANON) {
248                 /*
249                  * Mapping blank space is trivial.
250                  */
251                 handle = NULL;
252                 maxprot = VM_PROT_ALL;
253                 pos = 0;
254         } else {
255                 /*
256                  * Mapping file, get fp for validation. Obtain vnode and make
257                  * sure it is of appropriate type.
258                  */
259                 fp = holdfp(p->p_fd, fd, -1);
260                 if (fp == NULL)
261                         return (EBADF);
262                 if (fp->f_type != DTYPE_VNODE) {
263                         error = EINVAL;
264                         goto done;
265                 }
266                 /*
267                  * POSIX shared-memory objects are defined to have
268                  * kernel persistence, and are not defined to support
269                  * read(2)/write(2) -- or even open(2).  Thus, we can
270                  * use MAP_ASYNC to trade on-disk coherence for speed.
271                  * The shm_open(3) library routine turns on the FPOSIXSHM
272                  * flag to request this behavior.
273                  */
274                 if (fp->f_flag & FPOSIXSHM)
275                         flags |= MAP_NOSYNC;
276                 vp = (struct vnode *) fp->f_data;
277
278                 /*
279                  * Validate the vnode for the operation.
280                  */
281                 switch(vp->v_type) {
282                 case VREG:
283                         /*
284                          * Get the proper underlying object
285                          */
286                         if ((obj = vp->v_object) == NULL) {
287                                 error = EINVAL;
288                                 goto done;
289                         }
290                         KKASSERT((struct vnode *)obj->handle == vp);
291                         break;
292                 case VCHR:
293                         /*
294                          * Make sure a device has not been revoked.  
295                          * Mappability is handled by the device layer.
296                          */
297                         if (vp->v_rdev == NULL) {
298                                 error = EBADF;
299                                 goto done;
300                         }
301                         break;
302                 default:
303                         /*
304                          * Nothing else is mappable.
305                          */
306                         error = EINVAL;
307                         goto done;
308                 }
309
310                 /*
311                  * XXX hack to handle use of /dev/zero to map anon memory (ala
312                  * SunOS).
313                  */
314                 if (vp->v_type == VCHR && iszerodev(vp->v_rdev)) {
315                         handle = NULL;
316                         maxprot = VM_PROT_ALL;
317                         flags |= MAP_ANON;
318                         pos = 0;
319                 } else {
320                         /*
321                          * cdevs does not provide private mappings of any kind.
322                          */
323                         /*
324                          * However, for XIG X server to continue to work,
325                          * we should allow the superuser to do it anyway.
326                          * We only allow it at securelevel < 1.
327                          * (Because the XIG X server writes directly to video
328                          * memory via /dev/mem, it should never work at any
329                          * other securelevel.
330                          * XXX this will have to go
331                          */
332                         if (securelevel >= 1)
333                                 disablexworkaround = 1;
334                         else
335                                 disablexworkaround = suser(td);
336                         if (vp->v_type == VCHR && disablexworkaround &&
337                             (flags & (MAP_PRIVATE|MAP_COPY))) {
338                                 error = EINVAL;
339                                 goto done;
340                         }
341                         /*
342                          * Ensure that file and memory protections are
343                          * compatible.  Note that we only worry about
344                          * writability if mapping is shared; in this case,
345                          * current and max prot are dictated by the open file.
346                          * XXX use the vnode instead?  Problem is: what
347                          * credentials do we use for determination? What if
348                          * proc does a setuid?
349                          */
350                         maxprot = VM_PROT_EXECUTE;      /* ??? */
351                         if (fp->f_flag & FREAD) {
352                                 maxprot |= VM_PROT_READ;
353                         } else if (prot & PROT_READ) {
354                                 error = EACCES;
355                                 goto done;
356                         }
357                         /*
358                          * If we are sharing potential changes (either via
359                          * MAP_SHARED or via the implicit sharing of character
360                          * device mappings), and we are trying to get write
361                          * permission although we opened it without asking
362                          * for it, bail out.  Check for superuser, only if
363                          * we're at securelevel < 1, to allow the XIG X server
364                          * to continue to work.
365                          */
366
367                         if ((flags & MAP_SHARED) != 0 ||
368                             (vp->v_type == VCHR && disablexworkaround)) {
369                                 if ((fp->f_flag & FWRITE) != 0) {
370                                         struct vattr va;
371                                         if ((error = VOP_GETATTR(vp, &va))) {
372                                                 goto done;
373                                         }
374                                         if ((va.va_flags &
375                                             (IMMUTABLE|APPEND)) == 0) {
376                                                 maxprot |= VM_PROT_WRITE;
377                                         } else if (prot & PROT_WRITE) {
378                                                 error = EPERM;
379                                                 goto done;
380                                         }
381                                 } else if ((prot & PROT_WRITE) != 0) {
382                                         error = EACCES;
383                                         goto done;
384                                 }
385                         } else {
386                                 maxprot |= VM_PROT_WRITE;
387                         }
388                         handle = (void *)vp;
389                 }
390         }
391
392         /*
393          * Do not allow more then a certain number of vm_map_entry structures
394          * per process.  Scale with the number of rforks sharing the map
395          * to make the limit reasonable for threads.
396          */
397         if (max_proc_mmap && 
398             vms->vm_map.nentries >= max_proc_mmap * vms->vm_sysref.refcnt) {
399                 error = ENOMEM;
400                 goto done;
401         }
402
403         error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
404             flags, handle, pos);
405         if (error == 0)
406                 *res = (void *)(addr + pageoff);
407 done:
408         if (fp)
409                 fdrop(fp);
410         return (error);
411 }
412
413 int
414 sys_mmap(struct mmap_args *uap)
415 {
416         int error;
417
418         error = kern_mmap(curproc->p_vmspace, uap->addr, uap->len,
419                           uap->prot, uap->flags,
420                           uap->fd, uap->pos, &uap->sysmsg_resultp);
421
422         return (error);
423 }
424
425 /*
426  * msync_args(void *addr, int len, int flags)
427  */
428 int
429 sys_msync(struct msync_args *uap)
430 {
431         struct proc *p = curproc;
432         vm_offset_t addr;
433         vm_size_t size, pageoff;
434         int flags;
435         vm_map_t map;
436         int rv;
437
438         addr = (vm_offset_t) uap->addr;
439         size = uap->len;
440         flags = uap->flags;
441
442         pageoff = (addr & PAGE_MASK);
443         addr -= pageoff;
444         size += pageoff;
445         size = (vm_size_t) round_page(size);
446         if (addr + size < addr)
447                 return(EINVAL);
448
449         if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
450                 return (EINVAL);
451
452         map = &p->p_vmspace->vm_map;
453
454         /*
455          * XXX Gak!  If size is zero we are supposed to sync "all modified
456          * pages with the region containing addr".  Unfortunately, we don't
457          * really keep track of individual mmaps so we approximate by flushing
458          * the range of the map entry containing addr. This can be incorrect
459          * if the region splits or is coalesced with a neighbor.
460          */
461         if (size == 0) {
462                 vm_map_entry_t entry;
463
464                 vm_map_lock_read(map);
465                 rv = vm_map_lookup_entry(map, addr, &entry);
466                 vm_map_unlock_read(map);
467                 if (rv == FALSE)
468                         return (EINVAL);
469                 addr = entry->start;
470                 size = entry->end - entry->start;
471         }
472
473         /*
474          * Clean the pages and interpret the return value.
475          */
476         rv = vm_map_clean(map, addr, addr + size, (flags & MS_ASYNC) == 0,
477             (flags & MS_INVALIDATE) != 0);
478
479         switch (rv) {
480         case KERN_SUCCESS:
481                 break;
482         case KERN_INVALID_ADDRESS:
483                 return (EINVAL);        /* Sun returns ENOMEM? */
484         case KERN_FAILURE:
485                 return (EIO);
486         default:
487                 return (EINVAL);
488         }
489
490         return (0);
491 }
492
493 /*
494  * munmap_args(void *addr, size_t len)
495  */
496 int
497 sys_munmap(struct munmap_args *uap)
498 {
499         struct proc *p = curproc;
500         vm_offset_t addr;
501         vm_size_t size, pageoff;
502         vm_map_t map;
503
504         addr = (vm_offset_t) uap->addr;
505         size = uap->len;
506
507         pageoff = (addr & PAGE_MASK);
508         addr -= pageoff;
509         size += pageoff;
510         size = (vm_size_t) round_page(size);
511         if (addr + size < addr)
512                 return(EINVAL);
513
514         if (size == 0)
515                 return (0);
516
517         /*
518          * Check for illegal addresses.  Watch out for address wrap... Note
519          * that VM_*_ADDRESS are not constants due to casts (argh).
520          */
521         if (VM_MAX_USER_ADDRESS > 0 && addr + size > VM_MAX_USER_ADDRESS)
522                 return (EINVAL);
523         if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS)
524                 return (EINVAL);
525         map = &p->p_vmspace->vm_map;
526         /*
527          * Make sure entire range is allocated.
528          */
529         if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE))
530                 return (EINVAL);
531         /* returns nothing but KERN_SUCCESS anyway */
532         vm_map_remove(map, addr, addr + size);
533         return (0);
534 }
535
536 /*
537  * mprotect_args(const void *addr, size_t len, int prot)
538  */
539 int
540 sys_mprotect(struct mprotect_args *uap)
541 {
542         struct proc *p = curproc;
543         vm_offset_t addr;
544         vm_size_t size, pageoff;
545         vm_prot_t prot;
546
547         addr = (vm_offset_t) uap->addr;
548         size = uap->len;
549         prot = uap->prot & VM_PROT_ALL;
550 #if defined(VM_PROT_READ_IS_EXEC)
551         if (prot & VM_PROT_READ)
552                 prot |= VM_PROT_EXECUTE;
553 #endif
554
555         pageoff = (addr & PAGE_MASK);
556         addr -= pageoff;
557         size += pageoff;
558         size = (vm_size_t) round_page(size);
559         if (addr + size < addr)
560                 return(EINVAL);
561
562         switch (vm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot,
563                 FALSE)) {
564         case KERN_SUCCESS:
565                 return (0);
566         case KERN_PROTECTION_FAILURE:
567                 return (EACCES);
568         }
569         return (EINVAL);
570 }
571
572 /*
573  * minherit_args(void *addr, size_t len, int inherit)
574  */
575 int
576 sys_minherit(struct minherit_args *uap)
577 {
578         struct proc *p = curproc;
579         vm_offset_t addr;
580         vm_size_t size, pageoff;
581         vm_inherit_t inherit;
582
583         addr = (vm_offset_t)uap->addr;
584         size = uap->len;
585         inherit = uap->inherit;
586
587         pageoff = (addr & PAGE_MASK);
588         addr -= pageoff;
589         size += pageoff;
590         size = (vm_size_t) round_page(size);
591         if (addr + size < addr)
592                 return(EINVAL);
593
594         switch (vm_map_inherit(&p->p_vmspace->vm_map, addr, addr+size,
595             inherit)) {
596         case KERN_SUCCESS:
597                 return (0);
598         case KERN_PROTECTION_FAILURE:
599                 return (EACCES);
600         }
601         return (EINVAL);
602 }
603
604 /*
605  * madvise_args(void *addr, size_t len, int behav)
606  */
607 /* ARGSUSED */
608 int
609 sys_madvise(struct madvise_args *uap)
610 {
611         struct proc *p = curproc;
612         vm_offset_t start, end;
613
614         /*
615          * Check for illegal behavior
616          */
617         if (uap->behav < 0 || uap->behav >= MADV_CONTROL_END)
618                 return (EINVAL);
619         /*
620          * Check for illegal addresses.  Watch out for address wrap... Note
621          * that VM_*_ADDRESS are not constants due to casts (argh).
622          */
623         if (VM_MAX_USER_ADDRESS > 0 &&
624                 ((vm_offset_t) uap->addr + uap->len) > VM_MAX_USER_ADDRESS)
625                 return (EINVAL);
626         if (VM_MIN_USER_ADDRESS > 0 && uap->addr < VM_MIN_USER_ADDRESS)
627                 return (EINVAL);
628         if (((vm_offset_t) uap->addr + uap->len) < (vm_offset_t) uap->addr)
629                 return (EINVAL);
630
631         /*
632          * Since this routine is only advisory, we default to conservative
633          * behavior.
634          */
635         start = trunc_page((vm_offset_t) uap->addr);
636         end = round_page((vm_offset_t) uap->addr + uap->len);
637         
638         return (vm_map_madvise(&p->p_vmspace->vm_map, start, end,
639                 uap->behav, 0));
640 }
641
642 /*
643  * mcontrol_args(void *addr, size_t len, int behav, off_t value)
644  */
645 /* ARGSUSED */
646 int
647 sys_mcontrol(struct mcontrol_args *uap)
648 {
649         struct proc *p = curproc;
650         vm_offset_t start, end;
651
652         /*
653          * Check for illegal behavior
654          */
655         if (uap->behav < 0 || uap->behav > MADV_CONTROL_END)
656                 return (EINVAL);
657         /*
658          * Check for illegal addresses.  Watch out for address wrap... Note
659          * that VM_*_ADDRESS are not constants due to casts (argh).
660          */
661         if (VM_MAX_USER_ADDRESS > 0 &&
662                 ((vm_offset_t) uap->addr + uap->len) > VM_MAX_USER_ADDRESS)
663                 return (EINVAL);
664         if (VM_MIN_USER_ADDRESS > 0 && uap->addr < VM_MIN_USER_ADDRESS)
665                 return (EINVAL);
666         if (((vm_offset_t) uap->addr + uap->len) < (vm_offset_t) uap->addr)
667                 return (EINVAL);
668
669         /*
670          * Since this routine is only advisory, we default to conservative
671          * behavior.
672          */
673         start = trunc_page((vm_offset_t) uap->addr);
674         end = round_page((vm_offset_t) uap->addr + uap->len);
675         
676         return (vm_map_madvise(&p->p_vmspace->vm_map, start, end, 
677                               uap->behav, uap->value));
678 }
679
680
681 /*
682  * mincore_args(const void *addr, size_t len, char *vec)
683  */
684 /* ARGSUSED */
685 int
686 sys_mincore(struct mincore_args *uap)
687 {
688         struct proc *p = curproc;
689         vm_offset_t addr, first_addr;
690         vm_offset_t end, cend;
691         pmap_t pmap;
692         vm_map_t map;
693         char *vec;
694         int error;
695         int vecindex, lastvecindex;
696         vm_map_entry_t current;
697         vm_map_entry_t entry;
698         int mincoreinfo;
699         unsigned int timestamp;
700
701         /*
702          * Make sure that the addresses presented are valid for user
703          * mode.
704          */
705         first_addr = addr = trunc_page((vm_offset_t) uap->addr);
706         end = addr + (vm_size_t)round_page(uap->len);
707         if (VM_MAX_USER_ADDRESS > 0 && end > VM_MAX_USER_ADDRESS)
708                 return (EINVAL);
709         if (end < addr)
710                 return (EINVAL);
711
712         /*
713          * Address of byte vector
714          */
715         vec = uap->vec;
716
717         map = &p->p_vmspace->vm_map;
718         pmap = vmspace_pmap(p->p_vmspace);
719
720         vm_map_lock_read(map);
721 RestartScan:
722         timestamp = map->timestamp;
723
724         if (!vm_map_lookup_entry(map, addr, &entry))
725                 entry = entry->next;
726
727         /*
728          * Do this on a map entry basis so that if the pages are not
729          * in the current processes address space, we can easily look
730          * up the pages elsewhere.
731          */
732         lastvecindex = -1;
733         for(current = entry;
734                 (current != &map->header) && (current->start < end);
735                 current = current->next) {
736
737                 /*
738                  * ignore submaps (for now) or null objects
739                  */
740                 if (current->maptype != VM_MAPTYPE_NORMAL &&
741                     current->maptype != VM_MAPTYPE_VPAGETABLE) {
742                         continue;
743                 }
744                 if (current->object.vm_object == NULL)
745                         continue;
746                 
747                 /*
748                  * limit this scan to the current map entry and the
749                  * limits for the mincore call
750                  */
751                 if (addr < current->start)
752                         addr = current->start;
753                 cend = current->end;
754                 if (cend > end)
755                         cend = end;
756
757                 /*
758                  * scan this entry one page at a time
759                  */
760                 while (addr < cend) {
761                         /*
762                          * Check pmap first, it is likely faster, also
763                          * it can provide info as to whether we are the
764                          * one referencing or modifying the page.
765                          *
766                          * If we have to check the VM object, only mess
767                          * around with normal maps.  Do not mess around
768                          * with virtual page tables (XXX).
769                          */
770                         mincoreinfo = pmap_mincore(pmap, addr);
771                         if (mincoreinfo == 0 &&
772                             current->maptype == VM_MAPTYPE_NORMAL) {
773                                 vm_pindex_t pindex;
774                                 vm_ooffset_t offset;
775                                 vm_page_t m;
776
777                                 /*
778                                  * calculate the page index into the object
779                                  */
780                                 offset = current->offset + (addr - current->start);
781                                 pindex = OFF_TO_IDX(offset);
782
783                                 /*
784                                  * if the page is resident, then gather 
785                                  * information about it.  spl protection is
786                                  * required to maintain the object 
787                                  * association.  And XXX what if the page is
788                                  * busy?  What's the deal with that?
789                                  */
790                                 crit_enter();
791                                 m = vm_page_lookup(current->object.vm_object,
792                                                     pindex);
793                                 if (m && m->valid) {
794                                         mincoreinfo = MINCORE_INCORE;
795                                         if (m->dirty ||
796                                                 pmap_is_modified(m))
797                                                 mincoreinfo |= MINCORE_MODIFIED_OTHER;
798                                         if ((m->flags & PG_REFERENCED) ||
799                                                 pmap_ts_referenced(m)) {
800                                                 vm_page_flag_set(m, PG_REFERENCED);
801                                                 mincoreinfo |= MINCORE_REFERENCED_OTHER;
802                                         }
803                                 }
804                                 crit_exit();
805                         }
806
807                         /*
808                          * subyte may page fault.  In case it needs to modify
809                          * the map, we release the lock.
810                          */
811                         vm_map_unlock_read(map);
812
813                         /*
814                          * calculate index into user supplied byte vector
815                          */
816                         vecindex = OFF_TO_IDX(addr - first_addr);
817
818                         /*
819                          * If we have skipped map entries, we need to make sure that
820                          * the byte vector is zeroed for those skipped entries.
821                          */
822                         while((lastvecindex + 1) < vecindex) {
823                                 error = subyte( vec + lastvecindex, 0);
824                                 if (error) {
825                                         return (EFAULT);
826                                 }
827                                 ++lastvecindex;
828                         }
829
830                         /*
831                          * Pass the page information to the user
832                          */
833                         error = subyte( vec + vecindex, mincoreinfo);
834                         if (error) {
835                                 return (EFAULT);
836                         }
837
838                         /*
839                          * If the map has changed, due to the subyte, the previous
840                          * output may be invalid.
841                          */
842                         vm_map_lock_read(map);
843                         if (timestamp != map->timestamp)
844                                 goto RestartScan;
845
846                         lastvecindex = vecindex;
847                         addr += PAGE_SIZE;
848                 }
849         }
850
851         /*
852          * subyte may page fault.  In case it needs to modify
853          * the map, we release the lock.
854          */
855         vm_map_unlock_read(map);
856
857         /*
858          * Zero the last entries in the byte vector.
859          */
860         vecindex = OFF_TO_IDX(end - first_addr);
861         while((lastvecindex + 1) < vecindex) {
862                 error = subyte( vec + lastvecindex, 0);
863                 if (error) {
864                         return (EFAULT);
865                 }
866                 ++lastvecindex;
867         }
868         
869         /*
870          * If the map has changed, due to the subyte, the previous
871          * output may be invalid.
872          */
873         vm_map_lock_read(map);
874         if (timestamp != map->timestamp)
875                 goto RestartScan;
876         vm_map_unlock_read(map);
877
878         return (0);
879 }
880
881 /*
882  * mlock_args(const void *addr, size_t len)
883  */
884 int
885 sys_mlock(struct mlock_args *uap)
886 {
887         vm_offset_t addr;
888         vm_size_t size, pageoff;
889         int error;
890         struct proc *p = curproc;
891
892         addr = (vm_offset_t) uap->addr;
893         size = uap->len;
894
895         pageoff = (addr & PAGE_MASK);
896         addr -= pageoff;
897         size += pageoff;
898         size = (vm_size_t) round_page(size);
899
900         /* disable wrap around */
901         if (addr + size < addr)
902                 return (EINVAL);
903
904         if (atop(size) + vmstats.v_wire_count > vm_page_max_wired)
905                 return (EAGAIN);
906
907 #ifdef pmap_wired_count
908         if (size + ptoa(pmap_wired_count(vm_map_pmap(&p->p_vmspace->vm_map))) >
909             p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur)
910                 return (ENOMEM);
911 #else
912         error = suser_cred(p->p_ucred, 0);
913         if (error)
914                 return (error);
915 #endif
916
917         error = vm_map_unwire(&p->p_vmspace->vm_map, addr, addr + size, FALSE);
918         return (error == KERN_SUCCESS ? 0 : ENOMEM);
919 }
920
921 /*
922  * mlockall_args(int how)
923  */
924 int
925 sys_mlockall(struct mlockall_args *uap)
926 {
927         return 0;
928 }
929
930 /*
931  * munlockall_args(void)
932  */
933 int
934 sys_munlockall(struct munlockall_args *uap)
935 {
936         return 0;
937 }
938
939 /*
940  * munlock_args(const void *addr, size_t len)
941  */
942 int
943 sys_munlock(struct munlock_args *uap)
944 {
945         struct thread *td = curthread;
946         struct proc *p = td->td_proc;
947         vm_offset_t addr;
948         vm_size_t size, pageoff;
949         int error;
950
951         addr = (vm_offset_t) uap->addr;
952         size = uap->len;
953
954         pageoff = (addr & PAGE_MASK);
955         addr -= pageoff;
956         size += pageoff;
957         size = (vm_size_t) round_page(size);
958
959         /* disable wrap around */
960         if (addr + size < addr)
961                 return (EINVAL);
962
963 #ifndef pmap_wired_count
964         error = suser(td);
965         if (error)
966                 return (error);
967 #endif
968
969         error = vm_map_unwire(&p->p_vmspace->vm_map, addr, addr + size, TRUE);
970         return (error == KERN_SUCCESS ? 0 : ENOMEM);
971 }
972
973 /*
974  * Internal version of mmap.
975  * Currently used by mmap, exec, and sys5 shared memory.
976  * Handle is either a vnode pointer or NULL for MAP_ANON.
977  */
978 int
979 vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
980         vm_prot_t maxprot, int flags,
981         void *handle,
982         vm_ooffset_t foff)
983 {
984         boolean_t fitit;
985         vm_object_t object;
986         struct vnode *vp = NULL;
987         struct proc *p;
988         objtype_t type;
989         int rv = KERN_SUCCESS;
990         off_t objsize;
991         int docow;
992
993         if (size == 0)
994                 return (0);
995
996         objsize = size = round_page(size);
997
998         /*
999          * XXX messy code, fixme
1000          */
1001         if ((p = curproc) != NULL && map == &p->p_vmspace->vm_map) {
1002                 if (map->size + size > p->p_rlimit[RLIMIT_VMEM].rlim_cur)
1003                         return(ENOMEM);
1004         }
1005
1006         /*
1007          * We currently can only deal with page aligned file offsets.
1008          * The check is here rather than in the syscall because the
1009          * kernel calls this function internally for other mmaping
1010          * operations (such as in exec) and non-aligned offsets will
1011          * cause pmap inconsistencies...so we want to be sure to
1012          * disallow this in all cases.
1013          */
1014         if (foff & PAGE_MASK)
1015                 return (EINVAL);
1016
1017         if ((flags & MAP_FIXED) == 0) {
1018                 fitit = TRUE;
1019                 *addr = round_page(*addr);
1020         } else {
1021                 if (*addr != trunc_page(*addr))
1022                         return (EINVAL);
1023                 fitit = FALSE;
1024                 vm_map_remove(map, *addr, *addr + size);
1025         }
1026
1027         /*
1028          * Lookup/allocate object.
1029          */
1030         if (flags & MAP_ANON) {
1031                 type = OBJT_DEFAULT;
1032                 /*
1033                  * Unnamed anonymous regions always start at 0.
1034                  */
1035                 if (handle == 0)
1036                         foff = 0;
1037         } else {
1038                 vp = (struct vnode *) handle;
1039                 if (vp->v_type == VCHR) {
1040                         type = OBJT_DEVICE;
1041                         handle = (void *)(intptr_t)vp->v_rdev;
1042                 } else {
1043                         struct vattr vat, tsvat;
1044                         int error;
1045
1046                         error = VOP_GETATTR(vp, &vat);
1047                         if (error)
1048                                 return (error);
1049
1050                         /* Update access time */
1051                         VATTR_NULL(&tsvat);
1052                         vfs_timestamp(&tsvat.va_atime);
1053                         VOP_SETATTR(vp, &tsvat, curproc != NULL ? curproc->p_ucred : NULL);
1054
1055                         objsize = vat.va_size;
1056                         type = OBJT_VNODE;
1057                         /*
1058                          * if it is a regular file without any references
1059                          * we do not need to sync it.
1060                          */
1061                         if (vp->v_type == VREG && vat.va_nlink == 0) {
1062                                 flags |= MAP_NOSYNC;
1063                         }
1064                 }
1065         }
1066
1067         if (handle == NULL) {
1068                 object = NULL;
1069                 docow = 0;
1070         } else {
1071                 object = vm_pager_allocate(type, handle, objsize, prot, foff);
1072                 if (object == NULL)
1073                         return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
1074                 docow = MAP_PREFAULT_PARTIAL;
1075         }
1076
1077         /*
1078          * Force device mappings to be shared.
1079          */
1080         if (type == OBJT_DEVICE || type == OBJT_PHYS) {
1081                 flags &= ~(MAP_PRIVATE|MAP_COPY);
1082                 flags |= MAP_SHARED;
1083         }
1084
1085         if ((flags & (MAP_ANON|MAP_SHARED)) == 0)
1086                 docow |= MAP_COPY_ON_WRITE;
1087         if (flags & MAP_NOSYNC)
1088                 docow |= MAP_DISABLE_SYNCER;
1089         if (flags & MAP_NOCORE)
1090                 docow |= MAP_DISABLE_COREDUMP;
1091
1092 #if defined(VM_PROT_READ_IS_EXEC)
1093         if (prot & VM_PROT_READ)
1094                 prot |= VM_PROT_EXECUTE;
1095
1096         if (maxprot & VM_PROT_READ)
1097                 maxprot |= VM_PROT_EXECUTE;
1098 #endif
1099
1100         if (fitit) {
1101                 *addr = pmap_addr_hint(object, *addr, size);
1102         }
1103
1104         /*
1105          * Stack mappings need special attention.  Mappings that use virtual
1106          * page tables will default to storing the page table at offset 0.
1107          */
1108         if (flags & MAP_STACK) {
1109                 rv = vm_map_stack (map, *addr, size, prot, maxprot, docow);
1110         } else if (flags & MAP_VPAGETABLE) {
1111                 rv = vm_map_find(map, object, foff, addr, size, fitit,
1112                                  VM_MAPTYPE_VPAGETABLE, prot, maxprot, docow);
1113         } else {
1114                 rv = vm_map_find(map, object, foff, addr, size, fitit,
1115                                  VM_MAPTYPE_NORMAL, prot, maxprot, docow);
1116         }
1117
1118         if (rv != KERN_SUCCESS) {
1119                 /*
1120                  * Lose the object reference. Will destroy the
1121                  * object if it's an unnamed anonymous mapping
1122                  * or named anonymous without other references.
1123                  */
1124                 vm_object_deallocate(object);
1125                 goto out;
1126         }
1127
1128         /*
1129          * Shared memory is also shared with children.
1130          */
1131         if (flags & (MAP_SHARED|MAP_INHERIT)) {
1132                 rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE);
1133                 if (rv != KERN_SUCCESS) {
1134                         vm_map_remove(map, *addr, *addr + size);
1135                         goto out;
1136                 }
1137         }
1138 out:
1139         switch (rv) {
1140         case KERN_SUCCESS:
1141                 return (0);
1142         case KERN_INVALID_ADDRESS:
1143         case KERN_NO_SPACE:
1144                 return (ENOMEM);
1145         case KERN_PROTECTION_FAILURE:
1146                 return (EACCES);
1147         default:
1148                 return (EINVAL);
1149         }
1150 }