|
|
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,1989,1988,1987 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: /* ! 54: * File: vm/vm_map.h ! 55: * Author: Avadis Tevanian, Jr., Michael Wayne Young ! 56: * Date: 1985 ! 57: * ! 58: * Virtual memory map module definitions. ! 59: * ! 60: * Contributors: ! 61: * avie, dlb, mwyoung ! 62: */ ! 63: ! 64: #ifndef _VM_VM_MAP_H_ ! 65: #define _VM_VM_MAP_H_ ! 66: ! 67: #include <mach/mach_types.h> ! 68: #include <mach/kern_return.h> ! 69: #include <mach/boolean.h> ! 70: #include <mach/vm_types.h> ! 71: #include <mach/vm_prot.h> ! 72: #include <mach/vm_inherit.h> ! 73: #include <mach/vm_behavior.h> ! 74: #include <vm/pmap.h> ! 75: ! 76: typedef struct vm_map_entry *vm_map_entry_t; ! 77: ! 78: #ifndef MACH_KERNEL_PRIVATE ! 79: ! 80: struct vm_map_entry {}; ! 81: ! 82: extern void vm_map_reference(vm_map_t map); ! 83: extern vm_map_t current_map(void); ! 84: ! 85: #else /* MACH_KERNEL_PRIVATE */ ! 86: ! 87: #include <dipc.h> ! 88: #include <cpus.h> ! 89: #include <task_swapper.h> ! 90: #include <mach_assert.h> ! 91: #include <vm/vm_object.h> ! 92: #include <vm/vm_page.h> ! 93: #include <kern/lock.h> ! 94: #include <kern/zalloc.h> ! 95: #include <kern/macro_help.h> ! 96: #include <kern/thread_act.h> ! 97: ! 98: #define current_map_fast() (current_act_fast()->map) ! 99: #define current_map() (current_map_fast()) ! 100: ! 101: /* ! 102: * Types defined: ! 103: * ! 104: * vm_map_t the high-level address map data structure. ! 105: * vm_map_entry_t an entry in an address map. ! 106: * vm_map_version_t a timestamp of a map, for use with vm_map_lookup ! 107: * vm_map_copy_t represents memory copied from an address map, ! 108: * used for inter-map copy operations ! 109: */ ! 110: ! 111: /* ! 112: * Type: vm_map_object_t [internal use only] ! 113: * ! 114: * Description: ! 115: * The target of an address mapping, either a virtual ! 116: * memory object or a sub map (of the kernel map). ! 117: */ ! 118: typedef union vm_map_object { ! 119: struct vm_object *vm_object; /* object object */ ! 120: struct vm_map *sub_map; /* belongs to another map */ ! 121: } vm_map_object_t; ! 122: ! 123: #define named_entry_lock_init(object) mutex_init(&(object)->Lock, ETAP_VM_OBJ) ! 124: #define named_entry_lock(object) mutex_lock(&(object)->Lock) ! 125: #define named_entry_unlock(object) mutex_unlock(&(object)->Lock) ! 126: ! 127: /* ! 128: * Type: vm_named_entry_t [internal use only] ! 129: * ! 130: * Description: ! 131: * Description of a mapping to a memory cache object. ! 132: * ! 133: * Implementation: ! 134: * While the handle to this object is used as a means to map ! 135: * and pass around the right to map regions backed by pagers ! 136: * of all sorts, the named_entry itself is only manipulated ! 137: * by the kernel. Named entries hold information on the ! 138: * right to map a region of a cached object. Namely, ! 139: * the target cache object, the beginning and ending of the ! 140: * region to be mapped, and the permissions, (read, write) ! 141: * with which it can be mapped. ! 142: * ! 143: */ ! 144: ! 145: struct vm_named_entry { ! 146: decl_mutex_data(, Lock) /* Synchronization */ ! 147: vm_object_t object; /* object I point to */ ! 148: vm_offset_t offset; /* offset into object */ ! 149: union { ! 150: ipc_port_t pager; /* amo pager port */ ! 151: vm_map_t map; /* map backing submap */ ! 152: } backing; ! 153: unsigned int size; /* size of region */ ! 154: unsigned int protection; /* access permissions */ ! 155: int ref_count; /* Number of references */ ! 156: unsigned int ! 157: /* boolean_t */ internal:1, /* is an internal object */ ! 158: /* boolean_t */ is_sub_map:1; /* is object is a submap? */ ! 159: }; ! 160: ! 161: typedef struct vm_named_entry *vm_named_entry_t; ! 162: ! 163: ! 164: /* ! 165: * Type: vm_map_entry_t [internal use only] ! 166: * ! 167: * Description: ! 168: * A single mapping within an address map. ! 169: * ! 170: * Implementation: ! 171: * Address map entries consist of start and end addresses, ! 172: * a VM object (or sub map) and offset into that object, ! 173: * and user-exported inheritance and protection information. ! 174: * Control information for virtual copy operations is also ! 175: * stored in the address map entry. ! 176: */ ! 177: struct vm_map_links { ! 178: struct vm_map_entry *prev; /* previous entry */ ! 179: struct vm_map_entry *next; /* next entry */ ! 180: vm_offset_t start; /* start address */ ! 181: vm_offset_t end; /* end address */ ! 182: }; ! 183: ! 184: struct vm_map_entry { ! 185: struct vm_map_links links; /* links to other entries */ ! 186: #define vme_prev links.prev ! 187: #define vme_next links.next ! 188: #define vme_start links.start ! 189: #define vme_end links.end ! 190: union vm_map_object object; /* object I point to */ ! 191: vm_offset_t offset; /* offset into object */ ! 192: unsigned int ! 193: /* boolean_t */ is_shared:1, /* region is shared */ ! 194: /* boolean_t */ is_sub_map:1, /* Is "object" a submap? */ ! 195: /* boolean_t */ in_transition:1, /* Entry being changed */ ! 196: /* boolean_t */ needs_wakeup:1, /* Waiters on in_transition */ ! 197: /* vm_behavior_t */ behavior:2, /* user paging behavior hint */ ! 198: /* behavior is not defined for submap type */ ! 199: /* boolean_t */ needs_copy:1, /* object need to be copied? */ ! 200: /* Only in task maps: */ ! 201: /* vm_prot_t */ protection:3, /* protection code */ ! 202: /* vm_prot_t */ max_protection:3,/* maximum protection */ ! 203: /* vm_inherit_t */ inheritance:2, /* inheritance */ ! 204: /* pad */ pad1:1, ! 205: /* user alias */ alias:8; ! 206: unsigned short wired_count; /* can be paged if = 0 */ ! 207: unsigned short user_wired_count; /* for vm_wire */ ! 208: }; ! 209: ! 210: /* ! 211: * wired_counts are unsigned short. This value is used to safeguard ! 212: * against any mishaps due to runaway user programs. ! 213: */ ! 214: #define MAX_WIRE_COUNT 65535 ! 215: ! 216: ! 217: ! 218: /* ! 219: * Type: struct vm_map_header ! 220: * ! 221: * Description: ! 222: * Header for a vm_map and a vm_map_copy. ! 223: */ ! 224: struct vm_map_header { ! 225: struct vm_map_links links; /* first, last, min, max */ ! 226: int nentries; /* Number of entries */ ! 227: boolean_t entries_pageable; ! 228: /* are map entries pageable? */ ! 229: }; ! 230: ! 231: /* ! 232: * Type: vm_map_t [exported; contents invisible] ! 233: * ! 234: * Description: ! 235: * An address map -- a directory relating valid ! 236: * regions of a task's address space to the corresponding ! 237: * virtual memory objects. ! 238: * ! 239: * Implementation: ! 240: * Maps are doubly-linked lists of map entries, sorted ! 241: * by address. One hint is used to start ! 242: * searches again from the last successful search, ! 243: * insertion, or removal. Another hint is used to ! 244: * quickly find free space. ! 245: */ ! 246: struct vm_map { ! 247: lock_t lock; /* uni- and smp-lock */ ! 248: struct vm_map_header hdr; /* Map entry header */ ! 249: #define min_offset hdr.links.start /* start of range */ ! 250: #define max_offset hdr.links.end /* end of range */ ! 251: pmap_t pmap; /* Physical map */ ! 252: vm_size_t size; /* virtual size */ ! 253: int ref_count; /* Reference count */ ! 254: #if TASK_SWAPPER ! 255: int res_count; /* Residence count (swap) */ ! 256: int sw_state; /* Swap state */ ! 257: #endif /* TASK_SWAPPER */ ! 258: decl_mutex_data(, s_lock) /* Lock ref, res, hint fields */ ! 259: vm_map_entry_t hint; /* hint for quick lookups */ ! 260: vm_map_entry_t first_free; /* First free space hint */ ! 261: boolean_t wait_for_space; /* Should callers wait ! 262: for space? */ ! 263: boolean_t wiring_required;/* All memory wired? */ ! 264: boolean_t no_zero_fill; /* No zero fill absent pages */ ! 265: unsigned int timestamp; /* Version number */ ! 266: } ; ! 267: ! 268: #define vm_map_to_entry(map) ((struct vm_map_entry *) &(map)->hdr.links) ! 269: #define vm_map_first_entry(map) ((map)->hdr.links.next) ! 270: #define vm_map_last_entry(map) ((map)->hdr.links.prev) ! 271: ! 272: #if TASK_SWAPPER ! 273: /* ! 274: * VM map swap states. There are no transition states. ! 275: */ ! 276: #define MAP_SW_IN 1 /* map is swapped in; residence count > 0 */ ! 277: #define MAP_SW_OUT 2 /* map is out (res_count == 0 */ ! 278: #endif /* TASK_SWAPPER */ ! 279: ! 280: /* ! 281: * Type: vm_map_version_t [exported; contents invisible] ! 282: * ! 283: * Description: ! 284: * Map versions may be used to quickly validate a previous ! 285: * lookup operation. ! 286: * ! 287: * Usage note: ! 288: * Because they are bulky objects, map versions are usually ! 289: * passed by reference. ! 290: * ! 291: * Implementation: ! 292: * Just a timestamp for the main map. ! 293: */ ! 294: typedef struct vm_map_version { ! 295: unsigned int main_timestamp; ! 296: } vm_map_version_t; ! 297: ! 298: /* ! 299: * Type: vm_map_copy_t [exported; contents invisible] ! 300: * ! 301: * Description: ! 302: * A map copy object represents a region of virtual memory ! 303: * that has been copied from an address map but is still ! 304: * in transit. ! 305: * ! 306: * A map copy object may only be used by a single thread ! 307: * at a time. ! 308: * ! 309: * Implementation: ! 310: * There are three formats for map copy objects. ! 311: * The first is very similar to the main ! 312: * address map in structure, and as a result, some ! 313: * of the internal maintenance functions/macros can ! 314: * be used with either address maps or map copy objects. ! 315: * ! 316: * The map copy object contains a header links ! 317: * entry onto which the other entries that represent ! 318: * the region are chained. ! 319: * ! 320: * The second format is a single vm object. This is used ! 321: * primarily in the pageout path. The third format is a ! 322: * list of vm pages. An optional continuation provides ! 323: * a hook to be called to obtain more of the memory, ! 324: * or perform other operations. The continuation takes 3 ! 325: * arguments, a saved arg buffer, a pointer to a new vm_map_copy ! 326: * (returned) and an abort flag (abort if TRUE). ! 327: */ ! 328: ! 329: #define VM_MAP_COPY_PAGE_LIST_MAX 20 ! 330: #define VM_MAP_COPY_PAGE_LIST_MAX_SIZE (VM_MAP_COPY_PAGE_LIST_MAX * PAGE_SIZE) ! 331: ! 332: ! 333: /* ! 334: * Options for vm_map_copyin_page_list. ! 335: */ ! 336: ! 337: #define VM_MAP_COPYIN_OPT_VM_PROT 0x7 ! 338: #define VM_MAP_COPYIN_OPT_SRC_DESTROY 0x8 ! 339: #define VM_MAP_COPYIN_OPT_STEAL_PAGES 0x10 ! 340: #define VM_MAP_COPYIN_OPT_PMAP_ENTER 0x20 ! 341: #define VM_MAP_COPYIN_OPT_NO_ZERO_FILL 0x40 ! 342: ! 343: /* ! 344: * Continuation structures for vm_map_copyin_page_list. ! 345: */ ! 346: typedef struct { ! 347: vm_map_t map; ! 348: vm_offset_t src_addr; ! 349: vm_size_t src_len; ! 350: vm_offset_t destroy_addr; ! 351: vm_size_t destroy_len; ! 352: int options; ! 353: } vm_map_copyin_args_data_t, *vm_map_copyin_args_t; ! 354: ! 355: #define VM_MAP_COPYIN_ARGS_NULL ((vm_map_copyin_args_t) 0) ! 356: ! 357: ! 358: /* vm_map_copy_cont_t is a type definition/prototype ! 359: * for the cont function pointer in vm_map_copy structure. ! 360: */ ! 361: typedef kern_return_t (*vm_map_copy_cont_t)( ! 362: vm_map_copyin_args_t, ! 363: vm_map_copy_t *); ! 364: ! 365: #define VM_MAP_COPY_CONT_NULL ((vm_map_copy_cont_t) 0) ! 366: ! 367: struct vm_map_copy { ! 368: int type; ! 369: #define VM_MAP_COPY_ENTRY_LIST 1 ! 370: #define VM_MAP_COPY_OBJECT 2 ! 371: #define VM_MAP_COPY_PAGE_LIST 3 ! 372: #define VM_MAP_COPY_KERNEL_BUFFER 4 ! 373: vm_offset_t offset; ! 374: vm_size_t size; ! 375: union { ! 376: struct vm_map_header hdr; /* ENTRY_LIST */ ! 377: struct { /* OBJECT */ ! 378: vm_object_t object; ! 379: vm_size_t index; /* record progress as pages ! 380: * are moved from object to ! 381: * page list; must be zero ! 382: * when first invoking ! 383: * vm_map_object_to_page_list ! 384: */ ! 385: } c_o; ! 386: struct { /* PAGE_LIST */ ! 387: int npages; ! 388: boolean_t page_loose; ! 389: vm_map_copy_cont_t cont; ! 390: vm_map_copyin_args_t cont_args; ! 391: vm_page_t page_list[VM_MAP_COPY_PAGE_LIST_MAX]; ! 392: } c_p; ! 393: struct { /* KERNEL_BUFFER */ ! 394: vm_offset_t kdata; ! 395: vm_size_t kalloc_size; /* size of this copy_t */ ! 396: } c_k; ! 397: } c_u; ! 398: }; ! 399: ! 400: ! 401: #define cpy_hdr c_u.hdr ! 402: ! 403: #define cpy_object c_u.c_o.object ! 404: #define cpy_index c_u.c_o.index ! 405: ! 406: #define cpy_page_list c_u.c_p.page_list ! 407: #define cpy_npages c_u.c_p.npages ! 408: #define cpy_page_loose c_u.c_p.page_loose ! 409: #define cpy_cont c_u.c_p.cont ! 410: #define cpy_cont_args c_u.c_p.cont_args ! 411: ! 412: #define cpy_kdata c_u.c_k.kdata ! 413: #define cpy_kalloc_size c_u.c_k.kalloc_size ! 414: ! 415: ! 416: /* ! 417: * Useful macros for entry list copy objects ! 418: */ ! 419: ! 420: #define vm_map_copy_to_entry(copy) \ ! 421: ((struct vm_map_entry *) &(copy)->cpy_hdr.links) ! 422: #define vm_map_copy_first_entry(copy) \ ! 423: ((copy)->cpy_hdr.links.next) ! 424: #define vm_map_copy_last_entry(copy) \ ! 425: ((copy)->cpy_hdr.links.prev) ! 426: ! 427: /* ! 428: * Continuation macros for page list copy objects ! 429: */ ! 430: ! 431: #define vm_map_copy_invoke_cont(old_copy, new_copy, result) \ ! 432: MACRO_BEGIN \ ! 433: assert(vm_map_copy_cont_is_valid(old_copy)); \ ! 434: vm_map_copy_page_discard(old_copy); \ ! 435: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \ ! 436: new_copy); \ ! 437: (old_copy)->cpy_cont = VM_MAP_COPY_CONT_NULL; \ ! 438: MACRO_END ! 439: ! 440: #define vm_map_copy_invoke_extend_cont(old_copy, new_copy, result) \ ! 441: MACRO_BEGIN \ ! 442: assert(vm_map_copy_cont_is_valid(old_copy)); \ ! 443: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \ ! 444: new_copy); \ ! 445: (old_copy)->cpy_cont = VM_MAP_COPY_CONT_NULL; \ ! 446: MACRO_END ! 447: ! 448: #define vm_map_copy_abort_cont(old_copy) \ ! 449: MACRO_BEGIN \ ! 450: assert(vm_map_copy_cont_is_valid(old_copy)); \ ! 451: vm_map_copy_page_discard(old_copy); \ ! 452: (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \ ! 453: (vm_map_copy_t *) 0); \ ! 454: (old_copy)->cpy_cont = VM_MAP_COPY_CONT_NULL; \ ! 455: (old_copy)->cpy_cont_args = VM_MAP_COPYIN_ARGS_NULL; \ ! 456: MACRO_END ! 457: ! 458: #define vm_map_copy_has_cont(copy) \ ! 459: (((copy)->cpy_cont) != VM_MAP_COPY_CONT_NULL) ! 460: ! 461: /* ! 462: * Macro to determine number of pages in a page-list copy chain. ! 463: */ ! 464: ! 465: #define vm_map_copy_page_count(copy) \ ! 466: (round_page(((copy)->offset - trunc_page((copy)->offset)) + (copy)->size) \ ! 467: / PAGE_SIZE) ! 468: ! 469: /* ! 470: * Macros: vm_map_lock, etc. [internal use only] ! 471: * Description: ! 472: * Perform locking on the data portion of a map. ! 473: * When multiple maps are to be locked, order by map address. ! 474: * (See vm_map.c::vm_remap()) ! 475: */ ! 476: ! 477: #define vm_map_lock_init(map) \ ! 478: MACRO_BEGIN \ ! 479: lock_init(&(map)->lock, TRUE, ETAP_VM_MAP, ETAP_VM_MAP_I); \ ! 480: (map)->timestamp = 0; \ ! 481: MACRO_END ! 482: #define vm_map_lock(map) \ ! 483: MACRO_BEGIN \ ! 484: lock_write(&(map)->lock); \ ! 485: (map)->timestamp++; \ ! 486: MACRO_END ! 487: ! 488: #define vm_map_unlock(map) lock_write_done(&(map)->lock) ! 489: #define vm_map_lock_read(map) lock_read(&(map)->lock) ! 490: #define vm_map_unlock_read(map) lock_read_done(&(map)->lock) ! 491: #define vm_map_lock_write_to_read(map) \ ! 492: lock_write_to_read(&(map)->lock) ! 493: #define vm_map_lock_read_to_write(map) \ ! 494: (lock_read_to_write(&(map)->lock) || (((map)->timestamp++), 0)) ! 495: ! 496: extern zone_t vm_map_copy_zone; /* zone for vm_map_copy structures */ ! 497: ! 498: /* ! 499: * Exported procedures that operate on vm_map_t. ! 500: */ ! 501: ! 502: /* Initialize the module */ ! 503: extern void vm_map_init(void); ! 504: ! 505: /* Allocate a range in the specified virtual address map and ! 506: * return the entry allocated for that range. */ ! 507: extern kern_return_t vm_map_find_space( ! 508: vm_map_t map, ! 509: vm_offset_t *address, /* OUT */ ! 510: vm_size_t size, ! 511: vm_offset_t mask, ! 512: vm_map_entry_t *o_entry); /* OUT */ ! 513: ! 514: /* Lookup map entry containing or the specified address in the given map */ ! 515: extern boolean_t vm_map_lookup_entry( ! 516: vm_map_t map, ! 517: vm_offset_t address, ! 518: vm_map_entry_t *entry); /* OUT */ ! 519: ! 520: /* A version of vm_map_copy_discard that can be called ! 521: * as a continuation from a vm_map_copy page list. */ ! 522: extern kern_return_t vm_map_copy_discard_cont( ! 523: vm_map_copyin_args_t cont_args, ! 524: vm_map_copy_t *copy_result);/* OUT */ ! 525: ! 526: /* Find the VM object, offset, and protection for a given virtual address ! 527: * in the specified map, assuming a page fault of the type specified. */ ! 528: extern kern_return_t vm_map_lookup_locked( ! 529: vm_map_t *var_map, /* IN/OUT */ ! 530: vm_offset_t vaddr, ! 531: vm_prot_t fault_type, ! 532: vm_map_version_t *out_version, /* OUT */ ! 533: vm_object_t *object, /* OUT */ ! 534: vm_offset_t *offset, /* OUT */ ! 535: vm_prot_t *out_prot, /* OUT */ ! 536: boolean_t *wired, /* OUT */ ! 537: int *behavior, /* OUT */ ! 538: vm_offset_t *lo_offset, /* OUT */ ! 539: vm_offset_t *hi_offset); /* OUT */ ! 540: ! 541: /* Verifies that the map has not changed since the given version. */ ! 542: extern boolean_t vm_map_verify( ! 543: vm_map_t map, ! 544: vm_map_version_t *version); /* REF */ ! 545: ! 546: /* Split a vm_map_entry into 2 entries */ ! 547: extern void _vm_map_clip_start( ! 548: struct vm_map_header *map_header, ! 549: vm_map_entry_t entry, ! 550: vm_offset_t start); ! 551: ! 552: extern vm_map_entry_t vm_map_entry_insert( ! 553: vm_map_t map, ! 554: vm_map_entry_t insp_entry, ! 555: vm_offset_t start, ! 556: vm_offset_t end, ! 557: vm_object_t object, ! 558: vm_offset_t offset, ! 559: boolean_t needs_copy, ! 560: boolean_t is_shared, ! 561: boolean_t in_transition, ! 562: vm_prot_t cur_protection, ! 563: vm_prot_t max_protection, ! 564: vm_behavior_t behavior, ! 565: vm_inherit_t inheritance, ! 566: unsigned wired_count); ! 567: ! 568: extern kern_return_t vm_remap_extract( ! 569: vm_map_t map, ! 570: vm_offset_t addr, ! 571: vm_size_t size, ! 572: boolean_t copy, ! 573: struct vm_map_header *map_header, ! 574: vm_prot_t *cur_protection, ! 575: vm_prot_t *max_protection, ! 576: vm_inherit_t inheritance, ! 577: boolean_t pageable); ! 578: ! 579: extern kern_return_t vm_remap_range_allocate( ! 580: vm_map_t map, ! 581: vm_offset_t *address, ! 582: vm_size_t size, ! 583: vm_offset_t mask, ! 584: boolean_t anywhere, ! 585: vm_map_entry_t *map_entry); ! 586: ! 587: extern kern_return_t vm_remap_extract( ! 588: vm_map_t map, ! 589: vm_offset_t addr, ! 590: vm_size_t size, ! 591: boolean_t copy, ! 592: struct vm_map_header *map_header, ! 593: vm_prot_t *cur_protection, ! 594: vm_prot_t *max_protection, ! 595: vm_inherit_t inheritance, ! 596: boolean_t pageable); ! 597: ! 598: extern kern_return_t vm_remap_range_allocate( ! 599: vm_map_t map, ! 600: vm_offset_t *address, ! 601: vm_size_t size, ! 602: vm_offset_t mask, ! 603: boolean_t anywhere, ! 604: vm_map_entry_t *map_entry); ! 605: ! 606: /* ! 607: * Functions implemented as macros ! 608: */ ! 609: #define vm_map_min(map) ((map)->min_offset) ! 610: /* Lowest valid address in ! 611: * a map */ ! 612: ! 613: #define vm_map_max(map) ((map)->max_offset) ! 614: /* Highest valid address */ ! 615: ! 616: #define vm_map_pmap(map) ((map)->pmap) ! 617: /* Physical map associated ! 618: * with this address map */ ! 619: ! 620: #define vm_map_verify_done(map, version) vm_map_unlock_read(map) ! 621: /* Operation that required ! 622: * a verified lookup is ! 623: * now complete */ ! 624: ! 625: /* ! 626: * Macros/functions for map residence counts and swapin/out of vm maps ! 627: */ ! 628: #if TASK_SWAPPER ! 629: ! 630: #if MACH_ASSERT ! 631: /* Gain a reference to an existing map */ ! 632: extern void vm_map_reference( ! 633: vm_map_t map); ! 634: /* Lose a residence count */ ! 635: extern void vm_map_res_deallocate( ! 636: vm_map_t map); ! 637: /* Gain a residence count on a map */ ! 638: extern void vm_map_res_reference( ! 639: vm_map_t map); ! 640: /* Gain reference & residence counts to possibly swapped-out map */ ! 641: extern void vm_map_reference_swap( ! 642: vm_map_t map); ! 643: ! 644: #else /* MACH_ASSERT */ ! 645: ! 646: #define vm_map_reference(map) \ ! 647: MACRO_BEGIN \ ! 648: vm_map_t Map = (map); \ ! 649: if (Map) { \ ! 650: mutex_lock(&Map->s_lock); \ ! 651: Map->res_count++; \ ! 652: Map->ref_count++; \ ! 653: mutex_unlock(&Map->s_lock); \ ! 654: } \ ! 655: MACRO_END ! 656: ! 657: #define vm_map_res_reference(map) \ ! 658: MACRO_BEGIN \ ! 659: vm_map_t Lmap = (map); \ ! 660: if (Lmap->res_count == 0) { \ ! 661: mutex_unlock(&Lmap->s_lock); \ ! 662: vm_map_lock(Lmap); \ ! 663: vm_map_swapin(Lmap); \ ! 664: mutex_lock(&Lmap->s_lock); \ ! 665: ++Lmap->res_count; \ ! 666: vm_map_unlock(Lmap); \ ! 667: } else \ ! 668: ++Lmap->res_count; \ ! 669: MACRO_END ! 670: ! 671: #define vm_map_res_deallocate(map) \ ! 672: MACRO_BEGIN \ ! 673: vm_map_t Map = (map); \ ! 674: if (--Map->res_count == 0) { \ ! 675: mutex_unlock(&Map->s_lock); \ ! 676: vm_map_lock(Map); \ ! 677: vm_map_swapout(Map); \ ! 678: vm_map_unlock(Map); \ ! 679: mutex_lock(&Map->s_lock); \ ! 680: } \ ! 681: MACRO_END ! 682: ! 683: #define vm_map_reference_swap(map) \ ! 684: MACRO_BEGIN \ ! 685: vm_map_t Map = (map); \ ! 686: mutex_lock(&Map->s_lock); \ ! 687: ++Map->ref_count; \ ! 688: vm_map_res_reference(Map); \ ! 689: mutex_unlock(&Map->s_lock); \ ! 690: MACRO_END ! 691: #endif /* MACH_ASSERT */ ! 692: ! 693: extern void vm_map_swapin( ! 694: vm_map_t map); ! 695: ! 696: extern void vm_map_swapout( ! 697: vm_map_t map); ! 698: ! 699: #else /* TASK_SWAPPER */ ! 700: ! 701: #define vm_map_reference(map) \ ! 702: MACRO_BEGIN \ ! 703: vm_map_t Map = (map); \ ! 704: if (Map) { \ ! 705: mutex_lock(&Map->s_lock); \ ! 706: Map->ref_count++; \ ! 707: mutex_unlock(&Map->s_lock); \ ! 708: } \ ! 709: MACRO_END ! 710: ! 711: #define vm_map_reference_swap(map) vm_map_reference(map) ! 712: #define vm_map_res_reference(map) ! 713: #define vm_map_res_deallocate(map) ! 714: ! 715: #endif /* TASK_SWAPPER */ ! 716: ! 717: /* ! 718: * Submap object. Must be used to create memory to be put ! 719: * in a submap by vm_map_submap. ! 720: */ ! 721: extern vm_object_t vm_submap_object; ! 722: ! 723: /* ! 724: * Wait and wakeup macros for in_transition map entries. ! 725: */ ! 726: #define vm_map_entry_wait(map, interruptible) \ ! 727: MACRO_BEGIN \ ! 728: assert_wait((event_t)&(map)->hdr, interruptible); \ ! 729: vm_map_unlock(map); \ ! 730: thread_block((void (*)(void))0); \ ! 731: MACRO_END ! 732: ! 733: #define vm_map_entry_wakeup(map) thread_wakeup((event_t)(&(map)->hdr)) ! 734: ! 735: ! 736: ! 737: #define vm_map_ref_fast(map) \ ! 738: MACRO_BEGIN \ ! 739: mutex_lock(&map->s_lock); \ ! 740: map->ref_count++; \ ! 741: vm_map_res_reference(map); \ ! 742: mutex_unlock(&map->s_lock); \ ! 743: MACRO_END ! 744: ! 745: #define vm_map_dealloc_fast(map) \ ! 746: MACRO_BEGIN \ ! 747: register int c; \ ! 748: \ ! 749: mutex_lock(&map->s_lock); \ ! 750: c = --map->ref_count; \ ! 751: if (c > 0) \ ! 752: vm_map_res_deallocate(map); \ ! 753: mutex_unlock(&map->s_lock); \ ! 754: if (c == 0) \ ! 755: vm_map_destroy(map); \ ! 756: MACRO_END ! 757: ! 758: #if DIPC ! 759: extern void vm_map_entry_reset( ! 760: struct vm_map_header *header_map); ! 761: ! 762: extern vm_map_copy_t vm_map_entry_list_from_object( ! 763: vm_object_t object, ! 764: vm_offset_t offset, ! 765: vm_size_t size, ! 766: boolean_t pageable); ! 767: #endif ! 768: ! 769: /* simplify map entries */ ! 770: extern void vm_map_simplify( ! 771: vm_map_t map, ! 772: vm_offset_t start); ! 773: ! 774: /* Steal all the pages from a vm_map_copy page_list */ ! 775: extern void vm_map_copy_steal_pages( ! 776: vm_map_copy_t copy); ! 777: ! 778: /* Discard a copy without using it */ ! 779: extern void vm_map_copy_discard( ! 780: vm_map_copy_t copy); ! 781: ! 782: /* Move the information in a map copy object to a new map copy object */ ! 783: extern vm_map_copy_t vm_map_copy_copy( ! 784: vm_map_copy_t copy); ! 785: ! 786: /* Overwrite existing memory with a copy */ ! 787: extern kern_return_t vm_map_copy_overwrite( ! 788: vm_map_t dst_map, ! 789: vm_offset_t dst_addr, ! 790: vm_map_copy_t copy, ! 791: boolean_t interruptible); ! 792: ! 793: /* Version of vm_map_copyout() for page list vm map copies. */ ! 794: extern kern_return_t vm_map_copyout_page_list( ! 795: vm_map_t dst_map, ! 796: vm_offset_t *dst_addr, /* OUT */ ! 797: vm_map_copy_t copy); ! 798: ! 799: /* Get rid of the pages in a page_list copy. */ ! 800: extern void vm_map_copy_page_discard( ! 801: vm_map_copy_t copy); ! 802: ! 803: /* Create a copy object from an object. */ ! 804: extern kern_return_t vm_map_copyin_object( ! 805: vm_object_t object, ! 806: vm_offset_t offset, ! 807: vm_size_t size, ! 808: vm_map_copy_t *copy_result); /* OUT */ ! 809: ! 810: ! 811: /* Make a copy of a region */ ! 812: #if DIPC ! 813: /* ! 814: * For DIPC only, src_volatile=TRUE means that the user promises not ! 815: * to modify data in transit. Kernel may then avoid copy-on-write ! 816: * handling. ! 817: * ! 818: * For non-DIPC kernel configurations, the src_volatile parameter ! 819: * is visible (even though it has no effect) to avoid ifdef'ing ! 820: * the interface. The use of src_volatile has no effect in a ! 821: * non-DIPC kernel. ! 822: */ ! 823: #endif /* DIPC */ ! 824: /* Make a copy of a region using a page list copy */ ! 825: extern kern_return_t vm_map_copyin_page_list( ! 826: vm_map_t src_map, ! 827: vm_offset_t src_addr, ! 828: vm_size_t len, ! 829: int options, ! 830: vm_map_copy_t *copy_result, /* OUT */ ! 831: boolean_t is_cont); ! 832: ! 833: #if DIPC ! 834: extern kern_return_t vm_map_convert_to_page_list( ! 835: vm_map_copy_t *caller_copy); ! 836: ! 837: extern kern_return_t vm_map_object_to_page_list_cont( ! 838: vm_map_copy_t cont_args, ! 839: vm_map_copy_t *copy_result); /* OUT */ ! 840: ! 841: extern kern_return_t vm_map_object_to_page_list( ! 842: vm_map_copy_t *caller_copy); ! 843: ! 844: extern kern_return_t vm_map_convert_from_page_list( ! 845: vm_map_copy_t copy); ! 846: ! 847: extern kern_return_t vm_map_object_to_entry_list( ! 848: vm_map_copy_t copy); ! 849: ! 850: ! 851: extern kern_return_t vm_map_convert_to_entry_list( ! 852: vm_map_copy_t copy, ! 853: boolean_t pageable); ! 854: ! 855: extern vm_map_copy_t vm_map_copy_overwrite_recv( ! 856: vm_map_t map, ! 857: vm_offset_t addr, ! 858: vm_size_t size); ! 859: ! 860: extern kern_return_t vm_map_copy_overwrite_recv_done( ! 861: vm_map_t map, ! 862: vm_map_copy_t copy); ! 863: #endif /* DIPC */ ! 864: ! 865: ! 866: extern vm_map_t vm_map_switch( ! 867: vm_map_t map); ! 868: ! 869: extern int vm_map_copy_cont_is_valid( ! 870: vm_map_copy_t copy); ! 871: ! 872: ! 873: ! 874: #if DIPC ! 875: /* ! 876: * Caller promises not to modify data in transit. Kernel may then ! 877: * avoid copy-on-write handling. ! 878: * ! 879: * N.B. When src_destroy=TRUE, turning on src_volatile=TRUE has ! 880: * no effect. ! 881: */ ! 882: #define vm_map_copyin_volatile(src_map,src_addr,len,src_destroy,copy_result) \ ! 883: vm_map_copyin_common(src_map, src_addr, len, src_destroy, \ ! 884: TRUE, copy_result, FALSE) ! 885: #endif /* DIPC */ ! 886: ! 887: #endif /* !MACH_KERNEL_PRIVATE */ ! 888: ! 889: /* Get rid of a map */ ! 890: extern void vm_map_destroy( ! 891: vm_map_t map); ! 892: /* Lose a reference */ ! 893: extern void vm_map_deallocate( ! 894: vm_map_t map); ! 895: ! 896: /* Create an empty map */ ! 897: extern vm_map_t vm_map_create( ! 898: pmap_t pmap, ! 899: vm_offset_t min, ! 900: vm_offset_t max, ! 901: boolean_t pageable); ! 902: ! 903: ! 904: /* Enter a mapping */ ! 905: extern kern_return_t vm_map_enter( ! 906: vm_map_t map, ! 907: vm_offset_t *address, ! 908: vm_size_t size, ! 909: vm_offset_t mask, ! 910: int flags, ! 911: vm_object_t object, ! 912: vm_offset_t offset, ! 913: boolean_t needs_copy, ! 914: vm_prot_t cur_protection, ! 915: vm_prot_t max_protection, ! 916: vm_inherit_t inheritance); ! 917: ! 918: extern kern_return_t vm_map_write_user( ! 919: vm_map_t map, ! 920: vm_offset_t src_addr, ! 921: vm_offset_t dst_addr, ! 922: vm_size_t size); ! 923: ! 924: extern kern_return_t vm_map_read_user( ! 925: vm_map_t map, ! 926: vm_offset_t src_addr, ! 927: vm_offset_t dst_addr, ! 928: vm_size_t size); ! 929: ! 930: /* Create a new task map using an existing task map as a template. */ ! 931: extern vm_map_t vm_map_fork( ! 932: vm_map_t old_map); ! 933: ! 934: /* Change protection */ ! 935: extern kern_return_t vm_map_protect( ! 936: vm_map_t map, ! 937: vm_offset_t start, ! 938: vm_offset_t end, ! 939: vm_prot_t new_prot, ! 940: boolean_t set_max); ! 941: ! 942: /* Change inheritance */ ! 943: extern kern_return_t vm_map_inherit( ! 944: vm_map_t map, ! 945: vm_offset_t start, ! 946: vm_offset_t end, ! 947: vm_inherit_t new_inheritance); ! 948: ! 949: /* wire down a region */ ! 950: extern kern_return_t vm_map_wire( ! 951: vm_map_t map, ! 952: vm_offset_t start, ! 953: vm_offset_t end, ! 954: vm_prot_t access_type, ! 955: boolean_t user_wire); ! 956: ! 957: /* unwire a region */ ! 958: extern kern_return_t vm_map_unwire( ! 959: vm_map_t map, ! 960: vm_offset_t start, ! 961: vm_offset_t end, ! 962: boolean_t user_wire); ! 963: ! 964: /* Deallocate a region */ ! 965: extern kern_return_t vm_map_remove( ! 966: vm_map_t map, ! 967: vm_offset_t start, ! 968: vm_offset_t end, ! 969: boolean_t flags); ! 970: ! 971: /* Place a copy into a map */ ! 972: extern kern_return_t vm_map_copyout( ! 973: vm_map_t dst_map, ! 974: vm_offset_t *dst_addr, /* OUT */ ! 975: vm_map_copy_t copy); ! 976: ! 977: ! 978: /* Add or remove machine-dependent attributes from map regions */ ! 979: extern kern_return_t vm_map_machine_attribute( ! 980: vm_map_t map, ! 981: vm_offset_t address, ! 982: vm_size_t size, ! 983: vm_machine_attribute_t attribute, ! 984: vm_machine_attribute_val_t* value); /* IN/OUT */ ! 985: /* Set paging behavior */ ! 986: extern kern_return_t vm_map_behavior_set( ! 987: vm_map_t map, ! 988: vm_offset_t start, ! 989: vm_offset_t end, ! 990: vm_behavior_t new_behavior); ! 991: ! 992: extern kern_return_t vm_map_copyin_common( ! 993: vm_map_t src_map, ! 994: vm_offset_t src_addr, ! 995: vm_size_t len, ! 996: boolean_t src_destroy, ! 997: boolean_t src_volatile, ! 998: vm_map_copy_t *copy_result, /* OUT */ ! 999: boolean_t use_maxprot); ! 1000: ! 1001: /* ! 1002: * Macros to invoke vm_map_copyin_common. vm_map_copyin is the ! 1003: * usual form; it handles a copyin based on the current protection ! 1004: * (current protection == VM_PROT_NONE) is a failure. ! 1005: * vm_map_copyin_maxprot handles a copyin based on maximum possible ! 1006: * access. The difference is that a region with no current access ! 1007: * BUT possible maximum access is rejected by vm_map_copyin(), but ! 1008: * returned by vm_map_copyin_maxprot. ! 1009: */ ! 1010: #define vm_map_copyin(src_map, src_addr, len, src_destroy, copy_result) \ ! 1011: vm_map_copyin_common(src_map, src_addr, len, src_destroy, \ ! 1012: FALSE, copy_result, FALSE) ! 1013: ! 1014: #define vm_map_copyin_maxprot(src_map, \ ! 1015: src_addr, len, src_destroy, copy_result) \ ! 1016: vm_map_copyin_common(src_map, src_addr, len, src_destroy, \ ! 1017: FALSE, copy_result, TRUE) ! 1018: ! 1019: #define VM_MAP_ENTRY_NULL ((vm_map_entry_t) 0) ! 1020: ! 1021: /* ! 1022: * Flags for vm_map_remove() and vm_map_delete() ! 1023: */ ! 1024: #define VM_MAP_NO_FLAGS 0x0 ! 1025: #define VM_MAP_REMOVE_KUNWIRE 0x1 ! 1026: #define VM_MAP_REMOVE_INTERRUPTIBLE 0x2 ! 1027: #define VM_MAP_REMOVE_WAIT_FOR_KWIRE 0x4 ! 1028: ! 1029: #endif /* _VM_VM_MAP_H_ */ ! 1030:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.