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