]> git.saurik.com Git - apple/xnu.git/blob - osfmk/vm/vm_map.c
0e1cf4a48599fd3238875406f4ab6b0e072bae39
[apple/xnu.git] / osfmk / vm / vm_map.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * @OSF_COPYRIGHT@
24 */
25 /*
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
29 *
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
35 *
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39 *
40 * Carnegie Mellon requests users of this software to return to
41 *
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
46 *
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
49 */
50 /*
51 */
52 /*
53 * File: vm/vm_map.c
54 * Author: Avadis Tevanian, Jr., Michael Wayne Young
55 * Date: 1985
56 *
57 * Virtual memory mapping module.
58 */
59
60 #include <cpus.h>
61 #include <task_swapper.h>
62 #include <mach_assert.h>
63
64 #include <mach/kern_return.h>
65 #include <mach/port.h>
66 #include <mach/vm_attributes.h>
67 #include <mach/vm_param.h>
68 #include <mach/vm_behavior.h>
69 #include <kern/assert.h>
70 #include <kern/counters.h>
71 #include <kern/zalloc.h>
72 #include <vm/vm_init.h>
73 #include <vm/vm_fault.h>
74 #include <vm/vm_map.h>
75 #include <vm/vm_object.h>
76 #include <vm/vm_page.h>
77 #include <vm/vm_kern.h>
78 #include <ipc/ipc_port.h>
79 #include <kern/sched_prim.h>
80 #include <kern/misc_protos.h>
81 #include <mach/vm_map_server.h>
82 #include <mach/mach_host_server.h>
83 #include <ddb/tr.h>
84 #include <kern/xpr.h>
85
86 /* Internal prototypes
87 */
88 extern boolean_t vm_map_range_check(
89 vm_map_t map,
90 vm_offset_t start,
91 vm_offset_t end,
92 vm_map_entry_t *entry);
93
94 extern vm_map_entry_t _vm_map_entry_create(
95 struct vm_map_header *map_header);
96
97 extern void _vm_map_entry_dispose(
98 struct vm_map_header *map_header,
99 vm_map_entry_t entry);
100
101 extern void vm_map_pmap_enter(
102 vm_map_t map,
103 vm_offset_t addr,
104 vm_offset_t end_addr,
105 vm_object_t object,
106 vm_object_offset_t offset,
107 vm_prot_t protection);
108
109 extern void _vm_map_clip_end(
110 struct vm_map_header *map_header,
111 vm_map_entry_t entry,
112 vm_offset_t end);
113
114 extern void vm_map_entry_delete(
115 vm_map_t map,
116 vm_map_entry_t entry);
117
118 extern kern_return_t vm_map_delete(
119 vm_map_t map,
120 vm_offset_t start,
121 vm_offset_t end,
122 int flags);
123
124 extern void vm_map_copy_steal_pages(
125 vm_map_copy_t copy);
126
127 extern kern_return_t vm_map_copy_overwrite_unaligned(
128 vm_map_t dst_map,
129 vm_map_entry_t entry,
130 vm_map_copy_t copy,
131 vm_offset_t start);
132
133 extern kern_return_t vm_map_copy_overwrite_aligned(
134 vm_map_t dst_map,
135 vm_map_entry_t tmp_entry,
136 vm_map_copy_t copy,
137 vm_offset_t start,
138 pmap_t pmap);
139
140 extern kern_return_t vm_map_copyin_kernel_buffer(
141 vm_map_t src_map,
142 vm_offset_t src_addr,
143 vm_size_t len,
144 boolean_t src_destroy,
145 vm_map_copy_t *copy_result); /* OUT */
146
147 extern kern_return_t vm_map_copyout_kernel_buffer(
148 vm_map_t map,
149 vm_offset_t *addr, /* IN/OUT */
150 vm_map_copy_t copy,
151 boolean_t overwrite);
152
153 extern kern_return_t vm_map_copyin_page_list_cont(
154 vm_map_copyin_args_t cont_args,
155 vm_map_copy_t *copy_result); /* OUT */
156
157 extern void vm_map_fork_share(
158 vm_map_t old_map,
159 vm_map_entry_t old_entry,
160 vm_map_t new_map);
161
162 extern boolean_t vm_map_fork_copy(
163 vm_map_t old_map,
164 vm_map_entry_t *old_entry_p,
165 vm_map_t new_map);
166
167 extern kern_return_t vm_remap_range_allocate(
168 vm_map_t map,
169 vm_offset_t *address, /* IN/OUT */
170 vm_size_t size,
171 vm_offset_t mask,
172 boolean_t anywhere,
173 vm_map_entry_t *map_entry); /* OUT */
174
175 extern void _vm_map_clip_start(
176 struct vm_map_header *map_header,
177 vm_map_entry_t entry,
178 vm_offset_t start);
179
180 void vm_region_top_walk(
181 vm_map_entry_t entry,
182 vm_region_top_info_t top);
183
184 void vm_region_walk(
185 vm_map_entry_t entry,
186 vm_region_extended_info_t extended,
187 vm_object_offset_t offset,
188 vm_offset_t range,
189 vm_map_t map,
190 vm_offset_t va);
191
192 /*
193 * Macros to copy a vm_map_entry. We must be careful to correctly
194 * manage the wired page count. vm_map_entry_copy() creates a new
195 * map entry to the same memory - the wired count in the new entry
196 * must be set to zero. vm_map_entry_copy_full() creates a new
197 * entry that is identical to the old entry. This preserves the
198 * wire count; it's used for map splitting and zone changing in
199 * vm_map_copyout.
200 */
201 #define vm_map_entry_copy(NEW,OLD) \
202 MACRO_BEGIN \
203 *(NEW) = *(OLD); \
204 (NEW)->is_shared = FALSE; \
205 (NEW)->needs_wakeup = FALSE; \
206 (NEW)->in_transition = FALSE; \
207 (NEW)->wired_count = 0; \
208 (NEW)->user_wired_count = 0; \
209 MACRO_END
210
211 #define vm_map_entry_copy_full(NEW,OLD) (*(NEW) = *(OLD))
212
213 /*
214 * Virtual memory maps provide for the mapping, protection,
215 * and sharing of virtual memory objects. In addition,
216 * this module provides for an efficient virtual copy of
217 * memory from one map to another.
218 *
219 * Synchronization is required prior to most operations.
220 *
221 * Maps consist of an ordered doubly-linked list of simple
222 * entries; a single hint is used to speed up lookups.
223 *
224 * Sharing maps have been deleted from this version of Mach.
225 * All shared objects are now mapped directly into the respective
226 * maps. This requires a change in the copy on write strategy;
227 * the asymmetric (delayed) strategy is used for shared temporary
228 * objects instead of the symmetric (shadow) strategy. All maps
229 * are now "top level" maps (either task map, kernel map or submap
230 * of the kernel map).
231 *
232 * Since portions of maps are specified by start/end addreses,
233 * which may not align with existing map entries, all
234 * routines merely "clip" entries to these start/end values.
235 * [That is, an entry is split into two, bordering at a
236 * start or end value.] Note that these clippings may not
237 * always be necessary (as the two resulting entries are then
238 * not changed); however, the clipping is done for convenience.
239 * No attempt is currently made to "glue back together" two
240 * abutting entries.
241 *
242 * The symmetric (shadow) copy strategy implements virtual copy
243 * by copying VM object references from one map to
244 * another, and then marking both regions as copy-on-write.
245 * It is important to note that only one writeable reference
246 * to a VM object region exists in any map when this strategy
247 * is used -- this means that shadow object creation can be
248 * delayed until a write operation occurs. The symmetric (delayed)
249 * strategy allows multiple maps to have writeable references to
250 * the same region of a vm object, and hence cannot delay creating
251 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
252 * Copying of permanent objects is completely different; see
253 * vm_object_copy_strategically() in vm_object.c.
254 */
255
256 zone_t vm_map_zone; /* zone for vm_map structures */
257 zone_t vm_map_entry_zone; /* zone for vm_map_entry structures */
258 zone_t vm_map_kentry_zone; /* zone for kernel entry structures */
259 zone_t vm_map_copy_zone; /* zone for vm_map_copy structures */
260
261
262 /*
263 * Placeholder object for submap operations. This object is dropped
264 * into the range by a call to vm_map_find, and removed when
265 * vm_map_submap creates the submap.
266 */
267
268 vm_object_t vm_submap_object;
269
270 /*
271 * vm_map_init:
272 *
273 * Initialize the vm_map module. Must be called before
274 * any other vm_map routines.
275 *
276 * Map and entry structures are allocated from zones -- we must
277 * initialize those zones.
278 *
279 * There are three zones of interest:
280 *
281 * vm_map_zone: used to allocate maps.
282 * vm_map_entry_zone: used to allocate map entries.
283 * vm_map_kentry_zone: used to allocate map entries for the kernel.
284 *
285 * The kernel allocates map entries from a special zone that is initially
286 * "crammed" with memory. It would be difficult (perhaps impossible) for
287 * the kernel to allocate more memory to a entry zone when it became
288 * empty since the very act of allocating memory implies the creation
289 * of a new entry.
290 */
291
292 vm_offset_t map_data;
293 vm_size_t map_data_size;
294 vm_offset_t kentry_data;
295 vm_size_t kentry_data_size;
296 int kentry_count = 2048; /* to init kentry_data_size */
297
298 /*
299 * Threshold for aggressive (eager) page map entering for vm copyout
300 * operations. Any copyout larger will NOT be aggressively entered.
301 */
302 vm_size_t vm_map_aggressive_enter_max; /* set by bootstrap */
303
304 void
305 vm_map_init(
306 void)
307 {
308 vm_map_zone = zinit((vm_size_t) sizeof(struct vm_map), 40*1024,
309 PAGE_SIZE, "maps");
310
311 vm_map_entry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
312 1024*1024, PAGE_SIZE*5,
313 "non-kernel map entries");
314
315 vm_map_kentry_zone = zinit((vm_size_t) sizeof(struct vm_map_entry),
316 kentry_data_size, kentry_data_size,
317 "kernel map entries");
318
319 vm_map_copy_zone = zinit((vm_size_t) sizeof(struct vm_map_copy),
320 16*1024, PAGE_SIZE, "map copies");
321
322 /*
323 * Cram the map and kentry zones with initial data.
324 * Set kentry_zone non-collectible to aid zone_gc().
325 */
326 zone_change(vm_map_zone, Z_COLLECT, FALSE);
327 zone_change(vm_map_kentry_zone, Z_COLLECT, FALSE);
328 zone_change(vm_map_kentry_zone, Z_EXPAND, FALSE);
329 zcram(vm_map_zone, map_data, map_data_size);
330 zcram(vm_map_kentry_zone, kentry_data, kentry_data_size);
331 }
332
333 void
334 vm_map_steal_memory(
335 void)
336 {
337 map_data_size = round_page(10 * sizeof(struct vm_map));
338 map_data = pmap_steal_memory(map_data_size);
339
340 #if 0
341 /*
342 * Limiting worst case: vm_map_kentry_zone needs to map each "available"
343 * physical page (i.e. that beyond the kernel image and page tables)
344 * individually; we guess at most one entry per eight pages in the
345 * real world. This works out to roughly .1 of 1% of physical memory,
346 * or roughly 1900 entries (64K) for a 64M machine with 4K pages.
347 */
348 #endif
349 kentry_count = pmap_free_pages() / 8;
350
351
352 kentry_data_size =
353 round_page(kentry_count * sizeof(struct vm_map_entry));
354 kentry_data = pmap_steal_memory(kentry_data_size);
355 }
356
357 /*
358 * vm_map_create:
359 *
360 * Creates and returns a new empty VM map with
361 * the given physical map structure, and having
362 * the given lower and upper address bounds.
363 */
364 vm_map_t
365 vm_map_create(
366 pmap_t pmap,
367 vm_offset_t min,
368 vm_offset_t max,
369 boolean_t pageable)
370 {
371 register vm_map_t result;
372
373 result = (vm_map_t) zalloc(vm_map_zone);
374 if (result == VM_MAP_NULL)
375 panic("vm_map_create");
376
377 vm_map_first_entry(result) = vm_map_to_entry(result);
378 vm_map_last_entry(result) = vm_map_to_entry(result);
379 result->hdr.nentries = 0;
380 result->hdr.entries_pageable = pageable;
381
382 result->size = 0;
383 result->ref_count = 1;
384 #if TASK_SWAPPER
385 result->res_count = 1;
386 result->sw_state = MAP_SW_IN;
387 #endif /* TASK_SWAPPER */
388 result->pmap = pmap;
389 result->min_offset = min;
390 result->max_offset = max;
391 result->wiring_required = FALSE;
392 result->no_zero_fill = FALSE;
393 result->wait_for_space = FALSE;
394 result->first_free = vm_map_to_entry(result);
395 result->hint = vm_map_to_entry(result);
396 vm_map_lock_init(result);
397 mutex_init(&result->s_lock, ETAP_VM_RESULT);
398
399 return(result);
400 }
401
402 /*
403 * vm_map_entry_create: [ internal use only ]
404 *
405 * Allocates a VM map entry for insertion in the
406 * given map (or map copy). No fields are filled.
407 */
408 #define vm_map_entry_create(map) \
409 _vm_map_entry_create(&(map)->hdr)
410
411 #define vm_map_copy_entry_create(copy) \
412 _vm_map_entry_create(&(copy)->cpy_hdr)
413
414 vm_map_entry_t
415 _vm_map_entry_create(
416 register struct vm_map_header *map_header)
417 {
418 register zone_t zone;
419 register vm_map_entry_t entry;
420
421 if (map_header->entries_pageable)
422 zone = vm_map_entry_zone;
423 else
424 zone = vm_map_kentry_zone;
425
426 entry = (vm_map_entry_t) zalloc(zone);
427 if (entry == VM_MAP_ENTRY_NULL)
428 panic("vm_map_entry_create");
429
430 return(entry);
431 }
432
433 /*
434 * vm_map_entry_dispose: [ internal use only ]
435 *
436 * Inverse of vm_map_entry_create.
437 */
438 #define vm_map_entry_dispose(map, entry) \
439 MACRO_BEGIN \
440 if((entry) == (map)->first_free) \
441 (map)->first_free = vm_map_to_entry(map); \
442 if((entry) == (map)->hint) \
443 (map)->hint = vm_map_to_entry(map); \
444 _vm_map_entry_dispose(&(map)->hdr, (entry)); \
445 MACRO_END
446
447 #define vm_map_copy_entry_dispose(map, entry) \
448 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
449
450 void
451 _vm_map_entry_dispose(
452 register struct vm_map_header *map_header,
453 register vm_map_entry_t entry)
454 {
455 register zone_t zone;
456
457 if (map_header->entries_pageable)
458 zone = vm_map_entry_zone;
459 else
460 zone = vm_map_kentry_zone;
461
462 zfree(zone, (vm_offset_t) entry);
463 }
464
465 boolean_t first_free_is_valid(vm_map_t map); /* forward */
466 boolean_t first_free_check = FALSE;
467 boolean_t
468 first_free_is_valid(
469 vm_map_t map)
470 {
471 vm_map_entry_t entry, next;
472
473 if (!first_free_check)
474 return TRUE;
475
476 entry = vm_map_to_entry(map);
477 next = entry->vme_next;
478 while (trunc_page(next->vme_start) == trunc_page(entry->vme_end) ||
479 (trunc_page(next->vme_start) == trunc_page(entry->vme_start) &&
480 next != vm_map_to_entry(map))) {
481 entry = next;
482 next = entry->vme_next;
483 if (entry == vm_map_to_entry(map))
484 break;
485 }
486 if (map->first_free != entry) {
487 printf("Bad first_free for map 0x%x: 0x%x should be 0x%x\n",
488 map, map->first_free, entry);
489 return FALSE;
490 }
491 return TRUE;
492 }
493
494 /*
495 * UPDATE_FIRST_FREE:
496 *
497 * Updates the map->first_free pointer to the
498 * entry immediately before the first hole in the map.
499 * The map should be locked.
500 */
501 #define UPDATE_FIRST_FREE(map, new_first_free) \
502 MACRO_BEGIN \
503 vm_map_t UFF_map; \
504 vm_map_entry_t UFF_first_free; \
505 vm_map_entry_t UFF_next_entry; \
506 UFF_map = (map); \
507 UFF_first_free = (new_first_free); \
508 UFF_next_entry = UFF_first_free->vme_next; \
509 while (trunc_page(UFF_next_entry->vme_start) == \
510 trunc_page(UFF_first_free->vme_end) || \
511 (trunc_page(UFF_next_entry->vme_start) == \
512 trunc_page(UFF_first_free->vme_start) && \
513 UFF_next_entry != vm_map_to_entry(UFF_map))) { \
514 UFF_first_free = UFF_next_entry; \
515 UFF_next_entry = UFF_first_free->vme_next; \
516 if (UFF_first_free == vm_map_to_entry(UFF_map)) \
517 break; \
518 } \
519 UFF_map->first_free = UFF_first_free; \
520 assert(first_free_is_valid(UFF_map)); \
521 MACRO_END
522
523 /*
524 * vm_map_entry_{un,}link:
525 *
526 * Insert/remove entries from maps (or map copies).
527 */
528 #define vm_map_entry_link(map, after_where, entry) \
529 MACRO_BEGIN \
530 vm_map_t VMEL_map; \
531 vm_map_entry_t VMEL_entry; \
532 VMEL_map = (map); \
533 VMEL_entry = (entry); \
534 _vm_map_entry_link(&VMEL_map->hdr, after_where, VMEL_entry); \
535 UPDATE_FIRST_FREE(VMEL_map, VMEL_map->first_free); \
536 MACRO_END
537
538
539 #define vm_map_copy_entry_link(copy, after_where, entry) \
540 _vm_map_entry_link(&(copy)->cpy_hdr, after_where, (entry))
541
542 #define _vm_map_entry_link(hdr, after_where, entry) \
543 MACRO_BEGIN \
544 (hdr)->nentries++; \
545 (entry)->vme_prev = (after_where); \
546 (entry)->vme_next = (after_where)->vme_next; \
547 (entry)->vme_prev->vme_next = (entry)->vme_next->vme_prev = (entry); \
548 MACRO_END
549
550 #define vm_map_entry_unlink(map, entry) \
551 MACRO_BEGIN \
552 vm_map_t VMEU_map; \
553 vm_map_entry_t VMEU_entry; \
554 vm_map_entry_t VMEU_first_free; \
555 VMEU_map = (map); \
556 VMEU_entry = (entry); \
557 if (VMEU_entry->vme_start <= VMEU_map->first_free->vme_start) \
558 VMEU_first_free = VMEU_entry->vme_prev; \
559 else \
560 VMEU_first_free = VMEU_map->first_free; \
561 _vm_map_entry_unlink(&VMEU_map->hdr, VMEU_entry); \
562 UPDATE_FIRST_FREE(VMEU_map, VMEU_first_free); \
563 MACRO_END
564
565 #define vm_map_copy_entry_unlink(copy, entry) \
566 _vm_map_entry_unlink(&(copy)->cpy_hdr, (entry))
567
568 #define _vm_map_entry_unlink(hdr, entry) \
569 MACRO_BEGIN \
570 (hdr)->nentries--; \
571 (entry)->vme_next->vme_prev = (entry)->vme_prev; \
572 (entry)->vme_prev->vme_next = (entry)->vme_next; \
573 MACRO_END
574
575 /*
576 * kernel_vm_map_reference:
577 *
578 * kernel internal export version for iokit and bsd components
579 * in lieu of component interface semantics.
580 *
581 */
582 void
583 kernel_vm_map_reference(
584 register vm_map_t map)
585 {
586 if (map == VM_MAP_NULL)
587 return;
588
589 mutex_lock(&map->s_lock);
590 #if TASK_SWAPPER
591 assert(map->res_count > 0);
592 assert(map->ref_count >= map->res_count);
593 map->res_count++;
594 #endif
595 map->ref_count++;
596 mutex_unlock(&map->s_lock);
597 }
598
599 #if MACH_ASSERT && TASK_SWAPPER
600 /*
601 * vm_map_reference:
602 *
603 * Adds valid reference and residence counts to the given map.
604 * The map must be in memory (i.e. non-zero residence count).
605 *
606 */
607 void
608 vm_map_reference(
609 register vm_map_t map)
610 {
611 if (map == VM_MAP_NULL)
612 return;
613
614 mutex_lock(&map->s_lock);
615 assert(map->res_count > 0);
616 assert(map->ref_count >= map->res_count);
617 map->ref_count++;
618 map->res_count++;
619 mutex_unlock(&map->s_lock);
620 }
621
622 /*
623 * vm_map_res_reference:
624 *
625 * Adds another valid residence count to the given map.
626 *
627 * Map is locked so this function can be called from
628 * vm_map_swapin.
629 *
630 */
631 void vm_map_res_reference(register vm_map_t map)
632 {
633 /* assert map is locked */
634 assert(map->res_count >= 0);
635 assert(map->ref_count >= map->res_count);
636 if (map->res_count == 0) {
637 mutex_unlock(&map->s_lock);
638 vm_map_lock(map);
639 vm_map_swapin(map);
640 mutex_lock(&map->s_lock);
641 ++map->res_count;
642 vm_map_unlock(map);
643 } else
644 ++map->res_count;
645 }
646
647 /*
648 * vm_map_reference_swap:
649 *
650 * Adds valid reference and residence counts to the given map.
651 *
652 * The map may not be in memory (i.e. zero residence count).
653 *
654 */
655 void vm_map_reference_swap(register vm_map_t map)
656 {
657 assert(map != VM_MAP_NULL);
658 mutex_lock(&map->s_lock);
659 assert(map->res_count >= 0);
660 assert(map->ref_count >= map->res_count);
661 map->ref_count++;
662 vm_map_res_reference(map);
663 mutex_unlock(&map->s_lock);
664 }
665
666 /*
667 * vm_map_res_deallocate:
668 *
669 * Decrement residence count on a map; possibly causing swapout.
670 *
671 * The map must be in memory (i.e. non-zero residence count).
672 *
673 * The map is locked, so this function is callable from vm_map_deallocate.
674 *
675 */
676 void vm_map_res_deallocate(register vm_map_t map)
677 {
678 assert(map->res_count > 0);
679 if (--map->res_count == 0) {
680 mutex_unlock(&map->s_lock);
681 vm_map_lock(map);
682 vm_map_swapout(map);
683 vm_map_unlock(map);
684 mutex_lock(&map->s_lock);
685 }
686 assert(map->ref_count >= map->res_count);
687 }
688 #endif /* MACH_ASSERT && TASK_SWAPPER */
689
690 /*
691 * vm_map_deallocate:
692 *
693 * Removes a reference from the specified map,
694 * destroying it if no references remain.
695 * The map should not be locked.
696 */
697 void
698 vm_map_deallocate(
699 register vm_map_t map)
700 {
701 unsigned int ref;
702
703 if (map == VM_MAP_NULL)
704 return;
705
706 mutex_lock(&map->s_lock);
707 ref = --map->ref_count;
708 if (ref > 0) {
709 vm_map_res_deallocate(map);
710 mutex_unlock(&map->s_lock);
711 return;
712 }
713 assert(map->ref_count == 0);
714 mutex_unlock(&map->s_lock);
715
716 #if TASK_SWAPPER
717 /*
718 * The map residence count isn't decremented here because
719 * the vm_map_delete below will traverse the entire map,
720 * deleting entries, and the residence counts on objects
721 * and sharing maps will go away then.
722 */
723 #endif
724
725 vm_map_destroy(map);
726 }
727
728 /*
729 * vm_map_destroy:
730 *
731 * Actually destroy a map.
732 */
733 void
734 vm_map_destroy(
735 register vm_map_t map)
736 {
737 vm_map_lock(map);
738 (void) vm_map_delete(map, map->min_offset,
739 map->max_offset, VM_MAP_NO_FLAGS);
740 vm_map_unlock(map);
741
742 pmap_destroy(map->pmap);
743
744 zfree(vm_map_zone, (vm_offset_t) map);
745 }
746
747 #if TASK_SWAPPER
748 /*
749 * vm_map_swapin/vm_map_swapout
750 *
751 * Swap a map in and out, either referencing or releasing its resources.
752 * These functions are internal use only; however, they must be exported
753 * because they may be called from macros, which are exported.
754 *
755 * In the case of swapout, there could be races on the residence count,
756 * so if the residence count is up, we return, assuming that a
757 * vm_map_deallocate() call in the near future will bring us back.
758 *
759 * Locking:
760 * -- We use the map write lock for synchronization among races.
761 * -- The map write lock, and not the simple s_lock, protects the
762 * swap state of the map.
763 * -- If a map entry is a share map, then we hold both locks, in
764 * hierarchical order.
765 *
766 * Synchronization Notes:
767 * 1) If a vm_map_swapin() call happens while swapout in progress, it
768 * will block on the map lock and proceed when swapout is through.
769 * 2) A vm_map_reference() call at this time is illegal, and will
770 * cause a panic. vm_map_reference() is only allowed on resident
771 * maps, since it refuses to block.
772 * 3) A vm_map_swapin() call during a swapin will block, and
773 * proceeed when the first swapin is done, turning into a nop.
774 * This is the reason the res_count is not incremented until
775 * after the swapin is complete.
776 * 4) There is a timing hole after the checks of the res_count, before
777 * the map lock is taken, during which a swapin may get the lock
778 * before a swapout about to happen. If this happens, the swapin
779 * will detect the state and increment the reference count, causing
780 * the swapout to be a nop, thereby delaying it until a later
781 * vm_map_deallocate. If the swapout gets the lock first, then
782 * the swapin will simply block until the swapout is done, and
783 * then proceed.
784 *
785 * Because vm_map_swapin() is potentially an expensive operation, it
786 * should be used with caution.
787 *
788 * Invariants:
789 * 1) A map with a residence count of zero is either swapped, or
790 * being swapped.
791 * 2) A map with a non-zero residence count is either resident,
792 * or being swapped in.
793 */
794
795 int vm_map_swap_enable = 1;
796
797 void vm_map_swapin (vm_map_t map)
798 {
799 register vm_map_entry_t entry;
800
801 if (!vm_map_swap_enable) /* debug */
802 return;
803
804 /*
805 * Map is locked
806 * First deal with various races.
807 */
808 if (map->sw_state == MAP_SW_IN)
809 /*
810 * we raced with swapout and won. Returning will incr.
811 * the res_count, turning the swapout into a nop.
812 */
813 return;
814
815 /*
816 * The residence count must be zero. If we raced with another
817 * swapin, the state would have been IN; if we raced with a
818 * swapout (after another competing swapin), we must have lost
819 * the race to get here (see above comment), in which case
820 * res_count is still 0.
821 */
822 assert(map->res_count == 0);
823
824 /*
825 * There are no intermediate states of a map going out or
826 * coming in, since the map is locked during the transition.
827 */
828 assert(map->sw_state == MAP_SW_OUT);
829
830 /*
831 * We now operate upon each map entry. If the entry is a sub-
832 * or share-map, we call vm_map_res_reference upon it.
833 * If the entry is an object, we call vm_object_res_reference
834 * (this may iterate through the shadow chain).
835 * Note that we hold the map locked the entire time,
836 * even if we get back here via a recursive call in
837 * vm_map_res_reference.
838 */
839 entry = vm_map_first_entry(map);
840
841 while (entry != vm_map_to_entry(map)) {
842 if (entry->object.vm_object != VM_OBJECT_NULL) {
843 if (entry->is_sub_map) {
844 vm_map_t lmap = entry->object.sub_map;
845 mutex_lock(&lmap->s_lock);
846 vm_map_res_reference(lmap);
847 mutex_unlock(&lmap->s_lock);
848 } else {
849 vm_object_t object = entry->object.vm_object;
850 vm_object_lock(object);
851 /*
852 * This call may iterate through the
853 * shadow chain.
854 */
855 vm_object_res_reference(object);
856 vm_object_unlock(object);
857 }
858 }
859 entry = entry->vme_next;
860 }
861 assert(map->sw_state == MAP_SW_OUT);
862 map->sw_state = MAP_SW_IN;
863 }
864
865 void vm_map_swapout(vm_map_t map)
866 {
867 register vm_map_entry_t entry;
868
869 /*
870 * Map is locked
871 * First deal with various races.
872 * If we raced with a swapin and lost, the residence count
873 * will have been incremented to 1, and we simply return.
874 */
875 mutex_lock(&map->s_lock);
876 if (map->res_count != 0) {
877 mutex_unlock(&map->s_lock);
878 return;
879 }
880 mutex_unlock(&map->s_lock);
881
882 /*
883 * There are no intermediate states of a map going out or
884 * coming in, since the map is locked during the transition.
885 */
886 assert(map->sw_state == MAP_SW_IN);
887
888 if (!vm_map_swap_enable)
889 return;
890
891 /*
892 * We now operate upon each map entry. If the entry is a sub-
893 * or share-map, we call vm_map_res_deallocate upon it.
894 * If the entry is an object, we call vm_object_res_deallocate
895 * (this may iterate through the shadow chain).
896 * Note that we hold the map locked the entire time,
897 * even if we get back here via a recursive call in
898 * vm_map_res_deallocate.
899 */
900 entry = vm_map_first_entry(map);
901
902 while (entry != vm_map_to_entry(map)) {
903 if (entry->object.vm_object != VM_OBJECT_NULL) {
904 if (entry->is_sub_map) {
905 vm_map_t lmap = entry->object.sub_map;
906 mutex_lock(&lmap->s_lock);
907 vm_map_res_deallocate(lmap);
908 mutex_unlock(&lmap->s_lock);
909 } else {
910 vm_object_t object = entry->object.vm_object;
911 vm_object_lock(object);
912 /*
913 * This call may take a long time,
914 * since it could actively push
915 * out pages (if we implement it
916 * that way).
917 */
918 vm_object_res_deallocate(object);
919 vm_object_unlock(object);
920 }
921 }
922 entry = entry->vme_next;
923 }
924 assert(map->sw_state == MAP_SW_IN);
925 map->sw_state = MAP_SW_OUT;
926 }
927
928 #endif /* TASK_SWAPPER */
929
930
931 /*
932 * SAVE_HINT:
933 *
934 * Saves the specified entry as the hint for
935 * future lookups. Performs necessary interlocks.
936 */
937 #define SAVE_HINT(map,value) \
938 mutex_lock(&(map)->s_lock); \
939 (map)->hint = (value); \
940 mutex_unlock(&(map)->s_lock);
941
942 /*
943 * vm_map_lookup_entry: [ internal use only ]
944 *
945 * Finds the map entry containing (or
946 * immediately preceding) the specified address
947 * in the given map; the entry is returned
948 * in the "entry" parameter. The boolean
949 * result indicates whether the address is
950 * actually contained in the map.
951 */
952 boolean_t
953 vm_map_lookup_entry(
954 register vm_map_t map,
955 register vm_offset_t address,
956 vm_map_entry_t *entry) /* OUT */
957 {
958 register vm_map_entry_t cur;
959 register vm_map_entry_t last;
960
961 /*
962 * Start looking either from the head of the
963 * list, or from the hint.
964 */
965
966 mutex_lock(&map->s_lock);
967 cur = map->hint;
968 mutex_unlock(&map->s_lock);
969
970 if (cur == vm_map_to_entry(map))
971 cur = cur->vme_next;
972
973 if (address >= cur->vme_start) {
974 /*
975 * Go from hint to end of list.
976 *
977 * But first, make a quick check to see if
978 * we are already looking at the entry we
979 * want (which is usually the case).
980 * Note also that we don't need to save the hint
981 * here... it is the same hint (unless we are
982 * at the header, in which case the hint didn't
983 * buy us anything anyway).
984 */
985 last = vm_map_to_entry(map);
986 if ((cur != last) && (cur->vme_end > address)) {
987 *entry = cur;
988 return(TRUE);
989 }
990 }
991 else {
992 /*
993 * Go from start to hint, *inclusively*
994 */
995 last = cur->vme_next;
996 cur = vm_map_first_entry(map);
997 }
998
999 /*
1000 * Search linearly
1001 */
1002
1003 while (cur != last) {
1004 if (cur->vme_end > address) {
1005 if (address >= cur->vme_start) {
1006 /*
1007 * Save this lookup for future
1008 * hints, and return
1009 */
1010
1011 *entry = cur;
1012 SAVE_HINT(map, cur);
1013 return(TRUE);
1014 }
1015 break;
1016 }
1017 cur = cur->vme_next;
1018 }
1019 *entry = cur->vme_prev;
1020 SAVE_HINT(map, *entry);
1021 return(FALSE);
1022 }
1023
1024 /*
1025 * Routine: vm_map_find_space
1026 * Purpose:
1027 * Allocate a range in the specified virtual address map,
1028 * returning the entry allocated for that range.
1029 * Used by kmem_alloc, etc.
1030 *
1031 * The map must be NOT be locked. It will be returned locked
1032 * on KERN_SUCCESS, unlocked on failure.
1033 *
1034 * If an entry is allocated, the object/offset fields
1035 * are initialized to zero.
1036 */
1037 kern_return_t
1038 vm_map_find_space(
1039 register vm_map_t map,
1040 vm_offset_t *address, /* OUT */
1041 vm_size_t size,
1042 vm_offset_t mask,
1043 vm_map_entry_t *o_entry) /* OUT */
1044 {
1045 register vm_map_entry_t entry, new_entry;
1046 register vm_offset_t start;
1047 register vm_offset_t end;
1048
1049 new_entry = vm_map_entry_create(map);
1050
1051 /*
1052 * Look for the first possible address; if there's already
1053 * something at this address, we have to start after it.
1054 */
1055
1056 vm_map_lock(map);
1057
1058 assert(first_free_is_valid(map));
1059 if ((entry = map->first_free) == vm_map_to_entry(map))
1060 start = map->min_offset;
1061 else
1062 start = entry->vme_end;
1063
1064 /*
1065 * In any case, the "entry" always precedes
1066 * the proposed new region throughout the loop:
1067 */
1068
1069 while (TRUE) {
1070 register vm_map_entry_t next;
1071
1072 /*
1073 * Find the end of the proposed new region.
1074 * Be sure we didn't go beyond the end, or
1075 * wrap around the address.
1076 */
1077
1078 end = ((start + mask) & ~mask);
1079 if (end < start) {
1080 vm_map_entry_dispose(map, new_entry);
1081 vm_map_unlock(map);
1082 return(KERN_NO_SPACE);
1083 }
1084 start = end;
1085 end += size;
1086
1087 if ((end > map->max_offset) || (end < start)) {
1088 vm_map_entry_dispose(map, new_entry);
1089 vm_map_unlock(map);
1090 return(KERN_NO_SPACE);
1091 }
1092
1093 /*
1094 * If there are no more entries, we must win.
1095 */
1096
1097 next = entry->vme_next;
1098 if (next == vm_map_to_entry(map))
1099 break;
1100
1101 /*
1102 * If there is another entry, it must be
1103 * after the end of the potential new region.
1104 */
1105
1106 if (next->vme_start >= end)
1107 break;
1108
1109 /*
1110 * Didn't fit -- move to the next entry.
1111 */
1112
1113 entry = next;
1114 start = entry->vme_end;
1115 }
1116
1117 /*
1118 * At this point,
1119 * "start" and "end" should define the endpoints of the
1120 * available new range, and
1121 * "entry" should refer to the region before the new
1122 * range, and
1123 *
1124 * the map should be locked.
1125 */
1126
1127 *address = start;
1128
1129 new_entry->vme_start = start;
1130 new_entry->vme_end = end;
1131 assert(page_aligned(new_entry->vme_start));
1132 assert(page_aligned(new_entry->vme_end));
1133
1134 new_entry->is_shared = FALSE;
1135 new_entry->is_sub_map = FALSE;
1136 new_entry->use_pmap = FALSE;
1137 new_entry->object.vm_object = VM_OBJECT_NULL;
1138 new_entry->offset = (vm_object_offset_t) 0;
1139
1140 new_entry->needs_copy = FALSE;
1141
1142 new_entry->inheritance = VM_INHERIT_DEFAULT;
1143 new_entry->protection = VM_PROT_DEFAULT;
1144 new_entry->max_protection = VM_PROT_ALL;
1145 new_entry->behavior = VM_BEHAVIOR_DEFAULT;
1146 new_entry->wired_count = 0;
1147 new_entry->user_wired_count = 0;
1148
1149 new_entry->in_transition = FALSE;
1150 new_entry->needs_wakeup = FALSE;
1151
1152 /*
1153 * Insert the new entry into the list
1154 */
1155
1156 vm_map_entry_link(map, entry, new_entry);
1157
1158 map->size += size;
1159
1160 /*
1161 * Update the lookup hint
1162 */
1163 SAVE_HINT(map, new_entry);
1164
1165 *o_entry = new_entry;
1166 return(KERN_SUCCESS);
1167 }
1168
1169 int vm_map_pmap_enter_print = FALSE;
1170 int vm_map_pmap_enter_enable = FALSE;
1171
1172 /*
1173 * Routine: vm_map_pmap_enter
1174 *
1175 * Description:
1176 * Force pages from the specified object to be entered into
1177 * the pmap at the specified address if they are present.
1178 * As soon as a page not found in the object the scan ends.
1179 *
1180 * Returns:
1181 * Nothing.
1182 *
1183 * In/out conditions:
1184 * The source map should not be locked on entry.
1185 */
1186 void
1187 vm_map_pmap_enter(
1188 vm_map_t map,
1189 register vm_offset_t addr,
1190 register vm_offset_t end_addr,
1191 register vm_object_t object,
1192 vm_object_offset_t offset,
1193 vm_prot_t protection)
1194 {
1195 while (addr < end_addr) {
1196 register vm_page_t m;
1197
1198 vm_object_lock(object);
1199 vm_object_paging_begin(object);
1200
1201 m = vm_page_lookup(object, offset);
1202 if (m == VM_PAGE_NULL || m->busy ||
1203 (m->unusual && ( m->error || m->restart || m->absent ||
1204 protection & m->page_lock))) {
1205
1206 vm_object_paging_end(object);
1207 vm_object_unlock(object);
1208 return;
1209 }
1210
1211 assert(!m->fictitious); /* XXX is this possible ??? */
1212
1213 if (vm_map_pmap_enter_print) {
1214 printf("vm_map_pmap_enter:");
1215 printf("map: %x, addr: %x, object: %x, offset: %x\n",
1216 map, addr, object, offset);
1217 }
1218
1219 m->busy = TRUE;
1220 vm_object_unlock(object);
1221
1222 PMAP_ENTER(map->pmap, addr, m,
1223 protection, FALSE);
1224
1225 vm_object_lock(object);
1226 PAGE_WAKEUP_DONE(m);
1227 vm_page_lock_queues();
1228 if (!m->active && !m->inactive)
1229 vm_page_activate(m);
1230 vm_page_unlock_queues();
1231 vm_object_paging_end(object);
1232 vm_object_unlock(object);
1233
1234 offset += PAGE_SIZE_64;
1235 addr += PAGE_SIZE;
1236 }
1237 }
1238
1239 /*
1240 * Routine: vm_map_enter
1241 *
1242 * Description:
1243 * Allocate a range in the specified virtual address map.
1244 * The resulting range will refer to memory defined by
1245 * the given memory object and offset into that object.
1246 *
1247 * Arguments are as defined in the vm_map call.
1248 */
1249 kern_return_t
1250 vm_map_enter(
1251 register vm_map_t map,
1252 vm_offset_t *address, /* IN/OUT */
1253 vm_size_t size,
1254 vm_offset_t mask,
1255 int flags,
1256 vm_object_t object,
1257 vm_object_offset_t offset,
1258 boolean_t needs_copy,
1259 vm_prot_t cur_protection,
1260 vm_prot_t max_protection,
1261 vm_inherit_t inheritance)
1262 {
1263 vm_map_entry_t entry;
1264 register vm_offset_t start;
1265 register vm_offset_t end;
1266 kern_return_t result = KERN_SUCCESS;
1267
1268 boolean_t anywhere = VM_FLAGS_ANYWHERE & flags;
1269 char alias;
1270
1271 VM_GET_FLAGS_ALIAS(flags, alias);
1272
1273 #define RETURN(value) { result = value; goto BailOut; }
1274
1275 assert(page_aligned(*address));
1276 assert(page_aligned(size));
1277 StartAgain: ;
1278
1279 start = *address;
1280
1281 if (anywhere) {
1282 vm_map_lock(map);
1283
1284 /*
1285 * Calculate the first possible address.
1286 */
1287
1288 if (start < map->min_offset)
1289 start = map->min_offset;
1290 if (start > map->max_offset)
1291 RETURN(KERN_NO_SPACE);
1292
1293 /*
1294 * Look for the first possible address;
1295 * if there's already something at this
1296 * address, we have to start after it.
1297 */
1298
1299 assert(first_free_is_valid(map));
1300 if (start == map->min_offset) {
1301 if ((entry = map->first_free) != vm_map_to_entry(map))
1302 start = entry->vme_end;
1303 } else {
1304 vm_map_entry_t tmp_entry;
1305 if (vm_map_lookup_entry(map, start, &tmp_entry))
1306 start = tmp_entry->vme_end;
1307 entry = tmp_entry;
1308 }
1309
1310 /*
1311 * In any case, the "entry" always precedes
1312 * the proposed new region throughout the
1313 * loop:
1314 */
1315
1316 while (TRUE) {
1317 register vm_map_entry_t next;
1318
1319 /*
1320 * Find the end of the proposed new region.
1321 * Be sure we didn't go beyond the end, or
1322 * wrap around the address.
1323 */
1324
1325 end = ((start + mask) & ~mask);
1326 if (end < start)
1327 RETURN(KERN_NO_SPACE);
1328 start = end;
1329 end += size;
1330
1331 if ((end > map->max_offset) || (end < start)) {
1332 if (map->wait_for_space) {
1333 if (size <= (map->max_offset -
1334 map->min_offset)) {
1335 assert_wait((event_t)map,
1336 THREAD_ABORTSAFE);
1337 vm_map_unlock(map);
1338 thread_block((void (*)(void))0);
1339 goto StartAgain;
1340 }
1341 }
1342 RETURN(KERN_NO_SPACE);
1343 }
1344
1345 /*
1346 * If there are no more entries, we must win.
1347 */
1348
1349 next = entry->vme_next;
1350 if (next == vm_map_to_entry(map))
1351 break;
1352
1353 /*
1354 * If there is another entry, it must be
1355 * after the end of the potential new region.
1356 */
1357
1358 if (next->vme_start >= end)
1359 break;
1360
1361 /*
1362 * Didn't fit -- move to the next entry.
1363 */
1364
1365 entry = next;
1366 start = entry->vme_end;
1367 }
1368 *address = start;
1369 } else {
1370 vm_map_entry_t temp_entry;
1371
1372 /*
1373 * Verify that:
1374 * the address doesn't itself violate
1375 * the mask requirement.
1376 */
1377
1378 vm_map_lock(map);
1379 if ((start & mask) != 0)
1380 RETURN(KERN_NO_SPACE);
1381
1382 /*
1383 * ... the address is within bounds
1384 */
1385
1386 end = start + size;
1387
1388 if ((start < map->min_offset) ||
1389 (end > map->max_offset) ||
1390 (start >= end)) {
1391 RETURN(KERN_INVALID_ADDRESS);
1392 }
1393
1394 /*
1395 * ... the starting address isn't allocated
1396 */
1397
1398 if (vm_map_lookup_entry(map, start, &temp_entry))
1399 RETURN(KERN_NO_SPACE);
1400
1401 entry = temp_entry;
1402
1403 /*
1404 * ... the next region doesn't overlap the
1405 * end point.
1406 */
1407
1408 if ((entry->vme_next != vm_map_to_entry(map)) &&
1409 (entry->vme_next->vme_start < end))
1410 RETURN(KERN_NO_SPACE);
1411 }
1412
1413 /*
1414 * At this point,
1415 * "start" and "end" should define the endpoints of the
1416 * available new range, and
1417 * "entry" should refer to the region before the new
1418 * range, and
1419 *
1420 * the map should be locked.
1421 */
1422
1423 /*
1424 * See whether we can avoid creating a new entry (and object) by
1425 * extending one of our neighbors. [So far, we only attempt to
1426 * extend from below.]
1427 */
1428
1429 if ((object == VM_OBJECT_NULL) &&
1430 (entry != vm_map_to_entry(map)) &&
1431 (entry->vme_end == start) &&
1432 (!entry->is_shared) &&
1433 (!entry->is_sub_map) &&
1434 (entry->alias == alias) &&
1435 (entry->inheritance == inheritance) &&
1436 (entry->protection == cur_protection) &&
1437 (entry->max_protection == max_protection) &&
1438 (entry->behavior == VM_BEHAVIOR_DEFAULT) &&
1439 (entry->in_transition == 0) &&
1440 (entry->wired_count == 0)) { /* implies user_wired_count == 0 */
1441 if (vm_object_coalesce(entry->object.vm_object,
1442 VM_OBJECT_NULL,
1443 entry->offset,
1444 (vm_object_offset_t) 0,
1445 (vm_size_t)(entry->vme_end - entry->vme_start),
1446 (vm_size_t)(end - entry->vme_end))) {
1447
1448 /*
1449 * Coalesced the two objects - can extend
1450 * the previous map entry to include the
1451 * new range.
1452 */
1453 map->size += (end - entry->vme_end);
1454 entry->vme_end = end;
1455 UPDATE_FIRST_FREE(map, map->first_free);
1456 RETURN(KERN_SUCCESS);
1457 }
1458 }
1459
1460 /*
1461 * Create a new entry
1462 */
1463
1464 { /**/
1465 register vm_map_entry_t new_entry;
1466
1467 new_entry = vm_map_entry_insert(map, entry, start, end, object,
1468 offset, needs_copy, FALSE, FALSE,
1469 cur_protection, max_protection,
1470 VM_BEHAVIOR_DEFAULT, inheritance, 0);
1471 new_entry->alias = alias;
1472 vm_map_unlock(map);
1473
1474 /* Wire down the new entry if the user
1475 * requested all new map entries be wired.
1476 */
1477 if (map->wiring_required) {
1478 result = vm_map_wire(map, start, end,
1479 new_entry->protection, TRUE);
1480 return(result);
1481 }
1482
1483 if ((object != VM_OBJECT_NULL) &&
1484 (vm_map_pmap_enter_enable) &&
1485 (!anywhere) &&
1486 (!needs_copy) &&
1487 (size < (128*1024))) {
1488 vm_map_pmap_enter(map, start, end,
1489 object, offset, cur_protection);
1490 }
1491
1492 return(result);
1493 } /**/
1494
1495 BailOut: ;
1496 vm_map_unlock(map);
1497 return(result);
1498
1499 #undef RETURN
1500 }
1501
1502 /*
1503 * vm_map_clip_start: [ internal use only ]
1504 *
1505 * Asserts that the given entry begins at or after
1506 * the specified address; if necessary,
1507 * it splits the entry into two.
1508 */
1509 #ifndef i386
1510 #define vm_map_clip_start(map, entry, startaddr) \
1511 MACRO_BEGIN \
1512 vm_map_t VMCS_map; \
1513 vm_map_entry_t VMCS_entry; \
1514 vm_offset_t VMCS_startaddr; \
1515 VMCS_map = (map); \
1516 VMCS_entry = (entry); \
1517 VMCS_startaddr = (startaddr); \
1518 if (VMCS_startaddr > VMCS_entry->vme_start) { \
1519 if(entry->use_pmap) { \
1520 vm_offset_t pmap_base_addr; \
1521 vm_offset_t pmap_end_addr; \
1522 \
1523 pmap_base_addr = 0xF0000000 & entry->vme_start; \
1524 pmap_end_addr = (pmap_base_addr + 0x10000000) - 1; \
1525 pmap_unnest(map->pmap, pmap_base_addr, \
1526 (pmap_end_addr - pmap_base_addr) + 1); \
1527 entry->use_pmap = FALSE; \
1528 } \
1529 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
1530 } \
1531 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
1532 MACRO_END
1533 #else
1534 #define vm_map_clip_start(map, entry, startaddr) \
1535 MACRO_BEGIN \
1536 vm_map_t VMCS_map; \
1537 vm_map_entry_t VMCS_entry; \
1538 vm_offset_t VMCS_startaddr; \
1539 VMCS_map = (map); \
1540 VMCS_entry = (entry); \
1541 VMCS_startaddr = (startaddr); \
1542 if (VMCS_startaddr > VMCS_entry->vme_start) { \
1543 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
1544 } \
1545 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
1546 MACRO_END
1547 #endif
1548
1549 #define vm_map_copy_clip_start(copy, entry, startaddr) \
1550 MACRO_BEGIN \
1551 if ((startaddr) > (entry)->vme_start) \
1552 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
1553 MACRO_END
1554
1555 /*
1556 * This routine is called only when it is known that
1557 * the entry must be split.
1558 */
1559 void
1560 _vm_map_clip_start(
1561 register struct vm_map_header *map_header,
1562 register vm_map_entry_t entry,
1563 register vm_offset_t start)
1564 {
1565 register vm_map_entry_t new_entry;
1566
1567 /*
1568 * Split off the front portion --
1569 * note that we must insert the new
1570 * entry BEFORE this one, so that
1571 * this entry has the specified starting
1572 * address.
1573 */
1574
1575 new_entry = _vm_map_entry_create(map_header);
1576 vm_map_entry_copy_full(new_entry, entry);
1577
1578 new_entry->vme_end = start;
1579 entry->offset += (start - entry->vme_start);
1580 entry->vme_start = start;
1581
1582 _vm_map_entry_link(map_header, entry->vme_prev, new_entry);
1583
1584 if (entry->is_sub_map)
1585 vm_map_reference(new_entry->object.sub_map);
1586 else
1587 vm_object_reference(new_entry->object.vm_object);
1588 }
1589
1590
1591 /*
1592 * vm_map_clip_end: [ internal use only ]
1593 *
1594 * Asserts that the given entry ends at or before
1595 * the specified address; if necessary,
1596 * it splits the entry into two.
1597 */
1598 #ifndef i386
1599 #define vm_map_clip_end(map, entry, endaddr) \
1600 MACRO_BEGIN \
1601 vm_map_t VMCE_map; \
1602 vm_map_entry_t VMCE_entry; \
1603 vm_offset_t VMCE_endaddr; \
1604 VMCE_map = (map); \
1605 VMCE_entry = (entry); \
1606 VMCE_endaddr = (endaddr); \
1607 if (VMCE_endaddr < VMCE_entry->vme_end) { \
1608 if(entry->use_pmap) { \
1609 vm_offset_t pmap_base_addr; \
1610 vm_offset_t pmap_end_addr; \
1611 \
1612 pmap_base_addr = 0xF0000000 & entry->vme_start; \
1613 pmap_end_addr = (pmap_base_addr + 0x10000000) - 1; \
1614 pmap_unnest(map->pmap, pmap_base_addr, \
1615 (pmap_end_addr - pmap_base_addr) + 1); \
1616 entry->use_pmap = FALSE; \
1617 } \
1618 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
1619 } \
1620 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
1621 MACRO_END
1622 #else
1623 #define vm_map_clip_end(map, entry, endaddr) \
1624 MACRO_BEGIN \
1625 vm_map_t VMCE_map; \
1626 vm_map_entry_t VMCE_entry; \
1627 vm_offset_t VMCE_endaddr; \
1628 VMCE_map = (map); \
1629 VMCE_entry = (entry); \
1630 VMCE_endaddr = (endaddr); \
1631 if (VMCE_endaddr < VMCE_entry->vme_end) { \
1632 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
1633 } \
1634 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
1635 MACRO_END
1636 #endif
1637
1638 #define vm_map_copy_clip_end(copy, entry, endaddr) \
1639 MACRO_BEGIN \
1640 if ((endaddr) < (entry)->vme_end) \
1641 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
1642 MACRO_END
1643
1644 /*
1645 * This routine is called only when it is known that
1646 * the entry must be split.
1647 */
1648 void
1649 _vm_map_clip_end(
1650 register struct vm_map_header *map_header,
1651 register vm_map_entry_t entry,
1652 register vm_offset_t end)
1653 {
1654 register vm_map_entry_t new_entry;
1655
1656 /*
1657 * Create a new entry and insert it
1658 * AFTER the specified entry
1659 */
1660
1661 new_entry = _vm_map_entry_create(map_header);
1662 vm_map_entry_copy_full(new_entry, entry);
1663
1664 new_entry->vme_start = entry->vme_end = end;
1665 new_entry->offset += (end - entry->vme_start);
1666
1667 _vm_map_entry_link(map_header, entry, new_entry);
1668
1669 if (entry->is_sub_map)
1670 vm_map_reference(new_entry->object.sub_map);
1671 else
1672 vm_object_reference(new_entry->object.vm_object);
1673 }
1674
1675
1676 /*
1677 * VM_MAP_RANGE_CHECK: [ internal use only ]
1678 *
1679 * Asserts that the starting and ending region
1680 * addresses fall within the valid range of the map.
1681 */
1682 #define VM_MAP_RANGE_CHECK(map, start, end) \
1683 { \
1684 if (start < vm_map_min(map)) \
1685 start = vm_map_min(map); \
1686 if (end > vm_map_max(map)) \
1687 end = vm_map_max(map); \
1688 if (start > end) \
1689 start = end; \
1690 }
1691
1692 /*
1693 * vm_map_range_check: [ internal use only ]
1694 *
1695 * Check that the region defined by the specified start and
1696 * end addresses are wholly contained within a single map
1697 * entry or set of adjacent map entries of the spacified map,
1698 * i.e. the specified region contains no unmapped space.
1699 * If any or all of the region is unmapped, FALSE is returned.
1700 * Otherwise, TRUE is returned and if the output argument 'entry'
1701 * is not NULL it points to the map entry containing the start
1702 * of the region.
1703 *
1704 * The map is locked for reading on entry and is left locked.
1705 */
1706 boolean_t
1707 vm_map_range_check(
1708 register vm_map_t map,
1709 register vm_offset_t start,
1710 register vm_offset_t end,
1711 vm_map_entry_t *entry)
1712 {
1713 vm_map_entry_t cur;
1714 register vm_offset_t prev;
1715
1716 /*
1717 * Basic sanity checks first
1718 */
1719 if (start < vm_map_min(map) || end > vm_map_max(map) || start > end)
1720 return (FALSE);
1721
1722 /*
1723 * Check first if the region starts within a valid
1724 * mapping for the map.
1725 */
1726 if (!vm_map_lookup_entry(map, start, &cur))
1727 return (FALSE);
1728
1729 /*
1730 * Optimize for the case that the region is contained
1731 * in a single map entry.
1732 */
1733 if (entry != (vm_map_entry_t *) NULL)
1734 *entry = cur;
1735 if (end <= cur->vme_end)
1736 return (TRUE);
1737
1738 /*
1739 * If the region is not wholly contained within a
1740 * single entry, walk the entries looking for holes.
1741 */
1742 prev = cur->vme_end;
1743 cur = cur->vme_next;
1744 while ((cur != vm_map_to_entry(map)) && (prev == cur->vme_start)) {
1745 if (end <= cur->vme_end)
1746 return (TRUE);
1747 prev = cur->vme_end;
1748 cur = cur->vme_next;
1749 }
1750 return (FALSE);
1751 }
1752
1753 /*
1754 * vm_map_submap: [ kernel use only ]
1755 *
1756 * Mark the given range as handled by a subordinate map.
1757 *
1758 * This range must have been created with vm_map_find using
1759 * the vm_submap_object, and no other operations may have been
1760 * performed on this range prior to calling vm_map_submap.
1761 *
1762 * Only a limited number of operations can be performed
1763 * within this rage after calling vm_map_submap:
1764 * vm_fault
1765 * [Don't try vm_map_copyin!]
1766 *
1767 * To remove a submapping, one must first remove the
1768 * range from the superior map, and then destroy the
1769 * submap (if desired). [Better yet, don't try it.]
1770 */
1771 kern_return_t
1772 vm_map_submap(
1773 register vm_map_t map,
1774 register vm_offset_t start,
1775 register vm_offset_t end,
1776 vm_map_t submap,
1777 vm_offset_t offset,
1778 boolean_t use_pmap)
1779 {
1780 vm_map_entry_t entry;
1781 register kern_return_t result = KERN_INVALID_ARGUMENT;
1782 register vm_object_t object;
1783
1784 vm_map_lock(map);
1785
1786 VM_MAP_RANGE_CHECK(map, start, end);
1787
1788 if (vm_map_lookup_entry(map, start, &entry)) {
1789 vm_map_clip_start(map, entry, start);
1790 }
1791 else
1792 entry = entry->vme_next;
1793
1794 if(entry == vm_map_to_entry(map)) {
1795 vm_map_unlock(map);
1796 return KERN_INVALID_ARGUMENT;
1797 }
1798
1799 vm_map_clip_end(map, entry, end);
1800
1801 if ((entry->vme_start == start) && (entry->vme_end == end) &&
1802 (!entry->is_sub_map) &&
1803 ((object = entry->object.vm_object) == vm_submap_object) &&
1804 (object->resident_page_count == 0) &&
1805 (object->copy == VM_OBJECT_NULL) &&
1806 (object->shadow == VM_OBJECT_NULL) &&
1807 (!object->pager_created)) {
1808 entry->offset = (vm_object_offset_t)offset;
1809 entry->object.vm_object = VM_OBJECT_NULL;
1810 vm_object_deallocate(object);
1811 entry->is_sub_map = TRUE;
1812 vm_map_reference(entry->object.sub_map = submap);
1813 #ifndef i386
1814 if ((use_pmap) && (offset == 0)) {
1815 /* nest if platform code will allow */
1816 result = pmap_nest(map->pmap, (entry->object.sub_map)->pmap,
1817 start, end - start);
1818 if(result)
1819 panic("pmap_nest failed!");
1820 entry->use_pmap = TRUE;
1821 }
1822 #endif
1823 #ifdef i386
1824 pmap_remove(map->pmap, start, end);
1825 #endif
1826 result = KERN_SUCCESS;
1827 }
1828 vm_map_unlock(map);
1829
1830 return(result);
1831 }
1832
1833 /*
1834 * vm_map_protect:
1835 *
1836 * Sets the protection of the specified address
1837 * region in the target map. If "set_max" is
1838 * specified, the maximum protection is to be set;
1839 * otherwise, only the current protection is affected.
1840 */
1841 kern_return_t
1842 vm_map_protect(
1843 register vm_map_t map,
1844 register vm_offset_t start,
1845 register vm_offset_t end,
1846 register vm_prot_t new_prot,
1847 register boolean_t set_max)
1848 {
1849 register vm_map_entry_t current;
1850 register vm_offset_t prev;
1851 vm_map_entry_t entry;
1852 vm_prot_t new_max;
1853 boolean_t clip;
1854
1855 XPR(XPR_VM_MAP,
1856 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
1857 (integer_t)map, start, end, new_prot, set_max);
1858
1859 vm_map_lock(map);
1860
1861 /*
1862 * Lookup the entry. If it doesn't start in a valid
1863 * entry, return an error. Remember if we need to
1864 * clip the entry. We don't do it here because we don't
1865 * want to make any changes until we've scanned the
1866 * entire range below for address and protection
1867 * violations.
1868 */
1869 if (!(clip = vm_map_lookup_entry(map, start, &entry))) {
1870 vm_map_unlock(map);
1871 return(KERN_INVALID_ADDRESS);
1872 }
1873
1874 /*
1875 * Make a first pass to check for protection and address
1876 * violations.
1877 */
1878
1879 current = entry;
1880 prev = current->vme_start;
1881 while ((current != vm_map_to_entry(map)) &&
1882 (current->vme_start < end)) {
1883
1884 /*
1885 * If there is a hole, return an error.
1886 */
1887 if (current->vme_start != prev) {
1888 vm_map_unlock(map);
1889 return(KERN_INVALID_ADDRESS);
1890 }
1891
1892 new_max = current->max_protection;
1893 if(new_prot & VM_PROT_COPY) {
1894 new_max |= VM_PROT_WRITE;
1895 if ((new_prot & (new_max | VM_PROT_COPY)) != new_prot) {
1896 vm_map_unlock(map);
1897 return(KERN_PROTECTION_FAILURE);
1898 }
1899 } else {
1900 if ((new_prot & new_max) != new_prot) {
1901 vm_map_unlock(map);
1902 return(KERN_PROTECTION_FAILURE);
1903 }
1904 }
1905
1906 prev = current->vme_end;
1907 current = current->vme_next;
1908 }
1909 if (end > prev) {
1910 vm_map_unlock(map);
1911 return(KERN_INVALID_ADDRESS);
1912 }
1913
1914 /*
1915 * Go back and fix up protections.
1916 * Clip to start here if the range starts within
1917 * the entry.
1918 */
1919
1920 current = entry;
1921 if (clip) {
1922 vm_map_clip_start(map, entry, start);
1923 }
1924 while ((current != vm_map_to_entry(map)) &&
1925 (current->vme_start < end)) {
1926
1927 vm_prot_t old_prot;
1928
1929 vm_map_clip_end(map, current, end);
1930
1931 old_prot = current->protection;
1932
1933 if(new_prot & VM_PROT_COPY) {
1934 /* caller is asking specifically to copy the */
1935 /* mapped data, this implies that max protection */
1936 /* will include write. Caller must be prepared */
1937 /* for loss of shared memory communication in the */
1938 /* target area after taking this step */
1939 current->needs_copy = TRUE;
1940 current->max_protection |= VM_PROT_WRITE;
1941 }
1942
1943 if (set_max)
1944 current->protection =
1945 (current->max_protection =
1946 new_prot & ~VM_PROT_COPY) &
1947 old_prot;
1948 else
1949 current->protection = new_prot & ~VM_PROT_COPY;
1950
1951 /*
1952 * Update physical map if necessary.
1953 * If the request is to turn off write protection,
1954 * we won't do it for real (in pmap). This is because
1955 * it would cause copy-on-write to fail. We've already
1956 * set, the new protection in the map, so if a
1957 * write-protect fault occurred, it will be fixed up
1958 * properly, COW or not.
1959 */
1960 /* the 256M hack for existing hardware limitations */
1961 if (current->protection != old_prot) {
1962 if(current->is_sub_map && current->use_pmap) {
1963 vm_offset_t pmap_base_addr;
1964 vm_offset_t pmap_end_addr;
1965 vm_map_entry_t local_entry;
1966
1967 pmap_base_addr = 0xF0000000 & current->vme_start;
1968 pmap_end_addr = (pmap_base_addr + 0x10000000) - 1;
1969 #ifndef i386
1970 if(!vm_map_lookup_entry(map,
1971 pmap_base_addr, &local_entry))
1972 panic("vm_map_protect: nested pmap area is missing");
1973 while ((local_entry != vm_map_to_entry(map)) &&
1974 (local_entry->vme_start < pmap_end_addr)) {
1975 local_entry->use_pmap = FALSE;
1976 local_entry = local_entry->vme_next;
1977 }
1978 pmap_unnest(map->pmap, pmap_base_addr,
1979 (pmap_end_addr - pmap_base_addr) + 1);
1980 #endif
1981 }
1982 if (!(current->protection & VM_PROT_WRITE)) {
1983 /* Look one level in we support nested pmaps */
1984 /* from mapped submaps which are direct entries */
1985 /* in our map */
1986 if(current->is_sub_map && current->use_pmap) {
1987 pmap_protect(current->object.sub_map->pmap,
1988 current->vme_start,
1989 current->vme_end,
1990 current->protection);
1991 } else {
1992 pmap_protect(map->pmap, current->vme_start,
1993 current->vme_end,
1994 current->protection);
1995 }
1996 }
1997 }
1998 current = current->vme_next;
1999 }
2000
2001 vm_map_unlock(map);
2002 return(KERN_SUCCESS);
2003 }
2004
2005 /*
2006 * vm_map_inherit:
2007 *
2008 * Sets the inheritance of the specified address
2009 * range in the target map. Inheritance
2010 * affects how the map will be shared with
2011 * child maps at the time of vm_map_fork.
2012 */
2013 kern_return_t
2014 vm_map_inherit(
2015 register vm_map_t map,
2016 register vm_offset_t start,
2017 register vm_offset_t end,
2018 register vm_inherit_t new_inheritance)
2019 {
2020 register vm_map_entry_t entry;
2021 vm_map_entry_t temp_entry;
2022
2023 vm_map_lock(map);
2024
2025 VM_MAP_RANGE_CHECK(map, start, end);
2026
2027 if (vm_map_lookup_entry(map, start, &temp_entry)) {
2028 entry = temp_entry;
2029 vm_map_clip_start(map, entry, start);
2030 }
2031 else {
2032 temp_entry = temp_entry->vme_next;
2033 entry = temp_entry;
2034 }
2035
2036 /* first check entire range for submaps which can't support the */
2037 /* given inheritance. */
2038 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
2039 if(entry->is_sub_map) {
2040 if(new_inheritance == VM_INHERIT_COPY)
2041 return(KERN_INVALID_ARGUMENT);
2042 }
2043
2044 entry = entry->vme_next;
2045 }
2046
2047 entry = temp_entry;
2048
2049 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
2050 vm_map_clip_end(map, entry, end);
2051
2052 entry->inheritance = new_inheritance;
2053
2054 entry = entry->vme_next;
2055 }
2056
2057 vm_map_unlock(map);
2058 return(KERN_SUCCESS);
2059 }
2060
2061 /*
2062 * vm_map_wire:
2063 *
2064 * Sets the pageability of the specified address range in the
2065 * target map as wired. Regions specified as not pageable require
2066 * locked-down physical memory and physical page maps. The
2067 * access_type variable indicates types of accesses that must not
2068 * generate page faults. This is checked against protection of
2069 * memory being locked-down.
2070 *
2071 * The map must not be locked, but a reference must remain to the
2072 * map throughout the call.
2073 */
2074 kern_return_t
2075 vm_map_wire_nested(
2076 register vm_map_t map,
2077 register vm_offset_t start,
2078 register vm_offset_t end,
2079 register vm_prot_t access_type,
2080 boolean_t user_wire,
2081 pmap_t map_pmap)
2082 {
2083 register vm_map_entry_t entry;
2084 struct vm_map_entry *first_entry, tmp_entry;
2085 vm_map_t pmap_map;
2086 register vm_offset_t s,e;
2087 kern_return_t rc;
2088 boolean_t need_wakeup;
2089 boolean_t main_map = FALSE;
2090 unsigned int last_timestamp;
2091 vm_size_t size;
2092
2093 vm_map_lock(map);
2094 if(map_pmap == NULL)
2095 main_map = TRUE;
2096 last_timestamp = map->timestamp;
2097
2098 VM_MAP_RANGE_CHECK(map, start, end);
2099 assert(page_aligned(start));
2100 assert(page_aligned(end));
2101
2102 if (vm_map_lookup_entry(map, start, &first_entry)) {
2103 entry = first_entry;
2104 /* vm_map_clip_start will be done later. */
2105 } else {
2106 /* Start address is not in map */
2107 vm_map_unlock(map);
2108 return(KERN_INVALID_ADDRESS);
2109 }
2110
2111 s=start;
2112 need_wakeup = FALSE;
2113 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
2114 /*
2115 * If another thread is wiring/unwiring this entry then
2116 * block after informing other thread to wake us up.
2117 */
2118 if (entry->in_transition) {
2119 /*
2120 * We have not clipped the entry. Make sure that
2121 * the start address is in range so that the lookup
2122 * below will succeed.
2123 */
2124 s = entry->vme_start < start? start: entry->vme_start;
2125
2126 entry->needs_wakeup = TRUE;
2127
2128 /*
2129 * wake up anybody waiting on entries that we have
2130 * already wired.
2131 */
2132 if (need_wakeup) {
2133 vm_map_entry_wakeup(map);
2134 need_wakeup = FALSE;
2135 }
2136 /*
2137 * User wiring is interruptible
2138 */
2139 vm_map_entry_wait(map,
2140 (user_wire) ? THREAD_ABORTSAFE :
2141 THREAD_UNINT);
2142 if (user_wire && current_thread()->wait_result ==
2143 THREAD_INTERRUPTED) {
2144 /*
2145 * undo the wirings we have done so far
2146 * We do not clear the needs_wakeup flag,
2147 * because we cannot tell if we were the
2148 * only one waiting.
2149 */
2150 vm_map_unwire(map, start, s, user_wire);
2151 return(KERN_FAILURE);
2152 }
2153
2154 vm_map_lock(map);
2155 /*
2156 * Cannot avoid a lookup here. reset timestamp.
2157 */
2158 last_timestamp = map->timestamp;
2159
2160 /*
2161 * The entry could have been clipped, look it up again.
2162 * Worse that can happen is, it may not exist anymore.
2163 */
2164 if (!vm_map_lookup_entry(map, s, &first_entry)) {
2165 if (!user_wire)
2166 panic("vm_map_wire: re-lookup failed");
2167
2168 /*
2169 * User: undo everything upto the previous
2170 * entry. let vm_map_unwire worry about
2171 * checking the validity of the range.
2172 */
2173 vm_map_unlock(map);
2174 vm_map_unwire(map, start, s, user_wire);
2175 return(KERN_FAILURE);
2176 }
2177 entry = first_entry;
2178 continue;
2179 }
2180
2181 if(entry->is_sub_map) {
2182 vm_offset_t sub_start;
2183 vm_offset_t sub_end;
2184 vm_offset_t local_end;
2185 pmap_t pmap;
2186
2187 vm_map_clip_start(map, entry, start);
2188 vm_map_clip_end(map, entry, end);
2189
2190 sub_start += entry->offset;
2191 sub_end = entry->vme_end - entry->vme_start;
2192 sub_end += entry->offset;
2193
2194 local_end = entry->vme_end;
2195 if(map_pmap == NULL) {
2196 if(entry->use_pmap) {
2197 pmap = entry->object.sub_map->pmap;
2198 } else {
2199 pmap = map->pmap;
2200 }
2201 if (entry->wired_count) {
2202 if (entry->wired_count
2203 >= MAX_WIRE_COUNT)
2204 panic("vm_map_wire: too many wirings");
2205
2206 if (user_wire &&
2207 entry->user_wired_count
2208 >= MAX_WIRE_COUNT) {
2209 vm_map_unlock(map);
2210 vm_map_unwire(map, start,
2211 entry->vme_start, user_wire);
2212 return(KERN_FAILURE);
2213 }
2214 if (!user_wire ||
2215 (entry->user_wired_count++ == 0))
2216 entry->wired_count++;
2217 entry = entry->vme_next;
2218 continue;
2219
2220 } else {
2221 vm_object_t object;
2222 vm_object_offset_t offset_hi;
2223 vm_object_offset_t offset_lo;
2224 vm_object_offset_t offset;
2225 vm_prot_t prot;
2226 boolean_t wired;
2227 vm_behavior_t behavior;
2228 vm_offset_t local_start;
2229 vm_map_entry_t local_entry;
2230 vm_map_version_t version;
2231 vm_map_t lookup_map;
2232
2233 /* call vm_map_lookup_locked to */
2234 /* cause any needs copy to be */
2235 /* evaluated */
2236 local_start = entry->vme_start;
2237 lookup_map = map;
2238 vm_map_lock_write_to_read(map);
2239 if(vm_map_lookup_locked(
2240 &lookup_map, local_start,
2241 VM_PROT_WRITE,
2242 &version, &object,
2243 &offset, &prot, &wired,
2244 &behavior, &offset_lo,
2245 &offset_hi, &pmap_map)) {
2246
2247 vm_map_unlock(lookup_map);
2248 vm_map_unwire(map, start,
2249 entry->vme_start, user_wire);
2250 return(KERN_FAILURE);
2251 }
2252 if(pmap_map != lookup_map)
2253 vm_map_unlock(pmap_map);
2254 if(lookup_map != map) {
2255 vm_map_unlock(lookup_map);
2256 vm_map_lock(map);
2257 } else {
2258 vm_map_unlock(map);
2259 vm_map_lock(map);
2260 }
2261 last_timestamp =
2262 version.main_timestamp;
2263 vm_object_unlock(object);
2264 if (vm_map_lookup_entry(map,
2265 local_start, &local_entry)) {
2266 vm_map_unlock(map);
2267 vm_map_unwire(map, start,
2268 entry->vme_start, user_wire);
2269 return(KERN_FAILURE);
2270 }
2271 /* did we have a change of type? */
2272 if (!local_entry->is_sub_map)
2273 continue;
2274 entry = local_entry;
2275 if (user_wire)
2276 entry->user_wired_count++;
2277 entry->wired_count++;
2278
2279 entry->in_transition = TRUE;
2280
2281 vm_map_unlock(map);
2282 rc = vm_map_wire_nested(
2283 entry->object.sub_map,
2284 sub_start, sub_end,
2285 access_type,
2286 user_wire, pmap);
2287 vm_map_lock(map);
2288 last_timestamp = map->timestamp;
2289 }
2290 } else {
2291 vm_map_unlock(map);
2292 rc = vm_map_wire_nested(entry->object.sub_map,
2293 sub_start, sub_end,
2294 access_type,
2295 user_wire, pmap);
2296 vm_map_lock(map);
2297 last_timestamp = map->timestamp;
2298 }
2299 s = entry->vme_start;
2300 e = entry->vme_end;
2301 if (last_timestamp+1 != map->timestamp) {
2302 /*
2303 * Find the entry again. It could have been clipped
2304 * after we unlocked the map.
2305 */
2306 if (!vm_map_lookup_entry(map, local_end,
2307 &first_entry))
2308 panic("vm_map_wire: re-lookup failed");
2309
2310 entry = first_entry;
2311 }
2312
2313 last_timestamp = map->timestamp;
2314 while ((entry != vm_map_to_entry(map)) &&
2315 (entry->vme_start < e)) {
2316 assert(entry->in_transition);
2317 entry->in_transition = FALSE;
2318 if (entry->needs_wakeup) {
2319 entry->needs_wakeup = FALSE;
2320 need_wakeup = TRUE;
2321 }
2322 if (rc != KERN_SUCCESS) {/* from vm_*_wire */
2323 if(main_map) {
2324 if (user_wire)
2325 entry->user_wired_count--;
2326 entry->wired_count--;
2327 }
2328 }
2329 entry = entry->vme_next;
2330 }
2331 if (rc != KERN_SUCCESS) { /* from vm_*_wire */
2332 vm_map_unlock(map);
2333 if (need_wakeup)
2334 vm_map_entry_wakeup(map);
2335 /*
2336 * undo everything upto the previous entry.
2337 */
2338 (void)vm_map_unwire(map, start, s, user_wire);
2339 return rc;
2340 }
2341 continue;
2342 }
2343
2344 /*
2345 * If this entry is already wired then increment
2346 * the appropriate wire reference count.
2347 */
2348 if (entry->wired_count && main_map) {
2349 /* sanity check: wired_count is a short */
2350 if (entry->wired_count >= MAX_WIRE_COUNT)
2351 panic("vm_map_wire: too many wirings");
2352
2353 if (user_wire &&
2354 entry->user_wired_count >= MAX_WIRE_COUNT) {
2355 vm_map_unlock(map);
2356 vm_map_unwire(map, start,
2357 entry->vme_start, user_wire);
2358 return(KERN_FAILURE);
2359 }
2360 /*
2361 * entry is already wired down, get our reference
2362 * after clipping to our range.
2363 */
2364 vm_map_clip_start(map, entry, start);
2365 vm_map_clip_end(map, entry, end);
2366 if (!user_wire || (entry->user_wired_count++ == 0))
2367 entry->wired_count++;
2368
2369 entry = entry->vme_next;
2370 continue;
2371 }
2372
2373 /*
2374 * Unwired entry or wire request transmitted via submap
2375 */
2376
2377
2378 /*
2379 * Perform actions of vm_map_lookup that need the write
2380 * lock on the map: create a shadow object for a
2381 * copy-on-write region, or an object for a zero-fill
2382 * region.
2383 */
2384 size = entry->vme_end - entry->vme_start;
2385 /*
2386 * If wiring a copy-on-write page, we need to copy it now
2387 * even if we're only (currently) requesting read access.
2388 * This is aggressive, but once it's wired we can't move it.
2389 */
2390 if (entry->needs_copy) {
2391 vm_object_shadow(&entry->object.vm_object,
2392 &entry->offset, size);
2393 entry->needs_copy = FALSE;
2394 } else if (entry->object.vm_object == VM_OBJECT_NULL) {
2395 entry->object.vm_object = vm_object_allocate(size);
2396 entry->offset = (vm_object_offset_t)0;
2397 }
2398
2399 vm_map_clip_start(map, entry, start);
2400 vm_map_clip_end(map, entry, end);
2401
2402 s = entry->vme_start;
2403 e = entry->vme_end;
2404
2405 /*
2406 * Check for holes and protection mismatch.
2407 * Holes: Next entry should be contiguous unless this
2408 * is the end of the region.
2409 * Protection: Access requested must be allowed, unless
2410 * wiring is by protection class
2411 */
2412 if ((((entry->vme_end < end) &&
2413 ((entry->vme_next == vm_map_to_entry(map)) ||
2414 (entry->vme_next->vme_start > entry->vme_end))) ||
2415 ((entry->protection & access_type) != access_type))) {
2416 /*
2417 * Found a hole or protection problem.
2418 * Unwire the region we wired so far.
2419 */
2420 if (start != entry->vme_start) {
2421 vm_map_unlock(map);
2422 vm_map_unwire(map, start, s, user_wire);
2423 } else {
2424 vm_map_unlock(map);
2425 }
2426 return((entry->protection&access_type) != access_type?
2427 KERN_PROTECTION_FAILURE: KERN_INVALID_ADDRESS);
2428 }
2429
2430 assert(entry->wired_count == 0 && entry->user_wired_count == 0);
2431
2432 if(main_map) {
2433 if (user_wire)
2434 entry->user_wired_count++;
2435 entry->wired_count++;
2436 }
2437
2438 entry->in_transition = TRUE;
2439
2440 /*
2441 * This entry might get split once we unlock the map.
2442 * In vm_fault_wire(), we need the current range as
2443 * defined by this entry. In order for this to work
2444 * along with a simultaneous clip operation, we make a
2445 * temporary copy of this entry and use that for the
2446 * wiring. Note that the underlying objects do not
2447 * change during a clip.
2448 */
2449 tmp_entry = *entry;
2450
2451 /*
2452 * The in_transition state guarentees that the entry
2453 * (or entries for this range, if split occured) will be
2454 * there when the map lock is acquired for the second time.
2455 */
2456 vm_map_unlock(map);
2457 if(map_pmap)
2458 rc = vm_fault_wire(map, &tmp_entry, map_pmap);
2459 else
2460 rc = vm_fault_wire(map, &tmp_entry, map->pmap);
2461 vm_map_lock(map);
2462
2463 if (last_timestamp+1 != map->timestamp) {
2464 /*
2465 * Find the entry again. It could have been clipped
2466 * after we unlocked the map.
2467 */
2468 if (!vm_map_lookup_entry(map, tmp_entry.vme_start,
2469 &first_entry))
2470 panic("vm_map_wire: re-lookup failed");
2471
2472 entry = first_entry;
2473 }
2474
2475 last_timestamp = map->timestamp;
2476
2477 while ((entry != vm_map_to_entry(map)) &&
2478 (entry->vme_start < tmp_entry.vme_end)) {
2479 assert(entry->in_transition);
2480 entry->in_transition = FALSE;
2481 if (entry->needs_wakeup) {
2482 entry->needs_wakeup = FALSE;
2483 need_wakeup = TRUE;
2484 }
2485 if (rc != KERN_SUCCESS) { /* from vm_*_wire */
2486 if(main_map) {
2487 if (user_wire)
2488 entry->user_wired_count--;
2489 entry->wired_count--;
2490 }
2491 }
2492 entry = entry->vme_next;
2493 }
2494
2495 if (rc != KERN_SUCCESS) { /* from vm_*_wire */
2496 vm_map_unlock(map);
2497 if (need_wakeup)
2498 vm_map_entry_wakeup(map);
2499 /*
2500 * undo everything upto the previous entry.
2501 */
2502 (void)vm_map_unwire(map, start, s, user_wire);
2503 return rc;
2504 }
2505 } /* end while loop through map entries */
2506 vm_map_unlock(map);
2507
2508 /*
2509 * wake up anybody waiting on entries we wired.
2510 */
2511 if (need_wakeup)
2512 vm_map_entry_wakeup(map);
2513
2514 return(KERN_SUCCESS);
2515
2516 }
2517
2518 kern_return_t
2519 vm_map_wire(
2520 register vm_map_t map,
2521 register vm_offset_t start,
2522 register vm_offset_t end,
2523 register vm_prot_t access_type,
2524 boolean_t user_wire)
2525 {
2526
2527 kern_return_t kret;
2528
2529 #ifdef ppc
2530 /*
2531 * the calls to mapping_prealloc and mapping_relpre
2532 * (along with the VM_MAP_RANGE_CHECK to insure a
2533 * resonable range was passed in) are
2534 * currently necessary because
2535 * we haven't enabled kernel pre-emption
2536 * and/or the pmap_enter cannot purge and re-use
2537 * existing mappings
2538 */
2539 VM_MAP_RANGE_CHECK(map, start, end);
2540 mapping_prealloc(end - start);
2541 #endif
2542 kret = vm_map_wire_nested(map, start, end, access_type,
2543 user_wire, (pmap_t)NULL);
2544 #ifdef ppc
2545 mapping_relpre();
2546 #endif
2547 return kret;
2548 }
2549
2550 /*
2551 * vm_map_unwire:
2552 *
2553 * Sets the pageability of the specified address range in the target
2554 * as pageable. Regions specified must have been wired previously.
2555 *
2556 * The map must not be locked, but a reference must remain to the map
2557 * throughout the call.
2558 *
2559 * Kernel will panic on failures. User unwire ignores holes and
2560 * unwired and intransition entries to avoid losing memory by leaving
2561 * it unwired.
2562 */
2563 kern_return_t
2564 vm_map_unwire_nested(
2565 register vm_map_t map,
2566 register vm_offset_t start,
2567 register vm_offset_t end,
2568 boolean_t user_wire,
2569 pmap_t map_pmap)
2570 {
2571 register vm_map_entry_t entry;
2572 struct vm_map_entry *first_entry, tmp_entry;
2573 boolean_t need_wakeup;
2574 boolean_t main_map = FALSE;
2575 unsigned int last_timestamp;
2576
2577 vm_map_lock(map);
2578 if(map_pmap == NULL)
2579 main_map = TRUE;
2580 last_timestamp = map->timestamp;
2581
2582 VM_MAP_RANGE_CHECK(map, start, end);
2583 assert(page_aligned(start));
2584 assert(page_aligned(end));
2585
2586 if (vm_map_lookup_entry(map, start, &first_entry)) {
2587 entry = first_entry;
2588 /* vm_map_clip_start will be done later. */
2589 }
2590 else {
2591 /* Start address is not in map. */
2592 vm_map_unlock(map);
2593 return(KERN_INVALID_ADDRESS);
2594 }
2595
2596 need_wakeup = FALSE;
2597 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
2598 if (entry->in_transition) {
2599 /*
2600 * 1)
2601 * Another thread is wiring down this entry. Note
2602 * that if it is not for the other thread we would
2603 * be unwiring an unwired entry. This is not
2604 * permitted. If we wait, we will be unwiring memory
2605 * we did not wire.
2606 *
2607 * 2)
2608 * Another thread is unwiring this entry. We did not
2609 * have a reference to it, because if we did, this
2610 * entry will not be getting unwired now.
2611 */
2612 if (!user_wire)
2613 panic("vm_map_unwire: in_transition entry");
2614
2615 entry = entry->vme_next;
2616 continue;
2617 }
2618
2619 if(entry->is_sub_map) {
2620 vm_offset_t sub_start;
2621 vm_offset_t sub_end;
2622 vm_offset_t local_end;
2623 pmap_t pmap;
2624
2625
2626 vm_map_clip_start(map, entry, start);
2627 vm_map_clip_end(map, entry, end);
2628
2629 sub_start = entry->offset;
2630 sub_end = entry->vme_end - entry->vme_start;
2631 sub_end += entry->offset;
2632 local_end = entry->vme_end;
2633 if(map_pmap == NULL) {
2634 if(entry->use_pmap) {
2635 pmap = entry->object.sub_map->pmap;
2636 } else {
2637 pmap = map->pmap;
2638 }
2639 if (entry->wired_count == 0 ||
2640 (user_wire && entry->user_wired_count == 0)) {
2641 if (!user_wire)
2642 panic("vm_map_unwire: entry is unwired");
2643 entry = entry->vme_next;
2644 continue;
2645 }
2646
2647 /*
2648 * Check for holes
2649 * Holes: Next entry should be contiguous unless
2650 * this is the end of the region.
2651 */
2652 if (((entry->vme_end < end) &&
2653 ((entry->vme_next == vm_map_to_entry(map)) ||
2654 (entry->vme_next->vme_start
2655 > entry->vme_end)))) {
2656 if (!user_wire)
2657 panic("vm_map_unwire: non-contiguous region");
2658 /*
2659 entry = entry->vme_next;
2660 continue;
2661 */
2662 }
2663
2664 if (!user_wire || (--entry->user_wired_count == 0))
2665 entry->wired_count--;
2666
2667 if (entry->wired_count != 0) {
2668 entry = entry->vme_next;
2669 continue;
2670 }
2671
2672 entry->in_transition = TRUE;
2673 tmp_entry = *entry;/* see comment in vm_map_wire() */
2674
2675 /*
2676 * We can unlock the map now. The in_transition state
2677 * guarantees existance of the entry.
2678 */
2679 vm_map_unlock(map);
2680 vm_map_unwire_nested(entry->object.sub_map,
2681 sub_start, sub_end, user_wire, pmap);
2682 vm_map_lock(map);
2683
2684 if (last_timestamp+1 != map->timestamp) {
2685 /*
2686 * Find the entry again. It could have been
2687 * clipped or deleted after we unlocked the map.
2688 */
2689 if (!vm_map_lookup_entry(map,
2690 tmp_entry.vme_start,
2691 &first_entry)) {
2692 if (!user_wire)
2693 panic("vm_map_unwire: re-lookup failed");
2694 entry = first_entry->vme_next;
2695 } else
2696 entry = first_entry;
2697 }
2698 last_timestamp = map->timestamp;
2699
2700 /*
2701 * clear transition bit for all constituent entries
2702 * that were in the original entry (saved in
2703 * tmp_entry). Also check for waiters.
2704 */
2705 while ((entry != vm_map_to_entry(map)) &&
2706 (entry->vme_start < tmp_entry.vme_end)) {
2707 assert(entry->in_transition);
2708 entry->in_transition = FALSE;
2709 if (entry->needs_wakeup) {
2710 entry->needs_wakeup = FALSE;
2711 need_wakeup = TRUE;
2712 }
2713 entry = entry->vme_next;
2714 }
2715 continue;
2716 } else {
2717 vm_map_unlock(map);
2718 vm_map_unwire_nested(entry->object.sub_map,
2719 sub_start, sub_end, user_wire, pmap);
2720 vm_map_lock(map);
2721
2722 if (last_timestamp+1 != map->timestamp) {
2723 /*
2724 * Find the entry again. It could have been
2725 * clipped or deleted after we unlocked the map.
2726 */
2727 if (!vm_map_lookup_entry(map,
2728 tmp_entry.vme_start,
2729 &first_entry)) {
2730 if (!user_wire)
2731 panic("vm_map_unwire: re-lookup failed");
2732 entry = first_entry->vme_next;
2733 } else
2734 entry = first_entry;
2735 }
2736 last_timestamp = map->timestamp;
2737 }
2738 }
2739
2740
2741 if (main_map && (entry->wired_count == 0 ||
2742 (user_wire && entry->user_wired_count == 0))) {
2743 if (!user_wire)
2744 panic("vm_map_unwire: entry is unwired");
2745
2746 entry = entry->vme_next;
2747 continue;
2748 }
2749
2750 assert(entry->wired_count > 0 &&
2751 (!user_wire || entry->user_wired_count > 0));
2752
2753 vm_map_clip_start(map, entry, start);
2754 vm_map_clip_end(map, entry, end);
2755
2756 /*
2757 * Check for holes
2758 * Holes: Next entry should be contiguous unless
2759 * this is the end of the region.
2760 */
2761 if (((entry->vme_end < end) &&
2762 ((entry->vme_next == vm_map_to_entry(map)) ||
2763 (entry->vme_next->vme_start > entry->vme_end)))) {
2764
2765 if (!user_wire)
2766 panic("vm_map_unwire: non-contiguous region");
2767 entry = entry->vme_next;
2768 continue;
2769 }
2770
2771 if(main_map) {
2772 if (!user_wire || (--entry->user_wired_count == 0))
2773 entry->wired_count--;
2774
2775 if (entry->wired_count != 0) {
2776 entry = entry->vme_next;
2777 continue;
2778 }
2779 }
2780
2781 entry->in_transition = TRUE;
2782 tmp_entry = *entry; /* see comment in vm_map_wire() */
2783
2784 /*
2785 * We can unlock the map now. The in_transition state
2786 * guarantees existance of the entry.
2787 */
2788 vm_map_unlock(map);
2789 if(map_pmap) {
2790 vm_fault_unwire(map, &tmp_entry, FALSE, map_pmap);
2791 } else {
2792 vm_fault_unwire(map, &tmp_entry, FALSE, map->pmap);
2793 }
2794 vm_map_lock(map);
2795
2796 if (last_timestamp+1 != map->timestamp) {
2797 /*
2798 * Find the entry again. It could have been clipped
2799 * or deleted after we unlocked the map.
2800 */
2801 if (!vm_map_lookup_entry(map, tmp_entry.vme_start,
2802 &first_entry)) {
2803 if (!user_wire)
2804 panic("vm_map_unwire: re-lookup failed");
2805 entry = first_entry->vme_next;
2806 } else
2807 entry = first_entry;
2808 }
2809 last_timestamp = map->timestamp;
2810
2811 /*
2812 * clear transition bit for all constituent entries that
2813 * were in the original entry (saved in tmp_entry). Also
2814 * check for waiters.
2815 */
2816 while ((entry != vm_map_to_entry(map)) &&
2817 (entry->vme_start < tmp_entry.vme_end)) {
2818 assert(entry->in_transition);
2819 entry->in_transition = FALSE;
2820 if (entry->needs_wakeup) {
2821 entry->needs_wakeup = FALSE;
2822 need_wakeup = TRUE;
2823 }
2824 entry = entry->vme_next;
2825 }
2826 }
2827 vm_map_unlock(map);
2828 /*
2829 * wake up anybody waiting on entries that we have unwired.
2830 */
2831 if (need_wakeup)
2832 vm_map_entry_wakeup(map);
2833 return(KERN_SUCCESS);
2834
2835 }
2836
2837 kern_return_t
2838 vm_map_unwire(
2839 register vm_map_t map,
2840 register vm_offset_t start,
2841 register vm_offset_t end,
2842 boolean_t user_wire)
2843 {
2844 return vm_map_unwire_nested(map, start, end, user_wire, (pmap_t)NULL);
2845 }
2846
2847
2848 /*
2849 * vm_map_entry_delete: [ internal use only ]
2850 *
2851 * Deallocate the given entry from the target map.
2852 */
2853 void
2854 vm_map_entry_delete(
2855 register vm_map_t map,
2856 register vm_map_entry_t entry)
2857 {
2858 register vm_offset_t s, e;
2859 register vm_object_t object;
2860 register vm_map_t submap;
2861 extern vm_object_t kernel_object;
2862
2863 s = entry->vme_start;
2864 e = entry->vme_end;
2865 assert(page_aligned(s));
2866 assert(page_aligned(e));
2867 assert(entry->wired_count == 0);
2868 assert(entry->user_wired_count == 0);
2869
2870 if (entry->is_sub_map) {
2871 object = NULL;
2872 submap = entry->object.sub_map;
2873 } else {
2874 submap = NULL;
2875 object = entry->object.vm_object;
2876 }
2877
2878 vm_map_entry_unlink(map, entry);
2879 map->size -= e - s;
2880
2881 vm_map_entry_dispose(map, entry);
2882
2883 vm_map_unlock(map);
2884 /*
2885 * Deallocate the object only after removing all
2886 * pmap entries pointing to its pages.
2887 */
2888 if (submap)
2889 vm_map_deallocate(submap);
2890 else
2891 vm_object_deallocate(object);
2892
2893 }
2894
2895 void
2896 vm_map_submap_pmap_clean(
2897 vm_map_t map,
2898 vm_offset_t start,
2899 vm_offset_t end,
2900 vm_map_t sub_map,
2901 vm_offset_t offset)
2902 {
2903 vm_offset_t submap_start;
2904 vm_offset_t submap_end;
2905 vm_offset_t addr;
2906 vm_size_t remove_size;
2907 vm_map_entry_t entry;
2908
2909 submap_end = offset + (end - start);
2910 submap_start = offset;
2911 if(vm_map_lookup_entry(sub_map, offset, &entry)) {
2912
2913 remove_size = (entry->vme_end - entry->vme_start);
2914 if(offset > entry->vme_start)
2915 remove_size -= offset - entry->vme_start;
2916
2917
2918 if(submap_end < entry->vme_end) {
2919 remove_size -=
2920 entry->vme_end - submap_end;
2921 }
2922 if(entry->is_sub_map) {
2923 vm_map_submap_pmap_clean(
2924 sub_map,
2925 start,
2926 start + remove_size,
2927 entry->object.sub_map,
2928 entry->offset);
2929 } else {
2930 pmap_remove(map->pmap, start, start + remove_size);
2931 }
2932 }
2933
2934 entry = entry->vme_next;
2935
2936 while((entry != vm_map_to_entry(sub_map))
2937 && (entry->vme_start < submap_end)) {
2938 remove_size = (entry->vme_end - entry->vme_start);
2939 if(submap_end < entry->vme_end) {
2940 remove_size -= entry->vme_end - submap_end;
2941 }
2942 if(entry->is_sub_map) {
2943 vm_map_submap_pmap_clean(
2944 sub_map,
2945 (start + entry->vme_start) - offset,
2946 ((start + entry->vme_start) - offset) + remove_size,
2947 entry->object.sub_map,
2948 entry->offset);
2949 } else {
2950 pmap_remove(map->pmap,
2951 (start + entry->vme_start) - offset,
2952 ((start + entry->vme_start) - offset) + remove_size);
2953 }
2954 entry = entry->vme_next;
2955 }
2956 return;
2957 }
2958
2959 /*
2960 * vm_map_delete: [ internal use only ]
2961 *
2962 * Deallocates the given address range from the target map.
2963 * Removes all user wirings. Unwires one kernel wiring if
2964 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
2965 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
2966 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
2967 *
2968 * This routine is called with map locked and leaves map locked.
2969 */
2970 kern_return_t
2971 vm_map_delete(
2972 register vm_map_t map,
2973 vm_offset_t start,
2974 register vm_offset_t end,
2975 int flags)
2976 {
2977 vm_map_entry_t entry, next;
2978 struct vm_map_entry *first_entry, tmp_entry;
2979 register vm_offset_t s, e;
2980 register vm_object_t object;
2981 boolean_t need_wakeup;
2982 unsigned int last_timestamp = ~0; /* unlikely value */
2983 int interruptible;
2984 extern vm_map_t kernel_map;
2985
2986 interruptible = (flags & VM_MAP_REMOVE_INTERRUPTIBLE) ?
2987 THREAD_ABORTSAFE : THREAD_UNINT;
2988
2989 /*
2990 * All our DMA I/O operations in IOKit are currently done by
2991 * wiring through the map entries of the task requesting the I/O.
2992 * Because of this, we must always wait for kernel wirings
2993 * to go away on the entries before deleting them.
2994 *
2995 * Any caller who wants to actually remove a kernel wiring
2996 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
2997 * properly remove one wiring instead of blasting through
2998 * them all.
2999 */
3000 flags |= VM_MAP_REMOVE_WAIT_FOR_KWIRE;
3001
3002 /*
3003 * Find the start of the region, and clip it
3004 */
3005 if (vm_map_lookup_entry(map, start, &first_entry)) {
3006 entry = first_entry;
3007 vm_map_clip_start(map, entry, start);
3008
3009 /*
3010 * Fix the lookup hint now, rather than each
3011 * time through the loop.
3012 */
3013 SAVE_HINT(map, entry->vme_prev);
3014 } else {
3015 entry = first_entry->vme_next;
3016 }
3017
3018 need_wakeup = FALSE;
3019 /*
3020 * Step through all entries in this region
3021 */
3022 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
3023
3024 vm_map_clip_end(map, entry, end);
3025 if (entry->in_transition) {
3026 /*
3027 * Another thread is wiring/unwiring this entry.
3028 * Let the other thread know we are waiting.
3029 */
3030 s = entry->vme_start;
3031 entry->needs_wakeup = TRUE;
3032
3033 /*
3034 * wake up anybody waiting on entries that we have
3035 * already unwired/deleted.
3036 */
3037 if (need_wakeup) {
3038 vm_map_entry_wakeup(map);
3039 need_wakeup = FALSE;
3040 }
3041
3042 vm_map_entry_wait(map, interruptible);
3043
3044 if (interruptible &&
3045 current_thread()->wait_result == THREAD_INTERRUPTED)
3046 /*
3047 * We do not clear the needs_wakeup flag,
3048 * since we cannot tell if we were the only one.
3049 */
3050 return KERN_ABORTED;
3051
3052 vm_map_lock(map);
3053 /*
3054 * Cannot avoid a lookup here. reset timestamp.
3055 */
3056 last_timestamp = map->timestamp;
3057
3058 /*
3059 * The entry could have been clipped or it
3060 * may not exist anymore. Look it up again.
3061 */
3062 if (!vm_map_lookup_entry(map, s, &first_entry)) {
3063 assert((map != kernel_map) &&
3064 (!entry->is_sub_map));
3065 /*
3066 * User: use the next entry
3067 */
3068 entry = first_entry->vme_next;
3069 } else {
3070 entry = first_entry;
3071 SAVE_HINT(map, entry->vme_prev);
3072 }
3073 continue;
3074 } /* end in_transition */
3075
3076 if (entry->wired_count) {
3077 /*
3078 * Remove a kernel wiring if requested or if
3079 * there are user wirings.
3080 */
3081 if ((flags & VM_MAP_REMOVE_KUNWIRE) ||
3082 (entry->user_wired_count > 0))
3083 entry->wired_count--;
3084
3085 /* remove all user wire references */
3086 entry->user_wired_count = 0;
3087
3088 if (entry->wired_count != 0) {
3089 assert((map != kernel_map) &&
3090 (!entry->is_sub_map));
3091 /*
3092 * Cannot continue. Typical case is when
3093 * a user thread has physical io pending on
3094 * on this page. Either wait for the
3095 * kernel wiring to go away or return an
3096 * error.
3097 */
3098 if (flags & VM_MAP_REMOVE_WAIT_FOR_KWIRE) {
3099
3100 s = entry->vme_start;
3101 entry->needs_wakeup = TRUE;
3102 vm_map_entry_wait(map, interruptible);
3103
3104 if (interruptible &&
3105 current_thread()->wait_result ==
3106 THREAD_INTERRUPTED)
3107 /*
3108 * We do not clear the
3109 * needs_wakeup flag, since we
3110 * cannot tell if we were the
3111 * only one.
3112 */
3113 return KERN_ABORTED;
3114
3115 vm_map_lock(map);
3116 /*
3117 * Cannot avoid a lookup here. reset
3118 * timestamp.
3119 */
3120 last_timestamp = map->timestamp;
3121
3122 /*
3123 * The entry could have been clipped or
3124 * it may not exist anymore. Look it
3125 * up again.
3126 */
3127 if (!vm_map_lookup_entry(map, s,
3128 &first_entry)) {
3129 assert((map != kernel_map) &&
3130 (!entry->is_sub_map));
3131 /*
3132 * User: use the next entry
3133 */
3134 entry = first_entry->vme_next;
3135 } else {
3136 entry = first_entry;
3137 SAVE_HINT(map, entry->vme_prev);
3138 }
3139 continue;
3140 }
3141 else {
3142 return KERN_FAILURE;
3143 }
3144 }
3145
3146 entry->in_transition = TRUE;
3147 /*
3148 * copy current entry. see comment in vm_map_wire()
3149 */
3150 tmp_entry = *entry;
3151 s = entry->vme_start;
3152 e = entry->vme_end;
3153
3154 /*
3155 * We can unlock the map now. The in_transition
3156 * state guarentees existance of the entry.
3157 */
3158 vm_map_unlock(map);
3159 vm_fault_unwire(map, &tmp_entry,
3160 tmp_entry.object.vm_object == kernel_object,
3161 map->pmap);
3162 vm_map_lock(map);
3163
3164 if (last_timestamp+1 != map->timestamp) {
3165 /*
3166 * Find the entry again. It could have
3167 * been clipped after we unlocked the map.
3168 */
3169 if (!vm_map_lookup_entry(map, s, &first_entry)){
3170 assert((map != kernel_map) &&
3171 (!entry->is_sub_map));
3172 first_entry = first_entry->vme_next;
3173 } else {
3174 SAVE_HINT(map, entry->vme_prev);
3175 }
3176 } else {
3177 SAVE_HINT(map, entry->vme_prev);
3178 first_entry = entry;
3179 }
3180
3181 last_timestamp = map->timestamp;
3182
3183 entry = first_entry;
3184 while ((entry != vm_map_to_entry(map)) &&
3185 (entry->vme_start < tmp_entry.vme_end)) {
3186 assert(entry->in_transition);
3187 entry->in_transition = FALSE;
3188 if (entry->needs_wakeup) {
3189 entry->needs_wakeup = FALSE;
3190 need_wakeup = TRUE;
3191 }
3192 entry = entry->vme_next;
3193 }
3194 /*
3195 * We have unwired the entry(s). Go back and
3196 * delete them.
3197 */
3198 entry = first_entry;
3199 continue;
3200 }
3201
3202 /* entry is unwired */
3203 assert(entry->wired_count == 0);
3204 assert(entry->user_wired_count == 0);
3205
3206 if ((!entry->is_sub_map &&
3207 entry->object.vm_object != kernel_object) ||
3208 entry->is_sub_map) {
3209 if(entry->is_sub_map) {
3210 if(entry->use_pmap) {
3211 #ifndef i386
3212 pmap_unnest(map->pmap, entry->vme_start,
3213 entry->vme_end - entry->vme_start);
3214 #endif
3215 } else {
3216 vm_map_submap_pmap_clean(
3217 map, entry->vme_start, entry->vme_end,
3218 entry->object.sub_map,
3219 entry->offset);
3220 }
3221 } else {
3222 pmap_remove(map->pmap,
3223 entry->vme_start, entry->vme_end);
3224 }
3225 }
3226
3227 next = entry->vme_next;
3228 s = next->vme_start;
3229 last_timestamp = map->timestamp;
3230 vm_map_entry_delete(map, entry);
3231 /* vm_map_entry_delete unlocks the map */
3232 vm_map_lock(map);
3233 entry = next;
3234
3235 if(entry == vm_map_to_entry(map)) {
3236 break;
3237 }
3238 if (last_timestamp+1 != map->timestamp) {
3239 /*
3240 * we are responsible for deleting everything
3241 * from the give space, if someone has interfered
3242 * we pick up where we left off, back fills should
3243 * be all right for anyone except map_delete and
3244 * we have to assume that the task has been fully
3245 * disabled before we get here
3246 */
3247 if (!vm_map_lookup_entry(map, s, &entry)){
3248 entry = entry->vme_next;
3249 } else {
3250 SAVE_HINT(map, entry->vme_prev);
3251 }
3252 /*
3253 * others can not only allocate behind us, we can
3254 * also see coalesce while we don't have the map lock
3255 */
3256 if(entry == vm_map_to_entry(map)) {
3257 break;
3258 }
3259 vm_map_clip_start(map, entry, s);
3260 }
3261 last_timestamp = map->timestamp;
3262 }
3263
3264 if (map->wait_for_space)
3265 thread_wakeup((event_t) map);
3266 /*
3267 * wake up anybody waiting on entries that we have already deleted.
3268 */
3269 if (need_wakeup)
3270 vm_map_entry_wakeup(map);
3271
3272 return KERN_SUCCESS;
3273 }
3274
3275 /*
3276 * vm_map_remove:
3277 *
3278 * Remove the given address range from the target map.
3279 * This is the exported form of vm_map_delete.
3280 */
3281 kern_return_t
3282 vm_map_remove(
3283 register vm_map_t map,
3284 register vm_offset_t start,
3285 register vm_offset_t end,
3286 register boolean_t flags)
3287 {
3288 register kern_return_t result;
3289
3290 vm_map_lock(map);
3291 VM_MAP_RANGE_CHECK(map, start, end);
3292 result = vm_map_delete(map, start, end, flags);
3293 vm_map_unlock(map);
3294
3295 return(result);
3296 }
3297
3298
3299 /*
3300 * vm_map_copy_steal_pages:
3301 *
3302 * Steal all the pages from a vm_map_copy page_list by copying ones
3303 * that have not already been stolen.
3304 */
3305 void
3306 vm_map_copy_steal_pages(
3307 vm_map_copy_t copy)
3308 {
3309 register vm_page_t m, new_m;
3310 register int i;
3311 vm_object_t object;
3312
3313 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
3314 for (i = 0; i < copy->cpy_npages; i++) {
3315
3316 /*
3317 * If the page is not tabled, then it's already stolen.
3318 */
3319 m = copy->cpy_page_list[i];
3320 if (!m->tabled)
3321 continue;
3322
3323 /*
3324 * Page was not stolen, get a new
3325 * one and do the copy now.
3326 */
3327 while ((new_m = vm_page_grab()) == VM_PAGE_NULL) {
3328 VM_PAGE_WAIT();
3329 }
3330
3331 vm_page_gobble(new_m); /* mark as consumed internally */
3332 vm_page_copy(m, new_m);
3333
3334 object = m->object;
3335 vm_object_lock(object);
3336 vm_page_lock_queues();
3337 if (!m->active && !m->inactive)
3338 vm_page_activate(m);
3339 vm_page_unlock_queues();
3340 PAGE_WAKEUP_DONE(m);
3341 vm_object_paging_end(object);
3342 vm_object_unlock(object);
3343
3344 copy->cpy_page_list[i] = new_m;
3345 }
3346 copy->cpy_page_loose = TRUE;
3347 }
3348
3349 /*
3350 * vm_map_copy_page_discard:
3351 *
3352 * Get rid of the pages in a page_list copy. If the pages are
3353 * stolen, they are freed. If the pages are not stolen, they
3354 * are unbusied, and associated state is cleaned up.
3355 */
3356 void
3357 vm_map_copy_page_discard(
3358 vm_map_copy_t copy)
3359 {
3360 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
3361 while (copy->cpy_npages > 0) {
3362 vm_page_t m;
3363
3364 if ((m = copy->cpy_page_list[--(copy->cpy_npages)]) !=
3365 VM_PAGE_NULL) {
3366
3367 /*
3368 * If it's not in the table, then it's
3369 * a stolen page that goes back
3370 * to the free list. Else it belongs
3371 * to some object, and we hold a
3372 * paging reference on that object.
3373 */
3374 if (!m->tabled) {
3375 VM_PAGE_FREE(m);
3376 }
3377 else {
3378 vm_object_t object;
3379
3380 object = m->object;
3381
3382 vm_object_lock(object);
3383 vm_page_lock_queues();
3384 if (!m->active && !m->inactive)
3385 vm_page_activate(m);
3386 vm_page_unlock_queues();
3387
3388 if ((!m->busy)) {
3389 kern_return_t kr;
3390 kr = vm_page_unpin(m);
3391 assert(kr == KERN_SUCCESS);
3392 } else {
3393 PAGE_WAKEUP_DONE(m);
3394 }
3395 vm_object_paging_end(object);
3396 vm_object_unlock(object);
3397 }
3398 }
3399 }
3400 }
3401
3402 /*
3403 * Routine: vm_map_copy_discard
3404 *
3405 * Description:
3406 * Dispose of a map copy object (returned by
3407 * vm_map_copyin).
3408 */
3409 void
3410 vm_map_copy_discard(
3411 vm_map_copy_t copy)
3412 {
3413 TR_DECL("vm_map_copy_discard");
3414
3415 /* tr3("enter: copy 0x%x type %d", copy, copy->type);*/
3416 free_next_copy:
3417 if (copy == VM_MAP_COPY_NULL)
3418 return;
3419
3420 switch (copy->type) {
3421 case VM_MAP_COPY_ENTRY_LIST:
3422 while (vm_map_copy_first_entry(copy) !=
3423 vm_map_copy_to_entry(copy)) {
3424 vm_map_entry_t entry = vm_map_copy_first_entry(copy);
3425
3426 vm_map_copy_entry_unlink(copy, entry);
3427 vm_object_deallocate(entry->object.vm_object);
3428 vm_map_copy_entry_dispose(copy, entry);
3429 }
3430 break;
3431 case VM_MAP_COPY_OBJECT:
3432 vm_object_deallocate(copy->cpy_object);
3433 break;
3434 case VM_MAP_COPY_PAGE_LIST:
3435
3436 /*
3437 * To clean this up, we have to unbusy all the pages
3438 * and release the paging references in their objects.
3439 */
3440 if (copy->cpy_npages > 0)
3441 vm_map_copy_page_discard(copy);
3442
3443 /*
3444 * If there's a continuation, abort it. The
3445 * abort routine releases any storage.
3446 */
3447 if (vm_map_copy_has_cont(copy)) {
3448
3449 assert(vm_map_copy_cont_is_valid(copy));
3450 /*
3451 * Special case: recognize
3452 * vm_map_copy_discard_cont and optimize
3453 * here to avoid tail recursion.
3454 */
3455 if (copy->cpy_cont == vm_map_copy_discard_cont) {
3456 register vm_map_copy_t new_copy;
3457
3458 new_copy = (vm_map_copy_t) copy->cpy_cont_args;
3459 zfree(vm_map_copy_zone, (vm_offset_t) copy);
3460 copy = new_copy;
3461 goto free_next_copy;
3462 } else {
3463 vm_map_copy_abort_cont(copy);
3464 }
3465 }
3466
3467 break;
3468
3469 case VM_MAP_COPY_KERNEL_BUFFER:
3470
3471 /*
3472 * The vm_map_copy_t and possibly the data buffer were
3473 * allocated by a single call to kalloc(), i.e. the
3474 * vm_map_copy_t was not allocated out of the zone.
3475 */
3476 kfree((vm_offset_t) copy, copy->cpy_kalloc_size);
3477 return;
3478 }
3479 zfree(vm_map_copy_zone, (vm_offset_t) copy);
3480 }
3481
3482 /*
3483 * Routine: vm_map_copy_copy
3484 *
3485 * Description:
3486 * Move the information in a map copy object to
3487 * a new map copy object, leaving the old one
3488 * empty.
3489 *
3490 * This is used by kernel routines that need
3491 * to look at out-of-line data (in copyin form)
3492 * before deciding whether to return SUCCESS.
3493 * If the routine returns FAILURE, the original
3494 * copy object will be deallocated; therefore,
3495 * these routines must make a copy of the copy
3496 * object and leave the original empty so that
3497 * deallocation will not fail.
3498 */
3499 vm_map_copy_t
3500 vm_map_copy_copy(
3501 vm_map_copy_t copy)
3502 {
3503 vm_map_copy_t new_copy;
3504
3505 if (copy == VM_MAP_COPY_NULL)
3506 return VM_MAP_COPY_NULL;
3507
3508 /*
3509 * Allocate a new copy object, and copy the information
3510 * from the old one into it.
3511 */
3512
3513 new_copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
3514 *new_copy = *copy;
3515
3516 if (copy->type == VM_MAP_COPY_ENTRY_LIST) {
3517 /*
3518 * The links in the entry chain must be
3519 * changed to point to the new copy object.
3520 */
3521 vm_map_copy_first_entry(copy)->vme_prev
3522 = vm_map_copy_to_entry(new_copy);
3523 vm_map_copy_last_entry(copy)->vme_next
3524 = vm_map_copy_to_entry(new_copy);
3525 }
3526
3527 /*
3528 * Change the old copy object into one that contains
3529 * nothing to be deallocated.
3530 */
3531 copy->type = VM_MAP_COPY_OBJECT;
3532 copy->cpy_object = VM_OBJECT_NULL;
3533
3534 /*
3535 * Return the new object.
3536 */
3537 return new_copy;
3538 }
3539
3540 /*
3541 * Routine: vm_map_copy_discard_cont
3542 *
3543 * Description:
3544 * A version of vm_map_copy_discard that can be called
3545 * as a continuation from a vm_map_copy page list.
3546 */
3547 kern_return_t
3548 vm_map_copy_discard_cont(
3549 vm_map_copyin_args_t cont_args,
3550 vm_map_copy_t *copy_result) /* OUT */
3551 {
3552 vm_map_copy_discard((vm_map_copy_t) cont_args);
3553 if (copy_result != (vm_map_copy_t *)0)
3554 *copy_result = VM_MAP_COPY_NULL;
3555 return(KERN_SUCCESS);
3556 }
3557
3558 kern_return_t
3559 vm_map_overwrite_submap_recurse(
3560 vm_map_t dst_map,
3561 vm_offset_t dst_addr,
3562 vm_size_t dst_size)
3563 {
3564 vm_offset_t dst_end;
3565 vm_map_entry_t tmp_entry;
3566 vm_map_entry_t entry;
3567 kern_return_t result;
3568 boolean_t encountered_sub_map = FALSE;
3569
3570
3571
3572 /*
3573 * Verify that the destination is all writeable
3574 * initially. We have to trunc the destination
3575 * address and round the copy size or we'll end up
3576 * splitting entries in strange ways.
3577 */
3578
3579 dst_end = round_page(dst_addr + dst_size);
3580
3581 start_pass_1:
3582 vm_map_lock(dst_map);
3583 if (!vm_map_lookup_entry(dst_map, dst_addr, &tmp_entry)) {
3584 vm_map_unlock(dst_map);
3585 return(KERN_INVALID_ADDRESS);
3586 }
3587
3588 vm_map_clip_start(dst_map, tmp_entry, trunc_page(dst_addr));
3589
3590 for (entry = tmp_entry;;) {
3591 vm_map_entry_t next;
3592
3593 next = entry->vme_next;
3594 while(entry->is_sub_map) {
3595 vm_offset_t sub_start;
3596 vm_offset_t sub_end;
3597 vm_offset_t local_end;
3598
3599 if (entry->in_transition) {
3600 /*
3601 * Say that we are waiting, and wait for entry.
3602 */
3603 entry->needs_wakeup = TRUE;
3604 vm_map_entry_wait(dst_map, THREAD_UNINT);
3605
3606 goto start_pass_1;
3607 }
3608
3609 encountered_sub_map = TRUE;
3610 sub_start = entry->offset;
3611
3612 if(entry->vme_end < dst_end)
3613 sub_end = entry->vme_end;
3614 else
3615 sub_end = dst_end;
3616 sub_end -= entry->vme_start;
3617 sub_end += entry->offset;
3618 local_end = entry->vme_end;
3619 vm_map_unlock(dst_map);
3620
3621 result = vm_map_overwrite_submap_recurse(
3622 entry->object.sub_map,
3623 sub_start,
3624 sub_end - sub_start);
3625
3626 if(result != KERN_SUCCESS)
3627 return result;
3628 if (dst_end <= entry->vme_end)
3629 return KERN_SUCCESS;
3630 vm_map_lock(dst_map);
3631 if(!vm_map_lookup_entry(dst_map, local_end,
3632 &tmp_entry)) {
3633 vm_map_unlock(dst_map);
3634 return(KERN_INVALID_ADDRESS);
3635 }
3636 entry = tmp_entry;
3637 next = entry->vme_next;
3638 }
3639
3640 if ( ! (entry->protection & VM_PROT_WRITE)) {
3641 vm_map_unlock(dst_map);
3642 return(KERN_PROTECTION_FAILURE);
3643 }
3644
3645 /*
3646 * If the entry is in transition, we must wait
3647 * for it to exit that state. Anything could happen
3648 * when we unlock the map, so start over.
3649 */
3650 if (entry->in_transition) {
3651
3652 /*
3653 * Say that we are waiting, and wait for entry.
3654 */
3655 entry->needs_wakeup = TRUE;
3656 vm_map_entry_wait(dst_map, THREAD_UNINT);
3657
3658 goto start_pass_1;
3659 }
3660
3661 /*
3662 * our range is contained completely within this map entry
3663 */
3664 if (dst_end <= entry->vme_end) {
3665 vm_map_unlock(dst_map);
3666 return KERN_SUCCESS;
3667 }
3668 /*
3669 * check that range specified is contiguous region
3670 */
3671 if ((next == vm_map_to_entry(dst_map)) ||
3672 (next->vme_start != entry->vme_end)) {
3673 vm_map_unlock(dst_map);
3674 return(KERN_INVALID_ADDRESS);
3675 }
3676
3677 /*
3678 * Check for permanent objects in the destination.
3679 */
3680 if ((entry->object.vm_object != VM_OBJECT_NULL) &&
3681 ((!entry->object.vm_object->internal) ||
3682 (entry->object.vm_object->true_share))) {
3683 if(encountered_sub_map) {
3684 vm_map_unlock(dst_map);
3685 return(KERN_FAILURE);
3686 }
3687 }
3688
3689
3690 entry = next;
3691 }/* for */
3692 vm_map_unlock(dst_map);
3693 return(KERN_SUCCESS);
3694 }
3695
3696 /*
3697 * Routine: vm_map_copy_overwrite
3698 *
3699 * Description:
3700 * Copy the memory described by the map copy
3701 * object (copy; returned by vm_map_copyin) onto
3702 * the specified destination region (dst_map, dst_addr).
3703 * The destination must be writeable.
3704 *
3705 * Unlike vm_map_copyout, this routine actually
3706 * writes over previously-mapped memory. If the
3707 * previous mapping was to a permanent (user-supplied)
3708 * memory object, it is preserved.
3709 *
3710 * The attributes (protection and inheritance) of the
3711 * destination region are preserved.
3712 *
3713 * If successful, consumes the copy object.
3714 * Otherwise, the caller is responsible for it.
3715 *
3716 * Implementation notes:
3717 * To overwrite aligned temporary virtual memory, it is
3718 * sufficient to remove the previous mapping and insert
3719 * the new copy. This replacement is done either on
3720 * the whole region (if no permanent virtual memory
3721 * objects are embedded in the destination region) or
3722 * in individual map entries.
3723 *
3724 * To overwrite permanent virtual memory , it is necessary
3725 * to copy each page, as the external memory management
3726 * interface currently does not provide any optimizations.
3727 *
3728 * Unaligned memory also has to be copied. It is possible
3729 * to use 'vm_trickery' to copy the aligned data. This is
3730 * not done but not hard to implement.
3731 *
3732 * Once a page of permanent memory has been overwritten,
3733 * it is impossible to interrupt this function; otherwise,
3734 * the call would be neither atomic nor location-independent.
3735 * The kernel-state portion of a user thread must be
3736 * interruptible.
3737 *
3738 * It may be expensive to forward all requests that might
3739 * overwrite permanent memory (vm_write, vm_copy) to
3740 * uninterruptible kernel threads. This routine may be
3741 * called by interruptible threads; however, success is
3742 * not guaranteed -- if the request cannot be performed
3743 * atomically and interruptibly, an error indication is
3744 * returned.
3745 */
3746
3747 kern_return_t
3748 vm_map_copy_overwrite_nested(
3749 vm_map_t dst_map,
3750 vm_offset_t dst_addr,
3751 vm_map_copy_t copy,
3752 boolean_t interruptible,
3753 pmap_t pmap)
3754 {
3755 vm_offset_t dst_end;
3756 vm_map_entry_t tmp_entry;
3757 vm_map_entry_t entry;
3758 kern_return_t kr;
3759 boolean_t aligned = TRUE;
3760 boolean_t contains_permanent_objects = FALSE;
3761 boolean_t encountered_sub_map = FALSE;
3762 vm_offset_t base_addr;
3763 vm_size_t copy_size;
3764 vm_size_t total_size;
3765
3766
3767 /*
3768 * Check for null copy object.
3769 */
3770
3771 if (copy == VM_MAP_COPY_NULL)
3772 return(KERN_SUCCESS);
3773
3774 /*
3775 * Check for special kernel buffer allocated
3776 * by new_ipc_kmsg_copyin.
3777 */
3778
3779 if (copy->type == VM_MAP_COPY_KERNEL_BUFFER) {
3780 return(vm_map_copyout_kernel_buffer(dst_map, &dst_addr,
3781 copy, TRUE));
3782 }
3783
3784 /*
3785 * Only works for entry lists at the moment. Will
3786 * support page lists later.
3787 */
3788
3789 assert(copy->type == VM_MAP_COPY_ENTRY_LIST);
3790
3791 if (copy->size == 0) {
3792 vm_map_copy_discard(copy);
3793 return(KERN_SUCCESS);
3794 }
3795
3796 /*
3797 * Verify that the destination is all writeable
3798 * initially. We have to trunc the destination
3799 * address and round the copy size or we'll end up
3800 * splitting entries in strange ways.
3801 */
3802
3803 if (!page_aligned(copy->size) ||
3804 !page_aligned (copy->offset) ||
3805 !page_aligned (dst_addr))
3806 {
3807 aligned = FALSE;
3808 dst_end = round_page(dst_addr + copy->size);
3809 } else {
3810 dst_end = dst_addr + copy->size;
3811 }
3812
3813 start_pass_1:
3814 vm_map_lock(dst_map);
3815 if (!vm_map_lookup_entry(dst_map, dst_addr, &tmp_entry)) {
3816 vm_map_unlock(dst_map);
3817 return(KERN_INVALID_ADDRESS);
3818 }
3819 vm_map_clip_start(dst_map, tmp_entry, trunc_page(dst_addr));
3820 for (entry = tmp_entry;;) {
3821 vm_map_entry_t next = entry->vme_next;
3822
3823 while(entry->is_sub_map) {
3824 vm_offset_t sub_start;
3825 vm_offset_t sub_end;
3826 vm_offset_t local_end;
3827
3828 if (entry->in_transition) {
3829
3830 /*
3831 * Say that we are waiting, and wait for entry.
3832 */
3833 entry->needs_wakeup = TRUE;
3834 vm_map_entry_wait(dst_map, THREAD_UNINT);
3835
3836 goto start_pass_1;
3837 }
3838
3839 local_end = entry->vme_end;
3840 if (!(entry->needs_copy)) {
3841 /* if needs_copy we are a COW submap */
3842 /* in such a case we just replace so */
3843 /* there is no need for the follow- */
3844 /* ing check. */
3845 encountered_sub_map = TRUE;
3846 sub_start = entry->offset;
3847
3848 if(entry->vme_end < dst_end)
3849 sub_end = entry->vme_end;
3850 else
3851 sub_end = dst_end;
3852 sub_end -= entry->vme_start;
3853 sub_end += entry->offset;
3854 vm_map_unlock(dst_map);
3855
3856 kr = vm_map_overwrite_submap_recurse(
3857 entry->object.sub_map,
3858 sub_start,
3859 sub_end - sub_start);
3860 if(kr != KERN_SUCCESS)
3861 return kr;
3862 vm_map_lock(dst_map);
3863 }
3864
3865 if (dst_end <= entry->vme_end)
3866 goto start_overwrite;
3867 if(!vm_map_lookup_entry(dst_map, local_end,
3868 &entry)) {
3869 vm_map_unlock(dst_map);
3870 return(KERN_INVALID_ADDRESS);
3871 }
3872 next = entry->vme_next;
3873 }
3874
3875 if ( ! (entry->protection & VM_PROT_WRITE)) {
3876 vm_map_unlock(dst_map);
3877 return(KERN_PROTECTION_FAILURE);
3878 }
3879
3880 /*
3881 * If the entry is in transition, we must wait
3882 * for it to exit that state. Anything could happen
3883 * when we unlock the map, so start over.
3884 */
3885 if (entry->in_transition) {
3886
3887 /*
3888 * Say that we are waiting, and wait for entry.
3889 */
3890 entry->needs_wakeup = TRUE;
3891 vm_map_entry_wait(dst_map, THREAD_UNINT);
3892
3893 goto start_pass_1;
3894 }
3895
3896 /*
3897 * our range is contained completely within this map entry
3898 */
3899 if (dst_end <= entry->vme_end)
3900 break;
3901 /*
3902 * check that range specified is contiguous region
3903 */
3904 if ((next == vm_map_to_entry(dst_map)) ||
3905 (next->vme_start != entry->vme_end)) {
3906 vm_map_unlock(dst_map);
3907 return(KERN_INVALID_ADDRESS);
3908 }
3909
3910
3911 /*
3912 * Check for permanent objects in the destination.
3913 */
3914 if ((entry->object.vm_object != VM_OBJECT_NULL) &&
3915 ((!entry->object.vm_object->internal) ||
3916 (entry->object.vm_object->true_share))) {
3917 contains_permanent_objects = TRUE;
3918 }
3919
3920 entry = next;
3921 }/* for */
3922
3923 start_overwrite:
3924 /*
3925 * If there are permanent objects in the destination, then
3926 * the copy cannot be interrupted.
3927 */
3928
3929 if (interruptible && contains_permanent_objects) {
3930 vm_map_unlock(dst_map);
3931 return(KERN_FAILURE); /* XXX */
3932 }
3933
3934 /*
3935 *
3936 * Make a second pass, overwriting the data
3937 * At the beginning of each loop iteration,
3938 * the next entry to be overwritten is "tmp_entry"
3939 * (initially, the value returned from the lookup above),
3940 * and the starting address expected in that entry
3941 * is "start".
3942 */
3943
3944 total_size = copy->size;
3945 if(encountered_sub_map) {
3946 copy_size = 0;
3947 /* re-calculate tmp_entry since we've had the map */
3948 /* unlocked */
3949 if (!vm_map_lookup_entry( dst_map, dst_addr, &tmp_entry)) {
3950 vm_map_unlock(dst_map);
3951 return(KERN_INVALID_ADDRESS);
3952 }
3953 } else {
3954 copy_size = copy->size;
3955 }
3956
3957 base_addr = dst_addr;
3958 while(TRUE) {
3959 /* deconstruct the copy object and do in parts */
3960 /* only in sub_map, interruptable case */
3961 vm_map_entry_t copy_entry;
3962 vm_map_entry_t previous_prev;
3963 vm_map_entry_t next_copy;
3964 int nentries;
3965 int remaining_entries;
3966 int new_offset;
3967
3968 for (entry = tmp_entry; copy_size == 0;) {
3969 vm_map_entry_t next;
3970
3971 next = entry->vme_next;
3972
3973 /* tmp_entry and base address are moved along */
3974 /* each time we encounter a sub-map. Otherwise */
3975 /* entry can outpase tmp_entry, and the copy_size */
3976 /* may reflect the distance between them */
3977 /* if the current entry is found to be in transition */
3978 /* we will start over at the beginning or the last */
3979 /* encounter of a submap as dictated by base_addr */
3980 /* we will zero copy_size accordingly. */
3981 if (entry->in_transition) {
3982 /*
3983 * Say that we are waiting, and wait for entry.
3984 */
3985 entry->needs_wakeup = TRUE;
3986 vm_map_entry_wait(dst_map, THREAD_UNINT);
3987
3988 vm_map_lock(dst_map);
3989 if(!vm_map_lookup_entry(dst_map, base_addr,
3990 &tmp_entry)) {
3991 vm_map_unlock(dst_map);
3992 return(KERN_INVALID_ADDRESS);
3993 }
3994 copy_size = 0;
3995 entry = tmp_entry;
3996 continue;
3997 }
3998 if(entry->is_sub_map) {
3999 vm_offset_t sub_start;
4000 vm_offset_t sub_end;
4001 vm_offset_t local_end;
4002
4003 if (entry->needs_copy) {
4004 /* if this is a COW submap */
4005 /* just back the range with a */
4006 /* anonymous entry */
4007 if(entry->vme_end < dst_end)
4008 sub_end = entry->vme_end;
4009 else
4010 sub_end = dst_end;
4011 if(entry->vme_start < base_addr)
4012 sub_start = base_addr;
4013 else
4014 sub_start = entry->vme_start;
4015 vm_map_clip_end(
4016 dst_map, entry, sub_end);
4017 vm_map_clip_start(
4018 dst_map, entry, sub_start);
4019 entry->is_sub_map = FALSE;
4020 vm_map_deallocate(
4021 entry->object.sub_map);
4022 entry->object.sub_map = NULL;
4023 entry->is_shared = FALSE;
4024 entry->needs_copy = FALSE;
4025 entry->offset = 0;
4026 entry->protection = VM_PROT_ALL;
4027 entry->max_protection = VM_PROT_ALL;
4028 entry->wired_count = 0;
4029 entry->user_wired_count = 0;
4030 if(entry->inheritance
4031 == VM_INHERIT_SHARE)
4032 entry->inheritance = VM_INHERIT_COPY;
4033 continue;
4034 }
4035 /* first take care of any non-sub_map */
4036 /* entries to send */
4037 if(base_addr < entry->vme_start) {
4038 /* stuff to send */
4039 copy_size =
4040 entry->vme_start - base_addr;
4041 break;
4042 }
4043 sub_start = entry->offset;
4044
4045 if(entry->vme_end < dst_end)
4046 sub_end = entry->vme_end;
4047 else
4048 sub_end = dst_end;
4049 sub_end -= entry->vme_start;
4050 sub_end += entry->offset;
4051 local_end = entry->vme_end;
4052 vm_map_unlock(dst_map);
4053 copy_size = sub_end - sub_start;
4054
4055 /* adjust the copy object */
4056 if (total_size > copy_size) {
4057 vm_size_t local_size = 0;
4058 vm_size_t entry_size;
4059
4060 nentries = 1;
4061 new_offset = copy->offset;
4062 copy_entry = vm_map_copy_first_entry(copy);
4063 while(copy_entry !=
4064 vm_map_copy_to_entry(copy)){
4065 entry_size = copy_entry->vme_end -
4066 copy_entry->vme_start;
4067 if((local_size < copy_size) &&
4068 ((local_size + entry_size)
4069 >= copy_size)) {
4070 vm_map_copy_clip_end(copy,
4071 copy_entry,
4072 copy_entry->vme_start +
4073 (copy_size - local_size));
4074 entry_size = copy_entry->vme_end -
4075 copy_entry->vme_start;
4076 local_size += entry_size;
4077 new_offset += entry_size;
4078 }
4079 if(local_size >= copy_size) {
4080 next_copy = copy_entry->vme_next;
4081 copy_entry->vme_next =
4082 vm_map_copy_to_entry(copy);
4083 previous_prev =
4084 copy->cpy_hdr.links.prev;
4085 copy->cpy_hdr.links.prev = copy_entry;
4086 copy->size = copy_size;
4087 remaining_entries =
4088 copy->cpy_hdr.nentries;
4089 remaining_entries -= nentries;
4090 copy->cpy_hdr.nentries = nentries;
4091 break;
4092 } else {
4093 local_size += entry_size;
4094 new_offset += entry_size;
4095 nentries++;
4096 }
4097 copy_entry = copy_entry->vme_next;
4098 }
4099 }
4100
4101 if((entry->use_pmap) && (pmap == NULL)) {
4102 kr = vm_map_copy_overwrite_nested(
4103 entry->object.sub_map,
4104 sub_start,
4105 copy,
4106 interruptible,
4107 entry->object.sub_map->pmap);
4108 } else if (pmap != NULL) {
4109 kr = vm_map_copy_overwrite_nested(
4110 entry->object.sub_map,
4111 sub_start,
4112 copy,
4113 interruptible, pmap);
4114 } else {
4115 kr = vm_map_copy_overwrite_nested(
4116 entry->object.sub_map,
4117 sub_start,
4118 copy,
4119 interruptible,
4120 dst_map->pmap);
4121 }
4122 if(kr != KERN_SUCCESS) {
4123 if(next_copy != NULL) {
4124 copy->cpy_hdr.nentries +=
4125 remaining_entries;
4126 copy->cpy_hdr.links.prev->vme_next =
4127 next_copy;
4128 copy->cpy_hdr.links.prev
4129 = previous_prev;
4130 copy->size = total_size;
4131 }
4132 return kr;
4133 }
4134 if (dst_end <= local_end) {
4135 return(KERN_SUCCESS);
4136 }
4137 /* otherwise copy no longer exists, it was */
4138 /* destroyed after successful copy_overwrite */
4139 copy = (vm_map_copy_t)
4140 zalloc(vm_map_copy_zone);
4141 vm_map_copy_first_entry(copy) =
4142 vm_map_copy_last_entry(copy) =
4143 vm_map_copy_to_entry(copy);
4144 copy->type = VM_MAP_COPY_ENTRY_LIST;
4145 copy->offset = new_offset;
4146
4147 total_size -= copy_size;
4148 copy_size = 0;
4149 /* put back remainder of copy in container */
4150 if(next_copy != NULL) {
4151 copy->cpy_hdr.nentries = remaining_entries;
4152 copy->cpy_hdr.links.next = next_copy;
4153 copy->cpy_hdr.links.prev = previous_prev;
4154 copy->size = total_size;
4155 next_copy->vme_prev =
4156 vm_map_copy_to_entry(copy);
4157 next_copy = NULL;
4158 }
4159 base_addr = local_end;
4160 vm_map_lock(dst_map);
4161 if(!vm_map_lookup_entry(dst_map,
4162 local_end, &tmp_entry)) {
4163 vm_map_unlock(dst_map);
4164 return(KERN_INVALID_ADDRESS);
4165 }
4166 entry = tmp_entry;
4167 continue;
4168 }
4169 if (dst_end <= entry->vme_end) {
4170 copy_size = dst_end - base_addr;
4171 break;
4172 }
4173
4174 if ((next == vm_map_to_entry(dst_map)) ||
4175 (next->vme_start != entry->vme_end)) {
4176 vm_map_unlock(dst_map);
4177 return(KERN_INVALID_ADDRESS);
4178 }
4179
4180 entry = next;
4181 }/* for */
4182
4183 next_copy = NULL;
4184 nentries = 1;
4185
4186 /* adjust the copy object */
4187 if (total_size > copy_size) {
4188 vm_size_t local_size = 0;
4189 vm_size_t entry_size;
4190
4191 new_offset = copy->offset;
4192 copy_entry = vm_map_copy_first_entry(copy);
4193 while(copy_entry != vm_map_copy_to_entry(copy)) {
4194 entry_size = copy_entry->vme_end -
4195 copy_entry->vme_start;
4196 if((local_size < copy_size) &&
4197 ((local_size + entry_size)
4198 >= copy_size)) {
4199 vm_map_copy_clip_end(copy, copy_entry,
4200 copy_entry->vme_start +
4201 (copy_size - local_size));
4202 entry_size = copy_entry->vme_end -
4203 copy_entry->vme_start;
4204 local_size += entry_size;
4205 new_offset += entry_size;
4206 }
4207 if(local_size >= copy_size) {
4208 next_copy = copy_entry->vme_next;
4209 copy_entry->vme_next =
4210 vm_map_copy_to_entry(copy);
4211 previous_prev =
4212 copy->cpy_hdr.links.prev;
4213 copy->cpy_hdr.links.prev = copy_entry;
4214 copy->size = copy_size;
4215 remaining_entries =
4216 copy->cpy_hdr.nentries;
4217 remaining_entries -= nentries;
4218 copy->cpy_hdr.nentries = nentries;
4219 break;
4220 } else {
4221 local_size += entry_size;
4222 new_offset += entry_size;
4223 nentries++;
4224 }
4225 copy_entry = copy_entry->vme_next;
4226 }
4227 }
4228
4229 if (aligned) {
4230 pmap_t local_pmap;
4231
4232 if(pmap)
4233 local_pmap = pmap;
4234 else
4235 local_pmap = dst_map->pmap;
4236
4237 if ((kr = vm_map_copy_overwrite_aligned(
4238 dst_map, tmp_entry, copy,
4239 base_addr, local_pmap)) != KERN_SUCCESS) {
4240 if(next_copy != NULL) {
4241 copy->cpy_hdr.nentries +=
4242 remaining_entries;
4243 copy->cpy_hdr.links.prev->vme_next =
4244 next_copy;
4245 copy->cpy_hdr.links.prev =
4246 previous_prev;
4247 copy->size += copy_size;
4248 }
4249 return kr;
4250 }
4251 vm_map_unlock(dst_map);
4252 } else {
4253 /*
4254 * Performance gain:
4255 *
4256 * if the copy and dst address are misaligned but the same
4257 * offset within the page we can copy_not_aligned the
4258 * misaligned parts and copy aligned the rest. If they are
4259 * aligned but len is unaligned we simply need to copy
4260 * the end bit unaligned. We'll need to split the misaligned
4261 * bits of the region in this case !
4262 */
4263 /* ALWAYS UNLOCKS THE dst_map MAP */
4264 if ((kr = vm_map_copy_overwrite_unaligned( dst_map,
4265 tmp_entry, copy, base_addr)) != KERN_SUCCESS) {
4266 if(next_copy != NULL) {
4267 copy->cpy_hdr.nentries +=
4268 remaining_entries;
4269 copy->cpy_hdr.links.prev->vme_next =
4270 next_copy;
4271 copy->cpy_hdr.links.prev =
4272 previous_prev;
4273 copy->size += copy_size;
4274 }
4275 return kr;
4276 }
4277 }
4278 total_size -= copy_size;
4279 if(total_size == 0)
4280 break;
4281 base_addr += copy_size;
4282 copy_size = 0;
4283 copy->offset = new_offset;
4284 if(next_copy != NULL) {
4285 copy->cpy_hdr.nentries = remaining_entries;
4286 copy->cpy_hdr.links.next = next_copy;
4287 copy->cpy_hdr.links.prev = previous_prev;
4288 next_copy->vme_prev = vm_map_copy_to_entry(copy);
4289 copy->size = total_size;
4290 }
4291 vm_map_lock(dst_map);
4292 while(TRUE) {
4293 if (!vm_map_lookup_entry(dst_map,
4294 base_addr, &tmp_entry)) {
4295 vm_map_unlock(dst_map);
4296 return(KERN_INVALID_ADDRESS);
4297 }
4298 if (tmp_entry->in_transition) {
4299 entry->needs_wakeup = TRUE;
4300 vm_map_entry_wait(dst_map, THREAD_UNINT);
4301 } else {
4302 break;
4303 }
4304 }
4305 vm_map_clip_start(dst_map, tmp_entry, trunc_page(base_addr));
4306
4307 entry = tmp_entry;
4308 } /* while */
4309
4310 /*
4311 * Throw away the vm_map_copy object
4312 */
4313 vm_map_copy_discard(copy);
4314
4315 return(KERN_SUCCESS);
4316 }/* vm_map_copy_overwrite */
4317
4318 kern_return_t
4319 vm_map_copy_overwrite(
4320 vm_map_t dst_map,
4321 vm_offset_t dst_addr,
4322 vm_map_copy_t copy,
4323 boolean_t interruptible)
4324 {
4325 return vm_map_copy_overwrite_nested(
4326 dst_map, dst_addr, copy, interruptible, (pmap_t) NULL);
4327 }
4328
4329
4330 /*
4331 * Routine: vm_map_copy_overwrite_unaligned
4332 *
4333 * Decription:
4334 * Physically copy unaligned data
4335 *
4336 * Implementation:
4337 * Unaligned parts of pages have to be physically copied. We use
4338 * a modified form of vm_fault_copy (which understands none-aligned
4339 * page offsets and sizes) to do the copy. We attempt to copy as
4340 * much memory in one go as possibly, however vm_fault_copy copies
4341 * within 1 memory object so we have to find the smaller of "amount left"
4342 * "source object data size" and "target object data size". With
4343 * unaligned data we don't need to split regions, therefore the source
4344 * (copy) object should be one map entry, the target range may be split
4345 * over multiple map entries however. In any event we are pessimistic
4346 * about these assumptions.
4347 *
4348 * Assumptions:
4349 * dst_map is locked on entry and is return locked on success,
4350 * unlocked on error.
4351 */
4352
4353 kern_return_t
4354 vm_map_copy_overwrite_unaligned(
4355 vm_map_t dst_map,
4356 vm_map_entry_t entry,
4357 vm_map_copy_t copy,
4358 vm_offset_t start)
4359 {
4360 vm_map_entry_t copy_entry = vm_map_copy_first_entry(copy);
4361 vm_map_version_t version;
4362 vm_object_t dst_object;
4363 vm_object_offset_t dst_offset;
4364 vm_object_offset_t src_offset;
4365 vm_object_offset_t entry_offset;
4366 vm_offset_t entry_end;
4367 vm_size_t src_size,
4368 dst_size,
4369 copy_size,
4370 amount_left;
4371 kern_return_t kr = KERN_SUCCESS;
4372
4373 vm_map_lock_write_to_read(dst_map);
4374
4375 src_offset = copy->offset - trunc_page_64(copy->offset);
4376 amount_left = copy->size;
4377 /*
4378 * unaligned so we never clipped this entry, we need the offset into
4379 * the vm_object not just the data.
4380 */
4381 while (amount_left > 0) {
4382
4383 if (entry == vm_map_to_entry(dst_map)) {
4384 vm_map_unlock_read(dst_map);
4385 return KERN_INVALID_ADDRESS;
4386 }
4387
4388 /* "start" must be within the current map entry */
4389 assert ((start>=entry->vme_start) && (start<entry->vme_end));
4390
4391 dst_offset = start - entry->vme_start;
4392
4393 dst_size = entry->vme_end - start;
4394
4395 src_size = copy_entry->vme_end -
4396 (copy_entry->vme_start + src_offset);
4397
4398 if (dst_size < src_size) {
4399 /*
4400 * we can only copy dst_size bytes before
4401 * we have to get the next destination entry
4402 */
4403 copy_size = dst_size;
4404 } else {
4405 /*
4406 * we can only copy src_size bytes before
4407 * we have to get the next source copy entry
4408 */
4409 copy_size = src_size;
4410 }
4411
4412 if (copy_size > amount_left) {
4413 copy_size = amount_left;
4414 }
4415 /*
4416 * Entry needs copy, create a shadow shadow object for
4417 * Copy on write region.
4418 */
4419 if (entry->needs_copy &&
4420 ((entry->protection & VM_PROT_WRITE) != 0))
4421 {
4422 if (vm_map_lock_read_to_write(dst_map)) {
4423 vm_map_lock_read(dst_map);
4424 goto RetryLookup;
4425 }
4426 vm_object_shadow(&entry->object.vm_object,
4427 &entry->offset,
4428 (vm_size_t)(entry->vme_end
4429 - entry->vme_start));
4430 entry->needs_copy = FALSE;
4431 vm_map_lock_write_to_read(dst_map);
4432 }
4433 dst_object = entry->object.vm_object;
4434 /*
4435 * unlike with the virtual (aligned) copy we're going
4436 * to fault on it therefore we need a target object.
4437 */
4438 if (dst_object == VM_OBJECT_NULL) {
4439 if (vm_map_lock_read_to_write(dst_map)) {
4440 vm_map_lock_read(dst_map);
4441 goto RetryLookup;
4442 }
4443 dst_object = vm_object_allocate((vm_size_t)
4444 entry->vme_end - entry->vme_start);
4445 entry->object.vm_object = dst_object;
4446 entry->offset = 0;
4447 vm_map_lock_write_to_read(dst_map);
4448 }
4449 /*
4450 * Take an object reference and unlock map. The "entry" may
4451 * disappear or change when the map is unlocked.
4452 */
4453 vm_object_reference(dst_object);
4454 version.main_timestamp = dst_map->timestamp;
4455 entry_offset = entry->offset;
4456 entry_end = entry->vme_end;
4457 vm_map_unlock_read(dst_map);
4458 /*
4459 * Copy as much as possible in one pass
4460 */
4461 kr = vm_fault_copy(
4462 copy_entry->object.vm_object,
4463 copy_entry->offset + src_offset,
4464 &copy_size,
4465 dst_object,
4466 entry_offset + dst_offset,
4467 dst_map,
4468 &version,
4469 THREAD_UNINT );
4470
4471 start += copy_size;
4472 src_offset += copy_size;
4473 amount_left -= copy_size;
4474 /*
4475 * Release the object reference
4476 */
4477 vm_object_deallocate(dst_object);
4478 /*
4479 * If a hard error occurred, return it now
4480 */
4481 if (kr != KERN_SUCCESS)
4482 return kr;
4483
4484 if ((copy_entry->vme_start + src_offset) == copy_entry->vme_end
4485 || amount_left == 0)
4486 {
4487 /*
4488 * all done with this copy entry, dispose.
4489 */
4490 vm_map_copy_entry_unlink(copy, copy_entry);
4491 vm_object_deallocate(copy_entry->object.vm_object);
4492 vm_map_copy_entry_dispose(copy, copy_entry);
4493
4494 if ((copy_entry = vm_map_copy_first_entry(copy))
4495 == vm_map_copy_to_entry(copy) && amount_left) {
4496 /*
4497 * not finished copying but run out of source
4498 */
4499 return KERN_INVALID_ADDRESS;
4500 }
4501 src_offset = 0;
4502 }
4503
4504 if (amount_left == 0)
4505 return KERN_SUCCESS;
4506
4507 vm_map_lock_read(dst_map);
4508 if (version.main_timestamp == dst_map->timestamp) {
4509 if (start == entry_end) {
4510 /*
4511 * destination region is split. Use the version
4512 * information to avoid a lookup in the normal
4513 * case.
4514 */
4515 entry = entry->vme_next;
4516 /*
4517 * should be contiguous. Fail if we encounter
4518 * a hole in the destination.
4519 */
4520 if (start != entry->vme_start) {
4521 vm_map_unlock_read(dst_map);
4522 return KERN_INVALID_ADDRESS ;
4523 }
4524 }
4525 } else {
4526 /*
4527 * Map version check failed.
4528 * we must lookup the entry because somebody
4529 * might have changed the map behind our backs.
4530 */
4531 RetryLookup:
4532 if (!vm_map_lookup_entry(dst_map, start, &entry))
4533 {
4534 vm_map_unlock_read(dst_map);
4535 return KERN_INVALID_ADDRESS ;
4536 }
4537 }
4538 }/* while */
4539
4540 /* NOTREACHED ?? */
4541 vm_map_unlock_read(dst_map);
4542
4543 return KERN_SUCCESS;
4544 }/* vm_map_copy_overwrite_unaligned */
4545
4546 /*
4547 * Routine: vm_map_copy_overwrite_aligned
4548 *
4549 * Description:
4550 * Does all the vm_trickery possible for whole pages.
4551 *
4552 * Implementation:
4553 *
4554 * If there are no permanent objects in the destination,
4555 * and the source and destination map entry zones match,
4556 * and the destination map entry is not shared,
4557 * then the map entries can be deleted and replaced
4558 * with those from the copy. The following code is the
4559 * basic idea of what to do, but there are lots of annoying
4560 * little details about getting protection and inheritance
4561 * right. Should add protection, inheritance, and sharing checks
4562 * to the above pass and make sure that no wiring is involved.
4563 */
4564
4565 kern_return_t
4566 vm_map_copy_overwrite_aligned(
4567 vm_map_t dst_map,
4568 vm_map_entry_t tmp_entry,
4569 vm_map_copy_t copy,
4570 vm_offset_t start,
4571 pmap_t pmap)
4572 {
4573 vm_object_t object;
4574 vm_map_entry_t copy_entry;
4575 vm_size_t copy_size;
4576 vm_size_t size;
4577 vm_map_entry_t entry;
4578
4579 while ((copy_entry = vm_map_copy_first_entry(copy))
4580 != vm_map_copy_to_entry(copy))
4581 {
4582 copy_size = (copy_entry->vme_end - copy_entry->vme_start);
4583
4584 entry = tmp_entry;
4585 if (entry == vm_map_to_entry(dst_map)) {
4586 vm_map_unlock(dst_map);
4587 return KERN_INVALID_ADDRESS;
4588 }
4589 size = (entry->vme_end - entry->vme_start);
4590 /*
4591 * Make sure that no holes popped up in the
4592 * address map, and that the protection is
4593 * still valid, in case the map was unlocked
4594 * earlier.
4595 */
4596
4597 if ((entry->vme_start != start) || ((entry->is_sub_map)
4598 && !entry->needs_copy)) {
4599 vm_map_unlock(dst_map);
4600 return(KERN_INVALID_ADDRESS);
4601 }
4602 assert(entry != vm_map_to_entry(dst_map));
4603
4604 /*
4605 * Check protection again
4606 */
4607
4608 if ( ! (entry->protection & VM_PROT_WRITE)) {
4609 vm_map_unlock(dst_map);
4610 return(KERN_PROTECTION_FAILURE);
4611 }
4612
4613 /*
4614 * Adjust to source size first
4615 */
4616
4617 if (copy_size < size) {
4618 vm_map_clip_end(dst_map, entry, entry->vme_start + copy_size);
4619 size = copy_size;
4620 }
4621
4622 /*
4623 * Adjust to destination size
4624 */
4625
4626 if (size < copy_size) {
4627 vm_map_copy_clip_end(copy, copy_entry,
4628 copy_entry->vme_start + size);
4629 copy_size = size;
4630 }
4631
4632 assert((entry->vme_end - entry->vme_start) == size);
4633 assert((tmp_entry->vme_end - tmp_entry->vme_start) == size);
4634 assert((copy_entry->vme_end - copy_entry->vme_start) == size);
4635
4636 /*
4637 * If the destination contains temporary unshared memory,
4638 * we can perform the copy by throwing it away and
4639 * installing the source data.
4640 */
4641
4642 object = entry->object.vm_object;
4643 if ((!entry->is_shared &&
4644 ((object == VM_OBJECT_NULL) ||
4645 (object->internal && !object->true_share))) ||
4646 entry->needs_copy) {
4647 vm_object_t old_object = entry->object.vm_object;
4648 vm_object_offset_t old_offset = entry->offset;
4649 vm_object_offset_t offset;
4650
4651 /*
4652 * Ensure that the source and destination aren't
4653 * identical
4654 */
4655 if (old_object == copy_entry->object.vm_object &&
4656 old_offset == copy_entry->offset) {
4657 vm_map_copy_entry_unlink(copy, copy_entry);
4658 vm_map_copy_entry_dispose(copy, copy_entry);
4659
4660 if (old_object != VM_OBJECT_NULL)
4661 vm_object_deallocate(old_object);
4662
4663 start = tmp_entry->vme_end;
4664 tmp_entry = tmp_entry->vme_next;
4665 continue;
4666 }
4667
4668 if (old_object != VM_OBJECT_NULL) {
4669 if(entry->is_sub_map) {
4670 if(entry->use_pmap) {
4671 #ifndef i386
4672 pmap_unnest(dst_map->pmap,
4673 entry->vme_start,
4674 entry->vme_end - entry->vme_start);
4675 #endif
4676 } else {
4677 vm_map_submap_pmap_clean(
4678 dst_map, entry->vme_start,
4679 entry->vme_end,
4680 entry->object.sub_map,
4681 entry->offset);
4682 }
4683 vm_map_deallocate(
4684 entry->object.sub_map);
4685 } else {
4686 vm_object_pmap_protect(
4687 old_object,
4688 old_offset,
4689 size,
4690 pmap,
4691 tmp_entry->vme_start,
4692 VM_PROT_NONE);
4693
4694 vm_object_deallocate(old_object);
4695 }
4696 }
4697
4698 entry->is_sub_map = FALSE;
4699 entry->object = copy_entry->object;
4700 object = entry->object.vm_object;
4701 entry->needs_copy = copy_entry->needs_copy;
4702 entry->wired_count = 0;
4703 entry->user_wired_count = 0;
4704 offset = entry->offset = copy_entry->offset;
4705
4706 vm_map_copy_entry_unlink(copy, copy_entry);
4707 vm_map_copy_entry_dispose(copy, copy_entry);
4708 #if BAD_OPTIMIZATION
4709 /*
4710 * if we turn this optimization back on
4711 * we need to revisit our use of pmap mappings
4712 * large copies will cause us to run out and panic
4713 * this optimization only saved on average 2 us per page if ALL
4714 * the pages in the source were currently mapped
4715 * and ALL the pages in the dest were touched, if there were fewer
4716 * than 2/3 of the pages touched, this optimization actually cost more cycles
4717 */
4718
4719 /*
4720 * Try to aggressively enter physical mappings
4721 * (but avoid uninstantiated objects)
4722 */
4723 if (object != VM_OBJECT_NULL) {
4724 vm_offset_t va = entry->vme_start;
4725
4726 while (va < entry->vme_end) {
4727 register vm_page_t m;
4728 vm_prot_t prot;
4729
4730 /*
4731 * Look for the page in the top object
4732 */
4733 prot = entry->protection;
4734 vm_object_lock(object);
4735 vm_object_paging_begin(object);
4736
4737 if ((m = vm_page_lookup(object,offset)) !=
4738 VM_PAGE_NULL && !m->busy &&
4739 !m->fictitious &&
4740 (!m->unusual || (!m->error &&
4741 !m->restart && !m->absent &&
4742 (prot & m->page_lock) == 0))) {
4743
4744 m->busy = TRUE;
4745 vm_object_unlock(object);
4746
4747 /*
4748 * Honor COW obligations
4749 */
4750 if (entry->needs_copy)
4751 prot &= ~VM_PROT_WRITE;
4752
4753 PMAP_ENTER(pmap, va, m,
4754 prot, FALSE);
4755
4756 vm_object_lock(object);
4757 vm_page_lock_queues();
4758 if (!m->active && !m->inactive)
4759 vm_page_activate(m);
4760 vm_page_unlock_queues();
4761 PAGE_WAKEUP_DONE(m);
4762 }
4763 vm_object_paging_end(object);
4764 vm_object_unlock(object);
4765
4766 offset += PAGE_SIZE_64;
4767 va += PAGE_SIZE;
4768 } /* end while (va < entry->vme_end) */
4769 } /* end if (object) */
4770 #endif
4771 /*
4772 * Set up for the next iteration. The map
4773 * has not been unlocked, so the next
4774 * address should be at the end of this
4775 * entry, and the next map entry should be
4776 * the one following it.
4777 */
4778
4779 start = tmp_entry->vme_end;
4780 tmp_entry = tmp_entry->vme_next;
4781 } else {
4782 vm_map_version_t version;
4783 vm_object_t dst_object = entry->object.vm_object;
4784 vm_object_offset_t dst_offset = entry->offset;
4785 kern_return_t r;
4786
4787 /*
4788 * Take an object reference, and record
4789 * the map version information so that the
4790 * map can be safely unlocked.
4791 */
4792
4793 vm_object_reference(dst_object);
4794
4795 version.main_timestamp = dst_map->timestamp;
4796
4797 vm_map_unlock(dst_map);
4798
4799 /*
4800 * Copy as much as possible in one pass
4801 */
4802
4803 copy_size = size;
4804 r = vm_fault_copy(
4805 copy_entry->object.vm_object,
4806 copy_entry->offset,
4807 &copy_size,
4808 dst_object,
4809 dst_offset,
4810 dst_map,
4811 &version,
4812 THREAD_UNINT );
4813
4814 /*
4815 * Release the object reference
4816 */
4817
4818 vm_object_deallocate(dst_object);
4819
4820 /*
4821 * If a hard error occurred, return it now
4822 */
4823
4824 if (r != KERN_SUCCESS)
4825 return(r);
4826
4827 if (copy_size != 0) {
4828 /*
4829 * Dispose of the copied region
4830 */
4831
4832 vm_map_copy_clip_end(copy, copy_entry,
4833 copy_entry->vme_start + copy_size);
4834 vm_map_copy_entry_unlink(copy, copy_entry);
4835 vm_object_deallocate(copy_entry->object.vm_object);
4836 vm_map_copy_entry_dispose(copy, copy_entry);
4837 }
4838
4839 /*
4840 * Pick up in the destination map where we left off.
4841 *
4842 * Use the version information to avoid a lookup
4843 * in the normal case.
4844 */
4845
4846 start += copy_size;
4847 vm_map_lock(dst_map);
4848 if ((version.main_timestamp + 1) == dst_map->timestamp) {
4849 /* We can safely use saved tmp_entry value */
4850
4851 vm_map_clip_end(dst_map, tmp_entry, start);
4852 tmp_entry = tmp_entry->vme_next;
4853 } else {
4854 /* Must do lookup of tmp_entry */
4855
4856 if (!vm_map_lookup_entry(dst_map, start, &tmp_entry)) {
4857 vm_map_unlock(dst_map);
4858 return(KERN_INVALID_ADDRESS);
4859 }
4860 vm_map_clip_start(dst_map, tmp_entry, start);
4861 }
4862 }
4863 }/* while */
4864
4865 return(KERN_SUCCESS);
4866 }/* vm_map_copy_overwrite_aligned */
4867
4868 /*
4869 * Routine: vm_map_copyin_kernel_buffer
4870 *
4871 * Description:
4872 * Copy in data to a kernel buffer from space in the
4873 * source map. The original space may be otpionally
4874 * deallocated.
4875 *
4876 * If successful, returns a new copy object.
4877 */
4878 kern_return_t
4879 vm_map_copyin_kernel_buffer(
4880 vm_map_t src_map,
4881 vm_offset_t src_addr,
4882 vm_size_t len,
4883 boolean_t src_destroy,
4884 vm_map_copy_t *copy_result)
4885 {
4886 boolean_t flags;
4887 vm_map_copy_t copy;
4888 vm_size_t kalloc_size = sizeof(struct vm_map_copy) + len;
4889
4890 copy = (vm_map_copy_t) kalloc(kalloc_size);
4891 if (copy == VM_MAP_COPY_NULL) {
4892 return KERN_RESOURCE_SHORTAGE;
4893 }
4894 copy->type = VM_MAP_COPY_KERNEL_BUFFER;
4895 copy->size = len;
4896 copy->offset = 0;
4897 copy->cpy_kdata = (vm_offset_t) (copy + 1);
4898 copy->cpy_kalloc_size = kalloc_size;
4899
4900 if (src_map == kernel_map) {
4901 bcopy((char *)src_addr, (char *)copy->cpy_kdata, len);
4902 flags = VM_MAP_REMOVE_KUNWIRE | VM_MAP_REMOVE_WAIT_FOR_KWIRE |
4903 VM_MAP_REMOVE_INTERRUPTIBLE;
4904 } else {
4905 kern_return_t kr;
4906 kr = copyinmap(src_map, src_addr, copy->cpy_kdata, len);
4907 if (kr != KERN_SUCCESS) {
4908 kfree((vm_offset_t)copy, kalloc_size);
4909 return kr;
4910 }
4911 flags = VM_MAP_REMOVE_WAIT_FOR_KWIRE |
4912 VM_MAP_REMOVE_INTERRUPTIBLE;
4913 }
4914 if (src_destroy) {
4915 (void) vm_map_remove(src_map, trunc_page(src_addr),
4916 round_page(src_addr + len),
4917 flags);
4918 }
4919 *copy_result = copy;
4920 return KERN_SUCCESS;
4921 }
4922
4923 /*
4924 * Routine: vm_map_copyout_kernel_buffer
4925 *
4926 * Description:
4927 * Copy out data from a kernel buffer into space in the
4928 * destination map. The space may be otpionally dynamically
4929 * allocated.
4930 *
4931 * If successful, consumes the copy object.
4932 * Otherwise, the caller is responsible for it.
4933 */
4934 kern_return_t
4935 vm_map_copyout_kernel_buffer(
4936 vm_map_t map,
4937 vm_offset_t *addr, /* IN/OUT */
4938 vm_map_copy_t copy,
4939 boolean_t overwrite)
4940 {
4941 kern_return_t kr = KERN_SUCCESS;
4942 thread_act_t thr_act = current_act();
4943
4944 if (!overwrite) {
4945
4946 /*
4947 * Allocate space in the target map for the data
4948 */
4949 *addr = 0;
4950 kr = vm_map_enter(map,
4951 addr,
4952 round_page(copy->size),
4953 (vm_offset_t) 0,
4954 TRUE,
4955 VM_OBJECT_NULL,
4956 (vm_object_offset_t) 0,
4957 FALSE,
4958 VM_PROT_DEFAULT,
4959 VM_PROT_ALL,
4960 VM_INHERIT_DEFAULT);
4961 if (kr != KERN_SUCCESS)
4962 return(kr);
4963 }
4964
4965 /*
4966 * Copyout the data from the kernel buffer to the target map.
4967 */
4968 if (thr_act->map == map) {
4969
4970 /*
4971 * If the target map is the current map, just do
4972 * the copy.
4973 */
4974 if (copyout((char *)copy->cpy_kdata, (char *)*addr,
4975 copy->size)) {
4976 kr = KERN_INVALID_ADDRESS;
4977 }
4978 }
4979 else {
4980 vm_map_t oldmap;
4981
4982 /*
4983 * If the target map is another map, assume the
4984 * target's address space identity for the duration
4985 * of the copy.
4986 */
4987 vm_map_reference(map);
4988 oldmap = vm_map_switch(map);
4989
4990 if (copyout((char *)copy->cpy_kdata, (char *)*addr,
4991 copy->size)) {
4992 kr = KERN_INVALID_ADDRESS;
4993 }
4994
4995 (void) vm_map_switch(oldmap);
4996 vm_map_deallocate(map);
4997 }
4998
4999 kfree((vm_offset_t)copy, copy->cpy_kalloc_size);
5000
5001 return(kr);
5002 }
5003
5004 /*
5005 * Macro: vm_map_copy_insert
5006 *
5007 * Description:
5008 * Link a copy chain ("copy") into a map at the
5009 * specified location (after "where").
5010 * Side effects:
5011 * The copy chain is destroyed.
5012 * Warning:
5013 * The arguments are evaluated multiple times.
5014 */
5015 #define vm_map_copy_insert(map, where, copy) \
5016 MACRO_BEGIN \
5017 vm_map_t VMCI_map; \
5018 vm_map_entry_t VMCI_where; \
5019 vm_map_copy_t VMCI_copy; \
5020 VMCI_map = (map); \
5021 VMCI_where = (where); \
5022 VMCI_copy = (copy); \
5023 ((VMCI_where->vme_next)->vme_prev = vm_map_copy_last_entry(VMCI_copy))\
5024 ->vme_next = (VMCI_where->vme_next); \
5025 ((VMCI_where)->vme_next = vm_map_copy_first_entry(VMCI_copy)) \
5026 ->vme_prev = VMCI_where; \
5027 VMCI_map->hdr.nentries += VMCI_copy->cpy_hdr.nentries; \
5028 UPDATE_FIRST_FREE(VMCI_map, VMCI_map->first_free); \
5029 zfree(vm_map_copy_zone, (vm_offset_t) VMCI_copy); \
5030 MACRO_END
5031
5032 /*
5033 * Routine: vm_map_copyout
5034 *
5035 * Description:
5036 * Copy out a copy chain ("copy") into newly-allocated
5037 * space in the destination map.
5038 *
5039 * If successful, consumes the copy object.
5040 * Otherwise, the caller is responsible for it.
5041 */
5042 kern_return_t
5043 vm_map_copyout(
5044 register vm_map_t dst_map,
5045 vm_offset_t *dst_addr, /* OUT */
5046 register vm_map_copy_t copy)
5047 {
5048 vm_size_t size;
5049 vm_size_t adjustment;
5050 vm_offset_t start;
5051 vm_object_offset_t vm_copy_start;
5052 vm_map_entry_t last;
5053 register
5054 vm_map_entry_t entry;
5055
5056 /*
5057 * Check for null copy object.
5058 */
5059
5060 if (copy == VM_MAP_COPY_NULL) {
5061 *dst_addr = 0;
5062 return(KERN_SUCCESS);
5063 }
5064
5065 /*
5066 * Check for special copy object, created
5067 * by vm_map_copyin_object.
5068 */
5069
5070 if (copy->type == VM_MAP_COPY_OBJECT) {
5071 vm_object_t object = copy->cpy_object;
5072 kern_return_t kr;
5073 vm_object_offset_t offset;
5074
5075 offset = trunc_page_64(copy->offset);
5076 size = round_page(copy->size +
5077 (vm_size_t)(copy->offset - offset));
5078 *dst_addr = 0;
5079 kr = vm_map_enter(dst_map, dst_addr, size,
5080 (vm_offset_t) 0, TRUE,
5081 object, offset, FALSE,
5082 VM_PROT_DEFAULT, VM_PROT_ALL,
5083 VM_INHERIT_DEFAULT);
5084 if (kr != KERN_SUCCESS)
5085 return(kr);
5086 /* Account for non-pagealigned copy object */
5087 *dst_addr += (vm_offset_t)(copy->offset - offset);
5088 zfree(vm_map_copy_zone, (vm_offset_t) copy);
5089 return(KERN_SUCCESS);
5090 }
5091
5092 /*
5093 * Check for special kernel buffer allocated
5094 * by new_ipc_kmsg_copyin.
5095 */
5096
5097 if (copy->type == VM_MAP_COPY_KERNEL_BUFFER) {
5098 return(vm_map_copyout_kernel_buffer(dst_map, dst_addr,
5099 copy, FALSE));
5100 }
5101
5102 if (copy->type == VM_MAP_COPY_PAGE_LIST)
5103 return(vm_map_copyout_page_list(dst_map, dst_addr, copy));
5104
5105 /*
5106 * Find space for the data
5107 */
5108
5109 vm_copy_start = trunc_page_64(copy->offset);
5110 size = round_page((vm_size_t)copy->offset + copy->size)
5111 - vm_copy_start;
5112
5113 StartAgain: ;
5114
5115 vm_map_lock(dst_map);
5116 assert(first_free_is_valid(dst_map));
5117 start = ((last = dst_map->first_free) == vm_map_to_entry(dst_map)) ?
5118 vm_map_min(dst_map) : last->vme_end;
5119
5120 while (TRUE) {
5121 vm_map_entry_t next = last->vme_next;
5122 vm_offset_t end = start + size;
5123
5124 if ((end > dst_map->max_offset) || (end < start)) {
5125 if (dst_map->wait_for_space) {
5126 if (size <= (dst_map->max_offset - dst_map->min_offset)) {
5127 assert_wait((event_t) dst_map,
5128 THREAD_INTERRUPTIBLE);
5129 vm_map_unlock(dst_map);
5130 thread_block((void (*)(void))0);
5131 goto StartAgain;
5132 }
5133 }
5134 vm_map_unlock(dst_map);
5135 return(KERN_NO_SPACE);
5136 }
5137
5138 if ((next == vm_map_to_entry(dst_map)) ||
5139 (next->vme_start >= end))
5140 break;
5141
5142 last = next;
5143 start = last->vme_end;
5144 }
5145
5146 /*
5147 * Since we're going to just drop the map
5148 * entries from the copy into the destination
5149 * map, they must come from the same pool.
5150 */
5151
5152 if (copy->cpy_hdr.entries_pageable != dst_map->hdr.entries_pageable) {
5153 /*
5154 * Mismatches occur when dealing with the default
5155 * pager.
5156 */
5157 zone_t old_zone;
5158 vm_map_entry_t next, new;
5159
5160 /*
5161 * Find the zone that the copies were allocated from
5162 */
5163 old_zone = (copy->cpy_hdr.entries_pageable)
5164 ? vm_map_entry_zone
5165 : vm_map_kentry_zone;
5166 entry = vm_map_copy_first_entry(copy);
5167
5168 /*
5169 * Reinitialize the copy so that vm_map_copy_entry_link
5170 * will work.
5171 */
5172 copy->cpy_hdr.nentries = 0;
5173 copy->cpy_hdr.entries_pageable = dst_map->hdr.entries_pageable;
5174 vm_map_copy_first_entry(copy) =
5175 vm_map_copy_last_entry(copy) =
5176 vm_map_copy_to_entry(copy);
5177
5178 /*
5179 * Copy each entry.
5180 */
5181 while (entry != vm_map_copy_to_entry(copy)) {
5182 new = vm_map_copy_entry_create(copy);
5183 vm_map_entry_copy_full(new, entry);
5184 new->use_pmap = FALSE; /* clr address space specifics */
5185 vm_map_copy_entry_link(copy,
5186 vm_map_copy_last_entry(copy),
5187 new);
5188 next = entry->vme_next;
5189 zfree(old_zone, (vm_offset_t) entry);
5190 entry = next;
5191 }
5192 }
5193
5194 /*
5195 * Adjust the addresses in the copy chain, and
5196 * reset the region attributes.
5197 */
5198
5199 adjustment = start - vm_copy_start;
5200 for (entry = vm_map_copy_first_entry(copy);
5201 entry != vm_map_copy_to_entry(copy);
5202 entry = entry->vme_next) {
5203 entry->vme_start += adjustment;
5204 entry->vme_end += adjustment;
5205
5206 entry->inheritance = VM_INHERIT_DEFAULT;
5207 entry->protection = VM_PROT_DEFAULT;
5208 entry->max_protection = VM_PROT_ALL;
5209 entry->behavior = VM_BEHAVIOR_DEFAULT;
5210
5211 /*
5212 * If the entry is now wired,
5213 * map the pages into the destination map.
5214 */
5215 if (entry->wired_count != 0) {
5216 register vm_offset_t va;
5217 vm_object_offset_t offset;
5218 register vm_object_t object;
5219
5220 object = entry->object.vm_object;
5221 offset = entry->offset;
5222 va = entry->vme_start;
5223
5224 pmap_pageable(dst_map->pmap,
5225 entry->vme_start,
5226 entry->vme_end,
5227 TRUE);
5228
5229 while (va < entry->vme_end) {
5230 register vm_page_t m;
5231
5232 /*
5233 * Look up the page in the object.
5234 * Assert that the page will be found in the
5235 * top object:
5236 * either
5237 * the object was newly created by
5238 * vm_object_copy_slowly, and has
5239 * copies of all of the pages from
5240 * the source object
5241 * or
5242 * the object was moved from the old
5243 * map entry; because the old map
5244 * entry was wired, all of the pages
5245 * were in the top-level object.
5246 * (XXX not true if we wire pages for
5247 * reading)
5248 */
5249 vm_object_lock(object);
5250 vm_object_paging_begin(object);
5251
5252 m = vm_page_lookup(object, offset);
5253 if (m == VM_PAGE_NULL || m->wire_count == 0 ||
5254 m->absent)
5255 panic("vm_map_copyout: wiring 0x%x", m);
5256
5257 m->busy = TRUE;
5258 vm_object_unlock(object);
5259
5260 PMAP_ENTER(dst_map->pmap, va, m,
5261 entry->protection, TRUE);
5262
5263 vm_object_lock(object);
5264 PAGE_WAKEUP_DONE(m);
5265 /* the page is wired, so we don't have to activate */
5266 vm_object_paging_end(object);
5267 vm_object_unlock(object);
5268
5269 offset += PAGE_SIZE_64;
5270 va += PAGE_SIZE;
5271 }
5272 }
5273 else if (size <= vm_map_aggressive_enter_max) {
5274
5275 register vm_offset_t va;
5276 vm_object_offset_t offset;
5277 register vm_object_t object;
5278 vm_prot_t prot;
5279
5280 object = entry->object.vm_object;
5281 if (object != VM_OBJECT_NULL) {
5282
5283 offset = entry->offset;
5284 va = entry->vme_start;
5285 while (va < entry->vme_end) {
5286 register vm_page_t m;
5287
5288 /*
5289 * Look up the page in the object.
5290 * Assert that the page will be found
5291 * in the top object if at all...
5292 */
5293 vm_object_lock(object);
5294 vm_object_paging_begin(object);
5295
5296 if (((m = vm_page_lookup(object,
5297 offset))
5298 != VM_PAGE_NULL) &&
5299 !m->busy && !m->fictitious &&
5300 !m->absent && !m->error) {
5301 m->busy = TRUE;
5302 vm_object_unlock(object);
5303
5304 /* honor cow obligations */
5305 prot = entry->protection;
5306 if (entry->needs_copy)
5307 prot &= ~VM_PROT_WRITE;
5308
5309 PMAP_ENTER(dst_map->pmap, va,
5310 m, prot, FALSE);
5311
5312 vm_object_lock(object);
5313 vm_page_lock_queues();
5314 if (!m->active && !m->inactive)
5315 vm_page_activate(m);
5316 vm_page_unlock_queues();
5317 PAGE_WAKEUP_DONE(m);
5318 }
5319 vm_object_paging_end(object);
5320 vm_object_unlock(object);
5321
5322 offset += PAGE_SIZE_64;
5323 va += PAGE_SIZE;
5324 }
5325 }
5326 }
5327 }
5328
5329 /*
5330 * Correct the page alignment for the result
5331 */
5332
5333 *dst_addr = start + (copy->offset - vm_copy_start);
5334
5335 /*
5336 * Update the hints and the map size
5337 */
5338
5339 SAVE_HINT(dst_map, vm_map_copy_last_entry(copy));
5340
5341 dst_map->size += size;
5342
5343 /*
5344 * Link in the copy
5345 */
5346
5347 vm_map_copy_insert(dst_map, last, copy);
5348
5349 vm_map_unlock(dst_map);
5350
5351 /*
5352 * XXX If wiring_required, call vm_map_pageable
5353 */
5354
5355 return(KERN_SUCCESS);
5356 }
5357
5358 boolean_t vm_map_aggressive_enter; /* not used yet */
5359
5360 /*
5361 *
5362 * vm_map_copyout_page_list:
5363 *
5364 * Version of vm_map_copyout() for page list vm map copies.
5365 *
5366 */
5367 kern_return_t
5368 vm_map_copyout_page_list(
5369 register vm_map_t dst_map,
5370 vm_offset_t *dst_addr, /* OUT */
5371 register vm_map_copy_t copy)
5372 {
5373 vm_size_t size;
5374 vm_offset_t start;
5375 vm_offset_t end;
5376 vm_object_offset_t offset;
5377 vm_map_entry_t last;
5378 register
5379 vm_object_t object;
5380 vm_page_t *page_list, m;
5381 vm_map_entry_t entry;
5382 vm_object_offset_t old_last_offset;
5383 boolean_t cont_invoked, needs_wakeup;
5384 kern_return_t result = KERN_SUCCESS;
5385 vm_map_copy_t orig_copy;
5386 vm_object_offset_t dst_offset;
5387 boolean_t must_wire;
5388 boolean_t aggressive_enter;
5389
5390 /*
5391 * Check for null copy object.
5392 */
5393
5394 if (copy == VM_MAP_COPY_NULL) {
5395 *dst_addr = 0;
5396 return(KERN_SUCCESS);
5397 }
5398
5399 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
5400
5401 /*
5402 * Make sure the pages are stolen, because we are
5403 * going to put them in a new object. Assume that
5404 * all pages are identical to first in this regard.
5405 */
5406
5407 page_list = &copy->cpy_page_list[0];
5408 if (!copy->cpy_page_loose)
5409 vm_map_copy_steal_pages(copy);
5410
5411 /*
5412 * Find space for the data
5413 */
5414
5415 size = round_page_64(copy->offset + (vm_object_offset_t)copy->size) -
5416 trunc_page_64(copy->offset);
5417 StartAgain:
5418 vm_map_lock(dst_map);
5419 must_wire = dst_map->wiring_required;
5420
5421 assert(first_free_is_valid(dst_map));
5422 last = dst_map->first_free;
5423 if (last == vm_map_to_entry(dst_map)) {
5424 start = vm_map_min(dst_map);
5425 } else {
5426 start = last->vme_end;
5427 }
5428
5429 while (TRUE) {
5430 vm_map_entry_t next = last->vme_next;
5431 end = start + size;
5432
5433 if ((end > dst_map->max_offset) || (end < start)) {
5434 if (dst_map->wait_for_space) {
5435 if (size <= (dst_map->max_offset -
5436 dst_map->min_offset)) {
5437 assert_wait((event_t) dst_map,
5438 THREAD_INTERRUPTIBLE);
5439 vm_map_unlock(dst_map);
5440 thread_block((void (*)(void))0);
5441 goto StartAgain;
5442 }
5443 }
5444 vm_map_unlock(dst_map);
5445 return(KERN_NO_SPACE);
5446 }
5447
5448 if ((next == vm_map_to_entry(dst_map)) ||
5449 (next->vme_start >= end)) {
5450 break;
5451 }
5452
5453 last = next;
5454 start = last->vme_end;
5455 }
5456
5457 /*
5458 * See whether we can avoid creating a new entry (and object) by
5459 * extending one of our neighbors. [So far, we only attempt to
5460 * extend from below.]
5461 *
5462 * The code path below here is a bit twisted. If any of the
5463 * extension checks fails, we branch to create_object. If
5464 * it all works, we fall out the bottom and goto insert_pages.
5465 */
5466 if (last == vm_map_to_entry(dst_map) ||
5467 last->vme_end != start ||
5468 last->is_shared != FALSE ||
5469 last->is_sub_map != FALSE ||
5470 last->inheritance != VM_INHERIT_DEFAULT ||
5471 last->protection != VM_PROT_DEFAULT ||
5472 last->max_protection != VM_PROT_ALL ||
5473 last->behavior != VM_BEHAVIOR_DEFAULT ||
5474 last->in_transition ||
5475 (must_wire ? (last->wired_count != 1 ||
5476 last->user_wired_count != 0) :
5477 (last->wired_count != 0))) {
5478 goto create_object;
5479 }
5480
5481 /*
5482 * If this entry needs an object, make one.
5483 */
5484 if (last->object.vm_object == VM_OBJECT_NULL) {
5485 object = vm_object_allocate(
5486 (vm_size_t)(last->vme_end - last->vme_start + size));
5487 last->object.vm_object = object;
5488 last->offset = 0;
5489 }
5490 else {
5491 vm_object_offset_t prev_offset = last->offset;
5492 vm_size_t prev_size = start - last->vme_start;
5493 vm_size_t new_size;
5494
5495 /*
5496 * This is basically vm_object_coalesce.
5497 */
5498
5499 object = last->object.vm_object;
5500 vm_object_lock(object);
5501
5502 /*
5503 * Try to collapse the object first
5504 */
5505 vm_object_collapse(object);
5506
5507
5508 /*
5509 * Can't coalesce if pages not mapped to
5510 * last may be in use anyway:
5511 * . more than one reference
5512 * . paged out
5513 * . shadows another object
5514 * . has a copy elsewhere
5515 * . paging references (pages might be in page-list)
5516 */
5517
5518 if ((object->ref_count > 1) ||
5519 object->pager_created ||
5520 (object->shadow != VM_OBJECT_NULL) ||
5521 (object->copy != VM_OBJECT_NULL) ||
5522 (object->paging_in_progress != 0)) {
5523 vm_object_unlock(object);
5524 goto create_object;
5525 }
5526
5527 /*
5528 * Extend the object if necessary. Don't have to call
5529 * vm_object_page_remove because the pages aren't mapped,
5530 * and vm_page_replace will free up any old ones it encounters.
5531 */
5532 new_size = prev_offset + prev_size + size;
5533 if (new_size > object->size) {
5534 #if MACH_PAGEMAP
5535 /*
5536 * We cannot extend an object that has existence info,
5537 * since the existence info might then fail to cover
5538 * the entire object.
5539 *
5540 * This assertion must be true because the object
5541 * has no pager, and we only create existence info
5542 * for objects with pagers.
5543 */
5544 assert(object->existence_map == VM_EXTERNAL_NULL);
5545 #endif /* MACH_PAGEMAP */
5546 object->size = new_size;
5547 }
5548 vm_object_unlock(object);
5549 }
5550
5551 /*
5552 * Coalesced the two objects - can extend
5553 * the previous map entry to include the
5554 * new range.
5555 */
5556 dst_map->size += size;
5557 last->vme_end = end;
5558 UPDATE_FIRST_FREE(dst_map, dst_map->first_free);
5559
5560 SAVE_HINT(dst_map, last);
5561
5562 goto insert_pages;
5563
5564 create_object:
5565
5566 /*
5567 * Create object
5568 */
5569 object = vm_object_allocate(size);
5570
5571 /*
5572 * Create entry
5573 */
5574 last = vm_map_entry_insert(dst_map, last, start, start + size,
5575 object, 0, FALSE, FALSE, TRUE,
5576 VM_PROT_DEFAULT, VM_PROT_ALL,
5577 VM_BEHAVIOR_DEFAULT,
5578 VM_INHERIT_DEFAULT, (must_wire ? 1 : 0));
5579
5580 /*
5581 * Transfer pages into new object.
5582 * Scan page list in vm_map_copy.
5583 */
5584 insert_pages:
5585 dst_offset = copy->offset & PAGE_MASK_64;
5586 cont_invoked = FALSE;
5587 orig_copy = copy;
5588 last->in_transition = TRUE;
5589 old_last_offset = last->offset
5590 + (start - last->vme_start);
5591
5592 aggressive_enter = (size <= vm_map_aggressive_enter_max);
5593
5594 for (offset = 0; offset < size; offset += PAGE_SIZE_64) {
5595 m = *page_list;
5596 assert(m && !m->tabled);
5597
5598 /*
5599 * Must clear busy bit in page before inserting it.
5600 * Ok to skip wakeup logic because nobody else
5601 * can possibly know about this page. Also set
5602 * dirty bit on the assumption that the page is
5603 * not a page of zeros.
5604 */
5605
5606 m->busy = FALSE;
5607 m->dirty = TRUE;
5608 vm_object_lock(object);
5609 vm_page_lock_queues();
5610 vm_page_replace(m, object, old_last_offset + offset);
5611 if (must_wire) {
5612 vm_page_wire(m);
5613 } else if (aggressive_enter) {
5614 vm_page_activate(m);
5615 }
5616 vm_page_unlock_queues();
5617 vm_object_unlock(object);
5618
5619 if (aggressive_enter || must_wire) {
5620 PMAP_ENTER(dst_map->pmap,
5621 last->vme_start + m->offset - last->offset,
5622 m, last->protection, must_wire);
5623 }
5624
5625 *page_list++ = VM_PAGE_NULL;
5626 assert(copy != VM_MAP_COPY_NULL);
5627 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
5628 if (--(copy->cpy_npages) == 0 &&
5629 vm_map_copy_has_cont(copy)) {
5630 vm_map_copy_t new_copy;
5631
5632 /*
5633 * Ok to unlock map because entry is
5634 * marked in_transition.
5635 */
5636 cont_invoked = TRUE;
5637 vm_map_unlock(dst_map);
5638 vm_map_copy_invoke_cont(copy, &new_copy, &result);
5639
5640 if (result == KERN_SUCCESS) {
5641
5642 /*
5643 * If we got back a copy with real pages,
5644 * steal them now. Either all of the
5645 * pages in the list are tabled or none
5646 * of them are; mixtures are not possible.
5647 *
5648 * Save original copy for consume on
5649 * success logic at end of routine.
5650 */
5651 if (copy != orig_copy)
5652 vm_map_copy_discard(copy);
5653
5654 if ((copy = new_copy) != VM_MAP_COPY_NULL) {
5655 page_list = &copy->cpy_page_list[0];
5656 if (!copy->cpy_page_loose)
5657 vm_map_copy_steal_pages(copy);
5658 }
5659 }
5660 else {
5661 /*
5662 * Continuation failed.
5663 */
5664 vm_map_lock(dst_map);
5665 goto error;
5666 }
5667
5668 vm_map_lock(dst_map);
5669 }
5670 }
5671
5672 *dst_addr = start + dst_offset;
5673
5674 /*
5675 * Clear the in transition bits. This is easy if we
5676 * didn't have a continuation.
5677 */
5678 error:
5679 needs_wakeup = FALSE;
5680 if (!cont_invoked) {
5681 /*
5682 * We didn't unlock the map, so nobody could
5683 * be waiting.
5684 */
5685 last->in_transition = FALSE;
5686 assert(!last->needs_wakeup);
5687 }
5688 else {
5689 if (!vm_map_lookup_entry(dst_map, start, &entry))
5690 panic("vm_map_copyout_page_list: missing entry");
5691
5692 /*
5693 * Clear transition bit for all constituent entries that
5694 * were in the original entry. Also check for waiters.
5695 */
5696 while ((entry != vm_map_to_entry(dst_map)) &&
5697 (entry->vme_start < end)) {
5698 assert(entry->in_transition);
5699 entry->in_transition = FALSE;
5700 if (entry->needs_wakeup) {
5701 entry->needs_wakeup = FALSE;
5702 needs_wakeup = TRUE;
5703 }
5704 entry = entry->vme_next;
5705 }
5706 }
5707
5708 if (result != KERN_SUCCESS)
5709 (void) vm_map_delete(dst_map, start, end, VM_MAP_NO_FLAGS);
5710
5711 vm_map_unlock(dst_map);
5712
5713 if (needs_wakeup)
5714 vm_map_entry_wakeup(dst_map);
5715
5716 /*
5717 * Consume on success logic.
5718 */
5719 if (copy != VM_MAP_COPY_NULL && copy != orig_copy) {
5720 zfree(vm_map_copy_zone, (vm_offset_t) copy);
5721 }
5722 if (result == KERN_SUCCESS) {
5723 assert(orig_copy != VM_MAP_COPY_NULL);
5724 assert(orig_copy->type == VM_MAP_COPY_PAGE_LIST);
5725 zfree(vm_map_copy_zone, (vm_offset_t) orig_copy);
5726 }
5727
5728 return(result);
5729 }
5730
5731 /*
5732 * Routine: vm_map_copyin
5733 *
5734 * Description:
5735 * Copy the specified region (src_addr, len) from the
5736 * source address space (src_map), possibly removing
5737 * the region from the source address space (src_destroy).
5738 *
5739 * Returns:
5740 * A vm_map_copy_t object (copy_result), suitable for
5741 * insertion into another address space (using vm_map_copyout),
5742 * copying over another address space region (using
5743 * vm_map_copy_overwrite). If the copy is unused, it
5744 * should be destroyed (using vm_map_copy_discard).
5745 *
5746 * In/out conditions:
5747 * The source map should not be locked on entry.
5748 */
5749
5750 typedef struct submap_map {
5751 vm_map_t parent_map;
5752 vm_offset_t base_start;
5753 vm_offset_t base_end;
5754 struct submap_map *next;
5755 } submap_map_t;
5756
5757 kern_return_t
5758 vm_map_copyin_common(
5759 vm_map_t src_map,
5760 vm_offset_t src_addr,
5761 vm_size_t len,
5762 boolean_t src_destroy,
5763 boolean_t src_volatile,
5764 vm_map_copy_t *copy_result, /* OUT */
5765 boolean_t use_maxprot)
5766 {
5767 extern int msg_ool_size_small;
5768
5769 vm_map_entry_t tmp_entry; /* Result of last map lookup --
5770 * in multi-level lookup, this
5771 * entry contains the actual
5772 * vm_object/offset.
5773 */
5774 register
5775 vm_map_entry_t new_entry = VM_MAP_ENTRY_NULL; /* Map entry for copy */
5776
5777 vm_offset_t src_start; /* Start of current entry --
5778 * where copy is taking place now
5779 */
5780 vm_offset_t src_end; /* End of entire region to be
5781 * copied */
5782 vm_offset_t base_start; /* submap fields to save offsets */
5783 /* in original map */
5784 vm_offset_t base_end;
5785 vm_map_t base_map=src_map;
5786 vm_map_entry_t base_entry;
5787 boolean_t map_share=FALSE;
5788 submap_map_t *parent_maps = NULL;
5789
5790 register
5791 vm_map_copy_t copy; /* Resulting copy */
5792 vm_offset_t copy_addr;
5793
5794 /*
5795 * Check for copies of zero bytes.
5796 */
5797
5798 if (len == 0) {
5799 *copy_result = VM_MAP_COPY_NULL;
5800 return(KERN_SUCCESS);
5801 }
5802
5803 /*
5804 * If the copy is sufficiently small, use a kernel buffer instead
5805 * of making a virtual copy. The theory being that the cost of
5806 * setting up VM (and taking C-O-W faults) dominates the copy costs
5807 * for small regions.
5808 */
5809 if ((len < msg_ool_size_small) && !use_maxprot)
5810 return vm_map_copyin_kernel_buffer(src_map, src_addr, len,
5811 src_destroy, copy_result);
5812
5813 /*
5814 * Compute start and end of region
5815 */
5816
5817 src_start = trunc_page(src_addr);
5818 src_end = round_page(src_addr + len);
5819
5820 XPR(XPR_VM_MAP, "vm_map_copyin_common map 0x%x addr 0x%x len 0x%x dest %d\n", (natural_t)src_map, src_addr, len, src_destroy, 0);
5821
5822 /*
5823 * Check that the end address doesn't overflow
5824 */
5825
5826 if (src_end <= src_start)
5827 if ((src_end < src_start) || (src_start != 0))
5828 return(KERN_INVALID_ADDRESS);
5829
5830 /*
5831 * Allocate a header element for the list.
5832 *
5833 * Use the start and end in the header to
5834 * remember the endpoints prior to rounding.
5835 */
5836
5837 copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
5838 vm_map_copy_first_entry(copy) =
5839 vm_map_copy_last_entry(copy) = vm_map_copy_to_entry(copy);
5840 copy->type = VM_MAP_COPY_ENTRY_LIST;
5841 copy->cpy_hdr.nentries = 0;
5842 copy->cpy_hdr.entries_pageable = TRUE;
5843
5844 copy->offset = src_addr;
5845 copy->size = len;
5846
5847 new_entry = vm_map_copy_entry_create(copy);
5848
5849 #define RETURN(x) \
5850 MACRO_BEGIN \
5851 vm_map_unlock(src_map); \
5852 if (new_entry != VM_MAP_ENTRY_NULL) \
5853 vm_map_copy_entry_dispose(copy,new_entry); \
5854 vm_map_copy_discard(copy); \
5855 { \
5856 submap_map_t *ptr; \
5857 \
5858 for(ptr = parent_maps; ptr != NULL; ptr = parent_maps) { \
5859 parent_maps=parent_maps->next; \
5860 kfree((vm_offset_t)ptr, sizeof(submap_map_t)); \
5861 } \
5862 } \
5863 MACRO_RETURN(x); \
5864 MACRO_END
5865
5866 /*
5867 * Find the beginning of the region.
5868 */
5869
5870 vm_map_lock(src_map);
5871
5872 if (!vm_map_lookup_entry(src_map, src_start, &tmp_entry))
5873 RETURN(KERN_INVALID_ADDRESS);
5874 if(!tmp_entry->is_sub_map) {
5875 vm_map_clip_start(src_map, tmp_entry, src_start);
5876 }
5877 /* set for later submap fix-up */
5878 copy_addr = src_start;
5879
5880 /*
5881 * Go through entries until we get to the end.
5882 */
5883
5884 while (TRUE) {
5885 register
5886 vm_map_entry_t src_entry = tmp_entry; /* Top-level entry */
5887 vm_size_t src_size; /* Size of source
5888 * map entry (in both
5889 * maps)
5890 */
5891
5892 register
5893 vm_object_t src_object; /* Object to copy */
5894 vm_object_offset_t src_offset;
5895
5896 boolean_t src_needs_copy; /* Should source map
5897 * be made read-only
5898 * for copy-on-write?
5899 */
5900
5901 boolean_t new_entry_needs_copy; /* Will new entry be COW? */
5902
5903 boolean_t was_wired; /* Was source wired? */
5904 vm_map_version_t version; /* Version before locks
5905 * dropped to make copy
5906 */
5907 kern_return_t result; /* Return value from
5908 * copy_strategically.
5909 */
5910 while(tmp_entry->is_sub_map) {
5911 vm_size_t submap_len;
5912 submap_map_t *ptr;
5913
5914 ptr = (submap_map_t *)kalloc(sizeof(submap_map_t));
5915 ptr->next = parent_maps;
5916 parent_maps = ptr;
5917 ptr->parent_map = src_map;
5918 ptr->base_start = src_start;
5919 ptr->base_end = src_end;
5920 submap_len = tmp_entry->vme_end - src_start;
5921 if(submap_len > (src_end-src_start))
5922 submap_len = src_end-src_start;
5923 ptr->base_start += submap_len;
5924
5925 src_start -= tmp_entry->vme_start;
5926 src_start += tmp_entry->offset;
5927 src_end = src_start + submap_len;
5928 src_map = tmp_entry->object.sub_map;
5929 vm_map_lock(src_map);
5930 vm_map_unlock(ptr->parent_map);
5931 if (!vm_map_lookup_entry(
5932 src_map, src_start, &tmp_entry))
5933 RETURN(KERN_INVALID_ADDRESS);
5934 map_share = TRUE;
5935 if(!tmp_entry->is_sub_map)
5936 vm_map_clip_start(src_map, tmp_entry, src_start);
5937 src_entry = tmp_entry;
5938 }
5939 /*
5940 * Create a new address map entry to hold the result.
5941 * Fill in the fields from the appropriate source entries.
5942 * We must unlock the source map to do this if we need
5943 * to allocate a map entry.
5944 */
5945 if (new_entry == VM_MAP_ENTRY_NULL) {
5946 version.main_timestamp = src_map->timestamp;
5947 vm_map_unlock(src_map);
5948
5949 new_entry = vm_map_copy_entry_create(copy);
5950
5951 vm_map_lock(src_map);
5952 if ((version.main_timestamp + 1) != src_map->timestamp) {
5953 if (!vm_map_lookup_entry(src_map, src_start,
5954 &tmp_entry)) {
5955 RETURN(KERN_INVALID_ADDRESS);
5956 }
5957 vm_map_clip_start(src_map, tmp_entry, src_start);
5958 continue; /* restart w/ new tmp_entry */
5959 }
5960 }
5961
5962 /*
5963 * Verify that the region can be read.
5964 */
5965 if (((src_entry->protection & VM_PROT_READ) == VM_PROT_NONE &&
5966 !use_maxprot) ||
5967 (src_entry->max_protection & VM_PROT_READ) == 0)
5968 RETURN(KERN_PROTECTION_FAILURE);
5969
5970 /*
5971 * Clip against the endpoints of the entire region.
5972 */
5973
5974 vm_map_clip_end(src_map, src_entry, src_end);
5975
5976 src_size = src_entry->vme_end - src_start;
5977 src_object = src_entry->object.vm_object;
5978 src_offset = src_entry->offset;
5979 was_wired = (src_entry->wired_count != 0);
5980
5981 vm_map_entry_copy(new_entry, src_entry);
5982 new_entry->use_pmap = FALSE; /* clr address space specifics */
5983
5984 /*
5985 * Attempt non-blocking copy-on-write optimizations.
5986 */
5987
5988 if (src_destroy &&
5989 (src_object == VM_OBJECT_NULL ||
5990 (src_object->internal && !src_object->true_share
5991 && !map_share))) {
5992 /*
5993 * If we are destroying the source, and the object
5994 * is internal, we can move the object reference
5995 * from the source to the copy. The copy is
5996 * copy-on-write only if the source is.
5997 * We make another reference to the object, because
5998 * destroying the source entry will deallocate it.
5999 */
6000 vm_object_reference(src_object);
6001
6002 /*
6003 * Copy is always unwired. vm_map_copy_entry
6004 * set its wired count to zero.
6005 */
6006
6007 goto CopySuccessful;
6008 }
6009
6010
6011 RestartCopy:
6012 XPR(XPR_VM_MAP, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
6013 src_object, new_entry, new_entry->object.vm_object,
6014 was_wired, 0);
6015 if (!was_wired &&
6016 vm_object_copy_quickly(
6017 &new_entry->object.vm_object,
6018 src_offset,
6019 src_size,
6020 &src_needs_copy,
6021 &new_entry_needs_copy)) {
6022
6023 new_entry->needs_copy = new_entry_needs_copy;
6024
6025 /*
6026 * Handle copy-on-write obligations
6027 */
6028
6029 if (src_needs_copy && !tmp_entry->needs_copy) {
6030 if (tmp_entry->is_shared ||
6031 tmp_entry->object.vm_object->true_share ||
6032 map_share) {
6033 vm_map_unlock(src_map);
6034 new_entry->object.vm_object =
6035 vm_object_copy_delayed(
6036 src_object,
6037 src_offset,
6038 src_size);
6039 /* dec ref gained in copy_quickly */
6040 vm_object_lock(src_object);
6041 src_object->ref_count--;
6042 vm_object_res_deallocate(src_object);
6043 vm_object_unlock(src_object);
6044 vm_map_lock(src_map);
6045 /*
6046 * it turns out that we have
6047 * finished our copy. No matter
6048 * what the state of the map
6049 * we will lock it again here
6050 * knowing that if there is
6051 * additional data to copy
6052 * it will be checked at
6053 * the top of the loop
6054 *
6055 * Don't do timestamp check
6056 */
6057
6058 } else {
6059 vm_object_pmap_protect(
6060 src_object,
6061 src_offset,
6062 src_size,
6063 (src_entry->is_shared ?
6064 PMAP_NULL
6065 : src_map->pmap),
6066 src_entry->vme_start,
6067 src_entry->protection &
6068 ~VM_PROT_WRITE);
6069
6070 tmp_entry->needs_copy = TRUE;
6071 }
6072 }
6073
6074 /*
6075 * The map has never been unlocked, so it's safe
6076 * to move to the next entry rather than doing
6077 * another lookup.
6078 */
6079
6080 goto CopySuccessful;
6081 }
6082
6083 new_entry->needs_copy = FALSE;
6084
6085 /*
6086 * Take an object reference, so that we may
6087 * release the map lock(s).
6088 */
6089
6090 assert(src_object != VM_OBJECT_NULL);
6091 vm_object_reference(src_object);
6092
6093 /*
6094 * Record the timestamp for later verification.
6095 * Unlock the map.
6096 */
6097
6098 version.main_timestamp = src_map->timestamp;
6099 vm_map_unlock(src_map);
6100
6101 /*
6102 * Perform the copy
6103 */
6104
6105 if (was_wired) {
6106 vm_object_lock(src_object);
6107 result = vm_object_copy_slowly(
6108 src_object,
6109 src_offset,
6110 src_size,
6111 THREAD_UNINT,
6112 &new_entry->object.vm_object);
6113 new_entry->offset = 0;
6114 new_entry->needs_copy = FALSE;
6115 } else {
6116 result = vm_object_copy_strategically(src_object,
6117 src_offset,
6118 src_size,
6119 &new_entry->object.vm_object,
6120 &new_entry->offset,
6121 &new_entry_needs_copy);
6122
6123 new_entry->needs_copy = new_entry_needs_copy;
6124
6125 }
6126
6127 if (result != KERN_SUCCESS &&
6128 result != KERN_MEMORY_RESTART_COPY) {
6129 vm_map_lock(src_map);
6130 RETURN(result);
6131 }
6132
6133 /*
6134 * Throw away the extra reference
6135 */
6136
6137 vm_object_deallocate(src_object);
6138
6139 /*
6140 * Verify that the map has not substantially
6141 * changed while the copy was being made.
6142 */
6143
6144 vm_map_lock(src_map); /* Increments timestamp once! */
6145
6146 if ((version.main_timestamp + 1) == src_map->timestamp)
6147 goto VerificationSuccessful;
6148
6149 /*
6150 * Simple version comparison failed.
6151 *
6152 * Retry the lookup and verify that the
6153 * same object/offset are still present.
6154 *
6155 * [Note: a memory manager that colludes with
6156 * the calling task can detect that we have
6157 * cheated. While the map was unlocked, the
6158 * mapping could have been changed and restored.]
6159 */
6160
6161 if (!vm_map_lookup_entry(src_map, src_start, &tmp_entry)) {
6162 RETURN(KERN_INVALID_ADDRESS);
6163 }
6164
6165 src_entry = tmp_entry;
6166 vm_map_clip_start(src_map, src_entry, src_start);
6167
6168 if ((src_entry->protection & VM_PROT_READ == VM_PROT_NONE &&
6169 !use_maxprot) ||
6170 src_entry->max_protection & VM_PROT_READ == 0)
6171 goto VerificationFailed;
6172
6173 if (src_entry->vme_end < new_entry->vme_end)
6174 src_size = (new_entry->vme_end = src_entry->vme_end) - src_start;
6175
6176 if ((src_entry->object.vm_object != src_object) ||
6177 (src_entry->offset != src_offset) ) {
6178
6179 /*
6180 * Verification failed.
6181 *
6182 * Start over with this top-level entry.
6183 */
6184
6185 VerificationFailed: ;
6186
6187 vm_object_deallocate(new_entry->object.vm_object);
6188 tmp_entry = src_entry;
6189 continue;
6190 }
6191
6192 /*
6193 * Verification succeeded.
6194 */
6195
6196 VerificationSuccessful: ;
6197
6198 if (result == KERN_MEMORY_RESTART_COPY)
6199 goto RestartCopy;
6200
6201 /*
6202 * Copy succeeded.
6203 */
6204
6205 CopySuccessful: ;
6206
6207 /*
6208 * Link in the new copy entry.
6209 */
6210
6211 vm_map_copy_entry_link(copy, vm_map_copy_last_entry(copy),
6212 new_entry);
6213
6214 /*
6215 * Determine whether the entire region
6216 * has been copied.
6217 */
6218 src_start = new_entry->vme_end;
6219 new_entry = VM_MAP_ENTRY_NULL;
6220 while ((src_start >= src_end) && (src_end != 0)) {
6221 if (src_map != base_map) {
6222 submap_map_t *ptr;
6223
6224 ptr = parent_maps;
6225 assert(ptr != NULL);
6226 parent_maps = parent_maps->next;
6227 vm_map_lock(ptr->parent_map);
6228 vm_map_unlock(src_map);
6229 src_map = ptr->parent_map;
6230 src_start = ptr->base_start;
6231 src_end = ptr->base_end;
6232 if ((src_end > src_start) &&
6233 !vm_map_lookup_entry(
6234 src_map, src_start, &tmp_entry))
6235 RETURN(KERN_INVALID_ADDRESS);
6236 kfree((vm_offset_t)ptr, sizeof(submap_map_t));
6237 if(parent_maps == NULL)
6238 map_share = FALSE;
6239 src_entry = tmp_entry->vme_prev;
6240 } else
6241 break;
6242 }
6243 if ((src_start >= src_end) && (src_end != 0))
6244 break;
6245
6246 /*
6247 * Verify that there are no gaps in the region
6248 */
6249
6250 tmp_entry = src_entry->vme_next;
6251 if ((tmp_entry->vme_start != src_start) ||
6252 (tmp_entry == vm_map_to_entry(src_map)))
6253 RETURN(KERN_INVALID_ADDRESS);
6254 }
6255
6256 /*
6257 * If the source should be destroyed, do it now, since the
6258 * copy was successful.
6259 */
6260 if (src_destroy) {
6261 (void) vm_map_delete(src_map,
6262 trunc_page(src_addr),
6263 src_end,
6264 (src_map == kernel_map) ?
6265 VM_MAP_REMOVE_KUNWIRE :
6266 VM_MAP_NO_FLAGS);
6267 }
6268
6269 vm_map_unlock(src_map);
6270
6271 /* Fix-up start and end points in copy. This is necessary */
6272 /* when the various entries in the copy object were picked */
6273 /* up from different sub-maps */
6274
6275 tmp_entry = vm_map_copy_first_entry(copy);
6276 while (tmp_entry != vm_map_copy_to_entry(copy)) {
6277 tmp_entry->vme_end = copy_addr +
6278 (tmp_entry->vme_end - tmp_entry->vme_start);
6279 tmp_entry->vme_start = copy_addr;
6280 copy_addr += tmp_entry->vme_end - tmp_entry->vme_start;
6281 tmp_entry = (struct vm_map_entry *)tmp_entry->vme_next;
6282 }
6283
6284 *copy_result = copy;
6285 return(KERN_SUCCESS);
6286
6287 #undef RETURN
6288 }
6289
6290 /*
6291 * vm_map_copyin_object:
6292 *
6293 * Create a copy object from an object.
6294 * Our caller donates an object reference.
6295 */
6296
6297 kern_return_t
6298 vm_map_copyin_object(
6299 vm_object_t object,
6300 vm_object_offset_t offset, /* offset of region in object */
6301 vm_object_size_t size, /* size of region in object */
6302 vm_map_copy_t *copy_result) /* OUT */
6303 {
6304 vm_map_copy_t copy; /* Resulting copy */
6305
6306 /*
6307 * We drop the object into a special copy object
6308 * that contains the object directly.
6309 */
6310
6311 copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
6312 copy->type = VM_MAP_COPY_OBJECT;
6313 copy->cpy_object = object;
6314 copy->cpy_index = 0;
6315 copy->offset = offset;
6316 copy->size = size;
6317
6318 *copy_result = copy;
6319 return(KERN_SUCCESS);
6320 }
6321
6322 /*
6323 * vm_map_copyin_page_list_cont:
6324 *
6325 * Continuation routine for vm_map_copyin_page_list.
6326 *
6327 * If vm_map_copyin_page_list can't fit the entire vm range
6328 * into a single page list object, it creates a continuation.
6329 * When the target of the operation has used the pages in the
6330 * initial page list, it invokes the continuation, which calls
6331 * this routine. If an error happens, the continuation is aborted
6332 * (abort arg to this routine is TRUE). To avoid deadlocks, the
6333 * pages are discarded from the initial page list before invoking
6334 * the continuation.
6335 *
6336 * NOTE: This is not the same sort of continuation used by
6337 * the scheduler.
6338 */
6339
6340 kern_return_t
6341 vm_map_copyin_page_list_cont(
6342 vm_map_copyin_args_t cont_args,
6343 vm_map_copy_t *copy_result) /* OUT */
6344 {
6345 kern_return_t result = KERN_SUCCESS;
6346 register boolean_t abort, src_destroy, src_destroy_only;
6347
6348 /*
6349 * Check for cases that only require memory destruction.
6350 */
6351 abort = (copy_result == (vm_map_copy_t *) 0);
6352 src_destroy = (cont_args->destroy_len != (vm_size_t) 0);
6353 src_destroy_only = (cont_args->src_len == (vm_size_t) 0);
6354
6355 if (abort || src_destroy_only) {
6356 if (src_destroy)
6357 result = vm_map_remove(cont_args->map,
6358 cont_args->destroy_addr,
6359 cont_args->destroy_addr + cont_args->destroy_len,
6360 VM_MAP_NO_FLAGS);
6361 if (!abort)
6362 *copy_result = VM_MAP_COPY_NULL;
6363 }
6364 else {
6365 result = vm_map_copyin_page_list(cont_args->map,
6366 cont_args->src_addr, cont_args->src_len,
6367 cont_args->options, copy_result, TRUE);
6368
6369 if (src_destroy &&
6370 (cont_args->options & VM_MAP_COPYIN_OPT_STEAL_PAGES) &&
6371 vm_map_copy_has_cont(*copy_result)) {
6372 vm_map_copyin_args_t new_args;
6373 /*
6374 * Transfer old destroy info.
6375 */
6376 new_args = (vm_map_copyin_args_t)
6377 (*copy_result)->cpy_cont_args;
6378 new_args->destroy_addr = cont_args->destroy_addr;
6379 new_args->destroy_len = cont_args->destroy_len;
6380 }
6381 }
6382
6383 vm_map_deallocate(cont_args->map);
6384 kfree((vm_offset_t)cont_args, sizeof(vm_map_copyin_args_data_t));
6385
6386 return(result);
6387 }
6388
6389 /*
6390 * vm_map_copyin_page_list:
6391 *
6392 * This is a variant of vm_map_copyin that copies in a list of pages.
6393 * If steal_pages is TRUE, the pages are only in the returned list.
6394 * If steal_pages is FALSE, the pages are busy and still in their
6395 * objects. A continuation may be returned if not all the pages fit:
6396 * the recipient of this copy_result must be prepared to deal with it.
6397 */
6398
6399 kern_return_t
6400 vm_map_copyin_page_list(
6401 vm_map_t src_map,
6402 vm_offset_t src_addr,
6403 vm_size_t len,
6404 int options,
6405 vm_map_copy_t *copy_result, /* OUT */
6406 boolean_t is_cont)
6407 {
6408 vm_map_entry_t src_entry;
6409 vm_page_t m;
6410 vm_offset_t src_start;
6411 vm_offset_t src_end;
6412 vm_size_t src_size;
6413 register vm_object_t src_object;
6414 register vm_object_offset_t src_offset;
6415 vm_object_offset_t src_last_offset;
6416 register vm_map_copy_t copy; /* Resulting copy */
6417 kern_return_t result = KERN_SUCCESS;
6418 boolean_t need_map_lookup;
6419 vm_map_copyin_args_t cont_args;
6420 kern_return_t error_code;
6421 vm_prot_t prot;
6422 boolean_t wired;
6423 boolean_t no_zero_fill;
6424
6425 submap_map_t *parent_maps = NULL;
6426 vm_map_t base_map = src_map;
6427
6428 prot = (options & VM_MAP_COPYIN_OPT_VM_PROT);
6429 no_zero_fill = (options & VM_MAP_COPYIN_OPT_NO_ZERO_FILL);
6430
6431 /*
6432 * If steal_pages is FALSE, this leaves busy pages in
6433 * the object. A continuation must be used if src_destroy
6434 * is true in this case (!steal_pages && src_destroy).
6435 *
6436 * XXX Still have a more general problem of what happens
6437 * XXX if the same page occurs twice in a list. Deadlock
6438 * XXX can happen if vm_fault_page was called. A
6439 * XXX possible solution is to use a continuation if vm_fault_page
6440 * XXX is called and we cross a map entry boundary.
6441 */
6442
6443 /*
6444 * Check for copies of zero bytes.
6445 */
6446
6447 if (len == 0) {
6448 *copy_result = VM_MAP_COPY_NULL;
6449 return(KERN_SUCCESS);
6450 }
6451
6452 /*
6453 * Compute start and end of region
6454 */
6455
6456 src_start = trunc_page(src_addr);
6457 src_end = round_page(src_addr + len);
6458
6459 /*
6460 * If the region is not page aligned, override the no_zero_fill
6461 * argument.
6462 */
6463
6464 if (options & VM_MAP_COPYIN_OPT_NO_ZERO_FILL) {
6465 if (!page_aligned(src_addr) || !page_aligned(src_addr +len))
6466 options &= ~VM_MAP_COPYIN_OPT_NO_ZERO_FILL;
6467 }
6468
6469 /*
6470 * Check that the end address doesn't overflow
6471 */
6472
6473 if (src_end <= src_start && (src_end < src_start || src_start != 0)) {
6474 return KERN_INVALID_ADDRESS;
6475 }
6476
6477 /*
6478 * Allocate a header element for the page list.
6479 *
6480 * Record original offset and size, as caller may not
6481 * be page-aligned.
6482 */
6483
6484 copy = (vm_map_copy_t) zalloc(vm_map_copy_zone);
6485 copy->type = VM_MAP_COPY_PAGE_LIST;
6486 copy->cpy_npages = 0;
6487 copy->cpy_page_loose = FALSE;
6488 copy->offset = src_addr;
6489 copy->size = len;
6490 copy->cpy_cont = VM_MAP_COPY_CONT_NULL;
6491 copy->cpy_cont_args = VM_MAP_COPYIN_ARGS_NULL;
6492
6493 /*
6494 * Find the beginning of the region.
6495 */
6496
6497 do_map_lookup:
6498
6499 vm_map_lock(src_map);
6500
6501 if (!vm_map_lookup_entry(src_map, src_start, &src_entry)) {
6502 result = KERN_INVALID_ADDRESS;
6503 goto error;
6504 }
6505 need_map_lookup = FALSE;
6506
6507 /*
6508 * Go through entries until we get to the end.
6509 */
6510
6511 while (TRUE) {
6512 if ((src_entry->protection & prot) != prot) {
6513 result = KERN_PROTECTION_FAILURE;
6514 goto error;
6515 }
6516
6517 /* translate down through submaps to find the target entry */
6518 while(src_entry->is_sub_map) {
6519 vm_size_t submap_len;
6520 submap_map_t *ptr;
6521
6522 ptr = (submap_map_t *)kalloc(sizeof(submap_map_t));
6523 ptr->next = parent_maps;
6524 parent_maps = ptr;
6525 ptr->parent_map = src_map;
6526 ptr->base_start = src_start;
6527 ptr->base_end = src_end;
6528 submap_len = src_entry->vme_end - src_entry->vme_start;
6529 if(submap_len > (src_end-src_start))
6530 submap_len = src_end-src_start;
6531 ptr->base_start += submap_len;
6532
6533 src_start -= src_entry->vme_start;
6534 src_start += src_entry->offset;
6535 src_end = src_start + submap_len;
6536 src_map = src_entry->object.sub_map;
6537 vm_map_lock(src_map);
6538 vm_map_unlock(ptr->parent_map);
6539 if (!vm_map_lookup_entry(
6540 src_map, src_start, &src_entry)) {
6541 result = KERN_INVALID_ADDRESS;
6542 goto error;
6543 }
6544 vm_map_clip_start(src_map, src_entry, src_start);
6545 }
6546
6547 wired = (src_entry->wired_count != 0);
6548
6549 if (src_end > src_entry->vme_end)
6550 src_size = src_entry->vme_end - src_start;
6551 else
6552 src_size = src_end - src_start;
6553
6554 src_object = src_entry->object.vm_object;
6555
6556 /*
6557 * If src_object is NULL, allocate it now;
6558 * we're going to fault on it shortly.
6559 */
6560 if (src_object == VM_OBJECT_NULL) {
6561 src_object = vm_object_allocate((vm_size_t)
6562 src_entry->vme_end -
6563 src_entry->vme_start);
6564 src_entry->object.vm_object = src_object;
6565 }
6566 else if (src_entry->needs_copy && (prot & VM_PROT_WRITE)) {
6567 vm_object_shadow(
6568 &src_entry->object.vm_object,
6569 &src_entry->offset,
6570 (vm_size_t) (src_entry->vme_end -
6571 src_entry->vme_start));
6572
6573 src_entry->needs_copy = FALSE;
6574
6575 /* reset src_object */
6576 src_object = src_entry->object.vm_object;
6577 }
6578
6579 /*
6580 * calculate src_offset now, since vm_object_shadow
6581 * may have changed src_entry->offset.
6582 */
6583 src_offset = src_entry->offset + (src_start - src_entry->vme_start);
6584
6585 /*
6586 * Iterate over pages. Fault in ones that aren't present.
6587 */
6588 src_last_offset = src_offset + src_size;
6589 for (; (src_offset < src_last_offset);
6590 src_offset += PAGE_SIZE_64, src_start += PAGE_SIZE) {
6591
6592 if (copy->cpy_npages == VM_MAP_COPY_PAGE_LIST_MAX) {
6593 vm_offset_t src_delta;
6594 make_continuation:
6595 /*
6596 * At this point we have the max number of
6597 * pages busy for this thread that we're
6598 * willing to allow. Stop here and record
6599 * arguments for the remainder. Note:
6600 * this means that this routine isn't atomic,
6601 * but that's the breaks. Note that only
6602 * the first vm_map_copy_t that comes back
6603 * from this routine has the right offset
6604 * and size; those from continuations are
6605 * page rounded, and short by the amount
6606 * already done.
6607 *
6608 * Reset src_end so the src_destroy
6609 * code at the bottom doesn't do
6610 * something stupid.
6611 */
6612
6613 src_delta = src_end - src_start;
6614 while (src_map != base_map) {
6615 submap_map_t *ptr;
6616
6617 if(!need_map_lookup) {
6618 vm_map_unlock(src_map);
6619 }
6620 ptr = parent_maps;
6621 assert(ptr != NULL);
6622 parent_maps = parent_maps->next;
6623 src_map = ptr->parent_map;
6624 src_start = ptr->base_start - src_delta;
6625 src_delta = ptr->base_end - src_start;
6626 kfree((vm_offset_t)ptr, sizeof(submap_map_t));
6627
6628 need_map_lookup = TRUE;
6629 }
6630 src_end = src_start;
6631
6632
6633 cont_args = (vm_map_copyin_args_t)
6634 kalloc(sizeof(vm_map_copyin_args_data_t));
6635 cont_args->map = src_map;
6636 vm_map_reference(src_map);
6637 cont_args->src_addr = src_start;
6638 cont_args->src_len = len - (src_start - src_addr);
6639 if (options & VM_MAP_COPYIN_OPT_SRC_DESTROY) {
6640 cont_args->destroy_addr = cont_args->src_addr;
6641 cont_args->destroy_len = cont_args->src_len;
6642 } else {
6643 cont_args->destroy_addr = (vm_offset_t) 0;
6644 cont_args->destroy_len = (vm_offset_t) 0;
6645 }
6646 cont_args->options = options;
6647
6648 copy->cpy_cont_args = cont_args;
6649 copy->cpy_cont = vm_map_copyin_page_list_cont;
6650
6651 break;
6652 }
6653
6654 /*
6655 * Try to find the page of data. Have to
6656 * fault it in if there's no page, or something
6657 * going on with the page, or the object has
6658 * a copy object.
6659 */
6660 vm_object_lock(src_object);
6661 vm_object_paging_begin(src_object);
6662 if (((m = vm_page_lookup(src_object, src_offset)) !=
6663 VM_PAGE_NULL) &&
6664 !m->busy && !m->fictitious && !m->unusual &&
6665 ((prot & VM_PROT_WRITE) == 0 ||
6666 (m->object->copy == VM_OBJECT_NULL))) {
6667
6668 if (!m->absent &&
6669 !(options & VM_MAP_COPYIN_OPT_STEAL_PAGES)) {
6670
6671 /*
6672 * The page is present and will not be
6673 * replaced, prep it. Thus allowing
6674 * mutiple access on this page
6675 */
6676 kern_return_t kr;
6677
6678 kr = vm_page_prep(m);
6679 assert(kr == KERN_SUCCESS);
6680 kr = vm_page_pin(m);
6681 assert(kr == KERN_SUCCESS);
6682 } else {
6683 /*
6684 * This is the page. Mark it busy
6685 * and keep the paging reference on
6686 * the object whilst we do our thing.
6687 */
6688
6689 m->busy = TRUE;
6690 }
6691 } else {
6692 vm_prot_t result_prot;
6693 vm_page_t top_page;
6694 kern_return_t kr;
6695 boolean_t data_supply;
6696
6697 /*
6698 * Have to fault the page in; must
6699 * unlock the map to do so. While
6700 * the map is unlocked, anything
6701 * can happen, we must lookup the
6702 * map entry before continuing.
6703 */
6704 vm_map_unlock(src_map);
6705 need_map_lookup = TRUE;
6706 data_supply = src_object->silent_overwrite &&
6707 (prot & VM_PROT_WRITE) &&
6708 src_start >= src_addr &&
6709 src_start + PAGE_SIZE <=
6710 src_addr + len;
6711
6712 retry:
6713 result_prot = prot;
6714
6715 XPR(XPR_VM_FAULT,
6716 "vm_map_copyin_page_list -> vm_fault_page\n",
6717 0,0,0,0,0);
6718 kr = vm_fault_page(src_object, src_offset,
6719 prot, FALSE, THREAD_UNINT,
6720 src_entry->offset,
6721 src_entry->offset +
6722 (src_entry->vme_end -
6723 src_entry->vme_start),
6724 VM_BEHAVIOR_SEQUENTIAL,
6725 &result_prot, &m, &top_page,
6726 (int *)0,
6727 &error_code,
6728 options & VM_MAP_COPYIN_OPT_NO_ZERO_FILL,
6729 data_supply);
6730 /*
6731 * Cope with what happened.
6732 */
6733 switch (kr) {
6734 case VM_FAULT_SUCCESS:
6735
6736 /*
6737 * If we lost write access,
6738 * try again.
6739 */
6740 if ((prot & VM_PROT_WRITE) &&
6741 !(result_prot & VM_PROT_WRITE)) {
6742 vm_object_lock(src_object);
6743 vm_object_paging_begin(src_object);
6744 goto retry;
6745 }
6746 break;
6747 case VM_FAULT_MEMORY_SHORTAGE:
6748 VM_PAGE_WAIT();
6749 /* fall thru */
6750 case VM_FAULT_INTERRUPTED: /* ??? */
6751 case VM_FAULT_RETRY:
6752 vm_object_lock(src_object);
6753 vm_object_paging_begin(src_object);
6754 goto retry;
6755 case VM_FAULT_FICTITIOUS_SHORTAGE:
6756 vm_page_more_fictitious();
6757 vm_object_lock(src_object);
6758 vm_object_paging_begin(src_object);
6759 goto retry;
6760 case VM_FAULT_MEMORY_ERROR:
6761 /*
6762 * Something broke. If this
6763 * is a continuation, return
6764 * a partial result if possible,
6765 * else fail the whole thing.
6766 * In the continuation case, the
6767 * next continuation call will
6768 * get this error if it persists.
6769 */
6770 vm_map_lock(src_map);
6771 if (is_cont &&
6772 copy->cpy_npages != 0)
6773 goto make_continuation;
6774
6775 result = error_code ? error_code : KERN_MEMORY_ERROR;
6776 goto error;
6777 }
6778
6779 if (top_page != VM_PAGE_NULL) {
6780 vm_object_lock(src_object);
6781 VM_PAGE_FREE(top_page);
6782 vm_object_paging_end(src_object);
6783 vm_object_unlock(src_object);
6784 }
6785
6786 }
6787
6788 /*
6789 * The page is busy, its object is locked, and
6790 * we have a paging reference on it. Either
6791 * the map is locked, or need_map_lookup is
6792 * TRUE.
6793 */
6794
6795 /*
6796 * Put the page in the page list.
6797 */
6798 copy->cpy_page_list[copy->cpy_npages++] = m;
6799 vm_object_unlock(m->object);
6800
6801 /*
6802 * Pmap enter support. Only used for
6803 * device I/O for colocated server.
6804 *
6805 * WARNING: This code assumes that this
6806 * option is only used for well behaved
6807 * memory. If the mapping has changed,
6808 * the following code will make mistakes.
6809 *
6810 * XXXO probably ought to do pmap_extract first,
6811 * XXXO to avoid needless pmap_enter, but this
6812 * XXXO can't detect protection mismatch??
6813 */
6814
6815 if (options & VM_MAP_COPYIN_OPT_PMAP_ENTER) {
6816 /*
6817 * XXX Only used on kernel map.
6818 * XXX Must not remove VM_PROT_WRITE on
6819 * XXX an I/O only requiring VM_PROT_READ
6820 * XXX as another I/O may be active on same page
6821 * XXX assume that if mapping exists, it must
6822 * XXX have the equivalent of at least VM_PROT_READ,
6823 * XXX but don't assume it has VM_PROT_WRITE as the
6824 * XXX pmap might not all the rights of the object
6825 */
6826 assert(vm_map_pmap(src_map) == kernel_pmap);
6827
6828 if ((prot & VM_PROT_WRITE) ||
6829 (pmap_extract(vm_map_pmap(src_map),
6830 src_start) != m->phys_addr))
6831
6832 PMAP_ENTER(vm_map_pmap(src_map), src_start,
6833 m, prot, wired);
6834 }
6835 if(need_map_lookup) {
6836 need_map_lookup = FALSE;
6837 vm_map_lock(src_map);
6838 if (!vm_map_lookup_entry(src_map, src_start, &src_entry)) {
6839 result = KERN_INVALID_ADDRESS;
6840 goto error;
6841 }
6842 }
6843 }
6844
6845 /*
6846 * Verify that there are no gaps in the region
6847 */
6848 src_start = src_entry->vme_end;
6849 if (src_start < src_end) {
6850 src_entry = src_entry->vme_next;
6851 if (need_map_lookup) {
6852 need_map_lookup = FALSE;
6853 vm_map_lock(src_map);
6854 if(!vm_map_lookup_entry(src_map,
6855 src_start, &src_entry)) {
6856 result = KERN_INVALID_ADDRESS;
6857 goto error;
6858 }
6859 } else if (src_entry->vme_start != src_start) {
6860 result = KERN_INVALID_ADDRESS;
6861 goto error;
6862 }
6863 }
6864
6865 /*
6866 * DETERMINE whether the entire region
6867 * has been copied.
6868 */
6869
6870 while ((src_start >= src_end) && (src_end != 0)) {
6871 if (src_map != base_map) {
6872 submap_map_t *ptr;
6873
6874 ptr = parent_maps;
6875 assert(ptr != NULL);
6876 parent_maps = parent_maps->next;
6877 src_start = ptr->base_start;
6878 src_end = ptr->base_end;
6879 if(need_map_lookup) {
6880 need_map_lookup = FALSE;
6881 }
6882 else {
6883 vm_map_unlock(src_map);
6884 }
6885 src_map = ptr->parent_map;
6886 vm_map_lock(src_map);
6887 if((src_start < src_end) &&
6888 (!vm_map_lookup_entry(ptr->parent_map,
6889 src_start, &src_entry))) {
6890 result = KERN_INVALID_ADDRESS;
6891 kfree((vm_offset_t)ptr, sizeof(submap_map_t));
6892 goto error;
6893 }
6894 kfree((vm_offset_t)ptr, sizeof(submap_map_t));
6895 } else
6896 break;
6897 }
6898 if ((src_start >= src_end) && (src_end != 0)) {
6899 if (need_map_lookup)
6900 vm_map_lock(src_map);
6901 break;
6902 }
6903
6904 }
6905
6906 /*
6907 * If steal_pages is true, make sure all
6908 * pages in the copy are not in any object
6909 * We try to remove them from the original
6910 * object, but we may have to copy them.
6911 *
6912 * At this point every page in the list is busy
6913 * and holds a paging reference to its object.
6914 * When we're done stealing, every page is busy,
6915 * and in no object (m->tabled == FALSE).
6916 */
6917 src_start = trunc_page(src_addr);
6918 if (options & VM_MAP_COPYIN_OPT_STEAL_PAGES) {
6919 register int i;
6920 vm_offset_t page_vaddr;
6921 vm_offset_t unwire_end;
6922 vm_offset_t map_entry_end;
6923 boolean_t share_map = FALSE;
6924
6925 unwire_end = src_start;
6926 map_entry_end = src_start;
6927 for (i = 0; i < copy->cpy_npages; i++) {
6928
6929
6930 /*
6931 * Remove the page from its object if it
6932 * can be stolen. It can be stolen if:
6933 *
6934 * (1) The source is being destroyed,
6935 * the object is internal (hence
6936 * temporary), and not shared.
6937 * (2) The page is not precious.
6938 *
6939 * The not shared check consists of two
6940 * parts: (a) there are no objects that
6941 * shadow this object. (b) it is not the
6942 * object in any shared map entries (i.e.,
6943 * use_shared_copy is not set).
6944 *
6945 * The first check (a) means that we can't
6946 * steal pages from objects that are not
6947 * at the top of their shadow chains. This
6948 * should not be a frequent occurrence.
6949 *
6950 * Stealing wired pages requires telling the
6951 * pmap module to let go of them.
6952 *
6953 * NOTE: stealing clean pages from objects
6954 * whose mappings survive requires a call to
6955 * the pmap module. Maybe later.
6956 */
6957 m = copy->cpy_page_list[i];
6958 src_object = m->object;
6959 vm_object_lock(src_object);
6960
6961 page_vaddr = src_start + (i * PAGE_SIZE);
6962 if(page_vaddr > map_entry_end) {
6963 if (!vm_map_lookup_entry(src_map, page_vaddr, &src_entry))
6964 share_map = TRUE;
6965 else if (src_entry->is_sub_map) {
6966 map_entry_end = src_entry->vme_end;
6967 share_map = TRUE;
6968 } else {
6969 map_entry_end = src_entry->vme_end;
6970 share_map = FALSE;
6971 }
6972 }
6973
6974
6975 if ((options & VM_MAP_COPYIN_OPT_SRC_DESTROY) &&
6976 src_object->internal &&
6977 !src_object->true_share &&
6978 (!src_object->shadowed) &&
6979 (src_object->copy_strategy ==
6980 MEMORY_OBJECT_COPY_SYMMETRIC) &&
6981 !m->precious &&
6982 !share_map) {
6983
6984 if (m->wire_count > 0) {
6985
6986 assert(m->wire_count == 1);
6987 /*
6988 * In order to steal a wired
6989 * page, we have to unwire it
6990 * first. We do this inline
6991 * here because we have the page.
6992 *
6993 * Step 1: Unwire the map entry.
6994 * Also tell the pmap module
6995 * that this piece of the
6996 * pmap is pageable.
6997 */
6998 vm_object_unlock(src_object);
6999 if (page_vaddr >= unwire_end) {
7000 if (!vm_map_lookup_entry(src_map,
7001 page_vaddr, &src_entry))
7002 panic("vm_map_copyin_page_list: missing wired map entry");
7003
7004 vm_map_clip_start(src_map, src_entry,
7005 page_vaddr);
7006 vm_map_clip_end(src_map, src_entry,
7007 src_start + src_size);
7008
7009 /* revisit why this assert fails CDY
7010 assert(src_entry->wired_count > 0);
7011 */
7012 src_entry->wired_count = 0;
7013 src_entry->user_wired_count = 0;
7014 unwire_end = src_entry->vme_end;
7015 pmap_pageable(vm_map_pmap(src_map),
7016 page_vaddr, unwire_end, TRUE);
7017 }
7018
7019 /*
7020 * Step 2: Unwire the page.
7021 * pmap_remove handles this for us.
7022 */
7023 vm_object_lock(src_object);
7024 }
7025
7026 /*
7027 * Don't need to remove the mapping;
7028 * vm_map_delete will handle it.
7029 *
7030 * Steal the page. Setting the wire count
7031 * to zero is vm_page_unwire without
7032 * activating the page.
7033 */
7034 vm_page_lock_queues();
7035 vm_page_remove(m);
7036 if (m->wire_count > 0) {
7037 m->wire_count = 0;
7038 vm_page_wire_count--;
7039 } else {
7040 VM_PAGE_QUEUES_REMOVE(m);
7041 }
7042 vm_page_unlock_queues();
7043 } else {
7044 /*
7045 * Have to copy this page. Have to
7046 * unlock the map while copying,
7047 * hence no further page stealing.
7048 * Hence just copy all the pages.
7049 * Unlock the map while copying;
7050 * This means no further page stealing.
7051 */
7052 vm_object_unlock(src_object);
7053 vm_map_unlock(src_map);
7054 vm_map_copy_steal_pages(copy);
7055 vm_map_lock(src_map);
7056 break;
7057 }
7058
7059 vm_object_paging_end(src_object);
7060 vm_object_unlock(src_object);
7061 }
7062
7063 copy->cpy_page_loose = TRUE;
7064
7065 /*
7066 * If the source should be destroyed, do it now, since the
7067 * copy was successful.
7068 */
7069
7070 if (options & VM_MAP_COPYIN_OPT_SRC_DESTROY) {
7071 (void) vm_map_delete(src_map, src_start,
7072 src_end, VM_MAP_NO_FLAGS);
7073 }
7074 } else {
7075 /*
7076 * Not stealing pages leaves busy or prepped pages in the map.
7077 * This will cause source destruction to hang. Use
7078 * a continuation to prevent this.
7079 */
7080 if ((options & VM_MAP_COPYIN_OPT_SRC_DESTROY) &&
7081 !vm_map_copy_has_cont(copy)) {
7082 cont_args = (vm_map_copyin_args_t)
7083 kalloc(sizeof(vm_map_copyin_args_data_t));
7084 vm_map_reference(src_map);
7085 cont_args->map = src_map;
7086 cont_args->src_addr = (vm_offset_t) 0;
7087 cont_args->src_len = (vm_size_t) 0;
7088 cont_args->destroy_addr = src_start;
7089 cont_args->destroy_len = src_end - src_start;
7090 cont_args->options = options;
7091
7092 copy->cpy_cont_args = cont_args;
7093 copy->cpy_cont = vm_map_copyin_page_list_cont;
7094 }
7095 }
7096
7097 vm_map_unlock(src_map);
7098
7099 *copy_result = copy;
7100 return(result);
7101
7102 error:
7103 {
7104 submap_map_t *ptr;
7105
7106 vm_map_unlock(src_map);
7107 vm_map_copy_discard(copy);
7108
7109 for(ptr = parent_maps; ptr != NULL; ptr = parent_maps) {
7110 parent_maps=parent_maps->next;
7111 kfree((vm_offset_t)ptr, sizeof(submap_map_t));
7112 }
7113 return(result);
7114 }
7115 }
7116
7117 void
7118 vm_map_fork_share(
7119 vm_map_t old_map,
7120 vm_map_entry_t old_entry,
7121 vm_map_t new_map)
7122 {
7123 vm_object_t object;
7124 vm_map_entry_t new_entry;
7125 kern_return_t result;
7126
7127 /*
7128 * New sharing code. New map entry
7129 * references original object. Internal
7130 * objects use asynchronous copy algorithm for
7131 * future copies. First make sure we have
7132 * the right object. If we need a shadow,
7133 * or someone else already has one, then
7134 * make a new shadow and share it.
7135 */
7136
7137 object = old_entry->object.vm_object;
7138 if (old_entry->is_sub_map) {
7139 assert(old_entry->wired_count == 0);
7140 #ifndef i386
7141 if(old_entry->use_pmap) {
7142 result = pmap_nest(new_map->pmap,
7143 (old_entry->object.sub_map)->pmap,
7144 old_entry->vme_start,
7145 old_entry->vme_end - old_entry->vme_start);
7146 if(result)
7147 panic("vm_map_fork_share: pmap_nest failed!");
7148 }
7149 #endif
7150 } else if (object == VM_OBJECT_NULL) {
7151 object = vm_object_allocate((vm_size_t)(old_entry->vme_end -
7152 old_entry->vme_start));
7153 old_entry->offset = 0;
7154 old_entry->object.vm_object = object;
7155 assert(!old_entry->needs_copy);
7156 } else if (object->copy_strategy !=
7157 MEMORY_OBJECT_COPY_SYMMETRIC) {
7158
7159 /*
7160 * We are already using an asymmetric
7161 * copy, and therefore we already have
7162 * the right object.
7163 */
7164
7165 assert(! old_entry->needs_copy);
7166 }
7167 else if (old_entry->needs_copy || /* case 1 */
7168 object->shadowed || /* case 2 */
7169 (!object->true_share && /* case 3 */
7170 !old_entry->is_shared &&
7171 (object->size >
7172 (vm_size_t)(old_entry->vme_end -
7173 old_entry->vme_start)))) {
7174
7175 /*
7176 * We need to create a shadow.
7177 * There are three cases here.
7178 * In the first case, we need to
7179 * complete a deferred symmetrical
7180 * copy that we participated in.
7181 * In the second and third cases,
7182 * we need to create the shadow so
7183 * that changes that we make to the
7184 * object do not interfere with
7185 * any symmetrical copies which
7186 * have occured (case 2) or which
7187 * might occur (case 3).
7188 *
7189 * The first case is when we had
7190 * deferred shadow object creation
7191 * via the entry->needs_copy mechanism.
7192 * This mechanism only works when
7193 * only one entry points to the source
7194 * object, and we are about to create
7195 * a second entry pointing to the
7196 * same object. The problem is that
7197 * there is no way of mapping from
7198 * an object to the entries pointing
7199 * to it. (Deferred shadow creation
7200 * works with one entry because occurs
7201 * at fault time, and we walk from the
7202 * entry to the object when handling
7203 * the fault.)
7204 *
7205 * The second case is when the object
7206 * to be shared has already been copied
7207 * with a symmetric copy, but we point
7208 * directly to the object without
7209 * needs_copy set in our entry. (This
7210 * can happen because different ranges
7211 * of an object can be pointed to by
7212 * different entries. In particular,
7213 * a single entry pointing to an object
7214 * can be split by a call to vm_inherit,
7215 * which, combined with task_create, can
7216 * result in the different entries
7217 * having different needs_copy values.)
7218 * The shadowed flag in the object allows
7219 * us to detect this case. The problem
7220 * with this case is that if this object
7221 * has or will have shadows, then we
7222 * must not perform an asymmetric copy
7223 * of this object, since such a copy
7224 * allows the object to be changed, which
7225 * will break the previous symmetrical
7226 * copies (which rely upon the object
7227 * not changing). In a sense, the shadowed
7228 * flag says "don't change this object".
7229 * We fix this by creating a shadow
7230 * object for this object, and sharing
7231 * that. This works because we are free
7232 * to change the shadow object (and thus
7233 * to use an asymmetric copy strategy);
7234 * this is also semantically correct,
7235 * since this object is temporary, and
7236 * therefore a copy of the object is
7237 * as good as the object itself. (This
7238 * is not true for permanent objects,
7239 * since the pager needs to see changes,
7240 * which won't happen if the changes
7241 * are made to a copy.)
7242 *
7243 * The third case is when the object
7244 * to be shared has parts sticking
7245 * outside of the entry we're working
7246 * with, and thus may in the future
7247 * be subject to a symmetrical copy.
7248 * (This is a preemptive version of
7249 * case 2.)
7250 */
7251
7252 assert(!(object->shadowed && old_entry->is_shared));
7253 vm_object_shadow(&old_entry->object.vm_object,
7254 &old_entry->offset,
7255 (vm_size_t) (old_entry->vme_end -
7256 old_entry->vme_start));
7257
7258 /*
7259 * If we're making a shadow for other than
7260 * copy on write reasons, then we have
7261 * to remove write permission.
7262 */
7263
7264 /* CDY FIX this! page_protect! */
7265 if (!old_entry->needs_copy &&
7266 (old_entry->protection & VM_PROT_WRITE)) {
7267 if(old_entry->is_sub_map && old_entry->use_pmap) {
7268 pmap_protect(old_entry->object.sub_map->pmap,
7269 old_entry->vme_start,
7270 old_entry->vme_end,
7271 old_entry->protection & ~VM_PROT_WRITE);
7272 } else {
7273 pmap_protect(vm_map_pmap(old_map),
7274 old_entry->vme_start,
7275 old_entry->vme_end,
7276 old_entry->protection & ~VM_PROT_WRITE);
7277 }
7278 }
7279
7280 old_entry->needs_copy = FALSE;
7281 object = old_entry->object.vm_object;
7282 }
7283
7284 /*
7285 * If object was using a symmetric copy strategy,
7286 * change its copy strategy to the default
7287 * asymmetric copy strategy, which is copy_delay
7288 * in the non-norma case and copy_call in the
7289 * norma case. Bump the reference count for the
7290 * new entry.
7291 */
7292
7293 if(old_entry->is_sub_map) {
7294 vm_map_lock(old_entry->object.sub_map);
7295 vm_map_reference(old_entry->object.sub_map);
7296 vm_map_unlock(old_entry->object.sub_map);
7297 } else {
7298 vm_object_lock(object);
7299 object->ref_count++;
7300 vm_object_res_reference(object);
7301 if (object->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC) {
7302 object->copy_strategy = MEMORY_OBJECT_COPY_DELAY;
7303 }
7304 vm_object_unlock(object);
7305 }
7306
7307 /*
7308 * Clone the entry, using object ref from above.
7309 * Mark both entries as shared.
7310 */
7311
7312 new_entry = vm_map_entry_create(new_map);
7313 vm_map_entry_copy(new_entry, old_entry);
7314 old_entry->is_shared = TRUE;
7315 new_entry->is_shared = TRUE;
7316
7317 /*
7318 * Insert the entry into the new map -- we
7319 * know we're inserting at the end of the new
7320 * map.
7321 */
7322
7323 vm_map_entry_link(new_map, vm_map_last_entry(new_map), new_entry);
7324
7325 /*
7326 * Update the physical map
7327 */
7328
7329 if (old_entry->is_sub_map) {
7330 /* Bill Angell pmap support goes here */
7331 } else {
7332 pmap_copy(new_map->pmap, old_map->pmap, new_entry->vme_start,
7333 old_entry->vme_end - old_entry->vme_start,
7334 old_entry->vme_start);
7335 }
7336 }
7337
7338 boolean_t
7339 vm_map_fork_copy(
7340 vm_map_t old_map,
7341 vm_map_entry_t *old_entry_p,
7342 vm_map_t new_map)
7343 {
7344 vm_map_entry_t old_entry = *old_entry_p;
7345 vm_size_t entry_size = old_entry->vme_end - old_entry->vme_start;
7346 vm_offset_t start = old_entry->vme_start;
7347 vm_map_copy_t copy;
7348 vm_map_entry_t last = vm_map_last_entry(new_map);
7349
7350 vm_map_unlock(old_map);
7351 /*
7352 * Use maxprot version of copyin because we
7353 * care about whether this memory can ever
7354 * be accessed, not just whether it's accessible
7355 * right now.
7356 */
7357 if (vm_map_copyin_maxprot(old_map, start, entry_size, FALSE, &copy)
7358 != KERN_SUCCESS) {
7359 /*
7360 * The map might have changed while it
7361 * was unlocked, check it again. Skip
7362 * any blank space or permanently
7363 * unreadable region.
7364 */
7365 vm_map_lock(old_map);
7366 if (!vm_map_lookup_entry(old_map, start, &last) ||
7367 last->max_protection & VM_PROT_READ ==
7368 VM_PROT_NONE) {
7369 last = last->vme_next;
7370 }
7371 *old_entry_p = last;
7372
7373 /*
7374 * XXX For some error returns, want to
7375 * XXX skip to the next element. Note
7376 * that INVALID_ADDRESS and
7377 * PROTECTION_FAILURE are handled above.
7378 */
7379
7380 return FALSE;
7381 }
7382
7383 /*
7384 * Insert the copy into the new map
7385 */
7386
7387 vm_map_copy_insert(new_map, last, copy);
7388
7389 /*
7390 * Pick up the traversal at the end of
7391 * the copied region.
7392 */
7393
7394 vm_map_lock(old_map);
7395 start += entry_size;
7396 if (! vm_map_lookup_entry(old_map, start, &last)) {
7397 last = last->vme_next;
7398 } else {
7399 vm_map_clip_start(old_map, last, start);
7400 }
7401 *old_entry_p = last;
7402
7403 return TRUE;
7404 }
7405
7406 /*
7407 * vm_map_fork:
7408 *
7409 * Create and return a new map based on the old
7410 * map, according to the inheritance values on the
7411 * regions in that map.
7412 *
7413 * The source map must not be locked.
7414 */
7415 vm_map_t
7416 vm_map_fork(
7417 vm_map_t old_map)
7418 {
7419 pmap_t new_pmap = pmap_create((vm_size_t) 0);
7420 vm_map_t new_map;
7421 vm_map_entry_t old_entry;
7422 vm_size_t new_size = 0, entry_size;
7423 vm_map_entry_t new_entry;
7424 boolean_t src_needs_copy;
7425 boolean_t new_entry_needs_copy;
7426
7427 vm_map_reference_swap(old_map);
7428 vm_map_lock(old_map);
7429
7430 new_map = vm_map_create(new_pmap,
7431 old_map->min_offset,
7432 old_map->max_offset,
7433 old_map->hdr.entries_pageable);
7434
7435 for (
7436 old_entry = vm_map_first_entry(old_map);
7437 old_entry != vm_map_to_entry(old_map);
7438 ) {
7439
7440 entry_size = old_entry->vme_end - old_entry->vme_start;
7441
7442 switch (old_entry->inheritance) {
7443 case VM_INHERIT_NONE:
7444 break;
7445
7446 case VM_INHERIT_SHARE:
7447 vm_map_fork_share(old_map, old_entry, new_map);
7448 new_size += entry_size;
7449 break;
7450
7451 case VM_INHERIT_COPY:
7452
7453 /*
7454 * Inline the copy_quickly case;
7455 * upon failure, fall back on call
7456 * to vm_map_fork_copy.
7457 */
7458
7459 if(old_entry->is_sub_map)
7460 break;
7461 if (old_entry->wired_count != 0) {
7462 goto slow_vm_map_fork_copy;
7463 }
7464
7465 new_entry = vm_map_entry_create(new_map);
7466 vm_map_entry_copy(new_entry, old_entry);
7467 /* clear address space specifics */
7468 new_entry->use_pmap = FALSE;
7469
7470 if (! vm_object_copy_quickly(
7471 &new_entry->object.vm_object,
7472 old_entry->offset,
7473 (old_entry->vme_end -
7474 old_entry->vme_start),
7475 &src_needs_copy,
7476 &new_entry_needs_copy)) {
7477 vm_map_entry_dispose(new_map, new_entry);
7478 goto slow_vm_map_fork_copy;
7479 }
7480
7481 /*
7482 * Handle copy-on-write obligations
7483 */
7484
7485 if (src_needs_copy && !old_entry->needs_copy) {
7486 vm_object_pmap_protect(
7487 old_entry->object.vm_object,
7488 old_entry->offset,
7489 (old_entry->vme_end -
7490 old_entry->vme_start),
7491 ((old_entry->is_shared
7492 || old_entry->is_sub_map)
7493 ? PMAP_NULL :
7494 old_map->pmap),
7495 old_entry->vme_start,
7496 old_entry->protection & ~VM_PROT_WRITE);
7497
7498 old_entry->needs_copy = TRUE;
7499 }
7500 new_entry->needs_copy = new_entry_needs_copy;
7501
7502 /*
7503 * Insert the entry at the end
7504 * of the map.
7505 */
7506
7507 vm_map_entry_link(new_map, vm_map_last_entry(new_map),
7508 new_entry);
7509 new_size += entry_size;
7510 break;
7511
7512 slow_vm_map_fork_copy:
7513 if (vm_map_fork_copy(old_map, &old_entry, new_map)) {
7514 new_size += entry_size;
7515 }
7516 continue;
7517 }
7518 old_entry = old_entry->vme_next;
7519 }
7520
7521 new_map->size = new_size;
7522 vm_map_unlock(old_map);
7523 vm_map_deallocate(old_map);
7524
7525 return(new_map);
7526 }
7527
7528
7529 /*
7530 * vm_map_lookup_locked:
7531 *
7532 * Finds the VM object, offset, and
7533 * protection for a given virtual address in the
7534 * specified map, assuming a page fault of the
7535 * type specified.
7536 *
7537 * Returns the (object, offset, protection) for
7538 * this address, whether it is wired down, and whether
7539 * this map has the only reference to the data in question.
7540 * In order to later verify this lookup, a "version"
7541 * is returned.
7542 *
7543 * The map MUST be locked by the caller and WILL be
7544 * locked on exit. In order to guarantee the
7545 * existence of the returned object, it is returned
7546 * locked.
7547 *
7548 * If a lookup is requested with "write protection"
7549 * specified, the map may be changed to perform virtual
7550 * copying operations, although the data referenced will
7551 * remain the same.
7552 */
7553 kern_return_t
7554 vm_map_lookup_locked(
7555 vm_map_t *var_map, /* IN/OUT */
7556 register vm_offset_t vaddr,
7557 register vm_prot_t fault_type,
7558 vm_map_version_t *out_version, /* OUT */
7559 vm_object_t *object, /* OUT */
7560 vm_object_offset_t *offset, /* OUT */
7561 vm_prot_t *out_prot, /* OUT */
7562 boolean_t *wired, /* OUT */
7563 int *behavior, /* OUT */
7564 vm_object_offset_t *lo_offset, /* OUT */
7565 vm_object_offset_t *hi_offset, /* OUT */
7566 vm_map_t *pmap_map)
7567 {
7568 vm_map_entry_t entry;
7569 register vm_map_t map = *var_map;
7570 vm_map_t old_map = *var_map;
7571 vm_map_t cow_sub_map_parent = VM_MAP_NULL;
7572 vm_offset_t cow_parent_vaddr;
7573 vm_offset_t old_start;
7574 vm_offset_t old_end;
7575 register vm_prot_t prot;
7576
7577 *pmap_map = map;
7578 RetryLookup: ;
7579
7580 /*
7581 * If the map has an interesting hint, try it before calling
7582 * full blown lookup routine.
7583 */
7584
7585 mutex_lock(&map->s_lock);
7586 entry = map->hint;
7587 mutex_unlock(&map->s_lock);
7588
7589 if ((entry == vm_map_to_entry(map)) ||
7590 (vaddr < entry->vme_start) || (vaddr >= entry->vme_end)) {
7591 vm_map_entry_t tmp_entry;
7592
7593 /*
7594 * Entry was either not a valid hint, or the vaddr
7595 * was not contained in the entry, so do a full lookup.
7596 */
7597 if (!vm_map_lookup_entry(map, vaddr, &tmp_entry)) {
7598 if((cow_sub_map_parent) && (cow_sub_map_parent != map))
7599 vm_map_unlock(cow_sub_map_parent);
7600 if((*pmap_map != map)
7601 && (*pmap_map != cow_sub_map_parent))
7602 vm_map_unlock(*pmap_map);
7603 return KERN_INVALID_ADDRESS;
7604 }
7605
7606 entry = tmp_entry;
7607 }
7608 if(map == old_map) {
7609 old_start = entry->vme_start;
7610 old_end = entry->vme_end;
7611 }
7612
7613 /*
7614 * Handle submaps. Drop lock on upper map, submap is
7615 * returned locked.
7616 */
7617
7618 submap_recurse:
7619 if (entry->is_sub_map) {
7620 vm_offset_t local_vaddr;
7621 vm_offset_t end_delta;
7622 vm_offset_t start_delta;
7623 vm_offset_t object_start_delta;
7624 vm_map_entry_t submap_entry;
7625 boolean_t mapped_needs_copy=FALSE;
7626
7627 local_vaddr = vaddr;
7628
7629 if ((!entry->needs_copy) && (entry->use_pmap)) {
7630 /* if pmap_map equals map we unlock below */
7631 if ((*pmap_map != map) &&
7632 (*pmap_map != cow_sub_map_parent))
7633 vm_map_unlock(*pmap_map);
7634 *pmap_map = entry->object.sub_map;
7635 }
7636
7637 if(entry->needs_copy) {
7638 if (!mapped_needs_copy) {
7639 if (vm_map_lock_read_to_write(map)) {
7640 vm_map_lock_read(map);
7641 if(*pmap_map == entry->object.sub_map)
7642 *pmap_map = map;
7643 goto RetryLookup;
7644 }
7645 vm_map_lock_read(entry->object.sub_map);
7646 cow_sub_map_parent = map;
7647 /* reset base to map before cow object */
7648 /* this is the map which will accept */
7649 /* the new cow object */
7650 old_start = entry->vme_start;
7651 old_end = entry->vme_end;
7652 cow_parent_vaddr = vaddr;
7653 mapped_needs_copy = TRUE;
7654 } else {
7655 vm_map_lock_read(entry->object.sub_map);
7656 if((cow_sub_map_parent != map) &&
7657 (*pmap_map != map))
7658 vm_map_unlock(map);
7659 }
7660 } else {
7661 vm_map_lock_read(entry->object.sub_map);
7662 /* leave map locked if it is a target */
7663 /* cow sub_map above otherwise, just */
7664 /* follow the maps down to the object */
7665 /* here we unlock knowing we are not */
7666 /* revisiting the map. */
7667 if((*pmap_map != map) && (map != cow_sub_map_parent))
7668 vm_map_unlock_read(map);
7669 }
7670
7671 *var_map = map = entry->object.sub_map;
7672
7673 /* calculate the offset in the submap for vaddr */
7674 local_vaddr = (local_vaddr - entry->vme_start) + entry->offset;
7675
7676 RetrySubMap:
7677 if(!vm_map_lookup_entry(map, local_vaddr, &submap_entry)) {
7678 if((cow_sub_map_parent) && (cow_sub_map_parent != map)){
7679 vm_map_unlock(cow_sub_map_parent);
7680 }
7681 if((*pmap_map != map)
7682 && (*pmap_map != cow_sub_map_parent)) {
7683 vm_map_unlock(*pmap_map);
7684 }
7685 *pmap_map = map;
7686 return KERN_INVALID_ADDRESS;
7687 }
7688 /* find the attenuated shadow of the underlying object */
7689 /* on our target map */
7690
7691 /* in english the submap object may extend beyond the */
7692 /* region mapped by the entry or, may only fill a portion */
7693 /* of it. For our purposes, we only care if the object */
7694 /* doesn't fill. In this case the area which will */
7695 /* ultimately be clipped in the top map will only need */
7696 /* to be as big as the portion of the underlying entry */
7697 /* which is mapped */
7698 start_delta = submap_entry->vme_start > entry->offset ?
7699 submap_entry->vme_start - entry->offset : 0;
7700
7701 end_delta =
7702 (entry->offset + start_delta + (old_end - old_start)) <=
7703 submap_entry->vme_end ?
7704 0 : (entry->offset +
7705 (old_end - old_start))
7706 - submap_entry->vme_end;
7707
7708 old_start += start_delta;
7709 old_end -= end_delta;
7710
7711 if(submap_entry->is_sub_map) {
7712 entry = submap_entry;
7713 vaddr = local_vaddr;
7714 goto submap_recurse;
7715 }
7716
7717 if(((fault_type & VM_PROT_WRITE) && cow_sub_map_parent)) {
7718
7719 vm_object_t copy_object;
7720 vm_offset_t local_start;
7721 vm_offset_t local_end;
7722
7723 if (vm_map_lock_read_to_write(map)) {
7724 vm_map_lock_read(map);
7725 old_start -= start_delta;
7726 old_end += end_delta;
7727 goto RetrySubMap;
7728 }
7729 if (submap_entry->object.vm_object == VM_OBJECT_NULL) {
7730 submap_entry->object.vm_object =
7731 vm_object_allocate(
7732 (vm_size_t)
7733 (submap_entry->vme_end
7734 - submap_entry->vme_start));
7735 submap_entry->offset = 0;
7736 }
7737 local_start = local_vaddr -
7738 (cow_parent_vaddr - old_start);
7739 local_end = local_vaddr +
7740 (old_end - cow_parent_vaddr);
7741 vm_map_clip_start(map, submap_entry, local_start);
7742 vm_map_clip_end(map, submap_entry, local_end);
7743
7744 /* This is the COW case, lets connect */
7745 /* an entry in our space to the underlying */
7746 /* object in the submap, bypassing the */
7747 /* submap. */
7748
7749 /* set up shadow object */
7750 copy_object = submap_entry->object.vm_object;
7751 submap_entry->object.vm_object->shadowed = TRUE;
7752 submap_entry->needs_copy = TRUE;
7753 vm_object_pmap_protect(submap_entry->object.vm_object,
7754 submap_entry->offset,
7755 submap_entry->vme_end -
7756 submap_entry->vme_start,
7757 submap_entry->is_shared ?
7758 PMAP_NULL : map->pmap,
7759 submap_entry->vme_start,
7760 submap_entry->protection &
7761 ~VM_PROT_WRITE);
7762
7763
7764 /* This works diffently than the */
7765 /* normal submap case. We go back */
7766 /* to the parent of the cow map and*/
7767 /* clip out the target portion of */
7768 /* the sub_map, substituting the */
7769 /* new copy object, */
7770
7771 vm_map_unlock(map);
7772 local_start = old_start;
7773 local_end = old_end;
7774 map = cow_sub_map_parent;
7775 *var_map = cow_sub_map_parent;
7776 vaddr = cow_parent_vaddr;
7777 cow_sub_map_parent = NULL;
7778
7779 if(!vm_map_lookup_entry(map,
7780 vaddr, &entry)) {
7781 vm_object_deallocate(
7782 copy_object);
7783 vm_map_lock_write_to_read(map);
7784 return KERN_INVALID_ADDRESS;
7785 }
7786
7787 /* clip out the portion of space */
7788 /* mapped by the sub map which */
7789 /* corresponds to the underlying */
7790 /* object */
7791 vm_map_clip_start(map, entry, local_start);
7792 vm_map_clip_end(map, entry, local_end);
7793
7794
7795 /* substitute copy object for */
7796 /* shared map entry */
7797 vm_map_deallocate(entry->object.sub_map);
7798 entry->is_sub_map = FALSE;
7799 vm_object_reference(copy_object);
7800 entry->object.vm_object = copy_object;
7801 entry->offset = submap_entry->offset;
7802
7803 entry->protection |= VM_PROT_WRITE;
7804 entry->max_protection |= VM_PROT_WRITE;
7805 entry->needs_copy = TRUE;
7806 if(entry->inheritance == VM_INHERIT_SHARE)
7807 entry->inheritance = VM_INHERIT_COPY;
7808 if (map != old_map)
7809 entry->is_shared = TRUE;
7810
7811 vm_map_lock_write_to_read(map);
7812 } else {
7813 if((cow_sub_map_parent)
7814 && (cow_sub_map_parent != *pmap_map)
7815 && (cow_sub_map_parent != map)) {
7816 vm_map_unlock(cow_sub_map_parent);
7817 }
7818 entry = submap_entry;
7819 vaddr = local_vaddr;
7820 }
7821 }
7822
7823 /*
7824 * Check whether this task is allowed to have
7825 * this page.
7826 */
7827
7828 prot = entry->protection;
7829 if ((fault_type & (prot)) != fault_type) {
7830 if (*pmap_map != map) {
7831 vm_map_unlock(*pmap_map);
7832 }
7833 *pmap_map = map;
7834 return KERN_PROTECTION_FAILURE;
7835 }
7836
7837 /*
7838 * If this page is not pageable, we have to get
7839 * it for all possible accesses.
7840 */
7841
7842 if (*wired = (entry->wired_count != 0))
7843 prot = fault_type = entry->protection;
7844
7845 /*
7846 * If the entry was copy-on-write, we either ...
7847 */
7848
7849 if (entry->needs_copy) {
7850 /*
7851 * If we want to write the page, we may as well
7852 * handle that now since we've got the map locked.
7853 *
7854 * If we don't need to write the page, we just
7855 * demote the permissions allowed.
7856 */
7857
7858 if (fault_type & VM_PROT_WRITE || *wired) {
7859 /*
7860 * Make a new object, and place it in the
7861 * object chain. Note that no new references
7862 * have appeared -- one just moved from the
7863 * map to the new object.
7864 */
7865
7866 if (vm_map_lock_read_to_write(map)) {
7867 vm_map_lock_read(map);
7868 goto RetryLookup;
7869 }
7870 vm_object_shadow(&entry->object.vm_object,
7871 &entry->offset,
7872 (vm_size_t) (entry->vme_end -
7873 entry->vme_start));
7874
7875 entry->object.vm_object->shadowed = TRUE;
7876 entry->needs_copy = FALSE;
7877 vm_map_lock_write_to_read(map);
7878 }
7879 else {
7880 /*
7881 * We're attempting to read a copy-on-write
7882 * page -- don't allow writes.
7883 */
7884
7885 prot &= (~VM_PROT_WRITE);
7886 }
7887 }
7888
7889 /*
7890 * Create an object if necessary.
7891 */
7892 if (entry->object.vm_object == VM_OBJECT_NULL) {
7893
7894 if (vm_map_lock_read_to_write(map)) {
7895 vm_map_lock_read(map);
7896 goto RetryLookup;
7897 }
7898
7899 entry->object.vm_object = vm_object_allocate(
7900 (vm_size_t)(entry->vme_end - entry->vme_start));
7901 entry->offset = 0;
7902 vm_map_lock_write_to_read(map);
7903 }
7904
7905 /*
7906 * Return the object/offset from this entry. If the entry
7907 * was copy-on-write or empty, it has been fixed up. Also
7908 * return the protection.
7909 */
7910
7911 *offset = (vaddr - entry->vme_start) + entry->offset;
7912 *object = entry->object.vm_object;
7913 *out_prot = prot;
7914 *behavior = entry->behavior;
7915 *lo_offset = entry->offset;
7916 *hi_offset = (entry->vme_end - entry->vme_start) + entry->offset;
7917
7918 /*
7919 * Lock the object to prevent it from disappearing
7920 */
7921
7922 vm_object_lock(*object);
7923
7924 /*
7925 * Save the version number
7926 */
7927
7928 out_version->main_timestamp = map->timestamp;
7929
7930 return KERN_SUCCESS;
7931 }
7932
7933
7934 /*
7935 * vm_map_verify:
7936 *
7937 * Verifies that the map in question has not changed
7938 * since the given version. If successful, the map
7939 * will not change until vm_map_verify_done() is called.
7940 */
7941 boolean_t
7942 vm_map_verify(
7943 register vm_map_t map,
7944 register vm_map_version_t *version) /* REF */
7945 {
7946 boolean_t result;
7947
7948 vm_map_lock_read(map);
7949 result = (map->timestamp == version->main_timestamp);
7950
7951 if (!result)
7952 vm_map_unlock_read(map);
7953
7954 return(result);
7955 }
7956
7957 /*
7958 * vm_map_verify_done:
7959 *
7960 * Releases locks acquired by a vm_map_verify.
7961 *
7962 * This is now a macro in vm/vm_map.h. It does a
7963 * vm_map_unlock_read on the map.
7964 */
7965
7966
7967 /*
7968 * vm_region:
7969 *
7970 * User call to obtain information about a region in
7971 * a task's address map. Currently, only one flavor is
7972 * supported.
7973 *
7974 * XXX The reserved and behavior fields cannot be filled
7975 * in until the vm merge from the IK is completed, and
7976 * vm_reserve is implemented.
7977 *
7978 * XXX Dependency: syscall_vm_region() also supports only one flavor.
7979 */
7980
7981 kern_return_t
7982 vm_region(
7983 vm_map_t map,
7984 vm_offset_t *address, /* IN/OUT */
7985 vm_size_t *size, /* OUT */
7986 vm_region_flavor_t flavor, /* IN */
7987 vm_region_info_t info, /* OUT */
7988 mach_msg_type_number_t *count, /* IN/OUT */
7989 ipc_port_t *object_name) /* OUT */
7990 {
7991 vm_map_entry_t tmp_entry;
7992 register
7993 vm_map_entry_t entry;
7994 register
7995 vm_offset_t start;
7996 vm_region_basic_info_t basic;
7997 vm_region_extended_info_t extended;
7998 vm_region_top_info_t top;
7999
8000 if (map == VM_MAP_NULL)
8001 return(KERN_INVALID_ARGUMENT);
8002
8003 switch (flavor) {
8004
8005 case VM_REGION_BASIC_INFO:
8006 {
8007 if (*count < VM_REGION_BASIC_INFO_COUNT)
8008 return(KERN_INVALID_ARGUMENT);
8009
8010 basic = (vm_region_basic_info_t) info;
8011 *count = VM_REGION_BASIC_INFO_COUNT;
8012
8013 vm_map_lock_read(map);
8014
8015 start = *address;
8016 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8017 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8018 vm_map_unlock_read(map);
8019 return(KERN_INVALID_ADDRESS);
8020 }
8021 } else {
8022 entry = tmp_entry;
8023 }
8024
8025 start = entry->vme_start;
8026
8027 basic->offset = entry->offset;
8028 basic->protection = entry->protection;
8029 basic->inheritance = entry->inheritance;
8030 basic->max_protection = entry->max_protection;
8031 basic->behavior = entry->behavior;
8032 basic->user_wired_count = entry->user_wired_count;
8033 basic->reserved = entry->is_sub_map;
8034 *address = start;
8035 *size = (entry->vme_end - start);
8036
8037 if (object_name) *object_name = IP_NULL;
8038 if (entry->is_sub_map) {
8039 basic->shared = FALSE;
8040 } else {
8041 basic->shared = entry->is_shared;
8042 }
8043
8044 vm_map_unlock_read(map);
8045 return(KERN_SUCCESS);
8046 }
8047 case VM_REGION_EXTENDED_INFO:
8048 {
8049
8050 if (*count < VM_REGION_EXTENDED_INFO_COUNT)
8051 return(KERN_INVALID_ARGUMENT);
8052
8053 extended = (vm_region_extended_info_t) info;
8054 *count = VM_REGION_EXTENDED_INFO_COUNT;
8055
8056 vm_map_lock_read(map);
8057
8058 start = *address;
8059 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8060 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8061 vm_map_unlock_read(map);
8062 return(KERN_INVALID_ADDRESS);
8063 }
8064 } else {
8065 entry = tmp_entry;
8066 }
8067 start = entry->vme_start;
8068
8069 extended->protection = entry->protection;
8070 extended->user_tag = entry->alias;
8071 extended->pages_resident = 0;
8072 extended->pages_swapped_out = 0;
8073 extended->pages_shared_now_private = 0;
8074 extended->pages_referenced = 0;
8075 extended->external_pager = 0;
8076 extended->shadow_depth = 0;
8077
8078 vm_region_walk(entry, extended, entry->offset, entry->vme_end - start, map, start);
8079
8080 if (extended->external_pager && extended->ref_count == 2 && extended->share_mode == SM_SHARED)
8081 extended->share_mode = SM_PRIVATE;
8082
8083 if (object_name)
8084 *object_name = IP_NULL;
8085 *address = start;
8086 *size = (entry->vme_end - start);
8087
8088 vm_map_unlock_read(map);
8089 return(KERN_SUCCESS);
8090 }
8091 case VM_REGION_TOP_INFO:
8092 {
8093
8094 if (*count < VM_REGION_TOP_INFO_COUNT)
8095 return(KERN_INVALID_ARGUMENT);
8096
8097 top = (vm_region_top_info_t) info;
8098 *count = VM_REGION_TOP_INFO_COUNT;
8099
8100 vm_map_lock_read(map);
8101
8102 start = *address;
8103 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8104 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8105 vm_map_unlock_read(map);
8106 return(KERN_INVALID_ADDRESS);
8107 }
8108 } else {
8109 entry = tmp_entry;
8110
8111 }
8112 start = entry->vme_start;
8113
8114 top->private_pages_resident = 0;
8115 top->shared_pages_resident = 0;
8116
8117 vm_region_top_walk(entry, top);
8118
8119 if (object_name)
8120 *object_name = IP_NULL;
8121 *address = start;
8122 *size = (entry->vme_end - start);
8123
8124 vm_map_unlock_read(map);
8125 return(KERN_SUCCESS);
8126 }
8127 default:
8128 return(KERN_INVALID_ARGUMENT);
8129 }
8130 }
8131
8132 /*
8133 * vm_region_recurse: A form of vm_region which follows the
8134 * submaps in a target map
8135 *
8136 */
8137
8138 kern_return_t
8139 vm_region_recurse(
8140 vm_map_t map,
8141 vm_offset_t *address, /* IN/OUT */
8142 vm_size_t *size, /* OUT */
8143 natural_t *nesting_depth, /* IN/OUT */
8144 vm_region_recurse_info_t info, /* IN/OUT */
8145 mach_msg_type_number_t *count) /* IN/OUT */
8146 {
8147 vm_map_entry_t tmp_entry;
8148 register
8149 vm_map_entry_t entry;
8150 register
8151 vm_offset_t start;
8152
8153 unsigned int recurse_count;
8154 vm_map_t submap;
8155 vm_map_t base_map;
8156 vm_map_entry_t base_entry;
8157 vm_offset_t base_next;
8158 vm_offset_t base_addr;
8159 vm_offset_t baddr_start_delta;
8160 vm_region_submap_info_t submap_info;
8161 vm_region_extended_info_data_t extended;
8162
8163 if (map == VM_MAP_NULL)
8164 return(KERN_INVALID_ARGUMENT);
8165
8166 submap_info = (vm_region_submap_info_t) info;
8167 *count = VM_REGION_SUBMAP_INFO_COUNT;
8168
8169 if (*count < VM_REGION_SUBMAP_INFO_COUNT)
8170 return(KERN_INVALID_ARGUMENT);
8171
8172 start = *address;
8173 base_map = map;
8174 recurse_count = *nesting_depth;
8175
8176 LOOKUP_NEXT_BASE_ENTRY:
8177 vm_map_lock_read(map);
8178 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8179 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8180 vm_map_unlock_read(map);
8181 return(KERN_INVALID_ADDRESS);
8182 }
8183 } else {
8184 entry = tmp_entry;
8185 }
8186 *size = entry->vme_end - entry->vme_start;
8187 start = entry->vme_start;
8188 base_addr = start;
8189 baddr_start_delta = *address - start;
8190 base_next = entry->vme_end;
8191 base_entry = entry;
8192
8193 while(entry->is_sub_map && recurse_count) {
8194 recurse_count--;
8195 vm_map_lock_read(entry->object.sub_map);
8196
8197
8198 if(entry == base_entry) {
8199 start = entry->offset;
8200 start += *address - entry->vme_start;
8201 }
8202
8203 submap = entry->object.sub_map;
8204 vm_map_unlock_read(map);
8205 map = submap;
8206
8207 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8208 if ((entry = tmp_entry->vme_next)
8209 == vm_map_to_entry(map)) {
8210 vm_map_unlock_read(map);
8211 map = base_map;
8212 start = base_next;
8213 recurse_count = 0;
8214 *nesting_depth = 0;
8215 goto LOOKUP_NEXT_BASE_ENTRY;
8216 }
8217 } else {
8218 entry = tmp_entry;
8219
8220 }
8221 if(start <= entry->vme_start) {
8222 vm_offset_t old_start = start;
8223 if(baddr_start_delta) {
8224 base_addr += (baddr_start_delta);
8225 *size -= baddr_start_delta;
8226 baddr_start_delta = 0;
8227 }
8228 if(base_next <=
8229 (base_addr += (entry->vme_start - start))) {
8230 vm_map_unlock_read(map);
8231 map = base_map;
8232 start = base_next;
8233 recurse_count = 0;
8234 *nesting_depth = 0;
8235 goto LOOKUP_NEXT_BASE_ENTRY;
8236 }
8237 *size -= entry->vme_start - start;
8238 if (*size > (entry->vme_end - entry->vme_start)) {
8239 *size = entry->vme_end - entry->vme_start;
8240 }
8241 start = 0;
8242 } else {
8243 if(baddr_start_delta) {
8244 if((start - entry->vme_start)
8245 < baddr_start_delta) {
8246 base_addr += start - entry->vme_start;
8247 *size -= start - entry->vme_start;
8248 } else {
8249 base_addr += baddr_start_delta;
8250 *size += baddr_start_delta;
8251 }
8252 baddr_start_delta = 0;
8253 }
8254 base_addr += entry->vme_start;
8255 if(base_addr >= base_next) {
8256 vm_map_unlock_read(map);
8257 map = base_map;
8258 start = base_next;
8259 recurse_count = 0;
8260 *nesting_depth = 0;
8261 goto LOOKUP_NEXT_BASE_ENTRY;
8262 }
8263 if (*size > (entry->vme_end - start))
8264 *size = entry->vme_end - start;
8265
8266 start = entry->vme_start - start;
8267 }
8268
8269 start += entry->offset;
8270
8271 }
8272 *nesting_depth -= recurse_count;
8273 if(entry != base_entry) {
8274 start = entry->vme_start + (start - entry->offset);
8275 }
8276
8277
8278 submap_info->user_tag = entry->alias;
8279 submap_info->offset = entry->offset;
8280 submap_info->protection = entry->protection;
8281 submap_info->inheritance = entry->inheritance;
8282 submap_info->max_protection = entry->max_protection;
8283 submap_info->behavior = entry->behavior;
8284 submap_info->user_wired_count = entry->user_wired_count;
8285 submap_info->is_submap = entry->is_sub_map;
8286 submap_info->object_id = (vm_offset_t)entry->object.vm_object;
8287 *address = base_addr;
8288
8289
8290 extended.pages_resident = 0;
8291 extended.pages_swapped_out = 0;
8292 extended.pages_shared_now_private = 0;
8293 extended.pages_referenced = 0;
8294 extended.external_pager = 0;
8295 extended.shadow_depth = 0;
8296
8297 if(!entry->is_sub_map) {
8298 vm_region_walk(entry, &extended, entry->offset,
8299 entry->vme_end - start, map, start);
8300 submap_info->share_mode = extended.share_mode;
8301 if (extended.external_pager && extended.ref_count == 2
8302 && extended.share_mode == SM_SHARED)
8303 submap_info->share_mode = SM_PRIVATE;
8304 submap_info->ref_count = extended.ref_count;
8305 } else {
8306 if(entry->use_pmap)
8307 submap_info->share_mode = SM_TRUESHARED;
8308 else
8309 submap_info->share_mode = SM_PRIVATE;
8310 submap_info->ref_count = entry->object.sub_map->ref_count;
8311 }
8312
8313 submap_info->pages_resident = extended.pages_resident;
8314 submap_info->pages_swapped_out = extended.pages_swapped_out;
8315 submap_info->pages_shared_now_private =
8316 extended.pages_shared_now_private;
8317 submap_info->pages_referenced = extended.pages_referenced;
8318 submap_info->external_pager = extended.external_pager;
8319 submap_info->shadow_depth = extended.shadow_depth;
8320
8321 vm_map_unlock_read(map);
8322 return(KERN_SUCCESS);
8323 }
8324
8325 /*
8326 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
8327 * Goes away after regular vm_region_recurse function migrates to
8328 * 64 bits
8329 * vm_region_recurse: A form of vm_region which follows the
8330 * submaps in a target map
8331 *
8332 */
8333
8334 kern_return_t
8335 vm_region_recurse_64(
8336 vm_map_t map,
8337 vm_offset_t *address, /* IN/OUT */
8338 vm_size_t *size, /* OUT */
8339 natural_t *nesting_depth, /* IN/OUT */
8340 vm_region_recurse_info_t info, /* IN/OUT */
8341 mach_msg_type_number_t *count) /* IN/OUT */
8342 {
8343 vm_map_entry_t tmp_entry;
8344 register
8345 vm_map_entry_t entry;
8346 register
8347 vm_offset_t start;
8348
8349 unsigned int recurse_count;
8350 vm_map_t submap;
8351 vm_map_t base_map;
8352 vm_map_entry_t base_entry;
8353 vm_offset_t base_next;
8354 vm_offset_t base_addr;
8355 vm_offset_t baddr_start_delta;
8356 vm_region_submap_info_64_t submap_info;
8357 vm_region_extended_info_data_t extended;
8358
8359 if (map == VM_MAP_NULL)
8360 return(KERN_INVALID_ARGUMENT);
8361
8362 submap_info = (vm_region_submap_info_64_t) info;
8363 *count = VM_REGION_SUBMAP_INFO_COUNT;
8364
8365 if (*count < VM_REGION_SUBMAP_INFO_COUNT)
8366 return(KERN_INVALID_ARGUMENT);
8367
8368 start = *address;
8369 base_map = map;
8370 recurse_count = *nesting_depth;
8371
8372 LOOKUP_NEXT_BASE_ENTRY:
8373 vm_map_lock_read(map);
8374 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8375 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8376 vm_map_unlock_read(map);
8377 return(KERN_INVALID_ADDRESS);
8378 }
8379 } else {
8380 entry = tmp_entry;
8381 }
8382 *size = entry->vme_end - entry->vme_start;
8383 start = entry->vme_start;
8384 base_addr = start;
8385 baddr_start_delta = *address - start;
8386 base_next = entry->vme_end;
8387 base_entry = entry;
8388
8389 while(entry->is_sub_map && recurse_count) {
8390 recurse_count--;
8391 vm_map_lock_read(entry->object.sub_map);
8392
8393
8394 if(entry == base_entry) {
8395 start = entry->offset;
8396 start += *address - entry->vme_start;
8397 }
8398
8399 submap = entry->object.sub_map;
8400 vm_map_unlock_read(map);
8401 map = submap;
8402
8403 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8404 if ((entry = tmp_entry->vme_next)
8405 == vm_map_to_entry(map)) {
8406 vm_map_unlock_read(map);
8407 map = base_map;
8408 start = base_next;
8409 recurse_count = 0;
8410 *nesting_depth = 0;
8411 goto LOOKUP_NEXT_BASE_ENTRY;
8412 }
8413 } else {
8414 entry = tmp_entry;
8415
8416 }
8417 if(start <= entry->vme_start) {
8418 vm_offset_t old_start = start;
8419 if(baddr_start_delta) {
8420 base_addr += (baddr_start_delta);
8421 *size -= baddr_start_delta;
8422 baddr_start_delta = 0;
8423 }
8424 if(base_next <=
8425 (base_addr += (entry->vme_start - start))) {
8426 vm_map_unlock_read(map);
8427 map = base_map;
8428 start = base_next;
8429 recurse_count = 0;
8430 *nesting_depth = 0;
8431 goto LOOKUP_NEXT_BASE_ENTRY;
8432 }
8433 *size -= entry->vme_start - start;
8434 if (*size > (entry->vme_end - entry->vme_start)) {
8435 *size = entry->vme_end - entry->vme_start;
8436 }
8437 start = 0;
8438 } else {
8439 if(baddr_start_delta) {
8440 if((start - entry->vme_start)
8441 < baddr_start_delta) {
8442 base_addr += start - entry->vme_start;
8443 *size -= start - entry->vme_start;
8444 } else {
8445 base_addr += baddr_start_delta;
8446 *size += baddr_start_delta;
8447 }
8448 baddr_start_delta = 0;
8449 }
8450 base_addr += entry->vme_start;
8451 if(base_addr >= base_next) {
8452 vm_map_unlock_read(map);
8453 map = base_map;
8454 start = base_next;
8455 recurse_count = 0;
8456 *nesting_depth = 0;
8457 goto LOOKUP_NEXT_BASE_ENTRY;
8458 }
8459 if (*size > (entry->vme_end - start))
8460 *size = entry->vme_end - start;
8461
8462 start = entry->vme_start - start;
8463 }
8464
8465 start += entry->offset;
8466
8467 }
8468 *nesting_depth -= recurse_count;
8469 if(entry != base_entry) {
8470 start = entry->vme_start + (start - entry->offset);
8471 }
8472
8473
8474 submap_info->user_tag = entry->alias;
8475 submap_info->offset = entry->offset;
8476 submap_info->protection = entry->protection;
8477 submap_info->inheritance = entry->inheritance;
8478 submap_info->max_protection = entry->max_protection;
8479 submap_info->behavior = entry->behavior;
8480 submap_info->user_wired_count = entry->user_wired_count;
8481 submap_info->is_submap = entry->is_sub_map;
8482 submap_info->object_id = (vm_offset_t)entry->object.vm_object;
8483 *address = base_addr;
8484
8485
8486 extended.pages_resident = 0;
8487 extended.pages_swapped_out = 0;
8488 extended.pages_shared_now_private = 0;
8489 extended.pages_referenced = 0;
8490 extended.external_pager = 0;
8491 extended.shadow_depth = 0;
8492
8493 if(!entry->is_sub_map) {
8494 vm_region_walk(entry, &extended, entry->offset,
8495 entry->vme_end - start, map, start);
8496 submap_info->share_mode = extended.share_mode;
8497 if (extended.external_pager && extended.ref_count == 2
8498 && extended.share_mode == SM_SHARED)
8499 submap_info->share_mode = SM_PRIVATE;
8500 submap_info->ref_count = extended.ref_count;
8501 } else {
8502 if(entry->use_pmap)
8503 submap_info->share_mode = SM_TRUESHARED;
8504 else
8505 submap_info->share_mode = SM_PRIVATE;
8506 submap_info->ref_count = entry->object.sub_map->ref_count;
8507 }
8508
8509 submap_info->pages_resident = extended.pages_resident;
8510 submap_info->pages_swapped_out = extended.pages_swapped_out;
8511 submap_info->pages_shared_now_private =
8512 extended.pages_shared_now_private;
8513 submap_info->pages_referenced = extended.pages_referenced;
8514 submap_info->external_pager = extended.external_pager;
8515 submap_info->shadow_depth = extended.shadow_depth;
8516
8517 vm_map_unlock_read(map);
8518 return(KERN_SUCCESS);
8519 }
8520
8521
8522 /*
8523 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
8524 * Goes away after regular vm_region function migrates to
8525 * 64 bits
8526 */
8527
8528
8529 kern_return_t
8530 vm_region_64(
8531 vm_map_t map,
8532 vm_offset_t *address, /* IN/OUT */
8533 vm_size_t *size, /* OUT */
8534 vm_region_flavor_t flavor, /* IN */
8535 vm_region_info_t info, /* OUT */
8536 mach_msg_type_number_t *count, /* IN/OUT */
8537 ipc_port_t *object_name) /* OUT */
8538 {
8539 vm_map_entry_t tmp_entry;
8540 register
8541 vm_map_entry_t entry;
8542 register
8543 vm_offset_t start;
8544 vm_region_basic_info_64_t basic;
8545 vm_region_extended_info_t extended;
8546 vm_region_top_info_t top;
8547
8548 if (map == VM_MAP_NULL)
8549 return(KERN_INVALID_ARGUMENT);
8550
8551 switch (flavor) {
8552
8553 case VM_REGION_BASIC_INFO:
8554 {
8555 if (*count < VM_REGION_BASIC_INFO_COUNT)
8556 return(KERN_INVALID_ARGUMENT);
8557
8558 basic = (vm_region_basic_info_64_t) info;
8559 *count = VM_REGION_BASIC_INFO_COUNT;
8560
8561 vm_map_lock_read(map);
8562
8563 start = *address;
8564 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8565 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8566 vm_map_unlock_read(map);
8567 return(KERN_INVALID_ADDRESS);
8568 }
8569 } else {
8570 entry = tmp_entry;
8571 }
8572
8573 start = entry->vme_start;
8574
8575 basic->offset = entry->offset;
8576 basic->protection = entry->protection;
8577 basic->inheritance = entry->inheritance;
8578 basic->max_protection = entry->max_protection;
8579 basic->behavior = entry->behavior;
8580 basic->user_wired_count = entry->user_wired_count;
8581 basic->reserved = entry->is_sub_map;
8582 *address = start;
8583 *size = (entry->vme_end - start);
8584
8585 if (object_name) *object_name = IP_NULL;
8586 if (entry->is_sub_map) {
8587 basic->shared = FALSE;
8588 } else {
8589 basic->shared = entry->is_shared;
8590 }
8591
8592 vm_map_unlock_read(map);
8593 return(KERN_SUCCESS);
8594 }
8595 case VM_REGION_EXTENDED_INFO:
8596 {
8597
8598 if (*count < VM_REGION_EXTENDED_INFO_COUNT)
8599 return(KERN_INVALID_ARGUMENT);
8600
8601 extended = (vm_region_extended_info_t) info;
8602 *count = VM_REGION_EXTENDED_INFO_COUNT;
8603
8604 vm_map_lock_read(map);
8605
8606 start = *address;
8607 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8608 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8609 vm_map_unlock_read(map);
8610 return(KERN_INVALID_ADDRESS);
8611 }
8612 } else {
8613 entry = tmp_entry;
8614 }
8615 start = entry->vme_start;
8616
8617 extended->protection = entry->protection;
8618 extended->user_tag = entry->alias;
8619 extended->pages_resident = 0;
8620 extended->pages_swapped_out = 0;
8621 extended->pages_shared_now_private = 0;
8622 extended->pages_referenced = 0;
8623 extended->external_pager = 0;
8624 extended->shadow_depth = 0;
8625
8626 vm_region_walk(entry, extended, entry->offset, entry->vme_end - start, map, start);
8627
8628 if (extended->external_pager && extended->ref_count == 2 && extended->share_mode == SM_SHARED)
8629 extended->share_mode = SM_PRIVATE;
8630
8631 if (object_name)
8632 *object_name = IP_NULL;
8633 *address = start;
8634 *size = (entry->vme_end - start);
8635
8636 vm_map_unlock_read(map);
8637 return(KERN_SUCCESS);
8638 }
8639 case VM_REGION_TOP_INFO:
8640 {
8641
8642 if (*count < VM_REGION_TOP_INFO_COUNT)
8643 return(KERN_INVALID_ARGUMENT);
8644
8645 top = (vm_region_top_info_t) info;
8646 *count = VM_REGION_TOP_INFO_COUNT;
8647
8648 vm_map_lock_read(map);
8649
8650 start = *address;
8651 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
8652 if ((entry = tmp_entry->vme_next) == vm_map_to_entry(map)) {
8653 vm_map_unlock_read(map);
8654 return(KERN_INVALID_ADDRESS);
8655 }
8656 } else {
8657 entry = tmp_entry;
8658
8659 }
8660 start = entry->vme_start;
8661
8662 top->private_pages_resident = 0;
8663 top->shared_pages_resident = 0;
8664
8665 vm_region_top_walk(entry, top);
8666
8667 if (object_name)
8668 *object_name = IP_NULL;
8669 *address = start;
8670 *size = (entry->vme_end - start);
8671
8672 vm_map_unlock_read(map);
8673 return(KERN_SUCCESS);
8674 }
8675 default:
8676 return(KERN_INVALID_ARGUMENT);
8677 }
8678 }
8679
8680 void
8681 vm_region_top_walk(
8682 vm_map_entry_t entry,
8683 vm_region_top_info_t top)
8684 {
8685 register struct vm_object *obj, *tmp_obj;
8686
8687 if (entry->object.vm_object == 0) {
8688 top->share_mode = SM_EMPTY;
8689 top->ref_count = 0;
8690 top->obj_id = 0;
8691 return;
8692 }
8693 if (entry->is_sub_map)
8694 vm_region_top_walk((vm_map_entry_t)entry->object.sub_map, top);
8695 else {
8696 obj = entry->object.vm_object;
8697
8698 vm_object_lock(obj);
8699
8700 if (obj->shadow) {
8701 if (obj->ref_count == 1)
8702 top->private_pages_resident = obj->resident_page_count;
8703 else
8704 top->shared_pages_resident = obj->resident_page_count;
8705 top->ref_count = obj->ref_count;
8706 top->share_mode = SM_COW;
8707
8708 while (tmp_obj = obj->shadow) {
8709 vm_object_lock(tmp_obj);
8710 vm_object_unlock(obj);
8711 obj = tmp_obj;
8712
8713 top->shared_pages_resident += obj->resident_page_count;
8714 top->ref_count += obj->ref_count - 1;
8715 }
8716 } else {
8717 if (entry->needs_copy) {
8718 top->share_mode = SM_COW;
8719 top->shared_pages_resident = obj->resident_page_count;
8720 } else {
8721 if (obj->ref_count == 1 ||
8722 (obj->ref_count == 2 && !(obj->pager_trusted) && !(obj->internal))) {
8723 top->share_mode = SM_PRIVATE;
8724 top->private_pages_resident = obj->resident_page_count;
8725 } else {
8726 top->share_mode = SM_SHARED;
8727 top->shared_pages_resident = obj->resident_page_count;
8728 }
8729 }
8730 top->ref_count = obj->ref_count;
8731 }
8732 top->obj_id = (int)obj;
8733
8734 vm_object_unlock(obj);
8735 }
8736 }
8737
8738 void
8739 vm_region_walk(
8740 vm_map_entry_t entry,
8741 vm_region_extended_info_t extended,
8742 vm_object_offset_t offset,
8743 vm_offset_t range,
8744 vm_map_t map,
8745 vm_offset_t va)
8746 {
8747 register struct vm_object *obj, *tmp_obj;
8748 register vm_offset_t last_offset;
8749 register int i;
8750 void vm_region_look_for_page();
8751
8752 if (entry->object.vm_object == 0) {
8753 extended->share_mode = SM_EMPTY;
8754 extended->ref_count = 0;
8755 return;
8756 }
8757 if (entry->is_sub_map)
8758 vm_region_walk((vm_map_entry_t)entry->object.sub_map, extended, offset + entry->offset,
8759 range, map, va);
8760 else {
8761 obj = entry->object.vm_object;
8762
8763 vm_object_lock(obj);
8764
8765 for (last_offset = offset + range; offset < last_offset; offset += PAGE_SIZE_64, va += PAGE_SIZE)
8766 vm_region_look_for_page(obj, extended, offset, obj->ref_count, 0, map, va);
8767
8768 if (extended->shadow_depth || entry->needs_copy)
8769 extended->share_mode = SM_COW;
8770 else {
8771 if (obj->ref_count == 1)
8772 extended->share_mode = SM_PRIVATE;
8773 else {
8774 if (obj->true_share)
8775 extended->share_mode = SM_TRUESHARED;
8776 else
8777 extended->share_mode = SM_SHARED;
8778 }
8779 }
8780 extended->ref_count = obj->ref_count - extended->shadow_depth;
8781
8782 for (i = 0; i < extended->shadow_depth; i++) {
8783 if ((tmp_obj = obj->shadow) == 0)
8784 break;
8785 vm_object_lock(tmp_obj);
8786 vm_object_unlock(obj);
8787 extended->ref_count += tmp_obj->ref_count;
8788 obj = tmp_obj;
8789 }
8790 vm_object_unlock(obj);
8791
8792 if (extended->share_mode == SM_SHARED) {
8793 register vm_map_entry_t cur;
8794 register vm_map_entry_t last;
8795 int my_refs;
8796
8797 obj = entry->object.vm_object;
8798 last = vm_map_to_entry(map);
8799 my_refs = 0;
8800
8801 for (cur = vm_map_first_entry(map); cur != last; cur = cur->vme_next)
8802 my_refs += vm_region_count_obj_refs(cur, obj);
8803
8804 if (my_refs == obj->ref_count)
8805 extended->share_mode = SM_PRIVATE_ALIASED;
8806 else if (my_refs > 1)
8807 extended->share_mode = SM_SHARED_ALIASED;
8808 }
8809 }
8810 }
8811
8812
8813
8814 void
8815 vm_region_look_for_page(
8816 vm_object_t object,
8817 vm_region_extended_info_t extended,
8818 vm_object_offset_t offset,
8819 int max_refcnt,
8820 int depth,
8821 vm_map_t map,
8822 vm_offset_t va)
8823 {
8824 register vm_page_t p;
8825 register vm_object_t shadow;
8826
8827 shadow = object->shadow;
8828
8829 if ( !(object->pager_trusted) && !(object->internal))
8830 extended->external_pager = 1;
8831
8832 if ((p = vm_page_lookup(object, offset)) != VM_PAGE_NULL) {
8833 if (shadow && (max_refcnt == 1))
8834 extended->pages_shared_now_private++;
8835
8836 if (pmap_extract(vm_map_pmap(map), va))
8837 extended->pages_referenced++;
8838 extended->pages_resident++;
8839
8840 return;
8841 }
8842 if (object->existence_map) {
8843 if (vm_external_state_get(object->existence_map, offset) == VM_EXTERNAL_STATE_EXISTS) {
8844 if (shadow && (max_refcnt == 1))
8845 extended->pages_shared_now_private++;
8846 extended->pages_swapped_out++;
8847
8848 return;
8849 }
8850 }
8851 if (shadow) {
8852 vm_object_lock(shadow);
8853
8854 if (++depth > extended->shadow_depth)
8855 extended->shadow_depth = depth;
8856
8857 if (shadow->ref_count > max_refcnt)
8858 max_refcnt = shadow->ref_count;
8859
8860 vm_region_look_for_page(shadow, extended, offset + object->shadow_offset,
8861 max_refcnt, depth, map, va);
8862 vm_object_unlock(shadow);
8863
8864 return;
8865 }
8866 }
8867
8868
8869 vm_region_count_obj_refs(
8870 vm_map_entry_t entry,
8871 vm_object_t object)
8872 {
8873 register int ref_count;
8874 register vm_object_t chk_obj;
8875 register vm_object_t tmp_obj;
8876
8877 if (entry->object.vm_object == 0)
8878 return(0);
8879
8880 if (entry->is_sub_map)
8881 ref_count = vm_region_count_obj_refs((vm_map_entry_t)entry->object.sub_map, object);
8882 else {
8883 ref_count = 0;
8884
8885 chk_obj = entry->object.vm_object;
8886 vm_object_lock(chk_obj);
8887
8888 while (chk_obj) {
8889 if (chk_obj == object)
8890 ref_count++;
8891 if (tmp_obj = chk_obj->shadow)
8892 vm_object_lock(tmp_obj);
8893 vm_object_unlock(chk_obj);
8894
8895 chk_obj = tmp_obj;
8896 }
8897 }
8898 return(ref_count);
8899 }
8900
8901
8902 /*
8903 * Routine: vm_map_simplify
8904 *
8905 * Description:
8906 * Attempt to simplify the map representation in
8907 * the vicinity of the given starting address.
8908 * Note:
8909 * This routine is intended primarily to keep the
8910 * kernel maps more compact -- they generally don't
8911 * benefit from the "expand a map entry" technology
8912 * at allocation time because the adjacent entry
8913 * is often wired down.
8914 */
8915 void
8916 vm_map_simplify(
8917 vm_map_t map,
8918 vm_offset_t start)
8919 {
8920 vm_map_entry_t this_entry;
8921 vm_map_entry_t prev_entry;
8922 vm_map_entry_t next_entry;
8923
8924 vm_map_lock(map);
8925 if (
8926 (vm_map_lookup_entry(map, start, &this_entry)) &&
8927 ((prev_entry = this_entry->vme_prev) != vm_map_to_entry(map)) &&
8928
8929 (prev_entry->vme_end == this_entry->vme_start) &&
8930
8931 (prev_entry->is_shared == FALSE) &&
8932 (prev_entry->is_sub_map == FALSE) &&
8933
8934 (this_entry->is_shared == FALSE) &&
8935 (this_entry->is_sub_map == FALSE) &&
8936
8937 (prev_entry->inheritance == this_entry->inheritance) &&
8938 (prev_entry->protection == this_entry->protection) &&
8939 (prev_entry->max_protection == this_entry->max_protection) &&
8940 (prev_entry->behavior == this_entry->behavior) &&
8941 (prev_entry->wired_count == this_entry->wired_count) &&
8942 (prev_entry->user_wired_count == this_entry->user_wired_count)&&
8943 (prev_entry->in_transition == FALSE) &&
8944 (this_entry->in_transition == FALSE) &&
8945
8946 (prev_entry->needs_copy == this_entry->needs_copy) &&
8947
8948 (prev_entry->object.vm_object == this_entry->object.vm_object)&&
8949 ((prev_entry->offset +
8950 (prev_entry->vme_end - prev_entry->vme_start))
8951 == this_entry->offset)
8952 ) {
8953 SAVE_HINT(map, prev_entry);
8954 vm_map_entry_unlink(map, this_entry);
8955 prev_entry->vme_end = this_entry->vme_end;
8956 UPDATE_FIRST_FREE(map, map->first_free);
8957 vm_object_deallocate(this_entry->object.vm_object);
8958 vm_map_entry_dispose(map, this_entry);
8959 counter(c_vm_map_simplified_lower++);
8960 }
8961 if (
8962 (vm_map_lookup_entry(map, start, &this_entry)) &&
8963 ((next_entry = this_entry->vme_next) != vm_map_to_entry(map)) &&
8964
8965 (next_entry->vme_start == this_entry->vme_end) &&
8966
8967 (next_entry->is_shared == FALSE) &&
8968 (next_entry->is_sub_map == FALSE) &&
8969
8970 (next_entry->is_shared == FALSE) &&
8971 (next_entry->is_sub_map == FALSE) &&
8972
8973 (next_entry->inheritance == this_entry->inheritance) &&
8974 (next_entry->protection == this_entry->protection) &&
8975 (next_entry->max_protection == this_entry->max_protection) &&
8976 (next_entry->behavior == this_entry->behavior) &&
8977 (next_entry->wired_count == this_entry->wired_count) &&
8978 (next_entry->user_wired_count == this_entry->user_wired_count)&&
8979 (this_entry->in_transition == FALSE) &&
8980 (next_entry->in_transition == FALSE) &&
8981
8982 (next_entry->needs_copy == this_entry->needs_copy) &&
8983
8984 (next_entry->object.vm_object == this_entry->object.vm_object)&&
8985 ((this_entry->offset +
8986 (this_entry->vme_end - this_entry->vme_start))
8987 == next_entry->offset)
8988 ) {
8989 vm_map_entry_unlink(map, next_entry);
8990 this_entry->vme_end = next_entry->vme_end;
8991 UPDATE_FIRST_FREE(map, map->first_free);
8992 vm_object_deallocate(next_entry->object.vm_object);
8993 vm_map_entry_dispose(map, next_entry);
8994 counter(c_vm_map_simplified_upper++);
8995 }
8996 counter(c_vm_map_simplify_called++);
8997 vm_map_unlock(map);
8998 }
8999
9000
9001 /*
9002 * Routine: vm_map_machine_attribute
9003 * Purpose:
9004 * Provide machine-specific attributes to mappings,
9005 * such as cachability etc. for machines that provide
9006 * them. NUMA architectures and machines with big/strange
9007 * caches will use this.
9008 * Note:
9009 * Responsibilities for locking and checking are handled here,
9010 * everything else in the pmap module. If any non-volatile
9011 * information must be kept, the pmap module should handle
9012 * it itself. [This assumes that attributes do not
9013 * need to be inherited, which seems ok to me]
9014 */
9015 kern_return_t
9016 vm_map_machine_attribute(
9017 vm_map_t map,
9018 vm_offset_t address,
9019 vm_size_t size,
9020 vm_machine_attribute_t attribute,
9021 vm_machine_attribute_val_t* value) /* IN/OUT */
9022 {
9023 kern_return_t ret;
9024
9025 if (address < vm_map_min(map) ||
9026 (address + size) > vm_map_max(map))
9027 return KERN_INVALID_ADDRESS;
9028
9029 vm_map_lock(map);
9030
9031 ret = pmap_attribute(map->pmap, address, size, attribute, value);
9032
9033 vm_map_unlock(map);
9034
9035 return ret;
9036 }
9037
9038 /*
9039 * vm_map_behavior_set:
9040 *
9041 * Sets the paging reference behavior of the specified address
9042 * range in the target map. Paging reference behavior affects
9043 * how pagein operations resulting from faults on the map will be
9044 * clustered.
9045 */
9046 kern_return_t
9047 vm_map_behavior_set(
9048 vm_map_t map,
9049 vm_offset_t start,
9050 vm_offset_t end,
9051 vm_behavior_t new_behavior)
9052 {
9053 register vm_map_entry_t entry;
9054 vm_map_entry_t temp_entry;
9055
9056 XPR(XPR_VM_MAP,
9057 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
9058 (integer_t)map, start, end, new_behavior, 0);
9059
9060 switch (new_behavior) {
9061 case VM_BEHAVIOR_DEFAULT:
9062 case VM_BEHAVIOR_RANDOM:
9063 case VM_BEHAVIOR_SEQUENTIAL:
9064 case VM_BEHAVIOR_RSEQNTL:
9065 break;
9066 default:
9067 return(KERN_INVALID_ARGUMENT);
9068 }
9069
9070 vm_map_lock(map);
9071
9072 /*
9073 * The entire address range must be valid for the map.
9074 * Note that vm_map_range_check() does a
9075 * vm_map_lookup_entry() internally and returns the
9076 * entry containing the start of the address range if
9077 * the entire range is valid.
9078 */
9079 if (vm_map_range_check(map, start, end, &temp_entry)) {
9080 entry = temp_entry;
9081 vm_map_clip_start(map, entry, start);
9082 }
9083 else {
9084 vm_map_unlock(map);
9085 return(KERN_INVALID_ADDRESS);
9086 }
9087
9088 while ((entry != vm_map_to_entry(map)) && (entry->vme_start < end)) {
9089 vm_map_clip_end(map, entry, end);
9090
9091 entry->behavior = new_behavior;
9092
9093 entry = entry->vme_next;
9094 }
9095
9096 vm_map_unlock(map);
9097 return(KERN_SUCCESS);
9098 }
9099
9100
9101 int
9102 vm_map_copy_cont_is_valid(
9103 vm_map_copy_t copy)
9104 {
9105 vm_map_copy_cont_t cont;
9106
9107 assert(copy->type == VM_MAP_COPY_PAGE_LIST);
9108 cont = copy->cpy_cont;
9109 if (
9110 cont != vm_map_copy_discard_cont &&
9111 cont != vm_map_copyin_page_list_cont ) {
9112 printf("vm_map_copy_cont_is_valid: bogus cont 0x%x\n", cont);
9113 assert((integer_t) cont == 0xdeadbeef);
9114 }
9115 return 1;
9116 }
9117
9118 #include <mach_kdb.h>
9119 #if MACH_KDB
9120 #include <ddb/db_output.h>
9121 #include <vm/vm_print.h>
9122
9123 #define printf db_printf
9124
9125 /*
9126 * Forward declarations for internal functions.
9127 */
9128 extern void vm_map_links_print(
9129 struct vm_map_links *links);
9130
9131 extern void vm_map_header_print(
9132 struct vm_map_header *header);
9133
9134 extern void vm_map_entry_print(
9135 vm_map_entry_t entry);
9136
9137 extern void vm_follow_entry(
9138 vm_map_entry_t entry);
9139
9140 extern void vm_follow_map(
9141 vm_map_t map);
9142
9143 /*
9144 * vm_map_links_print: [ debug ]
9145 */
9146 void
9147 vm_map_links_print(
9148 struct vm_map_links *links)
9149 {
9150 iprintf("prev=0x%x, next=0x%x, start=0x%x, end=0x%x\n",
9151 links->prev,
9152 links->next,
9153 links->start,
9154 links->end);
9155 }
9156
9157 /*
9158 * vm_map_header_print: [ debug ]
9159 */
9160 void
9161 vm_map_header_print(
9162 struct vm_map_header *header)
9163 {
9164 vm_map_links_print(&header->links);
9165 iprintf("nentries=0x%x, %sentries_pageable\n",
9166 header->nentries,
9167 (header->entries_pageable ? "" : "!"));
9168 }
9169
9170 /*
9171 * vm_follow_entry: [ debug ]
9172 */
9173 void
9174 vm_follow_entry(
9175 vm_map_entry_t entry)
9176 {
9177 extern int db_indent;
9178 int shadows;
9179
9180 iprintf("map entry 0x%x:\n", entry);
9181
9182 db_indent += 2;
9183
9184 shadows = vm_follow_object(entry->object.vm_object);
9185 iprintf("Total objects : %d\n",shadows);
9186
9187 db_indent -= 2;
9188 }
9189
9190 /*
9191 * vm_map_entry_print: [ debug ]
9192 */
9193 void
9194 vm_map_entry_print(
9195 register vm_map_entry_t entry)
9196 {
9197 extern int db_indent;
9198 static char *inheritance_name[4] = { "share", "copy", "none", "?"};
9199 static char *behavior_name[4] = { "dflt", "rand", "seqtl", "rseqntl" };
9200
9201 iprintf("map entry 0x%x:\n", entry);
9202
9203 db_indent += 2;
9204
9205 vm_map_links_print(&entry->links);
9206
9207 iprintf("start=0x%x, end=0x%x, prot=%x/%x/%s\n",
9208 entry->vme_start,
9209 entry->vme_end,
9210 entry->protection,
9211 entry->max_protection,
9212 inheritance_name[(entry->inheritance & 0x3)]);
9213
9214 iprintf("behavior=%s, wired_count=%d, user_wired_count=%d\n",
9215 behavior_name[(entry->behavior & 0x3)],
9216 entry->wired_count,
9217 entry->user_wired_count);
9218 iprintf("%sin_transition, %sneeds_wakeup\n",
9219 (entry->in_transition ? "" : "!"),
9220 (entry->needs_wakeup ? "" : "!"));
9221
9222 if (entry->is_sub_map) {
9223 iprintf("submap=0x%x, offset=0x%x\n",
9224 entry->object.sub_map,
9225 entry->offset);
9226 } else {
9227 iprintf("object=0x%x, offset=0x%x, ",
9228 entry->object.vm_object,
9229 entry->offset);
9230 printf("%sis_shared, %sneeds_copy\n",
9231 (entry->is_shared ? "" : "!"),
9232 (entry->needs_copy ? "" : "!"));
9233 }
9234
9235 db_indent -= 2;
9236 }
9237
9238 /*
9239 * vm_follow_map: [ debug ]
9240 */
9241 void
9242 vm_follow_map(
9243 vm_map_t map)
9244 {
9245 register vm_map_entry_t entry;
9246 extern int db_indent;
9247
9248 iprintf("task map 0x%x:\n", map);
9249
9250 db_indent += 2;
9251
9252 for (entry = vm_map_first_entry(map);
9253 entry && entry != vm_map_to_entry(map);
9254 entry = entry->vme_next) {
9255 vm_follow_entry(entry);
9256 }
9257
9258 db_indent -= 2;
9259 }
9260
9261 /*
9262 * vm_map_print: [ debug ]
9263 */
9264 void
9265 vm_map_print(
9266 register vm_map_t map)
9267 {
9268 register vm_map_entry_t entry;
9269 extern int db_indent;
9270 char *swstate;
9271
9272 iprintf("task map 0x%x:\n", map);
9273
9274 db_indent += 2;
9275
9276 vm_map_header_print(&map->hdr);
9277
9278 iprintf("pmap=0x%x, size=%d, ref=%d, hint=0x%x, first_free=0x%x\n",
9279 map->pmap,
9280 map->size,
9281 map->ref_count,
9282 map->hint,
9283 map->first_free);
9284
9285 iprintf("%swait_for_space, %swiring_required, timestamp=%d\n",
9286 (map->wait_for_space ? "" : "!"),
9287 (map->wiring_required ? "" : "!"),
9288 map->timestamp);
9289
9290 #if TASK_SWAPPER
9291 switch (map->sw_state) {
9292 case MAP_SW_IN:
9293 swstate = "SW_IN";
9294 break;
9295 case MAP_SW_OUT:
9296 swstate = "SW_OUT";
9297 break;
9298 default:
9299 swstate = "????";
9300 break;
9301 }
9302 iprintf("res=%d, sw_state=%s\n", map->res_count, swstate);
9303 #endif /* TASK_SWAPPER */
9304
9305 for (entry = vm_map_first_entry(map);
9306 entry && entry != vm_map_to_entry(map);
9307 entry = entry->vme_next) {
9308 vm_map_entry_print(entry);
9309 }
9310
9311 db_indent -= 2;
9312 }
9313
9314 /*
9315 * Routine: vm_map_copy_print
9316 * Purpose:
9317 * Pretty-print a copy object for ddb.
9318 */
9319
9320 void
9321 vm_map_copy_print(
9322 vm_map_copy_t copy)
9323 {
9324 extern int db_indent;
9325 int i, npages;
9326 vm_map_entry_t entry;
9327
9328 printf("copy object 0x%x\n", copy);
9329
9330 db_indent += 2;
9331
9332 iprintf("type=%d", copy->type);
9333 switch (copy->type) {
9334 case VM_MAP_COPY_ENTRY_LIST:
9335 printf("[entry_list]");
9336 break;
9337
9338 case VM_MAP_COPY_OBJECT:
9339 printf("[object]");
9340 break;
9341
9342 case VM_MAP_COPY_PAGE_LIST:
9343 printf("[page_list]");
9344 break;
9345
9346 case VM_MAP_COPY_KERNEL_BUFFER:
9347 printf("[kernel_buffer]");
9348 break;
9349
9350 default:
9351 printf("[bad type]");
9352 break;
9353 }
9354 printf(", offset=0x%x", copy->offset);
9355 printf(", size=0x%x\n", copy->size);
9356
9357 switch (copy->type) {
9358 case VM_MAP_COPY_ENTRY_LIST:
9359 vm_map_header_print(&copy->cpy_hdr);
9360 for (entry = vm_map_copy_first_entry(copy);
9361 entry && entry != vm_map_copy_to_entry(copy);
9362 entry = entry->vme_next) {
9363 vm_map_entry_print(entry);
9364 }
9365 break;
9366
9367 case VM_MAP_COPY_OBJECT:
9368 iprintf("object=0x%x\n", copy->cpy_object);
9369 break;
9370
9371 case VM_MAP_COPY_KERNEL_BUFFER:
9372 iprintf("kernel buffer=0x%x", copy->cpy_kdata);
9373 printf(", kalloc_size=0x%x\n", copy->cpy_kalloc_size);
9374 break;
9375
9376 case VM_MAP_COPY_PAGE_LIST:
9377 iprintf("npages=%d", copy->cpy_npages);
9378 printf(", cont=%x", copy->cpy_cont);
9379 printf(", cont_args=%x\n", copy->cpy_cont_args);
9380 if (copy->cpy_npages < 0) {
9381 npages = 0;
9382 } else if (copy->cpy_npages > VM_MAP_COPY_PAGE_LIST_MAX) {
9383 npages = VM_MAP_COPY_PAGE_LIST_MAX;
9384 } else {
9385 npages = copy->cpy_npages;
9386 }
9387 iprintf("copy->cpy_page_list[0..%d] = {", npages);
9388 for (i = 0; i < npages - 1; i++) {
9389 printf("0x%x, ", copy->cpy_page_list[i]);
9390 }
9391 if (npages > 0) {
9392 printf("0x%x", copy->cpy_page_list[npages - 1]);
9393 }
9394 printf("}\n");
9395 break;
9396 }
9397
9398 db_indent -=2;
9399 }
9400
9401 /*
9402 * db_vm_map_total_size(map) [ debug ]
9403 *
9404 * return the total virtual size (in bytes) of the map
9405 */
9406 vm_size_t
9407 db_vm_map_total_size(
9408 vm_map_t map)
9409 {
9410 vm_map_entry_t entry;
9411 vm_size_t total;
9412
9413 total = 0;
9414 for (entry = vm_map_first_entry(map);
9415 entry != vm_map_to_entry(map);
9416 entry = entry->vme_next) {
9417 total += entry->vme_end - entry->vme_start;
9418 }
9419
9420 return total;
9421 }
9422
9423 #endif /* MACH_KDB */
9424
9425 /*
9426 * Routine: vm_map_entry_insert
9427 *
9428 * Descritpion: This routine inserts a new vm_entry in a locked map.
9429 */
9430 vm_map_entry_t
9431 vm_map_entry_insert(
9432 vm_map_t map,
9433 vm_map_entry_t insp_entry,
9434 vm_offset_t start,
9435 vm_offset_t end,
9436 vm_object_t object,
9437 vm_object_offset_t offset,
9438 boolean_t needs_copy,
9439 boolean_t is_shared,
9440 boolean_t in_transition,
9441 vm_prot_t cur_protection,
9442 vm_prot_t max_protection,
9443 vm_behavior_t behavior,
9444 vm_inherit_t inheritance,
9445 unsigned wired_count)
9446 {
9447 vm_map_entry_t new_entry;
9448
9449 assert(insp_entry != (vm_map_entry_t)0);
9450
9451 new_entry = vm_map_entry_create(map);
9452
9453 new_entry->vme_start = start;
9454 new_entry->vme_end = end;
9455 assert(page_aligned(new_entry->vme_start));
9456 assert(page_aligned(new_entry->vme_end));
9457
9458 new_entry->object.vm_object = object;
9459 new_entry->offset = offset;
9460 new_entry->is_shared = is_shared;
9461 new_entry->is_sub_map = FALSE;
9462 new_entry->needs_copy = needs_copy;
9463 new_entry->in_transition = in_transition;
9464 new_entry->needs_wakeup = FALSE;
9465 new_entry->inheritance = inheritance;
9466 new_entry->protection = cur_protection;
9467 new_entry->max_protection = max_protection;
9468 new_entry->behavior = behavior;
9469 new_entry->wired_count = wired_count;
9470 new_entry->user_wired_count = 0;
9471 new_entry->use_pmap = FALSE;
9472
9473 /*
9474 * Insert the new entry into the list.
9475 */
9476
9477 vm_map_entry_link(map, insp_entry, new_entry);
9478 map->size += end - start;
9479
9480 /*
9481 * Update the free space hint and the lookup hint.
9482 */
9483
9484 SAVE_HINT(map, new_entry);
9485 return new_entry;
9486 }
9487
9488 /*
9489 * Routine: vm_remap_extract
9490 *
9491 * Descritpion: This routine returns a vm_entry list from a map.
9492 */
9493 kern_return_t
9494 vm_remap_extract(
9495 vm_map_t map,
9496 vm_offset_t addr,
9497 vm_size_t size,
9498 boolean_t copy,
9499 struct vm_map_header *map_header,
9500 vm_prot_t *cur_protection,
9501 vm_prot_t *max_protection,
9502 /* What, no behavior? */
9503 vm_inherit_t inheritance,
9504 boolean_t pageable)
9505 {
9506 kern_return_t result;
9507 vm_size_t mapped_size;
9508 vm_size_t tmp_size;
9509 vm_map_entry_t src_entry; /* result of last map lookup */
9510 vm_map_entry_t new_entry;
9511 vm_object_offset_t offset;
9512 vm_offset_t map_address;
9513 vm_offset_t src_start; /* start of entry to map */
9514 vm_offset_t src_end; /* end of region to be mapped */
9515 vm_object_t object;
9516 vm_map_version_t version;
9517 boolean_t src_needs_copy;
9518 boolean_t new_entry_needs_copy;
9519
9520 assert(map != VM_MAP_NULL);
9521 assert(size != 0 && size == round_page(size));
9522 assert(inheritance == VM_INHERIT_NONE ||
9523 inheritance == VM_INHERIT_COPY ||
9524 inheritance == VM_INHERIT_SHARE);
9525
9526 /*
9527 * Compute start and end of region.
9528 */
9529 src_start = trunc_page(addr);
9530 src_end = round_page(src_start + size);
9531
9532 /*
9533 * Initialize map_header.
9534 */
9535 map_header->links.next = (struct vm_map_entry *)&map_header->links;
9536 map_header->links.prev = (struct vm_map_entry *)&map_header->links;
9537 map_header->nentries = 0;
9538 map_header->entries_pageable = pageable;
9539
9540 *cur_protection = VM_PROT_ALL;
9541 *max_protection = VM_PROT_ALL;
9542
9543 map_address = 0;
9544 mapped_size = 0;
9545 result = KERN_SUCCESS;
9546
9547 /*
9548 * The specified source virtual space might correspond to
9549 * multiple map entries, need to loop on them.
9550 */
9551 vm_map_lock(map);
9552 while (mapped_size != size) {
9553 vm_size_t entry_size;
9554
9555 /*
9556 * Find the beginning of the region.
9557 */
9558 if (! vm_map_lookup_entry(map, src_start, &src_entry)) {
9559 result = KERN_INVALID_ADDRESS;
9560 break;
9561 }
9562
9563 if (src_start < src_entry->vme_start ||
9564 (mapped_size && src_start != src_entry->vme_start)) {
9565 result = KERN_INVALID_ADDRESS;
9566 break;
9567 }
9568
9569 if(src_entry->is_sub_map) {
9570 result = KERN_INVALID_ADDRESS;
9571 break;
9572 }
9573
9574 tmp_size = size - mapped_size;
9575 if (src_end > src_entry->vme_end)
9576 tmp_size -= (src_end - src_entry->vme_end);
9577
9578 entry_size = (vm_size_t)(src_entry->vme_end -
9579 src_entry->vme_start);
9580
9581 if(src_entry->is_sub_map) {
9582 vm_map_reference(src_entry->object.sub_map);
9583 } else {
9584 object = src_entry->object.vm_object;
9585
9586 if (object == VM_OBJECT_NULL) {
9587 object = vm_object_allocate(entry_size);
9588 src_entry->offset = 0;
9589 src_entry->object.vm_object = object;
9590 } else if (object->copy_strategy !=
9591 MEMORY_OBJECT_COPY_SYMMETRIC) {
9592 /*
9593 * We are already using an asymmetric
9594 * copy, and therefore we already have
9595 * the right object.
9596 */
9597 assert(!src_entry->needs_copy);
9598 } else if (src_entry->needs_copy || object->shadowed ||
9599 (object->internal && !object->true_share &&
9600 !src_entry->is_shared &&
9601 object->size > entry_size)) {
9602
9603 vm_object_shadow(&src_entry->object.vm_object,
9604 &src_entry->offset,
9605 entry_size);
9606
9607 if (!src_entry->needs_copy &&
9608 (src_entry->protection & VM_PROT_WRITE)) {
9609 pmap_protect(vm_map_pmap(map),
9610 src_entry->vme_start,
9611 src_entry->vme_end,
9612 src_entry->protection &
9613 ~VM_PROT_WRITE);
9614 }
9615
9616 object = src_entry->object.vm_object;
9617 src_entry->needs_copy = FALSE;
9618 }
9619
9620
9621 vm_object_lock(object);
9622 object->ref_count++; /* object ref. for new entry */
9623 VM_OBJ_RES_INCR(object);
9624 if (object->copy_strategy ==
9625 MEMORY_OBJECT_COPY_SYMMETRIC) {
9626 object->copy_strategy =
9627 MEMORY_OBJECT_COPY_DELAY;
9628 }
9629 vm_object_unlock(object);
9630 }
9631
9632 offset = src_entry->offset + (src_start - src_entry->vme_start);
9633
9634 new_entry = _vm_map_entry_create(map_header);
9635 vm_map_entry_copy(new_entry, src_entry);
9636 new_entry->use_pmap = FALSE; /* clr address space specifics */
9637
9638 new_entry->vme_start = map_address;
9639 new_entry->vme_end = map_address + tmp_size;
9640 new_entry->inheritance = inheritance;
9641 new_entry->offset = offset;
9642
9643 /*
9644 * The new region has to be copied now if required.
9645 */
9646 RestartCopy:
9647 if (!copy) {
9648 src_entry->is_shared = TRUE;
9649 new_entry->is_shared = TRUE;
9650 if (!(new_entry->is_sub_map))
9651 new_entry->needs_copy = FALSE;
9652
9653 } else if (src_entry->is_sub_map) {
9654 /* make this a COW sub_map if not already */
9655 new_entry->needs_copy = TRUE;
9656 } else if (src_entry->wired_count == 0 &&
9657 vm_object_copy_quickly(&new_entry->object.vm_object,
9658 new_entry->offset,
9659 (new_entry->vme_end -
9660 new_entry->vme_start),
9661 &src_needs_copy,
9662 &new_entry_needs_copy)) {
9663
9664 new_entry->needs_copy = new_entry_needs_copy;
9665 new_entry->is_shared = FALSE;
9666
9667 /*
9668 * Handle copy_on_write semantics.
9669 */
9670 if (src_needs_copy && !src_entry->needs_copy) {
9671 vm_object_pmap_protect(object,
9672 offset,
9673 entry_size,
9674 (src_entry->is_shared ?
9675 PMAP_NULL : map->pmap),
9676 src_entry->vme_start,
9677 src_entry->protection &
9678 ~VM_PROT_WRITE);
9679
9680 src_entry->needs_copy = TRUE;
9681 }
9682 /*
9683 * Throw away the old object reference of the new entry.
9684 */
9685 vm_object_deallocate(object);
9686
9687 } else {
9688 new_entry->is_shared = FALSE;
9689
9690 /*
9691 * The map can be safely unlocked since we
9692 * already hold a reference on the object.
9693 *
9694 * Record the timestamp of the map for later
9695 * verification, and unlock the map.
9696 */
9697 version.main_timestamp = map->timestamp;
9698 vm_map_unlock(map);
9699
9700 /*
9701 * Perform the copy.
9702 */
9703 if (src_entry->wired_count > 0) {
9704 vm_object_lock(object);
9705 result = vm_object_copy_slowly(
9706 object,
9707 offset,
9708 entry_size,
9709 THREAD_UNINT,
9710 &new_entry->object.vm_object);
9711
9712 new_entry->offset = 0;
9713 new_entry->needs_copy = FALSE;
9714 } else {
9715 result = vm_object_copy_strategically(
9716 object,
9717 offset,
9718 entry_size,
9719 &new_entry->object.vm_object,
9720 &new_entry->offset,
9721 &new_entry_needs_copy);
9722
9723 new_entry->needs_copy = new_entry_needs_copy;
9724 }
9725
9726 /*
9727 * Throw away the old object reference of the new entry.
9728 */
9729 vm_object_deallocate(object);
9730
9731 if (result != KERN_SUCCESS &&
9732 result != KERN_MEMORY_RESTART_COPY) {
9733 _vm_map_entry_dispose(map_header, new_entry);
9734 break;
9735 }
9736
9737 /*
9738 * Verify that the map has not substantially
9739 * changed while the copy was being made.
9740 */
9741
9742 vm_map_lock(map); /* Increments timestamp once! */
9743 if (version.main_timestamp + 1 != map->timestamp) {
9744 /*
9745 * Simple version comparison failed.
9746 *
9747 * Retry the lookup and verify that the
9748 * same object/offset are still present.
9749 */
9750 vm_object_deallocate(new_entry->
9751 object.vm_object);
9752 _vm_map_entry_dispose(map_header, new_entry);
9753 if (result == KERN_MEMORY_RESTART_COPY)
9754 result = KERN_SUCCESS;
9755 continue;
9756 }
9757
9758 if (result == KERN_MEMORY_RESTART_COPY) {
9759 vm_object_reference(object);
9760 goto RestartCopy;
9761 }
9762 }
9763
9764 _vm_map_entry_link(map_header,
9765 map_header->links.prev, new_entry);
9766
9767 *cur_protection &= src_entry->protection;
9768 *max_protection &= src_entry->max_protection;
9769
9770 map_address += tmp_size;
9771 mapped_size += tmp_size;
9772 src_start += tmp_size;
9773
9774 } /* end while */
9775
9776 vm_map_unlock(map);
9777 if (result != KERN_SUCCESS) {
9778 /*
9779 * Free all allocated elements.
9780 */
9781 for (src_entry = map_header->links.next;
9782 src_entry != (struct vm_map_entry *)&map_header->links;
9783 src_entry = new_entry) {
9784 new_entry = src_entry->vme_next;
9785 _vm_map_entry_unlink(map_header, src_entry);
9786 vm_object_deallocate(src_entry->object.vm_object);
9787 _vm_map_entry_dispose(map_header, src_entry);
9788 }
9789 }
9790 return result;
9791 }
9792
9793 /*
9794 * Routine: vm_remap
9795 *
9796 * Map portion of a task's address space.
9797 * Mapped region must not overlap more than
9798 * one vm memory object. Protections and
9799 * inheritance attributes remain the same
9800 * as in the original task and are out parameters.
9801 * Source and Target task can be identical
9802 * Other attributes are identical as for vm_map()
9803 */
9804 kern_return_t
9805 vm_remap(
9806 vm_map_t target_map,
9807 vm_offset_t *address,
9808 vm_size_t size,
9809 vm_offset_t mask,
9810 boolean_t anywhere,
9811 vm_map_t src_map,
9812 vm_offset_t memory_address,
9813 boolean_t copy,
9814 vm_prot_t *cur_protection,
9815 vm_prot_t *max_protection,
9816 vm_inherit_t inheritance)
9817 {
9818 kern_return_t result;
9819 vm_map_entry_t entry;
9820 vm_map_entry_t insp_entry;
9821 vm_map_entry_t new_entry;
9822 struct vm_map_header map_header;
9823
9824 if (target_map == VM_MAP_NULL)
9825 return KERN_INVALID_ARGUMENT;
9826
9827 switch (inheritance) {
9828 case VM_INHERIT_NONE:
9829 case VM_INHERIT_COPY:
9830 case VM_INHERIT_SHARE:
9831 if (size != 0 && src_map != VM_MAP_NULL)
9832 break;
9833 /*FALL THRU*/
9834 default:
9835 return KERN_INVALID_ARGUMENT;
9836 }
9837
9838 size = round_page(size);
9839
9840 result = vm_remap_extract(src_map, memory_address,
9841 size, copy, &map_header,
9842 cur_protection,
9843 max_protection,
9844 inheritance,
9845 target_map->hdr.
9846 entries_pageable);
9847 vm_map_deallocate(src_map);
9848
9849 if (result != KERN_SUCCESS) {
9850 return result;
9851 }
9852
9853 /*
9854 * Allocate/check a range of free virtual address
9855 * space for the target
9856 */
9857 *address = trunc_page(*address);
9858 vm_map_lock(target_map);
9859 result = vm_remap_range_allocate(target_map, address, size,
9860 mask, anywhere, &insp_entry);
9861
9862 for (entry = map_header.links.next;
9863 entry != (struct vm_map_entry *)&map_header.links;
9864 entry = new_entry) {
9865 new_entry = entry->vme_next;
9866 _vm_map_entry_unlink(&map_header, entry);
9867 if (result == KERN_SUCCESS) {
9868 entry->vme_start += *address;
9869 entry->vme_end += *address;
9870 vm_map_entry_link(target_map, insp_entry, entry);
9871 insp_entry = entry;
9872 } else {
9873 if (!entry->is_sub_map) {
9874 vm_object_deallocate(entry->object.vm_object);
9875 } else {
9876 vm_map_deallocate(entry->object.sub_map);
9877 }
9878 _vm_map_entry_dispose(&map_header, entry);
9879 }
9880 }
9881
9882 if (result == KERN_SUCCESS) {
9883 target_map->size += size;
9884 SAVE_HINT(target_map, insp_entry);
9885 }
9886 vm_map_unlock(target_map);
9887
9888 if (result == KERN_SUCCESS && target_map->wiring_required)
9889 result = vm_map_wire(target_map, *address,
9890 *address + size, *cur_protection, TRUE);
9891 return result;
9892 }
9893
9894 /*
9895 * Routine: vm_remap_range_allocate
9896 *
9897 * Description:
9898 * Allocate a range in the specified virtual address map.
9899 * returns the address and the map entry just before the allocated
9900 * range
9901 *
9902 * Map must be locked.
9903 */
9904
9905 kern_return_t
9906 vm_remap_range_allocate(
9907 vm_map_t map,
9908 vm_offset_t *address, /* IN/OUT */
9909 vm_size_t size,
9910 vm_offset_t mask,
9911 boolean_t anywhere,
9912 vm_map_entry_t *map_entry) /* OUT */
9913 {
9914 register vm_map_entry_t entry;
9915 register vm_offset_t start;
9916 register vm_offset_t end;
9917 kern_return_t result = KERN_SUCCESS;
9918
9919 StartAgain: ;
9920
9921 start = *address;
9922
9923 if (anywhere)
9924 {
9925 /*
9926 * Calculate the first possible address.
9927 */
9928
9929 if (start < map->min_offset)
9930 start = map->min_offset;
9931 if (start > map->max_offset)
9932 return(KERN_NO_SPACE);
9933
9934 /*
9935 * Look for the first possible address;
9936 * if there's already something at this
9937 * address, we have to start after it.
9938 */
9939
9940 assert(first_free_is_valid(map));
9941 if (start == map->min_offset) {
9942 if ((entry = map->first_free) != vm_map_to_entry(map))
9943 start = entry->vme_end;
9944 } else {
9945 vm_map_entry_t tmp_entry;
9946 if (vm_map_lookup_entry(map, start, &tmp_entry))
9947 start = tmp_entry->vme_end;
9948 entry = tmp_entry;
9949 }
9950
9951 /*
9952 * In any case, the "entry" always precedes
9953 * the proposed new region throughout the
9954 * loop:
9955 */
9956
9957 while (TRUE) {
9958 register vm_map_entry_t next;
9959
9960 /*
9961 * Find the end of the proposed new region.
9962 * Be sure we didn't go beyond the end, or
9963 * wrap around the address.
9964 */
9965
9966 end = ((start + mask) & ~mask);
9967 if (end < start)
9968 return(KERN_NO_SPACE);
9969 start = end;
9970 end += size;
9971
9972 if ((end > map->max_offset) || (end < start)) {
9973 if (map->wait_for_space) {
9974 if (size <= (map->max_offset -
9975 map->min_offset)) {
9976 assert_wait((event_t) map, THREAD_INTERRUPTIBLE);
9977 vm_map_unlock(map);
9978 thread_block((void (*)(void))0);
9979 vm_map_lock(map);
9980 goto StartAgain;
9981 }
9982 }
9983
9984 return(KERN_NO_SPACE);
9985 }
9986
9987 /*
9988 * If there are no more entries, we must win.
9989 */
9990
9991 next = entry->vme_next;
9992 if (next == vm_map_to_entry(map))
9993 break;
9994
9995 /*
9996 * If there is another entry, it must be
9997 * after the end of the potential new region.
9998 */
9999
10000 if (next->vme_start >= end)
10001 break;
10002
10003 /*
10004 * Didn't fit -- move to the next entry.
10005 */
10006
10007 entry = next;
10008 start = entry->vme_end;
10009 }
10010 *address = start;
10011 } else {
10012 vm_map_entry_t temp_entry;
10013
10014 /*
10015 * Verify that:
10016 * the address doesn't itself violate
10017 * the mask requirement.
10018 */
10019
10020 if ((start & mask) != 0)
10021 return(KERN_NO_SPACE);
10022
10023
10024 /*
10025 * ... the address is within bounds
10026 */
10027
10028 end = start + size;
10029
10030 if ((start < map->min_offset) ||
10031 (end > map->max_offset) ||
10032 (start >= end)) {
10033 return(KERN_INVALID_ADDRESS);
10034 }
10035
10036 /*
10037 * ... the starting address isn't allocated
10038 */
10039
10040 if (vm_map_lookup_entry(map, start, &temp_entry))
10041 return(KERN_NO_SPACE);
10042
10043 entry = temp_entry;
10044
10045 /*
10046 * ... the next region doesn't overlap the
10047 * end point.
10048 */
10049
10050 if ((entry->vme_next != vm_map_to_entry(map)) &&
10051 (entry->vme_next->vme_start < end))
10052 return(KERN_NO_SPACE);
10053 }
10054 *map_entry = entry;
10055 return(KERN_SUCCESS);
10056 }
10057
10058 /*
10059 * vm_map_switch:
10060 *
10061 * Set the address map for the current thr_act to the specified map
10062 */
10063
10064 vm_map_t
10065 vm_map_switch(
10066 vm_map_t map)
10067 {
10068 int mycpu;
10069 thread_act_t thr_act = current_act();
10070 vm_map_t oldmap = thr_act->map;
10071
10072 mp_disable_preemption();
10073 mycpu = cpu_number();
10074
10075 /*
10076 * Deactivate the current map and activate the requested map
10077 */
10078 PMAP_SWITCH_USER(thr_act, map, mycpu);
10079
10080 mp_enable_preemption();
10081 return(oldmap);
10082 }
10083
10084
10085 /*
10086 * Routine: vm_map_write_user
10087 *
10088 * Description:
10089 * Copy out data from a kernel space into space in the
10090 * destination map. The space must already exist in the
10091 * destination map.
10092 * NOTE: This routine should only be called by threads
10093 * which can block on a page fault. i.e. kernel mode user
10094 * threads.
10095 *
10096 */
10097 kern_return_t
10098 vm_map_write_user(
10099 vm_map_t map,
10100 vm_offset_t src_addr,
10101 vm_offset_t dst_addr,
10102 vm_size_t size)
10103 {
10104 thread_act_t thr_act = current_act();
10105 kern_return_t kr = KERN_SUCCESS;
10106
10107 if(thr_act->map == map) {
10108 if (copyout((char *)src_addr, (char *)dst_addr, size)) {
10109 kr = KERN_INVALID_ADDRESS;
10110 }
10111 } else {
10112 vm_map_t oldmap;
10113
10114 /* take on the identity of the target map while doing */
10115 /* the transfer */
10116
10117 vm_map_reference(map);
10118 oldmap = vm_map_switch(map);
10119 if (copyout((char *)src_addr, (char *)dst_addr, size)) {
10120 kr = KERN_INVALID_ADDRESS;
10121 }
10122 vm_map_switch(oldmap);
10123 vm_map_deallocate(map);
10124 }
10125 return kr;
10126 }
10127
10128 /*
10129 * Routine: vm_map_read_user
10130 *
10131 * Description:
10132 * Copy in data from a user space source map into the
10133 * kernel map. The space must already exist in the
10134 * kernel map.
10135 * NOTE: This routine should only be called by threads
10136 * which can block on a page fault. i.e. kernel mode user
10137 * threads.
10138 *
10139 */
10140 kern_return_t
10141 vm_map_read_user(
10142 vm_map_t map,
10143 vm_offset_t src_addr,
10144 vm_offset_t dst_addr,
10145 vm_size_t size)
10146 {
10147 thread_act_t thr_act = current_act();
10148 kern_return_t kr = KERN_SUCCESS;
10149
10150 if(thr_act->map == map) {
10151 if (copyin((char *)src_addr, (char *)dst_addr, size)) {
10152 kr = KERN_INVALID_ADDRESS;
10153 }
10154 } else {
10155 vm_map_t oldmap;
10156
10157 /* take on the identity of the target map while doing */
10158 /* the transfer */
10159
10160 vm_map_reference(map);
10161 oldmap = vm_map_switch(map);
10162 if (copyin((char *)src_addr, (char *)dst_addr, size)) {
10163 kr = KERN_INVALID_ADDRESS;
10164 }
10165 vm_map_switch(oldmap);
10166 vm_map_deallocate(map);
10167 }
10168 return kr;
10169 }
10170
10171 /* Takes existing source and destination sub-maps and clones the contents of */
10172 /* the source map */
10173
10174 kern_return_t
10175 vm_region_clone(
10176 ipc_port_t src_region,
10177 ipc_port_t dst_region)
10178 {
10179 vm_named_entry_t src_object;
10180 vm_named_entry_t dst_object;
10181 vm_map_t src_map;
10182 vm_map_t dst_map;
10183 vm_offset_t addr;
10184 vm_offset_t max_off;
10185 vm_map_entry_t entry;
10186 vm_map_entry_t new_entry;
10187 vm_map_entry_t insert_point;
10188
10189 src_object = (vm_named_entry_t)src_region->ip_kobject;
10190 dst_object = (vm_named_entry_t)dst_region->ip_kobject;
10191 if((!src_object->is_sub_map) || (!dst_object->is_sub_map)) {
10192 return KERN_INVALID_ARGUMENT;
10193 }
10194 src_map = (vm_map_t)src_object->backing.map;
10195 dst_map = (vm_map_t)dst_object->backing.map;
10196 /* destination map is assumed to be unavailable to any other */
10197 /* activity. i.e. it is new */
10198 vm_map_lock(src_map);
10199 if((src_map->min_offset != dst_map->min_offset)
10200 || (src_map->max_offset != dst_map->max_offset)) {
10201 vm_map_unlock(src_map);
10202 return KERN_INVALID_ARGUMENT;
10203 }
10204 addr = src_map->min_offset;
10205 vm_map_lookup_entry(dst_map, addr, &entry);
10206 if(entry == vm_map_to_entry(dst_map)) {
10207 entry = entry->vme_next;
10208 }
10209 if(entry == vm_map_to_entry(dst_map)) {
10210 max_off = src_map->max_offset;
10211 } else {
10212 max_off = entry->vme_start;
10213 }
10214 vm_map_lookup_entry(src_map, addr, &entry);
10215 if(entry == vm_map_to_entry(src_map)) {
10216 entry = entry->vme_next;
10217 }
10218 vm_map_lookup_entry(dst_map, addr, &insert_point);
10219 while((entry != vm_map_to_entry(src_map)) &&
10220 (entry->vme_end <= max_off)) {
10221 addr = entry->vme_start;
10222 new_entry = vm_map_entry_create(dst_map);
10223 vm_map_entry_copy(new_entry, entry);
10224 vm_map_entry_link(dst_map, insert_point, new_entry);
10225 insert_point = new_entry;
10226 if (entry->object.vm_object != VM_OBJECT_NULL) {
10227 if (new_entry->is_sub_map) {
10228 vm_map_reference(new_entry->object.sub_map);
10229 } else {
10230 vm_object_reference(
10231 new_entry->object.vm_object);
10232 }
10233 }
10234 dst_map->size += new_entry->vme_end - new_entry->vme_start;
10235 entry = entry->vme_next;
10236 }
10237 vm_map_unlock(src_map);
10238 return KERN_SUCCESS;
10239 }
10240
10241 /*
10242 * Export routines to other components for the things we access locally through
10243 * macros.
10244 */
10245 #undef current_map
10246 vm_map_t
10247 current_map(void)
10248 {
10249 return (current_map_fast());
10250 }
10251
10252 /*
10253 * vm_map_check_protection:
10254 *
10255 * Assert that the target map allows the specified
10256 * privilege on the entire address region given.
10257 * The entire region must be allocated.
10258 */
10259 boolean_t vm_map_check_protection(map, start, end, protection)
10260 register vm_map_t map;
10261 register vm_offset_t start;
10262 register vm_offset_t end;
10263 register vm_prot_t protection;
10264 {
10265 register vm_map_entry_t entry;
10266 vm_map_entry_t tmp_entry;
10267
10268 vm_map_lock(map);
10269
10270 if (start < vm_map_min(map) || end > vm_map_max(map) || start > end)
10271 {
10272 vm_map_unlock(map);
10273 return (FALSE);
10274 }
10275
10276 if (!vm_map_lookup_entry(map, start, &tmp_entry)) {
10277 vm_map_unlock(map);
10278 return(FALSE);
10279 }
10280
10281 entry = tmp_entry;
10282
10283 while (start < end) {
10284 if (entry == vm_map_to_entry(map)) {
10285 vm_map_unlock(map);
10286 return(FALSE);
10287 }
10288
10289 /*
10290 * No holes allowed!
10291 */
10292
10293 if (start < entry->vme_start) {
10294 vm_map_unlock(map);
10295 return(FALSE);
10296 }
10297
10298 /*
10299 * Check protection associated with entry.
10300 */
10301
10302 if ((entry->protection & protection) != protection) {
10303 vm_map_unlock(map);
10304 return(FALSE);
10305 }
10306
10307 /* go to next entry */
10308
10309 start = entry->vme_end;
10310 entry = entry->vme_next;
10311 }
10312 vm_map_unlock(map);
10313 return(TRUE);
10314 }