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