Annotation of XNU/osfmk/i386/read_fault.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: 
                     53: #include <kern/thread.h>
                     54: #include <vm/vm_fault.h>
                     55: #include <mach/kern_return.h>
                     56: #include <mach/vm_behavior.h>
                     57: #include <vm/vm_map.h>
                     58: #include <vm/vm_object.h>
                     59: #include <vm/vm_page.h>
                     60: #include <vm/pmap.h>
                     61: 
                     62: #include <i386/intel_read_fault.h>
                     63: 
                     64: #include <kern/macro_help.h>
                     65: 
                     66: /*
                     67:  *     Expansion of vm_fault for read fault in kernel mode.
                     68:  *     Must enter the mapping as writable, since the i386
                     69:  *     (and i860 in i386 compatability mode) ignores write
                     70:  *     protection in kernel mode.
                     71:  *
                     72:  *     Note that this routine can be called for pmap's other
                     73:  *     than the kernel_pmap, in which case it just enters
                     74:  *     a read-only mapping.  (See e.g. kernel_trap().)
                     75:  */
                     76: kern_return_t
                     77: intel_read_fault(
                     78:        vm_map_t        map,
                     79:        vm_offset_t     vaddr)
                     80: {
                     81:        vm_map_version_t        version;        /* Map version for
                     82:                                                   verification */
                     83:        vm_object_t             object;         /* Top-level object */
                     84:        vm_offset_t             offset;         /* Top-level offset */
                     85:        vm_prot_t               prot;           /* Protection for mapping */
                     86:        vm_behavior_t           behavior;       /* Expected paging behavior */
                     87:        vm_offset_t             lo_offset, hi_offset;
                     88:        vm_page_t               result_page;    /* Result of vm_fault_page */
                     89:        vm_page_t               top_page;       /* Placeholder page */
                     90:        boolean_t               wired;          /* Is map region wired? */
                     91:        kern_return_t           result;
                     92:        register vm_page_t      m;
                     93: 
                     94:     RetryFault:
                     95: 
                     96:        /*
                     97:         *      Find the backing store object and offset into it
                     98:         *      to begin search.
                     99:         */
                    100:        vm_map_lock_read(map);
                    101:        result = vm_map_lookup_locked(&map, vaddr, VM_PROT_READ, &version,
                    102:                                      &object, &offset, &prot, &wired,
                    103:                                      &behavior, &lo_offset, &hi_offset);
                    104:        vm_map_unlock_read(map);
                    105: 
                    106:        if (result != KERN_SUCCESS)
                    107:            return (result);
                    108: 
                    109:        /*
                    110:         *      Make a reference to this object to prevent its
                    111:         *      disposal while we are playing with it.
                    112:         */
                    113:        assert(object->ref_count > 0);
                    114:        object->ref_count++;
                    115:        vm_object_res_reference(object);
                    116:        vm_object_paging_begin(object);
                    117: 
                    118:        result = vm_fault_page(object, offset, VM_PROT_READ, FALSE,
                    119:                               THREAD_ABORTSAFE,
                    120:                               lo_offset, hi_offset, behavior,
                    121:                               &prot, &result_page, &top_page, (int *)0,
                    122:                               0, map->no_zero_fill, FALSE);
                    123: 
                    124:        if (result != VM_FAULT_SUCCESS) {
                    125:            vm_object_deallocate(object);
                    126: 
                    127:            switch (result) {
                    128:                case VM_FAULT_RETRY:
                    129:                    goto RetryFault;
                    130:                case VM_FAULT_INTERRUPTED:
                    131:                    return (KERN_SUCCESS);
                    132:                case VM_FAULT_MEMORY_SHORTAGE:
                    133:                    VM_PAGE_WAIT();
                    134:                    goto RetryFault;
                    135:                case VM_FAULT_FICTITIOUS_SHORTAGE:
                    136:                    vm_page_more_fictitious();
                    137:                    goto RetryFault;
                    138:                case VM_FAULT_MEMORY_ERROR:
                    139:                    return (KERN_MEMORY_ERROR);
                    140:            }
                    141:        }
                    142: 
                    143:        m = result_page;
                    144: 
                    145:        /*
                    146:         *      How to clean up the result of vm_fault_page.  This
                    147:         *      happens whether the mapping is entered or not.
                    148:         */
                    149: 
                    150: #define UNLOCK_AND_DEALLOCATE                          \
                    151:        MACRO_BEGIN                                     \
                    152:        vm_fault_cleanup(m->object, top_page);          \
                    153:        vm_object_deallocate(object);                   \
                    154:        MACRO_END
                    155: 
                    156:        /*
                    157:         *      What to do with the resulting page from vm_fault_page
                    158:         *      if it doesn't get entered into the physical map:
                    159:         */
                    160: 
                    161: #define RELEASE_PAGE(m)                                        \
                    162:        MACRO_BEGIN                                     \
                    163:        PAGE_WAKEUP_DONE(m);                            \
                    164:        vm_page_lock_queues();                          \
                    165:        if (!m->active && !m->inactive)                 \
                    166:                vm_page_activate(m);                    \
                    167:        vm_page_unlock_queues();                        \
                    168:        MACRO_END
                    169: 
                    170:        /*
                    171:         *      We must verify that the maps have not changed.
                    172:         */
                    173:        vm_object_unlock(m->object);
                    174:        while (!vm_map_verify(map, &version)) {
                    175:            vm_object_t         retry_object;
                    176:            vm_offset_t         retry_offset;
                    177:            vm_prot_t           retry_prot;
                    178: 
                    179:            vm_map_lock_read(map);
                    180:            result = vm_map_lookup_locked(&map, vaddr, VM_PROT_READ, &version,
                    181:                                &retry_object, &retry_offset, &retry_prot,
                    182:                                &wired, &behavior, &lo_offset, &hi_offset);
                    183:            vm_map_unlock_read(map);
                    184: 
                    185:            if (result != KERN_SUCCESS) {
                    186:                vm_object_lock(m->object);
                    187:                RELEASE_PAGE(m);
                    188:                UNLOCK_AND_DEALLOCATE;
                    189:                return (result);
                    190:            }
                    191: 
                    192:            vm_object_unlock(retry_object);
                    193: 
                    194:            if (retry_object != object || retry_offset != offset) {
                    195:                vm_object_lock(m->object);
                    196:                RELEASE_PAGE(m);
                    197:                UNLOCK_AND_DEALLOCATE;
                    198:                goto RetryFault;
                    199:            }
                    200:        }
                    201: 
                    202:        /*
                    203:         *      Put the page in the physical map.
                    204:         */
                    205:        PMAP_ENTER(map->pmap, vaddr, m, VM_PROT_READ, wired);
                    206: 
                    207:        vm_object_lock(m->object);
                    208:        vm_page_lock_queues();
                    209:        if (!m->active && !m->inactive)
                    210:                vm_page_activate(m);
                    211:        m->reference = TRUE;
                    212:        vm_page_unlock_queues();
                    213: 
                    214:        vm_map_verify_done(map, &version);
                    215:        PAGE_WAKEUP_DONE(m);
                    216: 
                    217:        UNLOCK_AND_DEALLOCATE;
                    218: 
                    219: #undef UNLOCK_AND_DEALLOCATE
                    220: #undef RELEASE_PAGE
                    221: 
                    222:        return (KERN_SUCCESS);
                    223: }
                    224: 

unix.superglobalmegacorp.com

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