lock_init => lockinit
[unix-history] / usr / src / sys / vm / vm_map.c
CommitLineData
175f072e 1/*
ad0f93d2
KB
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
175f072e
KM
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
0e24ad83 8 * %sccs.include.redist.c%
175f072e 9 *
6ba59261 10 * @(#)vm_map.c 8.7 (Berkeley) %G%
0e24ad83
KM
11 *
12 *
13 * Copyright (c) 1987, 1990 Carnegie-Mellon University.
14 * All rights reserved.
15 *
16 * Authors: Avadis Tevanian, Jr., Michael Wayne Young
17 *
18 * Permission to use, copy, modify and distribute this software and
19 * its documentation is hereby granted, provided that both the copyright
20 * notice and this permission notice appear in all copies of the
21 * software, derivative works or modified versions, and any portions
22 * thereof, and that both notices appear in supporting documentation.
23 *
24 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
25 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
26 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
27 *
28 * Carnegie Mellon requests users of this software to return to
29 *
30 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
31 * School of Computer Science
32 * Carnegie Mellon University
33 * Pittsburgh PA 15213-3890
34 *
35 * any improvements or extensions that they make and grant Carnegie the
36 * rights to redistribute these changes.
175f072e
KM
37 */
38
39/*
40 * Virtual memory mapping module.
41 */
42
73506ff8
KB
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/malloc.h>
46
47#include <vm/vm.h>
48#include <vm/vm_page.h>
175f072e
KM
49
50/*
51 * Virtual memory maps provide for the mapping, protection,
52 * and sharing of virtual memory objects. In addition,
53 * this module provides for an efficient virtual copy of
54 * memory from one map to another.
55 *
56 * Synchronization is required prior to most operations.
57 *
58 * Maps consist of an ordered doubly-linked list of simple
59 * entries; a single hint is used to speed up lookups.
60 *
61 * In order to properly represent the sharing of virtual
62 * memory regions among maps, the map structure is bi-level.
63 * Top-level ("address") maps refer to regions of sharable
64 * virtual memory. These regions are implemented as
65 * ("sharing") maps, which then refer to the actual virtual
66 * memory objects. When two address maps "share" memory,
67 * their top-level maps both have references to the same
68 * sharing map. When memory is virtual-copied from one
69 * address map to another, the references in the sharing
70 * maps are actually copied -- no copying occurs at the
71 * virtual memory object level.
72 *
73 * Since portions of maps are specified by start/end addreses,
74 * which may not align with existing map entries, all
75 * routines merely "clip" entries to these start/end values.
76 * [That is, an entry is split into two, bordering at a
77 * start or end value.] Note that these clippings may not
78 * always be necessary (as the two resulting entries are then
79 * not changed); however, the clipping is done for convenience.
80 * No attempt is currently made to "glue back together" two
81 * abutting entries.
82 *
83 * As mentioned above, virtual copy operations are performed
84 * by copying VM object references from one sharing map to
85 * another, and then marking both regions as copy-on-write.
86 * It is important to note that only one writeable reference
87 * to a VM object region exists in any map -- this means that
88 * shadow object creation can be delayed until a write operation
89 * occurs.
90 */
91
92/*
5d7b9ad3 93 * vm_map_startup:
175f072e
KM
94 *
95 * Initialize the vm_map module. Must be called before
96 * any other vm_map routines.
97 *
98 * Map and entry structures are allocated from the general
99 * purpose memory pool with some exceptions:
100 *
101 * - The kernel map and kmem submap are allocated statically.
102 * - Kernel map entries are allocated out of a static pool.
103 *
104 * These restrictions are necessary since malloc() uses the
105 * maps and requires map entries.
106 */
107
108vm_offset_t kentry_data;
109vm_size_t kentry_data_size;
110vm_map_entry_t kentry_free;
111vm_map_t kmap_free;
112
73506ff8
KB
113static void _vm_map_clip_end __P((vm_map_t, vm_map_entry_t, vm_offset_t));
114static void _vm_map_clip_start __P((vm_map_t, vm_map_entry_t, vm_offset_t));
115
e61c0b32
CD
116void
117vm_map_startup()
175f072e
KM
118{
119 register int i;
120 register vm_map_entry_t mep;
121 vm_map_t mp;
122
123 /*
124 * Static map structures for allocation before initialization of
125 * kernel map or kmem map. vm_map_create knows how to deal with them.
126 */
127 kmap_free = mp = (vm_map_t) kentry_data;
128 i = MAX_KMAP;
129 while (--i > 0) {
130 mp->header.next = (vm_map_entry_t) (mp + 1);
131 mp++;
132 }
5d7b9ad3 133 mp++->header.next = NULL;
175f072e
KM
134
135 /*
136 * Form a free list of statically allocated kernel map entries
137 * with the rest.
138 */
139 kentry_free = mep = (vm_map_entry_t) mp;
140 i = (kentry_data_size - MAX_KMAP * sizeof *mp) / sizeof *mep;
141 while (--i > 0) {
142 mep->next = mep + 1;
143 mep++;
144 }
5d7b9ad3
MK
145 mep->next = NULL;
146}
147
148/*
149 * Allocate a vmspace structure, including a vm_map and pmap,
150 * and initialize those structures. The refcnt is set to 1.
151 * The remaining fields must be initialized by the caller.
152 */
153struct vmspace *
154vmspace_alloc(min, max, pageable)
155 vm_offset_t min, max;
156 int pageable;
157{
158 register struct vmspace *vm;
159
160 MALLOC(vm, struct vmspace *, sizeof(struct vmspace), M_VMMAP, M_WAITOK);
161 bzero(vm, (caddr_t) &vm->vm_startcopy - (caddr_t) vm);
162 vm_map_init(&vm->vm_map, min, max, pageable);
163 pmap_pinit(&vm->vm_pmap);
164 vm->vm_map.pmap = &vm->vm_pmap; /* XXX */
165 vm->vm_refcnt = 1;
166 return (vm);
167}
168
169void
170vmspace_free(vm)
171 register struct vmspace *vm;
172{
173
174 if (--vm->vm_refcnt == 0) {
175 /*
176 * Lock the map, to wait out all other references to it.
177 * Delete all of the mappings and pages they hold,
178 * then call the pmap module to reclaim anything left.
179 */
180 vm_map_lock(&vm->vm_map);
181 (void) vm_map_delete(&vm->vm_map, vm->vm_map.min_offset,
182 vm->vm_map.max_offset);
183 pmap_release(&vm->vm_pmap);
184 FREE(vm, M_VMMAP);
185 }
175f072e
KM
186}
187
188/*
189 * vm_map_create:
190 *
191 * Creates and returns a new empty VM map with
192 * the given physical map structure, and having
193 * the given lower and upper address bounds.
194 */
e61c0b32
CD
195vm_map_t
196vm_map_create(pmap, min, max, pageable)
175f072e
KM
197 pmap_t pmap;
198 vm_offset_t min, max;
199 boolean_t pageable;
200{
201 register vm_map_t result;
67e8af50 202 extern vm_map_t kmem_map;
175f072e 203
5d7b9ad3 204 if (kmem_map == NULL) {
175f072e 205 result = kmap_free;
5d7b9ad3
MK
206 if (result == NULL)
207 panic("vm_map_create: out of maps");
e61c0b32 208 kmap_free = (vm_map_t) result->header.next;
175f072e
KM
209 } else
210 MALLOC(result, vm_map_t, sizeof(struct vm_map),
211 M_VMMAP, M_WAITOK);
212
5d7b9ad3 213 vm_map_init(result, min, max, pageable);
175f072e 214 result->pmap = pmap;
175f072e
KM
215 return(result);
216}
217
5d7b9ad3
MK
218/*
219 * Initialize an existing vm_map structure
220 * such as that in the vmspace structure.
221 * The pmap is set elsewhere.
222 */
223void
224vm_map_init(map, min, max, pageable)
225 register struct vm_map *map;
226 vm_offset_t min, max;
227 boolean_t pageable;
228{
229 map->header.next = map->header.prev = &map->header;
230 map->nentries = 0;
231 map->size = 0;
232 map->ref_count = 1;
233 map->is_main_map = TRUE;
234 map->min_offset = min;
235 map->max_offset = max;
236 map->entries_pageable = pageable;
237 map->first_free = &map->header;
238 map->hint = &map->header;
239 map->timestamp = 0;
6ba59261 240 lockinit(&map->lock, PVM, "thrd_sleep", 0, 0);
5d7b9ad3
MK
241 simple_lock_init(&map->ref_lock);
242 simple_lock_init(&map->hint_lock);
243}
244
175f072e
KM
245/*
246 * vm_map_entry_create: [ internal use only ]
247 *
248 * Allocates a VM map entry for insertion.
249 * No entry fields are filled in. This routine is
250 */
e61c0b32
CD
251vm_map_entry_t
252vm_map_entry_create(map)
175f072e
KM
253 vm_map_t map;
254{
255 vm_map_entry_t entry;
5a11d901 256#ifdef DEBUG
931302a1 257 extern vm_map_t kernel_map, kmem_map, mb_map, pager_map;
5a11d901 258 boolean_t isspecial;
175f072e 259
5a11d901
MH
260 isspecial = (map == kernel_map || map == kmem_map ||
261 map == mb_map || map == pager_map);
262 if (isspecial && map->entries_pageable ||
263 !isspecial && !map->entries_pageable)
264 panic("vm_map_entry_create: bogus map");
265#endif
266 if (map->entries_pageable) {
175f072e
KM
267 MALLOC(entry, vm_map_entry_t, sizeof(struct vm_map_entry),
268 M_VMMAPENT, M_WAITOK);
5a11d901
MH
269 } else {
270 if (entry = kentry_free)
271 kentry_free = kentry_free->next;
272 }
5d7b9ad3 273 if (entry == NULL)
175f072e
KM
274 panic("vm_map_entry_create: out of map entries");
275
276 return(entry);
277}
278
279/*
280 * vm_map_entry_dispose: [ internal use only ]
281 *
282 * Inverse of vm_map_entry_create.
283 */
e61c0b32
CD
284void
285vm_map_entry_dispose(map, entry)
175f072e
KM
286 vm_map_t map;
287 vm_map_entry_t entry;
288{
5a11d901 289#ifdef DEBUG
931302a1 290 extern vm_map_t kernel_map, kmem_map, mb_map, pager_map;
5a11d901 291 boolean_t isspecial;
175f072e 292
5a11d901
MH
293 isspecial = (map == kernel_map || map == kmem_map ||
294 map == mb_map || map == pager_map);
295 if (isspecial && map->entries_pageable ||
296 !isspecial && !map->entries_pageable)
297 panic("vm_map_entry_dispose: bogus map");
298#endif
299 if (map->entries_pageable) {
300 FREE(entry, M_VMMAPENT);
301 } else {
175f072e
KM
302 entry->next = kentry_free;
303 kentry_free = entry;
5a11d901 304 }
175f072e
KM
305}
306
307/*
308 * vm_map_entry_{un,}link:
309 *
310 * Insert/remove entries from maps.
311 */
312#define vm_map_entry_link(map, after_where, entry) \
313 { \
314 (map)->nentries++; \
315 (entry)->prev = (after_where); \
316 (entry)->next = (after_where)->next; \
317 (entry)->prev->next = (entry); \
318 (entry)->next->prev = (entry); \
319 }
320#define vm_map_entry_unlink(map, entry) \
321 { \
322 (map)->nentries--; \
323 (entry)->next->prev = (entry)->prev; \
324 (entry)->prev->next = (entry)->next; \
325 }
326
327/*
328 * vm_map_reference:
329 *
330 * Creates another valid reference to the given map.
331 *
332 */
e61c0b32
CD
333void
334vm_map_reference(map)
175f072e
KM
335 register vm_map_t map;
336{
5d7b9ad3 337 if (map == NULL)
175f072e
KM
338 return;
339
340 simple_lock(&map->ref_lock);
341 map->ref_count++;
342 simple_unlock(&map->ref_lock);
343}
344
345/*
346 * vm_map_deallocate:
347 *
348 * Removes a reference from the specified map,
349 * destroying it if no references remain.
350 * The map should not be locked.
351 */
e61c0b32
CD
352void
353vm_map_deallocate(map)
175f072e
KM
354 register vm_map_t map;
355{
356 register int c;
357
5d7b9ad3 358 if (map == NULL)
175f072e
KM
359 return;
360
361 simple_lock(&map->ref_lock);
362 c = --map->ref_count;
363 simple_unlock(&map->ref_lock);
364
365 if (c > 0) {
366 return;
367 }
368
369 /*
370 * Lock the map, to wait out all other references
371 * to it.
372 */
373
374 vm_map_lock(map);
375
376 (void) vm_map_delete(map, map->min_offset, map->max_offset);
377
378 pmap_destroy(map->pmap);
379
380 FREE(map, M_VMMAP);
381}
382
383/*
5a11d901 384 * vm_map_insert:
175f072e
KM
385 *
386 * Inserts the given whole VM object into the target
387 * map at the specified address range. The object's
388 * size should match that of the address range.
389 *
390 * Requires that the map be locked, and leaves it so.
391 */
73506ff8 392int
175f072e
KM
393vm_map_insert(map, object, offset, start, end)
394 vm_map_t map;
395 vm_object_t object;
396 vm_offset_t offset;
397 vm_offset_t start;
398 vm_offset_t end;
399{
400 register vm_map_entry_t new_entry;
401 register vm_map_entry_t prev_entry;
402 vm_map_entry_t temp_entry;
403
404 /*
405 * Check that the start and end points are not bogus.
406 */
407
408 if ((start < map->min_offset) || (end > map->max_offset) ||
409 (start >= end))
410 return(KERN_INVALID_ADDRESS);
411
412 /*
413 * Find the entry prior to the proposed
414 * starting address; if it's part of an
415 * existing entry, this range is bogus.
416 */
417
418 if (vm_map_lookup_entry(map, start, &temp_entry))
419 return(KERN_NO_SPACE);
420
421 prev_entry = temp_entry;
422
423 /*
424 * Assert that the next entry doesn't overlap the
425 * end point.
426 */
427
428 if ((prev_entry->next != &map->header) &&
429 (prev_entry->next->start < end))
430 return(KERN_NO_SPACE);
431
432 /*
433 * See if we can avoid creating a new entry by
434 * extending one of our neighbors.
435 */
436
5d7b9ad3 437 if (object == NULL) {
175f072e
KM
438 if ((prev_entry != &map->header) &&
439 (prev_entry->end == start) &&
440 (map->is_main_map) &&
441 (prev_entry->is_a_map == FALSE) &&
442 (prev_entry->is_sub_map == FALSE) &&
443 (prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
444 (prev_entry->protection == VM_PROT_DEFAULT) &&
445 (prev_entry->max_protection == VM_PROT_DEFAULT) &&
446 (prev_entry->wired_count == 0)) {
447
448 if (vm_object_coalesce(prev_entry->object.vm_object,
5d7b9ad3 449 NULL,
175f072e
KM
450 prev_entry->offset,
451 (vm_offset_t) 0,
452 (vm_size_t)(prev_entry->end
453 - prev_entry->start),
454 (vm_size_t)(end - prev_entry->end))) {
455 /*
456 * Coalesced the two objects - can extend
457 * the previous map entry to include the
458 * new range.
459 */
460 map->size += (end - prev_entry->end);
461 prev_entry->end = end;
462 return(KERN_SUCCESS);
463 }
464 }
465 }
466
467 /*
468 * Create a new entry
469 */
470
471 new_entry = vm_map_entry_create(map);
472 new_entry->start = start;
473 new_entry->end = end;
474
475 new_entry->is_a_map = FALSE;
476 new_entry->is_sub_map = FALSE;
477 new_entry->object.vm_object = object;
478 new_entry->offset = offset;
479
480 new_entry->copy_on_write = FALSE;
481 new_entry->needs_copy = FALSE;
482
483 if (map->is_main_map) {
484 new_entry->inheritance = VM_INHERIT_DEFAULT;
485 new_entry->protection = VM_PROT_DEFAULT;
486 new_entry->max_protection = VM_PROT_DEFAULT;
487 new_entry->wired_count = 0;
488 }
489
490 /*
491 * Insert the new entry into the list
492 */
493
494 vm_map_entry_link(map, prev_entry, new_entry);
495 map->size += new_entry->end - new_entry->start;
496
497 /*
498 * Update the free space hint
499 */
500
501 if ((map->first_free == prev_entry) && (prev_entry->end >= new_entry->start))
502 map->first_free = new_entry;
503
504 return(KERN_SUCCESS);
505}
506
507/*
508 * SAVE_HINT:
509 *
510 * Saves the specified entry as the hint for
511 * future lookups. Performs necessary interlocks.
512 */
513#define SAVE_HINT(map,value) \
514 simple_lock(&(map)->hint_lock); \
515 (map)->hint = (value); \
516 simple_unlock(&(map)->hint_lock);
517
518/*
519 * vm_map_lookup_entry: [ internal use only ]
520 *
521 * Finds the map entry containing (or
522 * immediately preceding) the specified address
523 * in the given map; the entry is returned
524 * in the "entry" parameter. The boolean
525 * result indicates whether the address is
526 * actually contained in the map.
527 */
e61c0b32
CD
528boolean_t
529vm_map_lookup_entry(map, address, entry)
175f072e
KM
530 register vm_map_t map;
531 register vm_offset_t address;
532 vm_map_entry_t *entry; /* OUT */
533{
534 register vm_map_entry_t cur;
535 register vm_map_entry_t last;
536
537 /*
538 * Start looking either from the head of the
539 * list, or from the hint.
540 */
541
542 simple_lock(&map->hint_lock);
543 cur = map->hint;
544 simple_unlock(&map->hint_lock);
545
546 if (cur == &map->header)
547 cur = cur->next;
548
549 if (address >= cur->start) {
550 /*
551 * Go from hint to end of list.
552 *
553 * But first, make a quick check to see if
554 * we are already looking at the entry we
555 * want (which is usually the case).
556 * Note also that we don't need to save the hint
557 * here... it is the same hint (unless we are
558 * at the header, in which case the hint didn't
559 * buy us anything anyway).
560 */
561 last = &map->header;
562 if ((cur != last) && (cur->end > address)) {
563 *entry = cur;
564 return(TRUE);
565 }
566 }
567 else {
568 /*
569 * Go from start to hint, *inclusively*
570 */
571 last = cur->next;
572 cur = map->header.next;
573 }
574
575 /*
576 * Search linearly
577 */
578
579 while (cur != last) {
580 if (cur->end > address) {
581 if (address >= cur->start) {
582 /*
583 * Save this lookup for future
584 * hints, and return
585 */
586
587 *entry = cur;
588 SAVE_HINT(map, cur);
589 return(TRUE);
590 }
591 break;
592 }
593 cur = cur->next;
594 }
595 *entry = cur->prev;
596 SAVE_HINT(map, *entry);
597 return(FALSE);
598}
599
fc8007a4
CT
600/*
601 * Find sufficient space for `length' bytes in the given map, starting at
602 * `start'. The map must be locked. Returns 0 on success, 1 on no space.
603 */
604int
605vm_map_findspace(map, start, length, addr)
606 register vm_map_t map;
607 register vm_offset_t start;
608 vm_size_t length;
609 vm_offset_t *addr;
610{
611 register vm_map_entry_t entry, next;
612 register vm_offset_t end;
613
614 if (start < map->min_offset)
615 start = map->min_offset;
616 if (start > map->max_offset)
617 return (1);
618
619 /*
620 * Look for the first possible address; if there's already
621 * something at this address, we have to start after it.
622 */
623 if (start == map->min_offset) {
624 if ((entry = map->first_free) != &map->header)
625 start = entry->end;
626 } else {
627 vm_map_entry_t tmp;
628 if (vm_map_lookup_entry(map, start, &tmp))
629 start = tmp->end;
630 entry = tmp;
631 }
632
633 /*
634 * Look through the rest of the map, trying to fit a new region in
635 * the gap between existing regions, or after the very last region.
636 */
637 for (;; start = (entry = next)->end) {
638 /*
639 * Find the end of the proposed new region. Be sure we didn't
640 * go beyond the end of the map, or wrap around the address;
641 * if so, we lose. Otherwise, if this is the last entry, or
642 * if the proposed new region fits before the next entry, we
643 * win.
644 */
645 end = start + length;
646 if (end > map->max_offset || end < start)
647 return (1);
648 next = entry->next;
649 if (next == &map->header || next->start >= end)
650 break;
651 }
652 SAVE_HINT(map, entry);
653 *addr = start;
654 return (0);
655}
656
175f072e
KM
657/*
658 * vm_map_find finds an unallocated region in the target address
659 * map with the given length. The search is defined to be
660 * first-fit from the specified address; the region found is
661 * returned in the same parameter.
662 *
663 */
73506ff8 664int
175f072e
KM
665vm_map_find(map, object, offset, addr, length, find_space)
666 vm_map_t map;
667 vm_object_t object;
668 vm_offset_t offset;
669 vm_offset_t *addr; /* IN/OUT */
670 vm_size_t length;
671 boolean_t find_space;
672{
175f072e 673 register vm_offset_t start;
175f072e
KM
674 int result;
675
676 start = *addr;
175f072e 677 vm_map_lock(map);
175f072e 678 if (find_space) {
fc8007a4 679 if (vm_map_findspace(map, start, length, addr)) {
175f072e
KM
680 vm_map_unlock(map);
681 return (KERN_NO_SPACE);
682 }
fc8007a4 683 start = *addr;
175f072e 684 }
175f072e 685 result = vm_map_insert(map, object, offset, start, start + length);
175f072e 686 vm_map_unlock(map);
fc8007a4 687 return (result);
175f072e
KM
688}
689
690/*
691 * vm_map_simplify_entry: [ internal use only ]
692 *
693 * Simplify the given map entry by:
694 * removing extra sharing maps
695 * [XXX maybe later] merging with a neighbor
696 */
e61c0b32
CD
697void
698vm_map_simplify_entry(map, entry)
175f072e
KM
699 vm_map_t map;
700 vm_map_entry_t entry;
701{
702#ifdef lint
703 map++;
1524bcb8 704#endif
175f072e
KM
705
706 /*
707 * If this entry corresponds to a sharing map, then
708 * see if we can remove the level of indirection.
709 * If it's not a sharing map, then it points to
710 * a VM object, so see if we can merge with either
711 * of our neighbors.
712 */
713
714 if (entry->is_sub_map)
715 return;
716 if (entry->is_a_map) {
717#if 0
718 vm_map_t my_share_map;
719 int count;
720
721 my_share_map = entry->object.share_map;
722 simple_lock(&my_share_map->ref_lock);
723 count = my_share_map->ref_count;
724 simple_unlock(&my_share_map->ref_lock);
725
726 if (count == 1) {
727 /* Can move the region from
728 * entry->start to entry->end (+ entry->offset)
729 * in my_share_map into place of entry.
730 * Later.
731 */
732 }
1524bcb8 733#endif
175f072e
KM
734 }
735 else {
736 /*
737 * Try to merge with our neighbors.
738 *
739 * Conditions for merge are:
740 *
741 * 1. entries are adjacent.
742 * 2. both entries point to objects
743 * with null pagers.
744 *
745 * If a merge is possible, we replace the two
746 * entries with a single entry, then merge
747 * the two objects into a single object.
748 *
749 * Now, all that is left to do is write the
750 * code!
751 */
752 }
753}
754
755/*
756 * vm_map_clip_start: [ internal use only ]
757 *
758 * Asserts that the given entry begins at or after
759 * the specified address; if necessary,
760 * it splits the entry into two.
761 */
762#define vm_map_clip_start(map, entry, startaddr) \
763{ \
764 if (startaddr > entry->start) \
765 _vm_map_clip_start(map, entry, startaddr); \
766}
767
768/*
769 * This routine is called only when it is known that
770 * the entry must be split.
771 */
e61c0b32
CD
772static void
773_vm_map_clip_start(map, entry, start)
175f072e
KM
774 register vm_map_t map;
775 register vm_map_entry_t entry;
776 register vm_offset_t start;
777{
778 register vm_map_entry_t new_entry;
779
780 /*
781 * See if we can simplify this entry first
782 */
783
784 vm_map_simplify_entry(map, entry);
785
786 /*
787 * Split off the front portion --
788 * note that we must insert the new
789 * entry BEFORE this one, so that
790 * this entry has the specified starting
791 * address.
792 */
793
794 new_entry = vm_map_entry_create(map);
795 *new_entry = *entry;
796
797 new_entry->end = start;
798 entry->offset += (start - entry->start);
799 entry->start = start;
800
801 vm_map_entry_link(map, entry->prev, new_entry);
802
803 if (entry->is_a_map || entry->is_sub_map)
804 vm_map_reference(new_entry->object.share_map);
805 else
806 vm_object_reference(new_entry->object.vm_object);
807}
808
809/*
810 * vm_map_clip_end: [ internal use only ]
811 *
812 * Asserts that the given entry ends at or before
813 * the specified address; if necessary,
814 * it splits the entry into two.
815 */
816
175f072e
KM
817#define vm_map_clip_end(map, entry, endaddr) \
818{ \
819 if (endaddr < entry->end) \
820 _vm_map_clip_end(map, entry, endaddr); \
821}
822
823/*
824 * This routine is called only when it is known that
825 * the entry must be split.
826 */
e61c0b32
CD
827static void
828_vm_map_clip_end(map, entry, end)
175f072e
KM
829 register vm_map_t map;
830 register vm_map_entry_t entry;
831 register vm_offset_t end;
832{
833 register vm_map_entry_t new_entry;
834
835 /*
836 * Create a new entry and insert it
837 * AFTER the specified entry
838 */
839
840 new_entry = vm_map_entry_create(map);
841 *new_entry = *entry;
842
843 new_entry->start = entry->end = end;
844 new_entry->offset += (end - entry->start);
845
846 vm_map_entry_link(map, entry, new_entry);
847
848 if (entry->is_a_map || entry->is_sub_map)
849 vm_map_reference(new_entry->object.share_map);
850 else
851 vm_object_reference(new_entry->object.vm_object);
852}
853
854/*
855 * VM_MAP_RANGE_CHECK: [ internal use only ]
856 *
857 * Asserts that the starting and ending region
858 * addresses fall within the valid range of the map.
859 */
860#define VM_MAP_RANGE_CHECK(map, start, end) \
861 { \
862 if (start < vm_map_min(map)) \
863 start = vm_map_min(map); \
864 if (end > vm_map_max(map)) \
865 end = vm_map_max(map); \
866 if (start > end) \
867 start = end; \
868 }
869
870/*
871 * vm_map_submap: [ kernel use only ]
872 *
873 * Mark the given range as handled by a subordinate map.
874 *
875 * This range must have been created with vm_map_find,
876 * and no other operations may have been performed on this
877 * range prior to calling vm_map_submap.
878 *
879 * Only a limited number of operations can be performed
880 * within this rage after calling vm_map_submap:
881 * vm_fault
882 * [Don't try vm_map_copy!]
883 *
884 * To remove a submapping, one must first remove the
885 * range from the superior map, and then destroy the
886 * submap (if desired). [Better yet, don't try it.]
887 */
73506ff8 888int
175f072e
KM
889vm_map_submap(map, start, end, submap)
890 register vm_map_t map;
891 register vm_offset_t start;
892 register vm_offset_t end;
893 vm_map_t submap;
894{
895 vm_map_entry_t entry;
896 register int result = KERN_INVALID_ARGUMENT;
897
898 vm_map_lock(map);
899
900 VM_MAP_RANGE_CHECK(map, start, end);
901
902 if (vm_map_lookup_entry(map, start, &entry)) {
903 vm_map_clip_start(map, entry, start);
904 }
905 else
906 entry = entry->next;
907
908 vm_map_clip_end(map, entry, end);
909
910 if ((entry->start == start) && (entry->end == end) &&
911 (!entry->is_a_map) &&
5d7b9ad3 912 (entry->object.vm_object == NULL) &&
175f072e
KM
913 (!entry->copy_on_write)) {
914 entry->is_a_map = FALSE;
915 entry->is_sub_map = TRUE;
916 vm_map_reference(entry->object.sub_map = submap);
917 result = KERN_SUCCESS;
918 }
919 vm_map_unlock(map);
920
921 return(result);
922}
923
924/*
925 * vm_map_protect:
926 *
927 * Sets the protection of the specified address
928 * region in the target map. If "set_max" is
929 * specified, the maximum protection is to be set;
930 * otherwise, only the current protection is affected.
931 */
73506ff8 932int
175f072e
KM
933vm_map_protect(map, start, end, new_prot, set_max)
934 register vm_map_t map;
935 register vm_offset_t start;
936 register vm_offset_t end;
937 register vm_prot_t new_prot;
938 register boolean_t set_max;
939{
940 register vm_map_entry_t current;
941 vm_map_entry_t entry;
942
943 vm_map_lock(map);
944
945 VM_MAP_RANGE_CHECK(map, start, end);
946
947 if (vm_map_lookup_entry(map, start, &entry)) {
948 vm_map_clip_start(map, entry, start);
949 }
950 else
951 entry = entry->next;
952
953 /*
954 * Make a first pass to check for protection
955 * violations.
956 */
957
958 current = entry;
959 while ((current != &map->header) && (current->start < end)) {
960 if (current->is_sub_map)
961 return(KERN_INVALID_ARGUMENT);
962 if ((new_prot & current->max_protection) != new_prot) {
963 vm_map_unlock(map);
964 return(KERN_PROTECTION_FAILURE);
965 }
966
967 current = current->next;
968 }
969
970 /*
971 * Go back and fix up protections.
972 * [Note that clipping is not necessary the second time.]
973 */
974
975 current = entry;
976
977 while ((current != &map->header) && (current->start < end)) {
978 vm_prot_t old_prot;
979
980 vm_map_clip_end(map, current, end);
981
982 old_prot = current->protection;
983 if (set_max)
984 current->protection =
985 (current->max_protection = new_prot) &
986 old_prot;
987 else
988 current->protection = new_prot;
989
990 /*
991 * Update physical map if necessary.
992 * Worry about copy-on-write here -- CHECK THIS XXX
993 */
994
995 if (current->protection != old_prot) {
996
997#define MASK(entry) ((entry)->copy_on_write ? ~VM_PROT_WRITE : \
998 VM_PROT_ALL)
999#define max(a,b) ((a) > (b) ? (a) : (b))
1000
1001 if (current->is_a_map) {
1002 vm_map_entry_t share_entry;
1003 vm_offset_t share_end;
1004
1005 vm_map_lock(current->object.share_map);
1006 (void) vm_map_lookup_entry(
1007 current->object.share_map,
1008 current->offset,
1009 &share_entry);
1010 share_end = current->offset +
1011 (current->end - current->start);
1012 while ((share_entry !=
1013 &current->object.share_map->header) &&
1014 (share_entry->start < share_end)) {
1015
1016 pmap_protect(map->pmap,
1017 (max(share_entry->start,
1018 current->offset) -
1019 current->offset +
1020 current->start),
1021 min(share_entry->end,
1022 share_end) -
1023 current->offset +
1024 current->start,
1025 current->protection &
1026 MASK(share_entry));
1027
1028 share_entry = share_entry->next;
1029 }
1030 vm_map_unlock(current->object.share_map);
1031 }
1032 else
1033 pmap_protect(map->pmap, current->start,
1034 current->end,
1035 current->protection & MASK(entry));
1036#undef max
1037#undef MASK
1038 }
1039 current = current->next;
1040 }
1041
1042 vm_map_unlock(map);
1043 return(KERN_SUCCESS);
1044}
1045
1046/*
1047 * vm_map_inherit:
1048 *
1049 * Sets the inheritance of the specified address
1050 * range in the target map. Inheritance
1051 * affects how the map will be shared with
1052 * child maps at the time of vm_map_fork.
1053 */
73506ff8 1054int
175f072e
KM
1055vm_map_inherit(map, start, end, new_inheritance)
1056 register vm_map_t map;
1057 register vm_offset_t start;
1058 register vm_offset_t end;
1059 register vm_inherit_t new_inheritance;
1060{
1061 register vm_map_entry_t entry;
1062 vm_map_entry_t temp_entry;
1063
1064 switch (new_inheritance) {
1065 case VM_INHERIT_NONE:
1066 case VM_INHERIT_COPY:
1067 case VM_INHERIT_SHARE:
1068 break;
1069 default:
1070 return(KERN_INVALID_ARGUMENT);
1071 }
1072
1073 vm_map_lock(map);
1074
1075 VM_MAP_RANGE_CHECK(map, start, end);
1076
1077 if (vm_map_lookup_entry(map, start, &temp_entry)) {
1078 entry = temp_entry;
1079 vm_map_clip_start(map, entry, start);
1080 }
1081 else
1082 entry = temp_entry->next;
1083
1084 while ((entry != &map->header) && (entry->start < end)) {
1085 vm_map_clip_end(map, entry, end);
1086
1087 entry->inheritance = new_inheritance;
1088
1089 entry = entry->next;
1090 }
1091
1092 vm_map_unlock(map);
1093 return(KERN_SUCCESS);
1094}
1095
1096/*
1097 * vm_map_pageable:
1098 *
1099 * Sets the pageability of the specified address
1100 * range in the target map. Regions specified
1101 * as not pageable require locked-down physical
1102 * memory and physical page maps.
1103 *
1104 * The map must not be locked, but a reference
1105 * must remain to the map throughout the call.
1106 */
73506ff8 1107int
175f072e
KM
1108vm_map_pageable(map, start, end, new_pageable)
1109 register vm_map_t map;
1110 register vm_offset_t start;
1111 register vm_offset_t end;
1112 register boolean_t new_pageable;
1113{
1114 register vm_map_entry_t entry;
b5246c21 1115 vm_map_entry_t start_entry;
d4f41bb2
MH
1116 register vm_offset_t failed;
1117 int rv;
175f072e
KM
1118
1119 vm_map_lock(map);
1120
1121 VM_MAP_RANGE_CHECK(map, start, end);
1122
1123 /*
1124 * Only one pageability change may take place at one
1125 * time, since vm_fault assumes it will be called
1126 * only once for each wiring/unwiring. Therefore, we
1127 * have to make sure we're actually changing the pageability
1128 * for the entire region. We do so before making any changes.
1129 */
1130
b5246c21
MH
1131 if (vm_map_lookup_entry(map, start, &start_entry) == FALSE) {
1132 vm_map_unlock(map);
1133 return(KERN_INVALID_ADDRESS);
175f072e 1134 }
b5246c21 1135 entry = start_entry;
175f072e
KM
1136
1137 /*
1138 * Actions are rather different for wiring and unwiring,
1139 * so we have two separate cases.
1140 */
1141
1142 if (new_pageable) {
1143
b5246c21
MH
1144 vm_map_clip_start(map, entry, start);
1145
175f072e
KM
1146 /*
1147 * Unwiring. First ensure that the range to be
b5246c21
MH
1148 * unwired is really wired down and that there
1149 * are no holes.
175f072e
KM
1150 */
1151 while ((entry != &map->header) && (entry->start < end)) {
1152
b5246c21
MH
1153 if (entry->wired_count == 0 ||
1154 (entry->end < end &&
1155 (entry->next == &map->header ||
1156 entry->next->start > entry->end))) {
175f072e
KM
1157 vm_map_unlock(map);
1158 return(KERN_INVALID_ARGUMENT);
1159 }
1160 entry = entry->next;
1161 }
1162
1163 /*
1164 * Now decrement the wiring count for each region.
1165 * If a region becomes completely unwired,
1166 * unwire its physical pages and mappings.
1167 */
9587183e 1168 vm_map_set_recursive(&map->lock);
175f072e 1169
b5246c21 1170 entry = start_entry;
175f072e
KM
1171 while ((entry != &map->header) && (entry->start < end)) {
1172 vm_map_clip_end(map, entry, end);
1173
1174 entry->wired_count--;
1175 if (entry->wired_count == 0)
1176 vm_fault_unwire(map, entry->start, entry->end);
1177
1178 entry = entry->next;
1179 }
9587183e 1180 vm_map_clear_recursive(&map->lock);
175f072e
KM
1181 }
1182
1183 else {
1184 /*
1185 * Wiring. We must do this in two passes:
1186 *
b5246c21
MH
1187 * 1. Holding the write lock, we create any shadow
1188 * or zero-fill objects that need to be created.
1189 * Then we clip each map entry to the region to be
1190 * wired and increment its wiring count. We
1191 * create objects before clipping the map entries
1192 * to avoid object proliferation.
175f072e
KM
1193 *
1194 * 2. We downgrade to a read lock, and call
1195 * vm_fault_wire to fault in the pages for any
1196 * newly wired area (wired_count is 1).
1197 *
1198 * Downgrading to a read lock for vm_fault_wire avoids
1199 * a possible deadlock with another thread that may have
1200 * faulted on one of the pages to be wired (it would mark
1201 * the page busy, blocking us, then in turn block on the
1202 * map lock that we hold). Because of problems in the
1203 * recursive lock package, we cannot upgrade to a write
1204 * lock in vm_map_lookup. Thus, any actions that require
1205 * the write lock must be done beforehand. Because we
1206 * keep the read lock on the map, the copy-on-write status
1207 * of the entries we modify here cannot change.
1208 */
1209
1210 /*
1211 * Pass 1.
1212 */
175f072e 1213 while ((entry != &map->header) && (entry->start < end)) {
b5246c21 1214 if (entry->wired_count == 0) {
175f072e
KM
1215
1216 /*
1217 * Perform actions of vm_map_lookup that need
1218 * the write lock on the map: create a shadow
1219 * object for a copy-on-write region, or an
1220 * object for a zero-fill region.
1221 *
1222 * We don't have to do this for entries that
1223 * point to sharing maps, because we won't hold
1224 * the lock on the sharing map.
1225 */
1226 if (!entry->is_a_map) {
1227 if (entry->needs_copy &&
1228 ((entry->protection & VM_PROT_WRITE) != 0)) {
1229
1230 vm_object_shadow(&entry->object.vm_object,
1231 &entry->offset,
1232 (vm_size_t)(entry->end
1233 - entry->start));
1234 entry->needs_copy = FALSE;
1235 }
5d7b9ad3 1236 else if (entry->object.vm_object == NULL) {
175f072e
KM
1237 entry->object.vm_object =
1238 vm_object_allocate((vm_size_t)(entry->end
1239 - entry->start));
1240 entry->offset = (vm_offset_t)0;
1241 }
1242 }
1243 }
b5246c21
MH
1244 vm_map_clip_start(map, entry, start);
1245 vm_map_clip_end(map, entry, end);
1246 entry->wired_count++;
175f072e 1247
b5246c21
MH
1248 /*
1249 * Check for holes
1250 */
1251 if (entry->end < end &&
1252 (entry->next == &map->header ||
1253 entry->next->start > entry->end)) {
1254 /*
1255 * Found one. Object creation actions
1256 * do not need to be undone, but the
1257 * wired counts need to be restored.
1258 */
1259 while (entry != &map->header && entry->end > start) {
1260 entry->wired_count--;
1261 entry = entry->prev;
1262 }
1263 vm_map_unlock(map);
1264 return(KERN_INVALID_ARGUMENT);
1265 }
175f072e
KM
1266 entry = entry->next;
1267 }
1268
1269 /*
1270 * Pass 2.
1271 */
1272
1273 /*
1274 * HACK HACK HACK HACK
1275 *
1276 * If we are wiring in the kernel map or a submap of it,
1277 * unlock the map to avoid deadlocks. We trust that the
1278 * kernel threads are well-behaved, and therefore will
1279 * not do anything destructive to this region of the map
1280 * while we have it unlocked. We cannot trust user threads
1281 * to do the same.
1282 *
1283 * HACK HACK HACK HACK
1284 */
1285 if (vm_map_pmap(map) == kernel_pmap) {
1286 vm_map_unlock(map); /* trust me ... */
1287 }
1288 else {
9587183e 1289 vm_map_set_recursive(&map->lock);
89e4dee8 1290 lockmgr(&map->lock, LK_DOWNGRADE, (void *)0, LOCKPID);
175f072e
KM
1291 }
1292
d4f41bb2 1293 rv = 0;
b5246c21 1294 entry = start_entry;
175f072e 1295 while (entry != &map->header && entry->start < end) {
d4f41bb2
MH
1296 /*
1297 * If vm_fault_wire fails for any page we need to
1298 * undo what has been done. We decrement the wiring
1299 * count for those pages which have not yet been
1300 * wired (now) and unwire those that have (later).
1301 *
1302 * XXX this violates the locking protocol on the map,
1303 * needs to be fixed.
1304 */
1305 if (rv)
1306 entry->wired_count--;
1307 else if (entry->wired_count == 1) {
1308 rv = vm_fault_wire(map, entry->start, entry->end);
1309 if (rv) {
1310 failed = entry->start;
1311 entry->wired_count--;
1312 }
175f072e
KM
1313 }
1314 entry = entry->next;
1315 }
1316
1317 if (vm_map_pmap(map) == kernel_pmap) {
1318 vm_map_lock(map);
1319 }
1320 else {
9587183e 1321 vm_map_clear_recursive(&map->lock);
175f072e 1322 }
d4f41bb2
MH
1323 if (rv) {
1324 vm_map_unlock(map);
1325 (void) vm_map_pageable(map, start, failed, TRUE);
1326 return(rv);
1327 }
175f072e
KM
1328 }
1329
1330 vm_map_unlock(map);
1331
1332 return(KERN_SUCCESS);
1333}
1334
5a11d901
MH
1335/*
1336 * vm_map_clean
1337 *
1338 * Push any dirty cached pages in the address range to their pager.
1339 * If syncio is TRUE, dirty pages are written synchronously.
1340 * If invalidate is TRUE, any cached pages are freed as well.
1341 *
1342 * Returns an error if any part of the specified range is not mapped.
1343 */
1344int
1345vm_map_clean(map, start, end, syncio, invalidate)
1346 vm_map_t map;
1347 vm_offset_t start;
1348 vm_offset_t end;
1349 boolean_t syncio;
1350 boolean_t invalidate;
1351{
1352 register vm_map_entry_t current;
1353 vm_map_entry_t entry;
1354 vm_size_t size;
1355 vm_object_t object;
1356 vm_offset_t offset;
1357
1358 vm_map_lock_read(map);
1359 VM_MAP_RANGE_CHECK(map, start, end);
1360 if (!vm_map_lookup_entry(map, start, &entry)) {
1361 vm_map_unlock_read(map);
1362 return(KERN_INVALID_ADDRESS);
1363 }
1364
1365 /*
1366 * Make a first pass to check for holes.
1367 */
1368 for (current = entry; current->start < end; current = current->next) {
1369 if (current->is_sub_map) {
1370 vm_map_unlock_read(map);
1371 return(KERN_INVALID_ARGUMENT);
1372 }
1373 if (end > current->end &&
1374 (current->next == &map->header ||
1375 current->end != current->next->start)) {
1376 vm_map_unlock_read(map);
1377 return(KERN_INVALID_ADDRESS);
1378 }
1379 }
1380
1381 /*
1382 * Make a second pass, cleaning/uncaching pages from the indicated
1383 * objects as we go.
1384 */
1385 for (current = entry; current->start < end; current = current->next) {
1386 offset = current->offset + (start - current->start);
1387 size = (end <= current->end ? end : current->end) - start;
1388 if (current->is_a_map) {
1389 register vm_map_t smap;
1390 vm_map_entry_t tentry;
1391 vm_size_t tsize;
1392
1393 smap = current->object.share_map;
1394 vm_map_lock_read(smap);
1395 (void) vm_map_lookup_entry(smap, offset, &tentry);
1396 tsize = tentry->end - offset;
1397 if (tsize < size)
1398 size = tsize;
1399 object = tentry->object.vm_object;
1400 offset = tentry->offset + (offset - tentry->start);
1401 vm_object_lock(object);
1402 vm_map_unlock_read(smap);
1403 } else {
1404 object = current->object.vm_object;
1405 vm_object_lock(object);
1406 }
1407 /*
1408 * Flush pages if writing is allowed.
1409 * XXX should we continue on an error?
1410 */
1411 if ((current->protection & VM_PROT_WRITE) &&
1412 !vm_object_page_clean(object, offset, offset+size,
1413 syncio, FALSE)) {
1414 vm_object_unlock(object);
1415 vm_map_unlock_read(map);
1416 return(KERN_FAILURE);
1417 }
1418 if (invalidate)
1419 vm_object_page_remove(object, offset, offset+size);
1420 vm_object_unlock(object);
1421 start += size;
1422 }
1423
1424 vm_map_unlock_read(map);
1425 return(KERN_SUCCESS);
1426}
1427
175f072e
KM
1428/*
1429 * vm_map_entry_unwire: [ internal use only ]
1430 *
1431 * Make the region specified by this entry pageable.
1432 *
1433 * The map in question should be locked.
1434 * [This is the reason for this routine's existence.]
1435 */
e61c0b32
CD
1436void
1437vm_map_entry_unwire(map, entry)
175f072e
KM
1438 vm_map_t map;
1439 register vm_map_entry_t entry;
1440{
1441 vm_fault_unwire(map, entry->start, entry->end);
1442 entry->wired_count = 0;
1443}
1444
1445/*
1446 * vm_map_entry_delete: [ internal use only ]
1447 *
1448 * Deallocate the given entry from the target map.
1449 */
e61c0b32
CD
1450void
1451vm_map_entry_delete(map, entry)
175f072e
KM
1452 register vm_map_t map;
1453 register vm_map_entry_t entry;
1454{
1455 if (entry->wired_count != 0)
1456 vm_map_entry_unwire(map, entry);
1457
1458 vm_map_entry_unlink(map, entry);
1459 map->size -= entry->end - entry->start;
1460
1461 if (entry->is_a_map || entry->is_sub_map)
1462 vm_map_deallocate(entry->object.share_map);
1463 else
1464 vm_object_deallocate(entry->object.vm_object);
1465
1466 vm_map_entry_dispose(map, entry);
1467}
1468
1469/*
1470 * vm_map_delete: [ internal use only ]
1471 *
1472 * Deallocates the given address range from the target
1473 * map.
1474 *
1475 * When called with a sharing map, removes pages from
1476 * that region from all physical maps.
1477 */
73506ff8 1478int
175f072e
KM
1479vm_map_delete(map, start, end)
1480 register vm_map_t map;
1481 vm_offset_t start;
1482 register vm_offset_t end;
1483{
1484 register vm_map_entry_t entry;
1485 vm_map_entry_t first_entry;
1486
1487 /*
1488 * Find the start of the region, and clip it
1489 */
1490
1491 if (!vm_map_lookup_entry(map, start, &first_entry))
1492 entry = first_entry->next;
1493 else {
1494 entry = first_entry;
1495 vm_map_clip_start(map, entry, start);
1496
1497 /*
1498 * Fix the lookup hint now, rather than each
1499 * time though the loop.
1500 */
1501
1502 SAVE_HINT(map, entry->prev);
1503 }
1504
1505 /*
1506 * Save the free space hint
1507 */
1508
1509 if (map->first_free->start >= start)
1510 map->first_free = entry->prev;
1511
1512 /*
1513 * Step through all entries in this region
1514 */
1515
1516 while ((entry != &map->header) && (entry->start < end)) {
1517 vm_map_entry_t next;
1518 register vm_offset_t s, e;
1519 register vm_object_t object;
1520
1521 vm_map_clip_end(map, entry, end);
1522
1523 next = entry->next;
1524 s = entry->start;
1525 e = entry->end;
1526
1527 /*
1528 * Unwire before removing addresses from the pmap;
1529 * otherwise, unwiring will put the entries back in
1530 * the pmap.
1531 */
1532
1533 object = entry->object.vm_object;
1534 if (entry->wired_count != 0)
1535 vm_map_entry_unwire(map, entry);
1536
1537 /*
1538 * If this is a sharing map, we must remove
1539 * *all* references to this data, since we can't
1540 * find all of the physical maps which are sharing
1541 * it.
1542 */
1543
1544 if (object == kernel_object || object == kmem_object)
1545 vm_object_page_remove(object, entry->offset,
1546 entry->offset + (e - s));
1547 else if (!map->is_main_map)
1548 vm_object_pmap_remove(object,
1549 entry->offset,
1550 entry->offset + (e - s));
1551 else
1552 pmap_remove(map->pmap, s, e);
1553
1554 /*
1555 * Delete the entry (which may delete the object)
1556 * only after removing all pmap entries pointing
1557 * to its pages. (Otherwise, its page frames may
1558 * be reallocated, and any modify bits will be
1559 * set in the wrong object!)
1560 */
1561
1562 vm_map_entry_delete(map, entry);
1563 entry = next;
1564 }
1565 return(KERN_SUCCESS);
1566}
1567
1568/*
1569 * vm_map_remove:
1570 *
1571 * Remove the given address range from the target map.
1572 * This is the exported form of vm_map_delete.
1573 */
73506ff8 1574int
175f072e
KM
1575vm_map_remove(map, start, end)
1576 register vm_map_t map;
1577 register vm_offset_t start;
1578 register vm_offset_t end;
1579{
1580 register int result;
1581
1582 vm_map_lock(map);
1583 VM_MAP_RANGE_CHECK(map, start, end);
1584 result = vm_map_delete(map, start, end);
1585 vm_map_unlock(map);
1586
1587 return(result);
1588}
1589
1590/*
1591 * vm_map_check_protection:
1592 *
1593 * Assert that the target map allows the specified
1594 * privilege on the entire address region given.
1595 * The entire region must be allocated.
1596 */
e61c0b32
CD
1597boolean_t
1598vm_map_check_protection(map, start, end, protection)
175f072e
KM
1599 register vm_map_t map;
1600 register vm_offset_t start;
1601 register vm_offset_t end;
1602 register vm_prot_t protection;
1603{
1604 register vm_map_entry_t entry;
1605 vm_map_entry_t tmp_entry;
1606
1607 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
1608 return(FALSE);
1609 }
1610
1611 entry = tmp_entry;
1612
1613 while (start < end) {
1614 if (entry == &map->header) {
1615 return(FALSE);
1616 }
1617
1618 /*
1619 * No holes allowed!
1620 */
1621
1622 if (start < entry->start) {
1623 return(FALSE);
1624 }
1625
1626 /*
1627 * Check protection associated with entry.
1628 */
1629
1630 if ((entry->protection & protection) != protection) {
1631 return(FALSE);
1632 }
1633
1634 /* go to next entry */
1635
1636 start = entry->end;
1637 entry = entry->next;
1638 }
1639 return(TRUE);
1640}
1641
1642/*
1643 * vm_map_copy_entry:
1644 *
1645 * Copies the contents of the source entry to the destination
1646 * entry. The entries *must* be aligned properly.
1647 */
e61c0b32
CD
1648void
1649vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
175f072e
KM
1650 vm_map_t src_map, dst_map;
1651 register vm_map_entry_t src_entry, dst_entry;
1652{
1653 vm_object_t temp_object;
1654
1655 if (src_entry->is_sub_map || dst_entry->is_sub_map)
1656 return;
1657
5d7b9ad3 1658 if (dst_entry->object.vm_object != NULL &&
224765a4 1659 (dst_entry->object.vm_object->flags & OBJ_INTERNAL) == 0)
175f072e
KM
1660 printf("vm_map_copy_entry: copying over permanent data!\n");
1661
1662 /*
1663 * If our destination map was wired down,
1664 * unwire it now.
1665 */
1666
1667 if (dst_entry->wired_count != 0)
1668 vm_map_entry_unwire(dst_map, dst_entry);
1669
1670 /*
1671 * If we're dealing with a sharing map, we
1672 * must remove the destination pages from
1673 * all maps (since we cannot know which maps
1674 * this sharing map belongs in).
1675 */
1676
1677 if (dst_map->is_main_map)
1678 pmap_remove(dst_map->pmap, dst_entry->start, dst_entry->end);
1679 else
1680 vm_object_pmap_remove(dst_entry->object.vm_object,
1681 dst_entry->offset,
1682 dst_entry->offset +
1683 (dst_entry->end - dst_entry->start));
1684
1685 if (src_entry->wired_count == 0) {
1686
1687 boolean_t src_needs_copy;
1688
1689 /*
1690 * If the source entry is marked needs_copy,
1691 * it is already write-protected.
1692 */
1693 if (!src_entry->needs_copy) {
1694
1695 boolean_t su;
1696
1697 /*
1698 * If the source entry has only one mapping,
1699 * we can just protect the virtual address
1700 * range.
1701 */
1702 if (!(su = src_map->is_main_map)) {
1703 simple_lock(&src_map->ref_lock);
1704 su = (src_map->ref_count == 1);
1705 simple_unlock(&src_map->ref_lock);
1706 }
1707
1708 if (su) {
1709 pmap_protect(src_map->pmap,
1710 src_entry->start,
1711 src_entry->end,
1712 src_entry->protection & ~VM_PROT_WRITE);
1713 }
1714 else {
1715 vm_object_pmap_copy(src_entry->object.vm_object,
1716 src_entry->offset,
1717 src_entry->offset + (src_entry->end
1718 -src_entry->start));
1719 }
1720 }
1721
1722 /*
1723 * Make a copy of the object.
1724 */
1725 temp_object = dst_entry->object.vm_object;
1726 vm_object_copy(src_entry->object.vm_object,
1727 src_entry->offset,
1728 (vm_size_t)(src_entry->end -
1729 src_entry->start),
1730 &dst_entry->object.vm_object,
1731 &dst_entry->offset,
1732 &src_needs_copy);
1733 /*
1734 * If we didn't get a copy-object now, mark the
1735 * source map entry so that a shadow will be created
1736 * to hold its changed pages.
1737 */
1738 if (src_needs_copy)
1739 src_entry->needs_copy = TRUE;
1740
1741 /*
1742 * The destination always needs to have a shadow
1743 * created.
1744 */
1745 dst_entry->needs_copy = TRUE;
1746
1747 /*
1748 * Mark the entries copy-on-write, so that write-enabling
1749 * the entry won't make copy-on-write pages writable.
1750 */
1751 src_entry->copy_on_write = TRUE;
1752 dst_entry->copy_on_write = TRUE;
1753 /*
1754 * Get rid of the old object.
1755 */
1756 vm_object_deallocate(temp_object);
1757
1758 pmap_copy(dst_map->pmap, src_map->pmap, dst_entry->start,
1759 dst_entry->end - dst_entry->start, src_entry->start);
1760 }
1761 else {
1762 /*
1763 * Of course, wired down pages can't be set copy-on-write.
1764 * Cause wired pages to be copied into the new
1765 * map by simulating faults (the new pages are
1766 * pageable)
1767 */
1768 vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry);
1769 }
1770}
1771
1772/*
1773 * vm_map_copy:
1774 *
1775 * Perform a virtual memory copy from the source
1776 * address map/range to the destination map/range.
1777 *
1778 * If src_destroy or dst_alloc is requested,
1779 * the source and destination regions should be
1780 * disjoint, not only in the top-level map, but
1781 * in the sharing maps as well. [The best way
1782 * to guarantee this is to use a new intermediate
1783 * map to make copies. This also reduces map
1784 * fragmentation.]
1785 */
73506ff8 1786int
175f072e
KM
1787vm_map_copy(dst_map, src_map,
1788 dst_addr, len, src_addr,
1789 dst_alloc, src_destroy)
1790 vm_map_t dst_map;
1791 vm_map_t src_map;
1792 vm_offset_t dst_addr;
1793 vm_size_t len;
1794 vm_offset_t src_addr;
1795 boolean_t dst_alloc;
1796 boolean_t src_destroy;
1797{
1798 register
1799 vm_map_entry_t src_entry;
1800 register
1801 vm_map_entry_t dst_entry;
1802 vm_map_entry_t tmp_entry;
1803 vm_offset_t src_start;
1804 vm_offset_t src_end;
1805 vm_offset_t dst_start;
1806 vm_offset_t dst_end;
1807 vm_offset_t src_clip;
1808 vm_offset_t dst_clip;
1809 int result;
1810 boolean_t old_src_destroy;
1811
1812 /*
1813 * XXX While we figure out why src_destroy screws up,
1814 * we'll do it by explicitly vm_map_delete'ing at the end.
1815 */
1816
1817 old_src_destroy = src_destroy;
1818 src_destroy = FALSE;
1819
1820 /*
1821 * Compute start and end of region in both maps
1822 */
1823
1824 src_start = src_addr;
1825 src_end = src_start + len;
1826 dst_start = dst_addr;
1827 dst_end = dst_start + len;
1828
1829 /*
1830 * Check that the region can exist in both source
1831 * and destination.
1832 */
1833
1834 if ((dst_end < dst_start) || (src_end < src_start))
1835 return(KERN_NO_SPACE);
1836
1837 /*
1838 * Lock the maps in question -- we avoid deadlock
1839 * by ordering lock acquisition by map value
1840 */
1841
1842 if (src_map == dst_map) {
1843 vm_map_lock(src_map);
1844 }
e61c0b32 1845 else if ((long) src_map < (long) dst_map) {
175f072e
KM
1846 vm_map_lock(src_map);
1847 vm_map_lock(dst_map);
1848 } else {
1849 vm_map_lock(dst_map);
1850 vm_map_lock(src_map);
1851 }
1852
1853 result = KERN_SUCCESS;
1854
1855 /*
1856 * Check protections... source must be completely readable and
1857 * destination must be completely writable. [Note that if we're
1858 * allocating the destination region, we don't have to worry
1859 * about protection, but instead about whether the region
1860 * exists.]
1861 */
1862
1863 if (src_map->is_main_map && dst_map->is_main_map) {
1864 if (!vm_map_check_protection(src_map, src_start, src_end,
1865 VM_PROT_READ)) {
1866 result = KERN_PROTECTION_FAILURE;
1867 goto Return;
1868 }
1869
1870 if (dst_alloc) {
1871 /* XXX Consider making this a vm_map_find instead */
5d7b9ad3 1872 if ((result = vm_map_insert(dst_map, NULL,
175f072e
KM
1873 (vm_offset_t) 0, dst_start, dst_end)) != KERN_SUCCESS)
1874 goto Return;
1875 }
1876 else if (!vm_map_check_protection(dst_map, dst_start, dst_end,
1877 VM_PROT_WRITE)) {
1878 result = KERN_PROTECTION_FAILURE;
1879 goto Return;
1880 }
1881 }
1882
1883 /*
1884 * Find the start entries and clip.
1885 *
1886 * Note that checking protection asserts that the
1887 * lookup cannot fail.
1888 *
1889 * Also note that we wait to do the second lookup
1890 * until we have done the first clip, as the clip
1891 * may affect which entry we get!
1892 */
1893
1894 (void) vm_map_lookup_entry(src_map, src_addr, &tmp_entry);
1895 src_entry = tmp_entry;
1896 vm_map_clip_start(src_map, src_entry, src_start);
1897
1898 (void) vm_map_lookup_entry(dst_map, dst_addr, &tmp_entry);
1899 dst_entry = tmp_entry;
1900 vm_map_clip_start(dst_map, dst_entry, dst_start);
1901
1902 /*
1903 * If both source and destination entries are the same,
1904 * retry the first lookup, as it may have changed.
1905 */
1906
1907 if (src_entry == dst_entry) {
1908 (void) vm_map_lookup_entry(src_map, src_addr, &tmp_entry);
1909 src_entry = tmp_entry;
1910 }
1911
1912 /*
1913 * If source and destination entries are still the same,
1914 * a null copy is being performed.
1915 */
1916
1917 if (src_entry == dst_entry)
1918 goto Return;
1919
1920 /*
1921 * Go through entries until we get to the end of the
1922 * region.
1923 */
1924
1925 while (src_start < src_end) {
1926 /*
1927 * Clip the entries to the endpoint of the entire region.
1928 */
1929
1930 vm_map_clip_end(src_map, src_entry, src_end);
1931 vm_map_clip_end(dst_map, dst_entry, dst_end);
1932
1933 /*
1934 * Clip each entry to the endpoint of the other entry.
1935 */
1936
1937 src_clip = src_entry->start + (dst_entry->end - dst_entry->start);
1938 vm_map_clip_end(src_map, src_entry, src_clip);
1939
1940 dst_clip = dst_entry->start + (src_entry->end - src_entry->start);
1941 vm_map_clip_end(dst_map, dst_entry, dst_clip);
1942
1943 /*
1944 * Both entries now match in size and relative endpoints.
1945 *
1946 * If both entries refer to a VM object, we can
1947 * deal with them now.
1948 */
1949
1950 if (!src_entry->is_a_map && !dst_entry->is_a_map) {
1951 vm_map_copy_entry(src_map, dst_map, src_entry,
1952 dst_entry);
1953 }
1954 else {
1955 register vm_map_t new_dst_map;
1956 vm_offset_t new_dst_start;
1957 vm_size_t new_size;
1958 vm_map_t new_src_map;
1959 vm_offset_t new_src_start;
1960
1961 /*
1962 * We have to follow at least one sharing map.
1963 */
1964
1965 new_size = (dst_entry->end - dst_entry->start);
1966
1967 if (src_entry->is_a_map) {
1968 new_src_map = src_entry->object.share_map;
1969 new_src_start = src_entry->offset;
1970 }
1971 else {
1972 new_src_map = src_map;
1973 new_src_start = src_entry->start;
9587183e 1974 vm_map_set_recursive(&src_map->lock);
175f072e
KM
1975 }
1976
1977 if (dst_entry->is_a_map) {
1978 vm_offset_t new_dst_end;
1979
1980 new_dst_map = dst_entry->object.share_map;
1981 new_dst_start = dst_entry->offset;
1982
1983 /*
1984 * Since the destination sharing entries
1985 * will be merely deallocated, we can
1986 * do that now, and replace the region
1987 * with a null object. [This prevents
1988 * splitting the source map to match
1989 * the form of the destination map.]
1990 * Note that we can only do so if the
1991 * source and destination do not overlap.
1992 */
1993
1994 new_dst_end = new_dst_start + new_size;
1995
1996 if (new_dst_map != new_src_map) {
1997 vm_map_lock(new_dst_map);
1998 (void) vm_map_delete(new_dst_map,
1999 new_dst_start,
2000 new_dst_end);
2001 (void) vm_map_insert(new_dst_map,
5d7b9ad3 2002 NULL,
175f072e
KM
2003 (vm_offset_t) 0,
2004 new_dst_start,
2005 new_dst_end);
2006 vm_map_unlock(new_dst_map);
2007 }
2008 }
2009 else {
2010 new_dst_map = dst_map;
2011 new_dst_start = dst_entry->start;
9587183e 2012 vm_map_set_recursive(&dst_map->lock);
175f072e
KM
2013 }
2014
2015 /*
2016 * Recursively copy the sharing map.
2017 */
2018
2019 (void) vm_map_copy(new_dst_map, new_src_map,
2020 new_dst_start, new_size, new_src_start,
2021 FALSE, FALSE);
2022
2023 if (dst_map == new_dst_map)
9587183e 2024 vm_map_clear_recursive(&dst_map->lock);
175f072e 2025 if (src_map == new_src_map)
9587183e 2026 vm_map_clear_recursive(&src_map->lock);
175f072e
KM
2027 }
2028
2029 /*
2030 * Update variables for next pass through the loop.
2031 */
2032
2033 src_start = src_entry->end;
2034 src_entry = src_entry->next;
2035 dst_start = dst_entry->end;
2036 dst_entry = dst_entry->next;
2037
2038 /*
2039 * If the source is to be destroyed, here is the
2040 * place to do it.
2041 */
2042
2043 if (src_destroy && src_map->is_main_map &&
2044 dst_map->is_main_map)
2045 vm_map_entry_delete(src_map, src_entry->prev);
2046 }
2047
2048 /*
2049 * Update the physical maps as appropriate
2050 */
2051
2052 if (src_map->is_main_map && dst_map->is_main_map) {
2053 if (src_destroy)
2054 pmap_remove(src_map->pmap, src_addr, src_addr + len);
2055 }
2056
2057 /*
2058 * Unlock the maps
2059 */
2060
2061 Return: ;
2062
2063 if (old_src_destroy)
2064 vm_map_delete(src_map, src_addr, src_addr + len);
2065
2066 vm_map_unlock(src_map);
2067 if (src_map != dst_map)
2068 vm_map_unlock(dst_map);
2069
2070 return(result);
2071}
2072
2073/*
5d7b9ad3
MK
2074 * vmspace_fork:
2075 * Create a new process vmspace structure and vm_map
2076 * based on those of an existing process. The new map
2077 * is based on the old map, according to the inheritance
2078 * values on the regions in that map.
175f072e 2079 *
5d7b9ad3 2080 * The source map must not be locked.
175f072e 2081 */
5d7b9ad3
MK
2082struct vmspace *
2083vmspace_fork(vm1)
2084 register struct vmspace *vm1;
175f072e 2085{
5d7b9ad3
MK
2086 register struct vmspace *vm2;
2087 vm_map_t old_map = &vm1->vm_map;
175f072e
KM
2088 vm_map_t new_map;
2089 vm_map_entry_t old_entry;
2090 vm_map_entry_t new_entry;
2091 pmap_t new_pmap;
2092
2093 vm_map_lock(old_map);
2094
5d7b9ad3
MK
2095 vm2 = vmspace_alloc(old_map->min_offset, old_map->max_offset,
2096 old_map->entries_pageable);
2097 bcopy(&vm1->vm_startcopy, &vm2->vm_startcopy,
2098 (caddr_t) (vm1 + 1) - (caddr_t) &vm1->vm_startcopy);
2099 new_pmap = &vm2->vm_pmap; /* XXX */
2100 new_map = &vm2->vm_map; /* XXX */
175f072e
KM
2101
2102 old_entry = old_map->header.next;
2103
2104 while (old_entry != &old_map->header) {
2105 if (old_entry->is_sub_map)
2106 panic("vm_map_fork: encountered a submap");
2107
2108 switch (old_entry->inheritance) {
2109 case VM_INHERIT_NONE:
2110 break;
2111
2112 case VM_INHERIT_SHARE:
2113 /*
2114 * If we don't already have a sharing map:
2115 */
2116
2117 if (!old_entry->is_a_map) {
2118 vm_map_t new_share_map;
2119 vm_map_entry_t new_share_entry;
2120
2121 /*
2122 * Create a new sharing map
2123 */
2124
5d7b9ad3 2125 new_share_map = vm_map_create(NULL,
175f072e
KM
2126 old_entry->start,
2127 old_entry->end,
2128 TRUE);
2129 new_share_map->is_main_map = FALSE;
2130
2131 /*
2132 * Create the only sharing entry from the
2133 * old task map entry.
2134 */
2135
2136 new_share_entry =
2137 vm_map_entry_create(new_share_map);
2138 *new_share_entry = *old_entry;
b5246c21 2139 new_share_entry->wired_count = 0;
175f072e
KM
2140
2141 /*
2142 * Insert the entry into the new sharing
2143 * map
2144 */
2145
2146 vm_map_entry_link(new_share_map,
2147 new_share_map->header.prev,
2148 new_share_entry);
2149
2150 /*
2151 * Fix up the task map entry to refer
2152 * to the sharing map now.
2153 */
2154
2155 old_entry->is_a_map = TRUE;
2156 old_entry->object.share_map = new_share_map;
2157 old_entry->offset = old_entry->start;
2158 }
2159
2160 /*
2161 * Clone the entry, referencing the sharing map.
2162 */
2163
2164 new_entry = vm_map_entry_create(new_map);
2165 *new_entry = *old_entry;
b5246c21 2166 new_entry->wired_count = 0;
175f072e
KM
2167 vm_map_reference(new_entry->object.share_map);
2168
2169 /*
2170 * Insert the entry into the new map -- we
2171 * know we're inserting at the end of the new
2172 * map.
2173 */
2174
2175 vm_map_entry_link(new_map, new_map->header.prev,
2176 new_entry);
2177
2178 /*
2179 * Update the physical map
2180 */
2181
2182 pmap_copy(new_map->pmap, old_map->pmap,
2183 new_entry->start,
2184 (old_entry->end - old_entry->start),
2185 old_entry->start);
2186 break;
2187
2188 case VM_INHERIT_COPY:
2189 /*
2190 * Clone the entry and link into the map.
2191 */
2192
2193 new_entry = vm_map_entry_create(new_map);
2194 *new_entry = *old_entry;
2195 new_entry->wired_count = 0;
5d7b9ad3 2196 new_entry->object.vm_object = NULL;
175f072e
KM
2197 new_entry->is_a_map = FALSE;
2198 vm_map_entry_link(new_map, new_map->header.prev,
2199 new_entry);
2200 if (old_entry->is_a_map) {
2201 int check;
2202
2203 check = vm_map_copy(new_map,
2204 old_entry->object.share_map,
2205 new_entry->start,
2206 (vm_size_t)(new_entry->end -
2207 new_entry->start),
2208 old_entry->offset,
2209 FALSE, FALSE);
2210 if (check != KERN_SUCCESS)
2211 printf("vm_map_fork: copy in share_map region failed\n");
2212 }
2213 else {
2214 vm_map_copy_entry(old_map, new_map, old_entry,
2215 new_entry);
2216 }
2217 break;
2218 }
2219 old_entry = old_entry->next;
2220 }
2221
2222 new_map->size = old_map->size;
2223 vm_map_unlock(old_map);
2224
5d7b9ad3 2225 return(vm2);
175f072e
KM
2226}
2227
2228/*
2229 * vm_map_lookup:
2230 *
2231 * Finds the VM object, offset, and
2232 * protection for a given virtual address in the
2233 * specified map, assuming a page fault of the
2234 * type specified.
2235 *
2236 * Leaves the map in question locked for read; return
2237 * values are guaranteed until a vm_map_lookup_done
2238 * call is performed. Note that the map argument
2239 * is in/out; the returned map must be used in
2240 * the call to vm_map_lookup_done.
2241 *
2242 * A handle (out_entry) is returned for use in
2243 * vm_map_lookup_done, to make that fast.
2244 *
2245 * If a lookup is requested with "write protection"
2246 * specified, the map may be changed to perform virtual
2247 * copying operations, although the data referenced will
2248 * remain the same.
2249 */
73506ff8 2250int
175f072e
KM
2251vm_map_lookup(var_map, vaddr, fault_type, out_entry,
2252 object, offset, out_prot, wired, single_use)
2253 vm_map_t *var_map; /* IN/OUT */
2254 register vm_offset_t vaddr;
2255 register vm_prot_t fault_type;
2256
2257 vm_map_entry_t *out_entry; /* OUT */
2258 vm_object_t *object; /* OUT */
2259 vm_offset_t *offset; /* OUT */
2260 vm_prot_t *out_prot; /* OUT */
2261 boolean_t *wired; /* OUT */
2262 boolean_t *single_use; /* OUT */
2263{
2264 vm_map_t share_map;
2265 vm_offset_t share_offset;
2266 register vm_map_entry_t entry;
2267 register vm_map_t map = *var_map;
2268 register vm_prot_t prot;
2269 register boolean_t su;
2270
2271 RetryLookup: ;
2272
2273 /*
2274 * Lookup the faulting address.
2275 */
2276
2277 vm_map_lock_read(map);
2278
2279#define RETURN(why) \
2280 { \
2281 vm_map_unlock_read(map); \
2282 return(why); \
2283 }
2284
2285 /*
2286 * If the map has an interesting hint, try it before calling
2287 * full blown lookup routine.
2288 */
2289
2290 simple_lock(&map->hint_lock);
2291 entry = map->hint;
2292 simple_unlock(&map->hint_lock);
2293
2294 *out_entry = entry;
2295
2296 if ((entry == &map->header) ||
2297 (vaddr < entry->start) || (vaddr >= entry->end)) {
2298 vm_map_entry_t tmp_entry;
2299
2300 /*
2301 * Entry was either not a valid hint, or the vaddr
2302 * was not contained in the entry, so do a full lookup.
2303 */
2304 if (!vm_map_lookup_entry(map, vaddr, &tmp_entry))
2305 RETURN(KERN_INVALID_ADDRESS);
2306
2307 entry = tmp_entry;
2308 *out_entry = entry;
2309 }
2310
2311 /*
2312 * Handle submaps.
2313 */
2314
2315 if (entry->is_sub_map) {
2316 vm_map_t old_map = map;
2317
2318 *var_map = map = entry->object.sub_map;
2319 vm_map_unlock_read(old_map);
2320 goto RetryLookup;
2321 }
2322
2323 /*
2324 * Check whether this task is allowed to have
2325 * this page.
2326 */
2327
2328 prot = entry->protection;
2329 if ((fault_type & (prot)) != fault_type)
2330 RETURN(KERN_PROTECTION_FAILURE);
2331
2332 /*
2333 * If this page is not pageable, we have to get
2334 * it for all possible accesses.
2335 */
2336
2337 if (*wired = (entry->wired_count != 0))
2338 prot = fault_type = entry->protection;
2339
2340 /*
2341 * If we don't already have a VM object, track
2342 * it down.
2343 */
2344
2345 if (su = !entry->is_a_map) {
2346 share_map = map;
2347 share_offset = vaddr;
2348 }
2349 else {
2350 vm_map_entry_t share_entry;
2351
2352 /*
2353 * Compute the sharing map, and offset into it.
2354 */
2355
2356 share_map = entry->object.share_map;
2357 share_offset = (vaddr - entry->start) + entry->offset;
2358
2359 /*
2360 * Look for the backing store object and offset
2361 */
2362
2363 vm_map_lock_read(share_map);
2364
2365 if (!vm_map_lookup_entry(share_map, share_offset,
2366 &share_entry)) {
2367 vm_map_unlock_read(share_map);
2368 RETURN(KERN_INVALID_ADDRESS);
2369 }
2370 entry = share_entry;
2371 }
2372
2373 /*
2374 * If the entry was copy-on-write, we either ...
2375 */
2376
2377 if (entry->needs_copy) {
2378 /*
2379 * If we want to write the page, we may as well
2380 * handle that now since we've got the sharing
2381 * map locked.
2382 *
2383 * If we don't need to write the page, we just
2384 * demote the permissions allowed.
2385 */
2386
2387 if (fault_type & VM_PROT_WRITE) {
2388 /*
2389 * Make a new object, and place it in the
2390 * object chain. Note that no new references
2391 * have appeared -- one just moved from the
2392 * share map to the new object.
2393 */
2394
89e4dee8
KM
2395 if (lockmgr(&share_map->lock, LK_EXCLUPGRADE,
2396 (void *)0, LOCKPID)) {
175f072e
KM
2397 if (share_map != map)
2398 vm_map_unlock_read(map);
2399 goto RetryLookup;
2400 }
2401
2402 vm_object_shadow(
2403 &entry->object.vm_object,
2404 &entry->offset,
2405 (vm_size_t) (entry->end - entry->start));
2406
2407 entry->needs_copy = FALSE;
2408
89e4dee8
KM
2409 lockmgr(&share_map->lock, LK_DOWNGRADE,
2410 (void *)0, LOCKPID);
175f072e
KM
2411 }
2412 else {
2413 /*
2414 * We're attempting to read a copy-on-write
2415 * page -- don't allow writes.
2416 */
2417
2418 prot &= (~VM_PROT_WRITE);
2419 }
2420 }
2421
2422 /*
2423 * Create an object if necessary.
2424 */
5d7b9ad3 2425 if (entry->object.vm_object == NULL) {
175f072e 2426
89e4dee8
KM
2427 if (lockmgr(&share_map->lock, LK_EXCLUPGRADE,
2428 (void *)0, LOCKPID)) {
175f072e
KM
2429 if (share_map != map)
2430 vm_map_unlock_read(map);
2431 goto RetryLookup;
2432 }
2433
2434 entry->object.vm_object = vm_object_allocate(
2435 (vm_size_t)(entry->end - entry->start));
2436 entry->offset = 0;
89e4dee8 2437 lockmgr(&share_map->lock, LK_DOWNGRADE, (void *)0, LOCKPID);
175f072e
KM
2438 }
2439
2440 /*
2441 * Return the object/offset from this entry. If the entry
2442 * was copy-on-write or empty, it has been fixed up.
2443 */
2444
2445 *offset = (share_offset - entry->start) + entry->offset;
2446 *object = entry->object.vm_object;
2447
2448 /*
2449 * Return whether this is the only map sharing this data.
2450 */
2451
2452 if (!su) {
2453 simple_lock(&share_map->ref_lock);
2454 su = (share_map->ref_count == 1);
2455 simple_unlock(&share_map->ref_lock);
2456 }
2457
2458 *out_prot = prot;
2459 *single_use = su;
2460
2461 return(KERN_SUCCESS);
2462
2463#undef RETURN
2464}
2465
2466/*
2467 * vm_map_lookup_done:
2468 *
2469 * Releases locks acquired by a vm_map_lookup
2470 * (according to the handle returned by that lookup).
2471 */
2472
e61c0b32
CD
2473void
2474vm_map_lookup_done(map, entry)
175f072e
KM
2475 register vm_map_t map;
2476 vm_map_entry_t entry;
2477{
2478 /*
2479 * If this entry references a map, unlock it first.
2480 */
2481
2482 if (entry->is_a_map)
2483 vm_map_unlock_read(entry->object.share_map);
2484
2485 /*
2486 * Unlock the main-level map
2487 */
2488
2489 vm_map_unlock_read(map);
2490}
2491
2492/*
2493 * Routine: vm_map_simplify
2494 * Purpose:
2495 * Attempt to simplify the map representation in
2496 * the vicinity of the given starting address.
2497 * Note:
2498 * This routine is intended primarily to keep the
2499 * kernel maps more compact -- they generally don't
2500 * benefit from the "expand a map entry" technology
2501 * at allocation time because the adjacent entry
2502 * is often wired down.
2503 */
e61c0b32
CD
2504void
2505vm_map_simplify(map, start)
175f072e
KM
2506 vm_map_t map;
2507 vm_offset_t start;
2508{
2509 vm_map_entry_t this_entry;
2510 vm_map_entry_t prev_entry;
2511
2512 vm_map_lock(map);
2513 if (
2514 (vm_map_lookup_entry(map, start, &this_entry)) &&
2515 ((prev_entry = this_entry->prev) != &map->header) &&
2516
2517 (prev_entry->end == start) &&
2518 (map->is_main_map) &&
2519
2520 (prev_entry->is_a_map == FALSE) &&
2521 (prev_entry->is_sub_map == FALSE) &&
2522
2523 (this_entry->is_a_map == FALSE) &&
2524 (this_entry->is_sub_map == FALSE) &&
2525
2526 (prev_entry->inheritance == this_entry->inheritance) &&
2527 (prev_entry->protection == this_entry->protection) &&
2528 (prev_entry->max_protection == this_entry->max_protection) &&
2529 (prev_entry->wired_count == this_entry->wired_count) &&
2530
2531 (prev_entry->copy_on_write == this_entry->copy_on_write) &&
2532 (prev_entry->needs_copy == this_entry->needs_copy) &&
2533
2534 (prev_entry->object.vm_object == this_entry->object.vm_object) &&
2535 ((prev_entry->offset + (prev_entry->end - prev_entry->start))
2536 == this_entry->offset)
2537 ) {
2538 if (map->first_free == this_entry)
2539 map->first_free = prev_entry;
2540
2541 SAVE_HINT(map, prev_entry);
2542 vm_map_entry_unlink(map, this_entry);
2543 prev_entry->end = this_entry->end;
2544 vm_object_deallocate(this_entry->object.vm_object);
2545 vm_map_entry_dispose(map, this_entry);
2546 }
2547 vm_map_unlock(map);
2548}
2549
2550/*
2551 * vm_map_print: [ debug ]
2552 */
e61c0b32
CD
2553void
2554vm_map_print(map, full)
175f072e
KM
2555 register vm_map_t map;
2556 boolean_t full;
2557{
2558 register vm_map_entry_t entry;
2559 extern int indent;
2560
2561 iprintf("%s map 0x%x: pmap=0x%x,ref=%d,nentries=%d,version=%d\n",
2562 (map->is_main_map ? "Task" : "Share"),
2563 (int) map, (int) (map->pmap), map->ref_count, map->nentries,
2564 map->timestamp);
2565
2566 if (!full && indent)
2567 return;
2568
2569 indent += 2;
2570 for (entry = map->header.next; entry != &map->header;
2571 entry = entry->next) {
2572 iprintf("map entry 0x%x: start=0x%x, end=0x%x, ",
2573 (int) entry, (int) entry->start, (int) entry->end);
2574 if (map->is_main_map) {
2575 static char *inheritance_name[4] =
2576 { "share", "copy", "none", "donate_copy"};
2577 printf("prot=%x/%x/%s, ",
2578 entry->protection,
2579 entry->max_protection,
2580 inheritance_name[entry->inheritance]);
2581 if (entry->wired_count != 0)
2582 printf("wired, ");
2583 }
2584
2585 if (entry->is_a_map || entry->is_sub_map) {
2586 printf("share=0x%x, offset=0x%x\n",
2587 (int) entry->object.share_map,
2588 (int) entry->offset);
2589 if ((entry->prev == &map->header) ||
2590 (!entry->prev->is_a_map) ||
2591 (entry->prev->object.share_map !=
2592 entry->object.share_map)) {
2593 indent += 2;
2594 vm_map_print(entry->object.share_map, full);
2595 indent -= 2;
2596 }
2597
2598 }
2599 else {
2600 printf("object=0x%x, offset=0x%x",
2601 (int) entry->object.vm_object,
2602 (int) entry->offset);
2603 if (entry->copy_on_write)
2604 printf(", copy (%s)",
2605 entry->needs_copy ? "needed" : "done");
2606 printf("\n");
2607
2608 if ((entry->prev == &map->header) ||
2609 (entry->prev->is_a_map) ||
2610 (entry->prev->object.vm_object !=
2611 entry->object.vm_object)) {
2612 indent += 2;
2613 vm_object_print(entry->object.vm_object, full);
2614 indent -= 2;
2615 }
2616 }
2617 }
2618 indent -= 2;
2619}