diff options
author | mec <none@none> | 2008-02-19 13:14:17 -0800 |
---|---|---|
committer | mec <none@none> | 2008-02-19 13:14:17 -0800 |
commit | 60946fe0e0cab23f683e9de92451aa45b7913135 (patch) | |
tree | 66ca7e367ff1029f93715ef6334293d405c64f89 | |
parent | c0889d7a91fa87e1cb7ef4457629b0cb51d47b50 (diff) | |
download | illumos-gate-60946fe0e0cab23f683e9de92451aa45b7913135.tar.gz |
PSARC 2006/123 Mmap compatibility
5003415 Provide a MAP_NOOVERMAP option for mmap()
21 files changed, 159 insertions, 235 deletions
diff --git a/usr/src/uts/common/exec/elf/elf.c b/usr/src/uts/common/exec/elf/elf.c index 7813bf00df..ab19c025af 100644 --- a/usr/src/uts/common/exec/elf/elf.c +++ b/usr/src/uts/common/exec/elf/elf.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1106,7 +1106,7 @@ mapelfexec( { Phdr *phdr; int i, prot, error; - caddr_t addr; + caddr_t addr = NULL; size_t zfodsz; int ptload = 0; int page; diff --git a/usr/src/uts/common/fs/cachefs/cachefs_vnops.c b/usr/src/uts/common/fs/cachefs/cachefs_vnops.c index 795c70dc3d..6150b51381 100644 --- a/usr/src/uts/common/fs/cachefs/cachefs_vnops.c +++ b/usr/src/uts/common/fs/cachefs/cachefs_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -8194,18 +8194,10 @@ cachefs_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp, } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto out; - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto out; } /* diff --git a/usr/src/uts/common/fs/gfs.c b/usr/src/uts/common/fs/gfs.c index c56fb004f0..54aaa6854e 100644 --- a/usr/src/uts/common/fs/gfs.c +++ b/usr/src/uts/common/fs/gfs.c @@ -20,7 +20,7 @@ */ /* Portions Copyright 2007 Shivakumar GN */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1022,14 +1022,10 @@ gfs_vop_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, * Find appropriate address if needed, otherwise clear address range. */ as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, (offset_t)off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - (void) as_unmap(as, *addrp, len); + rv = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (rv != 0) { + as_rangeunlock(as); + return (rv); } /* diff --git a/usr/src/uts/common/fs/hsfs/hsfs_vnops.c b/usr/src/uts/common/fs/hsfs/hsfs_vnops.c index 7394b3e1ee..8651b88ee9 100644 --- a/usr/src/uts/common/fs/hsfs/hsfs_vnops.c +++ b/usr/src/uts/common/fs/hsfs/hsfs_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1814,18 +1814,10 @@ hsfs_map( return (EAGAIN); as_rangelock(as); - - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/mntfs/mntvnops.c b/usr/src/uts/common/fs/mntfs/mntvnops.c index 9e519167cf..dcfce13ab5 100644 --- a/usr/src/uts/common/fs/mntfs/mntvnops.c +++ b/usr/src/uts/common/fs/mntfs/mntvnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -158,13 +158,13 @@ mntfs_optprint(struct vfs *vfsp, char *buf) else optinbuf = 1; buf += snprintf(buf, MAX_MNTOPT_STR, - "%s", mop->mo_name); + "%s", mop->mo_name); /* * print option value if there is one */ if (mop->mo_arg != NULL) { buf += snprintf(buf, MAX_MNTOPT_STR, "=%s", - mop->mo_arg); + mop->mo_arg); } } } @@ -445,7 +445,7 @@ mntfs_mapin(char *base, size_t size) { size_t rlen = roundup(size, PAGESIZE); struct as *as = curproc->p_as; - char *addr; + char *addr = NULL; as_rangelock(as); map_addr(&addr, rlen, 0, 1, 0); @@ -466,11 +466,11 @@ mntfs_freesnap(mntsnap_t *snap) { if (snap->mnts_text != NULL) (void) as_unmap(curproc->p_as, snap->mnts_text, - roundup(snap->mnts_textsize, PAGESIZE)); + roundup(snap->mnts_textsize, PAGESIZE)); snap->mnts_textsize = snap->mnts_count = 0; if (snap->mnts_metadata != NULL) (void) as_unmap(curproc->p_as, snap->mnts_metadata, - roundup(snap->mnts_metasize, PAGESIZE)); + roundup(snap->mnts_metasize, PAGESIZE)); snap->mnts_metasize = 0; } diff --git a/usr/src/uts/common/fs/nfs/nfs3_vnops.c b/usr/src/uts/common/fs/nfs/nfs3_vnops.c index fed70c1106..54a0a40b5f 100644 --- a/usr/src/uts/common/fs/nfs/nfs3_vnops.c +++ b/usr/src/uts/common/fs/nfs/nfs3_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -5218,18 +5218,10 @@ nfs3_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, } as_rangelock(as); - if (!(flags & MAP_FIXED)) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto done; - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto done; } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/nfs/nfs4_vnops.c b/usr/src/uts/common/fs/nfs/nfs4_vnops.c index 1186d591af..a9c27d8502 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_vnops.c +++ b/usr/src/uts/common/fs/nfs/nfs4_vnops.c @@ -10416,18 +10416,10 @@ nfs4_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, } as_rangelock(as); - if (!(flags & MAP_FIXED)) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto done; - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto done; } if (vp->v_type == VREG) { diff --git a/usr/src/uts/common/fs/nfs/nfs_vnops.c b/usr/src/uts/common/fs/nfs/nfs_vnops.c index 1dfda0dded..ea8b2fb974 100644 --- a/usr/src/uts/common/fs/nfs/nfs_vnops.c +++ b/usr/src/uts/common/fs/nfs/nfs_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T. @@ -4314,18 +4314,10 @@ nfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, } as_rangelock(as); - if (!(flags & MAP_FIXED)) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto done; - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto done; } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/pcfs/pc_vnops.c b/usr/src/uts/common/fs/pcfs/pc_vnops.c index 9f77542636..3fa7e8d143 100644 --- a/usr/src/uts/common/fs/pcfs/pc_vnops.c +++ b/usr/src/uts/common/fs/pcfs/pc_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1865,17 +1865,10 @@ pcfs_map( return (ENXIO); as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/specfs/specvnops.c b/usr/src/uts/common/fs/specfs/specvnops.c index d452246135..bda8d893f9 100644 --- a/usr/src/uts/common/fs/specfs/specvnops.c +++ b/usr/src/uts/common/fs/specfs/specvnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2255,21 +2255,11 @@ spec_segmap( } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - /* - * Pick an address w/o worrying about - * any vac alignment constraints. - */ - map_addr(addrp, len, (offset_t)off, 0, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User-specified address; blow away any previous mappings. - */ - (void) as_unmap(as, *addrp, len); + /* Pick an address w/o worrying about any vac alignment constraints. */ + error = choose_addr(as, addrp, len, off, ADDR_NOVACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } dev_a.mapfunc = mapfunc; @@ -2407,18 +2397,10 @@ spec_map( return (ENXIO); as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User-specified address; blow away any - * previous mappings. - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } vn_a.vp = cvp; diff --git a/usr/src/uts/common/fs/tmpfs/tmp_vnops.c b/usr/src/uts/common/fs/tmpfs/tmp_vnops.c index c6fee2b1dd..3248df1b26 100644 --- a/usr/src/uts/common/fs/tmpfs/tmp_vnops.c +++ b/usr/src/uts/common/fs/tmpfs/tmp_vnops.c @@ -2174,17 +2174,10 @@ tmp_map( } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, (offset_t)off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/udfs/udf_vnops.c b/usr/src/uts/common/fs/udfs/udf_vnops.c index 2a2822eb3f..9496e9a86d 100644 --- a/usr/src/uts/common/fs/udfs/udf_vnops.c +++ b/usr/src/uts/common/fs/udfs/udf_vnops.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2048,18 +2048,10 @@ udf_map( } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto end; - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto end; } vn_a.vp = vp; diff --git a/usr/src/uts/common/fs/ufs/ufs_vnops.c b/usr/src/uts/common/fs/ufs/ufs_vnops.c index 2bbd577bf2..827ef4c81a 100644 --- a/usr/src/uts/common/fs/ufs/ufs_vnops.c +++ b/usr/src/uts/common/fs/ufs/ufs_vnops.c @@ -5601,22 +5601,16 @@ retry_map: } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - error = ENOMEM; - goto out; - } - } else { - /* - * User specified address - blow away any previous mappings. - * If we are retrying (because ufs_lockfs_trybegin failed in - * the previous attempt), some other thread could have grabbed - * the same VA range. In that case, we would unmap the valid - * VA range, that is ok. - */ - (void) as_unmap(as, *addrp, len); + /* + * Note that if we are retrying (because ufs_lockfs_trybegin failed in + * the previous attempt), some other thread could have grabbed + * the same VA range if MAP_FIXED is set. In that case, choose_addr + * would unmap the valid VA range, that is ok. + */ + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + goto out; } /* diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 267b4de114..811115fd00 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -4108,18 +4108,11 @@ zfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp, } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - map_addr(addrp, len, off, 1, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - ZFS_EXIT(zfsvfs); - return (ENOMEM); - } - } else { - /* - * User specified address - blow away any previous mappings - */ - (void) as_unmap(as, *addrp, len); + error = choose_addr(as, addrp, len, off, ADDR_VACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + ZFS_EXIT(zfsvfs); + return (error); } vn_a.vp = vp; diff --git a/usr/src/uts/common/io/ksyms.c b/usr/src/uts/common/io/ksyms.c index 2a8bc0bc30..92bb96ab83 100644 --- a/usr/src/uts/common/io/ksyms.c +++ b/usr/src/uts/common/io/ksyms.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -167,7 +166,7 @@ ksyms_buflist_alloc(ksyms_buflist_hdr_t *hdr, size_t size) static char * ksyms_asmap(struct as *as, size_t rlen) { - char *addr; + char *addr = NULL; as_rangelock(as); map_addr(&addr, rlen, 0, 1, 0); @@ -223,7 +222,7 @@ ksyms_open(dev_t *devp, int flag, int otyp, struct cred *cred) ksyms_buflist_hdr_t hdr; bzero(&hdr, sizeof (struct ksyms_buflist_hdr)); list_create(&hdr.blist, PAGESIZE, - offsetof(ksyms_buflist_t, buflist_node)); + offsetof(ksyms_buflist_t, buflist_node)); ASSERT(getminor(*devp) == 0); @@ -345,7 +344,7 @@ ksyms_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len, return (ENOTSUP); if (off < 0 || len <= 0 || off > kip->ksyms_size || - len > kip->ksyms_size - off) + len > kip->ksyms_size - off) return (EINVAL); rlen = roundup(len, PAGESIZE); diff --git a/usr/src/uts/common/io/mem.c b/usr/src/uts/common/io/mem.c index 1be161f8f9..36bf6819d7 100644 --- a/usr/src/uts/common/io/mem.c +++ b/usr/src/uts/common/io/mem.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -826,24 +826,15 @@ mmsegmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len, minor = getminor(dev); as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - /* - * No need to worry about vac alignment on /dev/zero - * since this is a "clone" object that doesn't yet exist. - */ - map_addr(addrp, len, (offset_t)off, - (minor == M_MEM) || (minor == M_KMEM), flags); - - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User specified address - - * Blow away any previous mappings. - */ - (void) as_unmap(as, *addrp, len); + /* + * No need to worry about vac alignment on /dev/zero + * since this is a "clone" object that doesn't yet exist. + */ + error = choose_addr(as, addrp, len, off, + (minor == M_MEM) || (minor == M_KMEM), flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } switch (minor) { diff --git a/usr/src/uts/common/io/smbios.c b/usr/src/uts/common/io/smbios.c index 533975e418..e7e68f3532 100644 --- a/usr/src/uts/common/io/smbios.c +++ b/usr/src/uts/common/io/smbios.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -171,7 +170,7 @@ smb_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len, smb_clone_t *cp = &smb_clones[getminor(dev)]; size_t alen = P2ROUNDUP(len, PAGESIZE); - caddr_t addr; + caddr_t addr = NULL; iovec_t iov; uio_t uio; diff --git a/usr/src/uts/common/os/grow.c b/usr/src/uts/common/os/grow.c index 0033b11ff4..2b82aaba0d 100644 --- a/usr/src/uts/common/os/grow.c +++ b/usr/src/uts/common/os/grow.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -230,7 +230,7 @@ brk_internal(caddr_t nva, uint_t brkszc) */ nva = (caddr_t)P2ROUNDUP((uintptr_t)nva, pgsz); ova = (caddr_t)P2ROUNDUP((uintptr_t)(p->p_brkbase + p->p_brksize), - PAGESIZE); + PAGESIZE); if ((nva < p->p_brkbase) || (size > p->p_brksize && size > as_rctl)) { @@ -490,6 +490,40 @@ grow_internal(caddr_t sp, uint_t growszc) } /* + * Find address for user to map. + * If MAP_FIXED is not specified, we can pick any address we want, but we will + * first try the value in *addrp if it is non-NULL. Thus this is implementing + * a way to try and get a preferred address. + */ +int +choose_addr(struct as *as, caddr_t *addrp, size_t len, offset_t off, + int vacalign, uint_t flags) +{ + caddr_t basep = (caddr_t)(uintptr_t)((uintptr_t)*addrp & PAGEMASK); + size_t lenp = len; + + ASSERT(AS_ISCLAIMGAP(as)); /* searches should be serialized */ + if (flags & MAP_FIXED) { + (void) as_unmap(as, *addrp, len); + return (0); + } else if (basep != NULL && ((flags & MAP_ALIGN) == 0) && + !as_gap(as, len, &basep, &lenp, 0, *addrp)) { + /* User supplied address was available */ + *addrp = basep; + } else { + /* + * No user supplied address or the address supplied was not + * available. + */ + map_addr(addrp, len, off, vacalign, flags); + } + if (*addrp == NULL) + return (ENOMEM); + return (0); +} + + +/* * Used for MAP_ANON - fast way to get anonymous pages */ static int @@ -497,6 +531,7 @@ zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags, offset_t pos) { struct segvn_crargs vn_a; + int error; if (((PROT_ALL & uprot) != uprot)) return (EACCES); @@ -523,16 +558,15 @@ zmap(struct as *as, caddr_t *addrp, size_t len, uint_t uprot, int flags, default: return (ENOMEM); } - (void) as_unmap(as, *addrp, len); - } else { - /* - * No need to worry about vac alignment for anonymous - * pages since this is a "clone" object that doesn't - * yet exist. - */ - map_addr(addrp, len, pos, 0, flags); - if (*addrp == NULL) - return (ENOMEM); + } + /* + * No need to worry about vac alignment for anonymous + * pages since this is a "clone" object that doesn't + * yet exist. + */ + error = choose_addr(as, addrp, len, pos, ADDR_NOVACALIGN, flags); + if (error != 0) { + return (error); } /* @@ -602,7 +636,7 @@ smmap_common(caddr_t *addrp, size_t len, /* alignment needs to be a power of 2 >= page size */ if (((uintptr_t)*addrp < PAGESIZE && (uintptr_t)*addrp != 0) || - !ISP2((uintptr_t)*addrp)) + !ISP2((uintptr_t)*addrp)) return (EINVAL); } /* diff --git a/usr/src/uts/common/os/schedctl.c b/usr/src/uts/common/os/schedctl.c index db6ee0e86e..98c8457523 100644 --- a/usr/src/uts/common/os/schedctl.c +++ b/usr/src/uts/common/os/schedctl.c @@ -556,7 +556,7 @@ schedctl_page_lookup(sc_shared_t *ssp) static int schedctl_map(struct anon_map *amp, caddr_t *uaddrp, caddr_t kaddr) { - caddr_t addr; + caddr_t addr = NULL; struct as *as = curproc->p_as; struct segvn_crargs vn_a; int error; diff --git a/usr/src/uts/common/sys/vmsystm.h b/usr/src/uts/common/sys/vmsystm.h index 0561ecf03a..a23d468f5a 100644 --- a/usr/src/uts/common/sys/vmsystm.h +++ b/usr/src/uts/common/sys/vmsystm.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -113,6 +113,12 @@ extern pgcnt_t pages_before_pager; /* XXX */ #define MAPPGSZC_STACK 0x04 #define MAPPGSZC_HEAP 0x08 +/* + * vacalign values for choose_addr + */ +#define ADDR_NOVACALIGN 0 +#define ADDR_VACALIGN 1 + struct as; struct page; struct anon; @@ -133,6 +139,8 @@ extern size_t map_pgsz(int maptype, struct proc *p, caddr_t addr, size_t len, int memcntl); extern uint_t map_pgszcvec(caddr_t addr, size_t size, uintptr_t off, int flags, int type, int memcntl); +extern int choose_addr(struct as *as, caddr_t *addrp, size_t len, offset_t off, + int vacalign, uint_t flags); extern void map_addr(caddr_t *addrp, size_t len, offset_t off, int vacalign, uint_t flags); extern int map_addr_vacalign_check(caddr_t, u_offset_t); diff --git a/usr/src/uts/common/vm/seg_dev.c b/usr/src/uts/common/vm/seg_dev.c index 2b24768e05..e3ea694c05 100644 --- a/usr/src/uts/common/vm/seg_dev.c +++ b/usr/src/uts/common/vm/seg_dev.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2439,21 +2439,11 @@ ddi_segmap_setup(dev_t dev, off_t offset, struct as *as, caddr_t *addrp, } as_rangelock(as); - if ((flags & MAP_FIXED) == 0) { - /* - * Pick an address w/o worrying about - * any vac alignment constraints. - */ - map_addr(addrp, len, ptob(pfn), 0, flags); - if (*addrp == NULL) { - as_rangeunlock(as); - return (ENOMEM); - } - } else { - /* - * User-specified address; blow away any previous mappings. - */ - (void) as_unmap(as, *addrp, len); + /* Pick an address w/o worrying about any vac alignment constraints. */ + error = choose_addr(as, addrp, len, ptob(pfn), ADDR_NOVACALIGN, flags); + if (error != 0) { + as_rangeunlock(as); + return (error); } dev_a.mapfunc = mapfunc; |