Annotation of OSKit-Mach/vm/vm_user.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File:   vm/vm_user.c
        !            28:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
        !            29:  * 
        !            30:  *     User-exported virtual memory functions.
        !            31:  */
        !            32: 
        !            33: #include <mach/boolean.h>
        !            34: #include <mach/kern_return.h>
        !            35: #include <mach/mach_types.h>   /* to get vm_address_t */
        !            36: #include <mach/memory_object.h>
        !            37: #include <mach/std_types.h>    /* to get pointer_t */
        !            38: #include <mach/vm_attributes.h>
        !            39: #include <mach/vm_param.h>
        !            40: #include <mach/vm_statistics.h>
        !            41: #include <kern/host.h>
        !            42: #include <kern/task.h>
        !            43: #include <vm/vm_fault.h>
        !            44: #include <vm/vm_map.h>
        !            45: #include <vm/vm_object.h>
        !            46: #include <vm/vm_page.h>
        !            47: 
        !            48: 
        !            49: 
        !            50: vm_statistics_data_t   vm_stat;
        !            51: 
        !            52: /*
        !            53:  *     vm_allocate allocates "zero fill" memory in the specfied
        !            54:  *     map.
        !            55:  */
        !            56: kern_return_t vm_allocate(map, addr, size, anywhere)
        !            57:        register vm_map_t       map;
        !            58:        register vm_offset_t    *addr;
        !            59:        register vm_size_t      size;
        !            60:        boolean_t               anywhere;
        !            61: {
        !            62:        kern_return_t   result;
        !            63: 
        !            64:        if (map == VM_MAP_NULL)
        !            65:                return(KERN_INVALID_ARGUMENT);
        !            66:        if (size == 0) {
        !            67:                *addr = 0;
        !            68:                return(KERN_SUCCESS);
        !            69:        }
        !            70: 
        !            71:        if (anywhere)
        !            72:                *addr = vm_map_min(map);
        !            73:        else
        !            74:                *addr = trunc_page(*addr);
        !            75:        size = round_page(size);
        !            76: 
        !            77:        result = vm_map_enter(
        !            78:                        map,
        !            79:                        addr,
        !            80:                        size,
        !            81:                        (vm_offset_t)0,
        !            82:                        anywhere,
        !            83:                        VM_OBJECT_NULL,
        !            84:                        (vm_offset_t)0,
        !            85:                        FALSE,
        !            86:                        VM_PROT_DEFAULT,
        !            87:                        VM_PROT_ALL,
        !            88:                        VM_INHERIT_DEFAULT);
        !            89: 
        !            90:        return(result);
        !            91: }
        !            92: 
        !            93: /*
        !            94:  *     vm_deallocate deallocates the specified range of addresses in the
        !            95:  *     specified address map.
        !            96:  */
        !            97: kern_return_t vm_deallocate(map, start, size)
        !            98:        register vm_map_t       map;
        !            99:        vm_offset_t             start;
        !           100:        vm_size_t               size;
        !           101: {
        !           102:        if (map == VM_MAP_NULL)
        !           103:                return(KERN_INVALID_ARGUMENT);
        !           104: 
        !           105:        if (size == (vm_offset_t) 0)
        !           106:                return(KERN_SUCCESS);
        !           107: 
        !           108:        return(vm_map_remove(map, trunc_page(start), round_page(start+size)));
        !           109: }
        !           110: 
        !           111: /*
        !           112:  *     vm_inherit sets the inheritance of the specified range in the
        !           113:  *     specified map.
        !           114:  */
        !           115: kern_return_t vm_inherit(map, start, size, new_inheritance)
        !           116:        register vm_map_t       map;
        !           117:        vm_offset_t             start;
        !           118:        vm_size_t               size;
        !           119:        vm_inherit_t            new_inheritance;
        !           120: {
        !           121:        if (map == VM_MAP_NULL)
        !           122:                return(KERN_INVALID_ARGUMENT);
        !           123: 
        !           124:         switch (new_inheritance) {
        !           125:         case VM_INHERIT_NONE:
        !           126:         case VM_INHERIT_COPY:
        !           127:         case VM_INHERIT_SHARE:
        !           128:                 break;
        !           129:         default:
        !           130:                 return(KERN_INVALID_ARGUMENT);
        !           131:         }
        !           132: 
        !           133:        /*Check if range includes projected buffer;
        !           134:          user is not allowed direct manipulation in that case*/
        !           135:        if (projected_buffer_in_range(map, start, start+size))
        !           136:                return(KERN_INVALID_ARGUMENT);
        !           137: 
        !           138:        return(vm_map_inherit(map,
        !           139:                              trunc_page(start),
        !           140:                              round_page(start+size),
        !           141:                              new_inheritance));
        !           142: }
        !           143: 
        !           144: /*
        !           145:  *     vm_protect sets the protection of the specified range in the
        !           146:  *     specified map.
        !           147:  */
        !           148: 
        !           149: kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
        !           150:        register vm_map_t       map;
        !           151:        vm_offset_t             start;
        !           152:        vm_size_t               size;
        !           153:        boolean_t               set_maximum;
        !           154:        vm_prot_t               new_protection;
        !           155: {
        !           156:        if ((map == VM_MAP_NULL) || 
        !           157:                (new_protection & ~(VM_PROT_ALL|VM_PROT_NOTIFY)))
        !           158:                return(KERN_INVALID_ARGUMENT);
        !           159: 
        !           160:        /*Check if range includes projected buffer;
        !           161:          user is not allowed direct manipulation in that case*/
        !           162:        if (projected_buffer_in_range(map, start, start+size))
        !           163:                return(KERN_INVALID_ARGUMENT);
        !           164: 
        !           165:        return(vm_map_protect(map,
        !           166:                              trunc_page(start),
        !           167:                              round_page(start+size),
        !           168:                              new_protection,
        !           169:                              set_maximum));
        !           170: }
        !           171: 
        !           172: kern_return_t vm_statistics(map, stat)
        !           173:        vm_map_t        map;
        !           174:        vm_statistics_data_t    *stat;
        !           175: {
        !           176:        if (map == VM_MAP_NULL)
        !           177:                return(KERN_INVALID_ARGUMENT);
        !           178: 
        !           179:        *stat = vm_stat;
        !           180: 
        !           181:        stat->pagesize = PAGE_SIZE;
        !           182:        stat->free_count = vm_page_free_count;
        !           183:        stat->active_count = vm_page_active_count;
        !           184:        stat->inactive_count = vm_page_inactive_count;
        !           185:        stat->wire_count = vm_page_wire_count;
        !           186: 
        !           187:        return(KERN_SUCCESS);
        !           188: }
        !           189: 
        !           190: /*
        !           191:  * Handle machine-specific attributes for a mapping, such
        !           192:  * as cachability, migrability, etc.
        !           193:  */
        !           194: kern_return_t vm_machine_attribute(map, address, size, attribute, value)
        !           195:        vm_map_t        map;
        !           196:        vm_address_t    address;
        !           197:        vm_size_t       size;
        !           198:        vm_machine_attribute_t  attribute;
        !           199:        vm_machine_attribute_val_t* value;              /* IN/OUT */
        !           200: {
        !           201:        extern kern_return_t    vm_map_machine_attribute();
        !           202: 
        !           203:        if (map == VM_MAP_NULL)
        !           204:                return(KERN_INVALID_ARGUMENT);
        !           205: 
        !           206:        /*Check if range includes projected buffer;
        !           207:          user is not allowed direct manipulation in that case*/
        !           208:        if (projected_buffer_in_range(map, address, address+size))
        !           209:                return(KERN_INVALID_ARGUMENT);
        !           210: 
        !           211:        return vm_map_machine_attribute(map, address, size, attribute, value);
        !           212: }
        !           213: 
        !           214: kern_return_t vm_read(map, address, size, data, data_size)
        !           215:        vm_map_t        map;
        !           216:        vm_address_t    address;
        !           217:        vm_size_t       size;
        !           218:        pointer_t       *data;
        !           219:        vm_size_t       *data_size;
        !           220: {
        !           221:        kern_return_t   error;
        !           222:        vm_map_copy_t   ipc_address;
        !           223: 
        !           224:        if (map == VM_MAP_NULL)
        !           225:                return(KERN_INVALID_ARGUMENT);
        !           226: 
        !           227:        if ((error = vm_map_copyin(map,
        !           228:                                address,
        !           229:                                size,
        !           230:                                FALSE,  /* src_destroy */
        !           231:                                &ipc_address)) == KERN_SUCCESS) {
        !           232:                *data = (pointer_t) ipc_address;
        !           233:                *data_size = size;
        !           234:        }
        !           235:        return(error);
        !           236: }
        !           237: 
        !           238: kern_return_t vm_write(map, address, data, size)
        !           239:        vm_map_t        map;
        !           240:        vm_address_t    address;
        !           241:        pointer_t       data;
        !           242:        vm_size_t       size;
        !           243: {
        !           244:        if (map == VM_MAP_NULL)
        !           245:                return KERN_INVALID_ARGUMENT;
        !           246: 
        !           247:        return vm_map_copy_overwrite(map, address, (vm_map_copy_t) data,
        !           248:                                     FALSE /* interruptible XXX */);
        !           249: }
        !           250: 
        !           251: kern_return_t vm_copy(map, source_address, size, dest_address)
        !           252:        vm_map_t        map;
        !           253:        vm_address_t    source_address;
        !           254:        vm_size_t       size;
        !           255:        vm_address_t    dest_address;
        !           256: {
        !           257:        vm_map_copy_t copy;
        !           258:        kern_return_t kr;
        !           259: 
        !           260:        if (map == VM_MAP_NULL)
        !           261:                return KERN_INVALID_ARGUMENT;
        !           262: 
        !           263:        kr = vm_map_copyin(map, source_address, size,
        !           264:                           FALSE, &copy);
        !           265:        if (kr != KERN_SUCCESS)
        !           266:                return kr;
        !           267: 
        !           268:        kr = vm_map_copy_overwrite(map, dest_address, copy,
        !           269:                                   FALSE /* interruptible XXX */);
        !           270:        if (kr != KERN_SUCCESS) {
        !           271:                vm_map_copy_discard(copy);
        !           272:                return kr;
        !           273:        }
        !           274: 
        !           275:        return KERN_SUCCESS;
        !           276: }
        !           277: 
        !           278: /*
        !           279:  *     Routine:        vm_map
        !           280:  */
        !           281: kern_return_t vm_map(
        !           282:                target_map,
        !           283:                address, size, mask, anywhere,
        !           284:                memory_object, offset,
        !           285:                copy,
        !           286:                cur_protection, max_protection, inheritance)
        !           287:        vm_map_t        target_map;
        !           288:        vm_offset_t     *address;
        !           289:        vm_size_t       size;
        !           290:        vm_offset_t     mask;
        !           291:        boolean_t       anywhere;
        !           292:        ipc_port_t      memory_object;
        !           293:        vm_offset_t     offset;
        !           294:        boolean_t       copy;
        !           295:        vm_prot_t       cur_protection;
        !           296:        vm_prot_t       max_protection;
        !           297:        vm_inherit_t    inheritance;
        !           298: {
        !           299:        register
        !           300:        vm_object_t     object;
        !           301:        register
        !           302:        kern_return_t   result;
        !           303: 
        !           304:        if ((target_map == VM_MAP_NULL) ||
        !           305:            (cur_protection & ~VM_PROT_ALL) ||
        !           306:            (max_protection & ~VM_PROT_ALL))
        !           307:                return(KERN_INVALID_ARGUMENT);
        !           308: 
        !           309:         switch (inheritance) {
        !           310:         case VM_INHERIT_NONE:
        !           311:         case VM_INHERIT_COPY:
        !           312:         case VM_INHERIT_SHARE:
        !           313:                 break;
        !           314:         default:
        !           315:                 return(KERN_INVALID_ARGUMENT);
        !           316:         }
        !           317: 
        !           318:        *address = trunc_page(*address);
        !           319:        size = round_page(size);
        !           320: 
        !           321:        if (!IP_VALID(memory_object)) {
        !           322:                object = VM_OBJECT_NULL;
        !           323:                offset = 0;
        !           324:                copy = FALSE;
        !           325:        } else if ((object = vm_object_enter(memory_object, size, FALSE))
        !           326:                        == VM_OBJECT_NULL)
        !           327:                return(KERN_INVALID_ARGUMENT);
        !           328: 
        !           329:        /*
        !           330:         *      Perform the copy if requested
        !           331:         */
        !           332: 
        !           333:        if (copy) {
        !           334:                vm_object_t     new_object;
        !           335:                vm_offset_t     new_offset;
        !           336: 
        !           337:                result = vm_object_copy_strategically(object, offset, size,
        !           338:                                &new_object, &new_offset,
        !           339:                                &copy);
        !           340: 
        !           341:                /*
        !           342:                 *      Throw away the reference to the
        !           343:                 *      original object, as it won't be mapped.
        !           344:                 */
        !           345: 
        !           346:                vm_object_deallocate(object);
        !           347: 
        !           348:                if (result != KERN_SUCCESS)
        !           349:                        return (result);
        !           350: 
        !           351:                object = new_object;
        !           352:                offset = new_offset;
        !           353:        }
        !           354: 
        !           355:        if ((result = vm_map_enter(target_map,
        !           356:                                address, size, mask, anywhere,
        !           357:                                object, offset,
        !           358:                                copy,
        !           359:                                cur_protection, max_protection, inheritance
        !           360:                                )) != KERN_SUCCESS)
        !           361:                vm_object_deallocate(object);
        !           362:        return(result);
        !           363: }
        !           364: 
        !           365: /*
        !           366:  *     Specify that the range of the virtual address space
        !           367:  *     of the target task must not cause page faults for
        !           368:  *     the indicated accesses.
        !           369:  *
        !           370:  *     [ To unwire the pages, specify VM_PROT_NONE. ]
        !           371:  */
        !           372: kern_return_t vm_wire(host, map, start, size, access)
        !           373:        host_t                  host;
        !           374:        register vm_map_t       map;
        !           375:        vm_offset_t             start;
        !           376:        vm_size_t               size;
        !           377:        vm_prot_t               access;
        !           378: {
        !           379:        if (host == HOST_NULL)
        !           380:                return KERN_INVALID_HOST;
        !           381: 
        !           382:        if (map == VM_MAP_NULL)
        !           383:                return KERN_INVALID_TASK;
        !           384: 
        !           385:        if (access & ~VM_PROT_ALL)
        !           386:                return KERN_INVALID_ARGUMENT;
        !           387: 
        !           388:        /*Check if range includes projected buffer;
        !           389:          user is not allowed direct manipulation in that case*/
        !           390:        if (projected_buffer_in_range(map, start, start+size))
        !           391:                return(KERN_INVALID_ARGUMENT);
        !           392: 
        !           393:        return vm_map_pageable_user(map,
        !           394:                                    trunc_page(start),
        !           395:                                    round_page(start+size),
        !           396:                                    access);
        !           397: }

unix.superglobalmegacorp.com

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