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