]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/vm/vm_mmap.c
MF8 r217553:
[FreeBSD/releng/8.2.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  * 4. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  * from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
35  *
36  *      @(#)vm_mmap.c   8.4 (Berkeley) 1/12/94
37  */
38
39 /*
40  * Mapped file (mmap) interface to VM
41  */
42
43 #include <sys/cdefs.h>
44 __FBSDID("$FreeBSD$");
45
46 #include "opt_compat.h"
47 #include "opt_hwpmc_hooks.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/sysproto.h>
55 #include <sys/filedesc.h>
56 #include <sys/priv.h>
57 #include <sys/proc.h>
58 #include <sys/resource.h>
59 #include <sys/resourcevar.h>
60 #include <sys/vnode.h>
61 #include <sys/fcntl.h>
62 #include <sys/file.h>
63 #include <sys/mman.h>
64 #include <sys/mount.h>
65 #include <sys/conf.h>
66 #include <sys/stat.h>
67 #include <sys/sysent.h>
68 #include <sys/vmmeter.h>
69 #include <sys/sysctl.h>
70
71 #include <security/mac/mac_framework.h>
72
73 #include <vm/vm.h>
74 #include <vm/vm_param.h>
75 #include <vm/pmap.h>
76 #include <vm/vm_map.h>
77 #include <vm/vm_object.h>
78 #include <vm/vm_page.h>
79 #include <vm/vm_pager.h>
80 #include <vm/vm_pageout.h>
81 #include <vm/vm_extern.h>
82 #include <vm/vm_page.h>
83 #include <vm/vm_kern.h>
84
85 #ifdef HWPMC_HOOKS
86 #include <sys/pmckern.h>
87 #endif
88
89 #ifndef _SYS_SYSPROTO_H_
90 struct sbrk_args {
91         int incr;
92 };
93 #endif
94
95 static int max_proc_mmap;
96 SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0,
97     "Maximum number of memory-mapped files per process");
98
99 /*
100  * Set the maximum number of vm_map_entry structures per process.  Roughly
101  * speaking vm_map_entry structures are tiny, so allowing them to eat 1/100
102  * of our KVM malloc space still results in generous limits.  We want a
103  * default that is good enough to prevent the kernel running out of resources
104  * if attacked from compromised user account but generous enough such that
105  * multi-threaded processes are not unduly inconvenienced.
106  */
107 static void vmmapentry_rsrc_init(void *);
108 SYSINIT(vmmersrc, SI_SUB_KVM_RSRC, SI_ORDER_FIRST, vmmapentry_rsrc_init,
109     NULL);
110
111 static void
112 vmmapentry_rsrc_init(dummy)
113         void *dummy;
114 {
115     max_proc_mmap = vm_kmem_size / sizeof(struct vm_map_entry);
116     max_proc_mmap /= 100;
117 }
118
119 static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
120     int *, struct vnode *, vm_ooffset_t *, vm_object_t *);
121 static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
122     int *, struct cdev *, vm_ooffset_t *, vm_object_t *);
123 static int vm_mmap_shm(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *,
124     int *, struct shmfd *, vm_ooffset_t, vm_object_t *);
125
126 /*
127  * MPSAFE
128  */
129 /* ARGSUSED */
130 int
131 sbrk(td, uap)
132         struct thread *td;
133         struct sbrk_args *uap;
134 {
135         /* Not yet implemented */
136         return (EOPNOTSUPP);
137 }
138
139 #ifndef _SYS_SYSPROTO_H_
140 struct sstk_args {
141         int incr;
142 };
143 #endif
144
145 /*
146  * MPSAFE
147  */
148 /* ARGSUSED */
149 int
150 sstk(td, uap)
151         struct thread *td;
152         struct sstk_args *uap;
153 {
154         /* Not yet implemented */
155         return (EOPNOTSUPP);
156 }
157
158 #if defined(COMPAT_43)
159 #ifndef _SYS_SYSPROTO_H_
160 struct getpagesize_args {
161         int dummy;
162 };
163 #endif
164
165 /* ARGSUSED */
166 int
167 ogetpagesize(td, uap)
168         struct thread *td;
169         struct getpagesize_args *uap;
170 {
171         /* MP SAFE */
172         td->td_retval[0] = PAGE_SIZE;
173         return (0);
174 }
175 #endif                          /* COMPAT_43 */
176
177
178 /*
179  * Memory Map (mmap) system call.  Note that the file offset
180  * and address are allowed to be NOT page aligned, though if
181  * the MAP_FIXED flag it set, both must have the same remainder
182  * modulo the PAGE_SIZE (POSIX 1003.1b).  If the address is not
183  * page-aligned, the actual mapping starts at trunc_page(addr)
184  * and the return value is adjusted up by the page offset.
185  *
186  * Generally speaking, only character devices which are themselves
187  * memory-based, such as a video framebuffer, can be mmap'd.  Otherwise
188  * there would be no cache coherency between a descriptor and a VM mapping
189  * both to the same character device.
190  */
191 #ifndef _SYS_SYSPROTO_H_
192 struct mmap_args {
193         void *addr;
194         size_t len;
195         int prot;
196         int flags;
197         int fd;
198         long pad;
199         off_t pos;
200 };
201 #endif
202
203 /*
204  * MPSAFE
205  */
206 int
207 mmap(td, uap)
208         struct thread *td;
209         struct mmap_args *uap;
210 {
211 #ifdef HWPMC_HOOKS
212         struct pmckern_map_in pkm;
213 #endif
214         struct file *fp;
215         struct vnode *vp;
216         vm_offset_t addr;
217         vm_size_t size, pageoff;
218         vm_prot_t prot, maxprot;
219         void *handle;
220         objtype_t handle_type;
221         int flags, error;
222         off_t pos;
223         struct vmspace *vms = td->td_proc->p_vmspace;
224
225         addr = (vm_offset_t) uap->addr;
226         size = uap->len;
227         prot = uap->prot & VM_PROT_ALL;
228         flags = uap->flags;
229         pos = uap->pos;
230
231         fp = NULL;
232         /* make sure mapping fits into numeric range etc */
233         if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) &&
234              curproc->p_osrel >= P_OSREL_MAP_ANON) ||
235             ((flags & MAP_ANON) && (uap->fd != -1 || pos != 0)))
236                 return (EINVAL);
237
238         if (flags & MAP_STACK) {
239                 if ((uap->fd != -1) ||
240                     ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE)))
241                         return (EINVAL);
242                 flags |= MAP_ANON;
243                 pos = 0;
244         }
245
246         /*
247          * Align the file position to a page boundary,
248          * and save its page offset component.
249          */
250         pageoff = (pos & PAGE_MASK);
251         pos -= pageoff;
252
253         /* Adjust size for rounding (on both ends). */
254         size += pageoff;                        /* low end... */
255         size = (vm_size_t) round_page(size);    /* hi end */
256
257         /*
258          * Check for illegal addresses.  Watch out for address wrap... Note
259          * that VM_*_ADDRESS are not constants due to casts (argh).
260          */
261         if (flags & MAP_FIXED) {
262                 /*
263                  * The specified address must have the same remainder
264                  * as the file offset taken modulo PAGE_SIZE, so it
265                  * should be aligned after adjustment by pageoff.
266                  */
267                 addr -= pageoff;
268                 if (addr & PAGE_MASK)
269                         return (EINVAL);
270                 /* Address range must be all in user VM space. */
271                 if (addr < vm_map_min(&vms->vm_map) ||
272                     addr + size > vm_map_max(&vms->vm_map))
273                         return (EINVAL);
274                 if (addr + size < addr)
275                         return (EINVAL);
276         } else {
277         /*
278          * XXX for non-fixed mappings where no hint is provided or
279          * the hint would fall in the potential heap space,
280          * place it after the end of the largest possible heap.
281          *
282          * There should really be a pmap call to determine a reasonable
283          * location.
284          */
285                 PROC_LOCK(td->td_proc);
286                 if (addr == 0 ||
287                     (addr >= round_page((vm_offset_t)vms->vm_taddr) &&
288                     addr < round_page((vm_offset_t)vms->vm_daddr +
289                     lim_max(td->td_proc, RLIMIT_DATA))))
290                         addr = round_page((vm_offset_t)vms->vm_daddr +
291                             lim_max(td->td_proc, RLIMIT_DATA));
292                 PROC_UNLOCK(td->td_proc);
293         }
294         if (flags & MAP_ANON) {
295                 /*
296                  * Mapping blank space is trivial.
297                  */
298                 handle = NULL;
299                 handle_type = OBJT_DEFAULT;
300                 maxprot = VM_PROT_ALL;
301         } else {
302                 /*
303                  * Mapping file, get fp for validation and
304                  * don't let the descriptor disappear on us if we block.
305                  */
306                 if ((error = fget(td, uap->fd, &fp)) != 0)
307                         goto done;
308                 if (fp->f_type == DTYPE_SHM) {
309                         handle = fp->f_data;
310                         handle_type = OBJT_SWAP;
311                         maxprot = VM_PROT_NONE;
312
313                         /* FREAD should always be set. */
314                         if (fp->f_flag & FREAD)
315                                 maxprot |= VM_PROT_EXECUTE | VM_PROT_READ;
316                         if (fp->f_flag & FWRITE)
317                                 maxprot |= VM_PROT_WRITE;
318                         goto map;
319                 }
320                 if (fp->f_type != DTYPE_VNODE) {
321                         error = ENODEV;
322                         goto done;
323                 }
324 #if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \
325     defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4)
326                 /*
327                  * POSIX shared-memory objects are defined to have
328                  * kernel persistence, and are not defined to support
329                  * read(2)/write(2) -- or even open(2).  Thus, we can
330                  * use MAP_ASYNC to trade on-disk coherence for speed.
331                  * The shm_open(3) library routine turns on the FPOSIXSHM
332                  * flag to request this behavior.
333                  */
334                 if (fp->f_flag & FPOSIXSHM)
335                         flags |= MAP_NOSYNC;
336 #endif
337                 vp = fp->f_vnode;
338                 /*
339                  * Ensure that file and memory protections are
340                  * compatible.  Note that we only worry about
341                  * writability if mapping is shared; in this case,
342                  * current and max prot are dictated by the open file.
343                  * XXX use the vnode instead?  Problem is: what
344                  * credentials do we use for determination? What if
345                  * proc does a setuid?
346                  */
347                 if (vp->v_mount != NULL && vp->v_mount->mnt_flag & MNT_NOEXEC)
348                         maxprot = VM_PROT_NONE;
349                 else
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.
363                  */
364                 if ((flags & MAP_SHARED) != 0) {
365                         if ((fp->f_flag & FWRITE) != 0) {
366                                 maxprot |= VM_PROT_WRITE;
367                         } else if ((prot & PROT_WRITE) != 0) {
368                                 error = EACCES;
369                                 goto done;
370                         }
371                 } else if (vp->v_type != VCHR || (fp->f_flag & FWRITE) != 0) {
372                         maxprot |= VM_PROT_WRITE;
373                 }
374                 handle = (void *)vp;
375                 handle_type = OBJT_VNODE;
376         }
377 map:
378
379         /*
380          * Do not allow more then a certain number of vm_map_entry structures
381          * per process.  Scale with the number of rforks sharing the map
382          * to make the limit reasonable for threads.
383          */
384         if (max_proc_mmap &&
385             vms->vm_map.nentries >= max_proc_mmap * vms->vm_refcnt) {
386                 error = ENOMEM;
387                 goto done;
388         }
389
390         td->td_fpop = fp;
391         error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot,
392             flags, handle_type, handle, pos);
393         td->td_fpop = NULL;
394 #ifdef HWPMC_HOOKS
395         /* inform hwpmc(4) if an executable is being mapped */
396         if (error == 0 && handle_type == OBJT_VNODE &&
397             (prot & PROT_EXEC)) {
398                 pkm.pm_file = handle;
399                 pkm.pm_address = (uintptr_t) addr;
400                 PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm);
401         }
402 #endif
403         if (error == 0)
404                 td->td_retval[0] = (register_t) (addr + pageoff);
405 done:
406         if (fp)
407                 fdrop(fp, td);
408
409         return (error);
410 }
411
412 int
413 freebsd6_mmap(struct thread *td, struct freebsd6_mmap_args *uap)
414 {
415         struct mmap_args oargs;
416
417         oargs.addr = uap->addr;
418         oargs.len = uap->len;
419         oargs.prot = uap->prot;
420         oargs.flags = uap->flags;
421         oargs.fd = uap->fd;
422         oargs.pos = uap->pos;
423         return (mmap(td, &oargs));
424 }
425
426 #ifdef COMPAT_43
427 #ifndef _SYS_SYSPROTO_H_
428 struct ommap_args {
429         caddr_t addr;
430         int len;
431         int prot;
432         int flags;
433         int fd;
434         long pos;
435 };
436 #endif
437 int
438 ommap(td, uap)
439         struct thread *td;
440         struct ommap_args *uap;
441 {
442         struct mmap_args nargs;
443         static const char cvtbsdprot[8] = {
444                 0,
445                 PROT_EXEC,
446                 PROT_WRITE,
447                 PROT_EXEC | PROT_WRITE,
448                 PROT_READ,
449                 PROT_EXEC | PROT_READ,
450                 PROT_WRITE | PROT_READ,
451                 PROT_EXEC | PROT_WRITE | PROT_READ,
452         };
453
454 #define OMAP_ANON       0x0002
455 #define OMAP_COPY       0x0020
456 #define OMAP_SHARED     0x0010
457 #define OMAP_FIXED      0x0100
458
459         nargs.addr = uap->addr;
460         nargs.len = uap->len;
461         nargs.prot = cvtbsdprot[uap->prot & 0x7];
462         nargs.flags = 0;
463         if (uap->flags & OMAP_ANON)
464                 nargs.flags |= MAP_ANON;
465         if (uap->flags & OMAP_COPY)
466                 nargs.flags |= MAP_COPY;
467         if (uap->flags & OMAP_SHARED)
468                 nargs.flags |= MAP_SHARED;
469         else
470                 nargs.flags |= MAP_PRIVATE;
471         if (uap->flags & OMAP_FIXED)
472                 nargs.flags |= MAP_FIXED;
473         nargs.fd = uap->fd;
474         nargs.pos = uap->pos;
475         return (mmap(td, &nargs));
476 }
477 #endif                          /* COMPAT_43 */
478
479
480 #ifndef _SYS_SYSPROTO_H_
481 struct msync_args {
482         void *addr;
483         size_t len;
484         int flags;
485 };
486 #endif
487 /*
488  * MPSAFE
489  */
490 int
491 msync(td, uap)
492         struct thread *td;
493         struct msync_args *uap;
494 {
495         vm_offset_t addr;
496         vm_size_t size, pageoff;
497         int flags;
498         vm_map_t map;
499         int rv;
500
501         addr = (vm_offset_t) uap->addr;
502         size = uap->len;
503         flags = uap->flags;
504
505         pageoff = (addr & PAGE_MASK);
506         addr -= pageoff;
507         size += pageoff;
508         size = (vm_size_t) round_page(size);
509         if (addr + size < addr)
510                 return (EINVAL);
511
512         if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
513                 return (EINVAL);
514
515         map = &td->td_proc->p_vmspace->vm_map;
516
517         /*
518          * Clean the pages and interpret the return value.
519          */
520         rv = vm_map_sync(map, addr, addr + size, (flags & MS_ASYNC) == 0,
521             (flags & MS_INVALIDATE) != 0);
522         switch (rv) {
523         case KERN_SUCCESS:
524                 return (0);
525         case KERN_INVALID_ADDRESS:
526                 return (EINVAL);        /* Sun returns ENOMEM? */
527         case KERN_INVALID_ARGUMENT:
528                 return (EBUSY);
529         default:
530                 return (EINVAL);
531         }
532 }
533
534 #ifndef _SYS_SYSPROTO_H_
535 struct munmap_args {
536         void *addr;
537         size_t len;
538 };
539 #endif
540 /*
541  * MPSAFE
542  */
543 int
544 munmap(td, uap)
545         struct thread *td;
546         struct munmap_args *uap;
547 {
548 #ifdef HWPMC_HOOKS
549         struct pmckern_map_out pkm;
550         vm_map_entry_t entry;
551 #endif
552         vm_offset_t addr;
553         vm_size_t size, pageoff;
554         vm_map_t map;
555
556         addr = (vm_offset_t) uap->addr;
557         size = uap->len;
558         if (size == 0)
559                 return (EINVAL);
560
561         pageoff = (addr & PAGE_MASK);
562         addr -= pageoff;
563         size += pageoff;
564         size = (vm_size_t) round_page(size);
565         if (addr + size < addr)
566                 return (EINVAL);
567
568         /*
569          * Check for illegal addresses.  Watch out for address wrap...
570          */
571         map = &td->td_proc->p_vmspace->vm_map;
572         if (addr < vm_map_min(map) || addr + size > vm_map_max(map))
573                 return (EINVAL);
574         vm_map_lock(map);
575 #ifdef HWPMC_HOOKS
576         /*
577          * Inform hwpmc if the address range being unmapped contains
578          * an executable region.
579          */
580         pkm.pm_address = (uintptr_t) NULL;
581         if (vm_map_lookup_entry(map, addr, &entry)) {
582                 for (;
583                      entry != &map->header && entry->start < addr + size;
584                      entry = entry->next) {
585                         if (vm_map_check_protection(map, entry->start,
586                                 entry->end, VM_PROT_EXECUTE) == TRUE) {
587                                 pkm.pm_address = (uintptr_t) addr;
588                                 pkm.pm_size = (size_t) size;
589                                 break;
590                         }
591                 }
592         }
593 #endif
594         vm_map_delete(map, addr, addr + size);
595
596 #ifdef HWPMC_HOOKS
597         /* downgrade the lock to prevent a LOR with the pmc-sx lock */
598         vm_map_lock_downgrade(map);
599         if (pkm.pm_address != (uintptr_t) NULL)
600                 PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm);
601         vm_map_unlock_read(map);
602 #else
603         vm_map_unlock(map);
604 #endif
605         /* vm_map_delete returns nothing but KERN_SUCCESS anyway */
606         return (0);
607 }
608
609 #ifndef _SYS_SYSPROTO_H_
610 struct mprotect_args {
611         const void *addr;
612         size_t len;
613         int prot;
614 };
615 #endif
616 /*
617  * MPSAFE
618  */
619 int
620 mprotect(td, uap)
621         struct thread *td;
622         struct mprotect_args *uap;
623 {
624         vm_offset_t addr;
625         vm_size_t size, pageoff;
626         vm_prot_t prot;
627
628         addr = (vm_offset_t) uap->addr;
629         size = uap->len;
630         prot = uap->prot & VM_PROT_ALL;
631
632         pageoff = (addr & PAGE_MASK);
633         addr -= pageoff;
634         size += pageoff;
635         size = (vm_size_t) round_page(size);
636         if (addr + size < addr)
637                 return (EINVAL);
638
639         switch (vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr,
640             addr + size, prot, FALSE)) {
641         case KERN_SUCCESS:
642                 return (0);
643         case KERN_PROTECTION_FAILURE:
644                 return (EACCES);
645         case KERN_RESOURCE_SHORTAGE:
646                 return (ENOMEM);
647         }
648         return (EINVAL);
649 }
650
651 #ifndef _SYS_SYSPROTO_H_
652 struct minherit_args {
653         void *addr;
654         size_t len;
655         int inherit;
656 };
657 #endif
658 /*
659  * MPSAFE
660  */
661 int
662 minherit(td, uap)
663         struct thread *td;
664         struct minherit_args *uap;
665 {
666         vm_offset_t addr;
667         vm_size_t size, pageoff;
668         vm_inherit_t inherit;
669
670         addr = (vm_offset_t)uap->addr;
671         size = uap->len;
672         inherit = uap->inherit;
673
674         pageoff = (addr & PAGE_MASK);
675         addr -= pageoff;
676         size += pageoff;
677         size = (vm_size_t) round_page(size);
678         if (addr + size < addr)
679                 return (EINVAL);
680
681         switch (vm_map_inherit(&td->td_proc->p_vmspace->vm_map, addr,
682             addr + size, inherit)) {
683         case KERN_SUCCESS:
684                 return (0);
685         case KERN_PROTECTION_FAILURE:
686                 return (EACCES);
687         }
688         return (EINVAL);
689 }
690
691 #ifndef _SYS_SYSPROTO_H_
692 struct madvise_args {
693         void *addr;
694         size_t len;
695         int behav;
696 };
697 #endif
698
699 /*
700  * MPSAFE
701  */
702 /* ARGSUSED */
703 int
704 madvise(td, uap)
705         struct thread *td;
706         struct madvise_args *uap;
707 {
708         vm_offset_t start, end;
709         vm_map_t map;
710         struct proc *p;
711         int error;
712
713         /*
714          * Check for our special case, advising the swap pager we are
715          * "immortal."
716          */
717         if (uap->behav == MADV_PROTECT) {
718                 error = priv_check(td, PRIV_VM_MADV_PROTECT);
719                 if (error == 0) {
720                         p = td->td_proc;
721                         PROC_LOCK(p);
722                         p->p_flag |= P_PROTECTED;
723                         PROC_UNLOCK(p);
724                 }
725                 return (error);
726         }
727         /*
728          * Check for illegal behavior
729          */
730         if (uap->behav < 0 || uap->behav > MADV_CORE)
731                 return (EINVAL);
732         /*
733          * Check for illegal addresses.  Watch out for address wrap... Note
734          * that VM_*_ADDRESS are not constants due to casts (argh).
735          */
736         map = &td->td_proc->p_vmspace->vm_map;
737         if ((vm_offset_t)uap->addr < vm_map_min(map) ||
738             (vm_offset_t)uap->addr + uap->len > vm_map_max(map))
739                 return (EINVAL);
740         if (((vm_offset_t) uap->addr + uap->len) < (vm_offset_t) uap->addr)
741                 return (EINVAL);
742
743         /*
744          * Since this routine is only advisory, we default to conservative
745          * behavior.
746          */
747         start = trunc_page((vm_offset_t) uap->addr);
748         end = round_page((vm_offset_t) uap->addr + uap->len);
749
750         if (vm_map_madvise(map, start, end, uap->behav))
751                 return (EINVAL);
752         return (0);
753 }
754
755 #ifndef _SYS_SYSPROTO_H_
756 struct mincore_args {
757         const void *addr;
758         size_t len;
759         char *vec;
760 };
761 #endif
762
763 /*
764  * MPSAFE
765  */
766 /* ARGSUSED */
767 int
768 mincore(td, uap)
769         struct thread *td;
770         struct mincore_args *uap;
771 {
772         vm_offset_t addr, first_addr;
773         vm_offset_t end, cend;
774         pmap_t pmap;
775         vm_map_t map;
776         char *vec;
777         int error = 0;
778         int vecindex, lastvecindex;
779         vm_map_entry_t current;
780         vm_map_entry_t entry;
781         int mincoreinfo;
782         unsigned int timestamp;
783
784         /*
785          * Make sure that the addresses presented are valid for user
786          * mode.
787          */
788         first_addr = addr = trunc_page((vm_offset_t) uap->addr);
789         end = addr + (vm_size_t)round_page(uap->len);
790         map = &td->td_proc->p_vmspace->vm_map;
791         if (end > vm_map_max(map) || end < addr)
792                 return (ENOMEM);
793
794         /*
795          * Address of byte vector
796          */
797         vec = uap->vec;
798
799         pmap = vmspace_pmap(td->td_proc->p_vmspace);
800
801         vm_map_lock_read(map);
802 RestartScan:
803         timestamp = map->timestamp;
804
805         if (!vm_map_lookup_entry(map, addr, &entry)) {
806                 vm_map_unlock_read(map);
807                 return (ENOMEM);
808         }
809
810         /*
811          * Do this on a map entry basis so that if the pages are not
812          * in the current processes address space, we can easily look
813          * up the pages elsewhere.
814          */
815         lastvecindex = -1;
816         for (current = entry;
817             (current != &map->header) && (current->start < end);
818             current = current->next) {
819
820                 /*
821                  * check for contiguity
822                  */
823                 if (current->end < end &&
824                     (entry->next == &map->header ||
825                      current->next->start > current->end)) {
826                         vm_map_unlock_read(map);
827                         return (ENOMEM);
828                 }
829
830                 /*
831                  * ignore submaps (for now) or null objects
832                  */
833                 if ((current->eflags & MAP_ENTRY_IS_SUB_MAP) ||
834                         current->object.vm_object == NULL)
835                         continue;
836
837                 /*
838                  * limit this scan to the current map entry and the
839                  * limits for the mincore call
840                  */
841                 if (addr < current->start)
842                         addr = current->start;
843                 cend = current->end;
844                 if (cend > end)
845                         cend = end;
846
847                 /*
848                  * scan this entry one page at a time
849                  */
850                 while (addr < cend) {
851                         /*
852                          * Check pmap first, it is likely faster, also
853                          * it can provide info as to whether we are the
854                          * one referencing or modifying the page.
855                          */
856                         mincoreinfo = pmap_mincore(pmap, addr);
857                         if (!mincoreinfo) {
858                                 vm_pindex_t pindex;
859                                 vm_ooffset_t offset;
860                                 vm_page_t m;
861                                 /*
862                                  * calculate the page index into the object
863                                  */
864                                 offset = current->offset + (addr - current->start);
865                                 pindex = OFF_TO_IDX(offset);
866                                 VM_OBJECT_LOCK(current->object.vm_object);
867                                 m = vm_page_lookup(current->object.vm_object,
868                                         pindex);
869                                 /*
870                                  * if the page is resident, then gather information about
871                                  * it.
872                                  */
873                                 if (m != NULL && m->valid != 0) {
874                                         mincoreinfo = MINCORE_INCORE;
875                                         vm_page_lock_queues();
876                                         if (m->dirty ||
877                                                 pmap_is_modified(m))
878                                                 mincoreinfo |= MINCORE_MODIFIED_OTHER;
879                                         if ((m->flags & PG_REFERENCED) ||
880                                                 pmap_ts_referenced(m)) {
881                                                 vm_page_flag_set(m, PG_REFERENCED);
882                                                 mincoreinfo |= MINCORE_REFERENCED_OTHER;
883                                         }
884                                         vm_page_unlock_queues();
885                                 }
886                                 VM_OBJECT_UNLOCK(current->object.vm_object);
887                         }
888
889                         /*
890                          * subyte may page fault.  In case it needs to modify
891                          * the map, we release the lock.
892                          */
893                         vm_map_unlock_read(map);
894
895                         /*
896                          * calculate index into user supplied byte vector
897                          */
898                         vecindex = OFF_TO_IDX(addr - first_addr);
899
900                         /*
901                          * If we have skipped map entries, we need to make sure that
902                          * the byte vector is zeroed for those skipped entries.
903                          */
904                         while ((lastvecindex + 1) < vecindex) {
905                                 error = subyte(vec + lastvecindex, 0);
906                                 if (error) {
907                                         error = EFAULT;
908                                         goto done2;
909                                 }
910                                 ++lastvecindex;
911                         }
912
913                         /*
914                          * Pass the page information to the user
915                          */
916                         error = subyte(vec + vecindex, mincoreinfo);
917                         if (error) {
918                                 error = EFAULT;
919                                 goto done2;
920                         }
921
922                         /*
923                          * If the map has changed, due to the subyte, the previous
924                          * output may be invalid.
925                          */
926                         vm_map_lock_read(map);
927                         if (timestamp != map->timestamp)
928                                 goto RestartScan;
929
930                         lastvecindex = vecindex;
931                         addr += PAGE_SIZE;
932                 }
933         }
934
935         /*
936          * subyte may page fault.  In case it needs to modify
937          * the map, we release the lock.
938          */
939         vm_map_unlock_read(map);
940
941         /*
942          * Zero the last entries in the byte vector.
943          */
944         vecindex = OFF_TO_IDX(end - first_addr);
945         while ((lastvecindex + 1) < vecindex) {
946                 error = subyte(vec + lastvecindex, 0);
947                 if (error) {
948                         error = EFAULT;
949                         goto done2;
950                 }
951                 ++lastvecindex;
952         }
953
954         /*
955          * If the map has changed, due to the subyte, the previous
956          * output may be invalid.
957          */
958         vm_map_lock_read(map);
959         if (timestamp != map->timestamp)
960                 goto RestartScan;
961         vm_map_unlock_read(map);
962 done2:
963         return (error);
964 }
965
966 #ifndef _SYS_SYSPROTO_H_
967 struct mlock_args {
968         const void *addr;
969         size_t len;
970 };
971 #endif
972 /*
973  * MPSAFE
974  */
975 int
976 mlock(td, uap)
977         struct thread *td;
978         struct mlock_args *uap;
979 {
980         struct proc *proc;
981         vm_offset_t addr, end, last, start;
982         vm_size_t npages, size;
983         int error;
984
985         error = priv_check(td, PRIV_VM_MLOCK);
986         if (error)
987                 return (error);
988         addr = (vm_offset_t)uap->addr;
989         size = uap->len;
990         last = addr + size;
991         start = trunc_page(addr);
992         end = round_page(last);
993         if (last < addr || end < addr)
994                 return (EINVAL);
995         npages = atop(end - start);
996         if (npages > vm_page_max_wired)
997                 return (ENOMEM);
998         proc = td->td_proc;
999         PROC_LOCK(proc);
1000         if (ptoa(npages +
1001             pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) >
1002             lim_cur(proc, RLIMIT_MEMLOCK)) {
1003                 PROC_UNLOCK(proc);
1004                 return (ENOMEM);
1005         }
1006         PROC_UNLOCK(proc);
1007         if (npages + cnt.v_wire_count > vm_page_max_wired)
1008                 return (EAGAIN);
1009         error = vm_map_wire(&proc->p_vmspace->vm_map, start, end,
1010             VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
1011         return (error == KERN_SUCCESS ? 0 : ENOMEM);
1012 }
1013
1014 #ifndef _SYS_SYSPROTO_H_
1015 struct mlockall_args {
1016         int     how;
1017 };
1018 #endif
1019
1020 /*
1021  * MPSAFE
1022  */
1023 int
1024 mlockall(td, uap)
1025         struct thread *td;
1026         struct mlockall_args *uap;
1027 {
1028         vm_map_t map;
1029         int error;
1030
1031         map = &td->td_proc->p_vmspace->vm_map;
1032         error = 0;
1033
1034         if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0))
1035                 return (EINVAL);
1036
1037 #if 0
1038         /*
1039          * If wiring all pages in the process would cause it to exceed
1040          * a hard resource limit, return ENOMEM.
1041          */
1042         PROC_LOCK(td->td_proc);
1043         if (map->size - ptoa(pmap_wired_count(vm_map_pmap(map)) >
1044                 lim_cur(td->td_proc, RLIMIT_MEMLOCK))) {
1045                 PROC_UNLOCK(td->td_proc);
1046                 return (ENOMEM);
1047         }
1048         PROC_UNLOCK(td->td_proc);
1049 #else
1050         error = priv_check(td, PRIV_VM_MLOCK);
1051         if (error)
1052                 return (error);
1053 #endif
1054
1055         if (uap->how & MCL_FUTURE) {
1056                 vm_map_lock(map);
1057                 vm_map_modflags(map, MAP_WIREFUTURE, 0);
1058                 vm_map_unlock(map);
1059                 error = 0;
1060         }
1061
1062         if (uap->how & MCL_CURRENT) {
1063                 /*
1064                  * P1003.1-2001 mandates that all currently mapped pages
1065                  * will be memory resident and locked (wired) upon return
1066                  * from mlockall(). vm_map_wire() will wire pages, by
1067                  * calling vm_fault_wire() for each page in the region.
1068                  */
1069                 error = vm_map_wire(map, vm_map_min(map), vm_map_max(map),
1070                     VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
1071                 error = (error == KERN_SUCCESS ? 0 : EAGAIN);
1072         }
1073
1074         return (error);
1075 }
1076
1077 #ifndef _SYS_SYSPROTO_H_
1078 struct munlockall_args {
1079         register_t dummy;
1080 };
1081 #endif
1082
1083 /*
1084  * MPSAFE
1085  */
1086 int
1087 munlockall(td, uap)
1088         struct thread *td;
1089         struct munlockall_args *uap;
1090 {
1091         vm_map_t map;
1092         int error;
1093
1094         map = &td->td_proc->p_vmspace->vm_map;
1095         error = priv_check(td, PRIV_VM_MUNLOCK);
1096         if (error)
1097                 return (error);
1098
1099         /* Clear the MAP_WIREFUTURE flag from this vm_map. */
1100         vm_map_lock(map);
1101         vm_map_modflags(map, 0, MAP_WIREFUTURE);
1102         vm_map_unlock(map);
1103
1104         /* Forcibly unwire all pages. */
1105         error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map),
1106             VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
1107
1108         return (error);
1109 }
1110
1111 #ifndef _SYS_SYSPROTO_H_
1112 struct munlock_args {
1113         const void *addr;
1114         size_t len;
1115 };
1116 #endif
1117 /*
1118  * MPSAFE
1119  */
1120 int
1121 munlock(td, uap)
1122         struct thread *td;
1123         struct munlock_args *uap;
1124 {
1125         vm_offset_t addr, end, last, start;
1126         vm_size_t size;
1127         int error;
1128
1129         error = priv_check(td, PRIV_VM_MUNLOCK);
1130         if (error)
1131                 return (error);
1132         addr = (vm_offset_t)uap->addr;
1133         size = uap->len;
1134         last = addr + size;
1135         start = trunc_page(addr);
1136         end = round_page(last);
1137         if (last < addr || end < addr)
1138                 return (EINVAL);
1139         error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end,
1140             VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
1141         return (error == KERN_SUCCESS ? 0 : ENOMEM);
1142 }
1143
1144 /*
1145  * vm_mmap_vnode()
1146  *
1147  * MPSAFE
1148  *
1149  * Helper function for vm_mmap.  Perform sanity check specific for mmap
1150  * operations on vnodes.
1151  */
1152 int
1153 vm_mmap_vnode(struct thread *td, vm_size_t objsize,
1154     vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
1155     struct vnode *vp, vm_ooffset_t *foffp, vm_object_t *objp)
1156 {
1157         struct vattr va;
1158         vm_object_t obj;
1159         vm_offset_t foff;
1160         struct mount *mp;
1161         struct ucred *cred;
1162         int error, flags;
1163         int vfslocked;
1164
1165         mp = vp->v_mount;
1166         cred = td->td_ucred;
1167         vfslocked = VFS_LOCK_GIANT(mp);
1168         if ((error = vget(vp, LK_SHARED, td)) != 0) {
1169                 VFS_UNLOCK_GIANT(vfslocked);
1170                 return (error);
1171         }
1172         foff = *foffp;
1173         flags = *flagsp;
1174         obj = vp->v_object;
1175         if (vp->v_type == VREG) {
1176                 /*
1177                  * Get the proper underlying object
1178                  */
1179                 if (obj == NULL) {
1180                         error = EINVAL;
1181                         goto done;
1182                 }
1183                 if (obj->handle != vp) {
1184                         vput(vp);
1185                         vp = (struct vnode*)obj->handle;
1186                         vget(vp, LK_SHARED, td);
1187                 }
1188         } else if (vp->v_type == VCHR) {
1189                 error = vm_mmap_cdev(td, objsize, prot, maxprotp, flagsp,
1190                     vp->v_rdev, foffp, objp);
1191                 if (error == 0)
1192                         goto mark_atime;
1193                 goto done;
1194         } else {
1195                 error = EINVAL;
1196                 goto done;
1197         }
1198         if ((error = VOP_GETATTR(vp, &va, cred)))
1199                 goto done;
1200 #ifdef MAC
1201         error = mac_vnode_check_mmap(cred, vp, prot, flags);
1202         if (error != 0)
1203                 goto done;
1204 #endif
1205         if ((flags & MAP_SHARED) != 0) {
1206                 if ((va.va_flags & (SF_SNAPSHOT|IMMUTABLE|APPEND)) != 0) {
1207                         if (prot & PROT_WRITE) {
1208                                 error = EPERM;
1209                                 goto done;
1210                         }
1211                         *maxprotp &= ~VM_PROT_WRITE;
1212                 }
1213         }
1214         /*
1215          * If it is a regular file without any references
1216          * we do not need to sync it.
1217          * Adjust object size to be the size of actual file.
1218          */
1219         objsize = round_page(va.va_size);
1220         if (va.va_nlink == 0)
1221                 flags |= MAP_NOSYNC;
1222         obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, td->td_ucred);
1223         if (obj == NULL) {
1224                 error = ENOMEM;
1225                 goto done;
1226         }
1227         *objp = obj;
1228         *flagsp = flags;
1229
1230 mark_atime:
1231         vfs_mark_atime(vp, cred);
1232
1233 done:
1234         vput(vp);
1235         VFS_UNLOCK_GIANT(vfslocked);
1236         return (error);
1237 }
1238
1239 /*
1240  * vm_mmap_cdev()
1241  *
1242  * MPSAFE
1243  *
1244  * Helper function for vm_mmap.  Perform sanity check specific for mmap
1245  * operations on cdevs.
1246  */
1247 int
1248 vm_mmap_cdev(struct thread *td, vm_size_t objsize,
1249     vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
1250     struct cdev *cdev, vm_ooffset_t *foff, vm_object_t *objp)
1251 {
1252         vm_object_t obj;
1253         struct cdevsw *dsw;
1254         int error, flags, ref;
1255
1256         flags = *flagsp;
1257
1258         dsw = dev_refthread(cdev, &ref);
1259         if (dsw == NULL)
1260                 return (ENXIO);
1261         if (dsw->d_flags & D_MMAP_ANON) {
1262                 dev_relthread(cdev, ref);
1263                 *maxprotp = VM_PROT_ALL;
1264                 *flagsp |= MAP_ANON;
1265                 return (0);
1266         }
1267         /*
1268          * cdevs do not provide private mappings of any kind.
1269          */
1270         if ((*maxprotp & VM_PROT_WRITE) == 0 &&
1271             (prot & PROT_WRITE) != 0) {
1272                 dev_relthread(cdev, ref);
1273                 return (EACCES);
1274         }
1275         if (flags & (MAP_PRIVATE|MAP_COPY)) {
1276                 dev_relthread(cdev, ref);
1277                 return (EINVAL);
1278         }
1279         /*
1280          * Force device mappings to be shared.
1281          */
1282         flags |= MAP_SHARED;
1283 #ifdef MAC_XXX
1284         error = mac_cdev_check_mmap(td->td_ucred, cdev, prot);
1285         if (error != 0) {
1286                 dev_relthread(cdev, ref);
1287                 return (error);
1288         }
1289 #endif
1290         /*
1291          * First, try d_mmap_single().  If that is not implemented
1292          * (returns ENODEV), fall back to using the device pager.
1293          * Note that d_mmap_single() must return a reference to the
1294          * object (it needs to bump the reference count of the object
1295          * it returns somehow).
1296          *
1297          * XXX assumes VM_PROT_* == PROT_*
1298          */
1299         error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot);
1300         dev_relthread(cdev, ref);
1301         if (error != ENODEV)
1302                 return (error);
1303         obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff,
1304             td->td_ucred);
1305         if (obj == NULL)
1306                 return (EINVAL);
1307         *objp = obj;
1308         *flagsp = flags;
1309         return (0);
1310 }
1311
1312 /*
1313  * vm_mmap_shm()
1314  *
1315  * MPSAFE
1316  *
1317  * Helper function for vm_mmap.  Perform sanity check specific for mmap
1318  * operations on shm file descriptors.
1319  */
1320 int
1321 vm_mmap_shm(struct thread *td, vm_size_t objsize,
1322     vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp,
1323     struct shmfd *shmfd, vm_ooffset_t foff, vm_object_t *objp)
1324 {
1325         int error;
1326
1327         if ((*flagsp & MAP_SHARED) != 0 &&
1328             (*maxprotp & VM_PROT_WRITE) == 0 &&
1329             (prot & PROT_WRITE) != 0)
1330                 return (EACCES);
1331 #ifdef MAC
1332         error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, *flagsp);
1333         if (error != 0)
1334                 return (error);
1335 #endif
1336         error = shm_mmap(shmfd, objsize, foff, objp);
1337         if (error)
1338                 return (error);
1339         return (0);
1340 }
1341
1342 /*
1343  * vm_mmap()
1344  *
1345  * MPSAFE
1346  *
1347  * Internal version of mmap.  Currently used by mmap, exec, and sys5
1348  * shared memory.  Handle is either a vnode pointer or NULL for MAP_ANON.
1349  */
1350 int
1351 vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot,
1352         vm_prot_t maxprot, int flags,
1353         objtype_t handle_type, void *handle,
1354         vm_ooffset_t foff)
1355 {
1356         boolean_t fitit;
1357         vm_object_t object = NULL;
1358         int rv = KERN_SUCCESS;
1359         int docow, error;
1360         struct thread *td = curthread;
1361
1362         if (size == 0)
1363                 return (0);
1364
1365         size = round_page(size);
1366
1367         PROC_LOCK(td->td_proc);
1368         if (td->td_proc->p_vmspace->vm_map.size + size >
1369             lim_cur(td->td_proc, RLIMIT_VMEM)) {
1370                 PROC_UNLOCK(td->td_proc);
1371                 return(ENOMEM);
1372         }
1373         PROC_UNLOCK(td->td_proc);
1374
1375         /*
1376          * We currently can only deal with page aligned file offsets.
1377          * The check is here rather than in the syscall because the
1378          * kernel calls this function internally for other mmaping
1379          * operations (such as in exec) and non-aligned offsets will
1380          * cause pmap inconsistencies...so we want to be sure to
1381          * disallow this in all cases.
1382          */
1383         if (foff & PAGE_MASK)
1384                 return (EINVAL);
1385
1386         if ((flags & MAP_FIXED) == 0) {
1387                 fitit = TRUE;
1388                 *addr = round_page(*addr);
1389         } else {
1390                 if (*addr != trunc_page(*addr))
1391                         return (EINVAL);
1392                 fitit = FALSE;
1393         }
1394         /*
1395          * Lookup/allocate object.
1396          */
1397         switch (handle_type) {
1398         case OBJT_DEVICE:
1399                 error = vm_mmap_cdev(td, size, prot, &maxprot, &flags,
1400                     handle, &foff, &object);
1401                 break;
1402         case OBJT_VNODE:
1403                 error = vm_mmap_vnode(td, size, prot, &maxprot, &flags,
1404                     handle, &foff, &object);
1405                 break;
1406         case OBJT_SWAP:
1407                 error = vm_mmap_shm(td, size, prot, &maxprot, &flags,
1408                     handle, foff, &object);
1409                 break;
1410         case OBJT_DEFAULT:
1411                 if (handle == NULL) {
1412                         error = 0;
1413                         break;
1414                 }
1415                 /* FALLTHROUGH */
1416         default:
1417                 error = EINVAL;
1418                 break;
1419         }
1420         if (error)
1421                 return (error);
1422         if (flags & MAP_ANON) {
1423                 object = NULL;
1424                 docow = 0;
1425                 /*
1426                  * Unnamed anonymous regions always start at 0.
1427                  */
1428                 if (handle == 0)
1429                         foff = 0;
1430         } else {
1431                 docow = MAP_PREFAULT_PARTIAL;
1432         }
1433
1434         if ((flags & (MAP_ANON|MAP_SHARED)) == 0)
1435                 docow |= MAP_COPY_ON_WRITE;
1436         if (flags & MAP_NOSYNC)
1437                 docow |= MAP_DISABLE_SYNCER;
1438         if (flags & MAP_NOCORE)
1439                 docow |= MAP_DISABLE_COREDUMP;
1440
1441         if (flags & MAP_STACK)
1442                 rv = vm_map_stack(map, *addr, size, prot, maxprot,
1443                     docow | MAP_STACK_GROWS_DOWN);
1444         else if (fitit)
1445                 rv = vm_map_find(map, object, foff, addr, size,
1446                     object != NULL && object->type == OBJT_DEVICE ?
1447                     VMFS_ALIGNED_SPACE : VMFS_ANY_SPACE, prot, maxprot, docow);
1448         else
1449                 rv = vm_map_fixed(map, object, foff, *addr, size,
1450                                  prot, maxprot, docow);
1451
1452         if (rv != KERN_SUCCESS) {
1453                 /*
1454                  * Lose the object reference. Will destroy the
1455                  * object if it's an unnamed anonymous mapping
1456                  * or named anonymous without other references.
1457                  */
1458                 vm_object_deallocate(object);
1459         } else if (flags & MAP_SHARED) {
1460                 /*
1461                  * Shared memory is also shared with children.
1462                  */
1463                 rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE);
1464                 if (rv != KERN_SUCCESS)
1465                         (void) vm_map_remove(map, *addr, *addr + size);
1466         }
1467
1468         /*
1469          * If the process has requested that all future mappings
1470          * be wired, then heed this.
1471          */
1472         if ((rv == KERN_SUCCESS) && (map->flags & MAP_WIREFUTURE))
1473                 vm_map_wire(map, *addr, *addr + size,
1474                     VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
1475
1476         switch (rv) {
1477         case KERN_SUCCESS:
1478                 return (0);
1479         case KERN_INVALID_ADDRESS:
1480         case KERN_NO_SPACE:
1481                 return (ENOMEM);
1482         case KERN_PROTECTION_FAILURE:
1483                 return (EACCES);
1484         default:
1485                 return (EINVAL);
1486         }
1487 }