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