|
|
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.