Annotation of OSKit-Mach/vm/vm_map.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
                      4:  * Copyright (c) 1993,1994 The University of Utah and
                      5:  * the Computer Systems Laboratory (CSL).
                      6:  * All rights reserved.
                      7:  *
                      8:  * Permission to use, copy, modify and distribute this software and its
                      9:  * documentation is hereby granted, provided that both the copyright
                     10:  * notice and this permission notice appear in all copies of the
                     11:  * software, derivative works or modified versions, and any portions
                     12:  * thereof, and that both notices appear in supporting documentation.
                     13:  *
                     14:  * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
                     15:  * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
                     16:  * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
                     17:  * THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  [email protected]
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie Mellon
                     27:  * the rights to redistribute these changes.
                     28:  */
                     29: /*
                     30:  *     File:   vm/vm_map.c
                     31:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     32:  *     Date:   1985
                     33:  *
                     34:  *     Virtual memory mapping module.
                     35:  */
                     36: 
                     37: #include <norma_ipc.h>
                     38: 
                     39: #include <mach/kern_return.h>
                     40: #include <mach/port.h>
                     41: #include <mach/vm_attributes.h>
                     42: #include <mach/vm_param.h>
                     43: #include <kern/assert.h>
                     44: #include <kern/zalloc.h>
                     45: #include <vm/vm_fault.h>
                     46: #include <vm/vm_map.h>
                     47: #include <vm/vm_object.h>
                     48: #include <vm/vm_page.h>
                     49: #include <vm/vm_kern.h>
                     50: #include <ipc/ipc_port.h>
                     51: 
                     52: /*
                     53:  * Macros to copy a vm_map_entry. We must be careful to correctly
                     54:  * manage the wired page count. vm_map_entry_copy() creates a new
                     55:  * map entry to the same memory - the wired count in the new entry
                     56:  * must be set to zero. vm_map_entry_copy_full() creates a new
                     57:  * entry that is identical to the old entry.  This preserves the
                     58:  * wire count; it's used for map splitting and zone changing in
                     59:  * vm_map_copyout.
                     60:  */
                     61: #define vm_map_entry_copy(NEW,OLD) \
                     62: MACRO_BEGIN                                     \
                     63:                 *(NEW) = *(OLD);                \
                     64:                 (NEW)->is_shared = FALSE;      \
                     65:                 (NEW)->needs_wakeup = FALSE;    \
                     66:                 (NEW)->in_transition = FALSE;   \
                     67:                 (NEW)->wired_count = 0;         \
                     68:                 (NEW)->user_wired_count = 0;    \
                     69: MACRO_END
                     70: 
                     71: #define vm_map_entry_copy_full(NEW,OLD)        (*(NEW) = *(OLD))
                     72: 
                     73: /*
                     74:  *     Virtual memory maps provide for the mapping, protection,
                     75:  *     and sharing of virtual memory objects.  In addition,
                     76:  *     this module provides for an efficient virtual copy of
                     77:  *     memory from one map to another.
                     78:  *
                     79:  *     Synchronization is required prior to most operations.
                     80:  *
                     81:  *     Maps consist of an ordered doubly-linked list of simple
                     82:  *     entries; a single hint is used to speed up lookups.
                     83:  *
                     84:  *     Sharing maps have been deleted from this version of Mach.
                     85:  *     All shared objects are now mapped directly into the respective
                     86:  *     maps.  This requires a change in the copy on write strategy;
                     87:  *     the asymmetric (delayed) strategy is used for shared temporary
                     88:  *     objects instead of the symmetric (shadow) strategy.  This is
                     89:  *     selected by the (new) use_shared_copy bit in the object.  See
                     90:  *     vm_object_copy_temporary in vm_object.c for details.  All maps
                     91:  *     are now "top level" maps (either task map, kernel map or submap
                     92:  *     of the kernel map).
                     93:  *
                     94:  *     Since portions of maps are specified by start/end addreses,
                     95:  *     which may not align with existing map entries, all
                     96:  *     routines merely "clip" entries to these start/end values.
                     97:  *     [That is, an entry is split into two, bordering at a
                     98:  *     start or end value.]  Note that these clippings may not
                     99:  *     always be necessary (as the two resulting entries are then
                    100:  *     not changed); however, the clipping is done for convenience.
                    101:  *     No attempt is currently made to "glue back together" two
                    102:  *     abutting entries.
                    103:  *
                    104:  *     The symmetric (shadow) copy strategy implements virtual copy
                    105:  *     by copying VM object references from one map to
                    106:  *     another, and then marking both regions as copy-on-write.
                    107:  *     It is important to note that only one writeable reference
                    108:  *     to a VM object region exists in any map when this strategy
                    109:  *     is used -- this means that shadow object creation can be
                    110:  *     delayed until a write operation occurs.  The asymmetric (delayed)
                    111:  *     strategy allows multiple maps to have writeable references to
                    112:  *     the same region of a vm object, and hence cannot delay creating
                    113:  *     its copy objects.  See vm_object_copy_temporary() in vm_object.c.
                    114:  *     Copying of permanent objects is completely different; see
                    115:  *     vm_object_copy_strategically() in vm_object.c.
                    116:  */
                    117: 
                    118: zone_t         vm_map_zone;            /* zone for vm_map structures */
                    119: zone_t         vm_map_entry_zone;      /* zone for vm_map_entry structures */
                    120: zone_t         vm_map_kentry_zone;     /* zone for kernel entry structures */
                    121: zone_t         vm_map_copy_zone;       /* zone for vm_map_copy structures */
                    122: 
                    123: boolean_t      vm_map_lookup_entry();  /* forward declaration */
                    124: 
                    125: /*
                    126:  *     Placeholder object for submap operations.  This object is dropped
                    127:  *     into the range by a call to vm_map_find, and removed when
                    128:  *     vm_map_submap creates the submap.
                    129:  */
                    130: 
                    131: vm_object_t    vm_submap_object;
                    132: 
                    133: /*
                    134:  *     vm_map_init:
                    135:  *
                    136:  *     Initialize the vm_map module.  Must be called before
                    137:  *     any other vm_map routines.
                    138:  *
                    139:  *     Map and entry structures are allocated from zones -- we must
                    140:  *     initialize those zones.
                    141:  *
                    142:  *     There are three zones of interest:
                    143:  *
                    144:  *     vm_map_zone:            used to allocate maps.
                    145:  *     vm_map_entry_zone:      used to allocate map entries.
                    146:  *     vm_map_kentry_zone:     used to allocate map entries for the kernel.
                    147:  *
                    148:  *     The kernel allocates map entries from a special zone that is initially
                    149:  *     "crammed" with memory.  It would be difficult (perhaps impossible) for
                    150:  *     the kernel to allocate more memory to a entry zone when it became
                    151:  *     empty since the very act of allocating memory implies the creation
                    152:  *     of a new entry.
                    153:  */
                    154: 
                    155: vm_offset_t    kentry_data;
                    156: vm_size_t      kentry_data_size;
                    157: int            kentry_count = 256;             /* to init kentry_data_size */
                    158: 
                    159: void vm_map_init()
                    160: {
                    161:        vm_map_zone = zinit((vm_size_t) sizeof(struct vm_map), 40*1024,
                    162:                                        PAGE_SIZE, 0, "maps");
                    163:        vm_map_entry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
                    164:                                        1024*1024, PAGE_SIZE*5,
                    165:                                        0, "non-kernel map entries");
                    166:        vm_map_kentry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
                    167:                                        kentry_data_size, kentry_data_size,
                    168:                                        ZONE_FIXED /* XXX */, "kernel map entries");
                    169: 
                    170:        vm_map_copy_zone = zinit((vm_size_t) sizeof(struct vm_map_copy),
                    171:                                        16*1024, PAGE_SIZE, 0,
                    172:                                        "map copies");
                    173: 
                    174:        /*
                    175:         *      Cram the kentry zone with initial data.
                    176:         */
                    177:        zcram(vm_map_kentry_zone, kentry_data, kentry_data_size);
                    178: 
                    179:        /*
                    180:         *      Submap object is initialized by vm_object_init.
                    181:         */
                    182: }
                    183: 
                    184: /*
                    185:  *     vm_map_create:
                    186:  *
                    187:  *     Creates and returns a new empty VM map with
                    188:  *     the given physical map structure, and having
                    189:  *     the given lower and upper address bounds.
                    190:  */
                    191: vm_map_t vm_map_create(pmap, min, max, pageable)
                    192:        pmap_t          pmap;
                    193:        vm_offset_t     min, max;
                    194:        boolean_t       pageable;
                    195: {
                    196:        register vm_map_t       result;
                    197: 
                    198:        result = (vm_map_t) zalloc(vm_map_zone);
                    199:        if (result == VM_MAP_NULL)
                    200:                panic("vm_map_create");
                    201: 
                    202:        vm_map_first_entry(result) = vm_map_to_entry(result);
                    203:        vm_map_last_entry(result)  = vm_map_to_entry(result);
                    204:        result->hdr.nentries = 0;
                    205:        result->hdr.entries_pageable = pageable;
                    206: 
                    207:        result->size = 0;
                    208:        result->ref_count = 1;
                    209:        result->pmap = pmap;
                    210:        result->min_offset = min;
                    211:        result->max_offset = max;
                    212:        result->wiring_required = FALSE;
                    213:        result->wait_for_space = FALSE;
                    214:        result->first_free = vm_map_to_entry(result);
                    215:        result->hint = vm_map_to_entry(result);
                    216:        vm_map_lock_init(result);
                    217:        simple_lock_init(&result->ref_lock);
                    218:        simple_lock_init(&result->hint_lock);
                    219: 
                    220:        return(result);
                    221: }
                    222: 
                    223: /*
                    224:  *     vm_map_entry_create:    [ internal use only ]
                    225:  *
                    226:  *     Allocates a VM map entry for insertion in the
                    227:  *     given map (or map copy).  No fields are filled.
                    228:  */
                    229: #define        vm_map_entry_create(map) \
                    230:            _vm_map_entry_create(&(map)->hdr)
                    231: 
                    232: #define        vm_map_copy_entry_create(copy) \
                    233:            _vm_map_entry_create(&(copy)->cpy_hdr)
                    234: 
                    235: vm_map_entry_t _vm_map_entry_create(map_header)
                    236:        register struct vm_map_header *map_header;
                    237: {
                    238:        register zone_t zone;
                    239:        register vm_map_entry_t entry;
                    240: 
                    241:        if (map_header->entries_pageable)
                    242:            zone = vm_map_entry_zone;
                    243:        else
                    244:            zone = vm_map_kentry_zone;
                    245: 
                    246:        entry = (vm_map_entry_t) zalloc(zone);
                    247:        if (entry == VM_MAP_ENTRY_NULL)
                    248:                panic("vm_map_entry_create");
                    249: 
                    250:        return(entry);
                    251: }
                    252: 
                    253: /*
                    254:  *     vm_map_entry_dispose:   [ internal use only ]
                    255:  *
                    256:  *     Inverse of vm_map_entry_create.
                    257:  */
                    258: #define        vm_map_entry_dispose(map, entry) \
                    259:        _vm_map_entry_dispose(&(map)->hdr, (entry))
                    260: 
                    261: #define        vm_map_copy_entry_dispose(map, entry) \
                    262:        _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
                    263: 
                    264: void _vm_map_entry_dispose(map_header, entry)
                    265:        register struct vm_map_header *map_header;
                    266:        register vm_map_entry_t entry;
                    267: {
                    268:        register zone_t         zone;
                    269: 
                    270:        if (map_header->entries_pageable)
                    271:            zone = vm_map_entry_zone;
                    272:        else
                    273:            zone = vm_map_kentry_zone;
                    274: 
                    275:        zfree(zone, (vm_offset_t) entry);
                    276: }
                    277: 
                    278: /*
                    279:  *     vm_map_entry_{un,}link:
                    280:  *
                    281:  *     Insert/remove entries from maps (or map copies).
                    282:  */
                    283: #define vm_map_entry_link(map, after_where, entry)     \
                    284:        _vm_map_entry_link(&(map)->hdr, after_where, entry)
                    285: 
                    286: #define vm_map_copy_entry_link(copy, after_where, entry)       \
                    287:        _vm_map_entry_link(&(copy)->cpy_hdr, after_where, entry)
                    288: 
                    289: #define _vm_map_entry_link(hdr, after_where, entry)    \
                    290:        MACRO_BEGIN                                     \
                    291:        (hdr)->nentries++;                              \
                    292:        (entry)->vme_prev = (after_where);              \
                    293:        (entry)->vme_next = (after_where)->vme_next;    \
                    294:        (entry)->vme_prev->vme_next =                   \
                    295:         (entry)->vme_next->vme_prev = (entry);         \
                    296:        MACRO_END
                    297: 
                    298: #define vm_map_entry_unlink(map, entry)                        \
                    299:        _vm_map_entry_unlink(&(map)->hdr, entry)
                    300: 
                    301: #define vm_map_copy_entry_unlink(copy, entry)                  \
                    302:        _vm_map_entry_unlink(&(copy)->cpy_hdr, entry)
                    303: 
                    304: #define _vm_map_entry_unlink(hdr, entry)               \
                    305:        MACRO_BEGIN                                     \
                    306:        (hdr)->nentries--;                              \
                    307:        (entry)->vme_next->vme_prev = (entry)->vme_prev; \
                    308:        (entry)->vme_prev->vme_next = (entry)->vme_next; \
                    309:        MACRO_END
                    310: 
                    311: /*
                    312:  *     vm_map_reference:
                    313:  *
                    314:  *     Creates another valid reference to the given map.
                    315:  *
                    316:  */
                    317: void vm_map_reference(map)
                    318:        register vm_map_t       map;
                    319: {
                    320:        if (map == VM_MAP_NULL)
                    321:                return;
                    322: 
                    323:        simple_lock(&map->ref_lock);
                    324:        map->ref_count++;
                    325:        simple_unlock(&map->ref_lock);
                    326: }
                    327: 
                    328: /*
                    329:  *     vm_map_deallocate:
                    330:  *
                    331:  *     Removes a reference from the specified map,
                    332:  *     destroying it if no references remain.
                    333:  *     The map should not be locked.
                    334:  */
                    335: void vm_map_deallocate(map)
                    336:        register vm_map_t       map;
                    337: {
                    338:        register int            c;
                    339: 
                    340:        if (map == VM_MAP_NULL)
                    341:                return;
                    342: 
                    343:        simple_lock(&map->ref_lock);
                    344:        c = --map->ref_count;
                    345:        simple_unlock(&map->ref_lock);
                    346: 
                    347:        if (c > 0) {
                    348:                return;
                    349:        }
                    350: 
                    351:        projected_buffer_collect(map);
                    352:        (void) vm_map_delete(map, map->min_offset, map->max_offset);
                    353: 
                    354:        pmap_destroy(map->pmap);
                    355: 
                    356:        zfree(vm_map_zone, (vm_offset_t) map);
                    357: }
                    358: 
                    359: /*
                    360:  *     SAVE_HINT:
                    361:  *
                    362:  *     Saves the specified entry as the hint for
                    363:  *     future lookups.  Performs necessary interlocks.
                    364:  */
                    365: #define        SAVE_HINT(map,value) \
                    366:                simple_lock(&(map)->hint_lock); \
                    367:                (map)->hint = (value); \
                    368:                simple_unlock(&(map)->hint_lock);
                    369: 
                    370: /*
                    371:  *     vm_map_lookup_entry:    [ internal use only ]
                    372:  *
                    373:  *     Finds the map entry containing (or
                    374:  *     immediately preceding) the specified address
                    375:  *     in the given map; the entry is returned
                    376:  *     in the "entry" parameter.  The boolean
                    377:  *     result indicates whether the address is
                    378:  *     actually contained in the map.
                    379:  */
                    380: boolean_t vm_map_lookup_entry(map, address, entry)
                    381:        register vm_map_t       map;
                    382:        register vm_offset_t    address;
                    383:        vm_map_entry_t          *entry;         /* OUT */
                    384: {
                    385:        register vm_map_entry_t         cur;
                    386:        register vm_map_entry_t         last;
                    387: 
                    388:        /*
                    389:         *      Start looking either from the head of the
                    390:         *      list, or from the hint.
                    391:         */
                    392: 
                    393:        simple_lock(&map->hint_lock);
                    394:        cur = map->hint;
                    395:        simple_unlock(&map->hint_lock);
                    396: 
                    397:        if (cur == vm_map_to_entry(map))
                    398:                cur = cur->vme_next;
                    399: 
                    400:        if (address >= cur->vme_start) {
                    401:                /*
                    402:                 *      Go from hint to end of list.
                    403:                 *
                    404:                 *      But first, make a quick check to see if
                    405:                 *      we are already looking at the entry we
                    406:                 *      want (which is usually the case).
                    407:                 *      Note also that we don't need to save the hint
                    408:                 *      here... it is the same hint (unless we are
                    409:                 *      at the header, in which case the hint didn't
                    410:                 *      buy us anything anyway).
                    411:                 */
                    412:                last = vm_map_to_entry(map);
                    413:                if ((cur != last) && (cur->vme_end > address)) {
                    414:                        *entry = cur;
                    415:                        return(TRUE);
                    416:                }
                    417:        }
                    418:        else {
                    419:                /*
                    420:                 *      Go from start to hint, *inclusively*
                    421:                 */
                    422:                last = cur->vme_next;
                    423:                cur = vm_map_first_entry(map);
                    424:        }
                    425: 
                    426:        /*
                    427:         *      Search linearly
                    428:         */
                    429: 
                    430:        while (cur != last) {
                    431:                if (cur->vme_end > address) {
                    432:                        if (address >= cur->vme_start) {
                    433:                                /*
                    434:                                 *      Save this lookup for future
                    435:                                 *      hints, and return
                    436:                                 */
                    437: 
                    438:                                *entry = cur;
                    439:                                SAVE_HINT(map, cur);
                    440:                                return(TRUE);
                    441:                        }
                    442:                        break;
                    443:                }
                    444:                cur = cur->vme_next;
                    445:        }
                    446:        *entry = cur->vme_prev;
                    447:        SAVE_HINT(map, *entry);
                    448:        return(FALSE);
                    449: }
                    450: 
                    451: /*
                    452:  *      Routine:     invalid_user_access
                    453:  *
                    454:  *     Verifies whether user access is valid.
                    455:  */
                    456: 
                    457: boolean_t
                    458: invalid_user_access(map, start, end, prot)
                    459:         vm_map_t map;
                    460:         vm_offset_t start, end;
                    461:         vm_prot_t prot;
                    462: {
                    463:         vm_map_entry_t entry;
                    464: 
                    465:         return (map == VM_MAP_NULL || map == kernel_map ||
                    466:                !vm_map_lookup_entry(map, start, &entry) ||
                    467:                entry->vme_end < end ||
                    468:                (prot & ~(entry->protection)));
                    469: }
                    470: 
                    471: 
                    472: /*
                    473:  *     Routine:        vm_map_find_entry
                    474:  *     Purpose:
                    475:  *             Allocate a range in the specified virtual address map,
                    476:  *             returning the entry allocated for that range.
                    477:  *             Used by kmem_alloc, etc.  Returns wired entries.
                    478:  *
                    479:  *             The map must be locked.
                    480:  *
                    481:  *             If an entry is allocated, the object/offset fields
                    482:  *             are initialized to zero.  If an object is supplied,
                    483:  *             then an existing entry may be extended.
                    484:  */
                    485: kern_return_t vm_map_find_entry(map, address, size, mask, object, o_entry)
                    486:        register vm_map_t       map;
                    487:        vm_offset_t             *address;       /* OUT */
                    488:        vm_size_t               size;
                    489:        vm_offset_t             mask;
                    490:        vm_object_t             object;
                    491:        vm_map_entry_t          *o_entry;       /* OUT */
                    492: {
                    493:        register vm_map_entry_t entry, new_entry;
                    494:        register vm_offset_t    start;
                    495:        register vm_offset_t    end;
                    496: 
                    497:        /*
                    498:         *      Look for the first possible address;
                    499:         *      if there's already something at this
                    500:         *      address, we have to start after it.
                    501:         */
                    502: 
                    503:        if ((entry = map->first_free) == vm_map_to_entry(map))
                    504:                start = map->min_offset;
                    505:        else
                    506:                start = entry->vme_end;
                    507: 
                    508:        /*
                    509:         *      In any case, the "entry" always precedes
                    510:         *      the proposed new region throughout the loop:
                    511:         */
                    512: 
                    513:        while (TRUE) {
                    514:                register vm_map_entry_t next;
                    515: 
                    516:                /*
                    517:                 *      Find the end of the proposed new region.
                    518:                 *      Be sure we didn't go beyond the end, or
                    519:                 *      wrap around the address.
                    520:                 */
                    521: 
                    522:                if (((start + mask) & ~mask) < start)
                    523:                        return(KERN_NO_SPACE);
                    524:                start = ((start + mask) & ~mask);
                    525:                end = start + size;
                    526: 
                    527:                if ((end > map->max_offset) || (end < start))
                    528:                        return(KERN_NO_SPACE);
                    529: 
                    530:                /*
                    531:                 *      If there are no more entries, we must win.
                    532:                 */
                    533: 
                    534:                next = entry->vme_next;
                    535:                if (next == vm_map_to_entry(map))
                    536:                        break;
                    537: 
                    538:                /*
                    539:                 *      If there is another entry, it must be
                    540:                 *      after the end of the potential new region.
                    541:                 */
                    542: 
                    543:                if (next->vme_start >= end)
                    544:                        break;
                    545: 
                    546:                /*
                    547:                 *      Didn't fit -- move to the next entry.
                    548:                 */
                    549: 
                    550:                entry = next;
                    551:                start = entry->vme_end;
                    552:        }
                    553: 
                    554:        /*
                    555:         *      At this point,
                    556:         *              "start" and "end" should define the endpoints of the
                    557:         *                      available new range, and
                    558:         *              "entry" should refer to the region before the new
                    559:         *                      range, and
                    560:         *
                    561:         *              the map should be locked.
                    562:         */
                    563: 
                    564:        *address = start;
                    565: 
                    566:        /*
                    567:         *      See whether we can avoid creating a new entry by
                    568:         *      extending one of our neighbors.  [So far, we only attempt to
                    569:         *      extend from below.]
                    570:         */
                    571: 
                    572:        if ((object != VM_OBJECT_NULL) &&
                    573:            (entry != vm_map_to_entry(map)) &&
                    574:            (entry->vme_end == start) &&
                    575:            (!entry->is_shared) &&
                    576:            (!entry->is_sub_map) &&
                    577:            (entry->object.vm_object == object) &&
                    578:            (entry->needs_copy == FALSE) &&
                    579:            (entry->inheritance == VM_INHERIT_DEFAULT) &&
                    580:            (entry->protection == VM_PROT_DEFAULT) &&
                    581:            (entry->max_protection == VM_PROT_ALL) &&
                    582:            (entry->wired_count == 1) &&
                    583:            (entry->user_wired_count == 0) &&
                    584:            (entry->projected_on == 0)) {
                    585:                /*
                    586:                 *      Because this is a special case,
                    587:                 *      we don't need to use vm_object_coalesce.
                    588:                 */
                    589: 
                    590:                entry->vme_end = end;
                    591:                new_entry = entry;
                    592:        } else {
                    593:                new_entry = vm_map_entry_create(map);
                    594: 
                    595:                new_entry->vme_start = start;
                    596:                new_entry->vme_end = end;
                    597: 
                    598:                new_entry->is_shared = FALSE;
                    599:                new_entry->is_sub_map = FALSE;
                    600:                new_entry->object.vm_object = VM_OBJECT_NULL;
                    601:                new_entry->offset = (vm_offset_t) 0;
                    602: 
                    603:                new_entry->needs_copy = FALSE;
                    604: 
                    605:                new_entry->inheritance = VM_INHERIT_DEFAULT;
                    606:                new_entry->protection = VM_PROT_DEFAULT;
                    607:                new_entry->max_protection = VM_PROT_ALL;
                    608:                new_entry->wired_count = 1;
                    609:                new_entry->user_wired_count = 0;
                    610: 
                    611:                new_entry->in_transition = FALSE;
                    612:                new_entry->needs_wakeup = FALSE;
                    613:                new_entry->projected_on = 0;
                    614: 
                    615:                /*
                    616:                 *      Insert the new entry into the list
                    617:                 */
                    618: 
                    619:                vm_map_entry_link(map, entry, new_entry);
                    620:        }
                    621: 
                    622:        map->size += size;
                    623: 
                    624:        /*
                    625:         *      Update the free space hint and the lookup hint
                    626:         */
                    627: 
                    628:        map->first_free = new_entry;
                    629:        SAVE_HINT(map, new_entry);
                    630: 
                    631:        *o_entry = new_entry;
                    632:        return(KERN_SUCCESS);
                    633: }
                    634: 
                    635: int vm_map_pmap_enter_print = FALSE;
                    636: int vm_map_pmap_enter_enable = FALSE;
                    637: 
                    638: /*
                    639:  *     Routine:        vm_map_pmap_enter
                    640:  *
                    641:  *     Description:
                    642:  *             Force pages from the specified object to be entered into
                    643:  *             the pmap at the specified address if they are present.
                    644:  *             As soon as a page not found in the object the scan ends.
                    645:  *
                    646:  *     Returns:
                    647:  *             Nothing.
                    648:  *
                    649:  *     In/out conditions:
                    650:  *             The source map should not be locked on entry.
                    651:  */
                    652: void
                    653: vm_map_pmap_enter(map, addr, end_addr, object, offset, protection)
                    654:        vm_map_t        map;
                    655:        register
                    656:        vm_offset_t     addr;
                    657:        register
                    658:        vm_offset_t     end_addr;
                    659:        register
                    660:        vm_object_t     object;
                    661:        vm_offset_t     offset;
                    662:        vm_prot_t       protection;
                    663: {
                    664:        while (addr < end_addr) {
                    665:                register vm_page_t      m;
                    666: 
                    667:                vm_object_lock(object);
                    668:                vm_object_paging_begin(object);
                    669: 
                    670:                m = vm_page_lookup(object, offset);
                    671:                if (m == VM_PAGE_NULL || m->absent) {
                    672:                        vm_object_paging_end(object);
                    673:                        vm_object_unlock(object);
                    674:                        return;
                    675:                }
                    676: 
                    677:                if (vm_map_pmap_enter_print) {
                    678:                        printf("vm_map_pmap_enter:");
                    679:                        printf("map: %x, addr: %x, object: %x, offset: %x\n",
                    680:                                map, addr, object, offset);
                    681:                }
                    682: 
                    683:                m->busy = TRUE;
                    684:                vm_object_unlock(object);
                    685: 
                    686:                PMAP_ENTER(map->pmap, addr, m,
                    687:                           protection, FALSE);
                    688: 
                    689:                vm_object_lock(object);
                    690:                PAGE_WAKEUP_DONE(m);
                    691:                vm_page_lock_queues();
                    692:                if (!m->active && !m->inactive)
                    693:                    vm_page_activate(m);
                    694:                vm_page_unlock_queues();
                    695:                vm_object_paging_end(object);
                    696:                vm_object_unlock(object);
                    697: 
                    698:                offset += PAGE_SIZE;
                    699:                addr += PAGE_SIZE;
                    700:        }
                    701: }
                    702: 
                    703: /*
                    704:  *     Routine:        vm_map_enter
                    705:  *
                    706:  *     Description:
                    707:  *             Allocate a range in the specified virtual address map.
                    708:  *             The resulting range will refer to memory defined by
                    709:  *             the given memory object and offset into that object.
                    710:  *
                    711:  *             Arguments are as defined in the vm_map call.
                    712:  */
                    713: kern_return_t vm_map_enter(
                    714:                map,
                    715:                address, size, mask, anywhere,
                    716:                object, offset, needs_copy,
                    717:                cur_protection, max_protection, inheritance)
                    718:        register
                    719:        vm_map_t        map;
                    720:        vm_offset_t     *address;       /* IN/OUT */
                    721:        vm_size_t       size;
                    722:        vm_offset_t     mask;
                    723:        boolean_t       anywhere;
                    724:        vm_object_t     object;
                    725:        vm_offset_t     offset;
                    726:        boolean_t       needs_copy;
                    727:        vm_prot_t       cur_protection;
                    728:        vm_prot_t       max_protection;
                    729:        vm_inherit_t    inheritance;
                    730: {
                    731:        register vm_map_entry_t entry;
                    732:        register vm_offset_t    start;
                    733:        register vm_offset_t    end;
                    734:        kern_return_t           result = KERN_SUCCESS;
                    735: 
                    736: #define        RETURN(value)   { result = value; goto BailOut; }
                    737: 
                    738:  StartAgain: ;
                    739: 
                    740:        start = *address;
                    741: 
                    742:        if (anywhere) {
                    743:                vm_map_lock(map);
                    744: 
                    745:                /*
                    746:                 *      Calculate the first possible address.
                    747:                 */
                    748: 
                    749:                if (start < map->min_offset)
                    750:                        start = map->min_offset;
                    751:                if (start > map->max_offset)
                    752:                        RETURN(KERN_NO_SPACE);
                    753: 
                    754:                /*
                    755:                 *      Look for the first possible address;
                    756:                 *      if there's already something at this
                    757:                 *      address, we have to start after it.
                    758:                 */
                    759: 
                    760:                if (start == map->min_offset) {
                    761:                        if ((entry = map->first_free) != vm_map_to_entry(map))
                    762:                                start = entry->vme_end;
                    763:                } else {
                    764:                        vm_map_entry_t  tmp_entry;
                    765:                        if (vm_map_lookup_entry(map, start, &tmp_entry))
                    766:                                start = tmp_entry->vme_end;
                    767:                        entry = tmp_entry;
                    768:                }
                    769: 
                    770:                /*
                    771:                 *      In any case, the "entry" always precedes
                    772:                 *      the proposed new region throughout the
                    773:                 *      loop:
                    774:                 */
                    775: 
                    776:                while (TRUE) {
                    777:                        register vm_map_entry_t next;
                    778: 
                    779:                        /*
                    780:                         *      Find the end of the proposed new region.
                    781:                         *      Be sure we didn't go beyond the end, or
                    782:                         *      wrap around the address.
                    783:                         */
                    784: 
                    785:                        if (((start + mask) & ~mask) < start)
                    786:                                return(KERN_NO_SPACE);
                    787:                        start = ((start + mask) & ~mask);
                    788:                        end = start + size;
                    789: 
                    790:                        if ((end > map->max_offset) || (end < start)) {
                    791:                                if (map->wait_for_space) {
                    792:                                        if (size <= (map->max_offset -
                    793:                                                     map->min_offset)) {
                    794:                                                assert_wait((event_t) map, TRUE);
                    795:                                                vm_map_unlock(map);
                    796:                                                thread_block((void (*)()) 0);
                    797:                                                goto StartAgain;
                    798:                                        }
                    799:                                }
                    800: 
                    801:                                RETURN(KERN_NO_SPACE);
                    802:                        }
                    803: 
                    804:                        /*
                    805:                         *      If there are no more entries, we must win.
                    806:                         */
                    807: 
                    808:                        next = entry->vme_next;
                    809:                        if (next == vm_map_to_entry(map))
                    810:                                break;
                    811: 
                    812:                        /*
                    813:                         *      If there is another entry, it must be
                    814:                         *      after the end of the potential new region.
                    815:                         */
                    816: 
                    817:                        if (next->vme_start >= end)
                    818:                                break;
                    819: 
                    820:                        /*
                    821:                         *      Didn't fit -- move to the next entry.
                    822:                         */
                    823: 
                    824:                        entry = next;
                    825:                        start = entry->vme_end;
                    826:                }
                    827:                *address = start;
                    828:        } else {
                    829:                vm_map_entry_t          temp_entry;
                    830: 
                    831:                /*
                    832:                 *      Verify that:
                    833:                 *              the address doesn't itself violate
                    834:                 *              the mask requirement.
                    835:                 */
                    836: 
                    837:                if ((start & mask) != 0)
                    838:                        return(KERN_NO_SPACE);
                    839: 
                    840:                vm_map_lock(map);
                    841: 
                    842:                /*
                    843:                 *      ...     the address is within bounds
                    844:                 */
                    845: 
                    846:                end = start + size;
                    847: 
                    848:                if ((start < map->min_offset) ||
                    849:                    (end > map->max_offset) ||
                    850:                    (start >= end)) {
                    851:                        RETURN(KERN_INVALID_ADDRESS);
                    852:                }
                    853: 
                    854:                /*
                    855:                 *      ...     the starting address isn't allocated
                    856:                 */
                    857: 
                    858:                if (vm_map_lookup_entry(map, start, &temp_entry))
                    859:                        RETURN(KERN_NO_SPACE);
                    860: 
                    861:                entry = temp_entry;
                    862: 
                    863:                /*
                    864:                 *      ...     the next region doesn't overlap the
                    865:                 *              end point.
                    866:                 */
                    867: 
                    868:                if ((entry->vme_next != vm_map_to_entry(map)) &&
                    869:                    (entry->vme_next->vme_start < end))
                    870:                        RETURN(KERN_NO_SPACE);
                    871:        }
                    872: 
                    873:        /*
                    874:         *      At this point,
                    875:         *              "start" and "end" should define the endpoints of the
                    876:         *                      available new range, and
                    877:         *              "entry" should refer to the region before the new
                    878:         *                      range, and
                    879:         *
                    880:         *              the map should be locked.
                    881:         */
                    882: 
                    883:        /*
                    884:         *      See whether we can avoid creating a new entry (and object) by
                    885:         *      extending one of our neighbors.  [So far, we only attempt to
                    886:         *      extend from below.]
                    887:         */
                    888: 
                    889:        if ((object == VM_OBJECT_NULL) &&
                    890:            (entry != vm_map_to_entry(map)) &&
                    891:            (entry->vme_end == start) &&
                    892:            (!entry->is_shared) &&
                    893:            (!entry->is_sub_map) &&
                    894:            (entry->inheritance == inheritance) &&
                    895:            (entry->protection == cur_protection) &&
                    896:            (entry->max_protection == max_protection) &&
                    897:            (entry->wired_count == 0) &&  /* implies user_wired_count == 0 */
                    898:            (entry->projected_on == 0)) {
                    899:                if (vm_object_coalesce(entry->object.vm_object,
                    900:                                VM_OBJECT_NULL,
                    901:                                entry->offset,
                    902:                                (vm_offset_t) 0,
                    903:                                (vm_size_t)(entry->vme_end - entry->vme_start),
                    904:                                (vm_size_t)(end - entry->vme_end))) {
                    905: 
                    906:                        /*
                    907:                         *      Coalesced the two objects - can extend
                    908:                         *      the previous map entry to include the
                    909:                         *      new range.
                    910:                         */
                    911:                        map->size += (end - entry->vme_end);
                    912:                        entry->vme_end = end;
                    913:                        RETURN(KERN_SUCCESS);
                    914:                }
                    915:        }
                    916: 
                    917:        /*
                    918:         *      Create a new entry
                    919:         */
                    920: 
                    921:        /**/ {
                    922:        register vm_map_entry_t new_entry;
                    923: 
                    924:        new_entry = vm_map_entry_create(map);
                    925: 
                    926:        new_entry->vme_start = start;
                    927:        new_entry->vme_end = end;
                    928: 
                    929:        new_entry->is_shared = FALSE;
                    930:        new_entry->is_sub_map = FALSE;
                    931:        new_entry->object.vm_object = object;
                    932:        new_entry->offset = offset;
                    933: 
                    934:        new_entry->needs_copy = needs_copy;
                    935: 
                    936:        new_entry->inheritance = inheritance;
                    937:        new_entry->protection = cur_protection;
                    938:        new_entry->max_protection = max_protection;
                    939:        new_entry->wired_count = 0;
                    940:        new_entry->user_wired_count = 0;
                    941: 
                    942:        new_entry->in_transition = FALSE;
                    943:        new_entry->needs_wakeup = FALSE;
                    944:        new_entry->projected_on = 0;
                    945: 
                    946:        /*
                    947:         *      Insert the new entry into the list
                    948:         */
                    949: 
                    950:        vm_map_entry_link(map, entry, new_entry);
                    951:        map->size += size;
                    952: 
                    953:        /*
                    954:         *      Update the free space hint and the lookup hint
                    955:         */
                    956: 
                    957:        if ((map->first_free == entry) &&
                    958:            ((entry == vm_map_to_entry(map) ? map->min_offset : entry->vme_end)
                    959:             >= new_entry->vme_start))
                    960:                map->first_free = new_entry;
                    961: 
                    962:        SAVE_HINT(map, new_entry);
                    963: 
                    964:        vm_map_unlock(map);
                    965: 
                    966:        if ((object != VM_OBJECT_NULL) &&
                    967:            (vm_map_pmap_enter_enable) &&
                    968:            (!anywhere)  &&
                    969:            (!needs_copy) &&
                    970:            (size < (128*1024))) {
                    971:                vm_map_pmap_enter(map, start, end,
                    972:                                  object, offset, cur_protection);
                    973:        }
                    974: 
                    975:        return(result);
                    976:        /**/ }
                    977: 
                    978:  BailOut: ;
                    979: 
                    980:        vm_map_unlock(map);
                    981:        return(result);
                    982: 
                    983: #undef RETURN
                    984: }
                    985: 
                    986: /*
                    987:  *     vm_map_clip_start:      [ internal use only ]
                    988:  *
                    989:  *     Asserts that the given entry begins at or after
                    990:  *     the specified address; if necessary,
                    991:  *     it splits the entry into two.
                    992:  */
                    993: void _vm_map_clip_start();
                    994: #define vm_map_clip_start(map, entry, startaddr) \
                    995:        MACRO_BEGIN \
                    996:        if ((startaddr) > (entry)->vme_start) \
                    997:                _vm_map_clip_start(&(map)->hdr,(entry),(startaddr)); \
                    998:        MACRO_END
                    999: 
                   1000: void _vm_map_copy_clip_start();
                   1001: #define vm_map_copy_clip_start(copy, entry, startaddr) \
                   1002:        MACRO_BEGIN \
                   1003:        if ((startaddr) > (entry)->vme_start) \
                   1004:                _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
                   1005:        MACRO_END
                   1006: 
                   1007: /*
                   1008:  *     This routine is called only when it is known that
                   1009:  *     the entry must be split.
                   1010:  */
                   1011: void _vm_map_clip_start(map_header, entry, start)
                   1012:        register struct vm_map_header *map_header;
                   1013:        register vm_map_entry_t entry;
                   1014:        register vm_offset_t    start;
                   1015: {
                   1016:        register vm_map_entry_t new_entry;
                   1017: 
                   1018:        /*
                   1019:         *      Split off the front portion --
                   1020:         *      note that we must insert the new
                   1021:         *      entry BEFORE this one, so that
                   1022:         *      this entry has the specified starting
                   1023:         *      address.
                   1024:         */
                   1025: 
                   1026:        new_entry = _vm_map_entry_create(map_header);
                   1027:        vm_map_entry_copy_full(new_entry, entry);
                   1028: 
                   1029:        new_entry->vme_end = start;
                   1030:        entry->offset += (start - entry->vme_start);
                   1031:        entry->vme_start = start;
                   1032: 
                   1033:        _vm_map_entry_link(map_header, entry->vme_prev, new_entry);
                   1034: 
                   1035:        if (entry->is_sub_map)
                   1036:                vm_map_reference(new_entry->object.sub_map);
                   1037:        else
                   1038:                vm_object_reference(new_entry->object.vm_object);
                   1039: }
                   1040: 
                   1041: /*
                   1042:  *     vm_map_clip_end:        [ internal use only ]
                   1043:  *
                   1044:  *     Asserts that the given entry ends at or before
                   1045:  *     the specified address; if necessary,
                   1046:  *     it splits the entry into two.
                   1047:  */
                   1048: void _vm_map_clip_end();
                   1049: #define vm_map_clip_end(map, entry, endaddr) \
                   1050:        MACRO_BEGIN \
                   1051:        if ((endaddr) < (entry)->vme_end) \
                   1052:                _vm_map_clip_end(&(map)->hdr,(entry),(endaddr)); \
                   1053:        MACRO_END
                   1054: 
                   1055: void _vm_map_copy_clip_end();
                   1056: #define vm_map_copy_clip_end(copy, entry, endaddr) \
                   1057:        MACRO_BEGIN \
                   1058:        if ((endaddr) < (entry)->vme_end) \
                   1059:                _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
                   1060:        MACRO_END
                   1061: 
                   1062: /*
                   1063:  *     This routine is called only when it is known that
                   1064:  *     the entry must be split.
                   1065:  */
                   1066: void _vm_map_clip_end(map_header, entry, end)
                   1067:        register struct vm_map_header *map_header;
                   1068:        register vm_map_entry_t entry;
                   1069:        register vm_offset_t    end;
                   1070: {
                   1071:        register vm_map_entry_t new_entry;
                   1072: 
                   1073:        /*
                   1074:         *      Create a new entry and insert it
                   1075:         *      AFTER the specified entry
                   1076:         */
                   1077: 
                   1078:        new_entry = _vm_map_entry_create(map_header);
                   1079:        vm_map_entry_copy_full(new_entry, entry);
                   1080: 
                   1081:        new_entry->vme_start = entry->vme_end = end;
                   1082:        new_entry->offset += (end - entry->vme_start);
                   1083: 
                   1084:        _vm_map_entry_link(map_header, entry, new_entry);
                   1085: 
                   1086:        if (entry->is_sub_map)
                   1087:                vm_map_reference(new_entry->object.sub_map);
                   1088:        else
                   1089:                vm_object_reference(new_entry->object.vm_object);
                   1090: }
                   1091: 
                   1092: /*
                   1093:  *     VM_MAP_RANGE_CHECK:     [ internal use only ]
                   1094:  *
                   1095:  *     Asserts that the starting and ending region
                   1096:  *     addresses fall within the valid range of the map.
                   1097:  */
                   1098: #define        VM_MAP_RANGE_CHECK(map, start, end)             \
                   1099:                {                                       \
                   1100:                if (start < vm_map_min(map))            \
                   1101:                        start = vm_map_min(map);        \
                   1102:                if (end > vm_map_max(map))              \
                   1103:                        end = vm_map_max(map);          \
                   1104:                if (start > end)                        \
                   1105:                        start = end;                    \
                   1106:                }
                   1107: 
                   1108: /*
                   1109:  *     vm_map_submap:          [ kernel use only ]
                   1110:  *
                   1111:  *     Mark the given range as handled by a subordinate map.
                   1112:  *
                   1113:  *     This range must have been created with vm_map_find using
                   1114:  *     the vm_submap_object, and no other operations may have been
                   1115:  *     performed on this range prior to calling vm_map_submap.
                   1116:  *
                   1117:  *     Only a limited number of operations can be performed
                   1118:  *     within this rage after calling vm_map_submap:
                   1119:  *             vm_fault
                   1120:  *     [Don't try vm_map_copyin!]
                   1121:  *
                   1122:  *     To remove a submapping, one must first remove the
                   1123:  *     range from the superior map, and then destroy the
                   1124:  *     submap (if desired).  [Better yet, don't try it.]
                   1125:  */
                   1126: kern_return_t vm_map_submap(map, start, end, submap)
                   1127:        register vm_map_t       map;
                   1128:        register vm_offset_t    start;
                   1129:        register vm_offset_t    end;
                   1130:        vm_map_t                submap;
                   1131: {
                   1132:        vm_map_entry_t          entry;
                   1133:        register kern_return_t  result = KERN_INVALID_ARGUMENT;
                   1134:        register vm_object_t    object;
                   1135: 
                   1136:        vm_map_lock(map);
                   1137: 
                   1138:        VM_MAP_RANGE_CHECK(map, start, end);
                   1139: 
                   1140:        if (vm_map_lookup_entry(map, start, &entry)) {
                   1141:                vm_map_clip_start(map, entry, start);
                   1142:        }
                   1143:         else
                   1144:                entry = entry->vme_next;
                   1145: 
                   1146:        vm_map_clip_end(map, entry, end);
                   1147: 
                   1148:        if ((entry->vme_start == start) && (entry->vme_end == end) &&
                   1149:            (!entry->is_sub_map) &&
                   1150:            ((object = entry->object.vm_object) == vm_submap_object) &&
                   1151:            (object->resident_page_count == 0) &&
                   1152:            (object->copy == VM_OBJECT_NULL) &&
                   1153:            (object->shadow == VM_OBJECT_NULL) &&
                   1154:            (!object->pager_created)) {
                   1155:                entry->object.vm_object = VM_OBJECT_NULL;
                   1156:                vm_object_deallocate(object);
                   1157:                entry->is_sub_map = TRUE;
                   1158:                vm_map_reference(entry->object.sub_map = submap);
                   1159:                result = KERN_SUCCESS;
                   1160:        }
                   1161:        vm_map_unlock(map);
                   1162: 
                   1163:        return(result);
                   1164: }
                   1165: 
                   1166: /*
                   1167:  *     vm_map_protect:
                   1168:  *
                   1169:  *     Sets the protection of the specified address
                   1170:  *     region in the target map.  If "set_max" is
                   1171:  *     specified, the maximum protection is to be set;
                   1172:  *     otherwise, only the current protection is affected.
                   1173:  */
                   1174: kern_return_t vm_map_protect(map, start, end, new_prot, set_max)
                   1175:        register vm_map_t       map;
                   1176:        register vm_offset_t    start;
                   1177:        register vm_offset_t    end;
                   1178:        register vm_prot_t      new_prot;
                   1179:        register boolean_t      set_max;
                   1180: {
                   1181:        register vm_map_entry_t         current;
                   1182:        vm_map_entry_t                  entry;
                   1183: 
                   1184:        vm_map_lock(map);
                   1185: 
                   1186:        VM_MAP_RANGE_CHECK(map, start, end);
                   1187: 
                   1188:        if (vm_map_lookup_entry(map, start, &entry)) {
                   1189:                vm_map_clip_start(map, entry, start);
                   1190:        }
                   1191:         else
                   1192:                entry = entry->vme_next;
                   1193: 
                   1194:        /*
                   1195:         *      Make a first pass to check for protection
                   1196:         *      violations.
                   1197:         */
                   1198: 
                   1199:        current = entry;
                   1200:        while ((current != vm_map_to_entry(map)) &&
                   1201:               (current->vme_start < end)) {
                   1202: 
                   1203:                if (current->is_sub_map) {
                   1204:                        vm_map_unlock(map);
                   1205:                        return(KERN_INVALID_ARGUMENT);
                   1206:                }
                   1207:                if ((new_prot & (VM_PROT_NOTIFY | current->max_protection))
                   1208:                    != new_prot) {
                   1209:                       vm_map_unlock(map);
                   1210:                       return(KERN_PROTECTION_FAILURE);
                   1211:                }
                   1212: 
                   1213:                current = current->vme_next;
                   1214:        }
                   1215: 
                   1216:        /*
                   1217:         *      Go back and fix up protections.
                   1218:         *      [Note that clipping is not necessary the second time.]
                   1219:         */
                   1220: 
                   1221:        current = entry;
                   1222: 
                   1223:        while ((current != vm_map_to_entry(map)) &&
                   1224:               (current->vme_start < end)) {
                   1225: 
                   1226:                vm_prot_t       old_prot;
                   1227: 
                   1228:                vm_map_clip_end(map, current, end);
                   1229: 
                   1230:                old_prot = current->protection;
                   1231:                if (set_max)
                   1232:                        current->protection =
                   1233:                                (current->max_protection = new_prot) &
                   1234:                                        old_prot;
                   1235:                else
                   1236:                        current->protection = new_prot;
                   1237: 
                   1238:                /*
                   1239:                 *      Update physical map if necessary.
                   1240:                 */
                   1241: 
                   1242:                if (current->protection != old_prot) {
                   1243:                        pmap_protect(map->pmap, current->vme_start,
                   1244:                                        current->vme_end,
                   1245:                                        current->protection);
                   1246:                }
                   1247:                current = current->vme_next;
                   1248:        }
                   1249: 
                   1250:        vm_map_unlock(map);
                   1251:        return(KERN_SUCCESS);
                   1252: }
                   1253: 
                   1254: /*
                   1255:  *     vm_map_inherit:
                   1256:  *
                   1257:  *     Sets the inheritance of the specified address
                   1258:  *     range in the target map.  Inheritance
                   1259:  *     affects how the map will be shared with
                   1260:  *     child maps at the time of vm_map_fork.
                   1261:  */
                   1262: kern_return_t vm_map_inherit(map, start, end, new_inheritance)
                   1263:        register vm_map_t       map;
                   1264:        register vm_offset_t    start;
                   1265:        register vm_offset_t    end;
                   1266:        register vm_inherit_t   new_inheritance;
                   1267: {
                   1268:        register vm_map_entry_t entry;
                   1269:        vm_map_entry_t  temp_entry;
                   1270: 
                   1271:        vm_map_lock(map);
                   1272: 
                   1273:        VM_MAP_RANGE_CHECK(map, start, end);
                   1274: 
                   1275:        if (vm_map_lookup_entry(map, start, &temp_entry)) {
                   1276:                entry = temp_entry;
                   1277:                vm_map_clip_start(map, entry, start);
                   1278:        }
                   1279:        else
                   1280:                entry = temp_entry->vme_next;
                   1281: 
                   1282:        while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
                   1283:                vm_map_clip_end(map, entry, end);
                   1284: 
                   1285:                entry->inheritance = new_inheritance;
                   1286: 
                   1287:                entry = entry->vme_next;
                   1288:        }
                   1289: 
                   1290:        vm_map_unlock(map);
                   1291:        return(KERN_SUCCESS);
                   1292: }
                   1293: 
                   1294: /*
                   1295:  *     vm_map_pageable_common:
                   1296:  *
                   1297:  *     Sets the pageability of the specified address
                   1298:  *     range in the target map.  Regions specified
                   1299:  *     as not pageable require locked-down physical
                   1300:  *     memory and physical page maps.  access_type indicates
                   1301:  *     types of accesses that must not generate page faults.
                   1302:  *     This is checked against protection of memory being locked-down.
                   1303:  *     access_type of VM_PROT_NONE makes memory pageable.
                   1304:  *
                   1305:  *     The map must not be locked, but a reference
                   1306:  *     must remain to the map throughout the call.
                   1307:  *
                   1308:  *     Callers should use macros in vm/vm_map.h (i.e. vm_map_pageable,
                   1309:  *     or vm_map_pageable_user); don't call vm_map_pageable directly.
                   1310:  */
                   1311: kern_return_t vm_map_pageable_common(map, start, end, access_type, user_wire)
                   1312:        register vm_map_t       map;
                   1313:        register vm_offset_t    start;
                   1314:        register vm_offset_t    end;
                   1315:        register vm_prot_t      access_type;
                   1316:        boolean_t               user_wire;
                   1317: {
                   1318:        register vm_map_entry_t entry;
                   1319:        vm_map_entry_t          start_entry;
                   1320: 
                   1321:        vm_map_lock(map);
                   1322: 
                   1323:        VM_MAP_RANGE_CHECK(map, start, end);
                   1324: 
                   1325:        if (vm_map_lookup_entry(map, start, &start_entry)) {
                   1326:                entry = start_entry;
                   1327:                /*
                   1328:                 *      vm_map_clip_start will be done later.
                   1329:                 */
                   1330:        }
                   1331:        else {
                   1332:                /*
                   1333:                 *      Start address is not in map; this is fatal.
                   1334:                 */
                   1335:                vm_map_unlock(map);
                   1336:                return(KERN_FAILURE);
                   1337:        }
                   1338: 
                   1339:        /*
                   1340:         *      Actions are rather different for wiring and unwiring,
                   1341:         *      so we have two separate cases.
                   1342:         */
                   1343: 
                   1344:        if (access_type == VM_PROT_NONE) {
                   1345: 
                   1346:                vm_map_clip_start(map, entry, start);
                   1347: 
                   1348:                /*
                   1349:                 *      Unwiring.  First ensure that the range to be
                   1350:                 *      unwired is really wired down.
                   1351:                 */
                   1352:                while ((entry != vm_map_to_entry(map)) &&
                   1353:                       (entry->vme_start < end)) {
                   1354: 
                   1355:                    if ((entry->wired_count == 0) ||
                   1356:                        ((entry->vme_end < end) &&
                   1357:                         ((entry->vme_next == vm_map_to_entry(map)) ||
                   1358:                          (entry->vme_next->vme_start > entry->vme_end))) ||
                   1359:                        (user_wire && (entry->user_wired_count == 0))) {
                   1360:                            vm_map_unlock(map);
                   1361:                            return(KERN_INVALID_ARGUMENT);
                   1362:                    }
                   1363:                    entry = entry->vme_next;
                   1364:                }
                   1365: 
                   1366:                /*
                   1367:                 *      Now decrement the wiring count for each region.
                   1368:                 *      If a region becomes completely unwired,
                   1369:                 *      unwire its physical pages and mappings.
                   1370:                 */
                   1371:                entry = start_entry;
                   1372:                while ((entry != vm_map_to_entry(map)) &&
                   1373:                       (entry->vme_start < end)) {
                   1374:                    vm_map_clip_end(map, entry, end);
                   1375: 
                   1376:                    if (user_wire) {
                   1377:                        if (--(entry->user_wired_count) == 0)
                   1378:                            entry->wired_count--;
                   1379:                    }
                   1380:                    else {
                   1381:                        entry->wired_count--;
                   1382:                    }
                   1383: 
                   1384:                    if (entry->wired_count == 0)
                   1385:                        vm_fault_unwire(map, entry);
                   1386: 
                   1387:                    entry = entry->vme_next;
                   1388:                }
                   1389:        }
                   1390: 
                   1391:        else {
                   1392:                /*
                   1393:                 *      Wiring.  We must do this in two passes:
                   1394:                 *
                   1395:                 *      1.  Holding the write lock, we create any shadow
                   1396:                 *          or zero-fill objects that need to be created.
                   1397:                 *          Then we clip each map entry to the region to be
                   1398:                 *          wired and increment its wiring count.  We
                   1399:                 *          create objects before clipping the map entries
                   1400:                 *          to avoid object proliferation.
                   1401:                 *
                   1402:                 *      2.  We downgrade to a read lock, and call
                   1403:                 *          vm_fault_wire to fault in the pages for any
                   1404:                 *          newly wired area (wired_count is 1).
                   1405:                 *
                   1406:                 *      Downgrading to a read lock for vm_fault_wire avoids
                   1407:                 *      a possible deadlock with another thread that may have
                   1408:                 *      faulted on one of the pages to be wired (it would mark
                   1409:                 *      the page busy, blocking us, then in turn block on the
                   1410:                 *      map lock that we hold).  Because of problems in the
                   1411:                 *      recursive lock package, we cannot upgrade to a write
                   1412:                 *      lock in vm_map_lookup.  Thus, any actions that require
                   1413:                 *      the write lock must be done beforehand.  Because we
                   1414:                 *      keep the read lock on the map, the copy-on-write
                   1415:                 *      status of the entries we modify here cannot change.
                   1416:                 */
                   1417: 
                   1418:                /*
                   1419:                 *      Pass 1.
                   1420:                 */
                   1421:                while ((entry != vm_map_to_entry(map)) &&
                   1422:                       (entry->vme_start < end)) {
                   1423:                    vm_map_clip_end(map, entry, end);
                   1424: 
                   1425:                    if (entry->wired_count == 0) {
                   1426: 
                   1427:                        /*
                   1428:                         *      Perform actions of vm_map_lookup that need
                   1429:                         *      the write lock on the map: create a shadow
                   1430:                         *      object for a copy-on-write region, or an
                   1431:                         *      object for a zero-fill region.
                   1432:                         */
                   1433:                        if (entry->needs_copy &&
                   1434:                            ((entry->protection & VM_PROT_WRITE) != 0)) {
                   1435: 
                   1436:                                vm_object_shadow(&entry->object.vm_object,
                   1437:                                                &entry->offset,
                   1438:                                                (vm_size_t)(entry->vme_end
                   1439:                                                        - entry->vme_start));
                   1440:                                entry->needs_copy = FALSE;
                   1441:                        }
                   1442:                        if (entry->object.vm_object == VM_OBJECT_NULL) {
                   1443:                                entry->object.vm_object =
                   1444:                                        vm_object_allocate(
                   1445:                                            (vm_size_t)(entry->vme_end
                   1446:                                                        - entry->vme_start));
                   1447:                                entry->offset = (vm_offset_t)0;
                   1448:                        }
                   1449:                    }
                   1450:                    vm_map_clip_start(map, entry, start);
                   1451:                    vm_map_clip_end(map, entry, end);
                   1452: 
                   1453:                    if (user_wire) {
                   1454:                        if ((entry->user_wired_count)++ == 0)
                   1455:                            entry->wired_count++;
                   1456:                    }
                   1457:                    else {
                   1458:                        entry->wired_count++;
                   1459:                    }
                   1460: 
                   1461:                    /*
                   1462:                     *  Check for holes and protection mismatch.
                   1463:                     *  Holes: Next entry should be contiguous unless
                   1464:                     *          this is the end of the region.
                   1465:                     *  Protection: Access requested must be allowed.
                   1466:                     */
                   1467:                    if (((entry->vme_end < end) &&
                   1468:                         ((entry->vme_next == vm_map_to_entry(map)) ||
                   1469:                          (entry->vme_next->vme_start > entry->vme_end))) ||
                   1470:                        ((entry->protection & access_type) != access_type)) {
                   1471:                            /*
                   1472:                             *  Found a hole or protection problem.
                   1473:                             *  Object creation actions
                   1474:                             *  do not need to be undone, but the
                   1475:                             *  wired counts need to be restored.
                   1476:                             */
                   1477:                            while ((entry != vm_map_to_entry(map)) &&
                   1478:                                (entry->vme_end > start)) {
                   1479:                                    if (user_wire) {
                   1480:                                        if (--(entry->user_wired_count) == 0)
                   1481:                                            entry->wired_count--;
                   1482:                                    }
                   1483:                                    else {
                   1484:                                       entry->wired_count--;
                   1485:                                    }
                   1486: 
                   1487:                                    entry = entry->vme_prev;
                   1488:                            }
                   1489: 
                   1490:                            vm_map_unlock(map);
                   1491:                            return(KERN_FAILURE);
                   1492:                    }
                   1493:                    entry = entry->vme_next;
                   1494:                }
                   1495: 
                   1496:                /*
                   1497:                 *      Pass 2.
                   1498:                 */
                   1499: 
                   1500:                /*
                   1501:                 * HACK HACK HACK HACK
                   1502:                 *
                   1503:                 * If we are wiring in the kernel map or a submap of it,
                   1504:                 * unlock the map to avoid deadlocks.  We trust that the
                   1505:                 * kernel threads are well-behaved, and therefore will
                   1506:                 * not do anything destructive to this region of the map
                   1507:                 * while we have it unlocked.  We cannot trust user threads
                   1508:                 * to do the same.
                   1509:                 *
                   1510:                 * HACK HACK HACK HACK
                   1511:                 */
                   1512:                if (vm_map_pmap(map) == kernel_pmap) {
                   1513:                    vm_map_unlock(map);         /* trust me ... */
                   1514:                }
                   1515:                else {
                   1516:                    vm_map_lock_set_recursive(map);
                   1517:                    vm_map_lock_write_to_read(map);
                   1518:                }
                   1519: 
                   1520:                entry = start_entry;
                   1521:                while (entry != vm_map_to_entry(map) &&
                   1522:                        entry->vme_start < end) {
                   1523:                    /*
                   1524:                     *  Wiring cases:
                   1525:                     *      Kernel: wired == 1 && user_wired == 0
                   1526:                     *      User:   wired == 1 && user_wired == 1
                   1527:                     *
                   1528:                     *  Don't need to wire if either is > 1.  wired = 0 &&
                   1529:                     *  user_wired == 1 can't happen.
                   1530:                     */
                   1531: 
                   1532:                    /*
                   1533:                     *  XXX This assumes that the faults always succeed.
                   1534:                     */
                   1535:                    if ((entry->wired_count == 1) &&
                   1536:                        (entry->user_wired_count <= 1)) {
                   1537:                            vm_fault_wire(map, entry);
                   1538:                    }
                   1539:                    entry = entry->vme_next;
                   1540:                }
                   1541: 
                   1542:                if (vm_map_pmap(map) == kernel_pmap) {
                   1543:                    vm_map_lock(map);
                   1544:                }
                   1545:                else {
                   1546:                    vm_map_lock_clear_recursive(map);
                   1547:                }
                   1548:        }
                   1549: 
                   1550:        vm_map_unlock(map);
                   1551: 
                   1552:        return(KERN_SUCCESS);
                   1553: }
                   1554: 
                   1555: /*
                   1556:  *     vm_map_entry_delete:    [ internal use only ]
                   1557:  *
                   1558:  *     Deallocate the given entry from the target map.
                   1559:  */
                   1560: void vm_map_entry_delete(map, entry)
                   1561:        register vm_map_t       map;
                   1562:        register vm_map_entry_t entry;
                   1563: {
                   1564:        register vm_offset_t    s, e;
                   1565:        register vm_object_t    object;
                   1566:        extern vm_object_t      kernel_object;
                   1567: 
                   1568:        s = entry->vme_start;
                   1569:        e = entry->vme_end;
                   1570: 
                   1571:        /*Check if projected buffer*/
                   1572:        if (map != kernel_map && entry->projected_on != 0) {
                   1573:          /*Check if projected kernel entry is persistent;
                   1574:            may only manipulate directly if it is*/
                   1575:          if (entry->projected_on->projected_on == 0)
                   1576:            entry->wired_count = 0;    /*Avoid unwire fault*/
                   1577:          else
                   1578:            return;
                   1579:        }
                   1580: 
                   1581:        /*
                   1582:         *      Get the object.    Null objects cannot have pmap entries.
                   1583:         */
                   1584: 
                   1585:        if ((object = entry->object.vm_object) != VM_OBJECT_NULL) {
                   1586: 
                   1587:            /*
                   1588:             *  Unwire before removing addresses from the pmap;
                   1589:             *  otherwise, unwiring will put the entries back in
                   1590:             *  the pmap.
                   1591:             */
                   1592: 
                   1593:            if (entry->wired_count != 0) {
                   1594:                vm_fault_unwire(map, entry);
                   1595:                entry->wired_count = 0;
                   1596:                entry->user_wired_count = 0;
                   1597:            }
                   1598: 
                   1599:            /*
                   1600:             *  If the object is shared, we must remove
                   1601:             *  *all* references to this data, since we can't
                   1602:             *  find all of the physical maps which are sharing
                   1603:             *  it.
                   1604:             */
                   1605: 
                   1606:            if (object == kernel_object) {
                   1607:                vm_object_lock(object);
                   1608:                vm_object_page_remove(object, entry->offset,
                   1609:                                entry->offset + (e - s));
                   1610:                vm_object_unlock(object);
                   1611:            } else if (entry->is_shared) {
                   1612:                vm_object_pmap_remove(object,
                   1613:                                 entry->offset,
                   1614:                                 entry->offset + (e - s));
                   1615:            }
                   1616:            else {
                   1617:                pmap_remove(map->pmap, s, e);
                   1618:            }
                   1619:         }
                   1620: 
                   1621:        /*
                   1622:         *      Deallocate the object only after removing all
                   1623:         *      pmap entries pointing to its pages.
                   1624:         */
                   1625: 
                   1626:        if (entry->is_sub_map)
                   1627:                vm_map_deallocate(entry->object.sub_map);
                   1628:        else
                   1629:                vm_object_deallocate(entry->object.vm_object);
                   1630: 
                   1631:        vm_map_entry_unlink(map, entry);
                   1632:        map->size -= e - s;
                   1633: 
                   1634:        vm_map_entry_dispose(map, entry);
                   1635: }
                   1636: 
                   1637: /*
                   1638:  *     vm_map_delete:  [ internal use only ]
                   1639:  *
                   1640:  *     Deallocates the given address range from the target
                   1641:  *     map.
                   1642:  */
                   1643: 
                   1644: kern_return_t vm_map_delete(map, start, end)
                   1645:        register vm_map_t       map;
                   1646:        register vm_offset_t    start;
                   1647:        register vm_offset_t    end;
                   1648: {
                   1649:        vm_map_entry_t          entry;
                   1650:        vm_map_entry_t          first_entry;
                   1651: 
                   1652:        /*
                   1653:         *      Find the start of the region, and clip it
                   1654:         */
                   1655: 
                   1656:        if (!vm_map_lookup_entry(map, start, &first_entry))
                   1657:                entry = first_entry->vme_next;
                   1658:        else {
                   1659:                entry = first_entry;
                   1660: #if    NORMA_IPC_xxx
                   1661:                /*
                   1662:                 * XXX Had to disable this code because:
                   1663: 
                   1664:                 _vm_map_delete(c0804b78,c2198000,c219a000,0,c219a000)+df
                   1665:                        [vm/vm_map.c:2007]
                   1666:                 _vm_map_remove(c0804b78,c2198000,c219a000,c0817834,
                   1667:                 c081786c)+42 [vm/vm_map.c:2094]
                   1668:                 _kmem_io_map_deallocate(c0804b78,c2198000,2000,c0817834,
                   1669:                 c081786c)+43 [vm/vm_kern.c:818]
                   1670:                 _device_write_dealloc(c081786c)+117 [device/ds_routines.c:814]
                   1671:                 _ds_write_done(c081786c,0)+2e [device/ds_routines.c:848]
                   1672:                 _io_done_thread_continue(c08150c0,c21d4e14,c21d4e30,c08150c0,
                   1673:                 c080c114)+14 [device/ds_routines.c:1350]
                   1674: 
                   1675:                 */
                   1676:                if (start > entry->vme_start
                   1677:                    && end == entry->vme_end
                   1678:                    && ! entry->wired_count     /* XXX ??? */
                   1679:                    && ! entry->is_shared
                   1680:                     && ! entry->projected_on
                   1681:                    && ! entry->is_sub_map) {
                   1682:                        extern vm_object_t kernel_object;
                   1683:                        register vm_object_t object = entry->object.vm_object;
                   1684: 
                   1685:                        /*
                   1686:                         * The region to be deleted lives at the end
                   1687:                         * of this entry, and thus all we have to do is
                   1688:                         * truncate the entry.
                   1689:                         *
                   1690:                         * This special case is necessary if we want
                   1691:                         * coalescing to do us any good.
                   1692:                         *
                   1693:                         * XXX Do we have to adjust object size?
                   1694:                         */
                   1695:                        if (object == kernel_object) {
                   1696:                                vm_object_lock(object);
                   1697:                                vm_object_page_remove(object,
                   1698:                                                      entry->offset + start,
                   1699:                                                      entry->offset +
                   1700:                                                      (end - start));
                   1701:                                vm_object_unlock(object);
                   1702:                        } else if (entry->is_shared) {
                   1703:                                vm_object_pmap_remove(object,
                   1704:                                                      entry->offset + start,
                   1705:                                                      entry->offset +
                   1706:                                                      (end - start));
                   1707:                        } else {
                   1708:                                pmap_remove(map->pmap, start, end);
                   1709:                        }
                   1710:                        object->size -= (end - start);  /* XXX */
                   1711: 
                   1712:                        entry->vme_end = start;
                   1713:                        map->size -= (end - start);
                   1714: 
                   1715:                        if (map->wait_for_space) {
                   1716:                                thread_wakeup((event_t) map);
                   1717:                        }
                   1718:                        return KERN_SUCCESS;
                   1719:                }
                   1720: #endif /* NORMA_IPC */
                   1721:                vm_map_clip_start(map, entry, start);
                   1722: 
                   1723:                /*
                   1724:                 *      Fix the lookup hint now, rather than each
                   1725:                 *      time though the loop.
                   1726:                 */
                   1727: 
                   1728:                SAVE_HINT(map, entry->vme_prev);
                   1729:        }
                   1730: 
                   1731:        /*
                   1732:         *      Save the free space hint
                   1733:         */
                   1734: 
                   1735:        if (map->first_free->vme_start >= start)
                   1736:                map->first_free = entry->vme_prev;
                   1737: 
                   1738:        /*
                   1739:         *      Step through all entries in this region
                   1740:         */
                   1741: 
                   1742:        while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
                   1743:                vm_map_entry_t          next;
                   1744: 
                   1745:                vm_map_clip_end(map, entry, end);
                   1746: 
                   1747:                /*
                   1748:                 *      If the entry is in transition, we must wait
                   1749:                 *      for it to exit that state.  It could be clipped
                   1750:                 *      while we leave the map unlocked.
                   1751:                 */
                   1752:                 if(entry->in_transition) {
                   1753:                         /*
                   1754:                          * Say that we are waiting, and wait for entry.
                   1755:                          */
                   1756:                         entry->needs_wakeup = TRUE;
                   1757:                         vm_map_entry_wait(map, FALSE);
                   1758:                         vm_map_lock(map);
                   1759: 
                   1760:                         /*
                   1761:                          * The entry could have been clipped or it
                   1762:                          * may not exist anymore.  look it up again.
                   1763:                          */
                   1764:                         if(!vm_map_lookup_entry(map, start, &entry)) {
                   1765:                                entry = entry->vme_next;
                   1766:                        }
                   1767:                        continue;
                   1768:                }
                   1769: 
                   1770:                next = entry->vme_next;
                   1771: 
                   1772:                vm_map_entry_delete(map, entry);
                   1773:                entry = next;
                   1774:        }
                   1775: 
                   1776:        if (map->wait_for_space)
                   1777:                thread_wakeup((event_t) map);
                   1778: 
                   1779:        return(KERN_SUCCESS);
                   1780: }
                   1781: 
                   1782: /*
                   1783:  *     vm_map_remove:
                   1784:  *
                   1785:  *     Remove the given address range from the target map.
                   1786:  *     This is the exported form of vm_map_delete.
                   1787:  */
                   1788: kern_return_t vm_map_remove(map, start, end)
                   1789:        register vm_map_t       map;
                   1790:        register vm_offset_t    start;
                   1791:        register vm_offset_t    end;
                   1792: {
                   1793:        register kern_return_t  result;
                   1794: 
                   1795:        vm_map_lock(map);
                   1796:        VM_MAP_RANGE_CHECK(map, start, end);
                   1797:        result = vm_map_delete(map, start, end);
                   1798:        vm_map_unlock(map);
                   1799: 
                   1800:        return(result);
                   1801: }
                   1802: 
                   1803: 
                   1804: /*
                   1805:  *     vm_map_copy_steal_pages:
                   1806:  *
                   1807:  *     Steal all the pages from a vm_map_copy page_list by copying ones
                   1808:  *     that have not already been stolen.
                   1809:  */
                   1810: void
                   1811: vm_map_copy_steal_pages(copy)
                   1812: vm_map_copy_t  copy;
                   1813: {
                   1814:        register vm_page_t      m, new_m;
                   1815:        register int            i;
                   1816:        vm_object_t             object;
                   1817: 
                   1818:        for (i = 0; i < copy->cpy_npages; i++) {
                   1819: 
                   1820:                /*
                   1821:                 *      If the page is not tabled, then it's already stolen.
                   1822:                 */
                   1823:                m = copy->cpy_page_list[i];
                   1824:                if (!m->tabled)
                   1825:                        continue;
                   1826: 
                   1827:                /*
                   1828:                 *      Page was not stolen,  get a new
                   1829:                 *      one and do the copy now.
                   1830:                 */
                   1831:                while ((new_m = vm_page_grab(FALSE)) == VM_PAGE_NULL) {
                   1832:                        VM_PAGE_WAIT((void(*)()) 0);
                   1833:                }
                   1834: 
                   1835:                vm_page_copy(m, new_m);
                   1836: 
                   1837:                object = m->object;
                   1838:                vm_object_lock(object);
                   1839:                vm_page_lock_queues();
                   1840:                if (!m->active && !m->inactive)
                   1841:                        vm_page_activate(m);
                   1842:                vm_page_unlock_queues();
                   1843:                PAGE_WAKEUP_DONE(m);
                   1844:                vm_object_paging_end(object);
                   1845:                vm_object_unlock(object);
                   1846: 
                   1847:                copy->cpy_page_list[i] = new_m;
                   1848:        }
                   1849: }
                   1850: 
                   1851: /*
                   1852:  *     vm_map_copy_page_discard:
                   1853:  *
                   1854:  *     Get rid of the pages in a page_list copy.  If the pages are
                   1855:  *     stolen, they are freed.  If the pages are not stolen, they
                   1856:  *     are unbusied, and associated state is cleaned up.
                   1857:  */
                   1858: void vm_map_copy_page_discard(copy)
                   1859: vm_map_copy_t  copy;
                   1860: {
                   1861:        while (copy->cpy_npages > 0) {
                   1862:                vm_page_t       m;
                   1863: 
                   1864:                if((m = copy->cpy_page_list[--(copy->cpy_npages)]) !=
                   1865:                    VM_PAGE_NULL) {
                   1866: 
                   1867:                        /*
                   1868:                         *      If it's not in the table, then it's
                   1869:                         *      a stolen page that goes back
                   1870:                         *      to the free list.  Else it belongs
                   1871:                         *      to some object, and we hold a
                   1872:                         *      paging reference on that object.
                   1873:                         */
                   1874:                        if (!m->tabled) {
                   1875:                                VM_PAGE_FREE(m);
                   1876:                        }
                   1877:                        else {
                   1878:                                vm_object_t     object;
                   1879: 
                   1880:                                object = m->object;
                   1881: 
                   1882:                                vm_object_lock(object);
                   1883:                                vm_page_lock_queues();
                   1884:                                if (!m->active && !m->inactive)
                   1885:                                        vm_page_activate(m);
                   1886:                                vm_page_unlock_queues();
                   1887: 
                   1888:                                PAGE_WAKEUP_DONE(m);
                   1889:                                vm_object_paging_end(object);
                   1890:                                vm_object_unlock(object);
                   1891:                        }
                   1892:                }
                   1893:        }
                   1894: }
                   1895: 
                   1896: /*
                   1897:  *     Routine:        vm_map_copy_discard
                   1898:  *
                   1899:  *     Description:
                   1900:  *             Dispose of a map copy object (returned by
                   1901:  *             vm_map_copyin).
                   1902:  */
                   1903: void
                   1904: vm_map_copy_discard(copy)
                   1905:        vm_map_copy_t   copy;
                   1906: {
                   1907: free_next_copy:
                   1908:        if (copy == VM_MAP_COPY_NULL)
                   1909:                return;
                   1910: 
                   1911:        switch (copy->type) {
                   1912:        case VM_MAP_COPY_ENTRY_LIST:
                   1913:                while (vm_map_copy_first_entry(copy) !=
                   1914:                                        vm_map_copy_to_entry(copy)) {
                   1915:                        vm_map_entry_t  entry = vm_map_copy_first_entry(copy);
                   1916: 
                   1917:                        vm_map_copy_entry_unlink(copy, entry);
                   1918:                        vm_object_deallocate(entry->object.vm_object);
                   1919:                        vm_map_copy_entry_dispose(copy, entry);
                   1920:                }
                   1921:                break;
                   1922:         case VM_MAP_COPY_OBJECT:
                   1923:                vm_object_deallocate(copy->cpy_object);
                   1924:                break;
                   1925:        case VM_MAP_COPY_PAGE_LIST:
                   1926: 
                   1927:                /*
                   1928:                 *      To clean this up, we have to unbusy all the pages
                   1929:                 *      and release the paging references in their objects.
                   1930:                 */
                   1931:                if (copy->cpy_npages > 0)
                   1932:                        vm_map_copy_page_discard(copy);
                   1933: 
                   1934:                /*
                   1935:                 *      If there's a continuation, abort it.  The
                   1936:                 *      abort routine releases any storage.
                   1937:                 */
                   1938:                if (vm_map_copy_has_cont(copy)) {
                   1939: 
                   1940:                        /*
                   1941:                         *      Special case: recognize
                   1942:                         *      vm_map_copy_discard_cont and optimize
                   1943:                         *      here to avoid tail recursion.
                   1944:                         */
                   1945:                        if (copy->cpy_cont == vm_map_copy_discard_cont) {
                   1946:                                register vm_map_copy_t  new_copy;
                   1947: 
                   1948:                                new_copy = (vm_map_copy_t) copy->cpy_cont_args;
                   1949:                                zfree(vm_map_copy_zone, (vm_offset_t) copy);
                   1950:                                copy = new_copy;
                   1951:                                goto free_next_copy;
                   1952:                        }
                   1953:                        else {
                   1954:                                vm_map_copy_abort_cont(copy);
                   1955:                        }
                   1956:                }
                   1957: 
                   1958:                break;
                   1959:        }
                   1960:        zfree(vm_map_copy_zone, (vm_offset_t) copy);
                   1961: }
                   1962: 
                   1963: /*
                   1964:  *     Routine:        vm_map_copy_copy
                   1965:  *
                   1966:  *     Description:
                   1967:  *                     Move the information in a map copy object to
                   1968:  *                     a new map copy object, leaving the old one
                   1969:  *                     empty.
                   1970:  *
                   1971:  *                     This is used by kernel routines that need
                   1972:  *                     to look at out-of-line data (in copyin form)
                   1973:  *                     before deciding whether to return SUCCESS.
                   1974:  *                     If the routine returns FAILURE, the original
                   1975:  *                     copy object will be deallocated; therefore,
                   1976:  *                     these routines must make a copy of the copy
                   1977:  *                     object and leave the original empty so that
                   1978:  *                     deallocation will not fail.
                   1979:  */
                   1980: vm_map_copy_t
                   1981: vm_map_copy_copy(copy)
                   1982:        vm_map_copy_t   copy;
                   1983: {
                   1984:        vm_map_copy_t   new_copy;
                   1985: 
                   1986:        if (copy == VM_MAP_COPY_NULL)
                   1987:                return VM_MAP_COPY_NULL;
                   1988: 
                   1989:        /*
                   1990:         * Allocate a new copy object, and copy the information
                   1991:         * from the old one into it.
                   1992:         */
                   1993: 
                   1994:        new_copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   1995:        *new_copy = *copy;
                   1996: 
                   1997:        if (copy->type == VM_MAP_COPY_ENTRY_LIST) {
                   1998:                /*
                   1999:                 * The links in the entry chain must be
                   2000:                 * changed to point to the new copy object.
                   2001:                 */
                   2002:                vm_map_copy_first_entry(copy)->vme_prev
                   2003:                        = vm_map_copy_to_entry(new_copy);
                   2004:                vm_map_copy_last_entry(copy)->vme_next
                   2005:                        = vm_map_copy_to_entry(new_copy);
                   2006:        }
                   2007: 
                   2008:        /*
                   2009:         * Change the old copy object into one that contains
                   2010:         * nothing to be deallocated.
                   2011:         */
                   2012:        copy->type = VM_MAP_COPY_OBJECT;
                   2013:        copy->cpy_object = VM_OBJECT_NULL;
                   2014: 
                   2015:        /*
                   2016:         * Return the new object.
                   2017:         */
                   2018:        return new_copy;
                   2019: }
                   2020: 
                   2021: /*
                   2022:  *     Routine:        vm_map_copy_discard_cont
                   2023:  *
                   2024:  *     Description:
                   2025:  *             A version of vm_map_copy_discard that can be called
                   2026:  *             as a continuation from a vm_map_copy page list.
                   2027:  */
                   2028: kern_return_t  vm_map_copy_discard_cont(cont_args, copy_result)
                   2029: vm_map_copyin_args_t   cont_args;
                   2030: vm_map_copy_t          *copy_result;   /* OUT */
                   2031: {
                   2032:        vm_map_copy_discard((vm_map_copy_t) cont_args);
                   2033:        if (copy_result != (vm_map_copy_t *)0)
                   2034:                *copy_result = VM_MAP_COPY_NULL;
                   2035:        return(KERN_SUCCESS);
                   2036: }
                   2037: 
                   2038: /*
                   2039:  *     Routine:        vm_map_copy_overwrite
                   2040:  *
                   2041:  *     Description:
                   2042:  *             Copy the memory described by the map copy
                   2043:  *             object (copy; returned by vm_map_copyin) onto
                   2044:  *             the specified destination region (dst_map, dst_addr).
                   2045:  *             The destination must be writeable.
                   2046:  *
                   2047:  *             Unlike vm_map_copyout, this routine actually
                   2048:  *             writes over previously-mapped memory.  If the
                   2049:  *             previous mapping was to a permanent (user-supplied)
                   2050:  *             memory object, it is preserved.
                   2051:  *
                   2052:  *             The attributes (protection and inheritance) of the
                   2053:  *             destination region are preserved.
                   2054:  *
                   2055:  *             If successful, consumes the copy object.
                   2056:  *             Otherwise, the caller is responsible for it.
                   2057:  *
                   2058:  *     Implementation notes:
                   2059:  *             To overwrite temporary virtual memory, it is
                   2060:  *             sufficient to remove the previous mapping and insert
                   2061:  *             the new copy.  This replacement is done either on
                   2062:  *             the whole region (if no permanent virtual memory
                   2063:  *             objects are embedded in the destination region) or
                   2064:  *             in individual map entries.
                   2065:  *
                   2066:  *             To overwrite permanent virtual memory, it is
                   2067:  *             necessary to copy each page, as the external
                   2068:  *             memory management interface currently does not
                   2069:  *             provide any optimizations.
                   2070:  *
                   2071:  *             Once a page of permanent memory has been overwritten,
                   2072:  *             it is impossible to interrupt this function; otherwise,
                   2073:  *             the call would be neither atomic nor location-independent.
                   2074:  *             The kernel-state portion of a user thread must be
                   2075:  *             interruptible.
                   2076:  *
                   2077:  *             It may be expensive to forward all requests that might
                   2078:  *             overwrite permanent memory (vm_write, vm_copy) to
                   2079:  *             uninterruptible kernel threads.  This routine may be
                   2080:  *             called by interruptible threads; however, success is
                   2081:  *             not guaranteed -- if the request cannot be performed
                   2082:  *             atomically and interruptibly, an error indication is
                   2083:  *             returned.
                   2084:  */
                   2085: kern_return_t vm_map_copy_overwrite(dst_map, dst_addr, copy, interruptible)
                   2086:        vm_map_t        dst_map;
                   2087:        vm_offset_t     dst_addr;
                   2088:        vm_map_copy_t   copy;
                   2089:        boolean_t       interruptible;
                   2090: {
                   2091:        vm_size_t       size;
                   2092:        vm_offset_t     start;
                   2093:        vm_map_entry_t  tmp_entry;
                   2094:        vm_map_entry_t  entry;
                   2095: 
                   2096:        boolean_t       contains_permanent_objects = FALSE;
                   2097: 
                   2098:        interruptible = FALSE;  /* XXX */
                   2099: 
                   2100:        /*
                   2101:         *      Check for null copy object.
                   2102:         */
                   2103: 
                   2104:        if (copy == VM_MAP_COPY_NULL)
                   2105:                return(KERN_SUCCESS);
                   2106: 
                   2107:        /*
                   2108:         *      Only works for entry lists at the moment.  Will
                   2109:         *      support page lists LATER.
                   2110:         */
                   2111: 
                   2112: #if    NORMA_IPC
                   2113:        vm_map_convert_from_page_list(copy);
                   2114: #else
                   2115:        assert(copy->type == VM_MAP_COPY_ENTRY_LIST);
                   2116: #endif
                   2117: 
                   2118:        /*
                   2119:         *      Currently this routine only handles page-aligned
                   2120:         *      regions.  Eventually, it should handle misalignments
                   2121:         *      by actually copying pages.
                   2122:         */
                   2123: 
                   2124:        if (!page_aligned(copy->offset) ||
                   2125:            !page_aligned(copy->size) ||
                   2126:            !page_aligned(dst_addr))
                   2127:                return(KERN_INVALID_ARGUMENT);
                   2128: 
                   2129:        size = copy->size;
                   2130: 
                   2131:        if (size == 0) {
                   2132:                vm_map_copy_discard(copy);
                   2133:                return(KERN_SUCCESS);
                   2134:        }
                   2135: 
                   2136:        /*
                   2137:         *      Verify that the destination is all writeable
                   2138:         *      initially.
                   2139:         */
                   2140: start_pass_1:
                   2141:        vm_map_lock(dst_map);
                   2142:        if (!vm_map_lookup_entry(dst_map, dst_addr, &tmp_entry)) {
                   2143:                vm_map_unlock(dst_map);
                   2144:                return(KERN_INVALID_ADDRESS);
                   2145:        }
                   2146:        vm_map_clip_start(dst_map, tmp_entry, dst_addr);
                   2147:        for (entry = tmp_entry;;) {
                   2148:                vm_size_t       sub_size = (entry->vme_end - entry->vme_start);
                   2149:                vm_map_entry_t  next = entry->vme_next;
                   2150: 
                   2151:                if ( ! (entry->protection & VM_PROT_WRITE)) {
                   2152:                        vm_map_unlock(dst_map);
                   2153:                        return(KERN_PROTECTION_FAILURE);
                   2154:                }
                   2155: 
                   2156:                /*
                   2157:                 *      If the entry is in transition, we must wait
                   2158:                 *      for it to exit that state.  Anything could happen
                   2159:                 *      when we unlock the map, so start over.
                   2160:                 */
                   2161:                 if (entry->in_transition) {
                   2162: 
                   2163:                         /*
                   2164:                          * Say that we are waiting, and wait for entry.
                   2165:                          */
                   2166:                         entry->needs_wakeup = TRUE;
                   2167:                         vm_map_entry_wait(dst_map, FALSE);
                   2168: 
                   2169:                        goto start_pass_1;
                   2170:                }
                   2171: 
                   2172:                if (size <= sub_size)
                   2173:                        break;
                   2174: 
                   2175:                if ((next == vm_map_to_entry(dst_map)) ||
                   2176:                    (next->vme_start != entry->vme_end)) {
                   2177:                        vm_map_unlock(dst_map);
                   2178:                        return(KERN_INVALID_ADDRESS);
                   2179:                }
                   2180: 
                   2181: 
                   2182:                /*
                   2183:                 *      Check for permanent objects in the destination.
                   2184:                 */
                   2185: 
                   2186:                if ((entry->object.vm_object != VM_OBJECT_NULL) &&
                   2187:                           !entry->object.vm_object->temporary)
                   2188:                        contains_permanent_objects = TRUE;
                   2189: 
                   2190:                size -= sub_size;
                   2191:                entry = next;
                   2192:        }
                   2193: 
                   2194:        /*
                   2195:         *      If there are permanent objects in the destination, then
                   2196:         *      the copy cannot be interrupted.
                   2197:         */
                   2198: 
                   2199:        if (interruptible && contains_permanent_objects)
                   2200:                return(KERN_FAILURE);   /* XXX */
                   2201: 
                   2202:        /*
                   2203:         * XXXO If there are no permanent objects in the destination,
                   2204:         * XXXO and the source and destination map entry zones match,
                   2205:         * XXXO and the destination map entry is not shared,
                   2206:         * XXXO then the map entries can be deleted and replaced
                   2207:         * XXXO with those from the copy.  The following code is the
                   2208:         * XXXO basic idea of what to do, but there are lots of annoying
                   2209:         * XXXO little details about getting protection and inheritance
                   2210:         * XXXO right.  Should add protection, inheritance, and sharing checks
                   2211:         * XXXO to the above pass and make sure that no wiring is involved.
                   2212:         */
                   2213: /*
                   2214:  *     if (!contains_permanent_objects &&
                   2215:  *         copy->cpy_hdr.entries_pageable == dst_map->hdr.entries_pageable) {
                   2216:  *
                   2217:  *              *
                   2218:  *              *      Run over copy and adjust entries.  Steal code
                   2219:  *              *      from vm_map_copyout() to do this.
                   2220:  *              *
                   2221:  *
                   2222:  *             tmp_entry = tmp_entry->vme_prev;
                   2223:  *             vm_map_delete(dst_map, dst_addr, dst_addr + copy->size);
                   2224:  *             vm_map_copy_insert(dst_map, tmp_entry, copy);
                   2225:  *
                   2226:  *             vm_map_unlock(dst_map);
                   2227:  *             vm_map_copy_discard(copy);
                   2228:  *     }
                   2229:  */
                   2230:        /*
                   2231:         *
                   2232:         *      Make a second pass, overwriting the data
                   2233:         *      At the beginning of each loop iteration,
                   2234:         *      the next entry to be overwritten is "tmp_entry"
                   2235:         *      (initially, the value returned from the lookup above),
                   2236:         *      and the starting address expected in that entry
                   2237:         *      is "start".
                   2238:         */
                   2239: 
                   2240:        start = dst_addr;
                   2241: 
                   2242:        while (vm_map_copy_first_entry(copy) != vm_map_copy_to_entry(copy)) {
                   2243:                vm_map_entry_t  copy_entry = vm_map_copy_first_entry(copy);
                   2244:                vm_size_t       copy_size = (copy_entry->vme_end - copy_entry->vme_start);
                   2245:                vm_object_t     object;
                   2246: 
                   2247:                entry = tmp_entry;
                   2248:                size = (entry->vme_end - entry->vme_start);
                   2249:                /*
                   2250:                 *      Make sure that no holes popped up in the
                   2251:                 *      address map, and that the protection is
                   2252:                 *      still valid, in case the map was unlocked
                   2253:                 *      earlier.
                   2254:                 */
                   2255: 
                   2256:                if (entry->vme_start != start) {
                   2257:                        vm_map_unlock(dst_map);
                   2258:                        return(KERN_INVALID_ADDRESS);
                   2259:                }
                   2260:                assert(entry != vm_map_to_entry(dst_map));
                   2261: 
                   2262:                /*
                   2263:                 *      Check protection again
                   2264:                 */
                   2265: 
                   2266:                if ( ! (entry->protection & VM_PROT_WRITE)) {
                   2267:                        vm_map_unlock(dst_map);
                   2268:                        return(KERN_PROTECTION_FAILURE);
                   2269:                }
                   2270: 
                   2271:                /*
                   2272:                 *      Adjust to source size first
                   2273:                 */
                   2274: 
                   2275:                if (copy_size < size) {
                   2276:                        vm_map_clip_end(dst_map, entry, entry->vme_start + copy_size);
                   2277:                        size = copy_size;
                   2278:                }
                   2279: 
                   2280:                /*
                   2281:                 *      Adjust to destination size
                   2282:                 */
                   2283: 
                   2284:                if (size < copy_size) {
                   2285:                        vm_map_copy_clip_end(copy, copy_entry,
                   2286:                                copy_entry->vme_start + size);
                   2287:                        copy_size = size;
                   2288:                }
                   2289: 
                   2290:                assert((entry->vme_end - entry->vme_start) == size);
                   2291:                assert((tmp_entry->vme_end - tmp_entry->vme_start) == size);
                   2292:                assert((copy_entry->vme_end - copy_entry->vme_start) == size);
                   2293: 
                   2294:                /*
                   2295:                 *      If the destination contains temporary unshared memory,
                   2296:                 *      we can perform the copy by throwing it away and
                   2297:                 *      installing the source data.
                   2298:                 */
                   2299: 
                   2300:                object = entry->object.vm_object;
                   2301:                if (!entry->is_shared &&
                   2302:                    ((object == VM_OBJECT_NULL) || object->temporary)) {
                   2303:                        vm_object_t     old_object = entry->object.vm_object;
                   2304:                        vm_offset_t     old_offset = entry->offset;
                   2305: 
                   2306:                        entry->object = copy_entry->object;
                   2307:                        entry->offset = copy_entry->offset;
                   2308:                        entry->needs_copy = copy_entry->needs_copy;
                   2309:                        entry->wired_count = 0;
                   2310:                        entry->user_wired_count = 0;
                   2311: 
                   2312:                        vm_map_copy_entry_unlink(copy, copy_entry);
                   2313:                        vm_map_copy_entry_dispose(copy, copy_entry);
                   2314: 
                   2315:                        vm_object_pmap_protect(
                   2316:                                old_object,
                   2317:                                old_offset,
                   2318:                                size,
                   2319:                                dst_map->pmap,
                   2320:                                tmp_entry->vme_start,
                   2321:                                VM_PROT_NONE);
                   2322: 
                   2323:                        vm_object_deallocate(old_object);
                   2324: 
                   2325:                        /*
                   2326:                         *      Set up for the next iteration.  The map
                   2327:                         *      has not been unlocked, so the next
                   2328:                         *      address should be at the end of this
                   2329:                         *      entry, and the next map entry should be
                   2330:                         *      the one following it.
                   2331:                         */
                   2332: 
                   2333:                        start = tmp_entry->vme_end;
                   2334:                        tmp_entry = tmp_entry->vme_next;
                   2335:                } else {
                   2336:                        vm_map_version_t        version;
                   2337:                        vm_object_t             dst_object = entry->object.vm_object;
                   2338:                        vm_offset_t             dst_offset = entry->offset;
                   2339:                        kern_return_t           r;
                   2340: 
                   2341:                        /*
                   2342:                         *      Take an object reference, and record
                   2343:                         *      the map version information so that the
                   2344:                         *      map can be safely unlocked.
                   2345:                         */
                   2346: 
                   2347:                        vm_object_reference(dst_object);
                   2348: 
                   2349:                        version.main_timestamp = dst_map->timestamp;
                   2350: 
                   2351:                        vm_map_unlock(dst_map);
                   2352: 
                   2353:                        /*
                   2354:                         *      Copy as much as possible in one pass
                   2355:                         */
                   2356: 
                   2357:                        copy_size = size;
                   2358:                        r = vm_fault_copy(
                   2359:                                        copy_entry->object.vm_object,
                   2360:                                        copy_entry->offset,
                   2361:                                        &copy_size,
                   2362:                                        dst_object,
                   2363:                                        dst_offset,
                   2364:                                        dst_map,
                   2365:                                        &version,
                   2366:                                        FALSE /* XXX interruptible */ );
                   2367: 
                   2368:                        /*
                   2369:                         *      Release the object reference
                   2370:                         */
                   2371: 
                   2372:                        vm_object_deallocate(dst_object);
                   2373: 
                   2374:                        /*
                   2375:                         *      If a hard error occurred, return it now
                   2376:                         */
                   2377: 
                   2378:                        if (r != KERN_SUCCESS)
                   2379:                                return(r);
                   2380: 
                   2381:                        if (copy_size != 0) {
                   2382:                                /*
                   2383:                                 *      Dispose of the copied region
                   2384:                                 */
                   2385: 
                   2386:                                vm_map_copy_clip_end(copy, copy_entry,
                   2387:                                        copy_entry->vme_start + copy_size);
                   2388:                                vm_map_copy_entry_unlink(copy, copy_entry);
                   2389:                                vm_object_deallocate(copy_entry->object.vm_object);
                   2390:                                vm_map_copy_entry_dispose(copy, copy_entry);
                   2391:                        }
                   2392: 
                   2393:                        /*
                   2394:                         *      Pick up in the destination map where we left off.
                   2395:                         *
                   2396:                         *      Use the version information to avoid a lookup
                   2397:                         *      in the normal case.
                   2398:                         */
                   2399: 
                   2400:                        start += copy_size;
                   2401:                        vm_map_lock(dst_map);
                   2402:                        if ((version.main_timestamp + 1) == dst_map->timestamp) {
                   2403:                                /* We can safely use saved tmp_entry value */
                   2404: 
                   2405:                                vm_map_clip_end(dst_map, tmp_entry, start);
                   2406:                                tmp_entry = tmp_entry->vme_next;
                   2407:                        } else {
                   2408:                                /* Must do lookup of tmp_entry */
                   2409: 
                   2410:                                if (!vm_map_lookup_entry(dst_map, start, &tmp_entry)) {
                   2411:                                        vm_map_unlock(dst_map);
                   2412:                                        return(KERN_INVALID_ADDRESS);
                   2413:                                }
                   2414:                                vm_map_clip_start(dst_map, tmp_entry, start);
                   2415:                        }
                   2416:                }
                   2417: 
                   2418:        }
                   2419:        vm_map_unlock(dst_map);
                   2420: 
                   2421:        /*
                   2422:         *      Throw away the vm_map_copy object
                   2423:         */
                   2424:        vm_map_copy_discard(copy);
                   2425: 
                   2426:        return(KERN_SUCCESS);
                   2427: }
                   2428: 
                   2429: /*
                   2430:  *     Macro:          vm_map_copy_insert
                   2431:  *
                   2432:  *     Description:
                   2433:  *             Link a copy chain ("copy") into a map at the
                   2434:  *             specified location (after "where").
                   2435:  *     Side effects:
                   2436:  *             The copy chain is destroyed.
                   2437:  *     Warning:
                   2438:  *             The arguments are evaluated multiple times.
                   2439:  */
                   2440: #define        vm_map_copy_insert(map, where, copy)                            \
                   2441:        MACRO_BEGIN                                                     \
                   2442:        (((where)->vme_next)->vme_prev = vm_map_copy_last_entry(copy))  \
                   2443:                ->vme_next = ((where)->vme_next);                       \
                   2444:        ((where)->vme_next = vm_map_copy_first_entry(copy))             \
                   2445:                ->vme_prev = (where);                                   \
                   2446:        (map)->hdr.nentries += (copy)->cpy_hdr.nentries;                \
                   2447:        zfree(vm_map_copy_zone, (vm_offset_t) copy);                    \
                   2448:        MACRO_END
                   2449: 
                   2450: /*
                   2451:  *     Routine:        vm_map_copyout
                   2452:  *
                   2453:  *     Description:
                   2454:  *             Copy out a copy chain ("copy") into newly-allocated
                   2455:  *             space in the destination map.
                   2456:  *
                   2457:  *             If successful, consumes the copy object.
                   2458:  *             Otherwise, the caller is responsible for it.
                   2459:  */
                   2460: kern_return_t vm_map_copyout(dst_map, dst_addr, copy)
                   2461:        register
                   2462:        vm_map_t        dst_map;
                   2463:        vm_offset_t     *dst_addr;      /* OUT */
                   2464:        register
                   2465:        vm_map_copy_t   copy;
                   2466: {
                   2467:        vm_size_t       size;
                   2468:        vm_size_t       adjustment;
                   2469:        vm_offset_t     start;
                   2470:        vm_offset_t     vm_copy_start;
                   2471:        vm_map_entry_t  last;
                   2472:        register
                   2473:        vm_map_entry_t  entry;
                   2474: 
                   2475:        /*
                   2476:         *      Check for null copy object.
                   2477:         */
                   2478: 
                   2479:        if (copy == VM_MAP_COPY_NULL) {
                   2480:                *dst_addr = 0;
                   2481:                return(KERN_SUCCESS);
                   2482:        }
                   2483: 
                   2484:        /*
                   2485:         *      Check for special copy object, created
                   2486:         *      by vm_map_copyin_object.
                   2487:         */
                   2488: 
                   2489:        if (copy->type == VM_MAP_COPY_OBJECT) {
                   2490:                vm_object_t object = copy->cpy_object;
                   2491:                vm_size_t offset = copy->offset;
                   2492:                vm_size_t tmp_size = copy->size;
                   2493:                kern_return_t kr;
                   2494: 
                   2495:                *dst_addr = 0;
                   2496:                kr = vm_map_enter(dst_map, dst_addr, tmp_size,
                   2497:                                  (vm_offset_t) 0, TRUE,
                   2498:                                  object, offset, FALSE,
                   2499:                                  VM_PROT_DEFAULT, VM_PROT_ALL,
                   2500:                                  VM_INHERIT_DEFAULT);
                   2501:                if (kr != KERN_SUCCESS)
                   2502:                        return(kr);
                   2503:                zfree(vm_map_copy_zone, (vm_offset_t) copy);
                   2504:                return(KERN_SUCCESS);
                   2505:        }
                   2506: 
                   2507:        if (copy->type == VM_MAP_COPY_PAGE_LIST)
                   2508:                return(vm_map_copyout_page_list(dst_map, dst_addr, copy));
                   2509: 
                   2510:        /*
                   2511:         *      Find space for the data
                   2512:         */
                   2513: 
                   2514:        vm_copy_start = trunc_page(copy->offset);
                   2515:        size =  round_page(copy->offset + copy->size) - vm_copy_start;
                   2516: 
                   2517:  StartAgain: ;
                   2518: 
                   2519:        vm_map_lock(dst_map);
                   2520:        start = ((last = dst_map->first_free) == vm_map_to_entry(dst_map)) ?
                   2521:                vm_map_min(dst_map) : last->vme_end;
                   2522: 
                   2523:        while (TRUE) {
                   2524:                vm_map_entry_t  next = last->vme_next;
                   2525:                vm_offset_t     end = start + size;
                   2526: 
                   2527:                if ((end > dst_map->max_offset) || (end < start)) {
                   2528:                        if (dst_map->wait_for_space) {
                   2529:                                if (size <= (dst_map->max_offset - dst_map->min_offset)) {
                   2530:                                        assert_wait((event_t) dst_map, TRUE);
                   2531:                                        vm_map_unlock(dst_map);
                   2532:                                        thread_block((void (*)()) 0);
                   2533:                                        goto StartAgain;
                   2534:                                }
                   2535:                        }
                   2536:                        vm_map_unlock(dst_map);
                   2537:                        return(KERN_NO_SPACE);
                   2538:                }
                   2539: 
                   2540:                if ((next == vm_map_to_entry(dst_map)) ||
                   2541:                    (next->vme_start >= end))
                   2542:                        break;
                   2543: 
                   2544:                last = next;
                   2545:                start = last->vme_end;
                   2546:        }
                   2547: 
                   2548:        /*
                   2549:         *      Since we're going to just drop the map
                   2550:         *      entries from the copy into the destination
                   2551:         *      map, they must come from the same pool.
                   2552:         */
                   2553: 
                   2554:        if (copy->cpy_hdr.entries_pageable != dst_map->hdr.entries_pageable) {
                   2555:            /*
                   2556:             * Mismatches occur when dealing with the default
                   2557:             * pager.
                   2558:             */
                   2559:            zone_t              old_zone;
                   2560:            vm_map_entry_t      next, new;
                   2561: 
                   2562:            /*
                   2563:             * Find the zone that the copies were allocated from
                   2564:             */
                   2565:            old_zone = (copy->cpy_hdr.entries_pageable)
                   2566:                        ? vm_map_entry_zone
                   2567:                        : vm_map_kentry_zone;
                   2568:            entry = vm_map_copy_first_entry(copy);
                   2569: 
                   2570:            /*
                   2571:             * Reinitialize the copy so that vm_map_copy_entry_link
                   2572:             * will work.
                   2573:             */
                   2574:            copy->cpy_hdr.nentries = 0;
                   2575:            copy->cpy_hdr.entries_pageable = dst_map->hdr.entries_pageable;
                   2576:            vm_map_copy_first_entry(copy) =
                   2577:             vm_map_copy_last_entry(copy) =
                   2578:                vm_map_copy_to_entry(copy);
                   2579: 
                   2580:            /*
                   2581:             * Copy each entry.
                   2582:             */
                   2583:            while (entry != vm_map_copy_to_entry(copy)) {
                   2584:                new = vm_map_copy_entry_create(copy);
                   2585:                vm_map_entry_copy_full(new, entry);
                   2586:                vm_map_copy_entry_link(copy,
                   2587:                                vm_map_copy_last_entry(copy),
                   2588:                                new);
                   2589:                next = entry->vme_next;
                   2590:                zfree(old_zone, (vm_offset_t) entry);
                   2591:                entry = next;
                   2592:            }
                   2593:        }
                   2594: 
                   2595:        /*
                   2596:         *      Adjust the addresses in the copy chain, and
                   2597:         *      reset the region attributes.
                   2598:         */
                   2599: 
                   2600:        adjustment = start - vm_copy_start;
                   2601:        for (entry = vm_map_copy_first_entry(copy);
                   2602:             entry != vm_map_copy_to_entry(copy);
                   2603:             entry = entry->vme_next) {
                   2604:                entry->vme_start += adjustment;
                   2605:                entry->vme_end += adjustment;
                   2606: 
                   2607:                entry->inheritance = VM_INHERIT_DEFAULT;
                   2608:                entry->protection = VM_PROT_DEFAULT;
                   2609:                entry->max_protection = VM_PROT_ALL;
                   2610:                entry->projected_on = 0;
                   2611: 
                   2612:                /*
                   2613:                 * If the entry is now wired,
                   2614:                 * map the pages into the destination map.
                   2615:                 */
                   2616:                if (entry->wired_count != 0) {
                   2617:                    register vm_offset_t va;
                   2618:                    vm_offset_t          offset;
                   2619:                    register vm_object_t object;
                   2620: 
                   2621:                    object = entry->object.vm_object;
                   2622:                    offset = entry->offset;
                   2623:                    va = entry->vme_start;
                   2624: 
                   2625:                    pmap_pageable(dst_map->pmap,
                   2626:                                  entry->vme_start,
                   2627:                                  entry->vme_end,
                   2628:                                  TRUE);
                   2629: 
                   2630:                    while (va < entry->vme_end) {
                   2631:                        register vm_page_t      m;
                   2632: 
                   2633:                        /*
                   2634:                         * Look up the page in the object.
                   2635:                         * Assert that the page will be found in the
                   2636:                         * top object:
                   2637:                         * either
                   2638:                         *      the object was newly created by
                   2639:                         *      vm_object_copy_slowly, and has
                   2640:                         *      copies of all of the pages from
                   2641:                         *      the source object
                   2642:                         * or
                   2643:                         *      the object was moved from the old
                   2644:                         *      map entry; because the old map
                   2645:                         *      entry was wired, all of the pages
                   2646:                         *      were in the top-level object.
                   2647:                         *      (XXX not true if we wire pages for
                   2648:                         *       reading)
                   2649:                         */
                   2650:                        vm_object_lock(object);
                   2651:                        vm_object_paging_begin(object);
                   2652: 
                   2653:                        m = vm_page_lookup(object, offset);
                   2654:                        if (m == VM_PAGE_NULL || m->wire_count == 0 ||
                   2655:                            m->absent)
                   2656:                            panic("vm_map_copyout: wiring 0x%x", m);
                   2657: 
                   2658:                        m->busy = TRUE;
                   2659:                        vm_object_unlock(object);
                   2660: 
                   2661:                        PMAP_ENTER(dst_map->pmap, va, m,
                   2662:                                   entry->protection, TRUE);
                   2663: 
                   2664:                        vm_object_lock(object);
                   2665:                        PAGE_WAKEUP_DONE(m);
                   2666:                        /* the page is wired, so we don't have to activate */
                   2667:                        vm_object_paging_end(object);
                   2668:                        vm_object_unlock(object);
                   2669: 
                   2670:                        offset += PAGE_SIZE;
                   2671:                        va += PAGE_SIZE;
                   2672:                    }
                   2673:                }
                   2674: 
                   2675: 
                   2676:        }
                   2677: 
                   2678:        /*
                   2679:         *      Correct the page alignment for the result
                   2680:         */
                   2681: 
                   2682:        *dst_addr = start + (copy->offset - vm_copy_start);
                   2683: 
                   2684:        /*
                   2685:         *      Update the hints and the map size
                   2686:         */
                   2687: 
                   2688:        if (dst_map->first_free == last)
                   2689:                dst_map->first_free = vm_map_copy_last_entry(copy);
                   2690:        SAVE_HINT(dst_map, vm_map_copy_last_entry(copy));
                   2691: 
                   2692:        dst_map->size += size;
                   2693: 
                   2694:        /*
                   2695:         *      Link in the copy
                   2696:         */
                   2697: 
                   2698:        vm_map_copy_insert(dst_map, last, copy);
                   2699: 
                   2700:        vm_map_unlock(dst_map);
                   2701: 
                   2702:        /*
                   2703:         * XXX  If wiring_required, call vm_map_pageable
                   2704:         */
                   2705: 
                   2706:        return(KERN_SUCCESS);
                   2707: }
                   2708: 
                   2709: /*
                   2710:  *
                   2711:  *     vm_map_copyout_page_list:
                   2712:  *
                   2713:  *     Version of vm_map_copyout() for page list vm map copies.
                   2714:  *
                   2715:  */
                   2716: kern_return_t vm_map_copyout_page_list(dst_map, dst_addr, copy)
                   2717:        register
                   2718:        vm_map_t        dst_map;
                   2719:        vm_offset_t     *dst_addr;      /* OUT */
                   2720:        register
                   2721:        vm_map_copy_t   copy;
                   2722: {
                   2723:        vm_size_t       size;
                   2724:        vm_offset_t     start;
                   2725:        vm_offset_t     end;
                   2726:        vm_offset_t     offset;
                   2727:        vm_map_entry_t  last;
                   2728:        register
                   2729:        vm_object_t     object;
                   2730:        vm_page_t       *page_list, m;
                   2731:        vm_map_entry_t  entry;
                   2732:        vm_offset_t     old_last_offset;
                   2733:        boolean_t       cont_invoked, needs_wakeup = FALSE;
                   2734:        kern_return_t   result = KERN_SUCCESS;
                   2735:        vm_map_copy_t   orig_copy;
                   2736:        vm_offset_t     dst_offset;
                   2737:        boolean_t       must_wire;
                   2738: 
                   2739:        /*
                   2740:         *      Make sure the pages are stolen, because we are
                   2741:         *      going to put them in a new object.  Assume that
                   2742:         *      all pages are identical to first in this regard.
                   2743:         */
                   2744: 
                   2745:        page_list = &copy->cpy_page_list[0];
                   2746:        if ((*page_list)->tabled)
                   2747:                vm_map_copy_steal_pages(copy);
                   2748: 
                   2749:        /*
                   2750:         *      Find space for the data
                   2751:         */
                   2752: 
                   2753:        size =  round_page(copy->offset + copy->size) -
                   2754:                trunc_page(copy->offset);
                   2755: StartAgain:
                   2756:        vm_map_lock(dst_map);
                   2757:        must_wire = dst_map->wiring_required;
                   2758: 
                   2759:        last = dst_map->first_free;
                   2760:        if (last == vm_map_to_entry(dst_map)) {
                   2761:                start = vm_map_min(dst_map);
                   2762:        } else {
                   2763:                start = last->vme_end;
                   2764:        }
                   2765: 
                   2766:        while (TRUE) {
                   2767:                vm_map_entry_t next = last->vme_next;
                   2768:                end = start + size;
                   2769: 
                   2770:                if ((end > dst_map->max_offset) || (end < start)) {
                   2771:                        if (dst_map->wait_for_space) {
                   2772:                                if (size <= (dst_map->max_offset -
                   2773:                                             dst_map->min_offset)) {
                   2774:                                        assert_wait((event_t) dst_map, TRUE);
                   2775:                                        vm_map_unlock(dst_map);
                   2776:                                        thread_block((void (*)()) 0);
                   2777:                                        goto StartAgain;
                   2778:                                }
                   2779:                        }
                   2780:                        vm_map_unlock(dst_map);
                   2781:                        return(KERN_NO_SPACE);
                   2782:                }
                   2783: 
                   2784:                if ((next == vm_map_to_entry(dst_map)) ||
                   2785:                    (next->vme_start >= end)) {
                   2786:                        break;
                   2787:                }
                   2788: 
                   2789:                last = next;
                   2790:                start = last->vme_end;
                   2791:        }
                   2792: 
                   2793:        /*
                   2794:         *      See whether we can avoid creating a new entry (and object) by
                   2795:         *      extending one of our neighbors.  [So far, we only attempt to
                   2796:         *      extend from below.]
                   2797:         *
                   2798:         *      The code path below here is a bit twisted.  If any of the
                   2799:         *      extension checks fails, we branch to create_object.  If
                   2800:         *      it all works, we fall out the bottom and goto insert_pages.
                   2801:         */
                   2802:        if (last == vm_map_to_entry(dst_map) ||
                   2803:            last->vme_end != start ||
                   2804:            last->is_shared != FALSE ||
                   2805:            last->is_sub_map != FALSE ||
                   2806:            last->inheritance != VM_INHERIT_DEFAULT ||
                   2807:            last->protection != VM_PROT_DEFAULT ||
                   2808:            last->max_protection != VM_PROT_ALL ||
                   2809:            (must_wire ? (last->wired_count != 1 ||
                   2810:                    last->user_wired_count != 1) :
                   2811:                (last->wired_count != 0))) {
                   2812:                    goto create_object;
                   2813:        }
                   2814: 
                   2815:        /*
                   2816:         * If this entry needs an object, make one.
                   2817:         */
                   2818:        if (last->object.vm_object == VM_OBJECT_NULL) {
                   2819:                object = vm_object_allocate(
                   2820:                        (vm_size_t)(last->vme_end - last->vme_start + size));
                   2821:                last->object.vm_object = object;
                   2822:                last->offset = 0;
                   2823:                vm_object_lock(object);
                   2824:        }
                   2825:        else {
                   2826:            vm_offset_t prev_offset = last->offset;
                   2827:            vm_size_t   prev_size = start - last->vme_start;
                   2828:            vm_size_t   new_size;
                   2829: 
                   2830:            /*
                   2831:             *  This is basically vm_object_coalesce.
                   2832:             */
                   2833: 
                   2834:            object = last->object.vm_object;
                   2835:            vm_object_lock(object);
                   2836: 
                   2837:            /*
                   2838:             *  Try to collapse the object first
                   2839:             */
                   2840:            vm_object_collapse(object);
                   2841: 
                   2842:            /*
                   2843:             *  Can't coalesce if pages not mapped to
                   2844:             *  last may be in use anyway:
                   2845:             *  . more than one reference
                   2846:             *  . paged out
                   2847:             *  . shadows another object
                   2848:             *  . has a copy elsewhere
                   2849:             *  . paging references (pages might be in page-list)
                   2850:             */
                   2851: 
                   2852:            if ((object->ref_count > 1) ||
                   2853:                object->pager_created ||
                   2854:                (object->shadow != VM_OBJECT_NULL) ||
                   2855:                (object->copy != VM_OBJECT_NULL) ||
                   2856:                (object->paging_in_progress != 0)) {
                   2857:                    vm_object_unlock(object);
                   2858:                    goto create_object;
                   2859:            }
                   2860: 
                   2861:            /*
                   2862:             *  Extend the object if necessary.  Don't have to call
                   2863:             *  vm_object_page_remove because the pages aren't mapped,
                   2864:             *  and vm_page_replace will free up any old ones it encounters.
                   2865:             */
                   2866:            new_size = prev_offset + prev_size + size;
                   2867:            if (new_size > object->size)
                   2868:                object->size = new_size;
                   2869:         }
                   2870: 
                   2871:        /*
                   2872:         *      Coalesced the two objects - can extend
                   2873:         *      the previous map entry to include the
                   2874:         *      new range.
                   2875:         */
                   2876:        dst_map->size += size;
                   2877:        last->vme_end = end;
                   2878: 
                   2879:        SAVE_HINT(dst_map, last);
                   2880: 
                   2881:        goto insert_pages;
                   2882: 
                   2883: create_object:
                   2884: 
                   2885:        /*
                   2886:         *      Create object
                   2887:         */
                   2888:        object = vm_object_allocate(size);
                   2889: 
                   2890:        /*
                   2891:         *      Create entry
                   2892:         */
                   2893: 
                   2894:        entry = vm_map_entry_create(dst_map);
                   2895: 
                   2896:        entry->object.vm_object = object;
                   2897:        entry->offset = 0;
                   2898: 
                   2899:        entry->is_shared = FALSE;
                   2900:        entry->is_sub_map = FALSE;
                   2901:        entry->needs_copy = FALSE;
                   2902: 
                   2903:        if (must_wire) {
                   2904:                entry->wired_count = 1;
                   2905:                entry->user_wired_count = 1;
                   2906:        } else {
                   2907:                entry->wired_count = 0;
                   2908:                entry->user_wired_count = 0;
                   2909:        }
                   2910: 
                   2911:        entry->in_transition = TRUE;
                   2912:        entry->needs_wakeup = FALSE;
                   2913: 
                   2914:        entry->vme_start = start;
                   2915:        entry->vme_end = start + size;
                   2916: 
                   2917:        entry->inheritance = VM_INHERIT_DEFAULT;
                   2918:        entry->protection = VM_PROT_DEFAULT;
                   2919:        entry->max_protection = VM_PROT_ALL;
                   2920:        entry->projected_on = 0;
                   2921: 
                   2922:        vm_object_lock(object);
                   2923: 
                   2924:        /*
                   2925:         *      Update the hints and the map size
                   2926:         */
                   2927:        if (dst_map->first_free == last) {
                   2928:                dst_map->first_free = entry;
                   2929:        }
                   2930:        SAVE_HINT(dst_map, entry);
                   2931:        dst_map->size += size;
                   2932: 
                   2933:        /*
                   2934:         *      Link in the entry
                   2935:         */
                   2936:        vm_map_entry_link(dst_map, last, entry);
                   2937:        last = entry;
                   2938: 
                   2939:        /*
                   2940:         *      Transfer pages into new object.
                   2941:         *      Scan page list in vm_map_copy.
                   2942:         */
                   2943: insert_pages:
                   2944:        dst_offset = copy->offset & PAGE_MASK;
                   2945:        cont_invoked = FALSE;
                   2946:        orig_copy = copy;
                   2947:        last->in_transition = TRUE;
                   2948:        old_last_offset = last->offset
                   2949:            + (start - last->vme_start);
                   2950: 
                   2951:        vm_page_lock_queues();
                   2952: 
                   2953:        for (offset = 0; offset < size; offset += PAGE_SIZE) {
                   2954:                m = *page_list;
                   2955:                assert(m && !m->tabled);
                   2956: 
                   2957:                /*
                   2958:                 *      Must clear busy bit in page before inserting it.
                   2959:                 *      Ok to skip wakeup logic because nobody else
                   2960:                 *      can possibly know about this page.
                   2961:                 *      The page is dirty in its new object.
                   2962:                 */
                   2963: 
                   2964:                assert(!m->wanted);
                   2965: 
                   2966:                m->busy = FALSE;
                   2967:                m->dirty = TRUE;
                   2968:                vm_page_replace(m, object, old_last_offset + offset);
                   2969:                if (must_wire) {
                   2970:                        vm_page_wire(m);
                   2971:                        PMAP_ENTER(dst_map->pmap,
                   2972:                                   last->vme_start + m->offset - last->offset,
                   2973:                                   m, last->protection, TRUE);
                   2974:                } else {
                   2975:                        vm_page_activate(m);
                   2976:                }
                   2977: 
                   2978:                *page_list++ = VM_PAGE_NULL;
                   2979:                if (--(copy->cpy_npages) == 0 &&
                   2980:                    vm_map_copy_has_cont(copy)) {
                   2981:                        vm_map_copy_t   new_copy;
                   2982: 
                   2983:                        /*
                   2984:                         *      Ok to unlock map because entry is
                   2985:                         *      marked in_transition.
                   2986:                         */
                   2987:                        cont_invoked = TRUE;
                   2988:                        vm_page_unlock_queues();
                   2989:                        vm_object_unlock(object);
                   2990:                        vm_map_unlock(dst_map);
                   2991:                        vm_map_copy_invoke_cont(copy, &new_copy, &result);
                   2992: 
                   2993:                        if (result == KERN_SUCCESS) {
                   2994: 
                   2995:                                /*
                   2996:                                 *      If we got back a copy with real pages,
                   2997:                                 *      steal them now.  Either all of the
                   2998:                                 *      pages in the list are tabled or none
                   2999:                                 *      of them are; mixtures are not possible.
                   3000:                                 *
                   3001:                                 *      Save original copy for consume on
                   3002:                                 *      success logic at end of routine.
                   3003:                                 */
                   3004:                                if (copy != orig_copy)
                   3005:                                        vm_map_copy_discard(copy);
                   3006: 
                   3007:                                if ((copy = new_copy) != VM_MAP_COPY_NULL) {
                   3008:                                        page_list = &copy->cpy_page_list[0];
                   3009:                                        if ((*page_list)->tabled)
                   3010:                                                vm_map_copy_steal_pages(copy);
                   3011:                                }
                   3012:                        }
                   3013:                        else {
                   3014:                                /*
                   3015:                                 *      Continuation failed.
                   3016:                                 */
                   3017:                                vm_map_lock(dst_map);
                   3018:                                goto error;
                   3019:                        }
                   3020: 
                   3021:                        vm_map_lock(dst_map);
                   3022:                        vm_object_lock(object);
                   3023:                        vm_page_lock_queues();
                   3024:                }
                   3025:        }
                   3026: 
                   3027:        vm_page_unlock_queues();
                   3028:        vm_object_unlock(object);
                   3029: 
                   3030:        *dst_addr = start + dst_offset;
                   3031: 
                   3032:        /*
                   3033:         *      Clear the in transition bits.  This is easy if we
                   3034:         *      didn't have a continuation.
                   3035:         */
                   3036: error:
                   3037:        if (!cont_invoked) {
                   3038:                /*
                   3039:                 *      We didn't unlock the map, so nobody could
                   3040:                 *      be waiting.
                   3041:                 */
                   3042:                last->in_transition = FALSE;
                   3043:                assert(!last->needs_wakeup);
                   3044:                needs_wakeup = FALSE;
                   3045:        }
                   3046:        else {
                   3047:                if (!vm_map_lookup_entry(dst_map, start, &entry))
                   3048:                        panic("vm_map_copyout_page_list: missing entry");
                   3049: 
                   3050:                 /*
                   3051:                  * Clear transition bit for all constituent entries that
                   3052:                  * were in the original entry.  Also check for waiters.
                   3053:                  */
                   3054:                 while((entry != vm_map_to_entry(dst_map)) &&
                   3055:                       (entry->vme_start < end)) {
                   3056:                         assert(entry->in_transition);
                   3057:                         entry->in_transition = FALSE;
                   3058:                         if(entry->needs_wakeup) {
                   3059:                                 entry->needs_wakeup = FALSE;
                   3060:                                 needs_wakeup = TRUE;
                   3061:                         }
                   3062:                         entry = entry->vme_next;
                   3063:                 }
                   3064:        }
                   3065: 
                   3066:        if (result != KERN_SUCCESS)
                   3067:                vm_map_delete(dst_map, start, end);
                   3068: 
                   3069:        vm_map_unlock(dst_map);
                   3070: 
                   3071:        if (needs_wakeup)
                   3072:                vm_map_entry_wakeup(dst_map);
                   3073: 
                   3074:        /*
                   3075:         *      Consume on success logic.
                   3076:         */
                   3077:        if (copy != orig_copy) {
                   3078:                zfree(vm_map_copy_zone, (vm_offset_t) copy);
                   3079:        }
                   3080:        if (result == KERN_SUCCESS) {
                   3081:                zfree(vm_map_copy_zone, (vm_offset_t) orig_copy);
                   3082:        }
                   3083: 
                   3084:        return(result);
                   3085: }
                   3086: 
                   3087: /*
                   3088:  *     Routine:        vm_map_copyin
                   3089:  *
                   3090:  *     Description:
                   3091:  *             Copy the specified region (src_addr, len) from the
                   3092:  *             source address space (src_map), possibly removing
                   3093:  *             the region from the source address space (src_destroy).
                   3094:  *
                   3095:  *     Returns:
                   3096:  *             A vm_map_copy_t object (copy_result), suitable for
                   3097:  *             insertion into another address space (using vm_map_copyout),
                   3098:  *             copying over another address space region (using
                   3099:  *             vm_map_copy_overwrite).  If the copy is unused, it
                   3100:  *             should be destroyed (using vm_map_copy_discard).
                   3101:  *
                   3102:  *     In/out conditions:
                   3103:  *             The source map should not be locked on entry.
                   3104:  */
                   3105: kern_return_t vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result)
                   3106:        vm_map_t        src_map;
                   3107:        vm_offset_t     src_addr;
                   3108:        vm_size_t       len;
                   3109:        boolean_t       src_destroy;
                   3110:        vm_map_copy_t   *copy_result;   /* OUT */
                   3111: {
                   3112:        vm_map_entry_t  tmp_entry;      /* Result of last map lookup --
                   3113:                                         * in multi-level lookup, this
                   3114:                                         * entry contains the actual
                   3115:                                         * vm_object/offset.
                   3116:                                         */
                   3117: 
                   3118:        vm_offset_t     src_start;      /* Start of current entry --
                   3119:                                         * where copy is taking place now
                   3120:                                         */
                   3121:        vm_offset_t     src_end;        /* End of entire region to be
                   3122:                                         * copied */
                   3123: 
                   3124:        register
                   3125:        vm_map_copy_t   copy;           /* Resulting copy */
                   3126: 
                   3127:        /*
                   3128:         *      Check for copies of zero bytes.
                   3129:         */
                   3130: 
                   3131:        if (len == 0) {
                   3132:                *copy_result = VM_MAP_COPY_NULL;
                   3133:                return(KERN_SUCCESS);
                   3134:        }
                   3135: 
                   3136:        /*
                   3137:         *      Compute start and end of region
                   3138:         */
                   3139: 
                   3140:        src_start = trunc_page(src_addr);
                   3141:        src_end = round_page(src_addr + len);
                   3142: 
                   3143:        /*
                   3144:         *      Check that the end address doesn't overflow
                   3145:         */
                   3146: 
                   3147:        if (src_end <= src_start)
                   3148:                if ((src_end < src_start) || (src_start != 0))
                   3149:                        return(KERN_INVALID_ADDRESS);
                   3150: 
                   3151:        /*
                   3152:         *      Allocate a header element for the list.
                   3153:         *
                   3154:         *      Use the start and end in the header to
                   3155:         *      remember the endpoints prior to rounding.
                   3156:         */
                   3157: 
                   3158:        copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   3159:        vm_map_copy_first_entry(copy) =
                   3160:         vm_map_copy_last_entry(copy) = vm_map_copy_to_entry(copy);
                   3161:        copy->type = VM_MAP_COPY_ENTRY_LIST;
                   3162:        copy->cpy_hdr.nentries = 0;
                   3163:        copy->cpy_hdr.entries_pageable = TRUE;
                   3164: 
                   3165:        copy->offset = src_addr;
                   3166:        copy->size = len;
                   3167: 
                   3168: #define        RETURN(x)                                               \
                   3169:        MACRO_BEGIN                                             \
                   3170:        vm_map_unlock(src_map);                                 \
                   3171:        vm_map_copy_discard(copy);                              \
                   3172:        MACRO_RETURN(x);                                        \
                   3173:        MACRO_END
                   3174: 
                   3175:        /*
                   3176:         *      Find the beginning of the region.
                   3177:         */
                   3178: 
                   3179:        vm_map_lock(src_map);
                   3180: 
                   3181:        if (!vm_map_lookup_entry(src_map, src_start, &tmp_entry))
                   3182:                RETURN(KERN_INVALID_ADDRESS);
                   3183:        vm_map_clip_start(src_map, tmp_entry, src_start);
                   3184: 
                   3185:        /*
                   3186:         *      Go through entries until we get to the end.
                   3187:         */
                   3188: 
                   3189:        while (TRUE) {
                   3190:                register
                   3191:                vm_map_entry_t  src_entry = tmp_entry;  /* Top-level entry */
                   3192:                vm_size_t       src_size;               /* Size of source
                   3193:                                                         * map entry (in both
                   3194:                                                         * maps)
                   3195:                                                         */
                   3196: 
                   3197:                register
                   3198:                vm_object_t     src_object;             /* Object to copy */
                   3199:                vm_offset_t     src_offset;
                   3200: 
                   3201:                boolean_t       src_needs_copy;         /* Should source map
                   3202:                                                         * be made read-only
                   3203:                                                         * for copy-on-write?
                   3204:                                                         */
                   3205: 
                   3206:                register
                   3207:                vm_map_entry_t  new_entry;              /* Map entry for copy */
                   3208:                boolean_t       new_entry_needs_copy;   /* Will new entry be COW? */
                   3209: 
                   3210:                boolean_t       was_wired;              /* Was source wired? */
                   3211:                vm_map_version_t version;               /* Version before locks
                   3212:                                                         * dropped to make copy
                   3213:                                                         */
                   3214: 
                   3215:                /*
                   3216:                 *      Verify that the region can be read.
                   3217:                 */
                   3218: 
                   3219:                if (! (src_entry->protection & VM_PROT_READ))
                   3220:                        RETURN(KERN_PROTECTION_FAILURE);
                   3221: 
                   3222:                /*
                   3223:                 *      Clip against the endpoints of the entire region.
                   3224:                 */
                   3225: 
                   3226:                vm_map_clip_end(src_map, src_entry, src_end);
                   3227: 
                   3228:                src_size = src_entry->vme_end - src_start;
                   3229:                src_object = src_entry->object.vm_object;
                   3230:                src_offset = src_entry->offset;
                   3231:                was_wired = (src_entry->wired_count != 0);
                   3232: 
                   3233:                /*
                   3234:                 *      Create a new address map entry to
                   3235:                 *      hold the result.  Fill in the fields from
                   3236:                 *      the appropriate source entries.
                   3237:                 */
                   3238: 
                   3239:                new_entry = vm_map_copy_entry_create(copy);
                   3240:                vm_map_entry_copy(new_entry, src_entry);
                   3241: 
                   3242:                /*
                   3243:                 *      Attempt non-blocking copy-on-write optimizations.
                   3244:                 */
                   3245: 
                   3246:                if (src_destroy &&
                   3247:                    (src_object == VM_OBJECT_NULL ||
                   3248:                     (src_object->temporary && !src_object->use_shared_copy)))
                   3249:                {
                   3250:                    /*
                   3251:                     * If we are destroying the source, and the object
                   3252:                     * is temporary, and not shared writable,
                   3253:                     * we can move the object reference
                   3254:                     * from the source to the copy.  The copy is
                   3255:                     * copy-on-write only if the source is.
                   3256:                     * We make another reference to the object, because
                   3257:                     * destroying the source entry will deallocate it.
                   3258:                     */
                   3259:                    vm_object_reference(src_object);
                   3260: 
                   3261:                    /*
                   3262:                     * Copy is always unwired.  vm_map_copy_entry
                   3263:                     * set its wired count to zero.
                   3264:                     */
                   3265: 
                   3266:                    goto CopySuccessful;
                   3267:                }
                   3268: 
                   3269:                if (!was_wired &&
                   3270:                    vm_object_copy_temporary(
                   3271:                                &new_entry->object.vm_object,
                   3272:                                &new_entry->offset,
                   3273:                                &src_needs_copy,
                   3274:                                &new_entry_needs_copy)) {
                   3275: 
                   3276:                        new_entry->needs_copy = new_entry_needs_copy;
                   3277: 
                   3278:                        /*
                   3279:                         *      Handle copy-on-write obligations
                   3280:                         */
                   3281: 
                   3282:                        if (src_needs_copy && !tmp_entry->needs_copy) {
                   3283:                                vm_object_pmap_protect(
                   3284:                                        src_object,
                   3285:                                        src_offset,
                   3286:                                        src_size,
                   3287:                                        (src_entry->is_shared ? PMAP_NULL
                   3288:                                                : src_map->pmap),
                   3289:                                        src_entry->vme_start,
                   3290:                                        src_entry->protection &
                   3291:                                                ~VM_PROT_WRITE);
                   3292: 
                   3293:                                tmp_entry->needs_copy = TRUE;
                   3294:                        }
                   3295: 
                   3296:                        /*
                   3297:                         *      The map has never been unlocked, so it's safe to
                   3298:                         *      move to the next entry rather than doing another
                   3299:                         *      lookup.
                   3300:                         */
                   3301: 
                   3302:                        goto CopySuccessful;
                   3303:                }
                   3304: 
                   3305:                new_entry->needs_copy = FALSE;
                   3306: 
                   3307:                /*
                   3308:                 *      Take an object reference, so that we may
                   3309:                 *      release the map lock(s).
                   3310:                 */
                   3311: 
                   3312:                assert(src_object != VM_OBJECT_NULL);
                   3313:                vm_object_reference(src_object);
                   3314: 
                   3315:                /*
                   3316:                 *      Record the timestamp for later verification.
                   3317:                 *      Unlock the map.
                   3318:                 */
                   3319: 
                   3320:                version.main_timestamp = src_map->timestamp;
                   3321:                vm_map_unlock(src_map);
                   3322: 
                   3323:                /*
                   3324:                 *      Perform the copy
                   3325:                 */
                   3326: 
                   3327:                if (was_wired) {
                   3328:                        vm_object_lock(src_object);
                   3329:                        (void) vm_object_copy_slowly(
                   3330:                                        src_object,
                   3331:                                        src_offset,
                   3332:                                        src_size,
                   3333:                                        FALSE,
                   3334:                                        &new_entry->object.vm_object);
                   3335:                        new_entry->offset = 0;
                   3336:                        new_entry->needs_copy = FALSE;
                   3337:                } else {
                   3338:                        kern_return_t   result;
                   3339: 
                   3340:                        result = vm_object_copy_strategically(src_object,
                   3341:                                src_offset,
                   3342:                                src_size,
                   3343:                                &new_entry->object.vm_object,
                   3344:                                &new_entry->offset,
                   3345:                                &new_entry_needs_copy);
                   3346: 
                   3347:                        new_entry->needs_copy = new_entry_needs_copy;
                   3348: 
                   3349: 
                   3350:                        if (result != KERN_SUCCESS) {
                   3351:                                vm_map_copy_entry_dispose(copy, new_entry);
                   3352: 
                   3353:                                vm_map_lock(src_map);
                   3354:                                RETURN(result);
                   3355:                        }
                   3356: 
                   3357:                }
                   3358: 
                   3359:                /*
                   3360:                 *      Throw away the extra reference
                   3361:                 */
                   3362: 
                   3363:                vm_object_deallocate(src_object);
                   3364: 
                   3365:                /*
                   3366:                 *      Verify that the map has not substantially
                   3367:                 *      changed while the copy was being made.
                   3368:                 */
                   3369: 
                   3370:                vm_map_lock(src_map);   /* Increments timestamp once! */
                   3371: 
                   3372:                if ((version.main_timestamp + 1) == src_map->timestamp)
                   3373:                        goto CopySuccessful;
                   3374: 
                   3375:                /*
                   3376:                 *      Simple version comparison failed.
                   3377:                 *
                   3378:                 *      Retry the lookup and verify that the
                   3379:                 *      same object/offset are still present.
                   3380:                 *
                   3381:                 *      [Note: a memory manager that colludes with
                   3382:                 *      the calling task can detect that we have
                   3383:                 *      cheated.  While the map was unlocked, the
                   3384:                 *      mapping could have been changed and restored.]
                   3385:                 */
                   3386: 
                   3387:                if (!vm_map_lookup_entry(src_map, src_start, &tmp_entry)) {
                   3388:                        vm_map_copy_entry_dispose(copy, new_entry);
                   3389:                        RETURN(KERN_INVALID_ADDRESS);
                   3390:                }
                   3391: 
                   3392:                src_entry = tmp_entry;
                   3393:                vm_map_clip_start(src_map, src_entry, src_start);
                   3394: 
                   3395:                if ((src_entry->protection & VM_PROT_READ) == VM_PROT_NONE)
                   3396:                        goto VerificationFailed;
                   3397: 
                   3398:                if (src_entry->vme_end < new_entry->vme_end)
                   3399:                        src_size = (new_entry->vme_end = src_entry->vme_end) - src_start;
                   3400: 
                   3401:                if ((src_entry->object.vm_object != src_object) ||
                   3402:                    (src_entry->offset != src_offset) ) {
                   3403: 
                   3404:                        /*
                   3405:                         *      Verification failed.
                   3406:                         *
                   3407:                         *      Start over with this top-level entry.
                   3408:                         */
                   3409: 
                   3410:                 VerificationFailed: ;
                   3411: 
                   3412:                        vm_object_deallocate(new_entry->object.vm_object);
                   3413:                        vm_map_copy_entry_dispose(copy, new_entry);
                   3414:                        tmp_entry = src_entry;
                   3415:                        continue;
                   3416:                }
                   3417: 
                   3418:                /*
                   3419:                 *      Verification succeeded.
                   3420:                 */
                   3421: 
                   3422:         CopySuccessful: ;
                   3423: 
                   3424:                /*
                   3425:                 *      Link in the new copy entry.
                   3426:                 */
                   3427: 
                   3428:                vm_map_copy_entry_link(copy, vm_map_copy_last_entry(copy),
                   3429:                                       new_entry);
                   3430: 
                   3431:                /*
                   3432:                 *      Determine whether the entire region
                   3433:                 *      has been copied.
                   3434:                 */
                   3435:                src_start = new_entry->vme_end;
                   3436:                if ((src_start >= src_end) && (src_end != 0))
                   3437:                        break;
                   3438: 
                   3439:                /*
                   3440:                 *      Verify that there are no gaps in the region
                   3441:                 */
                   3442: 
                   3443:                tmp_entry = src_entry->vme_next;
                   3444:                if (tmp_entry->vme_start != src_start)
                   3445:                        RETURN(KERN_INVALID_ADDRESS);
                   3446:        }
                   3447: 
                   3448:        /*
                   3449:         * If the source should be destroyed, do it now, since the
                   3450:         * copy was successful.
                   3451:         */
                   3452:        if (src_destroy)
                   3453:            (void) vm_map_delete(src_map, trunc_page(src_addr), src_end);
                   3454: 
                   3455:        vm_map_unlock(src_map);
                   3456: 
                   3457:        *copy_result = copy;
                   3458:        return(KERN_SUCCESS);
                   3459: 
                   3460: #undef RETURN
                   3461: }
                   3462: 
                   3463: /*
                   3464:  *     vm_map_copyin_object:
                   3465:  *
                   3466:  *     Create a copy object from an object.
                   3467:  *     Our caller donates an object reference.
                   3468:  */
                   3469: 
                   3470: kern_return_t vm_map_copyin_object(object, offset, size, copy_result)
                   3471:        vm_object_t     object;
                   3472:        vm_offset_t     offset;         /* offset of region in object */
                   3473:        vm_size_t       size;           /* size of region in object */
                   3474:        vm_map_copy_t   *copy_result;   /* OUT */
                   3475: {
                   3476:        vm_map_copy_t   copy;           /* Resulting copy */
                   3477: 
                   3478:        /*
                   3479:         *      We drop the object into a special copy object
                   3480:         *      that contains the object directly.  These copy objects
                   3481:         *      are distinguished by entries_pageable == FALSE
                   3482:         *      and null links.
                   3483:         */
                   3484: 
                   3485:        copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   3486:        vm_map_copy_first_entry(copy) =
                   3487:         vm_map_copy_last_entry(copy) = VM_MAP_ENTRY_NULL;
                   3488:        copy->type = VM_MAP_COPY_OBJECT;
                   3489:        copy->cpy_object = object;
                   3490:        copy->offset = offset;
                   3491:        copy->size = size;
                   3492: 
                   3493:        *copy_result = copy;
                   3494:        return(KERN_SUCCESS);
                   3495: }
                   3496: 
                   3497: /*
                   3498:  *     vm_map_copyin_page_list_cont:
                   3499:  *
                   3500:  *     Continuation routine for vm_map_copyin_page_list.
                   3501:  *
                   3502:  *     If vm_map_copyin_page_list can't fit the entire vm range
                   3503:  *     into a single page list object, it creates a continuation.
                   3504:  *     When the target of the operation has used the pages in the
                   3505:  *     initial page list, it invokes the continuation, which calls
                   3506:  *     this routine.  If an error happens, the continuation is aborted
                   3507:  *     (abort arg to this routine is TRUE).  To avoid deadlocks, the
                   3508:  *     pages are discarded from the initial page list before invoking
                   3509:  *     the continuation.
                   3510:  *
                   3511:  *     NOTE: This is not the same sort of continuation used by
                   3512:  *     the scheduler.
                   3513:  */
                   3514: 
                   3515: kern_return_t  vm_map_copyin_page_list_cont(cont_args, copy_result)
                   3516: vm_map_copyin_args_t   cont_args;
                   3517: vm_map_copy_t          *copy_result;   /* OUT */
                   3518: {
                   3519:        kern_return_t   result = 0; /* '=0' to quiet gcc warnings */
                   3520:        register boolean_t      do_abort, src_destroy, src_destroy_only;
                   3521: 
                   3522:        /*
                   3523:         *      Check for cases that only require memory destruction.
                   3524:         */
                   3525:        do_abort = (copy_result == (vm_map_copy_t *) 0);
                   3526:        src_destroy = (cont_args->destroy_len != (vm_size_t) 0);
                   3527:        src_destroy_only = (cont_args->src_len == (vm_size_t) 0);
                   3528: 
                   3529:        if (do_abort || src_destroy_only) {
                   3530:                if (src_destroy)
                   3531:                        result = vm_map_remove(cont_args->map,
                   3532:                            cont_args->destroy_addr,
                   3533:                            cont_args->destroy_addr + cont_args->destroy_len);
                   3534:                if (!do_abort)
                   3535:                        *copy_result = VM_MAP_COPY_NULL;
                   3536:        }
                   3537:        else {
                   3538:                result = vm_map_copyin_page_list(cont_args->map,
                   3539:                        cont_args->src_addr, cont_args->src_len, src_destroy,
                   3540:                        cont_args->steal_pages, copy_result, TRUE);
                   3541: 
                   3542:                if (src_destroy && !cont_args->steal_pages &&
                   3543:                        vm_map_copy_has_cont(*copy_result)) {
                   3544:                            vm_map_copyin_args_t        new_args;
                   3545:                            /*
                   3546:                             *  Transfer old destroy info.
                   3547:                             */
                   3548:                            new_args = (vm_map_copyin_args_t)
                   3549:                                        (*copy_result)->cpy_cont_args;
                   3550:                            new_args->destroy_addr = cont_args->destroy_addr;
                   3551:                            new_args->destroy_len = cont_args->destroy_len;
                   3552:                }
                   3553:        }
                   3554: 
                   3555:        vm_map_deallocate(cont_args->map);
                   3556:        kfree((vm_offset_t)cont_args, sizeof(vm_map_copyin_args_data_t));
                   3557: 
                   3558:        return(result);
                   3559: }
                   3560: 
                   3561: /*
                   3562:  *     vm_map_copyin_page_list:
                   3563:  *
                   3564:  *     This is a variant of vm_map_copyin that copies in a list of pages.
                   3565:  *     If steal_pages is TRUE, the pages are only in the returned list.
                   3566:  *     If steal_pages is FALSE, the pages are busy and still in their
                   3567:  *     objects.  A continuation may be returned if not all the pages fit:
                   3568:  *     the recipient of this copy_result must be prepared to deal with it.
                   3569:  */
                   3570: 
                   3571: kern_return_t vm_map_copyin_page_list(src_map, src_addr, len, src_destroy,
                   3572:                            steal_pages, copy_result, is_cont)
                   3573:        vm_map_t        src_map;
                   3574:        vm_offset_t     src_addr;
                   3575:        vm_size_t       len;
                   3576:        boolean_t       src_destroy;
                   3577:        boolean_t       steal_pages;
                   3578:        vm_map_copy_t   *copy_result;   /* OUT */
                   3579:        boolean_t       is_cont;
                   3580: {
                   3581:        vm_map_entry_t  src_entry;
                   3582:        vm_page_t       m;
                   3583:        vm_offset_t     src_start;
                   3584:        vm_offset_t     src_end;
                   3585:        vm_size_t       src_size;
                   3586:        register
                   3587:        vm_object_t     src_object;
                   3588:        register
                   3589:        vm_offset_t     src_offset;
                   3590:        vm_offset_t     src_last_offset;
                   3591:        register
                   3592:        vm_map_copy_t   copy;           /* Resulting copy */
                   3593:        kern_return_t   result = KERN_SUCCESS;
                   3594:        boolean_t       need_map_lookup;
                   3595:         vm_map_copyin_args_t   cont_args;
                   3596: 
                   3597:        /*
                   3598:         *      If steal_pages is FALSE, this leaves busy pages in
                   3599:         *      the object.  A continuation must be used if src_destroy
                   3600:         *      is true in this case (!steal_pages && src_destroy).
                   3601:         *
                   3602:         * XXX  Still have a more general problem of what happens
                   3603:         * XXX  if the same page occurs twice in a list.  Deadlock
                   3604:         * XXX  can happen if vm_fault_page was called.  A
                   3605:         * XXX  possible solution is to use a continuation if vm_fault_page
                   3606:         * XXX  is called and we cross a map entry boundary.
                   3607:         */
                   3608: 
                   3609:        /*
                   3610:         *      Check for copies of zero bytes.
                   3611:         */
                   3612: 
                   3613:        if (len == 0) {
                   3614:                *copy_result = VM_MAP_COPY_NULL;
                   3615:                return(KERN_SUCCESS);
                   3616:        }
                   3617: 
                   3618:        /*
                   3619:         *      Compute start and end of region
                   3620:         */
                   3621: 
                   3622:        src_start = trunc_page(src_addr);
                   3623:        src_end = round_page(src_addr + len);
                   3624: 
                   3625:        /*
                   3626:         *      Check that the end address doesn't overflow
                   3627:         */
                   3628: 
                   3629:        if (src_end <= src_start && (src_end < src_start || src_start != 0)) {
                   3630:                return KERN_INVALID_ADDRESS;
                   3631:        }
                   3632: 
                   3633:        /*
                   3634:         *      Allocate a header element for the page list.
                   3635:         *
                   3636:         *      Record original offset and size, as caller may not
                   3637:         *      be page-aligned.
                   3638:         */
                   3639: 
                   3640:        copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   3641:        copy->type = VM_MAP_COPY_PAGE_LIST;
                   3642:        copy->cpy_npages = 0;
                   3643:        copy->offset = src_addr;
                   3644:        copy->size = len;
                   3645:        copy->cpy_cont = ((kern_return_t (*)()) 0);
                   3646:        copy->cpy_cont_args = (char *) VM_MAP_COPYIN_ARGS_NULL;
                   3647: 
                   3648:        /*
                   3649:         *      Find the beginning of the region.
                   3650:         */
                   3651: 
                   3652: do_map_lookup:
                   3653: 
                   3654:        vm_map_lock(src_map);
                   3655: 
                   3656:        if (!vm_map_lookup_entry(src_map, src_start, &src_entry)) {
                   3657:                result = KERN_INVALID_ADDRESS;
                   3658:                goto error;
                   3659:        }
                   3660:        need_map_lookup = FALSE;
                   3661: 
                   3662:        /*
                   3663:         *      Go through entries until we get to the end.
                   3664:         */
                   3665: 
                   3666:        while (TRUE) {
                   3667: 
                   3668:                if (! (src_entry->protection & VM_PROT_READ)) {
                   3669:                        result = KERN_PROTECTION_FAILURE;
                   3670:                        goto error;
                   3671:                }
                   3672: 
                   3673:                if (src_end > src_entry->vme_end)
                   3674:                        src_size = src_entry->vme_end - src_start;
                   3675:                else
                   3676:                        src_size = src_end - src_start;
                   3677: 
                   3678:                src_object = src_entry->object.vm_object;
                   3679:                src_offset = src_entry->offset +
                   3680:                                (src_start - src_entry->vme_start);
                   3681: 
                   3682:                /*
                   3683:                 *      If src_object is NULL, allocate it now;
                   3684:                 *      we're going to fault on it shortly.
                   3685:                 */
                   3686:                if (src_object == VM_OBJECT_NULL) {
                   3687:                        src_object = vm_object_allocate((vm_size_t)
                   3688:                                src_entry->vme_end -
                   3689:                                src_entry->vme_start);
                   3690:                        src_entry->object.vm_object = src_object;
                   3691:                }
                   3692: 
                   3693:                /*
                   3694:                 * Iterate over pages.  Fault in ones that aren't present.
                   3695:                 */
                   3696:                src_last_offset = src_offset + src_size;
                   3697:                for (; (src_offset < src_last_offset && !need_map_lookup);
                   3698:                       src_offset += PAGE_SIZE, src_start += PAGE_SIZE) {
                   3699: 
                   3700:                        if (copy->cpy_npages == VM_MAP_COPY_PAGE_LIST_MAX) {
                   3701: make_continuation:
                   3702:                            /*
                   3703:                             *  At this point we have the max number of
                   3704:                             *  pages busy for this thread that we're
                   3705:                             *  willing to allow.  Stop here and record
                   3706:                             *  arguments for the remainder.  Note:
                   3707:                             *  this means that this routine isn't atomic,
                   3708:                             *  but that's the breaks.  Note that only
                   3709:                             *  the first vm_map_copy_t that comes back
                   3710:                             *  from this routine has the right offset
                   3711:                             *  and size; those from continuations are
                   3712:                             *  page rounded, and short by the amount
                   3713:                             *  already done.
                   3714:                             *
                   3715:                             *  Reset src_end so the src_destroy
                   3716:                             *  code at the bottom doesn't do
                   3717:                             *  something stupid.
                   3718:                             */
                   3719: 
                   3720:                            cont_args = (vm_map_copyin_args_t)
                   3721:                                    kalloc(sizeof(vm_map_copyin_args_data_t));
                   3722:                            cont_args->map = src_map;
                   3723:                            vm_map_reference(src_map);
                   3724:                            cont_args->src_addr = src_start;
                   3725:                            cont_args->src_len = len - (src_start - src_addr);
                   3726:                            if (src_destroy) {
                   3727:                                cont_args->destroy_addr = cont_args->src_addr;
                   3728:                                cont_args->destroy_len = cont_args->src_len;
                   3729:                            }
                   3730:                            else {
                   3731:                                cont_args->destroy_addr = (vm_offset_t) 0;
                   3732:                                cont_args->destroy_len = (vm_offset_t) 0;
                   3733:                            }
                   3734:                            cont_args->steal_pages = steal_pages;
                   3735: 
                   3736:                            copy->cpy_cont_args = (char *) cont_args;
                   3737:                            copy->cpy_cont = vm_map_copyin_page_list_cont;
                   3738: 
                   3739:                            src_end = src_start;
                   3740:                            vm_map_clip_end(src_map, src_entry, src_end);
                   3741:                            break;
                   3742:                        }
                   3743: 
                   3744:                        /*
                   3745:                         *      Try to find the page of data.
                   3746:                         */
                   3747:                        vm_object_lock(src_object);
                   3748:                        vm_object_paging_begin(src_object);
                   3749:                        if (((m = vm_page_lookup(src_object, src_offset)) !=
                   3750:                            VM_PAGE_NULL) && !m->busy && !m->fictitious &&
                   3751:                            !m->absent && !m->error) {
                   3752: 
                   3753:                                /*
                   3754:                                 *      This is the page.  Mark it busy
                   3755:                                 *      and keep the paging reference on
                   3756:                                 *      the object whilst we do our thing.
                   3757:                                 */
                   3758:                                m->busy = TRUE;
                   3759: 
                   3760:                                /*
                   3761:                                 *      Also write-protect the page, so
                   3762:                                 *      that the map`s owner cannot change
                   3763:                                 *      the data.  The busy bit will prevent
                   3764:                                 *      faults on the page from succeeding
                   3765:                                 *      until the copy is released; after
                   3766:                                 *      that, the page can be re-entered
                   3767:                                 *      as writable, since we didn`t alter
                   3768:                                 *      the map entry.  This scheme is a
                   3769:                                 *      cheap copy-on-write.
                   3770:                                 *
                   3771:                                 *      Don`t forget the protection and
                   3772:                                 *      the page_lock value!
                   3773:                                 *
                   3774:                                 *      If the source is being destroyed
                   3775:                                 *      AND not shared writable, we don`t
                   3776:                                 *      have to protect the page, since
                   3777:                                 *      we will destroy the (only)
                   3778:                                 *      writable mapping later.
                   3779:                                 */
                   3780:                                if (!src_destroy ||
                   3781:                                    src_object->use_shared_copy)
                   3782:                                {
                   3783:                                    pmap_page_protect(m->phys_addr,
                   3784:                                                  src_entry->protection
                   3785:                                                & ~m->page_lock
                   3786:                                                & ~VM_PROT_WRITE);
                   3787:                                }
                   3788: 
                   3789:                        }
                   3790:                        else {
                   3791:                                vm_prot_t result_prot;
                   3792:                                vm_page_t top_page;
                   3793:                                kern_return_t kr;
                   3794: 
                   3795:                                /*
                   3796:                                 *      Have to fault the page in; must
                   3797:                                 *      unlock the map to do so.  While
                   3798:                                 *      the map is unlocked, anything
                   3799:                                 *      can happen, we must lookup the
                   3800:                                 *      map entry before continuing.
                   3801:                                 */
                   3802:                                vm_map_unlock(src_map);
                   3803:                                need_map_lookup = TRUE;
                   3804: retry:
                   3805:                                result_prot = VM_PROT_READ;
                   3806: 
                   3807:                                kr = vm_fault_page(src_object, src_offset,
                   3808:                                                   VM_PROT_READ, FALSE, FALSE,
                   3809:                                                   &result_prot, &m, &top_page,
                   3810:                                                   FALSE, (void (*)()) 0);
                   3811:                                /*
                   3812:                                 *      Cope with what happened.
                   3813:                                 */
                   3814:                                switch (kr) {
                   3815:                                case VM_FAULT_SUCCESS:
                   3816:                                        break;
                   3817:                                case VM_FAULT_INTERRUPTED: /* ??? */
                   3818:                                case VM_FAULT_RETRY:
                   3819:                                        vm_object_lock(src_object);
                   3820:                                        vm_object_paging_begin(src_object);
                   3821:                                        goto retry;
                   3822:                                case VM_FAULT_MEMORY_SHORTAGE:
                   3823:                                        VM_PAGE_WAIT((void (*)()) 0);
                   3824:                                        vm_object_lock(src_object);
                   3825:                                        vm_object_paging_begin(src_object);
                   3826:                                        goto retry;
                   3827:                                case VM_FAULT_FICTITIOUS_SHORTAGE:
                   3828:                                        vm_page_more_fictitious();
                   3829:                                        vm_object_lock(src_object);
                   3830:                                        vm_object_paging_begin(src_object);
                   3831:                                        goto retry;
                   3832:                                case VM_FAULT_MEMORY_ERROR:
                   3833:                                        /*
                   3834:                                         *      Something broke.  If this
                   3835:                                         *      is a continuation, return
                   3836:                                         *      a partial result if possible,
                   3837:                                         *      else fail the whole thing.
                   3838:                                         *      In the continuation case, the
                   3839:                                         *      next continuation call will
                   3840:                                         *      get this error if it persists.
                   3841:                                         */
                   3842:                                        vm_map_lock(src_map);
                   3843:                                        if (is_cont &&
                   3844:                                            copy->cpy_npages != 0)
                   3845:                                                goto make_continuation;
                   3846: 
                   3847:                                        result = KERN_MEMORY_ERROR;
                   3848:                                        goto error;
                   3849:                                }
                   3850: 
                   3851:                                if (top_page != VM_PAGE_NULL) {
                   3852:                                        vm_object_lock(src_object);
                   3853:                                        VM_PAGE_FREE(top_page);
                   3854:                                        vm_object_paging_end(src_object);
                   3855:                                        vm_object_unlock(src_object);
                   3856:                                 }
                   3857: 
                   3858:                                 /*
                   3859:                                  *     We do not need to write-protect
                   3860:                                  *     the page, since it cannot have
                   3861:                                  *     been in the pmap (and we did not
                   3862:                                  *     enter it above).  The busy bit
                   3863:                                  *     will protect the page from being
                   3864:                                  *     entered as writable until it is
                   3865:                                  *     unlocked.
                   3866:                                  */
                   3867: 
                   3868:                        }
                   3869: 
                   3870:                        /*
                   3871:                         *      The page is busy, its object is locked, and
                   3872:                         *      we have a paging reference on it.  Either
                   3873:                         *      the map is locked, or need_map_lookup is
                   3874:                         *      TRUE.
                   3875:                         *
                   3876:                         *      Put the page in the page list.
                   3877:                         */
                   3878:                        copy->cpy_page_list[copy->cpy_npages++] = m;
                   3879:                        vm_object_unlock(m->object);
                   3880:                }
                   3881: 
                   3882:                /*
                   3883:                 *      DETERMINE whether the entire region
                   3884:                 *      has been copied.
                   3885:                 */
                   3886:                if (src_start >= src_end && src_end != 0) {
                   3887:                        if (need_map_lookup)
                   3888:                                vm_map_lock(src_map);
                   3889:                        break;
                   3890:                }
                   3891: 
                   3892:                /*
                   3893:                 *      If need_map_lookup is TRUE, have to start over with
                   3894:                 *      another map lookup.  Note that we dropped the map
                   3895:                 *      lock (to call vm_fault_page) above only in this case.
                   3896:                 */
                   3897:                if (need_map_lookup)
                   3898:                        goto do_map_lookup;
                   3899: 
                   3900:                /*
                   3901:                 *      Verify that there are no gaps in the region
                   3902:                 */
                   3903: 
                   3904:                src_start = src_entry->vme_end;
                   3905:                src_entry = src_entry->vme_next;
                   3906:                if (src_entry->vme_start != src_start) {
                   3907:                        result = KERN_INVALID_ADDRESS;
                   3908:                        goto error;
                   3909:                }
                   3910:        }
                   3911: 
                   3912:        /*
                   3913:         *      If steal_pages is true, make sure all
                   3914:         *      pages in the copy are not in any object
                   3915:         *      We try to remove them from the original
                   3916:         *      object, but we may have to copy them.
                   3917:         *
                   3918:         *      At this point every page in the list is busy
                   3919:         *      and holds a paging reference to its object.
                   3920:         *      When we're done stealing, every page is busy,
                   3921:         *      and in no object (m->tabled == FALSE).
                   3922:         */
                   3923:        src_start = trunc_page(src_addr);
                   3924:        if (steal_pages) {
                   3925:                register int i;
                   3926:                vm_offset_t     unwire_end;
                   3927: 
                   3928:                unwire_end = src_start;
                   3929:                for (i = 0; i < copy->cpy_npages; i++) {
                   3930: 
                   3931:                        /*
                   3932:                         *      Remove the page from its object if it
                   3933:                         *      can be stolen.  It can be stolen if:
                   3934:                         *
                   3935:                         *      (1) The source is being destroyed,
                   3936:                         *            the object is temporary, and
                   3937:                         *            not shared.
                   3938:                         *      (2) The page is not precious.
                   3939:                         *
                   3940:                         *      The not shared check consists of two
                   3941:                         *      parts:  (a) there are no objects that
                   3942:                         *      shadow this object.  (b) it is not the
                   3943:                         *      object in any shared map entries (i.e.,
                   3944:                         *      use_shared_copy is not set).
                   3945:                         *
                   3946:                         *      The first check (a) means that we can't
                   3947:                         *      steal pages from objects that are not
                   3948:                         *      at the top of their shadow chains.  This
                   3949:                         *      should not be a frequent occurrence.
                   3950:                         *
                   3951:                         *      Stealing wired pages requires telling the
                   3952:                         *      pmap module to let go of them.
                   3953:                         *
                   3954:                         *      NOTE: stealing clean pages from objects
                   3955:                         *      whose mappings survive requires a call to
                   3956:                         *      the pmap module.  Maybe later.
                   3957:                         */
                   3958:                        m = copy->cpy_page_list[i];
                   3959:                        src_object = m->object;
                   3960:                        vm_object_lock(src_object);
                   3961: 
                   3962:                        if (src_destroy &&
                   3963:                            src_object->temporary &&
                   3964:                            (!src_object->shadowed) &&
                   3965:                            (!src_object->use_shared_copy) &&
                   3966:                            !m->precious) {
                   3967:                                vm_offset_t     page_vaddr;
                   3968: 
                   3969:                                page_vaddr = src_start + (i * PAGE_SIZE);
                   3970:                                if (m->wire_count > 0) {
                   3971: 
                   3972:                                    assert(m->wire_count == 1);
                   3973:                                    /*
                   3974:                                     *  In order to steal a wired
                   3975:                                     *  page, we have to unwire it
                   3976:                                     *  first.  We do this inline
                   3977:                                     *  here because we have the page.
                   3978:                                     *
                   3979:                                     *  Step 1: Unwire the map entry.
                   3980:                                     *          Also tell the pmap module
                   3981:                                     *          that this piece of the
                   3982:                                     *          pmap is pageable.
                   3983:                                     */
                   3984:                                    vm_object_unlock(src_object);
                   3985:                                    if (page_vaddr >= unwire_end) {
                   3986:                                        if (!vm_map_lookup_entry(src_map,
                   3987:                                            page_vaddr, &src_entry))
                   3988:                    panic("vm_map_copyin_page_list: missing wired map entry");
                   3989: 
                   3990:                                        vm_map_clip_start(src_map, src_entry,
                   3991:                                                page_vaddr);
                   3992:                                        vm_map_clip_end(src_map, src_entry,
                   3993:                                                src_start + src_size);
                   3994: 
                   3995:                                        assert(src_entry->wired_count > 0);
                   3996:                                        src_entry->wired_count = 0;
                   3997:                                        src_entry->user_wired_count = 0;
                   3998:                                        unwire_end = src_entry->vme_end;
                   3999:                                        pmap_pageable(vm_map_pmap(src_map),
                   4000:                                            page_vaddr, unwire_end, TRUE);
                   4001:                                    }
                   4002: 
                   4003:                                    /*
                   4004:                                     *  Step 2: Unwire the page.
                   4005:                                     *  pmap_remove handles this for us.
                   4006:                                     */
                   4007:                                    vm_object_lock(src_object);
                   4008:                                }
                   4009: 
                   4010:                                /*
                   4011:                                 *      Don't need to remove the mapping;
                   4012:                                 *      vm_map_delete will handle it.
                   4013:                                 *
                   4014:                                 *      Steal the page.  Setting the wire count
                   4015:                                 *      to zero is vm_page_unwire without
                   4016:                                 *      activating the page.
                   4017:                                 */
                   4018:                                vm_page_lock_queues();
                   4019:                                vm_page_remove(m);
                   4020:                                if (m->wire_count > 0) {
                   4021:                                    m->wire_count = 0;
                   4022:                                    vm_page_wire_count--;
                   4023:                                } else {
                   4024:                                    VM_PAGE_QUEUES_REMOVE(m);
                   4025:                                }
                   4026:                                vm_page_unlock_queues();
                   4027:                        }
                   4028:                        else {
                   4029:                                /*
                   4030:                                 *      Have to copy this page.  Have to
                   4031:                                 *      unlock the map while copying,
                   4032:                                 *      hence no further page stealing.
                   4033:                                 *      Hence just copy all the pages.
                   4034:                                 *      Unlock the map while copying;
                   4035:                                 *      This means no further page stealing.
                   4036:                                 */
                   4037:                                vm_object_unlock(src_object);
                   4038:                                vm_map_unlock(src_map);
                   4039: 
                   4040:                                vm_map_copy_steal_pages(copy);
                   4041: 
                   4042:                                vm_map_lock(src_map);
                   4043:                                break;
                   4044:                        }
                   4045: 
                   4046:                        vm_object_paging_end(src_object);
                   4047:                        vm_object_unlock(src_object);
                   4048:                }
                   4049: 
                   4050:                /*
                   4051:                 * If the source should be destroyed, do it now, since the
                   4052:                 * copy was successful.
                   4053:                 */
                   4054: 
                   4055:                if (src_destroy) {
                   4056:                    (void) vm_map_delete(src_map, src_start, src_end);
                   4057:                }
                   4058:        }
                   4059:        else {
                   4060:                /*
                   4061:                 *      !steal_pages leaves busy pages in the map.
                   4062:                 *      This will cause src_destroy to hang.  Use
                   4063:                 *      a continuation to prevent this.
                   4064:                 */
                   4065:                if (src_destroy && !vm_map_copy_has_cont(copy)) {
                   4066:                        cont_args = (vm_map_copyin_args_t)
                   4067:                                kalloc(sizeof(vm_map_copyin_args_data_t));
                   4068:                        vm_map_reference(src_map);
                   4069:                        cont_args->map = src_map;
                   4070:                        cont_args->src_addr = (vm_offset_t) 0;
                   4071:                        cont_args->src_len = (vm_size_t) 0;
                   4072:                        cont_args->destroy_addr = src_start;
                   4073:                        cont_args->destroy_len = src_end - src_start;
                   4074:                        cont_args->steal_pages = FALSE;
                   4075: 
                   4076:                        copy->cpy_cont_args = (char *) cont_args;
                   4077:                        copy->cpy_cont = vm_map_copyin_page_list_cont;
                   4078:                }
                   4079: 
                   4080:        }
                   4081: 
                   4082:        vm_map_unlock(src_map);
                   4083: 
                   4084:        *copy_result = copy;
                   4085:        return(result);
                   4086: 
                   4087: error:
                   4088:        vm_map_unlock(src_map);
                   4089:        vm_map_copy_discard(copy);
                   4090:        return(result);
                   4091: }
                   4092: 
                   4093: /*
                   4094:  *     vm_map_fork:
                   4095:  *
                   4096:  *     Create and return a new map based on the old
                   4097:  *     map, according to the inheritance values on the
                   4098:  *     regions in that map.
                   4099:  *
                   4100:  *     The source map must not be locked.
                   4101:  */
                   4102: vm_map_t vm_map_fork(old_map)
                   4103:        vm_map_t        old_map;
                   4104: {
                   4105:        vm_map_t        new_map;
                   4106:        register
                   4107:        vm_map_entry_t  old_entry;
                   4108:        register
                   4109:        vm_map_entry_t  new_entry;
                   4110:        pmap_t          new_pmap = pmap_create((vm_size_t) 0);
                   4111:        vm_size_t       new_size = 0;
                   4112:        vm_size_t       entry_size;
                   4113:        register
                   4114:        vm_object_t     object;
                   4115: 
                   4116:        vm_map_lock(old_map);
                   4117: 
                   4118:        new_map = vm_map_create(new_pmap,
                   4119:                        old_map->min_offset,
                   4120:                        old_map->max_offset,
                   4121:                        old_map->hdr.entries_pageable);
                   4122: 
                   4123:        for (
                   4124:            old_entry = vm_map_first_entry(old_map);
                   4125:            old_entry != vm_map_to_entry(old_map);
                   4126:            ) {
                   4127:                if (old_entry->is_sub_map)
                   4128:                        panic("vm_map_fork: encountered a submap");
                   4129: 
                   4130:                entry_size = (old_entry->vme_end - old_entry->vme_start);
                   4131: 
                   4132:                switch (old_entry->inheritance) {
                   4133:                case VM_INHERIT_NONE:
                   4134:                        break;
                   4135: 
                   4136:                case VM_INHERIT_SHARE:
                   4137:                        /*
                   4138:                         *      New sharing code.  New map entry
                   4139:                         *      references original object.  Temporary
                   4140:                         *      objects use asynchronous copy algorithm for
                   4141:                         *      future copies.  First make sure we have
                   4142:                         *      the right object.  If we need a shadow,
                   4143:                         *      or someone else already has one, then
                   4144:                         *      make a new shadow and share it.
                   4145:                         */
                   4146: 
                   4147:                        object = old_entry->object.vm_object;
                   4148:                        if (object == VM_OBJECT_NULL) {
                   4149:                                object = vm_object_allocate(
                   4150:                                            (vm_size_t)(old_entry->vme_end -
                   4151:                                                        old_entry->vme_start));
                   4152:                                old_entry->offset = 0;
                   4153:                                old_entry->object.vm_object = object;
                   4154:                                assert(!old_entry->needs_copy);
                   4155:                        }
                   4156:                        else if (old_entry->needs_copy || object->shadowed ||
                   4157:                            (object->temporary && !old_entry->is_shared &&
                   4158:                             object->size > (vm_size_t)(old_entry->vme_end -
                   4159:                                                old_entry->vme_start))) {
                   4160: 
                   4161:                            assert(object->temporary);
                   4162:                            assert(!(object->shadowed && old_entry->is_shared));
                   4163:                            vm_object_shadow(
                   4164:                                &old_entry->object.vm_object,
                   4165:                                &old_entry->offset,
                   4166:                                (vm_size_t) (old_entry->vme_end -
                   4167:                                             old_entry->vme_start));
                   4168: 
                   4169:                            /*
                   4170:                             *  If we're making a shadow for other than
                   4171:                             *  copy on write reasons, then we have
                   4172:                             *  to remove write permission.
                   4173:                             */
                   4174: 
                   4175:                            if (!old_entry->needs_copy &&
                   4176:                                (old_entry->protection & VM_PROT_WRITE)) {
                   4177:                                pmap_protect(vm_map_pmap(old_map),
                   4178:                                             old_entry->vme_start,
                   4179:                                             old_entry->vme_end,
                   4180:                                             old_entry->protection &
                   4181:                                                ~VM_PROT_WRITE);
                   4182:                            }
                   4183:                            old_entry->needs_copy = FALSE;
                   4184:                            object = old_entry->object.vm_object;
                   4185:                        }
                   4186: 
                   4187:                        /*
                   4188:                         *      Set use_shared_copy to indicate that
                   4189:                         *      object must use shared (delayed) copy-on
                   4190:                         *      write.  This is ignored for permanent objects.
                   4191:                         *      Bump the reference count for the new entry
                   4192:                         */
                   4193: 
                   4194:                        vm_object_lock(object);
                   4195:                        object->use_shared_copy = TRUE;
                   4196:                        object->ref_count++;
                   4197:                        vm_object_unlock(object);
                   4198: 
                   4199:                        if (old_entry->projected_on != 0) {
                   4200:                          /*
                   4201:                           *   If entry is projected buffer, clone the
                   4202:                            *   entry exactly.
                   4203:                            */
                   4204: 
                   4205:                          vm_map_entry_copy_full(new_entry, old_entry);
                   4206: 
                   4207:                        } else {
                   4208:                          /*
                   4209:                           *    Clone the entry, using object ref from above.
                   4210:                           *    Mark both entries as shared.
                   4211:                           */
                   4212: 
                   4213:                          new_entry = vm_map_entry_create(new_map);
                   4214:                          vm_map_entry_copy(new_entry, old_entry);
                   4215:                          old_entry->is_shared = TRUE;
                   4216:                          new_entry->is_shared = TRUE;
                   4217:                        }
                   4218: 
                   4219:                        /*
                   4220:                         *      Insert the entry into the new map -- we
                   4221:                         *      know we're inserting at the end of the new
                   4222:                         *      map.
                   4223:                         */
                   4224: 
                   4225:                        vm_map_entry_link(
                   4226:                                new_map,
                   4227:                                vm_map_last_entry(new_map),
                   4228:                                new_entry);
                   4229: 
                   4230:                        /*
                   4231:                         *      Update the physical map
                   4232:                         */
                   4233: 
                   4234:                        pmap_copy(new_map->pmap, old_map->pmap,
                   4235:                                new_entry->vme_start,
                   4236:                                entry_size,
                   4237:                                old_entry->vme_start);
                   4238: 
                   4239:                        new_size += entry_size;
                   4240:                        break;
                   4241: 
                   4242:                case VM_INHERIT_COPY:
                   4243:                        if (old_entry->wired_count == 0) {
                   4244:                                boolean_t       src_needs_copy;
                   4245:                                boolean_t       new_entry_needs_copy;
                   4246: 
                   4247:                                new_entry = vm_map_entry_create(new_map);
                   4248:                                vm_map_entry_copy(new_entry, old_entry);
                   4249: 
                   4250:                                if (vm_object_copy_temporary(
                   4251:                                        &new_entry->object.vm_object,
                   4252:                                        &new_entry->offset,
                   4253:                                        &src_needs_copy,
                   4254:                                        &new_entry_needs_copy)) {
                   4255: 
                   4256:                                        /*
                   4257:                                         *      Handle copy-on-write obligations
                   4258:                                         */
                   4259: 
                   4260:                                        if (src_needs_copy && !old_entry->needs_copy) {
                   4261:                                                vm_object_pmap_protect(
                   4262:                                                        old_entry->object.vm_object,
                   4263:                                                        old_entry->offset,
                   4264:                                                        entry_size,
                   4265:                                                        (old_entry->is_shared ?
                   4266:                                                                PMAP_NULL :
                   4267:                                                                old_map->pmap),
                   4268:                                                        old_entry->vme_start,
                   4269:                                                        old_entry->protection &
                   4270:                                                            ~VM_PROT_WRITE);
                   4271: 
                   4272:                                                old_entry->needs_copy = TRUE;
                   4273:                                        }
                   4274: 
                   4275:                                        new_entry->needs_copy = new_entry_needs_copy;
                   4276: 
                   4277:                                        /*
                   4278:                                         *      Insert the entry at the end
                   4279:                                         *      of the map.
                   4280:                                         */
                   4281: 
                   4282:                                        vm_map_entry_link(new_map,
                   4283:                                                vm_map_last_entry(new_map),
                   4284:                                                new_entry);
                   4285: 
                   4286: 
                   4287:                                        new_size += entry_size;
                   4288:                                        break;
                   4289:                                }
                   4290: 
                   4291:                                vm_map_entry_dispose(new_map, new_entry);
                   4292:                        }
                   4293: 
                   4294:                        /* INNER BLOCK (copy cannot be optimized) */ {
                   4295: 
                   4296:                        vm_offset_t     start = old_entry->vme_start;
                   4297:                        vm_map_copy_t   copy;
                   4298:                        vm_map_entry_t  last = vm_map_last_entry(new_map);
                   4299: 
                   4300:                        vm_map_unlock(old_map);
                   4301:                        if (vm_map_copyin(old_map,
                   4302:                                        start,
                   4303:                                        entry_size,
                   4304:                                        FALSE,
                   4305:                                        &copy)
                   4306:                            != KERN_SUCCESS) {
                   4307:                                vm_map_lock(old_map);
                   4308:                                if (!vm_map_lookup_entry(old_map, start, &last))
                   4309:                                        last = last->vme_next;
                   4310:                                old_entry = last;
                   4311:                                /*
                   4312:                                 *      For some error returns, want to
                   4313:                                 *      skip to the next element.
                   4314:                                 */
                   4315: 
                   4316:                                continue;
                   4317:                        }
                   4318: 
                   4319:                        /*
                   4320:                         *      Insert the copy into the new map
                   4321:                         */
                   4322: 
                   4323:                        vm_map_copy_insert(new_map, last, copy);
                   4324:                        new_size += entry_size;
                   4325: 
                   4326:                        /*
                   4327:                         *      Pick up the traversal at the end of
                   4328:                         *      the copied region.
                   4329:                         */
                   4330: 
                   4331:                        vm_map_lock(old_map);
                   4332:                        start += entry_size;
                   4333:                        if (!vm_map_lookup_entry(old_map, start, &last))
                   4334:                                last = last->vme_next;
                   4335:                         else
                   4336:                                vm_map_clip_start(old_map, last, start);
                   4337:                        old_entry = last;
                   4338: 
                   4339:                        continue;
                   4340:                        /* INNER BLOCK (copy cannot be optimized) */ }
                   4341:                }
                   4342:                old_entry = old_entry->vme_next;
                   4343:        }
                   4344: 
                   4345:        new_map->size = new_size;
                   4346:        vm_map_unlock(old_map);
                   4347: 
                   4348:        return(new_map);
                   4349: }
                   4350: 
                   4351: /*
                   4352:  *     vm_map_lookup:
                   4353:  *
                   4354:  *     Finds the VM object, offset, and
                   4355:  *     protection for a given virtual address in the
                   4356:  *     specified map, assuming a page fault of the
                   4357:  *     type specified.
                   4358:  *
                   4359:  *     Returns the (object, offset, protection) for
                   4360:  *     this address, whether it is wired down, and whether
                   4361:  *     this map has the only reference to the data in question.
                   4362:  *     In order to later verify this lookup, a "version"
                   4363:  *     is returned.
                   4364:  *
                   4365:  *     The map should not be locked; it will not be
                   4366:  *     locked on exit.  In order to guarantee the
                   4367:  *     existence of the returned object, it is returned
                   4368:  *     locked.
                   4369:  *
                   4370:  *     If a lookup is requested with "write protection"
                   4371:  *     specified, the map may be changed to perform virtual
                   4372:  *     copying operations, although the data referenced will
                   4373:  *     remain the same.
                   4374:  */
                   4375: kern_return_t vm_map_lookup(var_map, vaddr, fault_type, out_version,
                   4376:                                object, offset, out_prot, wired)
                   4377:        vm_map_t                *var_map;       /* IN/OUT */
                   4378:        register vm_offset_t    vaddr;
                   4379:        register vm_prot_t      fault_type;
                   4380: 
                   4381:        vm_map_version_t        *out_version;   /* OUT */
                   4382:        vm_object_t             *object;        /* OUT */
                   4383:        vm_offset_t             *offset;        /* OUT */
                   4384:        vm_prot_t               *out_prot;      /* OUT */
                   4385:        boolean_t               *wired;         /* OUT */
                   4386: {
                   4387:        register vm_map_entry_t         entry;
                   4388:        register vm_map_t               map = *var_map;
                   4389:        register vm_prot_t              prot;
                   4390: 
                   4391:        RetryLookup: ;
                   4392: 
                   4393:        /*
                   4394:         *      Lookup the faulting address.
                   4395:         */
                   4396: 
                   4397:        vm_map_lock_read(map);
                   4398: 
                   4399: #define        RETURN(why) \
                   4400:                { \
                   4401:                vm_map_unlock_read(map); \
                   4402:                return(why); \
                   4403:                }
                   4404: 
                   4405:        /*
                   4406:         *      If the map has an interesting hint, try it before calling
                   4407:         *      full blown lookup routine.
                   4408:         */
                   4409: 
                   4410:        simple_lock(&map->hint_lock);
                   4411:        entry = map->hint;
                   4412:        simple_unlock(&map->hint_lock);
                   4413: 
                   4414:        if ((entry == vm_map_to_entry(map)) ||
                   4415:            (vaddr < entry->vme_start) || (vaddr >= entry->vme_end)) {
                   4416:                vm_map_entry_t  tmp_entry;
                   4417: 
                   4418:                /*
                   4419:                 *      Entry was either not a valid hint, or the vaddr
                   4420:                 *      was not contained in the entry, so do a full lookup.
                   4421:                 */
                   4422:                if (!vm_map_lookup_entry(map, vaddr, &tmp_entry))
                   4423:                        RETURN(KERN_INVALID_ADDRESS);
                   4424: 
                   4425:                entry = tmp_entry;
                   4426:        }
                   4427: 
                   4428:        /*
                   4429:         *      Handle submaps.
                   4430:         */
                   4431: 
                   4432:        if (entry->is_sub_map) {
                   4433:                vm_map_t        old_map = map;
                   4434: 
                   4435:                *var_map = map = entry->object.sub_map;
                   4436:                vm_map_unlock_read(old_map);
                   4437:                goto RetryLookup;
                   4438:        }
                   4439: 
                   4440:        /*
                   4441:         *      Check whether this task is allowed to have
                   4442:         *      this page.
                   4443:         */
                   4444: 
                   4445:        prot = entry->protection;
                   4446: 
                   4447:        if ((fault_type & (prot)) != fault_type)
                   4448:                if ((prot & VM_PROT_NOTIFY) && (fault_type & VM_PROT_WRITE)) {
                   4449:                        RETURN(KERN_WRITE_PROTECTION_FAILURE);
                   4450:                } else {
                   4451:                        RETURN(KERN_PROTECTION_FAILURE);
                   4452:                }
                   4453: 
                   4454:        /*
                   4455:         *      If this page is not pageable, we have to get
                   4456:         *      it for all possible accesses.
                   4457:         */
                   4458: 
                   4459:        if (*wired = (entry->wired_count != 0))
                   4460:                prot = fault_type = entry->protection;
                   4461: 
                   4462:        /*
                   4463:         *      If the entry was copy-on-write, we either ...
                   4464:         */
                   4465: 
                   4466:        if (entry->needs_copy) {
                   4467:                /*
                   4468:                 *      If we want to write the page, we may as well
                   4469:                 *      handle that now since we've got the map locked.
                   4470:                 *
                   4471:                 *      If we don't need to write the page, we just
                   4472:                 *      demote the permissions allowed.
                   4473:                 */
                   4474: 
                   4475:                if (fault_type & VM_PROT_WRITE) {
                   4476:                        /*
                   4477:                         *      Make a new object, and place it in the
                   4478:                         *      object chain.  Note that no new references
                   4479:                         *      have appeared -- one just moved from the
                   4480:                         *      map to the new object.
                   4481:                         */
                   4482: 
                   4483:                        if (vm_map_lock_read_to_write(map)) {
                   4484:                                goto RetryLookup;
                   4485:                        }
                   4486:                        map->timestamp++;
                   4487: 
                   4488:                        vm_object_shadow(
                   4489:                            &entry->object.vm_object,
                   4490:                            &entry->offset,
                   4491:                            (vm_size_t) (entry->vme_end - entry->vme_start));
                   4492: 
                   4493:                        entry->needs_copy = FALSE;
                   4494: 
                   4495:                        vm_map_lock_write_to_read(map);
                   4496:                }
                   4497:                else {
                   4498:                        /*
                   4499:                         *      We're attempting to read a copy-on-write
                   4500:                         *      page -- don't allow writes.
                   4501:                         */
                   4502: 
                   4503:                        prot &= (~VM_PROT_WRITE);
                   4504:                }
                   4505:        }
                   4506: 
                   4507:        /*
                   4508:         *      Create an object if necessary.
                   4509:         */
                   4510:        if (entry->object.vm_object == VM_OBJECT_NULL) {
                   4511: 
                   4512:                if (vm_map_lock_read_to_write(map)) {
                   4513:                        goto RetryLookup;
                   4514:                }
                   4515: 
                   4516:                entry->object.vm_object = vm_object_allocate(
                   4517:                                (vm_size_t)(entry->vme_end - entry->vme_start));
                   4518:                entry->offset = 0;
                   4519:                vm_map_lock_write_to_read(map);
                   4520:        }
                   4521: 
                   4522:        /*
                   4523:         *      Return the object/offset from this entry.  If the entry
                   4524:         *      was copy-on-write or empty, it has been fixed up.  Also
                   4525:         *      return the protection.
                   4526:         */
                   4527: 
                   4528:         *offset = (vaddr - entry->vme_start) + entry->offset;
                   4529:         *object = entry->object.vm_object;
                   4530:        *out_prot = prot;
                   4531: 
                   4532:        /*
                   4533:         *      Lock the object to prevent it from disappearing
                   4534:         */
                   4535: 
                   4536:        vm_object_lock(*object);
                   4537: 
                   4538:        /*
                   4539:         *      Save the version number and unlock the map.
                   4540:         */
                   4541: 
                   4542:        out_version->main_timestamp = map->timestamp;
                   4543: 
                   4544:        RETURN(KERN_SUCCESS);
                   4545: 
                   4546: #undef RETURN
                   4547: }
                   4548: 
                   4549: /*
                   4550:  *     vm_map_verify:
                   4551:  *
                   4552:  *     Verifies that the map in question has not changed
                   4553:  *     since the given version.  If successful, the map
                   4554:  *     will not change until vm_map_verify_done() is called.
                   4555:  */
                   4556: boolean_t      vm_map_verify(map, version)
                   4557:        register
                   4558:        vm_map_t        map;
                   4559:        register
                   4560:        vm_map_version_t *version;      /* REF */
                   4561: {
                   4562:        boolean_t       result;
                   4563: 
                   4564:        vm_map_lock_read(map);
                   4565:        result = (map->timestamp == version->main_timestamp);
                   4566: 
                   4567:        if (!result)
                   4568:                vm_map_unlock_read(map);
                   4569: 
                   4570:        return(result);
                   4571: }
                   4572: 
                   4573: /*
                   4574:  *     vm_map_verify_done:
                   4575:  *
                   4576:  *     Releases locks acquired by a vm_map_verify.
                   4577:  *
                   4578:  *     This is now a macro in vm/vm_map.h.  It does a
                   4579:  *     vm_map_unlock_read on the map.
                   4580:  */
                   4581: 
                   4582: /*
                   4583:  *     vm_region:
                   4584:  *
                   4585:  *     User call to obtain information about a region in
                   4586:  *     a task's address map.
                   4587:  */
                   4588: 
                   4589: kern_return_t  vm_region(map, address, size,
                   4590:                                protection, max_protection,
                   4591:                                inheritance, is_shared,
                   4592:                                object_name, offset_in_object)
                   4593:        vm_map_t        map;
                   4594:        vm_offset_t     *address;               /* IN/OUT */
                   4595:        vm_size_t       *size;                  /* OUT */
                   4596:        vm_prot_t       *protection;            /* OUT */
                   4597:        vm_prot_t       *max_protection;        /* OUT */
                   4598:        vm_inherit_t    *inheritance;           /* OUT */
                   4599:        boolean_t       *is_shared;             /* OUT */
                   4600:        ipc_port_t      *object_name;           /* OUT */
                   4601:        vm_offset_t     *offset_in_object;      /* OUT */
                   4602: {
                   4603:        vm_map_entry_t  tmp_entry;
                   4604:        register
                   4605:        vm_map_entry_t  entry;
                   4606:        register
                   4607:        vm_offset_t     tmp_offset;
                   4608:        vm_offset_t     start;
                   4609: 
                   4610:        if (map == VM_MAP_NULL)
                   4611:                return(KERN_INVALID_ARGUMENT);
                   4612: 
                   4613:        start = *address;
                   4614: 
                   4615:        vm_map_lock_read(map);
                   4616:        if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
                   4617:                if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
                   4618:                        vm_map_unlock_read(map);
                   4619:                        return(KERN_NO_SPACE);
                   4620:                }
                   4621:        } else {
                   4622:                entry = tmp_entry;
                   4623:        }
                   4624: 
                   4625:        start = entry->vme_start;
                   4626:        *protection = entry->protection;
                   4627:        *max_protection = entry->max_protection;
                   4628:        *inheritance = entry->inheritance;
                   4629:        *address = start;
                   4630:        *size = (entry->vme_end - start);
                   4631: 
                   4632:        tmp_offset = entry->offset;
                   4633: 
                   4634: 
                   4635:        if (entry->is_sub_map) {
                   4636:                *is_shared = FALSE;
                   4637:                *object_name = IP_NULL;
                   4638:                *offset_in_object = tmp_offset;
                   4639:        } else {
                   4640:                *is_shared = entry->is_shared;
                   4641:                *object_name = vm_object_name(entry->object.vm_object);
                   4642:                *offset_in_object = tmp_offset;
                   4643:        }
                   4644: 
                   4645:        vm_map_unlock_read(map);
                   4646: 
                   4647:        return(KERN_SUCCESS);
                   4648: }
                   4649: 
                   4650: /*
                   4651:  *     Routine:        vm_map_simplify
                   4652:  *
                   4653:  *     Description:
                   4654:  *             Attempt to simplify the map representation in
                   4655:  *             the vicinity of the given starting address.
                   4656:  *     Note:
                   4657:  *             This routine is intended primarily to keep the
                   4658:  *             kernel maps more compact -- they generally don't
                   4659:  *             benefit from the "expand a map entry" technology
                   4660:  *             at allocation time because the adjacent entry
                   4661:  *             is often wired down.
                   4662:  */
                   4663: void vm_map_simplify(map, start)
                   4664:        vm_map_t        map;
                   4665:        vm_offset_t     start;
                   4666: {
                   4667:        vm_map_entry_t  this_entry;
                   4668:        vm_map_entry_t  prev_entry;
                   4669: 
                   4670:        vm_map_lock(map);
                   4671:        if (
                   4672:                (vm_map_lookup_entry(map, start, &this_entry)) &&
                   4673:                ((prev_entry = this_entry->vme_prev) != vm_map_to_entry(map)) &&
                   4674: 
                   4675:                (prev_entry->vme_end == start) &&
                   4676: 
                   4677:                (prev_entry->is_shared == FALSE) &&
                   4678:                (prev_entry->is_sub_map == FALSE) &&
                   4679: 
                   4680:                (this_entry->is_shared == FALSE) &&
                   4681:                (this_entry->is_sub_map == FALSE) &&
                   4682: 
                   4683:                (prev_entry->inheritance == this_entry->inheritance) &&
                   4684:                (prev_entry->protection == this_entry->protection) &&
                   4685:                (prev_entry->max_protection == this_entry->max_protection) &&
                   4686:                (prev_entry->wired_count == this_entry->wired_count) &&
                   4687:                (prev_entry->user_wired_count == this_entry->user_wired_count) &&
                   4688: 
                   4689:                (prev_entry->needs_copy == this_entry->needs_copy) &&
                   4690: 
                   4691:                (prev_entry->object.vm_object == this_entry->object.vm_object) &&
                   4692:                ((prev_entry->offset + (prev_entry->vme_end - prev_entry->vme_start))
                   4693:                     == this_entry->offset) &&
                   4694:                (prev_entry->projected_on == 0) &&
                   4695:                (this_entry->projected_on == 0)
                   4696:        ) {
                   4697:                if (map->first_free == this_entry)
                   4698:                        map->first_free = prev_entry;
                   4699: 
                   4700:                SAVE_HINT(map, prev_entry);
                   4701:                vm_map_entry_unlink(map, this_entry);
                   4702:                prev_entry->vme_end = this_entry->vme_end;
                   4703:                vm_object_deallocate(this_entry->object.vm_object);
                   4704:                vm_map_entry_dispose(map, this_entry);
                   4705:        }
                   4706:        vm_map_unlock(map);
                   4707: }
                   4708: 
                   4709: 
                   4710: /*
                   4711:  *     Routine:        vm_map_machine_attribute
                   4712:  *     Purpose:
                   4713:  *             Provide machine-specific attributes to mappings,
                   4714:  *             such as cachability etc. for machines that provide
                   4715:  *             them.  NUMA architectures and machines with big/strange
                   4716:  *             caches will use this.
                   4717:  *     Note:
                   4718:  *             Responsibilities for locking and checking are handled here,
                   4719:  *             everything else in the pmap module. If any non-volatile
                   4720:  *             information must be kept, the pmap module should handle
                   4721:  *             it itself. [This assumes that attributes do not
                   4722:  *             need to be inherited, which seems ok to me]
                   4723:  */
                   4724: kern_return_t vm_map_machine_attribute(map, address, size, attribute, value)
                   4725:        vm_map_t        map;
                   4726:        vm_offset_t     address;
                   4727:        vm_size_t       size;
                   4728:        vm_machine_attribute_t  attribute;
                   4729:        vm_machine_attribute_val_t* value;              /* IN/OUT */
                   4730: {
                   4731:        kern_return_t   ret;
                   4732: 
                   4733:        if (address < vm_map_min(map) ||
                   4734:            (address + size) > vm_map_max(map))
                   4735:                return KERN_INVALID_ARGUMENT;
                   4736: 
                   4737:        vm_map_lock(map);
                   4738: 
                   4739:        ret = pmap_attribute(map->pmap, address, size, attribute, value);
                   4740: 
                   4741:        vm_map_unlock(map);
                   4742: 
                   4743:        return ret;
                   4744: }
                   4745: 
                   4746: #include <mach_kdb.h>
                   4747: 
                   4748: 
                   4749: #if    MACH_KDB
                   4750: 
                   4751: #define        printf  kdbprintf
                   4752: 
                   4753: /*
                   4754:  *     vm_map_print:   [ debug ]
                   4755:  */
                   4756: void vm_map_print(map)
                   4757:        register vm_map_t       map;
                   4758: {
                   4759:        register vm_map_entry_t entry;
                   4760:        extern int indent;
                   4761: 
                   4762:        iprintf("Task map 0x%X: pmap=0x%X,",
                   4763:                (vm_offset_t) map, (vm_offset_t) (map->pmap));
                   4764:         printf("ref=%d,nentries=%d,", map->ref_count, map->hdr.nentries);
                   4765:         printf("version=%d\n", map->timestamp);
                   4766:        indent += 2;
                   4767:        for (entry = vm_map_first_entry(map);
                   4768:             entry != vm_map_to_entry(map);
                   4769:             entry = entry->vme_next) {
                   4770:                static char *inheritance_name[3] = { "share", "copy", "none"};
                   4771: 
                   4772:                iprintf("map entry 0x%X: ", (vm_offset_t) entry);
                   4773:                 printf("start=0x%X, end=0x%X, ",
                   4774:                        (vm_offset_t) entry->vme_start, (vm_offset_t) entry->vme_end);
                   4775:                printf("prot=%X/%X/%s, ",
                   4776:                        entry->protection,
                   4777:                        entry->max_protection,
                   4778:                        inheritance_name[entry->inheritance]);
                   4779:                if (entry->wired_count != 0) {
                   4780:                        printf("wired(");
                   4781:                        if (entry->user_wired_count != 0)
                   4782:                                printf("u");
                   4783:                        if (entry->wired_count >
                   4784:                            ((entry->user_wired_count == 0) ? 0 : 1))
                   4785:                                printf("k");
                   4786:                        printf(") ");
                   4787:                }
                   4788:                if (entry->in_transition) {
                   4789:                        printf("in transition");
                   4790:                        if (entry->needs_wakeup)
                   4791:                                printf("(wake request)");
                   4792:                        printf(", ");
                   4793:                }
                   4794:                if (entry->is_sub_map) {
                   4795:                        printf("submap=0x%X, offset=0x%X\n",
                   4796:                                (vm_offset_t) entry->object.sub_map,
                   4797:                                (vm_offset_t) entry->offset);
                   4798:                } else {
                   4799:                        printf("object=0x%X, offset=0x%X",
                   4800:                                (vm_offset_t) entry->object.vm_object,
                   4801:                                (vm_offset_t) entry->offset);
                   4802:                        if (entry->is_shared)
                   4803:                                printf(", shared");
                   4804:                        if (entry->needs_copy)
                   4805:                                printf(", copy needed");
                   4806:                        printf("\n");
                   4807: 
                   4808:                        if ((entry->vme_prev == vm_map_to_entry(map)) ||
                   4809:                            (entry->vme_prev->object.vm_object != entry->object.vm_object)) {
                   4810:                                indent += 2;
                   4811:                                vm_object_print(entry->object.vm_object);
                   4812:                                indent -= 2;
                   4813:                        }
                   4814:                }
                   4815:        }
                   4816:        indent -= 2;
                   4817: }
                   4818: 
                   4819: /*
                   4820:  *     Routine:        vm_map_copy_print
                   4821:  *     Purpose:
                   4822:  *             Pretty-print a copy object for ddb.
                   4823:  */
                   4824: 
                   4825: void vm_map_copy_print(copy)
                   4826:        vm_map_copy_t copy;
                   4827: {
                   4828:        extern int indent;
                   4829:        int i, npages;
                   4830: 
                   4831:        printf("copy object 0x%x\n", copy);
                   4832: 
                   4833:        indent += 2;
                   4834: 
                   4835:        iprintf("type=%d", copy->type);
                   4836:        switch (copy->type) {
                   4837:                case VM_MAP_COPY_ENTRY_LIST:
                   4838:                printf("[entry_list]");
                   4839:                break;
                   4840: 
                   4841:                case VM_MAP_COPY_OBJECT:
                   4842:                printf("[object]");
                   4843:                break;
                   4844: 
                   4845:                case VM_MAP_COPY_PAGE_LIST:
                   4846:                printf("[page_list]");
                   4847:                break;
                   4848: 
                   4849:                default:
                   4850:                printf("[bad type]");
                   4851:                break;
                   4852:        }
                   4853:        printf(", offset=0x%x", copy->offset);
                   4854:        printf(", size=0x%x\n", copy->size);
                   4855: 
                   4856:        switch (copy->type) {
                   4857:                case VM_MAP_COPY_ENTRY_LIST:
                   4858:                /* XXX add stuff here */
                   4859:                break;
                   4860: 
                   4861:                case VM_MAP_COPY_OBJECT:
                   4862:                iprintf("object=0x%x\n", copy->cpy_object);
                   4863:                break;
                   4864: 
                   4865:                case VM_MAP_COPY_PAGE_LIST:
                   4866:                iprintf("npages=%d", copy->cpy_npages);
                   4867:                printf(", cont=%x", copy->cpy_cont);
                   4868:                printf(", cont_args=%x\n", copy->cpy_cont_args);
                   4869:                if (copy->cpy_npages < 0) {
                   4870:                        npages = 0;
                   4871:                } else if (copy->cpy_npages > VM_MAP_COPY_PAGE_LIST_MAX) {
                   4872:                        npages = VM_MAP_COPY_PAGE_LIST_MAX;
                   4873:                } else {
                   4874:                        npages = copy->cpy_npages;
                   4875:                }
                   4876:                iprintf("copy->cpy_page_list[0..%d] = {", npages);
                   4877:                for (i = 0; i < npages - 1; i++) {
                   4878:                        printf("0x%x, ", copy->cpy_page_list[i]);
                   4879:                }
                   4880:                if (npages > 0) {
                   4881:                        printf("0x%x", copy->cpy_page_list[npages - 1]);
                   4882:                }
                   4883:                printf("}\n");
                   4884:                break;
                   4885:        }
                   4886: 
                   4887:        indent -=2;
                   4888: }
                   4889: #endif /* MACH_KDB */
                   4890: 
                   4891: #if    NORMA_IPC
                   4892: /*
                   4893:  * This should one day be eliminated;
                   4894:  * we should always construct the right flavor of copy object
                   4895:  * the first time. Troublesome areas include vm_read, where vm_map_copyin
                   4896:  * is called without knowing whom the copy object is for.
                   4897:  * There are also situations where we do want a lazy data structure
                   4898:  * even if we are sending to a remote port...
                   4899:  */
                   4900: 
                   4901: /*
                   4902:  *     Convert a copy to a page list.  The copy argument is in/out
                   4903:  *     because we probably have to allocate a new vm_map_copy structure.
                   4904:  *     We take responsibility for discarding the old structure and
                   4905:  *     use a continuation to do so.  Postponing this discard ensures
                   4906:  *     that the objects containing the pages we've marked busy will stick
                   4907:  *     around.
                   4908:  */
                   4909: kern_return_t
                   4910: vm_map_convert_to_page_list(caller_copy)
                   4911:        vm_map_copy_t   *caller_copy;
                   4912: {
                   4913:        vm_map_entry_t entry, next_entry;
                   4914:        vm_offset_t va;
                   4915:        vm_offset_t offset;
                   4916:        vm_object_t object;
                   4917:        kern_return_t result;
                   4918:        vm_map_copy_t copy, new_copy;
                   4919:        int i, num_pages = 0;
                   4920: 
                   4921:        zone_t entry_zone;
                   4922: 
                   4923:        copy = *caller_copy;
                   4924: 
                   4925:        /*
                   4926:         * We may not have to do anything,
                   4927:         * or may not be able to do anything.
                   4928:         */
                   4929:        if (copy == VM_MAP_COPY_NULL || copy->type == VM_MAP_COPY_PAGE_LIST) {
                   4930:                return KERN_SUCCESS;
                   4931:        }
                   4932:        if (copy->type == VM_MAP_COPY_OBJECT) {
                   4933:                return vm_map_convert_to_page_list_from_object(caller_copy);
                   4934:        }
                   4935:        if (copy->type != VM_MAP_COPY_ENTRY_LIST) {
                   4936:                panic("vm_map_convert_to_page_list: copy type %d!\n",
                   4937:                      copy->type);
                   4938:        }
                   4939: 
                   4940:        /*
                   4941:         *      Allocate the new copy.  Set its continuation to
                   4942:         *      discard the old one.
                   4943:         */
                   4944:        new_copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   4945:        new_copy->type = VM_MAP_COPY_PAGE_LIST;
                   4946:        new_copy->cpy_npages = 0;
                   4947:        new_copy->offset = copy->offset;
                   4948:        new_copy->size = copy->size;
                   4949:        new_copy->cpy_cont = vm_map_copy_discard_cont;
                   4950:        new_copy->cpy_cont_args = (char *) copy;
                   4951: 
                   4952:        /*
                   4953:         * Iterate over entries.
                   4954:         */
                   4955:        for (entry = vm_map_copy_first_entry(copy);
                   4956:             entry != vm_map_copy_to_entry(copy);
                   4957:             entry = entry->vme_next) {
                   4958: 
                   4959:                object = entry->object.vm_object;
                   4960:                offset = entry->offset;
                   4961:                /*
                   4962:                 * Iterate over pages.
                   4963:                 */
                   4964:                for (va = entry->vme_start;
                   4965:                     va < entry->vme_end;
                   4966:                     va += PAGE_SIZE, offset += PAGE_SIZE) {
                   4967: 
                   4968:                        vm_page_t m;
                   4969: 
                   4970:                        if (new_copy->cpy_npages == VM_MAP_COPY_PAGE_LIST_MAX) {
                   4971:                                /*
                   4972:                                 *      What a mess.  We need a continuation
                   4973:                                 *      to do the page list, but also one
                   4974:                                 *      to discard the old copy.  The right
                   4975:                                 *      thing to do is probably to copy
                   4976:                                 *      out the old copy into the kernel
                   4977:                                 *      map (or some temporary task holding
                   4978:                                 *      map if we're paranoid about large
                   4979:                                 *      copies), and then copyin the page
                   4980:                                 *      list that we really wanted with
                   4981:                                 *      src_destroy.  LATER.
                   4982:                                 */
                   4983:                                panic("vm_map_convert_to_page_list: num\n");
                   4984:                        }
                   4985: 
                   4986:                        /*
                   4987:                         *      Try to find the page of data.
                   4988:                         */
                   4989:                        vm_object_lock(object);
                   4990:                        vm_object_paging_begin(object);
                   4991:                        if (((m = vm_page_lookup(object, offset)) !=
                   4992:                             VM_PAGE_NULL) && !m->busy && !m->fictitious &&
                   4993:                            !m->absent && !m->error) {
                   4994: 
                   4995:                                /*
                   4996:                                 *      This is the page.  Mark it busy
                   4997:                                 *      and keep the paging reference on
                   4998:                                 *      the object whilst we do our thing.
                   4999:                                 */
                   5000:                                m->busy = TRUE;
                   5001: 
                   5002:                                /*
                   5003:                                 *      Also write-protect the page, so
                   5004:                                 *      that the map`s owner cannot change
                   5005:                                 *      the data.  The busy bit will prevent
                   5006:                                 *      faults on the page from succeeding
                   5007:                                 *      until the copy is released; after
                   5008:                                 *      that, the page can be re-entered
                   5009:                                 *      as writable, since we didn`t alter
                   5010:                                 *      the map entry.  This scheme is a
                   5011:                                 *      cheap copy-on-write.
                   5012:                                 *
                   5013:                                 *      Don`t forget the protection and
                   5014:                                 *      the page_lock value!
                   5015:                                 */
                   5016: 
                   5017:                                pmap_page_protect(m->phys_addr,
                   5018:                                                  entry->protection
                   5019:                                                & ~m->page_lock
                   5020:                                                & ~VM_PROT_WRITE);
                   5021: 
                   5022:                        }
                   5023:                        else {
                   5024:                                vm_prot_t result_prot;
                   5025:                                vm_page_t top_page;
                   5026:                                kern_return_t kr;
                   5027: 
                   5028: retry:
                   5029:                                result_prot = VM_PROT_READ;
                   5030: 
                   5031:                                kr = vm_fault_page(object, offset,
                   5032:                                                   VM_PROT_READ, FALSE, FALSE,
                   5033:                                                   &result_prot, &m, &top_page,
                   5034:                                                   FALSE, (void (*)()) 0);
                   5035:                                if (kr == VM_FAULT_MEMORY_SHORTAGE) {
                   5036:                                        VM_PAGE_WAIT((void (*)()) 0);
                   5037:                                        vm_object_lock(object);
                   5038:                                        vm_object_paging_begin(object);
                   5039:                                        goto retry;
                   5040:                                }
                   5041:                                if (kr != VM_FAULT_SUCCESS) {
                   5042:                                        /* XXX what about data_error? */
                   5043:                                        vm_object_lock(object);
                   5044:                                        vm_object_paging_begin(object);
                   5045:                                        goto retry;
                   5046:                                }
                   5047:                                if (top_page != VM_PAGE_NULL) {
                   5048:                                        vm_object_lock(object);
                   5049:                                        VM_PAGE_FREE(top_page);
                   5050:                                        vm_object_paging_end(object);
                   5051:                                        vm_object_unlock(object);
                   5052:                                }
                   5053:                        }
                   5054:                        assert(m);
                   5055:                        m->busy = TRUE;
                   5056:                        new_copy->cpy_page_list[new_copy->cpy_npages++] = m;
                   5057:                        vm_object_unlock(object);
                   5058:                }
                   5059:        }
                   5060: 
                   5061:        *caller_copy = new_copy;
                   5062:        return KERN_SUCCESS;
                   5063: }
                   5064: 
                   5065: kern_return_t
                   5066: vm_map_convert_to_page_list_from_object(caller_copy)
                   5067:        vm_map_copy_t *caller_copy;
                   5068: {
                   5069:        vm_object_t object;
                   5070:        vm_offset_t offset;
                   5071:        vm_map_copy_t   copy, new_copy;
                   5072: 
                   5073:        copy = *caller_copy;
                   5074:        assert(copy->type == VM_MAP_COPY_OBJECT);
                   5075:        object = copy->cpy_object;
                   5076:        assert(object->size == round_page(object->size));
                   5077: 
                   5078:        /*
                   5079:         *      Allocate the new copy.  Set its continuation to
                   5080:         *      discard the old one.
                   5081:         */
                   5082:        new_copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
                   5083:        new_copy->type = VM_MAP_COPY_PAGE_LIST;
                   5084:        new_copy->cpy_npages = 0;
                   5085:        new_copy->offset = copy->offset;
                   5086:        new_copy->size = copy->size;
                   5087:        new_copy->cpy_cont = vm_map_copy_discard_cont;
                   5088:        new_copy->cpy_cont_args = (char *) copy;
                   5089: 
                   5090:        /*
                   5091:         * XXX  memory_object_lock_request can probably bust this
                   5092:         * XXX  See continuation comment in previous routine for solution.
                   5093:         */
                   5094:        assert(object->size <= VM_MAP_COPY_PAGE_LIST_MAX * PAGE_SIZE);
                   5095: 
                   5096:        for (offset = 0; offset < object->size; offset += PAGE_SIZE) {
                   5097:                vm_page_t m;
                   5098: 
                   5099:                /*
                   5100:                 *      Try to find the page of data.
                   5101:                 */
                   5102:                vm_object_lock(object);
                   5103:                vm_object_paging_begin(object);
                   5104:                m = vm_page_lookup(object, offset);
                   5105:                if ((m != VM_PAGE_NULL) && !m->busy && !m->fictitious &&
                   5106:                    !m->absent && !m->error) {
                   5107: 
                   5108:                        /*
                   5109:                         *      This is the page.  Mark it busy
                   5110:                         *      and keep the paging reference on
                   5111:                         *      the object whilst we do our thing.
                   5112:                         */
                   5113:                        m->busy = TRUE;
                   5114:                }
                   5115:                else {
                   5116:                        vm_prot_t result_prot;
                   5117:                        vm_page_t top_page;
                   5118:                        kern_return_t kr;
                   5119: 
                   5120: retry:
                   5121:                        result_prot = VM_PROT_READ;
                   5122: 
                   5123:                        kr = vm_fault_page(object, offset,
                   5124:                                           VM_PROT_READ, FALSE, FALSE,
                   5125:                                           &result_prot, &m, &top_page,
                   5126:                                           FALSE, (void (*)()) 0);
                   5127:                        if (kr == VM_FAULT_MEMORY_SHORTAGE) {
                   5128:                                VM_PAGE_WAIT((void (*)()) 0);
                   5129:                                vm_object_lock(object);
                   5130:                                vm_object_paging_begin(object);
                   5131:                                goto retry;
                   5132:                        }
                   5133:                        if (kr != VM_FAULT_SUCCESS) {
                   5134:                                /* XXX what about data_error? */
                   5135:                                vm_object_lock(object);
                   5136:                                vm_object_paging_begin(object);
                   5137:                                goto retry;
                   5138:                        }
                   5139: 
                   5140:                        if (top_page != VM_PAGE_NULL) {
                   5141:                                vm_object_lock(object);
                   5142:                                VM_PAGE_FREE(top_page);
                   5143:                                vm_object_paging_end(object);
                   5144:                                vm_object_unlock(object);
                   5145:                        }
                   5146:                }
                   5147:                assert(m);
                   5148:                m->busy = TRUE;
                   5149:                new_copy->cpy_page_list[new_copy->cpy_npages++] = m;
                   5150:                vm_object_unlock(object);
                   5151:        }
                   5152: 
                   5153:        *caller_copy = new_copy;
                   5154:        return (KERN_SUCCESS);
                   5155: }
                   5156: 
                   5157: kern_return_t
                   5158: vm_map_convert_from_page_list(copy)
                   5159:        vm_map_copy_t   copy;
                   5160: {
                   5161:        vm_object_t object;
                   5162:        int i;
                   5163:        vm_map_entry_t  new_entry;
                   5164:        vm_page_t       *page_list;
                   5165: 
                   5166:        /*
                   5167:         * Check type of copy object.
                   5168:         */
                   5169:        if (copy->type == VM_MAP_COPY_ENTRY_LIST) {
                   5170:                return KERN_SUCCESS;
                   5171:        }
                   5172:        if (copy->type == VM_MAP_COPY_OBJECT) {
                   5173:                printf("vm_map_convert_from_page_list: COPY_OBJECT?");
                   5174:                return KERN_SUCCESS;
                   5175:        }
                   5176:        if (copy->type != VM_MAP_COPY_PAGE_LIST) {
                   5177:                panic("vm_map_convert_from_page_list 0x%x %d",
                   5178:                      copy,
                   5179:                      copy->type);
                   5180:        }
                   5181: 
                   5182:        /*
                   5183:         *      Make sure the pages are loose.  This may be
                   5184:         *      a "Can't Happen", but just to be safe ...
                   5185:         */
                   5186:        page_list = &copy->cpy_page_list[0];
                   5187:        if ((*page_list)->tabled)
                   5188:                vm_map_copy_steal_pages(copy);
                   5189: 
                   5190:        /*
                   5191:         * Create object, and stuff pages into it.
                   5192:         */
                   5193:        object = vm_object_allocate(copy->cpy_npages);
                   5194:        for (i = 0; i < copy->cpy_npages; i++) {
                   5195:                register vm_page_t m = *page_list++;
                   5196:                vm_page_insert(m, object, i * PAGE_SIZE);
                   5197:                m->busy = FALSE;
                   5198:                m->dirty = TRUE;
                   5199:                vm_page_activate(m);
                   5200:        }
                   5201: 
                   5202:        /*
                   5203:         * XXX  If this page list contained a continuation, then
                   5204:         * XXX  we're screwed.  The right thing to do is probably do
                   5205:         * XXX  the copyout, and then copyin the entry list we really
                   5206:         * XXX  wanted.
                   5207:         */
                   5208:        if (vm_map_copy_has_cont(copy))
                   5209:                panic("convert_from_page_list: continuation");
                   5210: 
                   5211:        /*
                   5212:         * Change type of copy object
                   5213:         */
                   5214:        vm_map_copy_first_entry(copy) =
                   5215:            vm_map_copy_last_entry(copy) = vm_map_copy_to_entry(copy);
                   5216:        copy->type = VM_MAP_COPY_ENTRY_LIST;
                   5217:        copy->cpy_hdr.nentries = 0;
                   5218:        copy->cpy_hdr.entries_pageable = TRUE;
                   5219: 
                   5220:        /*
                   5221:         * Allocate and initialize an entry for object
                   5222:         */
                   5223:        new_entry = vm_map_copy_entry_create(copy);
                   5224:        new_entry->vme_start = trunc_page(copy->offset);
                   5225:        new_entry->vme_end = round_page(copy->offset + copy->size);
                   5226:        new_entry->object.vm_object = object;
                   5227:        new_entry->offset = 0;
                   5228:        new_entry->is_shared = FALSE;
                   5229:        new_entry->is_sub_map = FALSE;
                   5230:        new_entry->needs_copy = FALSE;
                   5231:        new_entry->protection = VM_PROT_DEFAULT;
                   5232:        new_entry->max_protection = VM_PROT_ALL;
                   5233:        new_entry->inheritance = VM_INHERIT_DEFAULT;
                   5234:        new_entry->wired_count = 0;
                   5235:        new_entry->user_wired_count = 0;
                   5236:        new_entry->projected_on = 0;
                   5237: 
                   5238:        /*
                   5239:         * Insert entry into copy object, and return.
                   5240:         */
                   5241:        vm_map_copy_entry_link(copy, vm_map_copy_last_entry(copy), new_entry);
                   5242:        return(KERN_SUCCESS);
                   5243: }
                   5244: #endif /* NORMA_IPC */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.