Annotation of kernel/vm/vm_user.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/vm_user.c
                     33:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     34:  *
                     35:  *     Copyright (C) 1985, Avadis Tevanian, Jr., Michael Wayne Young
                     36:  *
                     37:  *     User-exported virtual memory functions.
                     38:  */
                     39: 
                     40: #import <mach_xp.h>
                     41: 
                     42: #import <sys/types.h>
                     43: 
                     44: #import <mach/vm_param.h>
                     45: #import <vm/vm_object.h>
                     46: #import <vm/vm_map.h>
                     47: #import <vm/vm_page.h>
                     48: #import <mach/vm_statistics.h>
                     49: #import <mach/vm_attributes.h>
                     50: 
                     51: #import <mach/boolean.h>
                     52: #import <mach/kern_return.h>
                     53: #import <kern/task.h>
                     54: 
                     55: #import <mach/mach_types.h>    /* to get vm_address_t */
                     56: 
                     57: #import <vm/vm_kern.h>
                     58: 
                     59: vm_statistics_data_t   vm_stat;
                     60: 
                     61: #if    MACH_XP
                     62: #else  MACH_XP
                     63: #import <kern/lock.h>
                     64: lock_data_t            vm_alloc_lock;
                     65: 
                     66: /*
                     67:  *     vm_user_init initializes the vm_alloc lock.  XXX
                     68:  */
                     69: void
                     70: vm_user_init()
                     71: {
                     72:        lock_init(&vm_alloc_lock, TRUE);
                     73: }
                     74: #endif MACH_XP
                     75: 
                     76: /*
                     77:  *     vm_allocate allocates virtual memory in the specified address
                     78:  *     map.  Newly allocated memory is not yet validated, but will be
                     79:  *     when page faults occur.
                     80:  */
                     81: kern_return_t vm_allocate_with_pager(map, addr, size, find_space, pager,
                     82:                pager_offset)
                     83:        register vm_map_t       map;
                     84:        register vm_offset_t    *addr;
                     85:        register vm_size_t      size;
                     86:        boolean_t               find_space;
                     87:        vm_pager_t              pager;
                     88:        vm_offset_t             pager_offset;
                     89: {
                     90:        register vm_object_t    object;
                     91:        register kern_return_t  result;
                     92: 
                     93:        if (map == VM_MAP_NULL)
                     94:                return(KERN_INVALID_ARGUMENT);
                     95: 
                     96:        *addr = trunc_page(*addr);
                     97:        size = round_page(size);
                     98: 
                     99: #if    MACH_XP
                    100:        if ((object = (vm_object_t) vm_object_enter(pager, size, FALSE))
                    101:                        == VM_OBJECT_NULL)
                    102:                return(KERN_INVALID_ARGUMENT);
                    103: #else  MACH_XP
                    104:        /*
                    105:         *      Lookup the pager/paging-space in the object cache.
                    106:         *      If it's not there, then create a new object and cache
                    107:         *      it.
                    108:         */
                    109:        lock_write(&vm_alloc_lock);
                    110:        object = vm_object_lookup(pager);
                    111:        vm_stat.lookups++;
                    112:        if (object == VM_OBJECT_NULL) {
                    113:                /*
                    114:                 *      Need a new object.
                    115:                 */
                    116:                object = vm_object_allocate(size);
                    117:                /*
                    118:                 *      Associate the object with the pager and
                    119:                 *      put it in the cache.
                    120:                 */
                    121:                if (pager != vm_pager_null) {
                    122:                        vm_object_setpager(object, pager,
                    123:                                (vm_offset_t) 0, TRUE);
                    124:                        vm_object_enter(object, pager);
                    125:                }
                    126:        }
                    127:        else {
                    128:                vm_stat.hits++;
                    129:        }
                    130:        lock_write_done(&vm_alloc_lock);
                    131:        object->internal = FALSE;
                    132: #endif MACH_XP
                    133: 
                    134:        if ((result = vm_map_find(map, object, pager_offset, addr, size,
                    135:                                find_space)) != KERN_SUCCESS)
                    136:                vm_object_deallocate(object);
                    137:        return(result);
                    138: }
                    139: 
                    140: /*
                    141:  *     vm_allocate allocates "zero fill" memory in the specfied
                    142:  *     map.
                    143:  */
                    144: kern_return_t vm_allocate(map, addr, size, anywhere)
                    145:        register vm_map_t       map;
                    146:        register vm_offset_t    *addr;
                    147:        register vm_size_t      size;
                    148:        boolean_t               anywhere;
                    149: {
                    150:        kern_return_t   result;
                    151: 
                    152:        if (map == VM_MAP_NULL)
                    153:                return(KERN_INVALID_ARGUMENT);
                    154:        if (size == 0) {
                    155:                *addr = 0;
                    156:                return(KERN_SUCCESS);
                    157:        }
                    158: 
                    159:        if (anywhere)
                    160:                *addr = vm_map_min(map);
                    161:        else
                    162:                *addr = trunc_page(*addr);
                    163:        size = round_page(size);
                    164: 
                    165:        result = vm_map_find(map, VM_OBJECT_NULL, (vm_offset_t) 0, addr,
                    166:                        size, anywhere);
                    167: 
                    168:        return(result);
                    169: }
                    170: 
                    171: /*
                    172:  *     vm_deallocate deallocates the specified range of addresses in the
                    173:  *     specified address map.
                    174:  */
                    175: kern_return_t vm_deallocate(map, start, size)
                    176:        register vm_map_t       map;
                    177:        vm_offset_t             start;
                    178:        vm_size_t               size;
                    179: {
                    180:        if (map == VM_MAP_NULL)
                    181:                return(KERN_INVALID_ARGUMENT);
                    182: 
                    183:        if (size == (vm_offset_t) 0)
                    184:                return(KERN_SUCCESS);
                    185: 
                    186:        return(vm_map_remove(map, trunc_page(start), round_page(start+size)));
                    187: }
                    188: 
                    189: kern_return_t vm_reallocate(map, start, size)
                    190:        register vm_map_t       map;
                    191:        vm_offset_t             start;
                    192:        vm_size_t               size;
                    193: {
                    194:        if (map == VM_MAP_NULL)
                    195:                return(KERN_INVALID_ARGUMENT);
                    196: 
                    197:        if (size == (vm_offset_t) 0)
                    198:                return(KERN_SUCCESS);
                    199: 
                    200:        return(vm_map_reallocate(
                    201:                        map, trunc_page(start), round_page(start+size)));
                    202: }
                    203: 
                    204: /*
                    205:  *     vm_inherit sets the inheritence of the specified range in the
                    206:  *     specified map.
                    207:  */
                    208: kern_return_t vm_inherit(map, start, size, new_inheritance)
                    209:        register vm_map_t       map;
                    210:        vm_offset_t             start;
                    211:        vm_size_t               size;
                    212:        vm_inherit_t            new_inheritance;
                    213: {
                    214:        if (map == VM_MAP_NULL)
                    215:                return(KERN_INVALID_ARGUMENT);
                    216: 
                    217:        return(vm_map_inherit(map, trunc_page(start), round_page(start+size), new_inheritance));
                    218: }
                    219: 
                    220: /*
                    221:  *     vm_protect sets the protection of the specified range in the
                    222:  *     specified map.
                    223:  */
                    224: 
                    225: kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
                    226:        register vm_map_t       map;
                    227:        vm_offset_t             start;
                    228:        vm_size_t               size;
                    229:        boolean_t               set_maximum;
                    230:        vm_prot_t               new_protection;
                    231: {
                    232:        if (map == VM_MAP_NULL)
                    233:                return(KERN_INVALID_ARGUMENT);
                    234: 
                    235:        return(vm_map_protect(map, trunc_page(start), round_page(start+size), new_protection, set_maximum));
                    236: }
                    237: 
                    238: kern_return_t vm_statistics(map, stat)
                    239:        vm_map_t        map;
                    240:        vm_statistics_data_t    *stat;
                    241: {
                    242:        if (map == VM_MAP_NULL)
                    243:                return(KERN_INVALID_ARGUMENT);
                    244: 
                    245:        vm_stat.pagesize = PAGE_SIZE;
                    246:        vm_stat.free_count = vm_page_free_count;
                    247:        vm_stat.active_count = vm_page_active_count;
                    248:        vm_stat.inactive_count = vm_page_inactive_count;
                    249:        vm_stat.wire_count = vm_page_wire_count;
                    250:        
                    251:        *stat = vm_stat;
                    252: 
                    253:        return(KERN_SUCCESS);
                    254: }
                    255: 
                    256: /*
                    257:  * Handle machine-specific attributes for a mapping, such
                    258:  * as cachability, migrability, etc.
                    259:  */
                    260: kern_return_t vm_machine_attribute(map, address, size, attribute, value)
                    261:        vm_map_t        map;
                    262:        vm_address_t    address;
                    263:        vm_size_t       size;
                    264:        vm_machine_attribute_t  attribute;
                    265:        vm_machine_attribute_val_t* value;              /* IN/OUT */
                    266: {
                    267:        extern kern_return_t    vm_map_machine_attribute();
                    268: 
                    269:        if (map == VM_MAP_NULL)
                    270:                return(KERN_INVALID_ARGUMENT);
                    271: 
                    272:        return vm_map_machine_attribute(map, address, size, attribute, value);
                    273: }
                    274: 
                    275: kern_return_t vm_read(map, address, size, data, data_size)
                    276:        vm_map_t        map;
                    277:        vm_address_t    address;
                    278:        vm_size_t       size;
                    279:        pointer_t       *data;
                    280:        vm_size_t       *data_size;
                    281: {
                    282:        kern_return_t   error;
                    283:        vm_offset_t     ipc_address;
                    284: 
                    285:        if ((round_page(address) != address) || (round_page(size) != size))
                    286:                return(KERN_INVALID_ARGUMENT);
                    287: 
                    288:        if ((error = vm_allocate(ipc_soft_map, &ipc_address, size, TRUE)) != KERN_SUCCESS) {
                    289:                printf("vm_read: kernel error %d\n", error);
                    290:                return(KERN_RESOURCE_SHORTAGE);
                    291:        }
                    292: 
                    293:        if ((error = vm_map_copy(ipc_soft_map, map, ipc_address, size, address, FALSE, FALSE)) == KERN_SUCCESS) {
                    294:                *data = ipc_address;
                    295:                *data_size = size;
                    296:        }
                    297:        else
                    298:                (void) vm_deallocate(ipc_soft_map, ipc_address, size);
                    299:        return(error);
                    300: }
                    301: 
                    302: kern_return_t vm_write(map, address, data, size)
                    303:        vm_map_t        map;
                    304:        vm_address_t    address;
                    305:        pointer_t       data;
                    306:        vm_size_t       size;
                    307: {
                    308:        if ((round_page(address) != address) || (round_page(size) != size))
                    309:                return(KERN_INVALID_ARGUMENT);
                    310: 
                    311:        return(vm_map_copy(map, ipc_soft_map, address, size, data, FALSE, TRUE));
                    312: }
                    313: 
                    314: kern_return_t vm_copy(map, source_address, size, dest_address)
                    315:        vm_map_t        map;
                    316:        vm_address_t    source_address;
                    317:        vm_size_t       size;
                    318:        vm_address_t    dest_address;
                    319: {
                    320:        if ( (round_page(source_address) != source_address) || (round_page(dest_address) != dest_address)
                    321:             || (round_page(size) != size) )
                    322:                return(KERN_INVALID_ARGUMENT);
                    323: 
                    324:        return(vm_map_copy(map, map, dest_address, size, source_address, FALSE, FALSE));
                    325: }
                    326: 
                    327: 
                    328: 
                    329: /*
                    330:  *     Specify that the range of the virtual address space
                    331:  *     of the target task must not cause page faults for
                    332:  *     the indicated accesses.
                    333:  *
                    334:  *     [ To unwire the pages, specify VM_PROT_NONE. ]
                    335:  */
                    336: kern_return_t
                    337: vm_wire(
                    338:        host_t                  host,
                    339:        register vm_map_t       map,
                    340:        vm_offset_t             start,
                    341:        vm_size_t               size,
                    342:        vm_prot_t               access)
                    343: {
                    344:        kern_return_t           rc;
                    345: 
                    346:        if (host == HOST_NULL)
                    347:                return KERN_INVALID_HOST;
                    348: 
                    349:        if (map == VM_MAP_NULL)
                    350:                return KERN_INVALID_TASK;
                    351: 
                    352:        if (access & ~VM_PROT_ALL)
                    353:                return KERN_INVALID_ARGUMENT;
                    354: 
                    355:        if (access != VM_PROT_NONE) {
                    356:                rc = vm_map_pageable(map, trunc_page(start),
                    357:                                 round_page(start+size), FALSE);
                    358:        } else {
                    359:                rc = vm_map_pageable(map, trunc_page(start),
                    360:                                   round_page(start+size), TRUE);
                    361:        }
                    362:        return rc;
                    363: }

unix.superglobalmegacorp.com

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