2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /* Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved. */
  23 
  24 /*
  25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 
  29 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  30 /*        All Rights Reserved   */
  31 
  32 #include <sys/types.h>
  33 #include <sys/inttypes.h>
  34 #include <sys/param.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/systm.h>
  37 #include <sys/signal.h>
  38 #include <sys/user.h>
  39 #include <sys/errno.h>
  40 #include <sys/var.h>
  41 #include <sys/proc.h>
  42 #include <sys/tuneable.h>
  43 #include <sys/debug.h>
  44 #include <sys/cmn_err.h>
  45 #include <sys/cred.h>
  46 #include <sys/vnode.h>
  47 #include <sys/vfs.h>
  48 #include <sys/vm.h>
  49 #include <sys/file.h>
  50 #include <sys/mman.h>
  51 #include <sys/vmparam.h>
  52 #include <sys/fcntl.h>
  53 #include <sys/lwpchan_impl.h>
  54 #include <sys/nbmlock.h>
  55 
  56 #include <vm/hat.h>
  57 #include <vm/as.h>
  58 #include <vm/seg.h>
  59 #include <vm/seg_dev.h>
  60 #include <vm/seg_vn.h>
  61 
  62 int use_brk_lpg = 1;
  63 int use_stk_lpg = 1;
  64 
  65 static int brk_lpg(caddr_t nva);
  66 static int grow_lpg(caddr_t sp);
  67 
  68 int
  69 brk(caddr_t nva)
  70 {
  71         int error;
  72         proc_t *p = curproc;
  73 
  74         /*
 
 525 
 526         if (flags & MAP_FIXED) {
 527                 (void) as_unmap(as, *addrp, len);
 528                 return (0);
 529         } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) &&
 530             !as_gap(as, len, &basep, &lenp, 0, *addrp)) {
 531                 /* User supplied address was available */
 532                 *addrp = basep;
 533         } else {
 534                 /*
 535                  * No user supplied address or the address supplied was not
 536                  * available.
 537                  */
 538                 map_addr(addrp, len, off, vacalign, flags);
 539         }
 540         if (*addrp == NULL)
 541                 return (ENOMEM);
 542         return (0);
 543 }
 544 
 545 
 546 /*
 547  * Used for MAP_ANON - fast way to get anonymous pages
 548  */
 549 static int
 550 zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags,
 551     offset_t pos)
 552 {
 553         struct segvn_crargs vn_a;
 554         int error;
 555 
 556         if (((PROT_ALL & uprot) != uprot))
 557                 return (EACCES);
 558 
 559         if ((flags & MAP_FIXED) != 0) {
 560                 caddr_t userlimit;
 561 
 562                 /*
 563                  * Use the user address.  First verify that
 564                  * the address to be used is page aligned.
 565                  * Then make some simple bounds checks.
 566                  */
 567                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
 568                         return (EINVAL);
 569 
 570                 userlimit = flags & _MAP_LOW32 ?
 571                     (caddr_t)USERLIMIT32 : as->a_userlimit;
 572                 switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
 573                 case RANGE_OKAY:
 574                         break;
 575                 case RANGE_BADPROT:
 576                         return (ENOTSUP);
 577                 case RANGE_BADADDR:
 578                 default:
 579                         return (ENOMEM);
 580                 }
 581         }
 582         /*
 583          * No need to worry about vac alignment for anonymous
 584          * pages since this is a "clone" object that doesn't
 585          * yet exist.
 586          */
 587         error = choose_addr(as, addrp, len, pos, ADDR_NOVACALIGN, flags);
 588         if (error != 0) {
 589                 return (error);
 590         }
 591 
 592         /*
 
 720          * on the vnode for the current user, maxprot probably
 721          * should disallow PROT_EXEC also?  This is different
 722          * from the write access as this would be a per vnode
 723          * test as opposed to a per fd test for writability.
 724          */
 725 
 726         /*
 727          * Verify that the specified protections are not greater than
 728          * the maximum allowable protections.  Also test to make sure
 729          * that the file descriptor does allows for read access since
 730          * "write only" mappings are hard to do since normally we do
 731          * the read from the file before the page can be written.
 732          */
 733         if (((maxprot & uprot) != uprot) || (fp->f_flag & FREAD) == 0)
 734                 return (EACCES);
 735 
 736         /*
 737          * If the user specified an address, do some simple checks here
 738          */
 739         if ((flags & MAP_FIXED) != 0) {
 740                 caddr_t userlimit;
 741 
 742                 /*
 743                  * Use the user address.  First verify that
 744                  * the address to be used is page aligned.
 745                  * Then make some simple bounds checks.
 746                  */
 747                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
 748                         return (EINVAL);
 749 
 750                 userlimit = flags & _MAP_LOW32 ?
 751                     (caddr_t)USERLIMIT32 : as->a_userlimit;
 752                 switch (valid_usr_range(*addrp, len, uprot, as, userlimit)) {
 753                 case RANGE_OKAY:
 754                         break;
 755                 case RANGE_BADPROT:
 756                         return (ENOTSUP);
 757                 case RANGE_BADADDR:
 758                 default:
 759                         return (ENOMEM);
 760                 }
 761         }
 762 
 763         if ((prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
 764             nbl_need_check(vp)) {
 765                 int svmand;
 766                 nbl_op_t nop;
 767 
 768                 nbl_start_crit(vp, RW_READER);
 769                 in_crit = 1;
 770                 error = nbl_svmand(vp, fp->f_cred, &svmand);
 771                 if (error != 0)
 772                         goto done;
 
 | 
 
 
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2013 OmniTI Computer Consulting, Inc. All rights reserved.
  24  * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  25  */
  26 
  27 /*
  28  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  29  * Use is subject to license terms.
  30  */
  31 
  32 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  33 /*        All Rights Reserved   */
  34 
  35 #include <sys/types.h>
  36 #include <sys/inttypes.h>
  37 #include <sys/param.h>
  38 #include <sys/sysmacros.h>
  39 #include <sys/systm.h>
  40 #include <sys/signal.h>
  41 #include <sys/user.h>
  42 #include <sys/errno.h>
  43 #include <sys/var.h>
  44 #include <sys/proc.h>
  45 #include <sys/tuneable.h>
  46 #include <sys/debug.h>
  47 #include <sys/cmn_err.h>
  48 #include <sys/cred.h>
  49 #include <sys/vnode.h>
  50 #include <sys/vfs.h>
  51 #include <sys/vm.h>
  52 #include <sys/file.h>
  53 #include <sys/mman.h>
  54 #include <sys/vmparam.h>
  55 #include <sys/fcntl.h>
  56 #include <sys/lwpchan_impl.h>
  57 #include <sys/nbmlock.h>
  58 #include <sys/brand.h>
  59 
  60 #include <vm/hat.h>
  61 #include <vm/as.h>
  62 #include <vm/seg.h>
  63 #include <vm/seg_dev.h>
  64 #include <vm/seg_vn.h>
  65 
  66 int use_brk_lpg = 1;
  67 int use_stk_lpg = 1;
  68 
  69 static int brk_lpg(caddr_t nva);
  70 static int grow_lpg(caddr_t sp);
  71 
  72 int
  73 brk(caddr_t nva)
  74 {
  75         int error;
  76         proc_t *p = curproc;
  77 
  78         /*
 
 529 
 530         if (flags & MAP_FIXED) {
 531                 (void) as_unmap(as, *addrp, len);
 532                 return (0);
 533         } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) &&
 534             !as_gap(as, len, &basep, &lenp, 0, *addrp)) {
 535                 /* User supplied address was available */
 536                 *addrp = basep;
 537         } else {
 538                 /*
 539                  * No user supplied address or the address supplied was not
 540                  * available.
 541                  */
 542                 map_addr(addrp, len, off, vacalign, flags);
 543         }
 544         if (*addrp == NULL)
 545                 return (ENOMEM);
 546         return (0);
 547 }
 548 
 549 caddr_t
 550 map_userlimit(proc_t *pp, struct as *as, int flags)
 551 {
 552         if (flags & _MAP_LOW32) {
 553                 if (PROC_IS_BRANDED(pp) && BROP(pp)->b_map32limit != NULL) {
 554                         return ((caddr_t)(uintptr_t)BROP(pp)->b_map32limit(pp));
 555                 } else {
 556                         return ((caddr_t)_userlimit32);
 557                 }
 558         }
 559 
 560         return (as->a_userlimit);
 561 }
 562 
 563 
 564 /*
 565  * Used for MAP_ANON - fast way to get anonymous pages
 566  */
 567 static int
 568 zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags,
 569     offset_t pos)
 570 {
 571         struct segvn_crargs vn_a;
 572         int error;
 573 
 574         if (((PROT_ALL & uprot) != uprot))
 575                 return (EACCES);
 576 
 577         if ((flags & MAP_FIXED) != 0) {
 578                 /*
 579                  * Use the user address.  First verify that
 580                  * the address to be used is page aligned.
 581                  * Then make some simple bounds checks.
 582                  */
 583                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
 584                         return (EINVAL);
 585 
 586                 switch (valid_usr_range(*addrp, len, uprot, as,
 587                     map_userlimit(as->a_proc, as, flags))) {
 588                 case RANGE_OKAY:
 589                         break;
 590                 case RANGE_BADPROT:
 591                         return (ENOTSUP);
 592                 case RANGE_BADADDR:
 593                 default:
 594                         return (ENOMEM);
 595                 }
 596         }
 597         /*
 598          * No need to worry about vac alignment for anonymous
 599          * pages since this is a "clone" object that doesn't
 600          * yet exist.
 601          */
 602         error = choose_addr(as, addrp, len, pos, ADDR_NOVACALIGN, flags);
 603         if (error != 0) {
 604                 return (error);
 605         }
 606 
 607         /*
 
 735          * on the vnode for the current user, maxprot probably
 736          * should disallow PROT_EXEC also?  This is different
 737          * from the write access as this would be a per vnode
 738          * test as opposed to a per fd test for writability.
 739          */
 740 
 741         /*
 742          * Verify that the specified protections are not greater than
 743          * the maximum allowable protections.  Also test to make sure
 744          * that the file descriptor does allows for read access since
 745          * "write only" mappings are hard to do since normally we do
 746          * the read from the file before the page can be written.
 747          */
 748         if (((maxprot & uprot) != uprot) || (fp->f_flag & FREAD) == 0)
 749                 return (EACCES);
 750 
 751         /*
 752          * If the user specified an address, do some simple checks here
 753          */
 754         if ((flags & MAP_FIXED) != 0) {
 755                 /*
 756                  * Use the user address.  First verify that
 757                  * the address to be used is page aligned.
 758                  * Then make some simple bounds checks.
 759                  */
 760                 if (((uintptr_t)*addrp & PAGEOFFSET) != 0)
 761                         return (EINVAL);
 762                 switch (valid_usr_range(*addrp, len, uprot, as,
 763                     map_userlimit(curproc, as, flags))) {
 764                 case RANGE_OKAY:
 765                         break;
 766                 case RANGE_BADPROT:
 767                         return (ENOTSUP);
 768                 case RANGE_BADADDR:
 769                 default:
 770                         return (ENOMEM);
 771                 }
 772         }
 773 
 774         if ((prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) &&
 775             nbl_need_check(vp)) {
 776                 int svmand;
 777                 nbl_op_t nop;
 778 
 779                 nbl_start_crit(vp, RW_READER);
 780                 in_crit = 1;
 781                 error = nbl_svmand(vp, fp->f_cred, &svmand);
 782                 if (error != 0)
 783                         goto done;
 
 |