Annotation of kernel/vm/vm_fault.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1987 Carnegie-Mellon University
                     28:  * All rights reserved.  The CMU software License Agreement specifies
                     29:  * the terms and conditions for use and redistribution.
                     30:  */
                     31: /*
                     32:  *     File:   vm_fault.c
                     33:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     34:  *
                     35:  *     Copyright (C) 1985, Avadis Tevanian, Jr., Michael Wayne Young
                     36:  *
                     37:  *     Page fault handling module.
                     38:  */
                     39: 
                     40: #import <mach_xp.h>
                     41: 
                     42: #define        USE_VERSIONS    MACH_XP
                     43: 
                     44: #import <mach/kern_return.h>
                     45: #import <mach/message.h>       /* for error codes */
                     46: #import <kern/thread.h>
                     47: #import <kern/sched_prim.h>
                     48: #import <vm/vm_map.h>
                     49: #import <vm/vm_object.h>
                     50: #import <vm/vm_page.h>
                     51: #import <vm/pmap.h>
                     52: #import <mach/vm_statistics.h>
                     53: #import <vm/vm_pageout.h>
                     54: #import <mach/vm_param.h>
                     55: 
                     56: 
                     57: /*
                     58:  *     vm_fault:
                     59:  *
                     60:  *     Handle a page fault occuring at the given address,
                     61:  *     requiring the given permissions, in the map specified.
                     62:  *     If successful, the page is inserted into the
                     63:  *     associated physical map.
                     64:  *
                     65:  *     NOTE: the given address should be truncated to the
                     66:  *     proper page address.
                     67:  *
                     68:  *     KERN_SUCCESS is returned if the page fault is handled; otherwise,
                     69:  *     a standard error specifying why the fault is fatal is returned.
                     70:  *
                     71:  *
                     72:  *     The map in question must be referenced, and remains so.
                     73:  *     Caller may hold no locks.
                     74:  */
                     75: #if    NeXT
                     76: kern_return_t vm_fault(map, vaddr, fault_type, change_wiring, error)
                     77:        vm_map_t        map;
                     78:        vm_offset_t     vaddr;
                     79:        vm_prot_t       fault_type;
                     80:        boolean_t       change_wiring;
                     81:        int             *error;
                     82: #else  NeXT
                     83: kern_return_t vm_fault(map, vaddr, fault_type, change_wiring)
                     84:        vm_map_t        map;
                     85:        vm_offset_t     vaddr;
                     86:        vm_prot_t       fault_type;
                     87:        boolean_t       change_wiring;
                     88: #endif NeXT
                     89: {
                     90:        vm_object_t             first_object;
                     91:        vm_offset_t             first_offset;
                     92: #if    USE_VERSIONS
                     93:        vm_map_version_t        version;
                     94: #else  USE_VERSIONS
                     95:        vm_map_entry_t          entry;
                     96: #endif USE_VERSIONS
                     97:        register vm_object_t    object;
                     98:        register vm_offset_t    offset;
                     99:        register vm_page_t      m;
                    100:        vm_page_t               first_m;
                    101:        vm_prot_t               prot;
                    102:        kern_return_t           result;
                    103:        boolean_t               wired;
                    104:        boolean_t               su;
                    105: #if    !USE_VERSIONS
                    106:        boolean_t               lookup_still_valid;
                    107: #endif !USE_VERSIONS
                    108:        boolean_t               page_exists;
                    109:        vm_page_t               old_m;
                    110:        vm_object_t             next_object;
                    111: 
                    112:        vm_stat.faults++;               /* needs lock XXX */
                    113: /*
                    114:  *     Recovery actions
                    115:  */
                    116: #if    MACH_XP
                    117: /* vm_page_free does a PAGE_WAKEUP anyway */
                    118: #define        FREE_PAGE(m) {                                  \
                    119:        vm_page_lock_queues();                          \
                    120:        vm_page_free(m);                                \
                    121:        vm_page_unlock_queues();                        \
                    122: }
                    123: #else  MACH_XP
                    124: #define        FREE_PAGE(m)    {                               \
                    125:        PAGE_WAKEUP(m);                                 \
                    126:        vm_page_lock_queues();                          \
                    127:        vm_page_free(m);                                \
                    128:        vm_page_unlock_queues();                        \
                    129: }
                    130: #endif MACH_XP
                    131: 
                    132: #define        RELEASE_PAGE(m) {                               \
                    133:        PAGE_WAKEUP(m);                                 \
                    134:        vm_page_lock_queues();                          \
                    135:        vm_page_activate(m);                            \
                    136:        vm_page_unlock_queues();                        \
                    137: }
                    138: 
                    139: #if    USE_VERSIONS
                    140: #define        UNLOCK_MAP
                    141: #else  USE_VERSIONS
                    142: #define        UNLOCK_MAP      {                               \
                    143:        if (lookup_still_valid) {                       \
                    144:                vm_map_lookup_done(map, entry);         \
                    145:                lookup_still_valid = FALSE;             \
                    146:        }                                               \
                    147: }
                    148: #endif USE_VERSIONS
                    149: 
                    150: #define        UNLOCK_THINGS   {                               \
                    151:        object->paging_in_progress--;                   \
                    152:        vm_object_unlock(object);                       \
                    153:        if (object != first_object) {                   \
                    154:                vm_object_lock(first_object);           \
                    155:                FREE_PAGE(first_m);                     \
                    156:                first_object->paging_in_progress--;     \
                    157:                vm_object_unlock(first_object);         \
                    158:        }                                               \
                    159:        UNLOCK_MAP;                                     \
                    160: }
                    161: 
                    162: #define        UNLOCK_AND_DEALLOCATE   {                       \
                    163:        UNLOCK_THINGS;                                  \
                    164:        vm_object_deallocate(first_object);             \
                    165: }
                    166: 
                    167:     RetryFault: ;
                    168: 
                    169:        /*
                    170:         *      Find the backing store object and offset into
                    171:         *      it to begin the search.
                    172:         */
                    173: 
                    174: #if    USE_VERSIONS
                    175:        if ((result = vm_map_lookup(&map, vaddr, fault_type, &version,
                    176: #else  USE_VERSIONS
                    177:        if ((result = vm_map_lookup(&map, vaddr, fault_type, &entry,
                    178: #endif USE_VERSIONS
                    179:                        &first_object, &first_offset,
                    180:                        &prot, &wired, &su)) != KERN_SUCCESS) {
                    181:                return(result);
                    182:        }
                    183: #if    !USE_VERSIONS
                    184:        lookup_still_valid = TRUE;
                    185: #endif !USE_VERSIONS
                    186: 
                    187:        if (wired)
                    188:                fault_type = prot;
                    189: 
                    190:        first_m = VM_PAGE_NULL;
                    191: 
                    192:        /*
                    193:         *      Make a reference to this object to
                    194:         *      prevent its disposal while we are messing with
                    195:         *      it.  Once we have the reference, the map is free
                    196:         *      to be diddled.  Since objects reference their
                    197:         *      shadows (and copies), they will stay around as well.
                    198:         */
                    199: 
                    200: #if    !USE_VERSIONS
                    201:        vm_object_lock(first_object);
                    202: #endif !USE_VERSIONS
                    203: 
                    204:        first_object->ref_count++;
                    205:        first_object->paging_in_progress++;
                    206: 
                    207:        /*
                    208:         *      INVARIANTS (through entire routine):
                    209:         *
                    210:         *      1)      At all times, we must either have the object
                    211:         *              lock or a busy page in some object to prevent
                    212:         *              some other thread from trying to bring in
                    213:         *              the same page.
                    214:         *
                    215:         *              Note that we cannot hold any locks during the
                    216:         *              pager access or when waiting for memory, so
                    217:         *              we use a busy page then.
                    218:         *
                    219:         *              Note also that we aren't as concerned about
                    220:         *              more than one thead attempting to pager_data_unlock
                    221:         *              the same page at once, so we don't hold the page
                    222:         *              as busy then, but do record the highest unlock
                    223:         *              value so far.  [Unlock requests may also be delivered
                    224:         *              out of order.]
                    225:         *
                    226:         *      2)      Once we have a busy page, we must remove it from
                    227:         *              the pageout queues, so that the pageout daemon
                    228:         *              will not grab it away.
                    229:         *
                    230:         *      3)      To prevent another thread from racing us down the
                    231:         *              shadow chain and entering a new page in the top
                    232:         *              object before we do, we must keep a busy page in
                    233:         *              the top object while following the shadow chain.
                    234:         *
                    235:         *      4)      We must increment paging_in_progress on any object
                    236:         *              for which we have a busy page, to prevent
                    237:         *              vm_object_collapse from removing the busy page
                    238:         *              without our noticing.
                    239:         */
                    240: 
                    241:        /*
                    242:         *      Search for the page at object/offset.
                    243:         */
                    244: 
                    245:        object = first_object;
                    246:        offset = first_offset;
                    247: 
                    248:        /*
                    249:         *      See whether this page is resident
                    250:         */
                    251: 
                    252:        while (TRUE) {
                    253:                m = vm_page_lookup(object, offset);
                    254:                if (m != VM_PAGE_NULL) {
                    255:                        /*
                    256:                         *      If the page is in error, give up now.
                    257:                         */
                    258: 
                    259:                        if (m->error) {
                    260:                                FREE_PAGE(m);
                    261:                                UNLOCK_AND_DEALLOCATE;
                    262:                                return(KERN_MEMORY_ERROR);
                    263:                        }
                    264: 
                    265:                        /*
                    266:                         *      If the page is being brought in,
                    267:                         *      wait for it and then retry.
                    268:                         */
                    269:                        if (m->busy) {
                    270:                                kern_return_t   wait_result;
                    271: #if SCRUBVM3
                    272:                                /* hint if we miss it its ok */
                    273:                                if (m->dry_vp){
                    274:                                    vm_page_lock_queues();
                    275:                                    (void) vm_page_completeio(m, TRUE);
                    276:                                    vm_page_unlock_queues();
                    277:                                } else {
                    278: #endif
                    279:                                    PAGE_ASSERT_WAIT(m, !change_wiring);
                    280:                                    UNLOCK_MAP;                         
                    281:                                    vm_object_unlock(object);
                    282:                                    thread_block();
                    283:                                    wait_result = current_thread()->wait_result;
                    284:                                    vm_object_lock(object);
                    285:                                    if (wait_result == THREAD_RESTART) {
                    286:                                            UNLOCK_AND_DEALLOCATE;
                    287:                                            goto RetryFault;
                    288:                                    }
                    289:                                    if (wait_result != THREAD_AWAKENED) {
                    290:                                            UNLOCK_AND_DEALLOCATE;
                    291:                                            return(KERN_SUCCESS);
                    292:                                    }
                    293:                                    continue;
                    294: #if SCRUBVM3
                    295:                                }
                    296: #endif
                    297:                        }
                    298: 
                    299:                        /*
                    300:                         *      If the page isn't busy, but is absent,
                    301:                         *      then it was deemed "unavailable".
                    302:                         */
                    303: 
                    304:                        if (m->absent) {
                    305:                                /*
                    306:                                 * Remove the non-existent page (unless it's
                    307:                                 * in the top object) and move on down to the
                    308:                                 * next object (if there is one).
                    309:                                 */
                    310:                                offset += object->shadow_offset;
                    311:                                next_object = object->shadow;
                    312:                                if (next_object == VM_OBJECT_NULL) {
                    313:                                        /*
                    314:                                         * Absent page at bottom of shadow
                    315:                                         * chain; zero fill the page we left
                    316:                                         * busy in the first object, and flush
                    317:                                         * the absent page.
                    318:                                         */
                    319:                                        if (object != first_object) {
                    320:                                                m->busy = m->absent = FALSE;
                    321:                                                FREE_PAGE(m);
                    322:                                                object->paging_in_progress--;
                    323:                                                vm_object_unlock(object);
                    324:                                                object = first_object;
                    325:                                                offset = first_offset;
                    326:                                                m = first_m;
                    327:                                                vm_object_lock(object);
                    328:                                        }
                    329:                                        first_m = VM_PAGE_NULL;
                    330:                                        vm_page_zero_fill(m);
                    331:                                        vm_stat.zero_fill_count++;
                    332:                                        m->absent = FALSE;
                    333:                                } else {
                    334:                                        if (object != first_object) {
                    335:                                                object->paging_in_progress--;
                    336:                                                FREE_PAGE(m);
                    337:                                        } else {
                    338:                                                first_m = m;
                    339:                                                m->absent = FALSE;
                    340:                                        }
                    341:                                        vm_object_lock(next_object);
                    342:                                        vm_object_unlock(object);
                    343:                                        object = next_object;
                    344:                                        object->paging_in_progress++;
                    345:                                        continue;
                    346:                                }
                    347:                        }
                    348: 
                    349:                        /*
                    350:                         *      If the desired access to this page has
                    351:                         *      been locked out, request that it be unlocked.
                    352:                         */
                    353: 
                    354:                        if (fault_type & m->page_lock) {
                    355:                                UNLOCK_AND_DEALLOCATE;
                    356:                                return (KERN_MEMORY_ERROR);
                    357:                        }
                    358: 
                    359:                        /*
                    360:                         *      Remove the page from the pageout daemon's
                    361:                         *      reach while we play with it.
                    362:                         */
                    363: 
                    364:                        vm_page_lock_queues();
                    365:                        if (m->inactive) {
                    366:                                queue_remove(&vm_page_queue_inactive, m,
                    367:                                                vm_page_t, pageq);
                    368:                                m->inactive = FALSE;
                    369:                                vm_page_inactive_count--;
                    370:                                vm_stat.reactivations++;
                    371:                        } 
                    372: 
                    373:                        if (m->active) {
                    374:                                queue_remove(&vm_page_queue_active, m,
                    375:                                                vm_page_t, pageq);
                    376:                                m->active = FALSE;
                    377:                                vm_page_active_count--;
                    378:                        }
                    379: #if    NeXT
                    380:                        if (m->free) {
                    381:                                /*
                    382:                                 * We only get here on reactivation of a free page,
                    383:                                 * vm_page_alloc takes care of this for us in the
                    384:                                 * typical case.
                    385:                                 */
                    386:                                queue_remove(&vm_page_queue_free, m,
                    387:                                                vm_page_t, pageq);
                    388:                                m->free = FALSE;
                    389:                                vm_page_free_count--;
                    390:                                vm_stat.reactivations++;
                    391:                        }
                    392: #endif NeXT
                    393:                        vm_page_unlock_queues();
                    394: 
                    395:                        /*
                    396:                         *      Mark page busy for other threads.
                    397:                         */
                    398:                        m->busy = TRUE;
                    399:                        m->absent = FALSE;
                    400:                        break;
                    401:                }
                    402: 
                    403:                if (((object->pager != vm_pager_null) &&
                    404:                                (!change_wiring || wired))
                    405:                    || (object == first_object)) {
                    406: 
                    407:                        /*
                    408:                         *      Allocate a new page for this object/offset
                    409:                         *      pair.
                    410:                         */
                    411: 
                    412:                        m = vm_page_alloc(object, offset);
                    413: 
                    414:                        if (m == VM_PAGE_NULL) {
                    415:                                UNLOCK_AND_DEALLOCATE;
                    416:                                VM_WAIT;
                    417:                                goto RetryFault;
                    418:                        }
                    419:                }
                    420: 
                    421:                if ((object->pager != vm_pager_null) &&
                    422:                                (!change_wiring || wired)) {
                    423: #if    MACH_XP
                    424:                        kern_return_t   rc;
                    425: #else  MACH_XP
                    426:                        pager_return_t  rc;
                    427: #endif MACH_XP
                    428: 
                    429:                        /*
                    430:                         *      Now that we have a busy page, we can
                    431:                         *      release the object lock.
                    432:                         */
                    433:                        vm_object_unlock(object);
                    434: 
                    435:                        /*
                    436:                         *      Call the pager to retrieve the data, if any,
                    437:                         *      after releasing the lock on the map.
                    438:                         */
                    439:                        UNLOCK_MAP;
                    440: 
                    441: #if    MACH_XP
                    442:                        m->absent = TRUE;
                    443: 
                    444:                        vm_stat.pageins++;
                    445:                        if ((rc = pager_data_request(object->pager, 
                    446:                                object->pager_request,
                    447:                                m->offset + object->paging_offset, 
                    448:                                PAGE_SIZE, fault_type)) != KERN_SUCCESS) {
                    449:                                if (rc != SEND_INTERRUPTED)
                    450:                                        kprintf("%s(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) failed, %d\n",
                    451:                                                "pager_data_request",
                    452:                                                object->pager,
                    453:                                                object->pager_request,
                    454:                                                m->offset + object->paging_offset, 
                    455:                                                PAGE_SIZE, fault_type, rc);
                    456:                                vm_object_lock(object);
                    457:                                FREE_PAGE(m);
                    458:                                UNLOCK_AND_DEALLOCATE;
                    459:                                return((rc == SEND_INTERRUPTED) ?
                    460:                                        KERN_SUCCESS : KERN_MEMORY_ERROR);
                    461:                        }
                    462:                        
                    463:                        /*
                    464:                         * Retry with same object/offset, since new data may
                    465:                         * be in a different page (ie, m is meaningless at
                    466:                         * this point).
                    467:                         */
                    468:                        vm_object_lock(object);
                    469:                        continue;
                    470: #else  MACH_XP
                    471: #if    NeXT
                    472:                        rc = vm_pager_get(object->pager, m, error);
                    473: #else  NeXT
                    474:                        rc = vm_pager_get(object->pager, m);
                    475: #endif NeXT
                    476:                        if (rc == PAGER_SUCCESS) {
                    477: 
                    478:                                /*
                    479:                                 *      Found the page.
                    480:                                 *      Leave it busy while we play with it.
                    481:                                 */
                    482:                                vm_object_lock(object);
                    483: 
                    484:                                /*
                    485:                                 *      Relookup in case pager changed page.
                    486:                                 *      Pager is responsible for disposition
                    487:                                 *      of old page if moved.
                    488:                                 */
                    489:                                m = vm_page_lookup(object, offset);
                    490: 
                    491:                                vm_stat.pageins++;
                    492:                                pmap_clear_modify(VM_PAGE_TO_PHYS(m));
                    493:                                break;
                    494:                        }
                    495:                        if (rc == PAGER_ERROR) {
                    496:                                /*
                    497:                                 *      Pager had the page, but could not
                    498:                                 *      read it.  Return error to stop caller.
                    499:                                 */
                    500:                                vm_object_lock(object);
                    501:                                FREE_PAGE(m);
                    502:                                UNLOCK_AND_DEALLOCATE;
                    503:                                return(KERN_MEMORY_ERROR);
                    504:                        }
                    505: 
                    506:                        /*
                    507:                         *      Remove the bogus page (which does not
                    508:                         *      exist at this object/offset); before
                    509:                         *      doing so, we must get back our object
                    510:                         *      lock to preserve our invariant.
                    511:                         *
                    512:                         *      Also wake up any other thread that may want
                    513:                         *      to bring in this page.
                    514:                         *
                    515:                         *      If this is the top-level object, we must
                    516:                         *      leave the busy page to prevent another
                    517:                         *      thread from rushing past us, and inserting
                    518:                         *      the page in that object at the same time
                    519:                         *      that we are.
                    520:                         */
                    521: 
                    522:                        vm_object_lock(object);
                    523:                        if (object != first_object) {
                    524:                                FREE_PAGE(m);
                    525:                        }
                    526: #endif MACH_XP
                    527:                }
                    528: 
                    529:                /*
                    530:                 * For the XP system, the only case in which we get here is if
                    531:                 * object has no pager (or unwiring).  If the pager doesn't
                    532:                 * have the page this is handled in the m->absent case above
                    533:                 * (and if you change things here you should look above).
                    534:                 */
                    535:                if (object == first_object)
                    536:                        first_m = m;
                    537: 
                    538:                /*
                    539:                 *      Move on to the next object.  Lock the next
                    540:                 *      object before unlocking the current one.
                    541:                 */
                    542: 
                    543:                offset += object->shadow_offset;
                    544:                next_object = object->shadow;
                    545:                if (next_object == VM_OBJECT_NULL) {
                    546:                        /*
                    547:                         *      If there's no object left, fill the page
                    548:                         *      in the top object with zeros.
                    549:                         */
                    550:                        if (object != first_object) {
                    551:                                object->paging_in_progress--;
                    552:                                vm_object_unlock(object);
                    553: 
                    554:                                object = first_object;
                    555:                                offset = first_offset;
                    556:                                m = first_m;
                    557:                                vm_object_lock(object);
                    558:                        }
                    559:                        first_m = VM_PAGE_NULL;
                    560: 
                    561:                        vm_page_zero_fill(m);
                    562:                        vm_stat.zero_fill_count++;
                    563:                        m->absent = FALSE;
                    564:                        break;
                    565:                }
                    566:                else {
                    567:                        vm_object_lock(next_object);
                    568:                        if (object != first_object)
                    569:                                object->paging_in_progress--;
                    570:                        vm_object_unlock(object);
                    571:                        object = next_object;
                    572:                        object->paging_in_progress++;
                    573:                }
                    574:        }
                    575: 
                    576:        if (m->absent || m->active || m->inactive || !m->busy)
                    577:                panic("vm_fault: absent or active or inactive or not busy after main loop");
                    578: 
                    579:        /*
                    580:         *      PAGE HAS BEEN FOUND.
                    581:         *      [Loop invariant still holds -- the object lock
                    582:         *      is held.]
                    583:         */
                    584: 
                    585:        old_m = m;      /* save page that would be copied */
                    586: 
                    587:        /*
                    588:         *      If the page is being written, but isn't
                    589:         *      already owned by the top-level object,
                    590:         *      we have to copy it into a new page owned
                    591:         *      by the top-level object.
                    592:         */
                    593: 
                    594:        if (object != first_object) {
                    595:                /*
                    596:                 *      We only really need to copy if we
                    597:                 *      want to write it.
                    598:                 */
                    599: 
                    600:                if (fault_type & VM_PROT_WRITE) {
                    601: 
                    602:                        /*
                    603:                         *      If we try to collapse first_object at this
                    604:                         *      point, we may deadlock when we try to get
                    605:                         *      the lock on an intermediate object (since we
                    606:                         *      have the bottom object locked).  We can't
                    607:                         *      unlock the bottom object, because the page
                    608:                         *      we found may move (by collapse) if we do.
                    609:                         *
                    610:                         *      Instead, we first copy the page.  Then, when
                    611:                         *      we have no more use for the bottom object,
                    612:                         *      we unlock it and try to collapse.
                    613:                         *
                    614:                         *      Note that we copy the page even if we didn't
                    615:                         *      need to... that's the breaks.
                    616:                         */
                    617: 
                    618:                        /*
                    619:                         *      We already have an empty page in
                    620:                         *      first_object - use it.
                    621:                         */
                    622: 
                    623:                        vm_page_copy(m, first_m);
                    624:                        first_m->absent = FALSE;
                    625: 
                    626:                        /*
                    627:                         *      If another map is truly sharing this
                    628:                         *      page with us, we have to flush all
                    629:                         *      uses of the original page, since we
                    630:                         *      can't distinguish those which want the
                    631:                         *      original from those which need the
                    632:                         *      new copy.
                    633:                         */
                    634: 
                    635:                        vm_page_lock_queues();
                    636:                        /*
                    637:                         *      We first activate the page, then deactivate
                    638:                         *      it since vm_page_deactivate will only
                    639:                         *      deactivate active pages.
                    640:                         */
                    641:                        vm_page_activate(m);
                    642:                        vm_page_deactivate(m);
                    643:                        if (!su)
                    644:                                pmap_remove_all(VM_PAGE_TO_PHYS(m));
                    645:                        vm_page_unlock_queues();
                    646: 
                    647:                        /*
                    648:                         *      We no longer need the old page or object.
                    649:                         */
                    650:                        PAGE_WAKEUP(m);
                    651:                        object->paging_in_progress--;
                    652:                        vm_object_unlock(object);
                    653: 
                    654:                        /*
                    655:                         *      Only use the new page below...
                    656:                         */
                    657: 
                    658:                        vm_stat.cow_faults++;
                    659:                        m = first_m;
                    660:                        object = first_object;
                    661:                        offset = first_offset;
                    662: 
                    663:                        /*
                    664:                         *      Now that we've gotten the copy out of the
                    665:                         *      way, let's try to collapse the top object.
                    666:                         */
                    667:                        vm_object_lock(object);
                    668:                        /*
                    669:                         *      But we have to play ugly games with
                    670:                         *      paging_in_progress to do that...
                    671:                         */
                    672:                        object->paging_in_progress--;
                    673:                        vm_object_collapse(object);
                    674:                        object->paging_in_progress++;
                    675:                }
                    676:                else {
                    677:                        prot &= (~VM_PROT_WRITE);
                    678:                        m->copy_on_write = TRUE;
                    679:                }
                    680:        }
                    681: 
                    682:        if (m->active || m->inactive)
                    683:                panic("vm_fault: active or inactive before copy object handling");
                    684: 
                    685:        /*
                    686:         *      If the page is being written, but hasn't been
                    687:         *      copied to the copy-object, we have to copy it there.
                    688:         */
                    689:     RetryCopy:
                    690:        if (first_object->copy != VM_OBJECT_NULL) {
                    691:                vm_object_t             copy_object = first_object->copy;
                    692:                vm_offset_t             copy_offset;
                    693:                vm_page_t               copy_m;
                    694: 
                    695:                /*
                    696:                 *      We only need to copy if we want to write it.
                    697:                 */
                    698:                if ((fault_type & VM_PROT_WRITE) == 0) {
                    699:                        prot &= ~VM_PROT_WRITE;
                    700:                        m->copy_on_write = TRUE;
                    701:                }
                    702:                else {
                    703:                        /*
                    704:                         *      Try to get the lock on the copy_object.
                    705:                         */
                    706:                        if (!vm_object_lock_try(copy_object)) {
                    707:                                vm_object_unlock(object);
                    708:                                /* should spin a bit here... */
                    709:                                vm_object_lock(object);
                    710:                                goto RetryCopy;
                    711:                        }
                    712: 
                    713:                        /*
                    714:                         *      Make another reference to the copy-object,
                    715:                         *      to keep it from disappearing during the
                    716:                         *      copy.
                    717:                         */
                    718:                        copy_object->ref_count++;
                    719: 
                    720:                        /*
                    721:                         *      Does the page exist in the copy?
                    722:                         */
                    723:                        copy_offset = first_offset
                    724:                                - copy_object->shadow_offset;
                    725:                        copy_m = vm_page_lookup(copy_object, copy_offset);
                    726:                        if (page_exists = (copy_m != VM_PAGE_NULL)) {
                    727:                                if (copy_m->busy) {
                    728:                                        kern_return_t   wait_result;
                    729: #if SCRUBVM3
                    730:                                        /* hint if we miss it its ok */
                    731:                                        if (copy_m->dry_vp){
                    732:                                            vm_page_lock_queues();
                    733:                                            (void) vm_page_completeio(copy_m, TRUE);
                    734:                                            vm_page_unlock_queues();
                    735:                                        } else {
                    736: #endif
                    737: 
                    738:                                            /*
                    739:                                             *  If the page is being brought
                    740:                                             *  in, wait for it and then retry.
                    741:                                             */
                    742:                                            PAGE_ASSERT_WAIT(copy_m, !change_wiring);
                    743:                                            RELEASE_PAGE(m);
                    744:                                            copy_object->ref_count--;
                    745:                                            vm_object_unlock(copy_object);
                    746:                                            UNLOCK_THINGS;
                    747:                                            thread_block();
                    748:                                            wait_result = current_thread()->wait_result;
                    749:                                            vm_object_deallocate(first_object);
                    750:                                                        /* may block */
                    751:                                            if (wait_result != THREAD_AWAKENED)
                    752:                                                    return(KERN_SUCCESS);
                    753:                                            goto RetryFault;
                    754: #if SCRUBVM3
                    755:                                        }
                    756: #endif
                    757:                                }
                    758:                        }
                    759: 
                    760: #if    MACH_XP
                    761:                         else {
                    762:                                /*
                    763:                                 *      Allocate a page for the copy
                    764:                                 */
                    765:                                copy_m = vm_page_alloc(copy_object,
                    766:                                                                copy_offset);
                    767:                                if (copy_m == VM_PAGE_NULL) {
                    768:                                        /*
                    769:                                         *      Wait for a page, then retry.
                    770:                                         */
                    771:                                        RELEASE_PAGE(m);
                    772:                                        copy_object->ref_count--;
                    773:                                        vm_object_unlock(copy_object);
                    774:                                        UNLOCK_AND_DEALLOCATE;
                    775:                                        VM_WAIT;
                    776:                                        goto RetryFault;
                    777:                                }
                    778: 
                    779:                                /*
                    780:                                 *      Must copy page into copy-object.
                    781:                                 */
                    782: 
                    783:                                vm_page_copy(m, copy_m);
                    784:                                m->copy_on_write = FALSE;
                    785:                                copy_m->absent = FALSE;
                    786:                                
                    787:                                /*
                    788:                                 *      If the old page was in use by any users
                    789:                                 *      of the copy-object, it must be removed
                    790:                                 *      from all pmaps.  (We can't know which
                    791:                                 *      pmaps use it.)
                    792:                                 */
                    793: 
                    794:                                vm_page_lock_queues();
                    795:                                pmap_remove_all(VM_PAGE_TO_PHYS(old_m));
                    796:                                copy_m->clean = FALSE;
                    797:                                vm_page_unlock_queues();
                    798: 
                    799:                                /*
                    800:                                 *      If there's a pager, then immediately
                    801:                                 *      page out this page, using the "initialize"
                    802:                                 *      option.  Else, we use the copy.
                    803:                                 */
                    804: 
                    805:                                if (copy_object->pager == vm_pager_null) {
                    806:                                        vm_page_lock_queues();
                    807:                                        vm_page_activate(copy_m);
                    808:                                        vm_page_unlock_queues();
                    809:                                        PAGE_WAKEUP(copy_m);
                    810:                                } else {
                    811:                                        /*
                    812:                                         *      Prepare the page for pageout:
                    813:                                         *
                    814:                                         *      Since it was just allocated,
                    815:                                         *      it is not on a pageout queue, but
                    816:                                         *      it is busy.
                    817:                                         */
                    818: 
                    819:                                        copy_m->busy = FALSE;
                    820: 
                    821:                                        /*
                    822:                                         *      Unlock everything except the
                    823:                                         *      copy_object itself.
                    824:                                         */
                    825: 
                    826:                                        vm_object_unlock(object);
                    827:                                        UNLOCK_MAP;
                    828: 
                    829:                                        vm_pageout_page(copy_m, TRUE);
                    830: 
                    831:                                        /*
                    832:                                         *      Since the pageout may have
                    833:                                         *      temporarily dropped the
                    834:                                         *      copy_object's lock, we
                    835:                                         *      check whether we'll have
                    836:                                         *      to deallocate the hard way.
                    837:                                         */
                    838: 
                    839:                                        if ((copy_object->shadow != object) ||
                    840:                                            (copy_object->ref_count == 1)) {
                    841:                                                vm_object_unlock(copy_object);
                    842:                                                vm_object_deallocate(copy_object);
                    843:                                                vm_object_lock(object);
                    844:                                                goto RetryCopy;
                    845:                                        }
                    846:                                        
                    847:                                        /*
                    848:                                         *      Pick back up the old object's
                    849:                                         *      lock.  [It is safe to do so,
                    850:                                         *      since it must be deeper in the
                    851:                                         *      object tree.]
                    852:                                         */
                    853:                                        
                    854:                                        vm_object_lock(object);
                    855:                                }
                    856:                        }
                    857: #if    defined(lint) || defined(hc)
                    858:                        if (++page_exists != 0)
                    859:                                panic("lint");
                    860: #endif defined(lint) || defined(hc)
                    861: #else  MACH_XP
                    862:                        /*
                    863:                         *      If the page is not in memory (in the object)
                    864:                         *      and the object has a pager, we have to check
                    865:                         *      if the pager has the data in secondary
                    866:                         *      storage.
                    867:                         */
                    868:                        if (!page_exists) {
                    869: 
                    870:                                /*
                    871:                                 *      If we don't allocate a (blank) page
                    872:                                 *      here... another thread could try
                    873:                                 *      to page it in, allocate a page, and
                    874:                                 *      then block on the busy page in its
                    875:                                 *      shadow (first_object).  Then we'd
                    876:                                 *      trip over the busy page after we
                    877:                                 *      found that the copy_object's pager
                    878:                                 *      doesn't have the page...
                    879:                                 */
                    880:                                copy_m = vm_page_alloc(copy_object,
                    881:                                                                copy_offset);
                    882:                                if (copy_m == VM_PAGE_NULL) {
                    883:                                        /*
                    884:                                         *      Wait for a page, then retry.
                    885:                                         */
                    886:                                        RELEASE_PAGE(m);
                    887:                                        copy_object->ref_count--;
                    888:                                        vm_object_unlock(copy_object);
                    889:                                        UNLOCK_AND_DEALLOCATE;
                    890:                                        VM_WAIT;
                    891:                                        goto RetryFault;
                    892:                                }
                    893: 
                    894:                                if (copy_object->pager != vm_pager_null) {
                    895:                                        vm_object_unlock(object);
                    896:                                        vm_object_unlock(copy_object);
                    897:                                        UNLOCK_MAP;
                    898: 
                    899:                                        page_exists = vm_pager_has_page(
                    900:                                                        copy_object->pager,
                    901:                                                        (copy_offset + copy_object->paging_offset));
                    902: 
                    903:                                        vm_object_lock(copy_object);
                    904: 
                    905:                                        /*
                    906:                                         * Since the map is unlocked, someone
                    907:                                         * else could have copied this object
                    908:                                         * and put a different copy_object
                    909:                                         * between the two.  Or, the last
                    910:                                         * reference to the copy-object (other
                    911:                                         * than the one we have) may have
                    912:                                         * disappeared - if that has happened,
                    913:                                         * we don't need to make the copy.
                    914:                                         */
                    915:                                        if (copy_object->shadow != object ||
                    916:                                            copy_object->ref_count == 1) {
                    917:                                                /*
                    918:                                                 *      Gaah... start over!
                    919:                                                 */
                    920:                                                FREE_PAGE(copy_m);
                    921:                                                vm_object_unlock(copy_object);
                    922:                                                vm_object_deallocate(copy_object);
                    923:                                                        /* may block */
                    924:                                                vm_object_lock(object);
                    925:                                                goto RetryCopy;
                    926:                                        }
                    927:                                        vm_object_lock(object);
                    928: 
                    929:                                        if (page_exists) {
                    930:                                                /*
                    931:                                                 *      We didn't need the page
                    932:                                                 */
                    933:                                                FREE_PAGE(copy_m);
                    934:                                        }
                    935:                                }
                    936:                        }
                    937:                        if (!page_exists) {
                    938:                                /*
                    939:                                 *      Must copy page into copy-object.
                    940:                                 */
                    941:                                vm_page_copy(m, copy_m);
                    942:                                copy_m->absent = FALSE;
                    943: 
                    944:                                /*
                    945:                                 * Things to remember:
                    946:                                 * 1. The copied page must be marked 'dirty'
                    947:                                 *    so it will be paged out to the copy
                    948:                                 *    object.
                    949:                                 * 2. If the old page was in use by any users
                    950:                                 *    of the copy-object, it must be removed
                    951:                                 *    from all pmaps.  (We can't know which
                    952:                                 *    pmaps use it.)
                    953:                                 */
                    954:                                vm_page_lock_queues();
                    955:                                pmap_remove_all(VM_PAGE_TO_PHYS(old_m));
                    956:                                copy_m->clean = FALSE;
                    957:                                vm_page_activate(copy_m);       /* XXX */
                    958:                                vm_page_unlock_queues();
                    959: 
                    960:                                PAGE_WAKEUP(copy_m);
                    961:                        }
                    962: #endif MACH_XP
                    963:                        /*
                    964:                         *      The reference count on copy_object must be
                    965:                         *      at least 2: one for our extra reference,
                    966:                         *      and at least one from the outside world
                    967:                         *      (we checked that when we last locked
                    968:                         *      copy_object).
                    969:                         */
                    970:                        copy_object->ref_count--;
                    971:                        vm_object_unlock(copy_object);
                    972:                        m->copy_on_write = FALSE;
                    973:                }
                    974:        }
                    975: 
                    976:        if (m->active || m->inactive)
                    977:                panic("vm_fault: active or inactive before retrying lookup");
                    978: 
                    979:        /*
                    980:         *      We must verify that the maps have not changed
                    981:         *      since our last lookup.
                    982:         */
                    983: 
                    984: #if    USE_VERSIONS
                    985:        vm_object_unlock(object);
                    986:        while (!vm_map_verify(map, &version)) {
                    987:                vm_object_t     retry_object;
                    988:                vm_offset_t     retry_offset;
                    989:                vm_prot_t       retry_prot;
                    990: 
                    991:                /*
                    992:                 *      To avoid trying to write_lock the map while another
                    993:                 *      thread has it read_locked (in vm_map_pageable), we
                    994:                 *      do not try for write permission.  If the page is
                    995:                 *      still writable, we will get write permission.  If it
                    996:                 *      is not, or has been marked needs_copy, we enter the
                    997:                 *      mapping without write permission, and will merely
                    998:                 *      take another fault.
                    999:                 */
                   1000:                result = vm_map_lookup(&map, vaddr,
                   1001:                                fault_type & ~VM_PROT_WRITE, &version,
                   1002:                                &retry_object, &retry_offset, &retry_prot,
                   1003:                                &wired, &su);
                   1004: 
                   1005:                if (result != KERN_SUCCESS) {
                   1006:                        RELEASE_PAGE(m);
                   1007:                        UNLOCK_AND_DEALLOCATE;
                   1008:                        return(result);
                   1009:                }
                   1010: 
                   1011:                vm_object_unlock(retry_object);
                   1012:                vm_object_lock(object);
                   1013: 
                   1014:                if ((retry_object != first_object) ||
                   1015:                                (retry_offset != first_offset)) {
                   1016:                        RELEASE_PAGE(m);
                   1017:                        UNLOCK_AND_DEALLOCATE;
                   1018:                        goto RetryFault;
                   1019:                }
                   1020: 
                   1021:                /*
                   1022:                 *      Check whether the protection has changed or the object
                   1023:                 *      has been copied while we left the map unlocked.
                   1024:                 *      Changing from read to write permission is OK - we leave
                   1025:                 *      the page write-protected, and catch the write fault.
                   1026:                 *      Changing from write to read permission means that we
                   1027:                 *      can't mark the page write-enabled after all.
                   1028:                 */
                   1029:                prot &= retry_prot;
                   1030:                if (m->copy_on_write)
                   1031:                        prot &= ~VM_PROT_WRITE;
                   1032: 
                   1033:                vm_object_unlock(object);
                   1034:        }
                   1035:        vm_object_lock(object);
                   1036: #else  USE_VERSIONS
                   1037: 
                   1038:        if (!lookup_still_valid) {
                   1039:                vm_object_t     retry_object;
                   1040:                vm_offset_t     retry_offset;
                   1041:                vm_prot_t       retry_prot;
                   1042: 
                   1043:                /*
                   1044:                 *      Since map entries may be pageable, make sure we can
                   1045:                 *      take a page fault on them.
                   1046:                 */
                   1047:                vm_object_unlock(object);
                   1048: 
                   1049:                /*
                   1050:                 *      To avoid trying to write_lock the map while another
                   1051:                 *      thread has it read_locked (in vm_map_pageable), we
                   1052:                 *      do not try for write permission.  If the page is
                   1053:                 *      still writable, we will get write permission.  If it
                   1054:                 *      is not, or has been marked needs_copy, we enter the
                   1055:                 *      mapping without write permission, and will merely
                   1056:                 *      take another fault.
                   1057:                 */
                   1058: 
                   1059:                result = vm_map_lookup(&map, vaddr,
                   1060:                                fault_type & ~VM_PROT_WRITE, &entry,
                   1061:                                &retry_object, &retry_offset, &retry_prot,
                   1062:                                &wired, &su);
                   1063:                vm_object_lock(object);
                   1064: 
                   1065:                /*
                   1066:                 *      If we don't need the page any longer, put it on the
                   1067:                 *      active list (the easiest thing to do here).  If no
                   1068:                 *      one needs it, pageout will grab it eventually.
                   1069:                 */
                   1070: 
                   1071:                if (result != KERN_SUCCESS) {
                   1072:                        RELEASE_PAGE(m);
                   1073:                        UNLOCK_AND_DEALLOCATE;
                   1074:                        return(result);
                   1075:                }
                   1076: 
                   1077:                lookup_still_valid = TRUE;
                   1078: 
                   1079:                if ((retry_object != first_object) ||
                   1080:                                (retry_offset != first_offset)) {
                   1081:                        RELEASE_PAGE(m);
                   1082:                        UNLOCK_AND_DEALLOCATE;
                   1083:                        goto RetryFault;
                   1084:                }
                   1085: 
                   1086:                /*
                   1087:                 *      Check whether the protection has changed or the object
                   1088:                 *      has been copied while we left the map unlocked.
                   1089:                 *      Changing from read to write permission is OK - we leave
                   1090:                 *      the page write-protected, and catch the write fault.
                   1091:                 *      Changing from write to read permission means that we
                   1092:                 *      can't mark the page write-enabled after all.
                   1093:                 */
                   1094:                prot &= retry_prot;
                   1095:                if (m->copy_on_write)
                   1096:                        prot &= ~VM_PROT_WRITE;
                   1097:                /*
                   1098:                 *      Can't catch write fault if page is to be wired.  This
                   1099:                 *      should never happen because caller holds a read lock
                   1100:                 *      on the map.
                   1101:                 */
                   1102:                if (wired && (prot != fault_type)) {
                   1103:                        RELEASE_PAGE(m);
                   1104:                        UNLOCK_AND_DEALLOCATE;
                   1105:                        goto RetryFault;
                   1106:                }
                   1107:        }
                   1108: #endif USE_VERSIONS
                   1109: 
                   1110:        /*
                   1111:         * (the various bits we're fiddling with here are locked by
                   1112:         * the object's lock)
                   1113:         */
                   1114: 
                   1115:        /* XXX This distorts the meaning of the copy_on_write bit */
                   1116: 
                   1117:        if (prot & VM_PROT_WRITE)
                   1118:                m->copy_on_write = FALSE;
                   1119: 
                   1120:        /*
                   1121:         *      It's critically important that a wired-down page be faulted
                   1122:         *      only once in each map for which it is wired.
                   1123:         */
                   1124: 
                   1125:        if (m->active || m->inactive)
                   1126:                panic("vm_fault: active or inactive before pmap_enter");
                   1127: 
                   1128:        vm_object_unlock(object);
                   1129: 
                   1130:        /*
                   1131:         *      Put this page into the physical map.
                   1132:         *      We had to do the unlock above because pmap_enter
                   1133:         *      may cause other faults.   We don't put the
                   1134:         *      page back on the active queue until later so
                   1135:         *      that the page-out daemon won't find us (yet).
                   1136:         */
                   1137: 
                   1138:        pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m), 
                   1139:                        prot & ~(m->page_lock), wired);
                   1140: 
                   1141:        /*
                   1142:         *      If the page is not wired down, then put it where the
                   1143:         *      pageout daemon can find it.
                   1144:         */
                   1145:        vm_object_lock(object);
                   1146:        vm_page_lock_queues();
                   1147:        if (change_wiring) {
                   1148:                if (wired)
                   1149:                        vm_page_wire(m);
                   1150:                else
                   1151:                        vm_page_unwire(m);
                   1152:        }
                   1153:        else
                   1154:                vm_page_activate(m);
                   1155:        vm_page_unlock_queues();
                   1156: 
                   1157:        /*
                   1158:         *      Unlock everything, and return
                   1159:         */
                   1160: 
                   1161: #if    USE_VERSIONS
                   1162:        vm_map_verify_done(map, &version);
                   1163: #endif USE_VERSIONS
                   1164:        PAGE_WAKEUP(m);
                   1165:        UNLOCK_AND_DEALLOCATE;
                   1166: 
                   1167:        return(KERN_SUCCESS);
                   1168: 
                   1169: }
                   1170: 
                   1171: kern_return_t  vm_fault_wire_fast();
                   1172: 
                   1173: /*
                   1174:  *     vm_fault_wire:
                   1175:  *
                   1176:  *     Wire down a range of virtual addresses in a map.
                   1177:  */
                   1178: void vm_fault_wire(map, entry)
                   1179:        vm_map_t        map;
                   1180:        vm_map_entry_t  entry;
                   1181: {
                   1182: 
                   1183:        register vm_offset_t    va;
                   1184:        register pmap_t         pmap;
                   1185:        register vm_offset_t    end_addr = entry->vme_end;
                   1186: 
                   1187:        pmap = vm_map_pmap(map);
                   1188: 
                   1189:        /*
                   1190:         *      Inform the physical mapping system that the
                   1191:         *      range of addresses may not fault, so that
                   1192:         *      page tables and such can be locked down as well.
                   1193:         */
                   1194: 
                   1195:        pmap_pageable(pmap, entry->vme_start, end_addr, FALSE);
                   1196: 
                   1197:        /*
                   1198:         *      We simulate a fault to get the page and enter it
                   1199:         *      in the physical map.
                   1200:         */
                   1201: 
                   1202:        for (va = entry->vme_start; va < end_addr; va += PAGE_SIZE) {
                   1203:                if (vm_fault_wire_fast(map, va, entry) != KERN_SUCCESS)
                   1204:                        (void) vm_fault(map, va, VM_PROT_NONE, TRUE, 0);
                   1205:        }
                   1206: }
                   1207: 
                   1208: 
                   1209: /*
                   1210:  *     vm_fault_unwire:
                   1211:  *
                   1212:  *     Unwire a range of virtual addresses in a map.
                   1213:  */
                   1214: void vm_fault_unwire(map, entry)
                   1215:        vm_map_t        map;
                   1216:        vm_map_entry_t  entry;
                   1217: {
                   1218: 
                   1219:        register vm_offset_t    va, pa;
                   1220:        register pmap_t         pmap;
                   1221:        register vm_offset_t    end_addr = entry->vme_end;
                   1222: 
                   1223:        pmap = vm_map_pmap(map);
                   1224: 
                   1225:        /*
                   1226:         *      Since the pages are wired down, we must be able to
                   1227:         *      get their mappings from the physical map system.
                   1228:         */
                   1229: 
                   1230:        vm_page_lock_queues();
                   1231: 
                   1232:        for (va = entry->vme_start; va < end_addr; va += PAGE_SIZE) {
                   1233:                pa = pmap_extract(pmap, va);
                   1234:                if (pa == (vm_offset_t) 0)
                   1235:                        continue;
                   1236: 
                   1237:                pmap_change_wiring(pmap, va, FALSE);
                   1238:                vm_page_unwire(PHYS_TO_VM_PAGE(pa));
                   1239:        }
                   1240:        vm_page_unlock_queues();
                   1241: 
                   1242:        /*
                   1243:         *      Inform the physical mapping system that the range
                   1244:         *      of addresses may fault, so that page tables and
                   1245:         *      such may be unwired themselves.
                   1246:         */
                   1247: 
                   1248:        pmap_pageable(pmap, entry->vme_start, end_addr, TRUE);
                   1249: 
                   1250: }
                   1251: 
                   1252: /*
                   1253:  *     Routine:
                   1254:  *             vm_fault_copy_entry
                   1255:  *     Function:
                   1256:  *             Copy all of the pages from a wired-down map entry to another.
                   1257:  *
                   1258:  *     In/out conditions:
                   1259:  *             The source and destination maps must be locked for write.
                   1260:  *             The source map entry must be wired down (or be a sharing map
                   1261:  *             entry corresponding to a main map entry that is wired down).
                   1262:  */
                   1263: 
                   1264: void vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
                   1265:        vm_map_t        dst_map;
                   1266:        vm_map_t        src_map;
                   1267:        vm_map_entry_t  dst_entry;
                   1268:        vm_map_entry_t  src_entry;
                   1269: {
                   1270: 
                   1271:        vm_object_t     dst_object;
                   1272:        vm_object_t     src_object;
                   1273:        vm_offset_t     dst_offset;
                   1274:        vm_offset_t     src_offset;
                   1275:        vm_prot_t       prot;
                   1276:        vm_offset_t     vaddr;
                   1277:        vm_page_t       dst_m;
                   1278:        vm_page_t       src_m;
                   1279: 
                   1280: #ifdef lint
                   1281:        src_map++;
                   1282: #endif lint
                   1283: 
                   1284:        src_object = src_entry->object.vm_object;
                   1285:        src_offset = src_entry->offset;
                   1286: 
                   1287:        /*
                   1288:         *      Create the top-level object for the destination entry.
                   1289:         *      (Doesn't actually shadow anything - we copy the pages
                   1290:         *      directly.)
                   1291:         */
                   1292:        dst_object = vm_object_allocate(
                   1293:                        (vm_size_t) (dst_entry->vme_end -
                   1294:                                        dst_entry->vme_start));
                   1295: 
                   1296:        dst_entry->object.vm_object = dst_object;
                   1297:        dst_entry->offset = 0;
                   1298: 
                   1299:        prot  = dst_entry->max_protection;
                   1300: 
                   1301:        /*
                   1302:         *      Loop through all of the pages in the entry's range, copying
                   1303:         *      each one from the source object (it should be there) to the
                   1304:         *      destination object.
                   1305:         */
                   1306:        for (vaddr = dst_entry->vme_start, dst_offset = 0;
                   1307:             vaddr < dst_entry->vme_end;
                   1308:             vaddr += PAGE_SIZE, dst_offset += PAGE_SIZE) {
                   1309: 
                   1310:                /*
                   1311:                 *      Allocate a page in the destination object
                   1312:                 */
                   1313:                vm_object_lock(dst_object);
                   1314:                do {
                   1315:                        dst_m = vm_page_alloc(dst_object, dst_offset);
                   1316:                        if (dst_m == VM_PAGE_NULL) {
                   1317:                                vm_object_unlock(dst_object);
                   1318:                                VM_WAIT;
                   1319:                                vm_object_lock(dst_object);
                   1320:                        }
                   1321:                } while (dst_m == VM_PAGE_NULL);
                   1322: 
                   1323:                /*
                   1324:                 *      Find the page in the source object, and copy it in.
                   1325:                 *      (Because the source is wired down, the page will be
                   1326:                 *      in memory.)
                   1327:                 */
                   1328:                vm_object_lock(src_object);
                   1329:                src_m = vm_page_lookup(src_object, dst_offset + src_offset);
                   1330:                if (src_m == VM_PAGE_NULL)
                   1331:                        panic("vm_fault_copy_wired: page missing");
                   1332: 
                   1333:                vm_page_copy(src_m, dst_m);
                   1334: 
                   1335:                /*
                   1336:                 *      Enter it in the pmap...
                   1337:                 */
                   1338:                vm_object_unlock(src_object);
                   1339:                vm_object_unlock(dst_object);
                   1340: 
                   1341:                pmap_enter(dst_map->pmap, vaddr, VM_PAGE_TO_PHYS(dst_m),
                   1342:                                prot, FALSE);
                   1343: 
                   1344:                /*
                   1345:                 *      Mark it no longer busy, and put it on the active list.
                   1346:                 */
                   1347:                vm_object_lock(dst_object);
                   1348:                vm_page_lock_queues();
                   1349:                vm_page_activate(dst_m);
                   1350:                vm_page_unlock_queues();
                   1351:                PAGE_WAKEUP(dst_m);
                   1352:                vm_object_unlock(dst_object);
                   1353:        }
                   1354: 
                   1355: }
                   1356: 
                   1357: 
                   1358: /*
                   1359:  *     vm_fault_wire_fast:
                   1360:  *
                   1361:  *     Handle common case of a wire down page fault at the given address.
                   1362:  *     If successful, the page is inserted into the associated physical map.
                   1363:  *     The map entry is passed in to avoid the overhead of a map lookup.
                   1364:  *
                   1365:  *     NOTE: the given address should be truncated to the
                   1366:  *     proper page address.
                   1367:  *
                   1368:  *     KERN_SUCCESS is returned if the page fault is handled; otherwise,
                   1369:  *     a standard error specifying why the fault is fatal is returned.
                   1370:  *
                   1371:  *     The map in question must be referenced, and remains so.
                   1372:  *     Caller has a read lock on the map.
                   1373:  *
                   1374:  *     This is a stripped version of vm_fault() for wiring pages.  Anything
                   1375:  *     other than the common case will return KERN_FAILURE, and the caller
                   1376:  *     is expected to call vm_fault().
                   1377:  */
                   1378: kern_return_t vm_fault_wire_fast(map, va, entry)
                   1379:        vm_map_t        map;
                   1380:        vm_offset_t     va;
                   1381:        vm_map_entry_t  entry;
                   1382: {
                   1383:        vm_object_t             object;
                   1384:        vm_offset_t             offset;
                   1385:        register vm_page_t      m;
                   1386:        vm_prot_t               prot;
                   1387: 
                   1388:        vm_stat.faults++;               /* needs lock XXX */
                   1389: /*
                   1390:  *     Recovery actions
                   1391:  */
                   1392: 
                   1393: #undef RELEASE_PAGE
                   1394: #define        RELEASE_PAGE(m) {                               \
                   1395:        PAGE_WAKEUP(m);                                 \
                   1396:        vm_page_lock_queues();                          \
                   1397:        vm_page_unwire(m);                              \
                   1398:        vm_page_unlock_queues();                        \
                   1399: }
                   1400: 
                   1401: 
                   1402: #undef UNLOCK_THINGS
                   1403: #define        UNLOCK_THINGS   {                               \
                   1404:        object->paging_in_progress--;                   \
                   1405:        vm_object_unlock(object);                       \
                   1406: }
                   1407: 
                   1408: #undef UNLOCK_AND_DEALLOCATE
                   1409: #define        UNLOCK_AND_DEALLOCATE   {                       \
                   1410:        UNLOCK_THINGS;                                  \
                   1411:        vm_object_deallocate(object);                   \
                   1412: }
                   1413: /*
                   1414:  *     Give up and have caller do things the hard way.
                   1415:  */
                   1416: 
                   1417: #define        GIVE_UP {                                       \
                   1418:        UNLOCK_AND_DEALLOCATE;                          \
                   1419:        return(KERN_FAILURE);                           \
                   1420: }
                   1421: 
                   1422: 
                   1423:        /*
                   1424:         *      If this entry is not directly to a vm_object, bail out.
                   1425:         */
                   1426:        if ((entry->is_a_map) || (entry->is_sub_map))
                   1427:                return(KERN_FAILURE);
                   1428: 
                   1429:        /*
                   1430:         *      Find the backing store object and offset into it.
                   1431:         */
                   1432: 
                   1433:        object = entry->object.vm_object;
                   1434:        offset = va - entry->vme_start + entry->offset;
                   1435:        prot = entry->protection;
                   1436: 
                   1437:        /*
                   1438:         *      Make a reference to this object to prevent its
                   1439:         *      disposal while we are messing with it.
                   1440:         */
                   1441: 
                   1442:        vm_object_lock(object);
                   1443:        object->ref_count++;
                   1444:        object->paging_in_progress++;
                   1445: 
                   1446:        /*
                   1447:         *      INVARIANTS (through entire routine):
                   1448:         *
                   1449:         *      1)      At all times, we must either have the object
                   1450:         *              lock or a busy page in some object to prevent
                   1451:         *              some other thread from trying to bring in
                   1452:         *              the same page.
                   1453:         *
                   1454:         *      2)      Once we have a busy page, we must remove it from
                   1455:         *              the pageout queues, so that the pageout daemon
                   1456:         *              will not grab it away.
                   1457:         *
                   1458:         */
                   1459: 
                   1460:        /*
                   1461:         *      Look for page in top-level object.  If it's not there or
                   1462:         *      there's something going on, give up.
                   1463:         */
                   1464:        m = vm_page_lookup(object, offset);
                   1465: #if SCRUBVM3
                   1466:        if ((m != VM_PAGE_NULL) && (m->dry_vp)){
                   1467:            vm_page_lock_queues();
                   1468:            (void) vm_page_completeio(m, TRUE);
                   1469:            vm_page_unlock_queues();
                   1470:        }
                   1471: #endif
                   1472:        if ((m == VM_PAGE_NULL) || (m->busy) || (m->absent) ||
                   1473:            (prot & m->page_lock)) {
                   1474:                GIVE_UP;
                   1475:        }
                   1476: 
                   1477:        /*
                   1478:         *      Wire the page down now.  All bail outs beyond this
                   1479:         *      point must unwire the page.  
                   1480:         */
                   1481: 
                   1482:        vm_page_lock_queues();
                   1483:        vm_page_wire(m);
                   1484:        vm_page_unlock_queues();
                   1485: 
                   1486:        /*
                   1487:         *      Mark page busy for other threads.
                   1488:         */
                   1489:        m->busy = TRUE;
                   1490:        m->absent = FALSE;
                   1491: 
                   1492:        /*
                   1493:         *      Give up if the page is being written and there's a copy object
                   1494:         */
                   1495:        if (object->copy != VM_OBJECT_NULL) {
                   1496:                if ((prot & VM_PROT_WRITE) == 0) {
                   1497:                        m->copy_on_write = TRUE;
                   1498:                }
                   1499:                else {
                   1500:                        RELEASE_PAGE(m);
                   1501:                        GIVE_UP;
                   1502:                }
                   1503:        }
                   1504: 
                   1505:        /*
                   1506:         * (the various bits we're fiddling with here are locked by
                   1507:         * the object's lock)
                   1508:         */
                   1509: 
                   1510:        /* XXX This distorts the meaning of the copy_on_write bit */
                   1511: 
                   1512:        if (prot & VM_PROT_WRITE)
                   1513:                m->copy_on_write = FALSE;
                   1514: 
                   1515:        /*
                   1516:         *      Put this page into the physical map.
                   1517:         *      We have to unlock the object because pmap_enter
                   1518:         *      may cause other faults.   
                   1519:         */
                   1520:        vm_object_unlock(object);
                   1521: 
                   1522:        pmap_enter(map->pmap, va, VM_PAGE_TO_PHYS(m), prot , TRUE);
                   1523: 
                   1524:        /*
                   1525:         *      Must relock object so that paging_in_progress can be cleared.
                   1526:         */
                   1527:        vm_object_lock(object);
                   1528: 
                   1529:        /*
                   1530:         *      Unlock everything, and return
                   1531:         */
                   1532: 
                   1533:        PAGE_WAKEUP(m);
                   1534:        UNLOCK_AND_DEALLOCATE;
                   1535: 
                   1536:        return(KERN_SUCCESS);
                   1537: 
                   1538: }

unix.superglobalmegacorp.com

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