home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / vm / vm_fault.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-07  |  26.0 KB  |  1,068 lines

  1. /* 
  2.  * Copyright (c) 1991 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * The Mach Operating System project at Carnegie-Mellon University.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  *
  36.  *    @(#)vm_fault.c    7.6 (Berkeley) 5/7/91
  37.  *
  38.  *
  39.  * Copyright (c) 1987, 1990 Carnegie-Mellon University.
  40.  * All rights reserved.
  41.  *
  42.  * Authors: Avadis Tevanian, Jr., Michael Wayne Young
  43.  * 
  44.  * Permission to use, copy, modify and distribute this software and
  45.  * its documentation is hereby granted, provided that both the copyright
  46.  * notice and this permission notice appear in all copies of the
  47.  * software, derivative works or modified versions, and any portions
  48.  * thereof, and that both notices appear in supporting documentation.
  49.  * 
  50.  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 
  51.  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 
  52.  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  53.  * 
  54.  * Carnegie Mellon requests users of this software to return to
  55.  *
  56.  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  57.  *  School of Computer Science
  58.  *  Carnegie Mellon University
  59.  *  Pittsburgh PA 15213-3890
  60.  *
  61.  * any improvements or extensions that they make and grant Carnegie the
  62.  * rights to redistribute these changes.
  63.  */
  64.  
  65. /*
  66.  *    Page fault handling module.
  67.  */
  68.  
  69. #include "param.h"
  70.  
  71. #include "vm.h"
  72. #include "vm_page.h"
  73. #include "vm_pageout.h"
  74.  
  75. /*
  76.  *    vm_fault:
  77.  *
  78.  *    Handle a page fault occuring at the given address,
  79.  *    requiring the given permissions, in the map specified.
  80.  *    If successful, the page is inserted into the
  81.  *    associated physical map.
  82.  *
  83.  *    NOTE: the given address should be truncated to the
  84.  *    proper page address.
  85.  *
  86.  *    KERN_SUCCESS is returned if the page fault is handled; otherwise,
  87.  *    a standard error specifying why the fault is fatal is returned.
  88.  *
  89.  *
  90.  *    The map in question must be referenced, and remains so.
  91.  *    Caller may hold no locks.
  92.  */
  93. vm_fault(map, vaddr, fault_type, change_wiring)
  94.     vm_map_t    map;
  95.     vm_offset_t    vaddr;
  96.     vm_prot_t    fault_type;
  97.     boolean_t    change_wiring;
  98. {
  99.     vm_object_t        first_object;
  100.     vm_offset_t        first_offset;
  101.     vm_map_entry_t        entry;
  102.     register vm_object_t    object;
  103.     register vm_offset_t    offset;
  104.     register vm_page_t    m;
  105.     vm_page_t        first_m;
  106.     vm_prot_t        prot;
  107.     int            result;
  108.     boolean_t        wired;
  109.     boolean_t        su;
  110.     boolean_t        lookup_still_valid;
  111.     boolean_t        page_exists;
  112.     vm_page_t        old_m;
  113.     vm_object_t        next_object;
  114.  
  115.     vm_stat.faults++;        /* needs lock XXX */
  116. /*
  117.  *    Recovery actions
  118.  */
  119. #define    FREE_PAGE(m)    {                \
  120.     PAGE_WAKEUP(m);                    \
  121.     vm_page_lock_queues();                \
  122.     vm_page_free(m);                \
  123.     vm_page_unlock_queues();            \
  124. }
  125.  
  126. #define    RELEASE_PAGE(m)    {                \
  127.     PAGE_WAKEUP(m);                    \
  128.     vm_page_lock_queues();                \
  129.     vm_page_activate(m);                \
  130.     vm_page_unlock_queues();            \
  131. }
  132.  
  133. #define    UNLOCK_MAP    {                \
  134.     if (lookup_still_valid) {            \
  135.         vm_map_lookup_done(map, entry);        \
  136.         lookup_still_valid = FALSE;        \
  137.     }                        \
  138. }
  139.  
  140. #define    UNLOCK_THINGS    {                \
  141.     object->paging_in_progress--;            \
  142.     vm_object_unlock(object);            \
  143.     if (object != first_object) {            \
  144.         vm_object_lock(first_object);        \
  145.         FREE_PAGE(first_m);            \
  146.         first_object->paging_in_progress--;    \
  147.         vm_object_unlock(first_object);        \
  148.     }                        \
  149.     UNLOCK_MAP;                    \
  150. }
  151.  
  152. #define    UNLOCK_AND_DEALLOCATE    {            \
  153.     UNLOCK_THINGS;                    \
  154.     vm_object_deallocate(first_object);        \
  155. }
  156.  
  157.     RetryFault: ;
  158.  
  159.     /*
  160.      *    Find the backing store object and offset into
  161.      *    it to begin the search.
  162.      */
  163.  
  164.     if ((result = vm_map_lookup(&map, vaddr, fault_type, &entry,
  165.             &first_object, &first_offset,
  166.             &prot, &wired, &su)) != KERN_SUCCESS) {
  167.         return(result);
  168.     }
  169.     lookup_still_valid = TRUE;
  170.  
  171.     if (wired)
  172.         fault_type = prot;
  173.  
  174.     first_m = NULL;
  175.  
  176.        /*
  177.      *    Make a reference to this object to
  178.      *    prevent its disposal while we are messing with
  179.      *    it.  Once we have the reference, the map is free
  180.      *    to be diddled.  Since objects reference their
  181.      *    shadows (and copies), they will stay around as well.
  182.      */
  183.  
  184.     vm_object_lock(first_object);
  185.  
  186.     first_object->ref_count++;
  187.     first_object->paging_in_progress++;
  188.  
  189.     /*
  190.      *    INVARIANTS (through entire routine):
  191.      *
  192.      *    1)    At all times, we must either have the object
  193.      *        lock or a busy page in some object to prevent
  194.      *        some other thread from trying to bring in
  195.      *        the same page.
  196.      *
  197.      *        Note that we cannot hold any locks during the
  198.      *        pager access or when waiting for memory, so
  199.      *        we use a busy page then.
  200.      *
  201.      *        Note also that we aren't as concerned about
  202.      *        more than one thead attempting to pager_data_unlock
  203.      *        the same page at once, so we don't hold the page
  204.      *        as busy then, but do record the highest unlock
  205.      *        value so far.  [Unlock requests may also be delivered
  206.      *        out of order.]
  207.      *
  208.      *    2)    Once we have a busy page, we must remove it from
  209.      *        the pageout queues, so that the pageout daemon
  210.      *        will not grab it away.
  211.      *
  212.      *    3)    To prevent another thread from racing us down the
  213.      *        shadow chain and entering a new page in the top
  214.      *        object before we do, we must keep a busy page in
  215.      *        the top object while following the shadow chain.
  216.      *
  217.      *    4)    We must increment paging_in_progress on any object
  218.      *        for which we have a busy page, to prevent
  219.      *        vm_object_collapse from removing the busy page
  220.      *        without our noticing.
  221.      */
  222.  
  223.     /*
  224.      *    Search for the page at object/offset.
  225.      */
  226.  
  227.     object = first_object;
  228.     offset = first_offset;
  229.  
  230.     /*
  231.      *    See whether this page is resident
  232.      */
  233.  
  234.     while (TRUE) {
  235.         m = vm_page_lookup(object, offset);
  236.         if (m != NULL) {
  237.             /*
  238.              *    If the page is being brought in,
  239.              *    wait for it and then retry.
  240.              */
  241.             if (m->busy) {
  242. #ifdef DOTHREADS
  243.                 int    wait_result;
  244.  
  245.                 PAGE_ASSERT_WAIT(m, !change_wiring);
  246.                 UNLOCK_THINGS;
  247.                 thread_block();
  248.                 wait_result = current_thread()->wait_result;
  249.                 vm_object_deallocate(first_object);
  250.                 if (wait_result != THREAD_AWAKENED)
  251.                     return(KERN_SUCCESS);
  252.                 goto RetryFault;
  253. #else
  254.                 PAGE_ASSERT_WAIT(m, !change_wiring);
  255.                 UNLOCK_THINGS;
  256.                 thread_block();
  257.                 vm_object_deallocate(first_object);
  258.                 goto RetryFault;
  259. #endif
  260.             }
  261.  
  262.             if (m->absent)
  263.                 panic("vm_fault: absent");
  264.  
  265.             /*
  266.              *    If the desired access to this page has
  267.              *    been locked out, request that it be unlocked.
  268.              */
  269.  
  270.             if (fault_type & m->page_lock) {
  271. #ifdef DOTHREADS
  272.                 int    wait_result;
  273.  
  274.                 if ((fault_type & m->unlock_request) != fault_type)
  275.                     panic("vm_fault: pager_data_unlock");
  276.  
  277.                 PAGE_ASSERT_WAIT(m, !change_wiring);
  278.                 UNLOCK_THINGS;
  279.                 thread_block();
  280.                 wait_result = current_thread()->wait_result;
  281.                 vm_object_deallocate(first_object);
  282.                 if (wait_result != THREAD_AWAKENED)
  283.                     return(KERN_SUCCESS);
  284.                 goto RetryFault;
  285. #else
  286.                 if ((fault_type & m->unlock_request) != fault_type)
  287.                     panic("vm_fault: pager_data_unlock");
  288.  
  289.                 PAGE_ASSERT_WAIT(m, !change_wiring);
  290.                 UNLOCK_THINGS;
  291.                 thread_block();
  292.                 vm_object_deallocate(first_object);
  293.                 goto RetryFault;
  294. #endif
  295.             }
  296.  
  297.             /*
  298.              *    Remove the page from the pageout daemon's
  299.              *    reach while we play with it.
  300.              */
  301.  
  302.             vm_page_lock_queues();
  303.             if (m->inactive) {
  304.                 queue_remove(&vm_page_queue_inactive, m,
  305.                         vm_page_t, pageq);
  306.                 m->inactive = FALSE;
  307.                 vm_page_inactive_count--;
  308.                 vm_stat.reactivations++;
  309.             } 
  310.  
  311.             if (m->active) {
  312.                 queue_remove(&vm_page_queue_active, m,
  313.                         vm_page_t, pageq);
  314.                 m->active = FALSE;
  315.                 vm_page_active_count--;
  316.             }
  317.             vm_page_unlock_queues();
  318.  
  319.             /*
  320.              *    Mark page busy for other threads.
  321.              */
  322.             m->busy = TRUE;
  323.             m->absent = FALSE;
  324.             break;
  325.         }
  326.  
  327.         if (((object->pager != NULL) &&
  328.                 (!change_wiring || wired))
  329.             || (object == first_object)) {
  330.  
  331.             /*
  332.              *    Allocate a new page for this object/offset
  333.              *    pair.
  334.              */
  335.  
  336.             m = vm_page_alloc(object, offset);
  337.  
  338.             if (m == NULL) {
  339.                 UNLOCK_AND_DEALLOCATE;
  340.                 VM_WAIT;
  341.                 goto RetryFault;
  342.             }
  343.         }
  344.  
  345.         if ((object->pager != NULL) &&
  346.                 (!change_wiring || wired)) {
  347.             int rv;
  348.  
  349.             /*
  350.              *    Now that we have a busy page, we can
  351.              *    release the object lock.
  352.              */
  353.             vm_object_unlock(object);
  354.  
  355.             /*
  356.              *    Call the pager to retrieve the data, if any,
  357.              *    after releasing the lock on the map.
  358.              */
  359.             UNLOCK_MAP;
  360.  
  361.             rv = vm_pager_get(object->pager, m, TRUE);
  362.             if (rv == VM_PAGER_OK) {
  363.                 /*
  364.                  *    Found the page.
  365.                  *    Leave it busy while we play with it.
  366.                  */
  367.                 vm_object_lock(object);
  368.  
  369.                 /*
  370.                  *    Relookup in case pager changed page.
  371.                  *    Pager is responsible for disposition
  372.                  *    of old page if moved.
  373.                  */
  374.                 m = vm_page_lookup(object, offset);
  375.  
  376.                 vm_stat.pageins++;
  377.                 m->fake = FALSE;
  378.                 pmap_clear_modify(VM_PAGE_TO_PHYS(m));
  379.                 break;
  380.             }
  381.  
  382.             /*
  383.              *    Remove the bogus page (which does not
  384.              *    exist at this object/offset); before
  385.              *    doing so, we must get back our object
  386.              *    lock to preserve our invariant.
  387.              *
  388.              *    Also wake up any other thread that may want
  389.              *    to bring in this page.
  390.              *
  391.              *    If this is the top-level object, we must
  392.              *    leave the busy page to prevent another
  393.              *    thread from rushing past us, and inserting
  394.              *    the page in that object at the same time
  395.              *    that we are.
  396.              */
  397.  
  398.             vm_object_lock(object);
  399.             /*
  400.              * Data outside the range of the pager; an error
  401.              */
  402.             if (rv == VM_PAGER_BAD) {
  403.                 FREE_PAGE(m);
  404.                 UNLOCK_AND_DEALLOCATE;
  405.                 return(KERN_PROTECTION_FAILURE); /* XXX */
  406.             }
  407.             if (object != first_object) {
  408.                 FREE_PAGE(m);
  409.                 /*
  410.                  * XXX - we cannot just fall out at this
  411.                  * point, m has been freed and is invalid!
  412.                  */
  413.             }
  414.         }
  415.  
  416.         /*
  417.          * We get here if the object has no pager (or unwiring)
  418.          * or the pager doesn't have the page.
  419.          */
  420.         if (object == first_object)
  421.             first_m = m;
  422.  
  423.         /*
  424.          *    Move on to the next object.  Lock the next
  425.          *    object before unlocking the current one.
  426.          */
  427.  
  428.         offset += object->shadow_offset;
  429.         next_object = object->shadow;
  430.         if (next_object == NULL) {
  431.             /*
  432.              *    If there's no object left, fill the page
  433.              *    in the top object with zeros.
  434.              */
  435.             if (object != first_object) {
  436.                 object->paging_in_progress--;
  437.                 vm_object_unlock(object);
  438.  
  439.                 object = first_object;
  440.                 offset = first_offset;
  441.                 m = first_m;
  442.                 vm_object_lock(object);
  443.             }
  444.             first_m = NULL;
  445.  
  446.             vm_page_zero_fill(m);
  447.             vm_stat.zero_fill_count++;
  448.             m->fake = FALSE;
  449.             m->absent = FALSE;
  450.             break;
  451.         }
  452.         else {
  453.             vm_object_lock(next_object);
  454.             if (object != first_object)
  455.                 object->paging_in_progress--;
  456.             vm_object_unlock(object);
  457.             object = next_object;
  458.             object->paging_in_progress++;
  459.         }
  460.     }
  461.  
  462.     if (m->absent || m->active || m->inactive || !m->busy)
  463.         panic("vm_fault: absent or active or inactive or not busy after main loop");
  464.  
  465.     /*
  466.      *    PAGE HAS BEEN FOUND.
  467.      *    [Loop invariant still holds -- the object lock
  468.      *    is held.]
  469.      */
  470.  
  471.     old_m = m;    /* save page that would be copied */
  472.  
  473.     /*
  474.      *    If the page is being written, but isn't
  475.      *    already owned by the top-level object,
  476.      *    we have to copy it into a new page owned
  477.      *    by the top-level object.
  478.      */
  479.  
  480.     if (object != first_object) {
  481.             /*
  482.          *    We only really need to copy if we
  483.          *    want to write it.
  484.          */
  485.  
  486.             if (fault_type & VM_PROT_WRITE) {
  487.  
  488.             /*
  489.              *    If we try to collapse first_object at this
  490.              *    point, we may deadlock when we try to get
  491.              *    the lock on an intermediate object (since we
  492.              *    have the bottom object locked).  We can't
  493.              *    unlock the bottom object, because the page
  494.              *    we found may move (by collapse) if we do.
  495.              *
  496.              *    Instead, we first copy the page.  Then, when
  497.              *    we have no more use for the bottom object,
  498.              *    we unlock it and try to collapse.
  499.              *
  500.              *    Note that we copy the page even if we didn't
  501.              *    need to... that's the breaks.
  502.              */
  503.  
  504.                 /*
  505.              *    We already have an empty page in
  506.              *    first_object - use it.
  507.              */
  508.  
  509.             vm_page_copy(m, first_m);
  510.             first_m->fake = FALSE;
  511.             first_m->absent = FALSE;
  512.  
  513.             /*
  514.              *    If another map is truly sharing this
  515.              *    page with us, we have to flush all
  516.              *    uses of the original page, since we
  517.              *    can't distinguish those which want the
  518.              *    original from those which need the
  519.              *    new copy.
  520.              *
  521.              *    XXX If we know that only one map has
  522.              *    access to this page, then we could
  523.              *    avoid the pmap_page_protect() call.
  524.              */
  525.  
  526.             vm_page_lock_queues();
  527.             vm_page_deactivate(m);
  528.             pmap_page_protect(VM_PAGE_TO_PHYS(m), VM_PROT_NONE);
  529.             vm_page_unlock_queues();
  530.  
  531.             /*
  532.              *    We no longer need the old page or object.
  533.              */
  534.             PAGE_WAKEUP(m);
  535.             object->paging_in_progress--;
  536.             vm_object_unlock(object);
  537.  
  538.             /*
  539.              *    Only use the new page below...
  540.              */
  541.  
  542.             vm_stat.cow_faults++;
  543.             m = first_m;
  544.             object = first_object;
  545.             offset = first_offset;
  546.  
  547.             /*
  548.              *    Now that we've gotten the copy out of the
  549.              *    way, let's try to collapse the top object.
  550.              */
  551.             vm_object_lock(object);
  552.             /*
  553.              *    But we have to play ugly games with
  554.              *    paging_in_progress to do that...
  555.              */
  556.             object->paging_in_progress--;
  557.             vm_object_collapse(object);
  558.             object->paging_in_progress++;
  559.         }
  560.         else {
  561.                 prot &= (~VM_PROT_WRITE);
  562.             m->copy_on_write = TRUE;
  563.         }
  564.     }
  565.  
  566.     if (m->active || m->inactive)
  567.         panic("vm_fault: active or inactive before copy object handling");
  568.  
  569.     /*
  570.      *    If the page is being written, but hasn't been
  571.      *    copied to the copy-object, we have to copy it there.
  572.      */
  573.     RetryCopy:
  574.     if (first_object->copy != NULL) {
  575.         vm_object_t copy_object = first_object->copy;
  576.         vm_offset_t copy_offset;
  577.         vm_page_t copy_m;
  578.  
  579.         /*
  580.          *    We only need to copy if we want to write it.
  581.          */
  582.         if ((fault_type & VM_PROT_WRITE) == 0) {
  583.             prot &= ~VM_PROT_WRITE;
  584.             m->copy_on_write = TRUE;
  585.         }
  586.         else {
  587.             /*
  588.              *    Try to get the lock on the copy_object.
  589.              */
  590.             if (!vm_object_lock_try(copy_object)) {
  591.                 vm_object_unlock(object);
  592.                 /* should spin a bit here... */
  593.                 vm_object_lock(object);
  594.                 goto RetryCopy;
  595.             }
  596.  
  597.             /*
  598.              *    Make another reference to the copy-object,
  599.              *    to keep it from disappearing during the
  600.              *    copy.
  601.              */
  602.             copy_object->ref_count++;
  603.  
  604.             /*
  605.              *    Does the page exist in the copy?
  606.              */
  607.             copy_offset = first_offset
  608.                 - copy_object->shadow_offset;
  609.             copy_m = vm_page_lookup(copy_object, copy_offset);
  610.             if (page_exists = (copy_m != NULL)) {
  611.                 if (copy_m->busy) {
  612. #ifdef DOTHREADS
  613.                     int    wait_result;
  614.  
  615.                     /*
  616.                      *    If the page is being brought
  617.                      *    in, wait for it and then retry.
  618.                      */
  619.                     PAGE_ASSERT_WAIT(copy_m, !change_wiring);
  620.                     RELEASE_PAGE(m);
  621.                     copy_object->ref_count--;
  622.                     vm_object_unlock(copy_object);
  623.                     UNLOCK_THINGS;
  624.                     thread_block();
  625.                     wait_result = current_thread()->wait_result;
  626.                     vm_object_deallocate(first_object);
  627.                     if (wait_result != THREAD_AWAKENED)
  628.                         return(KERN_SUCCESS);
  629.                     goto RetryFault;
  630. #else
  631.                     /*
  632.                      *    If the page is being brought
  633.                      *    in, wait for it and then retry.
  634.                      */
  635.                     PAGE_ASSERT_WAIT(copy_m, !change_wiring);
  636.                     RELEASE_PAGE(m);
  637.                     copy_object->ref_count--;
  638.                     vm_object_unlock(copy_object);
  639.                     UNLOCK_THINGS;
  640.                     thread_block();
  641.                     vm_object_deallocate(first_object);
  642.                     goto RetryFault;
  643. #endif
  644.                 }
  645.             }
  646.  
  647.             /*
  648.              *    If the page is not in memory (in the object)
  649.              *    and the object has a pager, we have to check
  650.              *    if the pager has the data in secondary
  651.              *    storage.
  652.              */
  653.             if (!page_exists) {
  654.  
  655.                 /*
  656.                  *    If we don't allocate a (blank) page
  657.                  *    here... another thread could try
  658.                  *    to page it in, allocate a page, and
  659.                  *    then block on the busy page in its
  660.                  *    shadow (first_object).  Then we'd
  661.                  *    trip over the busy page after we
  662.                  *    found that the copy_object's pager
  663.                  *    doesn't have the page...
  664.                  */
  665.                 copy_m = vm_page_alloc(copy_object,
  666.                                 copy_offset);
  667.                 if (copy_m == NULL) {
  668.                     /*
  669.                      *    Wait for a page, then retry.
  670.                      */
  671.                     RELEASE_PAGE(m);
  672.                     copy_object->ref_count--;
  673.                     vm_object_unlock(copy_object);
  674.                     UNLOCK_AND_DEALLOCATE;
  675.                     VM_WAIT;
  676.                     goto RetryFault;
  677.                 }
  678.  
  679.                  if (copy_object->pager != NULL) {
  680.                     vm_object_unlock(object);
  681.                     vm_object_unlock(copy_object);
  682.                     UNLOCK_MAP;
  683.  
  684.                     page_exists = vm_pager_has_page(
  685.                             copy_object->pager,
  686.                             (copy_offset + copy_object->paging_offset));
  687.  
  688.                     vm_object_lock(copy_object);
  689.  
  690.                     /*
  691.                      * Since the map is unlocked, someone
  692.                      * else could have copied this object
  693.                      * and put a different copy_object
  694.                      * between the two.  Or, the last
  695.                      * reference to the copy-object (other
  696.                      * than the one we have) may have
  697.                      * disappeared - if that has happened,
  698.                      * we don't need to make the copy.
  699.                      */
  700.                     if (copy_object->shadow != object ||
  701.                         copy_object->ref_count == 1) {
  702.                         /*
  703.                          *    Gaah... start over!
  704.                          */
  705.                         FREE_PAGE(copy_m);
  706.                         vm_object_unlock(copy_object);
  707.                         vm_object_deallocate(copy_object);
  708.                             /* may block */
  709.                         vm_object_lock(object);
  710.                         goto RetryCopy;
  711.                     }
  712.                     vm_object_lock(object);
  713.  
  714.                     if (page_exists) {
  715.                         /*
  716.                          *    We didn't need the page
  717.                          */
  718.                         FREE_PAGE(copy_m);
  719.                     }
  720.                 }
  721.             }
  722.             if (!page_exists) {
  723.                 /*
  724.                  *    Must copy page into copy-object.
  725.                  */
  726.                 vm_page_copy(m, copy_m);
  727.                 copy_m->fake = FALSE;
  728.                 copy_m->absent = FALSE;
  729.  
  730.                 /*
  731.                  * Things to remember:
  732.                  * 1. The copied page must be marked 'dirty'
  733.                  *    so it will be paged out to the copy
  734.                  *    object.
  735.                  * 2. If the old page was in use by any users
  736.                  *    of the copy-object, it must be removed
  737.                  *    from all pmaps.  (We can't know which
  738.                  *    pmaps use it.)
  739.                  */
  740.                 vm_page_lock_queues();
  741.                 pmap_page_protect(VM_PAGE_TO_PHYS(old_m),
  742.                           VM_PROT_NONE);
  743.                 copy_m->clean = FALSE;
  744.                 vm_page_activate(copy_m);    /* XXX */
  745.                 vm_page_unlock_queues();
  746.  
  747.                 PAGE_WAKEUP(copy_m);
  748.             }
  749.             /*
  750.              *    The reference count on copy_object must be
  751.              *    at least 2: one for our extra reference,
  752.              *    and at least one from the outside world
  753.              *    (we checked that when we last locked
  754.              *    copy_object).
  755.              */
  756.             copy_object->ref_count--;
  757.             vm_object_unlock(copy_object);
  758.             m->copy_on_write = FALSE;
  759.         }
  760.     }
  761.  
  762.     if (m->active || m->inactive)
  763.         panic("vm_fault: active or inactive before retrying lookup");
  764.  
  765.     /*
  766.      *    We must verify that the maps have not changed
  767.      *    since our last lookup.
  768.      */
  769.  
  770.     if (!lookup_still_valid) {
  771.         vm_object_t    retry_object;
  772.         vm_offset_t    retry_offset;
  773.         vm_prot_t    retry_prot;
  774.  
  775.         /*
  776.          *    Since map entries may be pageable, make sure we can
  777.          *    take a page fault on them.
  778.          */
  779.         vm_object_unlock(object);
  780.  
  781.         /*
  782.          *    To avoid trying to write_lock the map while another
  783.          *    thread has it read_locked (in vm_map_pageable), we
  784.          *    do not try for write permission.  If the page is
  785.          *    still writable, we will get write permission.  If it
  786.          *    is not, or has been marked needs_copy, we enter the
  787.          *    mapping without write permission, and will merely
  788.          *    take another fault.
  789.          */
  790.         result = vm_map_lookup(&map, vaddr,
  791.                 fault_type & ~VM_PROT_WRITE, &entry,
  792.                 &retry_object, &retry_offset, &retry_prot,
  793.                 &wired, &su);
  794.  
  795.         vm_object_lock(object);
  796.  
  797.         /*
  798.          *    If we don't need the page any longer, put it on the
  799.          *    active list (the easiest thing to do here).  If no
  800.          *    one needs it, pageout will grab it eventually.
  801.          */
  802.  
  803.         if (result != KERN_SUCCESS) {
  804.             RELEASE_PAGE(m);
  805.             UNLOCK_AND_DEALLOCATE;
  806.             return(result);
  807.         }
  808.  
  809.         lookup_still_valid = TRUE;
  810.  
  811.         if ((retry_object != first_object) ||
  812.                 (retry_offset != first_offset)) {
  813.             RELEASE_PAGE(m);
  814.             UNLOCK_AND_DEALLOCATE;
  815.             goto RetryFault;
  816.         }
  817.  
  818.         /*
  819.          *    Check whether the protection has changed or the object
  820.          *    has been copied while we left the map unlocked.
  821.          *    Changing from read to write permission is OK - we leave
  822.          *    the page write-protected, and catch the write fault.
  823.          *    Changing from write to read permission means that we
  824.          *    can't mark the page write-enabled after all.
  825.          */
  826.         prot &= retry_prot;
  827.         if (m->copy_on_write)
  828.             prot &= ~VM_PROT_WRITE;
  829.     }
  830.  
  831.     /*
  832.      * (the various bits we're fiddling with here are locked by
  833.      * the object's lock)
  834.      */
  835.  
  836.     /* XXX This distorts the meaning of the copy_on_write bit */
  837.  
  838.     if (prot & VM_PROT_WRITE)
  839.         m->copy_on_write = FALSE;
  840.  
  841.     /*
  842.      *    It's critically important that a wired-down page be faulted
  843.      *    only once in each map for which it is wired.
  844.      */
  845.  
  846.     if (m->active || m->inactive)
  847.         panic("vm_fault: active or inactive before pmap_enter");
  848.  
  849.     vm_object_unlock(object);
  850.  
  851.     /*
  852.      *    Put this page into the physical map.
  853.      *    We had to do the unlock above because pmap_enter
  854.      *    may cause other faults.   We don't put the
  855.      *    page back on the active queue until later so
  856.      *    that the page-out daemon won't find us (yet).
  857.      */
  858.  
  859.     pmap_enter(map->pmap, vaddr, VM_PAGE_TO_PHYS(m), 
  860.             prot & ~(m->page_lock), wired);
  861.  
  862.     /*
  863.      *    If the page is not wired down, then put it where the
  864.      *    pageout daemon can find it.
  865.      */
  866.     vm_object_lock(object);
  867.     vm_page_lock_queues();
  868.     if (change_wiring) {
  869.         if (wired)
  870.             vm_page_wire(m);
  871.         else
  872.             vm_page_unwire(m);
  873.     }
  874.     else
  875.         vm_page_activate(m);
  876.     vm_page_unlock_queues();
  877.  
  878.     /*
  879.      *    Unlock everything, and return
  880.      */
  881.  
  882.     PAGE_WAKEUP(m);
  883.     UNLOCK_AND_DEALLOCATE;
  884.  
  885.     return(KERN_SUCCESS);
  886.  
  887. }
  888.  
  889. /*
  890.  *    vm_fault_wire:
  891.  *
  892.  *    Wire down a range of virtual addresses in a map.
  893.  */
  894. void vm_fault_wire(map, start, end)
  895.     vm_map_t    map;
  896.     vm_offset_t    start, end;
  897. {
  898.  
  899.     register vm_offset_t    va;
  900.     register pmap_t        pmap;
  901.  
  902.     pmap = vm_map_pmap(map);
  903.  
  904.     /*
  905.      *    Inform the physical mapping system that the
  906.      *    range of addresses may not fault, so that
  907.      *    page tables and such can be locked down as well.
  908.      */
  909.  
  910.     pmap_pageable(pmap, start, end, FALSE);
  911.  
  912.     /*
  913.      *    We simulate a fault to get the page and enter it
  914.      *    in the physical map.
  915.      */
  916.  
  917.     for (va = start; va < end; va += PAGE_SIZE) {
  918.         (void) vm_fault(map, va, VM_PROT_NONE, TRUE);
  919.     }
  920. }
  921.  
  922.  
  923. /*
  924.  *    vm_fault_unwire:
  925.  *
  926.  *    Unwire a range of virtual addresses in a map.
  927.  */
  928. void vm_fault_unwire(map, start, end)
  929.     vm_map_t    map;
  930.     vm_offset_t    start, end;
  931. {
  932.  
  933.     register vm_offset_t    va, pa;
  934.     register pmap_t        pmap;
  935.  
  936.     pmap = vm_map_pmap(map);
  937.  
  938.     /*
  939.      *    Since the pages are wired down, we must be able to
  940.      *    get their mappings from the physical map system.
  941.      */
  942.  
  943.     vm_page_lock_queues();
  944.  
  945.     for (va = start; va < end; va += PAGE_SIZE) {
  946.         pa = pmap_extract(pmap, va);
  947.         if (pa == (vm_offset_t) 0) {
  948.             panic("unwire: page not in pmap");
  949.         }
  950.         pmap_change_wiring(pmap, va, FALSE);
  951.         vm_page_unwire(PHYS_TO_VM_PAGE(pa));
  952.     }
  953.     vm_page_unlock_queues();
  954.  
  955.     /*
  956.      *    Inform the physical mapping system that the range
  957.      *    of addresses may fault, so that page tables and
  958.      *    such may be unwired themselves.
  959.      */
  960.  
  961.     pmap_pageable(pmap, start, end, TRUE);
  962.  
  963. }
  964.  
  965. /*
  966.  *    Routine:
  967.  *        vm_fault_copy_entry
  968.  *    Function:
  969.  *        Copy all of the pages from a wired-down map entry to another.
  970.  *
  971.  *    In/out conditions:
  972.  *        The source and destination maps must be locked for write.
  973.  *        The source map entry must be wired down (or be a sharing map
  974.  *        entry corresponding to a main map entry that is wired down).
  975.  */
  976.  
  977. void vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
  978.     vm_map_t    dst_map;
  979.     vm_map_t    src_map;
  980.     vm_map_entry_t    dst_entry;
  981.     vm_map_entry_t    src_entry;
  982. {
  983.  
  984.     vm_object_t    dst_object;
  985.     vm_object_t    src_object;
  986.     vm_offset_t    dst_offset;
  987.     vm_offset_t    src_offset;
  988.     vm_prot_t    prot;
  989.     vm_offset_t    vaddr;
  990.     vm_page_t    dst_m;
  991.     vm_page_t    src_m;
  992.  
  993. #ifdef    lint
  994.     src_map++;
  995. #endif    lint
  996.  
  997.     src_object = src_entry->object.vm_object;
  998.     src_offset = src_entry->offset;
  999.  
  1000.     /*
  1001.      *    Create the top-level object for the destination entry.
  1002.      *    (Doesn't actually shadow anything - we copy the pages
  1003.      *    directly.)
  1004.      */
  1005.     dst_object = vm_object_allocate(
  1006.             (vm_size_t) (dst_entry->end - dst_entry->start));
  1007.  
  1008.     dst_entry->object.vm_object = dst_object;
  1009.     dst_entry->offset = 0;
  1010.  
  1011.     prot  = dst_entry->max_protection;
  1012.  
  1013.     /*
  1014.      *    Loop through all of the pages in the entry's range, copying
  1015.      *    each one from the source object (it should be there) to the
  1016.      *    destination object.
  1017.      */
  1018.     for (vaddr = dst_entry->start, dst_offset = 0;
  1019.          vaddr < dst_entry->end;
  1020.          vaddr += PAGE_SIZE, dst_offset += PAGE_SIZE) {
  1021.  
  1022.         /*
  1023.          *    Allocate a page in the destination object
  1024.          */
  1025.         vm_object_lock(dst_object);
  1026.         do {
  1027.             dst_m = vm_page_alloc(dst_object, dst_offset);
  1028.             if (dst_m == NULL) {
  1029.                 vm_object_unlock(dst_object);
  1030.                 VM_WAIT;
  1031.                 vm_object_lock(dst_object);
  1032.             }
  1033.         } while (dst_m == NULL);
  1034.  
  1035.         /*
  1036.          *    Find the page in the source object, and copy it in.
  1037.          *    (Because the source is wired down, the page will be
  1038.          *    in memory.)
  1039.          */
  1040.         vm_object_lock(src_object);
  1041.         src_m = vm_page_lookup(src_object, dst_offset + src_offset);
  1042.         if (src_m == NULL)
  1043.             panic("vm_fault_copy_wired: page missing");
  1044.  
  1045.         vm_page_copy(src_m, dst_m);
  1046.  
  1047.         /*
  1048.          *    Enter it in the pmap...
  1049.          */
  1050.         vm_object_unlock(src_object);
  1051.         vm_object_unlock(dst_object);
  1052.  
  1053.         pmap_enter(dst_map->pmap, vaddr, VM_PAGE_TO_PHYS(dst_m),
  1054.                 prot, FALSE);
  1055.  
  1056.         /*
  1057.          *    Mark it no longer busy, and put it on the active list.
  1058.          */
  1059.         vm_object_lock(dst_object);
  1060.         vm_page_lock_queues();
  1061.         vm_page_activate(dst_m);
  1062.         vm_page_unlock_queues();
  1063.         PAGE_WAKEUP(dst_m);
  1064.         vm_object_unlock(dst_object);
  1065.     }
  1066.  
  1067. }
  1068.