|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University.
4: * Copyright (c) 1993,1994 The University of Utah and
5: * the Computer Systems Laboratory (CSL).
6: * All rights reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
17: * THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or [email protected]
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
28: */
29: /*
30: * File: vm/vm_map.h
31: * Author: Avadis Tevanian, Jr., Michael Wayne Young
32: * Date: 1985
33: *
34: * Virtual memory map module definitions.
35: *
36: * Contributors:
37: * avie, dlb, mwyoung
38: */
39:
40: #ifndef _VM_VM_MAP_H_
41: #define _VM_VM_MAP_H_
42:
43: #include <mach/kern_return.h>
44: #include <mach/boolean.h>
45: #include <mach/machine/vm_types.h>
1.1.1.3 root 46: #include <mach/vm_attributes.h>
1.1 root 47: #include <mach/vm_prot.h>
48: #include <mach/vm_inherit.h>
49: #include <vm/pmap.h>
50: #include <vm/vm_object.h>
51: #include <vm/vm_page.h>
1.1.1.3 root 52: #include <vm/vm_types.h>
1.1.1.7 ! root 53: #include <kern/list.h>
1.1 root 54: #include <kern/lock.h>
1.1.1.3 root 55: #include <kern/rbtree.h>
1.1.1.5 root 56: #include <kern/macros.h>
1.1 root 57:
1.1.1.3 root 58: /* TODO: make it dynamic */
1.1.1.4 root 59: #define KENTRY_DATA_SIZE (256*PAGE_SIZE)
1.1.1.3 root 60:
1.1 root 61: /*
62: * Types defined:
63: *
64: * vm_map_entry_t an entry in an address map.
65: * vm_map_version_t a timestamp of a map, for use with vm_map_lookup
66: * vm_map_copy_t represents memory copied from an address map,
67: * used for inter-map copy operations
68: */
69:
70: /*
71: * Type: vm_map_object_t [internal use only]
72: *
73: * Description:
74: * The target of an address mapping, either a virtual
75: * memory object or a sub map (of the kernel map).
76: */
77: typedef union vm_map_object {
78: struct vm_object *vm_object; /* object object */
79: struct vm_map *sub_map; /* belongs to another map */
80: } vm_map_object_t;
81:
82: /*
83: * Type: vm_map_entry_t [internal use only]
84: *
85: * Description:
86: * A single mapping within an address map.
87: *
88: * Implementation:
89: * Address map entries consist of start and end addresses,
90: * a VM object (or sub map) and offset into that object,
91: * and user-exported inheritance and protection information.
92: * Control information for virtual copy operations is also
93: * stored in the address map entry.
94: */
95: struct vm_map_links {
96: struct vm_map_entry *prev; /* previous entry */
97: struct vm_map_entry *next; /* next entry */
98: vm_offset_t start; /* start address */
99: vm_offset_t end; /* end address */
100: };
101:
102: struct vm_map_entry {
103: struct vm_map_links links; /* links to other entries */
104: #define vme_prev links.prev
105: #define vme_next links.next
106: #define vme_start links.start
107: #define vme_end links.end
1.1.1.3 root 108: struct rbtree_node tree_node; /* links to other entries in tree */
1.1.1.7 ! root 109: struct rbtree_node gap_node; /* links to other entries in gap tree */
! 110: struct list gap_list; /* links to other entries with
! 111: the same gap size */
! 112: vm_size_t gap_size; /* size of available memory
! 113: following this entry */
1.1 root 114: union vm_map_object object; /* object I point to */
115: vm_offset_t offset; /* offset into object */
116: unsigned int
1.1.1.7 ! root 117: /* boolean_t */ in_gap_tree:1, /* entry is in the gap tree if true,
! 118: or linked to other entries with
! 119: the same gap size if false */
1.1 root 120: /* boolean_t */ is_shared:1, /* region is shared */
121: /* boolean_t */ is_sub_map:1, /* Is "object" a submap? */
122: /* boolean_t */ in_transition:1, /* Entry being changed */
123: /* boolean_t */ needs_wakeup:1, /* Waiters on in_transition */
124: /* Only used when object is a vm_object: */
125: /* boolean_t */ needs_copy:1; /* does object need to be copied */
126:
127: /* Only in task maps: */
128: vm_prot_t protection; /* protection code */
129: vm_prot_t max_protection; /* maximum protection */
130: vm_inherit_t inheritance; /* inheritance */
131: unsigned short wired_count; /* can be paged if = 0 */
132: unsigned short user_wired_count; /* for vm_wire */
133: struct vm_map_entry *projected_on; /* 0 for normal map entry
134: or persistent kernel map projected buffer entry;
135: -1 for non-persistent kernel map projected buffer entry;
136: pointer to corresponding kernel map entry for user map
137: projected buffer entry */
138: };
139:
140: typedef struct vm_map_entry *vm_map_entry_t;
141:
142: #define VM_MAP_ENTRY_NULL ((vm_map_entry_t) 0)
143:
144: /*
145: * Type: struct vm_map_header
146: *
147: * Description:
148: * Header for a vm_map and a vm_map_copy.
149: */
150: struct vm_map_header {
151: struct vm_map_links links; /* first, last, min, max */
1.1.1.3 root 152: struct rbtree tree; /* Sorted tree of entries */
1.1.1.7 ! root 153: struct rbtree gap_tree; /* Sorted tree of gap lists
! 154: for allocations */
1.1 root 155: int nentries; /* Number of entries */
156: };
157:
158: /*
159: * Type: vm_map_t [exported; contents invisible]
160: *
161: * Description:
162: * An address map -- a directory relating valid
163: * regions of a task's address space to the corresponding
164: * virtual memory objects.
165: *
166: * Implementation:
167: * Maps are doubly-linked lists of map entries, sorted
1.1.1.3 root 168: * by address. They're also contained in a red-black tree.
169: * One hint is used to start searches again at the last
170: * successful search, insertion, or removal. If the hint
171: * lookup failed (i.e. the hint didn't refer to the requested
172: * entry), a BST lookup is performed. Another hint is used to
1.1 root 173: * quickly find free space.
174: */
175: struct vm_map {
176: lock_data_t lock; /* Lock for map data */
177: struct vm_map_header hdr; /* Map entry header */
178: #define min_offset hdr.links.start /* start of range */
179: #define max_offset hdr.links.end /* end of range */
180: pmap_t pmap; /* Physical map */
181: vm_size_t size; /* virtual size */
1.1.1.5 root 182: vm_size_t user_wired; /* wired by user size */
1.1 root 183: int ref_count; /* Reference count */
184: decl_simple_lock_data(, ref_lock) /* Lock for ref_count field */
185: vm_map_entry_t hint; /* hint for quick lookups */
186: decl_simple_lock_data(, hint_lock) /* lock for hint storage */
187: vm_map_entry_t first_free; /* First free space hint */
1.1.1.4 root 188:
189: /* Flags */
190: unsigned int wait_for_space:1, /* Should callers wait
1.1 root 191: for space? */
1.1.1.4 root 192: /* boolean_t */ wiring_required:1; /* All memory wired? */
193:
1.1 root 194: unsigned int timestamp; /* Version number */
1.1.1.7 ! root 195:
! 196: const char *name; /* Associated name */
1.1 root 197: };
198:
199: #define vm_map_to_entry(map) ((struct vm_map_entry *) &(map)->hdr.links)
200: #define vm_map_first_entry(map) ((map)->hdr.links.next)
201: #define vm_map_last_entry(map) ((map)->hdr.links.prev)
202:
203: /*
204: * Type: vm_map_version_t [exported; contents invisible]
205: *
206: * Description:
207: * Map versions may be used to quickly validate a previous
208: * lookup operation.
209: *
210: * Usage note:
211: * Because they are bulky objects, map versions are usually
212: * passed by reference.
213: *
214: * Implementation:
215: * Just a timestamp for the main map.
216: */
217: typedef struct vm_map_version {
218: unsigned int main_timestamp;
219: } vm_map_version_t;
220:
221: /*
222: * Type: vm_map_copy_t [exported; contents invisible]
223: *
224: * Description:
225: * A map copy object represents a region of virtual memory
226: * that has been copied from an address map but is still
227: * in transit.
228: *
229: * A map copy object may only be used by a single thread
230: * at a time.
231: *
232: * Implementation:
1.1.1.2 root 233: * There are three formats for map copy objects.
1.1 root 234: * The first is very similar to the main
235: * address map in structure, and as a result, some
236: * of the internal maintenance functions/macros can
237: * be used with either address maps or map copy objects.
238: *
239: * The map copy object contains a header links
240: * entry onto which the other entries that represent
241: * the region are chained.
242: *
243: * The second format is a single vm object. This is used
244: * primarily in the pageout path. The third format is a
245: * list of vm pages. An optional continuation provides
246: * a hook to be called to obtain more of the memory,
247: * or perform other operations. The continuation takes 3
248: * arguments, a saved arg buffer, a pointer to a new vm_map_copy
249: * (returned) and an abort flag (abort if TRUE).
250: */
251:
252: #define VM_MAP_COPY_PAGE_LIST_MAX 64
253:
254: typedef struct vm_map_copy {
255: int type;
256: #define VM_MAP_COPY_ENTRY_LIST 1
257: #define VM_MAP_COPY_OBJECT 2
258: #define VM_MAP_COPY_PAGE_LIST 3
259: vm_offset_t offset;
260: vm_size_t size;
261: union {
262: struct vm_map_header hdr; /* ENTRY_LIST */
263: struct { /* OBJECT */
264: vm_object_t object;
265: } c_o;
266: struct { /* PAGE_LIST */
267: vm_page_t page_list[VM_MAP_COPY_PAGE_LIST_MAX];
268: int npages;
269: kern_return_t (*cont)();
270: char *cont_args;
271: } c_p;
272: } c_u;
273: } *vm_map_copy_t;
274:
275: #define cpy_hdr c_u.hdr
276:
277: #define cpy_object c_u.c_o.object
278:
279: #define cpy_page_list c_u.c_p.page_list
280: #define cpy_npages c_u.c_p.npages
281: #define cpy_cont c_u.c_p.cont
282: #define cpy_cont_args c_u.c_p.cont_args
283:
284: #define VM_MAP_COPY_NULL ((vm_map_copy_t) 0)
285:
286: /*
287: * Useful macros for entry list copy objects
288: */
289:
290: #define vm_map_copy_to_entry(copy) \
291: ((struct vm_map_entry *) &(copy)->cpy_hdr.links)
292: #define vm_map_copy_first_entry(copy) \
293: ((copy)->cpy_hdr.links.next)
294: #define vm_map_copy_last_entry(copy) \
295: ((copy)->cpy_hdr.links.prev)
296:
297: /*
298: * Continuation macros for page list copy objects
299: */
300:
301: #define vm_map_copy_invoke_cont(old_copy, new_copy, result) \
302: MACRO_BEGIN \
303: vm_map_copy_page_discard(old_copy); \
304: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
305: new_copy); \
306: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
307: MACRO_END
308:
309: #define vm_map_copy_invoke_extend_cont(old_copy, new_copy, result) \
310: MACRO_BEGIN \
311: *result = (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
312: new_copy); \
313: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
314: MACRO_END
315:
316: #define vm_map_copy_abort_cont(old_copy) \
317: MACRO_BEGIN \
318: vm_map_copy_page_discard(old_copy); \
319: (*((old_copy)->cpy_cont))((old_copy)->cpy_cont_args, \
320: (vm_map_copy_t *) 0); \
321: (old_copy)->cpy_cont = (kern_return_t (*)()) 0; \
322: (old_copy)->cpy_cont_args = (char *) 0; \
323: MACRO_END
324:
325: #define vm_map_copy_has_cont(copy) \
326: (((copy)->cpy_cont) != (kern_return_t (*)()) 0)
327:
328: /*
329: * Continuation structures for vm_map_copyin_page_list.
330: */
331:
332: typedef struct {
333: vm_map_t map;
334: vm_offset_t src_addr;
335: vm_size_t src_len;
336: vm_offset_t destroy_addr;
337: vm_size_t destroy_len;
338: boolean_t steal_pages;
339: } vm_map_copyin_args_data_t, *vm_map_copyin_args_t;
340:
341: #define VM_MAP_COPYIN_ARGS_NULL ((vm_map_copyin_args_t) 0)
342:
343: /*
344: * Macros: vm_map_lock, etc. [internal use only]
345: * Description:
346: * Perform locking on the data portion of a map.
347: */
348:
349: #define vm_map_lock_init(map) \
350: MACRO_BEGIN \
351: lock_init(&(map)->lock, TRUE); \
352: (map)->timestamp = 0; \
353: MACRO_END
354:
1.1.1.7 ! root 355: void vm_map_lock(struct vm_map *map);
! 356: void vm_map_unlock(struct vm_map *map);
1.1 root 357:
358: #define vm_map_lock_read(map) lock_read(&(map)->lock)
359: #define vm_map_unlock_read(map) lock_read_done(&(map)->lock)
360: #define vm_map_lock_write_to_read(map) \
361: lock_write_to_read(&(map)->lock)
362: #define vm_map_lock_read_to_write(map) \
363: (lock_read_to_write(&(map)->lock) || (((map)->timestamp++), 0))
364: #define vm_map_lock_set_recursive(map) \
365: lock_set_recursive(&(map)->lock)
366: #define vm_map_lock_clear_recursive(map) \
367: lock_clear_recursive(&(map)->lock)
368:
369: /*
370: * Exported procedures that operate on vm_map_t.
371: */
372:
1.1.1.3 root 373: /* Initialize the module */
374: extern void vm_map_init(void);
1.1 root 375:
1.1.1.3 root 376: /* Initialize an empty map */
1.1.1.7 ! root 377: extern void vm_map_setup(vm_map_t, pmap_t, vm_offset_t, vm_offset_t);
1.1.1.3 root 378: /* Create an empty map */
1.1.1.7 ! root 379: extern vm_map_t vm_map_create(pmap_t, vm_offset_t, vm_offset_t);
1.1.1.3 root 380: /* Create a map in the image of an existing map */
381: extern vm_map_t vm_map_fork(vm_map_t);
382:
383: /* Gain a reference to an existing map */
384: extern void vm_map_reference(vm_map_t);
385: /* Lose a reference */
386: extern void vm_map_deallocate(vm_map_t);
387:
388: /* Enter a mapping */
389: extern kern_return_t vm_map_enter(vm_map_t, vm_offset_t *, vm_size_t,
390: vm_offset_t, boolean_t, vm_object_t,
391: vm_offset_t, boolean_t, vm_prot_t,
392: vm_prot_t, vm_inherit_t);
393: /* Enter a mapping primitive */
394: extern kern_return_t vm_map_find_entry(vm_map_t, vm_offset_t *, vm_size_t,
395: vm_offset_t, vm_object_t,
396: vm_map_entry_t *);
397: /* Deallocate a region */
398: extern kern_return_t vm_map_remove(vm_map_t, vm_offset_t, vm_offset_t);
399: /* Change protection */
400: extern kern_return_t vm_map_protect(vm_map_t, vm_offset_t, vm_offset_t,
401: vm_prot_t, boolean_t);
402: /* Change inheritance */
403: extern kern_return_t vm_map_inherit(vm_map_t, vm_offset_t, vm_offset_t,
404: vm_inherit_t);
405:
406: /* Look up an address */
407: extern kern_return_t vm_map_lookup(vm_map_t *, vm_offset_t, vm_prot_t,
408: vm_map_version_t *, vm_object_t *,
409: vm_offset_t *, vm_prot_t *, boolean_t *);
410: /* Find a map entry */
411: extern boolean_t vm_map_lookup_entry(vm_map_t, vm_offset_t,
412: vm_map_entry_t *);
413: /* Verify that a previous lookup is still valid */
414: extern boolean_t vm_map_verify(vm_map_t, vm_map_version_t *);
1.1 root 415: /* vm_map_verify_done is now a macro -- see below */
1.1.1.3 root 416: /* Make a copy of a region */
417: extern kern_return_t vm_map_copyin(vm_map_t, vm_offset_t, vm_size_t,
418: boolean_t, vm_map_copy_t *);
419: /* Make a copy of a region using a page list copy */
420: extern kern_return_t vm_map_copyin_page_list(vm_map_t, vm_offset_t,
421: vm_size_t, boolean_t,
422: boolean_t, vm_map_copy_t *,
423: boolean_t);
424: /* Place a copy into a map */
425: extern kern_return_t vm_map_copyout(vm_map_t, vm_offset_t *, vm_map_copy_t);
426: /* Overwrite existing memory with a copy */
427: extern kern_return_t vm_map_copy_overwrite(vm_map_t, vm_offset_t,
428: vm_map_copy_t, boolean_t);
429: /* Discard a copy without using it */
430: extern void vm_map_copy_discard(vm_map_copy_t);
431: extern void vm_map_copy_page_discard(vm_map_copy_t);
432: extern vm_map_copy_t vm_map_copy_copy(vm_map_copy_t);
433: /* Page list continuation version of previous */
434: extern kern_return_t vm_map_copy_discard_cont(vm_map_copyin_args_t,
435: vm_map_copy_t *);
436:
437: /* Add or remove machine- dependent attributes from map regions */
438: extern kern_return_t vm_map_machine_attribute(vm_map_t, vm_offset_t,
439: vm_size_t,
440: vm_machine_attribute_t,
441: vm_machine_attribute_val_t *);
442:
443: /* Delete entry from map */
444: extern void vm_map_entry_delete(vm_map_t, vm_map_entry_t);
1.1 root 445:
1.1.1.4 root 446: kern_return_t vm_map_delete(
447: vm_map_t map,
448: vm_offset_t start,
449: vm_offset_t end);
450:
451: kern_return_t vm_map_copyout_page_list(
452: vm_map_t dst_map,
453: vm_offset_t *dst_addr, /* OUT */
454: vm_map_copy_t copy);
455:
456: void vm_map_copy_page_discard (vm_map_copy_t copy);
457:
458: boolean_t vm_map_lookup_entry(
459: vm_map_t map,
460: vm_offset_t address,
461: vm_map_entry_t *entry); /* OUT */
462:
1.1.1.7 ! root 463: static inline void vm_map_set_name(vm_map_t map, const char *name)
! 464: {
! 465: map->name = name;
! 466: }
! 467:
! 468:
1.1 root 469: /*
470: * Functions implemented as macros
471: */
472: #define vm_map_min(map) ((map)->min_offset)
473: /* Lowest valid address in
474: * a map */
475:
476: #define vm_map_max(map) ((map)->max_offset)
477: /* Highest valid address */
478:
479: #define vm_map_pmap(map) ((map)->pmap)
480: /* Physical map associated
481: * with this address map */
482:
483: #define vm_map_verify_done(map, version) (vm_map_unlock_read(map))
484: /* Operation that required
485: * a verified lookup is
486: * now complete */
487: /*
488: * Pageability functions. Includes macro to preserve old interface.
489: */
1.1.1.3 root 490: extern kern_return_t vm_map_pageable_common(vm_map_t, vm_offset_t,
491: vm_offset_t, vm_prot_t,
492: boolean_t);
1.1 root 493:
494: #define vm_map_pageable(map, s, e, access) \
495: vm_map_pageable_common(map, s, e, access, FALSE)
496:
497: #define vm_map_pageable_user(map, s, e, access) \
498: vm_map_pageable_common(map, s, e, access, TRUE)
499:
500: /*
501: * Submap object. Must be used to create memory to be put
502: * in a submap by vm_map_submap.
503: */
504: extern vm_object_t vm_submap_object;
505:
506: /*
1.1.1.3 root 507: * vm_map_copyin_object:
508: *
509: * Create a copy object from an object.
510: * Our caller donates an object reference.
511: */
512: extern kern_return_t vm_map_copyin_object(
513: vm_object_t object,
514: vm_offset_t offset, /* offset of region in object */
515: vm_size_t size, /* size of region in object */
516: vm_map_copy_t *copy_result); /* OUT */
517:
518: /*
519: * vm_map_submap: [ kernel use only ]
520: *
521: * Mark the given range as handled by a subordinate map.
522: *
523: * This range must have been created with vm_map_find using
524: * the vm_submap_object, and no other operations may have been
525: * performed on this range prior to calling vm_map_submap.
526: *
527: * Only a limited number of operations can be performed
528: * within this rage after calling vm_map_submap:
529: * vm_fault
530: * [Don't try vm_map_copyin!]
531: *
532: * To remove a submapping, one must first remove the
533: * range from the superior map, and then destroy the
534: * submap (if desired). [Better yet, don't try it.]
535: */
536: extern kern_return_t vm_map_submap(
537: vm_map_t map,
538: vm_offset_t start,
539: vm_offset_t end,
540: vm_map_t submap);
541:
542: /*
1.1 root 543: * Wait and wakeup macros for in_transition map entries.
544: */
545: #define vm_map_entry_wait(map, interruptible) \
546: MACRO_BEGIN \
547: assert_wait((event_t)&(map)->hdr, interruptible); \
548: vm_map_unlock(map); \
549: thread_block((void (*)()) 0); \
550: MACRO_END
551:
552: #define vm_map_entry_wakeup(map) thread_wakeup((event_t)&(map)->hdr)
553:
1.1.1.3 root 554: /*
555: * This routine is called only when it is known that
556: * the entry must be split.
557: */
558: extern void _vm_map_clip_start(
559: struct vm_map_header *map_header,
560: vm_map_entry_t entry,
561: vm_offset_t start);
562:
563: /*
564: * vm_map_clip_end: [ internal use only ]
565: *
566: * Asserts that the given entry ends at or before
567: * the specified address; if necessary,
568: * it splits the entry into two.
569: */
1.1.1.4 root 570: void _vm_map_clip_end(
571: struct vm_map_header *map_header,
572: vm_map_entry_t entry,
573: vm_offset_t end);
1.1.1.3 root 574:
1.1.1.2 root 575: #endif /* _VM_VM_MAP_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.