xref: /freebsd/sys/vm/vm_mmap.c (revision 05c7a37afb48ddd5ee1bd921a5d46fe59cc70b15)
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  * $Id: vm_mmap.c,v 1.39 1996/03/12 02:27:20 dyson Exp $
42  */
43 
44 /*
45  * Mapped file (mmap) interface to VM
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/sysproto.h>
51 #include <sys/filedesc.h>
52 #include <sys/resourcevar.h>
53 #include <sys/proc.h>
54 #include <sys/vnode.h>
55 #include <sys/file.h>
56 #include <sys/mman.h>
57 #include <sys/conf.h>
58 #include <sys/vmmeter.h>
59 
60 #include <miscfs/specfs/specdev.h>
61 
62 #include <vm/vm.h>
63 #include <vm/vm_param.h>
64 #include <vm/vm_prot.h>
65 #include <vm/vm_inherit.h>
66 #include <vm/lock.h>
67 #include <vm/pmap.h>
68 #include <vm/vm_map.h>
69 #include <vm/vm_object.h>
70 #include <vm/vm_pager.h>
71 #include <vm/vm_pageout.h>
72 #include <vm/vm_extern.h>
73 #include <vm/vm_kern.h>
74 
75 #ifndef _SYS_SYSPROTO_H_
76 struct sbrk_args {
77 	int incr;
78 };
79 #endif
80 
81 /* ARGSUSED */
82 int
83 sbrk(p, uap, retval)
84 	struct proc *p;
85 	struct sbrk_args *uap;
86 	int *retval;
87 {
88 
89 	/* Not yet implemented */
90 	return (EOPNOTSUPP);
91 }
92 
93 #ifndef _SYS_SYSPROTO_H_
94 struct sstk_args {
95 	int incr;
96 };
97 #endif
98 
99 /* ARGSUSED */
100 int
101 sstk(p, uap, retval)
102 	struct proc *p;
103 	struct sstk_args *uap;
104 	int *retval;
105 {
106 
107 	/* Not yet implemented */
108 	return (EOPNOTSUPP);
109 }
110 
111 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
112 #ifndef _SYS_SYSPROTO_H_
113 struct getpagesize_args {
114 	int dummy;
115 };
116 #endif
117 
118 /* ARGSUSED */
119 int
120 ogetpagesize(p, uap, retval)
121 	struct proc *p;
122 	struct getpagesize_args *uap;
123 	int *retval;
124 {
125 
126 	*retval = PAGE_SIZE;
127 	return (0);
128 }
129 #endif				/* COMPAT_43 || COMPAT_SUNOS */
130 
131 #ifndef _SYS_SYSPROTO_H_
132 struct mmap_args {
133 	caddr_t addr;
134 	size_t len;
135 	int prot;
136 	int flags;
137 	int fd;
138 	long pad;
139 	off_t pos;
140 };
141 #endif
142 
143 int
144 mmap(p, uap, retval)
145 	struct proc *p;
146 	register struct mmap_args *uap;
147 	int *retval;
148 {
149 	register struct filedesc *fdp = p->p_fd;
150 	register struct file *fp;
151 	struct vnode *vp;
152 	vm_offset_t addr;
153 	vm_size_t size, pageoff;
154 	vm_prot_t prot, maxprot;
155 	caddr_t handle;
156 	int flags, error;
157 
158 	prot = uap->prot & VM_PROT_ALL;
159 	flags = uap->flags;
160 	/*
161 	 * Address (if FIXED) must be page aligned. Size is implicitly rounded
162 	 * to a page boundary.
163 	 */
164 	addr = (vm_offset_t) uap->addr;
165 	if (((flags & MAP_FIXED) && (addr & PAGE_MASK)) ||
166 	    (ssize_t) uap->len < 0 || ((flags & MAP_ANON) && uap->fd != -1))
167 		return (EINVAL);
168 
169 	/*
170 	 * Round page if not already disallowed by above test
171 	 * XXX: Is there any point in the MAP_FIXED align requirement above?
172 	 */
173 	size = uap->len;
174 	pageoff = (addr & PAGE_MASK);
175 	addr -= pageoff;
176 	size += pageoff;
177 	size = (vm_size_t) round_page(size);
178 
179 	/*
180 	 * Check for illegal addresses.  Watch out for address wrap... Note
181 	 * that VM_*_ADDRESS are not constants due to casts (argh).
182 	 */
183 	if (flags & MAP_FIXED) {
184 		if (VM_MAXUSER_ADDRESS > 0 && addr + size > VM_MAXUSER_ADDRESS)
185 			return (EINVAL);
186 #ifndef i386
187 		if (VM_MIN_ADDRESS > 0 && addr < VM_MIN_ADDRESS)
188 			return (EINVAL);
189 #endif
190 		if (addr + size < addr)
191 			return (EINVAL);
192 	}
193 	/*
194 	 * XXX if no hint provided for a non-fixed mapping place it after the
195 	 * end of the largest possible heap.
196 	 *
197 	 * There should really be a pmap call to determine a reasonable location.
198 	 */
199 	if (addr == 0 && (flags & MAP_FIXED) == 0)
200 		addr = round_page(p->p_vmspace->vm_daddr + MAXDSIZ);
201 	if (flags & MAP_ANON) {
202 		/*
203 		 * Mapping blank space is trivial.
204 		 */
205 		handle = NULL;
206 		maxprot = VM_PROT_ALL;
207 	} else {
208 		/*
209 		 * Mapping file, get fp for validation. Obtain vnode and make
210 		 * sure it is of appropriate type.
211 		 */
212 		if (((unsigned) uap->fd) >= fdp->fd_nfiles ||
213 		    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
214 			return (EBADF);
215 		if (fp->f_type != DTYPE_VNODE)
216 			return (EINVAL);
217 		vp = (struct vnode *) fp->f_data;
218 		if (vp->v_type != VREG && vp->v_type != VCHR)
219 			return (EINVAL);
220 		/*
221 		 * XXX hack to handle use of /dev/zero to map anon memory (ala
222 		 * SunOS).
223 		 */
224 		if (vp->v_type == VCHR && iszerodev(vp->v_rdev)) {
225 			handle = NULL;
226 			maxprot = VM_PROT_ALL;
227 			flags |= MAP_ANON;
228 		} else {
229 			/*
230 			 * Ensure that file and memory protections are
231 			 * compatible.  Note that we only worry about
232 			 * writability if mapping is shared; in this case,
233 			 * current and max prot are dictated by the open file.
234 			 * XXX use the vnode instead?  Problem is: what
235 			 * credentials do we use for determination? What if
236 			 * proc does a setuid?
237 			 */
238 			maxprot = VM_PROT_EXECUTE;	/* ??? */
239 			if (fp->f_flag & FREAD)
240 				maxprot |= VM_PROT_READ;
241 			else if (prot & PROT_READ)
242 				return (EACCES);
243 			if (flags & MAP_SHARED) {
244 				if (fp->f_flag & FWRITE)
245 					maxprot |= VM_PROT_WRITE;
246 				else if (prot & PROT_WRITE)
247 					return (EACCES);
248 			} else
249 				maxprot |= VM_PROT_WRITE;
250 			handle = (caddr_t) vp;
251 		}
252 	}
253 	error = vm_mmap(&p->p_vmspace->vm_map, &addr, size, prot, maxprot,
254 	    flags, handle, uap->pos);
255 	if (error == 0)
256 		*retval = (int) addr;
257 	return (error);
258 }
259 
260 #ifdef COMPAT_43
261 #ifndef _SYS_SYSPROTO_H_
262 struct ommap_args {
263 	caddr_t addr;
264 	int len;
265 	int prot;
266 	int flags;
267 	int fd;
268 	long pos;
269 };
270 #endif
271 int
272 ommap(p, uap, retval)
273 	struct proc *p;
274 	register struct ommap_args *uap;
275 	int *retval;
276 {
277 	struct mmap_args nargs;
278 	static const char cvtbsdprot[8] = {
279 		0,
280 		PROT_EXEC,
281 		PROT_WRITE,
282 		PROT_EXEC | PROT_WRITE,
283 		PROT_READ,
284 		PROT_EXEC | PROT_READ,
285 		PROT_WRITE | PROT_READ,
286 		PROT_EXEC | PROT_WRITE | PROT_READ,
287 	};
288 
289 #define	OMAP_ANON	0x0002
290 #define	OMAP_COPY	0x0020
291 #define	OMAP_SHARED	0x0010
292 #define	OMAP_FIXED	0x0100
293 #define	OMAP_INHERIT	0x0800
294 
295 	nargs.addr = uap->addr;
296 	nargs.len = uap->len;
297 	nargs.prot = cvtbsdprot[uap->prot & 0x7];
298 	nargs.flags = 0;
299 	if (uap->flags & OMAP_ANON)
300 		nargs.flags |= MAP_ANON;
301 	if (uap->flags & OMAP_COPY)
302 		nargs.flags |= MAP_COPY;
303 	if (uap->flags & OMAP_SHARED)
304 		nargs.flags |= MAP_SHARED;
305 	else
306 		nargs.flags |= MAP_PRIVATE;
307 	if (uap->flags & OMAP_FIXED)
308 		nargs.flags |= MAP_FIXED;
309 	if (uap->flags & OMAP_INHERIT)
310 		nargs.flags |= MAP_INHERIT;
311 	nargs.fd = uap->fd;
312 	nargs.pos = uap->pos;
313 	return (mmap(p, &nargs, retval));
314 }
315 #endif				/* COMPAT_43 */
316 
317 
318 #ifndef _SYS_SYSPROTO_H_
319 struct msync_args {
320 	caddr_t addr;
321 	int len;
322 	int flags;
323 };
324 #endif
325 int
326 msync(p, uap, retval)
327 	struct proc *p;
328 	struct msync_args *uap;
329 	int *retval;
330 {
331 	vm_offset_t addr;
332 	vm_size_t size, pageoff;
333 	int flags;
334 	vm_map_t map;
335 	int rv;
336 
337 	addr = (vm_offset_t) uap->addr;
338 	size = uap->len;
339 	flags = uap->flags;
340 
341 	pageoff = (addr & PAGE_MASK);
342 	addr -= pageoff;
343 	size += pageoff;
344 	size = (vm_size_t) round_page(size);
345 	if (addr + size < addr)
346 		return(EINVAL);
347 
348 	if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE))
349 		return (EINVAL);
350 
351 	map = &p->p_vmspace->vm_map;
352 
353 	/*
354 	 * XXX Gak!  If size is zero we are supposed to sync "all modified
355 	 * pages with the region containing addr".  Unfortunately, we don't
356 	 * really keep track of individual mmaps so we approximate by flushing
357 	 * the range of the map entry containing addr. This can be incorrect
358 	 * if the region splits or is coalesced with a neighbor.
359 	 */
360 	if (size == 0) {
361 		vm_map_entry_t entry;
362 
363 		vm_map_lock_read(map);
364 		rv = vm_map_lookup_entry(map, addr, &entry);
365 		vm_map_unlock_read(map);
366 		if (rv == FALSE)
367 			return (EINVAL);
368 		addr = entry->start;
369 		size = entry->end - entry->start;
370 	}
371 
372 	/*
373 	 * Clean the pages and interpret the return value.
374 	 */
375 	rv = vm_map_clean(map, addr, addr + size, (flags & MS_ASYNC) == 0,
376 	    (flags & MS_INVALIDATE) != 0);
377 
378 	switch (rv) {
379 	case KERN_SUCCESS:
380 		break;
381 	case KERN_INVALID_ADDRESS:
382 		return (EINVAL);	/* Sun returns ENOMEM? */
383 	case KERN_FAILURE:
384 		return (EIO);
385 	default:
386 		return (EINVAL);
387 	}
388 
389 	return (0);
390 }
391 
392 #ifndef _SYS_SYSPROTO_H_
393 struct munmap_args {
394 	caddr_t addr;
395 	size_t len;
396 };
397 #endif
398 int
399 munmap(p, uap, retval)
400 	register struct proc *p;
401 	register struct munmap_args *uap;
402 	int *retval;
403 {
404 	vm_offset_t addr;
405 	vm_size_t size, pageoff;
406 	vm_map_t map;
407 
408 	addr = (vm_offset_t) uap->addr;
409 	size = uap->len;
410 
411 	pageoff = (addr & PAGE_MASK);
412 	addr -= pageoff;
413 	size += pageoff;
414 	size = (vm_size_t) round_page(size);
415 	if (addr + size < addr)
416 		return(EINVAL);
417 
418 	if (size == 0)
419 		return (0);
420 
421 	/*
422 	 * Check for illegal addresses.  Watch out for address wrap... Note
423 	 * that VM_*_ADDRESS are not constants due to casts (argh).
424 	 */
425 	if (VM_MAXUSER_ADDRESS > 0 && addr + size > VM_MAXUSER_ADDRESS)
426 		return (EINVAL);
427 #ifndef i386
428 	if (VM_MIN_ADDRESS > 0 && addr < VM_MIN_ADDRESS)
429 		return (EINVAL);
430 #endif
431 	if (addr + size < addr)
432 		return (EINVAL);
433 	map = &p->p_vmspace->vm_map;
434 	/*
435 	 * Make sure entire range is allocated.
436 	 */
437 	if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE))
438 		return (EINVAL);
439 	/* returns nothing but KERN_SUCCESS anyway */
440 	(void) vm_map_remove(map, addr, addr + size);
441 	return (0);
442 }
443 
444 void
445 munmapfd(p, fd)
446 	struct proc *p;
447 	int fd;
448 {
449 	/*
450 	 * XXX should unmap any regions mapped to this file
451 	 */
452 	p->p_fd->fd_ofileflags[fd] &= ~UF_MAPPED;
453 }
454 
455 #ifndef _SYS_SYSPROTO_H_
456 struct mprotect_args {
457 	caddr_t addr;
458 	size_t len;
459 	int prot;
460 };
461 #endif
462 int
463 mprotect(p, uap, retval)
464 	struct proc *p;
465 	struct mprotect_args *uap;
466 	int *retval;
467 {
468 	vm_offset_t addr;
469 	vm_size_t size, pageoff;
470 	register vm_prot_t prot;
471 
472 	addr = (vm_offset_t) uap->addr;
473 	size = uap->len;
474 	prot = uap->prot & VM_PROT_ALL;
475 
476 	pageoff = (addr & PAGE_MASK);
477 	addr -= pageoff;
478 	size += pageoff;
479 	size = (vm_size_t) round_page(size);
480 	if (addr + size < addr)
481 		return(EINVAL);
482 
483 	switch (vm_map_protect(&p->p_vmspace->vm_map, addr, addr + size, prot,
484 		FALSE)) {
485 	case KERN_SUCCESS:
486 		return (0);
487 	case KERN_PROTECTION_FAILURE:
488 		return (EACCES);
489 	}
490 	return (EINVAL);
491 }
492 
493 #ifndef _SYS_SYSPROTO_H_
494 struct minherit_args {
495 	caddr_t addr;
496 	size_t len;
497 	int inherit;
498 };
499 #endif
500 int
501 minherit(p, uap, retval)
502 	struct proc *p;
503 	struct minherit_args *uap;
504 	int *retval;
505 {
506 	vm_offset_t addr;
507 	vm_size_t size, pageoff;
508 	register vm_inherit_t inherit;
509 
510 	addr = (vm_offset_t)uap->addr;
511 	size = uap->len;
512 	inherit = uap->inherit;
513 
514 	pageoff = (addr & PAGE_MASK);
515 	addr -= pageoff;
516 	size += pageoff;
517 	size = (vm_size_t) round_page(size);
518 	if (addr + size < addr)
519 		return(EINVAL);
520 
521 	switch (vm_map_inherit(&p->p_vmspace->vm_map, addr, addr+size,
522 	    inherit)) {
523 	case KERN_SUCCESS:
524 		return (0);
525 	case KERN_PROTECTION_FAILURE:
526 		return (EACCES);
527 	}
528 	return (EINVAL);
529 }
530 
531 #ifndef _SYS_SYSPROTO_H_
532 struct madvise_args {
533 	caddr_t addr;
534 	size_t len;
535 	int behav;
536 };
537 #endif
538 
539 /* ARGSUSED */
540 int
541 madvise(p, uap, retval)
542 	struct proc *p;
543 	struct madvise_args *uap;
544 	int *retval;
545 {
546 
547 	/* Not yet implemented */
548 	return (EOPNOTSUPP);
549 }
550 
551 #ifndef _SYS_SYSPROTO_H_
552 struct mincore_args {
553 	caddr_t addr;
554 	size_t len;
555 	char *vec;
556 };
557 #endif
558 
559 /* ARGSUSED */
560 int
561 mincore(p, uap, retval)
562 	struct proc *p;
563 	struct mincore_args *uap;
564 	int *retval;
565 {
566 	vm_offset_t addr;
567 	vm_offset_t end;
568 	char *vec;
569 
570 	addr = trunc_page((vm_offset_t) uap->addr);
571 	end = addr + (vm_size_t)round_page(uap->len);
572 	if (VM_MAXUSER_ADDRESS > 0 && end > VM_MAXUSER_ADDRESS)
573 		return (EINVAL);
574 	if (end < addr)
575 		return (EINVAL);
576 
577 	vec = uap->vec;
578 	while(addr < end) {
579 		int error;
580 		if (pmap_extract(&p->p_vmspace->vm_pmap, addr)) {
581 			error = subyte( vec, 1);
582 		} else {
583 			error = subyte( vec, 0);
584 		}
585 		if (error)
586 			return EFAULT;
587 		vec++;
588 		addr += PAGE_SIZE;
589 	}
590 	return (0);
591 }
592 
593 #ifndef _SYS_SYSPROTO_H_
594 struct mlock_args {
595 	caddr_t addr;
596 	size_t len;
597 };
598 #endif
599 int
600 mlock(p, uap, retval)
601 	struct proc *p;
602 	struct mlock_args *uap;
603 	int *retval;
604 {
605 	vm_offset_t addr;
606 	vm_size_t size, pageoff;
607 	int error;
608 
609 	addr = (vm_offset_t) uap->addr;
610 	size = uap->len;
611 
612 	pageoff = (addr & PAGE_MASK);
613 	addr -= pageoff;
614 	size += pageoff;
615 	size = (vm_size_t) round_page(size);
616 
617 	/* disable wrap around */
618 	if (addr + size < addr)
619 		return (EINVAL);
620 
621 	if (atop(size) + cnt.v_wire_count > vm_page_max_wired)
622 		return (EAGAIN);
623 
624 #ifdef pmap_wired_count
625 	if (size + ptoa(pmap_wired_count(vm_map_pmap(&p->p_vmspace->vm_map))) >
626 	    p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur)
627 		return (EAGAIN);
628 #else
629 	error = suser(p->p_ucred, &p->p_acflag);
630 	if (error)
631 		return (error);
632 #endif
633 
634 	error = vm_map_pageable(&p->p_vmspace->vm_map, addr, addr + size, FALSE);
635 	return (error == KERN_SUCCESS ? 0 : ENOMEM);
636 }
637 
638 #ifndef _SYS_SYSPROTO_H_
639 struct munlock_args {
640 	caddr_t addr;
641 	size_t len;
642 };
643 #endif
644 int
645 munlock(p, uap, retval)
646 	struct proc *p;
647 	struct munlock_args *uap;
648 	int *retval;
649 {
650 	vm_offset_t addr;
651 	vm_size_t size, pageoff;
652 	int error;
653 
654 	addr = (vm_offset_t) uap->addr;
655 	size = uap->len;
656 
657 	pageoff = (addr & PAGE_MASK);
658 	addr -= pageoff;
659 	size += pageoff;
660 	size = (vm_size_t) round_page(size);
661 
662 	/* disable wrap around */
663 	if (addr + size < addr)
664 		return (EINVAL);
665 
666 #ifndef pmap_wired_count
667 	error = suser(p->p_ucred, &p->p_acflag);
668 	if (error)
669 		return (error);
670 #endif
671 
672 	error = vm_map_pageable(&p->p_vmspace->vm_map, addr, addr + size, TRUE);
673 	return (error == KERN_SUCCESS ? 0 : ENOMEM);
674 }
675 
676 /*
677  * Internal version of mmap.
678  * Currently used by mmap, exec, and sys5 shared memory.
679  * Handle is either a vnode pointer or NULL for MAP_ANON.
680  */
681 int
682 vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
683 	register vm_map_t map;
684 	register vm_offset_t *addr;
685 	register vm_size_t size;
686 	vm_prot_t prot, maxprot;
687 	register int flags;
688 	caddr_t handle;		/* XXX should be vp */
689 	vm_ooffset_t foff;
690 {
691 	boolean_t fitit;
692 	vm_object_t object, object2;
693 	struct vnode *vp = NULL;
694 	objtype_t type;
695 	int rv = KERN_SUCCESS;
696 	vm_ooffset_t objsize;
697 	int docow;
698 	struct proc *p = curproc;
699 
700 	if (size == 0)
701 		return (0);
702 
703 	objsize = size = round_page(size);
704 
705 	/*
706 	 * We currently can only deal with page aligned file offsets.
707 	 * The check is here rather than in the syscall because the
708 	 * kernel calls this function internally for other mmaping
709 	 * operations (such as in exec) and non-aligned offsets will
710 	 * cause pmap inconsistencies...so we want to be sure to
711 	 * disallow this in all cases.
712 	 */
713 	if (foff & PAGE_MASK)
714 		return (EINVAL);
715 
716 	if ((flags & MAP_FIXED) == 0) {
717 		fitit = TRUE;
718 		*addr = round_page(*addr);
719 	} else {
720 		if (*addr != trunc_page(*addr))
721 			return (EINVAL);
722 		fitit = FALSE;
723 		(void) vm_map_remove(map, *addr, *addr + size);
724 	}
725 
726 	/*
727 	 * Lookup/allocate object.
728 	 */
729 	if (flags & MAP_ANON) {
730 		type = OBJT_SWAP;
731 		/*
732 		 * Unnamed anonymous regions always start at 0.
733 		 */
734 		if (handle == 0)
735 			foff = 0;
736 	} else {
737 		vp = (struct vnode *) handle;
738 		if (vp->v_type == VCHR) {
739 			type = OBJT_DEVICE;
740 			handle = (caddr_t) vp->v_rdev;
741 		} else {
742 			struct vattr vat;
743 			int error;
744 
745 			error = VOP_GETATTR(vp, &vat, p->p_ucred, p);
746 			if (error)
747 				return (error);
748 			objsize = round_page(vat.va_size);
749 			type = OBJT_VNODE;
750 		}
751 	}
752 	object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff);
753 	if (object == NULL)
754 		return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
755 
756 	/*
757 	 * Force device mappings to be shared.
758 	 */
759 	if (type == OBJT_DEVICE) {
760 		flags &= ~(MAP_PRIVATE|MAP_COPY);
761 		flags |= MAP_SHARED;
762 	}
763 
764 	object2 = NULL;
765 	docow = 0;
766 	if ((flags & (MAP_ANON|MAP_SHARED)) == 0) {
767 		docow = MAP_COPY_ON_WRITE;
768 		if (objsize < size) {
769 			object2 = vm_object_allocate( OBJT_DEFAULT,
770 				OFF_TO_IDX(size - (foff & ~(PAGE_SIZE - 1))));
771 			object2->backing_object = object;
772 			object2->backing_object_offset = foff;
773 			TAILQ_INSERT_TAIL(&object->shadow_head,
774 				object2, shadow_list);
775 			++object->shadow_count;
776 		} else {
777 			docow |= MAP_COPY_NEEDED;
778 		}
779 	}
780 
781 	if (object2)
782 		rv = vm_map_find(map, object2, 0, addr, size, fitit,
783 			prot, maxprot, docow);
784 	else
785 		rv = vm_map_find(map, object, foff, addr, size, fitit,
786 			prot, maxprot, docow);
787 
788 
789 	if (rv != KERN_SUCCESS) {
790 		/*
791 		 * Lose the object reference. Will destroy the
792 		 * object if it's an unnamed anonymous mapping
793 		 * or named anonymous without other references.
794 		 */
795 		if (object2)
796 			vm_object_deallocate(object2);
797 		else
798 			vm_object_deallocate(object);
799 		goto out;
800 	}
801 
802 	/*
803 	 * "Pre-fault" resident pages.
804 	 */
805 	if ((map != kernel_map) &&
806 		(type == OBJT_VNODE) && (map->pmap != NULL)) {
807 		pmap_object_init_pt(map->pmap, *addr,
808 			object, (vm_pindex_t) OFF_TO_IDX(foff), size);
809 	}
810 
811 	/*
812 	 * Shared memory is also shared with children.
813 	 */
814 	if (flags & (MAP_SHARED|MAP_INHERIT)) {
815 		rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE);
816 		if (rv != KERN_SUCCESS) {
817 			(void) vm_map_remove(map, *addr, *addr + size);
818 			goto out;
819 		}
820 	}
821 out:
822 	switch (rv) {
823 	case KERN_SUCCESS:
824 		return (0);
825 	case KERN_INVALID_ADDRESS:
826 	case KERN_NO_SPACE:
827 		return (ENOMEM);
828 	case KERN_PROTECTION_FAILURE:
829 		return (EACCES);
830 	default:
831 		return (EINVAL);
832 	}
833 }
834