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