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