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 #include "opt_mac.h" 49 50 #include <sys/param.h> 51 #include <sys/systm.h> 52 #include <sys/kernel.h> 53 #include <sys/lock.h> 54 #include <sys/mutex.h> 55 #include <sys/sysproto.h> 56 #include <sys/filedesc.h> 57 #include <sys/priv.h> 58 #include <sys/proc.h> 59 #include <sys/resource.h> 60 #include <sys/resourcevar.h> 61 #include <sys/vnode.h> 62 #include <sys/fcntl.h> 63 #include <sys/file.h> 64 #include <sys/mman.h> 65 #include <sys/mount.h> 66 #include <sys/conf.h> 67 #include <sys/stat.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 98 /* 99 * Set the maximum number of vm_map_entry structures per process. Roughly 100 * speaking vm_map_entry structures are tiny, so allowing them to eat 1/100 101 * of our KVM malloc space still results in generous limits. We want a 102 * default that is good enough to prevent the kernel running out of resources 103 * if attacked from compromised user account but generous enough such that 104 * multi-threaded processes are not unduly inconvenienced. 105 */ 106 static void vmmapentry_rsrc_init(void *); 107 SYSINIT(vmmersrc, SI_SUB_KVM_RSRC, SI_ORDER_FIRST, vmmapentry_rsrc_init, 108 NULL); 109 110 static void 111 vmmapentry_rsrc_init(dummy) 112 void *dummy; 113 { 114 max_proc_mmap = vm_kmem_size / sizeof(struct vm_map_entry); 115 max_proc_mmap /= 100; 116 } 117 118 static int vm_mmap_vnode(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, 119 int *, struct vnode *, vm_ooffset_t, vm_object_t *); 120 static int vm_mmap_cdev(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, 121 int *, struct cdev *, vm_ooffset_t, vm_object_t *); 122 static int vm_mmap_shm(struct thread *, vm_size_t, vm_prot_t, vm_prot_t *, 123 int *, struct shmfd *, vm_ooffset_t, vm_object_t *); 124 125 /* 126 * MPSAFE 127 */ 128 /* ARGSUSED */ 129 int 130 sbrk(td, uap) 131 struct thread *td; 132 struct sbrk_args *uap; 133 { 134 /* Not yet implemented */ 135 return (EOPNOTSUPP); 136 } 137 138 #ifndef _SYS_SYSPROTO_H_ 139 struct sstk_args { 140 int incr; 141 }; 142 #endif 143 144 /* 145 * MPSAFE 146 */ 147 /* ARGSUSED */ 148 int 149 sstk(td, uap) 150 struct thread *td; 151 struct sstk_args *uap; 152 { 153 /* Not yet implemented */ 154 return (EOPNOTSUPP); 155 } 156 157 #if defined(COMPAT_43) 158 #ifndef _SYS_SYSPROTO_H_ 159 struct getpagesize_args { 160 int dummy; 161 }; 162 #endif 163 164 /* ARGSUSED */ 165 int 166 ogetpagesize(td, uap) 167 struct thread *td; 168 struct getpagesize_args *uap; 169 { 170 /* MP SAFE */ 171 td->td_retval[0] = PAGE_SIZE; 172 return (0); 173 } 174 #endif /* COMPAT_43 */ 175 176 177 /* 178 * Memory Map (mmap) system call. Note that the file offset 179 * and address are allowed to be NOT page aligned, though if 180 * the MAP_FIXED flag it set, both must have the same remainder 181 * modulo the PAGE_SIZE (POSIX 1003.1b). If the address is not 182 * page-aligned, the actual mapping starts at trunc_page(addr) 183 * and the return value is adjusted up by the page offset. 184 * 185 * Generally speaking, only character devices which are themselves 186 * memory-based, such as a video framebuffer, can be mmap'd. Otherwise 187 * there would be no cache coherency between a descriptor and a VM mapping 188 * both to the same character device. 189 * 190 * Block devices can be mmap'd no matter what they represent. Cache coherency 191 * is maintained as long as you do not write directly to the underlying 192 * character device. 193 */ 194 #ifndef _SYS_SYSPROTO_H_ 195 struct mmap_args { 196 void *addr; 197 size_t len; 198 int prot; 199 int flags; 200 int fd; 201 long pad; 202 off_t pos; 203 }; 204 #endif 205 206 /* 207 * MPSAFE 208 */ 209 int 210 mmap(td, uap) 211 struct thread *td; 212 struct mmap_args *uap; 213 { 214 #ifdef HWPMC_HOOKS 215 struct pmckern_map_in pkm; 216 #endif 217 struct file *fp; 218 struct vnode *vp; 219 vm_offset_t addr; 220 vm_size_t size, pageoff; 221 vm_prot_t prot, maxprot; 222 void *handle; 223 objtype_t handle_type; 224 int flags, error; 225 off_t pos; 226 struct vmspace *vms = td->td_proc->p_vmspace; 227 228 addr = (vm_offset_t) uap->addr; 229 size = uap->len; 230 prot = uap->prot & VM_PROT_ALL; 231 flags = uap->flags; 232 pos = uap->pos; 233 234 fp = NULL; 235 /* make sure mapping fits into numeric range etc */ 236 if ((ssize_t) uap->len < 0 || 237 ((flags & MAP_ANON) && uap->fd != -1)) 238 return (EINVAL); 239 240 if (flags & MAP_STACK) { 241 if ((uap->fd != -1) || 242 ((prot & (PROT_READ | PROT_WRITE)) != (PROT_READ | PROT_WRITE))) 243 return (EINVAL); 244 flags |= MAP_ANON; 245 pos = 0; 246 } 247 248 /* 249 * Align the file position to a page boundary, 250 * and save its page offset component. 251 */ 252 pageoff = (pos & PAGE_MASK); 253 pos -= pageoff; 254 255 /* Adjust size for rounding (on both ends). */ 256 size += pageoff; /* low end... */ 257 size = (vm_size_t) round_page(size); /* hi end */ 258 259 /* 260 * Check for illegal addresses. Watch out for address wrap... Note 261 * that VM_*_ADDRESS are not constants due to casts (argh). 262 */ 263 if (flags & MAP_FIXED) { 264 /* 265 * The specified address must have the same remainder 266 * as the file offset taken modulo PAGE_SIZE, so it 267 * should be aligned after adjustment by pageoff. 268 */ 269 addr -= pageoff; 270 if (addr & PAGE_MASK) 271 return (EINVAL); 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 pos = 0; 304 } else { 305 /* 306 * Mapping file, get fp for validation and 307 * don't let the descriptor disappear on us if we block. 308 */ 309 if ((error = fget(td, uap->fd, &fp)) != 0) 310 goto done; 311 if (fp->f_type == DTYPE_SHM) { 312 handle = fp->f_data; 313 handle_type = OBJT_SWAP; 314 maxprot = VM_PROT_NONE; 315 316 /* FREAD should always be set. */ 317 if (fp->f_flag & FREAD) 318 maxprot |= VM_PROT_EXECUTE | VM_PROT_READ; 319 if (fp->f_flag & FWRITE) 320 maxprot |= VM_PROT_WRITE; 321 goto map; 322 } 323 if (fp->f_type != DTYPE_VNODE) { 324 error = ENODEV; 325 goto done; 326 } 327 #if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \ 328 defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4) 329 /* 330 * POSIX shared-memory objects are defined to have 331 * kernel persistence, and are not defined to support 332 * read(2)/write(2) -- or even open(2). Thus, we can 333 * use MAP_ASYNC to trade on-disk coherence for speed. 334 * The shm_open(3) library routine turns on the FPOSIXSHM 335 * flag to request this behavior. 336 */ 337 if (fp->f_flag & FPOSIXSHM) 338 flags |= MAP_NOSYNC; 339 #endif 340 vp = fp->f_vnode; 341 /* 342 * Ensure that file and memory protections are 343 * compatible. Note that we only worry about 344 * writability if mapping is shared; in this case, 345 * current and max prot are dictated by the open file. 346 * XXX use the vnode instead? Problem is: what 347 * credentials do we use for determination? What if 348 * proc does a setuid? 349 */ 350 if (vp->v_mount != NULL && vp->v_mount->mnt_flag & MNT_NOEXEC) 351 maxprot = VM_PROT_NONE; 352 else 353 maxprot = VM_PROT_EXECUTE; 354 if (fp->f_flag & FREAD) { 355 maxprot |= VM_PROT_READ; 356 } else if (prot & PROT_READ) { 357 error = EACCES; 358 goto done; 359 } 360 /* 361 * If we are sharing potential changes (either via 362 * MAP_SHARED or via the implicit sharing of character 363 * device mappings), and we are trying to get write 364 * permission although we opened it without asking 365 * for it, bail out. 366 */ 367 if ((flags & MAP_SHARED) != 0) { 368 if ((fp->f_flag & FWRITE) != 0) { 369 maxprot |= VM_PROT_WRITE; 370 } else if ((prot & PROT_WRITE) != 0) { 371 error = EACCES; 372 goto done; 373 } 374 } else if (vp->v_type != VCHR || (fp->f_flag & FWRITE) != 0) { 375 maxprot |= VM_PROT_WRITE; 376 } 377 handle = (void *)vp; 378 handle_type = OBJT_VNODE; 379 } 380 map: 381 382 /* 383 * Do not allow more then a certain number of vm_map_entry structures 384 * per process. Scale with the number of rforks sharing the map 385 * to make the limit reasonable for threads. 386 */ 387 if (max_proc_mmap && 388 vms->vm_map.nentries >= max_proc_mmap * vms->vm_refcnt) { 389 error = ENOMEM; 390 goto done; 391 } 392 393 error = vm_mmap(&vms->vm_map, &addr, size, prot, maxprot, 394 flags, handle_type, handle, pos); 395 #ifdef HWPMC_HOOKS 396 /* inform hwpmc(4) if an executable is being mapped */ 397 if (error == 0 && handle_type == OBJT_VNODE && 398 (prot & PROT_EXEC)) { 399 pkm.pm_file = handle; 400 pkm.pm_address = (uintptr_t) addr; 401 PMC_CALL_HOOK(td, PMC_FN_MMAP, (void *) &pkm); 402 } 403 #endif 404 if (error == 0) 405 td->td_retval[0] = (register_t) (addr + pageoff); 406 done: 407 if (fp) 408 fdrop(fp, td); 409 410 return (error); 411 } 412 413 int 414 freebsd6_mmap(struct thread *td, struct freebsd6_mmap_args *uap) 415 { 416 struct mmap_args oargs; 417 418 oargs.addr = uap->addr; 419 oargs.len = uap->len; 420 oargs.prot = uap->prot; 421 oargs.flags = uap->flags; 422 oargs.fd = uap->fd; 423 oargs.pos = uap->pos; 424 return (mmap(td, &oargs)); 425 } 426 427 #ifdef COMPAT_43 428 #ifndef _SYS_SYSPROTO_H_ 429 struct ommap_args { 430 caddr_t addr; 431 int len; 432 int prot; 433 int flags; 434 int fd; 435 long pos; 436 }; 437 #endif 438 int 439 ommap(td, uap) 440 struct thread *td; 441 struct ommap_args *uap; 442 { 443 struct mmap_args nargs; 444 static const char cvtbsdprot[8] = { 445 0, 446 PROT_EXEC, 447 PROT_WRITE, 448 PROT_EXEC | PROT_WRITE, 449 PROT_READ, 450 PROT_EXEC | PROT_READ, 451 PROT_WRITE | PROT_READ, 452 PROT_EXEC | PROT_WRITE | PROT_READ, 453 }; 454 455 #define OMAP_ANON 0x0002 456 #define OMAP_COPY 0x0020 457 #define OMAP_SHARED 0x0010 458 #define OMAP_FIXED 0x0100 459 460 nargs.addr = uap->addr; 461 nargs.len = uap->len; 462 nargs.prot = cvtbsdprot[uap->prot & 0x7]; 463 nargs.flags = 0; 464 if (uap->flags & OMAP_ANON) 465 nargs.flags |= MAP_ANON; 466 if (uap->flags & OMAP_COPY) 467 nargs.flags |= MAP_COPY; 468 if (uap->flags & OMAP_SHARED) 469 nargs.flags |= MAP_SHARED; 470 else 471 nargs.flags |= MAP_PRIVATE; 472 if (uap->flags & OMAP_FIXED) 473 nargs.flags |= MAP_FIXED; 474 nargs.fd = uap->fd; 475 nargs.pos = uap->pos; 476 return (mmap(td, &nargs)); 477 } 478 #endif /* COMPAT_43 */ 479 480 481 #ifndef _SYS_SYSPROTO_H_ 482 struct msync_args { 483 void *addr; 484 size_t len; 485 int flags; 486 }; 487 #endif 488 /* 489 * MPSAFE 490 */ 491 int 492 msync(td, uap) 493 struct thread *td; 494 struct msync_args *uap; 495 { 496 vm_offset_t addr; 497 vm_size_t size, pageoff; 498 int flags; 499 vm_map_t map; 500 int rv; 501 502 addr = (vm_offset_t) uap->addr; 503 size = uap->len; 504 flags = uap->flags; 505 506 pageoff = (addr & PAGE_MASK); 507 addr -= pageoff; 508 size += pageoff; 509 size = (vm_size_t) round_page(size); 510 if (addr + size < addr) 511 return (EINVAL); 512 513 if ((flags & (MS_ASYNC|MS_INVALIDATE)) == (MS_ASYNC|MS_INVALIDATE)) 514 return (EINVAL); 515 516 map = &td->td_proc->p_vmspace->vm_map; 517 518 /* 519 * Clean the pages and interpret the return value. 520 */ 521 rv = vm_map_sync(map, addr, addr + size, (flags & MS_ASYNC) == 0, 522 (flags & MS_INVALIDATE) != 0); 523 switch (rv) { 524 case KERN_SUCCESS: 525 return (0); 526 case KERN_INVALID_ADDRESS: 527 return (EINVAL); /* Sun returns ENOMEM? */ 528 case KERN_INVALID_ARGUMENT: 529 return (EBUSY); 530 default: 531 return (EINVAL); 532 } 533 } 534 535 #ifndef _SYS_SYSPROTO_H_ 536 struct munmap_args { 537 void *addr; 538 size_t len; 539 }; 540 #endif 541 /* 542 * MPSAFE 543 */ 544 int 545 munmap(td, uap) 546 struct thread *td; 547 struct munmap_args *uap; 548 { 549 #ifdef HWPMC_HOOKS 550 struct pmckern_map_out pkm; 551 vm_map_entry_t entry; 552 #endif 553 vm_offset_t addr; 554 vm_size_t size, pageoff; 555 vm_map_t map; 556 557 addr = (vm_offset_t) uap->addr; 558 size = uap->len; 559 if (size == 0) 560 return (EINVAL); 561 562 pageoff = (addr & PAGE_MASK); 563 addr -= pageoff; 564 size += pageoff; 565 size = (vm_size_t) round_page(size); 566 if (addr + size < addr) 567 return (EINVAL); 568 569 /* 570 * Check for illegal addresses. Watch out for address wrap... 571 */ 572 map = &td->td_proc->p_vmspace->vm_map; 573 if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) 574 return (EINVAL); 575 vm_map_lock(map); 576 /* 577 * Make sure entire range is allocated. 578 */ 579 if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE)) { 580 vm_map_unlock(map); 581 return (EINVAL); 582 } 583 #ifdef HWPMC_HOOKS 584 /* 585 * Inform hwpmc if the address range being unmapped contains 586 * an executable region. 587 */ 588 if (vm_map_lookup_entry(map, addr, &entry)) { 589 for (; 590 entry != &map->header && entry->start < addr + size; 591 entry = entry->next) { 592 if (vm_map_check_protection(map, entry->start, 593 entry->end, VM_PROT_EXECUTE) == TRUE) { 594 pkm.pm_address = (uintptr_t) addr; 595 pkm.pm_size = (size_t) size; 596 PMC_CALL_HOOK(td, PMC_FN_MUNMAP, 597 (void *) &pkm); 598 break; 599 } 600 } 601 } 602 #endif 603 /* returns nothing but KERN_SUCCESS anyway */ 604 vm_map_delete(map, addr, addr + size); 605 vm_map_unlock(map); 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 #if defined(VM_PROT_READ_IS_EXEC) 632 if (prot & VM_PROT_READ) 633 prot |= VM_PROT_EXECUTE; 634 #endif 635 636 pageoff = (addr & PAGE_MASK); 637 addr -= pageoff; 638 size += pageoff; 639 size = (vm_size_t) round_page(size); 640 if (addr + size < addr) 641 return (EINVAL); 642 643 switch (vm_map_protect(&td->td_proc->p_vmspace->vm_map, addr, 644 addr + size, prot, FALSE)) { 645 case KERN_SUCCESS: 646 return (0); 647 case KERN_PROTECTION_FAILURE: 648 return (EACCES); 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 int mincoreinfo; 784 unsigned int timestamp; 785 786 /* 787 * Make sure that the addresses presented are valid for user 788 * mode. 789 */ 790 first_addr = addr = trunc_page((vm_offset_t) uap->addr); 791 end = addr + (vm_size_t)round_page(uap->len); 792 map = &td->td_proc->p_vmspace->vm_map; 793 if (end > vm_map_max(map) || end < addr) 794 return (ENOMEM); 795 796 /* 797 * Address of byte vector 798 */ 799 vec = uap->vec; 800 801 pmap = vmspace_pmap(td->td_proc->p_vmspace); 802 803 vm_map_lock_read(map); 804 RestartScan: 805 timestamp = map->timestamp; 806 807 if (!vm_map_lookup_entry(map, addr, &entry)) { 808 vm_map_unlock_read(map); 809 return (ENOMEM); 810 } 811 812 /* 813 * Do this on a map entry basis so that if the pages are not 814 * in the current processes address space, we can easily look 815 * up the pages elsewhere. 816 */ 817 lastvecindex = -1; 818 for (current = entry; 819 (current != &map->header) && (current->start < end); 820 current = current->next) { 821 822 /* 823 * check for contiguity 824 */ 825 if (current->end < end && 826 (entry->next == &map->header || 827 current->next->start > current->end)) { 828 vm_map_unlock_read(map); 829 return (ENOMEM); 830 } 831 832 /* 833 * ignore submaps (for now) or null objects 834 */ 835 if ((current->eflags & MAP_ENTRY_IS_SUB_MAP) || 836 current->object.vm_object == NULL) 837 continue; 838 839 /* 840 * limit this scan to the current map entry and the 841 * limits for the mincore call 842 */ 843 if (addr < current->start) 844 addr = current->start; 845 cend = current->end; 846 if (cend > end) 847 cend = end; 848 849 /* 850 * scan this entry one page at a time 851 */ 852 while (addr < cend) { 853 /* 854 * Check pmap first, it is likely faster, also 855 * it can provide info as to whether we are the 856 * one referencing or modifying the page. 857 */ 858 mincoreinfo = pmap_mincore(pmap, addr); 859 if (!mincoreinfo) { 860 vm_pindex_t pindex; 861 vm_ooffset_t offset; 862 vm_page_t m; 863 /* 864 * calculate the page index into the object 865 */ 866 offset = current->offset + (addr - current->start); 867 pindex = OFF_TO_IDX(offset); 868 VM_OBJECT_LOCK(current->object.vm_object); 869 m = vm_page_lookup(current->object.vm_object, 870 pindex); 871 /* 872 * if the page is resident, then gather information about 873 * it. 874 */ 875 if (m != NULL && m->valid != 0) { 876 mincoreinfo = MINCORE_INCORE; 877 vm_page_lock_queues(); 878 if (m->dirty || 879 pmap_is_modified(m)) 880 mincoreinfo |= MINCORE_MODIFIED_OTHER; 881 if ((m->flags & PG_REFERENCED) || 882 pmap_ts_referenced(m)) { 883 vm_page_flag_set(m, PG_REFERENCED); 884 mincoreinfo |= MINCORE_REFERENCED_OTHER; 885 } 886 vm_page_unlock_queues(); 887 } 888 VM_OBJECT_UNLOCK(current->object.vm_object); 889 } 890 891 /* 892 * subyte may page fault. In case it needs to modify 893 * the map, we release the lock. 894 */ 895 vm_map_unlock_read(map); 896 897 /* 898 * calculate index into user supplied byte vector 899 */ 900 vecindex = OFF_TO_IDX(addr - first_addr); 901 902 /* 903 * If we have skipped map entries, we need to make sure that 904 * the byte vector is zeroed for those skipped entries. 905 */ 906 while ((lastvecindex + 1) < vecindex) { 907 error = subyte(vec + lastvecindex, 0); 908 if (error) { 909 error = EFAULT; 910 goto done2; 911 } 912 ++lastvecindex; 913 } 914 915 /* 916 * Pass the page information to the user 917 */ 918 error = subyte(vec + vecindex, mincoreinfo); 919 if (error) { 920 error = EFAULT; 921 goto done2; 922 } 923 924 /* 925 * If the map has changed, due to the subyte, the previous 926 * output may be invalid. 927 */ 928 vm_map_lock_read(map); 929 if (timestamp != map->timestamp) 930 goto RestartScan; 931 932 lastvecindex = vecindex; 933 addr += PAGE_SIZE; 934 } 935 } 936 937 /* 938 * subyte may page fault. In case it needs to modify 939 * the map, we release the lock. 940 */ 941 vm_map_unlock_read(map); 942 943 /* 944 * Zero the last entries in the byte vector. 945 */ 946 vecindex = OFF_TO_IDX(end - first_addr); 947 while ((lastvecindex + 1) < vecindex) { 948 error = subyte(vec + lastvecindex, 0); 949 if (error) { 950 error = EFAULT; 951 goto done2; 952 } 953 ++lastvecindex; 954 } 955 956 /* 957 * If the map has changed, due to the subyte, the previous 958 * output may be invalid. 959 */ 960 vm_map_lock_read(map); 961 if (timestamp != map->timestamp) 962 goto RestartScan; 963 vm_map_unlock_read(map); 964 done2: 965 return (error); 966 } 967 968 #ifndef _SYS_SYSPROTO_H_ 969 struct mlock_args { 970 const void *addr; 971 size_t len; 972 }; 973 #endif 974 /* 975 * MPSAFE 976 */ 977 int 978 mlock(td, uap) 979 struct thread *td; 980 struct mlock_args *uap; 981 { 982 struct proc *proc; 983 vm_offset_t addr, end, last, start; 984 vm_size_t npages, size; 985 int error; 986 987 error = priv_check(td, PRIV_VM_MLOCK); 988 if (error) 989 return (error); 990 addr = (vm_offset_t)uap->addr; 991 size = uap->len; 992 last = addr + size; 993 start = trunc_page(addr); 994 end = round_page(last); 995 if (last < addr || end < addr) 996 return (EINVAL); 997 npages = atop(end - start); 998 if (npages > vm_page_max_wired) 999 return (ENOMEM); 1000 proc = td->td_proc; 1001 PROC_LOCK(proc); 1002 if (ptoa(npages + 1003 pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) > 1004 lim_cur(proc, RLIMIT_MEMLOCK)) { 1005 PROC_UNLOCK(proc); 1006 return (ENOMEM); 1007 } 1008 PROC_UNLOCK(proc); 1009 if (npages + cnt.v_wire_count > vm_page_max_wired) 1010 return (EAGAIN); 1011 error = vm_map_wire(&proc->p_vmspace->vm_map, start, end, 1012 VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); 1013 return (error == KERN_SUCCESS ? 0 : ENOMEM); 1014 } 1015 1016 #ifndef _SYS_SYSPROTO_H_ 1017 struct mlockall_args { 1018 int how; 1019 }; 1020 #endif 1021 1022 /* 1023 * MPSAFE 1024 */ 1025 int 1026 mlockall(td, uap) 1027 struct thread *td; 1028 struct mlockall_args *uap; 1029 { 1030 vm_map_t map; 1031 int error; 1032 1033 map = &td->td_proc->p_vmspace->vm_map; 1034 error = 0; 1035 1036 if ((uap->how == 0) || ((uap->how & ~(MCL_CURRENT|MCL_FUTURE)) != 0)) 1037 return (EINVAL); 1038 1039 #if 0 1040 /* 1041 * If wiring all pages in the process would cause it to exceed 1042 * a hard resource limit, return ENOMEM. 1043 */ 1044 PROC_LOCK(td->td_proc); 1045 if (map->size - ptoa(pmap_wired_count(vm_map_pmap(map)) > 1046 lim_cur(td->td_proc, RLIMIT_MEMLOCK))) { 1047 PROC_UNLOCK(td->td_proc); 1048 return (ENOMEM); 1049 } 1050 PROC_UNLOCK(td->td_proc); 1051 #else 1052 error = priv_check(td, PRIV_VM_MLOCK); 1053 if (error) 1054 return (error); 1055 #endif 1056 1057 if (uap->how & MCL_FUTURE) { 1058 vm_map_lock(map); 1059 vm_map_modflags(map, MAP_WIREFUTURE, 0); 1060 vm_map_unlock(map); 1061 error = 0; 1062 } 1063 1064 if (uap->how & MCL_CURRENT) { 1065 /* 1066 * P1003.1-2001 mandates that all currently mapped pages 1067 * will be memory resident and locked (wired) upon return 1068 * from mlockall(). vm_map_wire() will wire pages, by 1069 * calling vm_fault_wire() for each page in the region. 1070 */ 1071 error = vm_map_wire(map, vm_map_min(map), vm_map_max(map), 1072 VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); 1073 error = (error == KERN_SUCCESS ? 0 : EAGAIN); 1074 } 1075 1076 return (error); 1077 } 1078 1079 #ifndef _SYS_SYSPROTO_H_ 1080 struct munlockall_args { 1081 register_t dummy; 1082 }; 1083 #endif 1084 1085 /* 1086 * MPSAFE 1087 */ 1088 int 1089 munlockall(td, uap) 1090 struct thread *td; 1091 struct munlockall_args *uap; 1092 { 1093 vm_map_t map; 1094 int error; 1095 1096 map = &td->td_proc->p_vmspace->vm_map; 1097 error = priv_check(td, PRIV_VM_MUNLOCK); 1098 if (error) 1099 return (error); 1100 1101 /* Clear the MAP_WIREFUTURE flag from this vm_map. */ 1102 vm_map_lock(map); 1103 vm_map_modflags(map, 0, MAP_WIREFUTURE); 1104 vm_map_unlock(map); 1105 1106 /* Forcibly unwire all pages. */ 1107 error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map), 1108 VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK); 1109 1110 return (error); 1111 } 1112 1113 #ifndef _SYS_SYSPROTO_H_ 1114 struct munlock_args { 1115 const void *addr; 1116 size_t len; 1117 }; 1118 #endif 1119 /* 1120 * MPSAFE 1121 */ 1122 int 1123 munlock(td, uap) 1124 struct thread *td; 1125 struct munlock_args *uap; 1126 { 1127 vm_offset_t addr, end, last, start; 1128 vm_size_t size; 1129 int error; 1130 1131 error = priv_check(td, PRIV_VM_MUNLOCK); 1132 if (error) 1133 return (error); 1134 addr = (vm_offset_t)uap->addr; 1135 size = uap->len; 1136 last = addr + size; 1137 start = trunc_page(addr); 1138 end = round_page(last); 1139 if (last < addr || end < addr) 1140 return (EINVAL); 1141 error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end, 1142 VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); 1143 return (error == KERN_SUCCESS ? 0 : ENOMEM); 1144 } 1145 1146 /* 1147 * vm_mmap_vnode() 1148 * 1149 * MPSAFE 1150 * 1151 * Helper function for vm_mmap. Perform sanity check specific for mmap 1152 * operations on vnodes. 1153 */ 1154 int 1155 vm_mmap_vnode(struct thread *td, vm_size_t objsize, 1156 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1157 struct vnode *vp, vm_ooffset_t foff, vm_object_t *objp) 1158 { 1159 struct vattr va; 1160 void *handle; 1161 vm_object_t obj; 1162 struct mount *mp; 1163 struct cdevsw *dsw; 1164 int error, flags, type; 1165 int vfslocked; 1166 1167 mp = vp->v_mount; 1168 vfslocked = VFS_LOCK_GIANT(mp); 1169 if ((error = vget(vp, LK_EXCLUSIVE, td)) != 0) { 1170 VFS_UNLOCK_GIANT(vfslocked); 1171 return (error); 1172 } 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_EXCLUSIVE, td); 1187 } 1188 type = OBJT_VNODE; 1189 handle = vp; 1190 } else if (vp->v_type == VCHR) { 1191 type = OBJT_DEVICE; 1192 handle = vp->v_rdev; 1193 1194 dsw = dev_refthread(handle); 1195 if (dsw == NULL) { 1196 error = ENXIO; 1197 goto done; 1198 } 1199 if (dsw->d_flags & D_MMAP_ANON) { 1200 dev_relthread(handle); 1201 *maxprotp = VM_PROT_ALL; 1202 *flagsp |= MAP_ANON; 1203 error = 0; 1204 goto done; 1205 } 1206 dev_relthread(handle); 1207 /* 1208 * cdevs does not provide private mappings of any kind. 1209 */ 1210 if ((*maxprotp & VM_PROT_WRITE) == 0 && 1211 (prot & PROT_WRITE) != 0) { 1212 error = EACCES; 1213 goto done; 1214 } 1215 if (flags & (MAP_PRIVATE|MAP_COPY)) { 1216 error = EINVAL; 1217 goto done; 1218 } 1219 /* 1220 * Force device mappings to be shared. 1221 */ 1222 flags |= MAP_SHARED; 1223 } else { 1224 error = EINVAL; 1225 goto done; 1226 } 1227 if ((error = VOP_GETATTR(vp, &va, td->td_ucred, td))) { 1228 goto done; 1229 } 1230 #ifdef MAC 1231 error = mac_vnode_check_mmap(td->td_ucred, vp, prot, flags); 1232 if (error != 0) 1233 goto done; 1234 #endif 1235 if ((flags & MAP_SHARED) != 0) { 1236 if ((va.va_flags & (SF_SNAPSHOT|IMMUTABLE|APPEND)) != 0) { 1237 if (prot & PROT_WRITE) { 1238 error = EPERM; 1239 goto done; 1240 } 1241 *maxprotp &= ~VM_PROT_WRITE; 1242 } 1243 } 1244 /* 1245 * If it is a regular file without any references 1246 * we do not need to sync it. 1247 * Adjust object size to be the size of actual file. 1248 */ 1249 if (vp->v_type == VREG) { 1250 objsize = round_page(va.va_size); 1251 if (va.va_nlink == 0) 1252 flags |= MAP_NOSYNC; 1253 } 1254 obj = vm_pager_allocate(type, handle, objsize, prot, foff); 1255 if (obj == NULL) { 1256 error = (type == OBJT_DEVICE ? EINVAL : ENOMEM); 1257 goto done; 1258 } 1259 *objp = obj; 1260 *flagsp = flags; 1261 vfs_mark_atime(vp, td); 1262 1263 done: 1264 vput(vp); 1265 VFS_UNLOCK_GIANT(vfslocked); 1266 return (error); 1267 } 1268 1269 /* 1270 * vm_mmap_cdev() 1271 * 1272 * MPSAFE 1273 * 1274 * Helper function for vm_mmap. Perform sanity check specific for mmap 1275 * operations on cdevs. 1276 */ 1277 int 1278 vm_mmap_cdev(struct thread *td, vm_size_t objsize, 1279 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1280 struct cdev *cdev, vm_ooffset_t foff, vm_object_t *objp) 1281 { 1282 vm_object_t obj; 1283 struct cdevsw *dsw; 1284 int flags; 1285 1286 flags = *flagsp; 1287 1288 dsw = dev_refthread(cdev); 1289 if (dsw == NULL) 1290 return (ENXIO); 1291 if (dsw->d_flags & D_MMAP_ANON) { 1292 dev_relthread(cdev); 1293 *maxprotp = VM_PROT_ALL; 1294 *flagsp |= MAP_ANON; 1295 return (0); 1296 } 1297 dev_relthread(cdev); 1298 /* 1299 * cdevs does not provide private mappings of any kind. 1300 */ 1301 if ((*maxprotp & VM_PROT_WRITE) == 0 && 1302 (prot & PROT_WRITE) != 0) 1303 return (EACCES); 1304 if (flags & (MAP_PRIVATE|MAP_COPY)) 1305 return (EINVAL); 1306 /* 1307 * Force device mappings to be shared. 1308 */ 1309 flags |= MAP_SHARED; 1310 #ifdef MAC_XXX 1311 error = mac_check_cdev_mmap(td->td_ucred, cdev, prot); 1312 if (error != 0) 1313 return (error); 1314 #endif 1315 obj = vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff); 1316 if (obj == NULL) 1317 return (EINVAL); 1318 *objp = obj; 1319 *flagsp = flags; 1320 return (0); 1321 } 1322 1323 /* 1324 * vm_mmap_shm() 1325 * 1326 * MPSAFE 1327 * 1328 * Helper function for vm_mmap. Perform sanity check specific for mmap 1329 * operations on shm file descriptors. 1330 */ 1331 int 1332 vm_mmap_shm(struct thread *td, vm_size_t objsize, 1333 vm_prot_t prot, vm_prot_t *maxprotp, int *flagsp, 1334 struct shmfd *shmfd, vm_ooffset_t foff, vm_object_t *objp) 1335 { 1336 int error; 1337 1338 if ((*maxprotp & VM_PROT_WRITE) == 0 && 1339 (prot & PROT_WRITE) != 0) 1340 return (EACCES); 1341 #ifdef MAC 1342 error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, *flagsp); 1343 if (error != 0) 1344 return (error); 1345 #endif 1346 error = shm_mmap(shmfd, objsize, foff, objp); 1347 if (error) 1348 return (error); 1349 return (0); 1350 } 1351 1352 /* 1353 * vm_mmap() 1354 * 1355 * MPSAFE 1356 * 1357 * Internal version of mmap. Currently used by mmap, exec, and sys5 1358 * shared memory. Handle is either a vnode pointer or NULL for MAP_ANON. 1359 */ 1360 int 1361 vm_mmap(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, 1362 vm_prot_t maxprot, int flags, 1363 objtype_t handle_type, void *handle, 1364 vm_ooffset_t foff) 1365 { 1366 boolean_t fitit; 1367 vm_object_t object = NULL; 1368 int rv = KERN_SUCCESS; 1369 int docow, error; 1370 struct thread *td = curthread; 1371 1372 if (size == 0) 1373 return (0); 1374 1375 size = round_page(size); 1376 1377 PROC_LOCK(td->td_proc); 1378 if (td->td_proc->p_vmspace->vm_map.size + size > 1379 lim_cur(td->td_proc, RLIMIT_VMEM)) { 1380 PROC_UNLOCK(td->td_proc); 1381 return(ENOMEM); 1382 } 1383 PROC_UNLOCK(td->td_proc); 1384 1385 /* 1386 * We currently can only deal with page aligned file offsets. 1387 * The check is here rather than in the syscall because the 1388 * kernel calls this function internally for other mmaping 1389 * operations (such as in exec) and non-aligned offsets will 1390 * cause pmap inconsistencies...so we want to be sure to 1391 * disallow this in all cases. 1392 */ 1393 if (foff & PAGE_MASK) 1394 return (EINVAL); 1395 1396 if ((flags & MAP_FIXED) == 0) { 1397 fitit = TRUE; 1398 *addr = round_page(*addr); 1399 } else { 1400 if (*addr != trunc_page(*addr)) 1401 return (EINVAL); 1402 fitit = FALSE; 1403 } 1404 /* 1405 * Lookup/allocate object. 1406 */ 1407 switch (handle_type) { 1408 case OBJT_DEVICE: 1409 error = vm_mmap_cdev(td, size, prot, &maxprot, &flags, 1410 handle, foff, &object); 1411 break; 1412 case OBJT_VNODE: 1413 error = vm_mmap_vnode(td, size, prot, &maxprot, &flags, 1414 handle, foff, &object); 1415 break; 1416 case OBJT_SWAP: 1417 error = vm_mmap_shm(td, size, prot, &maxprot, &flags, 1418 handle, foff, &object); 1419 break; 1420 case OBJT_DEFAULT: 1421 if (handle == NULL) { 1422 error = 0; 1423 break; 1424 } 1425 /* FALLTHROUGH */ 1426 default: 1427 error = EINVAL; 1428 break; 1429 } 1430 if (error) 1431 return (error); 1432 if (flags & MAP_ANON) { 1433 object = NULL; 1434 docow = 0; 1435 /* 1436 * Unnamed anonymous regions always start at 0. 1437 */ 1438 if (handle == 0) 1439 foff = 0; 1440 } else { 1441 docow = MAP_PREFAULT_PARTIAL; 1442 } 1443 1444 if ((flags & (MAP_ANON|MAP_SHARED)) == 0) 1445 docow |= MAP_COPY_ON_WRITE; 1446 if (flags & MAP_NOSYNC) 1447 docow |= MAP_DISABLE_SYNCER; 1448 if (flags & MAP_NOCORE) 1449 docow |= MAP_DISABLE_COREDUMP; 1450 1451 #if defined(VM_PROT_READ_IS_EXEC) 1452 if (prot & VM_PROT_READ) 1453 prot |= VM_PROT_EXECUTE; 1454 1455 if (maxprot & VM_PROT_READ) 1456 maxprot |= VM_PROT_EXECUTE; 1457 #endif 1458 1459 if (fitit) 1460 *addr = pmap_addr_hint(object, *addr, size); 1461 1462 if (flags & MAP_STACK) 1463 rv = vm_map_stack(map, *addr, size, prot, maxprot, 1464 docow | MAP_STACK_GROWS_DOWN); 1465 else if (fitit) 1466 rv = vm_map_find(map, object, foff, addr, size, TRUE, 1467 prot, maxprot, docow); 1468 else 1469 rv = vm_map_fixed(map, object, foff, addr, size, 1470 prot, maxprot, docow); 1471 1472 if (rv != KERN_SUCCESS) { 1473 /* 1474 * Lose the object reference. Will destroy the 1475 * object if it's an unnamed anonymous mapping 1476 * or named anonymous without other references. 1477 */ 1478 vm_object_deallocate(object); 1479 } else if (flags & MAP_SHARED) { 1480 /* 1481 * Shared memory is also shared with children. 1482 */ 1483 rv = vm_map_inherit(map, *addr, *addr + size, VM_INHERIT_SHARE); 1484 if (rv != KERN_SUCCESS) 1485 (void) vm_map_remove(map, *addr, *addr + size); 1486 } 1487 1488 /* 1489 * If the process has requested that all future mappings 1490 * be wired, then heed this. 1491 */ 1492 if ((rv == KERN_SUCCESS) && (map->flags & MAP_WIREFUTURE)) 1493 vm_map_wire(map, *addr, *addr + size, 1494 VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 1495 1496 switch (rv) { 1497 case KERN_SUCCESS: 1498 return (0); 1499 case KERN_INVALID_ADDRESS: 1500 case KERN_NO_SPACE: 1501 return (ENOMEM); 1502 case KERN_PROTECTION_FAILURE: 1503 return (EACCES); 1504 default: 1505 return (EINVAL); 1506 } 1507 } 1508