Annotation of kernel/vm/vm_user.c, revision 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.