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 233 /* Make sure mapping fits into numeric range, etc. */ 234 if ((uap->len == 0 && !SV_CURPROC_FLAG(SV_AOUT) && 235 curproc->p_osrel >= __FreeBSD_version_MAP_ANON) || 236 ((flags & MAP_ANON) && (uap->fd != -1 || pos != 0))) 237 return (EINVAL); 238 239 if (flags & MAP_STACK) { 240 if ((uap->fd != -1) || 241 ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) 242 return (EINVAL); 243 flags |= MAP_ANON; 244 pos = 0; 245 } 246 247 /* 248 * Align the file position to a page boundary, 249 * and save its page offset component. 250 */ 251 pageoff = (pos & PAGE_MASK); 252 pos -= pageoff; 253 254 /* Adjust size for rounding (on both ends). */ 255 size += pageoff; /* low end... */ 256 size = (vm_size_t) round_page(size); /* hi end */ 257 258 /* 259 * Check for illegal addresses. Watch out for address wrap... Note 260 * that VM_*_ADDRESS are not constants due to casts (argh). 261 */ 262 if (flags & MAP_FIXED) { 263 /* 264 * The specified address must have the same remainder 265 * as the file offset taken modulo PAGE_SIZE, so it 266 * should be aligned after adjustment by pageoff. 267 */ 268 addr -= pageoff; 269 if (addr & PAGE_MASK) 270 return (EINVAL); 271 272 /* Address range must be all in user VM space. */ 273 if (addr < vm_map_min(&vms->vm_map) || 274 addr + size > vm_map_max(&vms->vm_map)) 275 return (EINVAL); 276 if (addr + size < addr) 277 return (EINVAL); 278 } else { 279 /* 280 * XXX for non-fixed mappings where no hint is provided or 281 * the hint would fall in the potential heap space, 282 * place it after the end of the largest possible heap. 283 * 284 * There should really be a pmap call to determine a reasonable 285 * location. 286 */ 287 PROC_LOCK(td->td_proc); 288 if (addr == 0 || 289 (addr >= round_page((vm_offset_t)vms->vm_taddr) && 290 addr < round_page((vm_offset_t)vms->vm_daddr + 291 lim_max(td->td_proc, RLIMIT_DATA)))) 292 addr = round_page((vm_offset_t)vms->vm_daddr + 293 lim_max(td->td_proc, RLIMIT_DATA)); 294 PROC_UNLOCK(td->td_proc); 295 } 296 if (flags & MAP_ANON) { 297 /* 298 * Mapping blank space is trivial. 299 */ 300 handle = NULL; 301 handle_type = OBJT_DEFAULT; 302 maxprot = VM_PROT_ALL; 303 } else { 304 /* 305 * Mapping file, get fp for validation and 306 * don't let the descriptor disappear on us if we block. 307 */ 308 if ((error = fget(td, uap->fd, &fp)) != 0) 309 goto done; 310 if (fp->f_type == DTYPE_SHM) { 311 handle = fp->f_data; 312 handle_type = OBJT_SWAP; 313 maxprot = VM_PROT_NONE; 314 315 /* FREAD should always be set. */ 316 if (fp->f_flag & FREAD) 317 maxprot |= VM_PROT_EXECUTE | VM_PROT_READ; 318 if (fp->f_flag & FWRITE) 319 maxprot |= VM_PROT_WRITE; 320 goto map; 321 } 322 if (fp->f_type != DTYPE_VNODE) { 323 error = ENODEV; 324 goto done; 325 } 326 #if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \ 327 defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) 328 /* 329 * POSIX shared-memory objects are defined to have 330 * kernel persistence, and are not defined to support 331 * read(2)/write(2) -- or even open(2). Thus, we can 332 * use MAP_ASYNC to trade on-disk coherence for speed. 333 * The shm_open(3) library routine turns on the FPOSIXSHM 334 * flag to request this behavior. 335 */ 336 if (fp->f_flag & FPOSIXSHM) 337 flags |= MAP_NOSYNC; 338 #endif 339 vp = fp->f_vnode; 340 /* 341 * Ensure that file and memory protections are 342 * compatible. Note that we only worry about 343 * writability if mapping is shared; in this case, 344 * current and max prot are dictated by the open file. 345 * XXX use the vnode instead? Problem is: what 346 * credentials do we use for determination? What if 347 * proc does a setuid? 348 */ 349 if (vp->v_mount != NULL && vp->v_mount->mnt_flag & MNT_NOEXEC) 350 maxprot = VM_PROT_NONE; 351 else 352 maxprot = VM_PROT_EXECUTE; 353 if (fp->f_flag & FREAD) { 354 maxprot |= VM_PROT_READ; 355 } else if (prot & PROT_READ) { 356 error = EACCES; 357 goto done; 358 } 359 /* 360 * If we are sharing potential changes (either via 361 * MAP_SHARED or via the implicit sharing of character 362 * device mappings), and we are trying to get write 363 * permission although we opened it without asking 364 * for it, bail out. 365 */ 366 if ((flags & MAP_SHARED) != 0) { 367 if ((fp->f_flag & FWRITE) != 0) { 368 maxprot |= VM_PROT_WRITE; 369 } else if ((prot & PROT_WRITE) != 0) { 370 error = EACCES; 371 goto done; 372 } 373 } else if (vp->v_type != VCHR || (fp->f_flag & FWRITE) != 0) { 374 maxprot |= VM_PROT_WRITE; 375 } 376 handle = (void *)vp; 377 handle_type = OBJT_VNODE; 378 } 379 map: 380 381 /* 382 * Do not allow more then a certain number of vm_map_entry structures 383 * per process. Scale with the number of rforks sharing the map 384 * to make the limit reasonable for threads. 385 */ 386 if (max_proc_mmap && 387 vms->vm_map.nentries >= max_proc_mmap * vms->vm_refcnt) { 388 error = ENOMEM; 389 goto done; 390 } 391 392 td->td_fpop = fp; 393 error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, 394 flags, handle_type, handle, pos); 395 td->td_fpop = NULL; 396 #ifdef HWPMC_HOOKS 397 /* inform hwpmc(4) if an executable is being mapped */ 398 if (error == 0 && handle_type == OBJT_VNODE && 399 (prot & PROT_EXEC)) { 400 pkm.pm_file = handle; 401 pkm.pm_address = (uintptr_t) addr; 402 PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm); 403 } 404 #endif 405 if (error == 0) 406 td->td_retval[0] = (register_t) (addr + pageoff); 407 done: 408 if (fp) 409 fdrop(fp, td); 410 411 return (error); 412 } 413 414 int 415 freebsd6_mmap(struct thread *td, struct freebsd6_mmap_args *uap) 416 { 417 struct mmap_args oargs; 418 419 oargs.addr = uap->addr; 420 oargs.len = uap->len; 421 oargs.prot = uap->prot; 422 oargs.flags = uap->flags; 423 oargs.fd = uap->fd; 424 oargs.pos = uap->pos; 425 return (mmap(td, &oargs)); 426 } 427 428 #ifdef COMPAT_43 429 #ifndef _SYS_SYSPROTO_H_ 430 struct ommap_args { 431 caddr_t addr; 432 int len; 433 int prot; 434 int flags; 435 int fd; 436 long pos; 437 }; 438 #endif 439 int 440 ommap(td, uap) 441 struct thread *td; 442 struct ommap_args *uap; 443 { 444 struct mmap_args nargs; 445 static const char cvtbsdprot[8] = { 446 0, 447 PROT_EXEC, 448 PROT_WRITE, 449 PROT_EXEC | PROT_WRITE, 450 PROT_READ, 451 PROT_EXEC | PROT_READ, 452 PROT_WRITE | PROT_READ, 453 PROT_EXEC | PROT_WRITE | PROT_READ, 454 }; 455 456 #define OMAP_ANON 0x0002 457 #define OMAP_COPY 0x0020 458 #define OMAP_SHARED 0x0010 459 #define OMAP_FIXED 0x0100 460 461 nargs.addr = uap->addr; 462 nargs.len = uap->len; 463 nargs.prot = cvtbsdprot[uap->prot & 0x7]; 464 nargs.flags = 0; 465 if (uap->flags & OMAP_ANON) 466 nargs.flags |= MAP_ANON; 467 if (uap->flags & OMAP_COPY) 468 nargs.flags |= MAP_COPY; 469 if (uap->flags & OMAP_SHARED) 470 nargs.flags |= MAP_SHARED; 471 else 472 nargs.flags |= MAP_PRIVATE; 473 if (uap->flags & OMAP_FIXED) 474 nargs.flags |= MAP_FIXED; 475 nargs.fd = uap->fd; 476 nargs.pos = uap->pos; 477 return (mmap(td, &nargs)); 478 } 479 #endif /* COMPAT_43 */ 480 481 482 #ifndef _SYS_SYSPROTO_H_ 483 struct msync_args { 484 void *addr; 485 size_t len; 486 int flags; 487 }; 488 #endif 489 /* 490 * MPSAFE 491 */ 492 int 493 msync(td, uap) 494 struct thread *td; 495 struct msync_args *uap; 496 { 497 vm_offset_t addr; 498 vm_size_t size, pageoff; 499 int flags; 500 vm_map_t map; 501 int rv; 502 503 addr = (vm_offset_t) uap->addr; 504 size = uap->len; 505 flags = uap->flags; 506 507 pageoff = (addr & PAGE_MASK); 508 addr -= pageoff; 509 size += pageoff; 510 size = (vm_size_t) round_page(size); 511 if (addr + size < addr) 512 return (EINVAL); 513 514 if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE)) 515 return (EINVAL); 516 517 map = &td->td_proc->p_vmspace->vm_map; 518 519 /* 520 * Clean the pages and interpret the return value. 521 */ 522 rv = vm_map_sync(map, addr, addr + size, (flags & MS_ASYNC) == 0, 523 (flags & MS_INVALIDATE) != 0); 524 switch (rv) { 525 case KERN_SUCCESS: 526 return (0); 527 case KERN_INVALID_ADDRESS: 528 return (EINVAL); /* Sun returns ENOMEM? */ 529 case KERN_INVALID_ARGUMENT: 530 return (EBUSY); 531 default: 532 return (EINVAL); 533 } 534 } 535 536 #ifndef _SYS_SYSPROTO_H_ 537 struct munmap_args { 538 void *addr; 539 size_t len; 540 }; 541 #endif 542 /* 543 * MPSAFE 544 */ 545 int 546 munmap(td, uap) 547 struct thread *td; 548 struct munmap_args *uap; 549 { 550 #ifdef HWPMC_HOOKS 551 struct pmckern_map_out pkm; 552 vm_map_entry_t entry; 553 #endif 554 vm_offset_t addr; 555 vm_size_t size, pageoff; 556 vm_map_t map; 557 558 addr = (vm_offset_t) uap->addr; 559 size = uap->len; 560 if (size == 0) 561 return (EINVAL); 562 563 pageoff = (addr & PAGE_MASK); 564 addr -= pageoff; 565 size += pageoff; 566 size = (vm_size_t) round_page(size); 567 if (addr + size < addr) 568 return (EINVAL); 569 570 /* 571 * Check for illegal addresses. Watch out for address wrap... 572 */ 573 map = &td->td_proc->p_vmspace->vm_map; 574 if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) 575 return (EINVAL); 576 vm_map_lock(map); 577 #ifdef HWPMC_HOOKS 578 /* 579 * Inform hwpmc if the address range being unmapped contains 580 * an executable region. 581 */ 582 pkm.pm_address = (uintptr_t) NULL; 583 if (vm_map_lookup_entry(map, addr, &entry)) { 584 for (; 585 entry != &map->header && entry->start < addr + size; 586 entry = entry->next) { 587 if (vm_map_check_protection(map, entry->start, 588 entry->end, VM_PROT_EXECUTE) == TRUE) { 589 pkm.pm_address = (uintptr_t) addr; 590 pkm.pm_size = (size_t) size; 591 break; 592 } 593 } 594 } 595 #endif 596 vm_map_delete(map, addr, addr + size); 597 598 #ifdef HWPMC_HOOKS 599 /* downgrade the lock to prevent a LOR with the pmc-sx lock */ 600 vm_map_lock_downgrade(map); 601 if (pkm.pm_address != (uintptr_t) NULL) 602 PMC_CALL_HOOK(td, PMC_FN_MUNMAP, (void *) &pkm); 603 vm_map_unlock_read(map); 604 #else 605 vm_map_unlock(map); 606 #endif 607 /* vm_map_delete returns nothing but KERN_SUCCESS anyway */ 608 return (0); 609 } 610 611 #ifndef _SYS_SYSPROTO_H_ 612 struct mprotect_args { 613 const void *addr; 614 size_t len; 615 int prot; 616 }; 617 #endif 618 /* 619 * MPSAFE 620 */ 621 int 622 mprotect(td, uap) 623 struct thread *td; 624 struct mprotect_args *uap; 625 { 626 vm_offset_t addr; 627 vm_size_t size, pageoff; 628 vm_prot_t prot; 629 630 addr = (vm_offset_t) uap->addr; 631 size = uap->len; 632 prot = uap->prot & VM_PROT_ALL; 633 634 pageoff = (addr & PAGE_MASK); 635 addr -= pageoff; 636 size += pageoff; 637 size = (vm_size_t) round_page(size); 638 if (addr + size < addr) 639 return (EINVAL); 640 641 switch (vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr, 642 addr + size, prot, FALSE)) { 643 case KERN_SUCCESS: 644 return (0); 645 case KERN_PROTECTION_FAILURE: 646 return (EACCES); 647 case KERN_RESOURCE_SHORTAGE: 648 return (ENOMEM); 649 } 650 return (EINVAL); 651 } 652 653 #ifndef _SYS_SYSPROTO_H_ 654 struct minherit_args { 655 void *addr; 656 size_t len; 657 int inherit; 658 }; 659 #endif 660 /* 661 * MPSAFE 662 */ 663 int 664 minherit(td, uap) 665 struct thread *td; 666 struct minherit_args *uap; 667 { 668 vm_offset_t addr; 669 vm_size_t size, pageoff; 670 vm_inherit_t inherit; 671 672 addr = (vm_offset_t)uap->addr; 673 size = uap->len; 674 inherit = uap->inherit; 675 676 pageoff = (addr & PAGE_MASK); 677 addr -= pageoff; 678 size += pageoff; 679 size = (vm_size_t) round_page(size); 680 if (addr + size < addr) 681 return (EINVAL); 682 683 switch (vm_map_inherit(&td->td_proc->p_vmspace->vm_map, addr, 684 addr + size, inherit)) { 685 case KERN_SUCCESS: 686 return (0); 687 case KERN_PROTECTION_FAILURE: 688 return (EACCES); 689 } 690 return (EINVAL); 691 } 692 693 #ifndef _SYS_SYSPROTO_H_ 694 struct madvise_args { 695 void *addr; 696 size_t len; 697 int behav; 698 }; 699 #endif 700 701 /* 702 * MPSAFE 703 */ 704 /* ARGSUSED */ 705 int 706 madvise(td, uap) 707 struct thread *td; 708 struct madvise_args *uap; 709 { 710 vm_offset_t start, end; 711 vm_map_t map; 712 struct proc *p; 713 int error; 714 715 /* 716 * Check for our special case, advising the swap pager we are 717 * "immortal." 718 */ 719 if (uap->behav == MADV_PROTECT) { 720 error = priv_check(td, PRIV_VM_MADV_PROTECT); 721 if (error == 0) { 722 p = td->td_proc; 723 PROC_LOCK(p); 724 p->p_flag |= P_PROTECTED; 725 PROC_UNLOCK(p); 726 } 727 return (error); 728 } 729 /* 730 * Check for illegal behavior 731 */ 732 if (uap->behav < 0 || uap->behav > MADV_CORE) 733 return (EINVAL); 734 /* 735 * Check for illegal addresses. Watch out for address wrap... Note 736 * that VM_*_ADDRESS are not constants due to casts (argh). 737 */ 738 map = &td->td_proc->p_vmspace->vm_map; 739 if ((vm_offset_t)uap->addr < vm_map_min(map) || 740 (vm_offset_t)uap->addr + uap->len > vm_map_max(map)) 741 return (EINVAL); 742 if (((vm_offset_t) uap->addr + uap->len) < (vm_offset_t) uap->addr) 743 return (EINVAL); 744 745 /* 746 * Since this routine is only advisory, we default to conservative 747 * behavior. 748 */ 749 start = trunc_page((vm_offset_t) uap->addr); 750 end = round_page((vm_offset_t) uap->addr + uap->len); 751 752 if (vm_map_madvise(map, start, end, uap->behav)) 753 return (EINVAL); 754 return (0); 755 } 756 757 #ifndef _SYS_SYSPROTO_H_ 758 struct mincore_args { 759 const void *addr; 760 size_t len; 761 char *vec; 762 }; 763 #endif 764 765 /* 766 * MPSAFE 767 */ 768 /* ARGSUSED */ 769 int 770 mincore(td, uap) 771 struct thread *td; 772 struct mincore_args *uap; 773 { 774 vm_offset_t addr, first_addr; 775 vm_offset_t end, cend; 776 pmap_t pmap; 777 vm_map_t map; 778 char *vec; 779 int error = 0; 780 int vecindex, lastvecindex; 781 vm_map_entry_t current; 782 vm_map_entry_t entry; 783 vm_object_t object; 784 vm_paddr_t locked_pa; 785 vm_page_t m; 786 vm_pindex_t pindex; 787 int mincoreinfo; 788 unsigned int timestamp; 789 boolean_t locked; 790 791 /* 792 * Make sure that the addresses presented are valid for user 793 * mode. 794 */ 795 first_addr = addr = trunc_page((vm_offset_t) uap->addr); 796 end = addr + (vm_size_t)round_page(uap->len); 797 map = &td->td_proc->p_vmspace->vm_map; 798 if (end > vm_map_max(map) || end < addr) 799 return (ENOMEM); 800 801 /* 802 * Address of byte vector 803 */ 804 vec = uap->vec; 805 806 pmap = vmspace_pmap(td->td_proc->p_vmspace); 807 808 vm_map_lock_read(map); 809 RestartScan: 810 timestamp = map->timestamp; 811 812 if (!vm_map_lookup_entry(map, addr, &entry)) { 813 vm_map_unlock_read(map); 814 return (ENOMEM); 815 } 816 817 /* 818 * Do this on a map entry basis so that if the pages are not 819 * in the current processes address space, we can easily look 820 * up the pages elsewhere. 821 */ 822 lastvecindex = -1; 823 for (current = entry; 824 (current != &map->header) && (current->start < end); 825 current = current->next) { 826 827 /* 828 * check for contiguity 829 */ 830 if (current->end < end && 831 (entry->next == &map->header || 832 current->next->start > current->end)) { 833 vm_map_unlock_read(map); 834 return (ENOMEM); 835 } 836 837 /* 838 * ignore submaps (for now) or null objects 839 */ 840 if ((current->eflags & MAP_ENTRY_IS_SUB_MAP) || 841 current->object.vm_object == NULL) 842 continue; 843 844 /* 845 * limit this scan to the current map entry and the 846 * limits for the mincore call 847 */ 848 if (addr < current->start) 849 addr = current->start; 850 cend = current->end; 851 if (cend > end) 852 cend = end; 853 854 /* 855 * scan this entry one page at a time 856 */ 857 while (addr < cend) { 858 /* 859 * Check pmap first, it is likely faster, also 860 * it can provide info as to whether we are the 861 * one referencing or modifying the page. 862 */ 863 object = NULL; 864 locked_pa = 0; 865 retry: 866 m = NULL; 867 mincoreinfo = pmap_mincore(pmap, addr, &locked_pa); 868 if (locked_pa != 0) { 869 /* 870 * The page is mapped by this process but not 871 * both accessed and modified. It is also 872 * managed. Acquire the object lock so that 873 * other mappings might be examined. 874 */ 875 m = PHYS_TO_VM_PAGE(locked_pa); 876 if (m->object != object) { 877 if (object != NULL) 878 VM_OBJECT_UNLOCK(object); 879 object = m->object; 880 locked = VM_OBJECT_TRYLOCK(object); 881 vm_page_unlock(m); 882 if (!locked) { 883 VM_OBJECT_LOCK(object); 884 vm_page_lock(m); 885 goto retry; 886 } 887 } else 888 vm_page_unlock(m); 889 KASSERT(m->valid == VM_PAGE_BITS_ALL, 890 ("mincore: page %p is mapped but invalid", 891 m)); 892 } else if (mincoreinfo == 0) { 893 /* 894 * The page is not mapped by this process. If 895 * the object implements managed pages, then 896 * determine if the page is resident so that 897 * the mappings might be examined. 898 */ 899 if (current->object.vm_object != object) { 900 if (object != NULL) 901 VM_OBJECT_UNLOCK(object); 902 object = current->object.vm_object; 903 VM_OBJECT_LOCK(object); 904 } 905 if (object->type == OBJT_DEFAULT || 906 object->type == OBJT_SWAP || 907 object->type == OBJT_VNODE) { 908 pindex = OFF_TO_IDX(current->offset + 909 (addr - current->start)); 910 m = vm_page_lookup(object, pindex); 911 if (m != NULL && m->valid == 0) 912 m = NULL; 913 if (m != NULL) 914 mincoreinfo = MINCORE_INCORE; 915 } 916 } 917 if (m != NULL) { 918 /* Examine other mappings to the page. */ 919 if (m->dirty == 0 && pmap_is_modified(m)) 920 vm_page_dirty(m); 921 if (m->dirty != 0) 922 mincoreinfo |= MINCORE_MODIFIED_OTHER; 923 /* 924 * The first test for PG_REFERENCED is an 925 * optimization. The second test is 926 * required because a concurrent pmap 927 * operation could clear the last reference 928 * and set PG_REFERENCED before the call to 929 * pmap_is_referenced(). 930 */ 931 if ((m->flags & PG_REFERENCED) != 0 || 932 pmap_is_referenced(m) || 933 (m->flags & PG_REFERENCED) != 0) 934 mincoreinfo |= MINCORE_REFERENCED_OTHER; 935 } 936 if (object != NULL) 937 VM_OBJECT_UNLOCK(object); 938 939 /* 940 * subyte may page fault. In case it needs to modify 941 * the map, we release the lock. 942 */ 943 vm_map_unlock_read(map); 944 945 /* 946 * calculate index into user supplied byte vector 947 */ 948 vecindex = OFF_TO_IDX(addr - first_addr); 949 950 /* 951 * If we have skipped map entries, we need to make sure that 952 * the byte vector is zeroed for those skipped entries. 953 */ 954 while ((lastvecindex + 1) < vecindex) { 955 error = subyte(vec + lastvecindex, 0); 956 if (error) { 957 error = EFAULT; 958 goto done2; 959 } 960 ++lastvecindex; 961 } 962 963 /* 964 * Pass the page information to the user 965 */ 966 error = subyte(vec + vecindex, mincoreinfo); 967 if (error) { 968 error = EFAULT; 969 goto done2; 970 } 971 972 /* 973 * If the map has changed, due to the subyte, the previous 974 * output may be invalid. 975 */ 976 vm_map_lock_read(map); 977 if (timestamp != map->timestamp) 978 goto RestartScan; 979 980 lastvecindex = vecindex; 981 addr += PAGE_SIZE; 982 } 983 } 984 985 /* 986 * subyte may page fault. In case it needs to modify 987 * the map, we release the lock. 988 */ 989 vm_map_unlock_read(map); 990 991 /* 992 * Zero the last entries in the byte vector. 993 */ 994 vecindex = OFF_TO_IDX(end - first_addr); 995 while ((lastvecindex + 1) < vecindex) { 996 error = subyte(vec + lastvecindex, 0); 997 if (error) { 998 error = EFAULT; 999 goto done2; 1000 } 1001 ++lastvecindex; 1002 } 1003 1004 /* 1005 * If the map has changed, due to the subyte, the previous 1006 * output may be invalid. 1007 */ 1008 vm_map_lock_read(map); 1009 if (timestamp != map->timestamp) 1010 goto RestartScan; 1011 vm_map_unlock_read(map); 1012 done2: 1013 return (error); 1014 } 1015 1016 #ifndef _SYS_SYSPROTO_H_ 1017 struct mlock_args { 1018 const void *addr; 1019 size_t len; 1020 }; 1021 #endif 1022 /* 1023 * MPSAFE 1024 */ 1025 int 1026 mlock(td, uap) 1027 struct thread *td; 1028 struct mlock_args *uap; 1029 { 1030 struct proc *proc; 1031 vm_offset_t addr, end, last, start; 1032 vm_size_t npages, size; 1033 int error; 1034 1035 error = priv_check(td, PRIV_VM_MLOCK); 1036 if (error) 1037 return (error); 1038 addr = (vm_offset_t)uap->addr; 1039 size = uap->len; 1040 last = addr + size; 1041 start = trunc_page(addr); 1042 end = round_page(last); 1043 if (last < addr || end < addr) 1044 return (EINVAL); 1045 npages = atop(end - start); 1046 if (npages > vm_page_max_wired) 1047 return (ENOMEM); 1048 proc = td->td_proc; 1049 PROC_LOCK(proc); 1050 if (ptoa(npages + 1051 pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) > 1052 lim_cur(proc, RLIMIT_MEMLOCK)) { 1053 PROC_UNLOCK(proc); 1054 return (ENOMEM); 1055 } 1056 PROC_UNLOCK(proc); 1057 if (npages + cnt.v_wire_count > vm_page_max_wired) 1058 return (EAGAIN); 1059 error = vm_map_wire(&proc->p_vmspace->vm_map, start, end, 1060 VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); 1061 return (error == KERN_SUCCESS ? 0 : ENOMEM); 1062 } 1063 1064 #ifndef _SYS_SYSPROTO_H_ 1065 struct mlockall_args { 1066 int how; 1067 }; 1068 #endif 1069 1070 /* 1071 * MPSAFE 1072 */ 1073 int 1074 mlockall(td, uap) 1075 struct thread *td; 1076 struct mlockall_args *uap; 1077 { 1078 vm_map_t map; 1079 int error; 1080 1081 map = &td->td_proc->p_vmspace->vm_map; 1082 error = 0; 1083 1084 if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0)) 1085 return (EINVAL); 1086 1087 #if 0 1088 /* 1089 * If wiring all pages in the process would cause it to exceed 1090 * a hard resource limit, return ENOMEM. 1091 */ 1092 PROC_LOCK(td->td_proc); 1093 if (map->size > lim_cur(td->td_proc, RLIMIT_MEMLOCK)) { 1094 PROC_UNLOCK(td->td_proc); 1095 return (ENOMEM); 1096 } 1097 PROC_UNLOCK(td->td_proc); 1098 #else 1099 error = priv_check(td, PRIV_VM_MLOCK); 1100 if (error) 1101 return (error); 1102 #endif 1103 1104 if (uap->how & MCL_FUTURE) { 1105 vm_map_lock(map); 1106 vm_map_modflags(map, MAP_WIREFUTURE, 0); 1107 vm_map_unlock(map); 1108 error = 0; 1109 } 1110 1111 if (uap->how & MCL_CURRENT) { 1112 /* 1113 * P1003.1-2001 mandates that all currently mapped pages 1114 * will be memory resident and locked (wired) upon return 1115 * from mlockall(). vm_map_wire() will wire pages, by 1116 * calling vm_fault_wire() for each page in the region. 1117 */ 1118 error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), 1119 VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); 1120 error = (error == KERN_SUCCESS ? 0 : EAGAIN); 1121 } 1122 1123 return (error); 1124 } 1125 1126 #ifndef _SYS_SYSPROTO_H_ 1127 struct munlockall_args { 1128 register_t dummy; 1129 }; 1130 #endif 1131 1132 /* 1133 * MPSAFE 1134 */ 1135 int 1136 munlockall(td, uap) 1137 struct thread *td; 1138 struct munlockall_args *uap; 1139 { 1140 vm_map_t map; 1141 int error; 1142 1143 map = &td->td_proc->p_vmspace->vm_map; 1144 error = priv_check(td, PRIV_VM_MUNLOCK); 1145 if (error) 1146 return (error); 1147 1148 /* Clear the MAP_WIREFUTURE flag from this vm_map. */ 1149 vm_map_lock(map); 1150 vm_map_modflags(map, 0, MAP_WIREFUTURE); 1151 vm_map_unlock(map); 1152 1153 /* Forcibly unwire all pages. */ 1154 error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), 1155 VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); 1156 1157 return (error); 1158 } 1159 1160 #ifndef _SYS_SYSPROTO_H_ 1161 struct munlock_args { 1162 const void *addr; 1163 size_t len; 1164 }; 1165 #endif 1166 /* 1167 * MPSAFE 1168 */ 1169 int 1170 munlock(td, uap) 1171 struct thread *td; 1172 struct munlock_args *uap; 1173 { 1174 vm_offset_t addr, end, last, start; 1175 vm_size_t size; 1176 int error; 1177 1178 error = priv_check(td, PRIV_VM_MUNLOCK); 1179 if (error) 1180 return (error); 1181 addr = (vm_offset_t)uap->addr; 1182 size = uap->len; 1183 last = addr + size; 1184 start = trunc_page(addr); 1185 end = round_page(last); 1186 if (last < addr || end < addr) 1187 return (EINVAL); 1188 error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end, 1189 VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); 1190 return (error == KERN_SUCCESS ? 0 : ENOMEM); 1191 } 1192 1193 /* 1194 * vm_mmap_vnode() 1195 * 1196 * MPSAFE 1197 * 1198 * Helper function for vm_mmap. Perform sanity check specific for mmap 1199 * operations on vnodes. 1200 */ 1201 int 1202 vm_mmap_vnode(struct thread *td, vm_size_t objsize, 1203 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1204 struct vnode *vp, vm_ooffset_t *foffp, vm_object_t *objp) 1205 { 1206 struct vattr va; 1207 vm_object_t obj; 1208 vm_offset_t foff; 1209 struct mount *mp; 1210 struct ucred *cred; 1211 int error, flags; 1212 int vfslocked; 1213 1214 mp = vp->v_mount; 1215 cred = td->td_ucred; 1216 vfslocked = VFS_LOCK_GIANT(mp); 1217 if ((error = vget(vp, LK_SHARED, td)) != 0) { 1218 VFS_UNLOCK_GIANT(vfslocked); 1219 return (error); 1220 } 1221 foff = *foffp; 1222 flags = *flagsp; 1223 obj = vp->v_object; 1224 if (vp->v_type == VREG) { 1225 /* 1226 * Get the proper underlying object 1227 */ 1228 if (obj == NULL) { 1229 error = EINVAL; 1230 goto done; 1231 } 1232 if (obj->handle != vp) { 1233 vput(vp); 1234 vp = (struct vnode*)obj->handle; 1235 vget(vp, LK_SHARED, td); 1236 } 1237 } else if (vp->v_type == VCHR) { 1238 error = vm_mmap_cdev(td, objsize, prot, maxprotp, flagsp, 1239 vp->v_rdev, foffp, objp); 1240 if (error == 0) 1241 goto mark_atime; 1242 goto done; 1243 } else { 1244 error = EINVAL; 1245 goto done; 1246 } 1247 if ((error = VOP_GETATTR(vp, &va, cred))) 1248 goto done; 1249 #ifdef MAC 1250 error = mac_vnode_check_mmap(cred, vp, prot, flags); 1251 if (error != 0) 1252 goto done; 1253 #endif 1254 if ((flags & MAP_SHARED) != 0) { 1255 if ((va.va_flags & (SF_SNAPSHOT|IMMUTABLE|APPEND)) != 0) { 1256 if (prot & PROT_WRITE) { 1257 error = EPERM; 1258 goto done; 1259 } 1260 *maxprotp &= ~VM_PROT_WRITE; 1261 } 1262 } 1263 /* 1264 * If it is a regular file without any references 1265 * we do not need to sync it. 1266 * Adjust object size to be the size of actual file. 1267 */ 1268 objsize = round_page(va.va_size); 1269 if (va.va_nlink == 0) 1270 flags |= MAP_NOSYNC; 1271 obj = vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, td->td_ucred); 1272 if (obj == NULL) { 1273 error = ENOMEM; 1274 goto done; 1275 } 1276 *objp = obj; 1277 *flagsp = flags; 1278 1279 mark_atime: 1280 vfs_mark_atime(vp, cred); 1281 1282 done: 1283 vput(vp); 1284 VFS_UNLOCK_GIANT(vfslocked); 1285 return (error); 1286 } 1287 1288 /* 1289 * vm_mmap_cdev() 1290 * 1291 * MPSAFE 1292 * 1293 * Helper function for vm_mmap. Perform sanity check specific for mmap 1294 * operations on cdevs. 1295 */ 1296 int 1297 vm_mmap_cdev(struct thread *td, vm_size_t objsize, 1298 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1299 struct cdev *cdev, vm_ooffset_t *foff, vm_object_t *objp) 1300 { 1301 vm_object_t obj; 1302 struct cdevsw *dsw; 1303 int error, flags, ref; 1304 1305 flags = *flagsp; 1306 1307 dsw = dev_refthread(cdev, &ref); 1308 if (dsw == NULL) 1309 return (ENXIO); 1310 if (dsw->d_flags & D_MMAP_ANON) { 1311 dev_relthread(cdev, ref); 1312 *maxprotp = VM_PROT_ALL; 1313 *flagsp |= MAP_ANON; 1314 return (0); 1315 } 1316 /* 1317 * cdevs do not provide private mappings of any kind. 1318 */ 1319 if ((*maxprotp & VM_PROT_WRITE) == 0 && 1320 (prot & PROT_WRITE) != 0) { 1321 dev_relthread(cdev, ref); 1322 return (EACCES); 1323 } 1324 if (flags & (MAP_PRIVATE|MAP_COPY)) { 1325 dev_relthread(cdev, ref); 1326 return (EINVAL); 1327 } 1328 /* 1329 * Force device mappings to be shared. 1330 */ 1331 flags |= MAP_SHARED; 1332 #ifdef MAC_XXX 1333 error = mac_cdev_check_mmap(td->td_ucred, cdev, prot); 1334 if (error != 0) { 1335 dev_relthread(cdev, ref); 1336 return (error); 1337 } 1338 #endif 1339 /* 1340 * First, try d_mmap_single(). If that is not implemented 1341 * (returns ENODEV), fall back to using the device pager. 1342 * Note that d_mmap_single() must return a reference to the 1343 * object (it needs to bump the reference count of the object 1344 * it returns somehow). 1345 * 1346 * XXX assumes VM_PROT_* == PROT_* 1347 */ 1348 error = dsw->d_mmap_single(cdev, foff, objsize, objp, (int)prot); 1349 dev_relthread(cdev, ref); 1350 if (error != ENODEV) 1351 return (error); 1352 obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, *foff, 1353 td->td_ucred); 1354 if (obj == NULL) 1355 return (EINVAL); 1356 *objp = obj; 1357 *flagsp = flags; 1358 return (0); 1359 } 1360 1361 /* 1362 * vm_mmap_shm() 1363 * 1364 * MPSAFE 1365 * 1366 * Helper function for vm_mmap. Perform sanity check specific for mmap 1367 * operations on shm file descriptors. 1368 */ 1369 int 1370 vm_mmap_shm(struct thread *td, vm_size_t objsize, 1371 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1372 struct shmfd *shmfd, vm_ooffset_t foff, vm_object_t *objp) 1373 { 1374 int error; 1375 1376 if ((*flagsp & MAP_SHARED) != 0 && 1377 (*maxprotp & VM_PROT_WRITE) == 0 && 1378 (prot & PROT_WRITE) != 0) 1379 return (EACCES); 1380 #ifdef MAC 1381 error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, *flagsp); 1382 if (error != 0) 1383 return (error); 1384 #endif 1385 error = shm_mmap(shmfd, objsize, foff, objp); 1386 if (error) 1387 return (error); 1388 return (0); 1389 } 1390 1391 /* 1392 * vm_mmap() 1393 * 1394 * MPSAFE 1395 * 1396 * Internal version of mmap. Currently used by mmap, exec, and sys5 1397 * shared memory. Handle is either a vnode pointer or NULL for MAP_ANON. 1398 */ 1399 int 1400 vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, 1401 vm_prot_t maxprot, int flags, 1402 objtype_t handle_type, void *handle, 1403 vm_ooffset_t foff) 1404 { 1405 boolean_t fitit; 1406 vm_object_t object = NULL; 1407 int rv = KERN_SUCCESS; 1408 int docow, error; 1409 struct thread *td = curthread; 1410 1411 if (size == 0) 1412 return (0); 1413 1414 size = round_page(size); 1415 1416 PROC_LOCK(td->td_proc); 1417 if (td->td_proc->p_vmspace->vm_map.size + size > 1418 lim_cur(td->td_proc, RLIMIT_VMEM)) { 1419 PROC_UNLOCK(td->td_proc); 1420 return(ENOMEM); 1421 } 1422 PROC_UNLOCK(td->td_proc); 1423 1424 /* 1425 * We currently can only deal with page aligned file offsets. 1426 * The check is here rather than in the syscall because the 1427 * kernel calls this function internally for other mmaping 1428 * operations (such as in exec) and non-aligned offsets will 1429 * cause pmap inconsistencies...so we want to be sure to 1430 * disallow this in all cases. 1431 */ 1432 if (foff & PAGE_MASK) 1433 return (EINVAL); 1434 1435 if ((flags & MAP_FIXED) == 0) { 1436 fitit = TRUE; 1437 *addr = round_page(*addr); 1438 } else { 1439 if (*addr != trunc_page(*addr)) 1440 return (EINVAL); 1441 fitit = FALSE; 1442 } 1443 /* 1444 * Lookup/allocate object. 1445 */ 1446 switch (handle_type) { 1447 case OBJT_DEVICE: 1448 error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, 1449 handle, &foff, &object); 1450 break; 1451 case OBJT_VNODE: 1452 error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, 1453 handle, &foff, &object); 1454 break; 1455 case OBJT_SWAP: 1456 error = vm_mmap_shm(td, size, prot, &maxprot, &flags, 1457 handle, foff, &object); 1458 break; 1459 case OBJT_DEFAULT: 1460 if (handle == NULL) { 1461 error = 0; 1462 break; 1463 } 1464 /* FALLTHROUGH */ 1465 default: 1466 error = EINVAL; 1467 break; 1468 } 1469 if (error) 1470 return (error); 1471 if (flags & MAP_ANON) { 1472 object = NULL; 1473 docow = 0; 1474 /* 1475 * Unnamed anonymous regions always start at 0. 1476 */ 1477 if (handle == 0) 1478 foff = 0; 1479 } else if (flags & MAP_PREFAULT_READ) 1480 docow = MAP_PREFAULT; 1481 else 1482 docow = MAP_PREFAULT_PARTIAL; 1483 1484 if ((flags & (MAP_ANON|MAP_SHARED)) == 0) 1485 docow |= MAP_COPY_ON_WRITE; 1486 if (flags & MAP_NOSYNC) 1487 docow |= MAP_DISABLE_SYNCER; 1488 if (flags & MAP_NOCORE) 1489 docow |= MAP_DISABLE_COREDUMP; 1490 1491 if (flags & MAP_STACK) 1492 rv = vm_map_stack(map, *addr, size, prot, maxprot, 1493 docow | MAP_STACK_GROWS_DOWN); 1494 else if (fitit) 1495 rv = vm_map_find(map, object, foff, addr, size, 1496 object != NULL && object->type == OBJT_DEVICE ? 1497 VMFS_ALIGNED_SPACE : VMFS_ANY_SPACE, prot, maxprot, docow); 1498 else 1499 rv = vm_map_fixed(map, object, foff, *addr, size, 1500 prot, maxprot, docow); 1501 1502 if (rv != KERN_SUCCESS) { 1503 /* 1504 * Lose the object reference. Will destroy the 1505 * object if it's an unnamed anonymous mapping 1506 * or named anonymous without other references. 1507 */ 1508 vm_object_deallocate(object); 1509 } else if (flags & MAP_SHARED) { 1510 /* 1511 * Shared memory is also shared with children. 1512 */ 1513 rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE); 1514 if (rv != KERN_SUCCESS) 1515 (void) vm_map_remove(map, *addr, *addr + size); 1516 } 1517 1518 /* 1519 * If the process has requested that all future mappings 1520 * be wired, then heed this. 1521 */ 1522 if ((rv == KERN_SUCCESS) && (map->flags & MAP_WIREFUTURE)) 1523 vm_map_wire(map, *addr, *addr + size, 1524 VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 1525 1526 switch (rv) { 1527 case KERN_SUCCESS: 1528 return (0); 1529 case KERN_INVALID_ADDRESS: 1530 case KERN_NO_SPACE: 1531 return (ENOMEM); 1532 case KERN_PROTECTION_FAILURE: 1533 return (EACCES); 1534 default: 1535 return (EINVAL); 1536 } 1537 } 1538