2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
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.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 * Mach Operating System
35 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
36 * All Rights Reserved.
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.
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.
48 * Carnegie Mellon requests users of this software to return to
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science
52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890
55 * any improvements or extensions that they make and grant Carnegie Mellon
56 * the rights to redistribute these changes.
62 * Author: Avadis Tevanian, Jr., Michael Wayne Young
65 * Virtual memory mapping module.
68 #include <task_swapper.h>
69 #include <mach_assert.h>
70 #include <libkern/OSAtomic.h>
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>
81 #include <kern/assert.h>
82 #include <kern/counters.h>
83 #include <kern/kalloc.h>
84 #include <kern/zalloc.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>
97 #include <machine/db_machdep.h>
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
106 #include <ppc/mappings.h>
109 #include <vm/vm_protos.h>
111 /* Internal prototypes
114 static void vm_map_simplify_range(
116 vm_map_offset_t start
,
117 vm_map_offset_t end
); /* forward */
119 static boolean_t
vm_map_range_check(
121 vm_map_offset_t start
,
123 vm_map_entry_t
*entry
);
125 static vm_map_entry_t
_vm_map_entry_create(
126 struct vm_map_header
*map_header
);
128 static void _vm_map_entry_dispose(
129 struct vm_map_header
*map_header
,
130 vm_map_entry_t entry
);
132 static void vm_map_pmap_enter(
134 vm_map_offset_t addr
,
135 vm_map_offset_t end_addr
,
137 vm_object_offset_t offset
,
138 vm_prot_t protection
);
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
);
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
);
150 static void vm_map_entry_delete(
152 vm_map_entry_t entry
);
154 static kern_return_t
vm_map_delete(
156 vm_map_offset_t start
,
161 static kern_return_t
vm_map_copy_overwrite_unaligned(
163 vm_map_entry_t entry
,
165 vm_map_address_t start
);
167 static kern_return_t
vm_map_copy_overwrite_aligned(
169 vm_map_entry_t tmp_entry
,
171 vm_map_offset_t start
,
174 static kern_return_t
vm_map_copyin_kernel_buffer(
176 vm_map_address_t src_addr
,
178 boolean_t src_destroy
,
179 vm_map_copy_t
*copy_result
); /* OUT */
181 static kern_return_t
vm_map_copyout_kernel_buffer(
183 vm_map_address_t
*addr
, /* IN/OUT */
185 boolean_t overwrite
);
187 static void vm_map_fork_share(
189 vm_map_entry_t old_entry
,
192 static boolean_t
vm_map_fork_copy(
194 vm_map_entry_t
*old_entry_p
,
197 static void vm_map_region_top_walk(
198 vm_map_entry_t entry
,
199 vm_region_top_info_t top
);
201 static void vm_map_region_walk(
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
);
209 static kern_return_t
vm_map_wire_nested(
211 vm_map_offset_t start
,
213 vm_prot_t access_type
,
216 vm_map_offset_t pmap_addr
);
218 static kern_return_t
vm_map_unwire_nested(
220 vm_map_offset_t start
,
224 vm_map_offset_t pmap_addr
);
226 static kern_return_t
vm_map_overwrite_submap_recurse(
228 vm_map_offset_t dst_addr
,
229 vm_map_size_t dst_size
);
231 static kern_return_t
vm_map_copy_overwrite_nested(
233 vm_map_offset_t dst_addr
,
235 boolean_t interruptible
,
238 static kern_return_t
vm_map_remap_extract(
240 vm_map_offset_t addr
,
243 struct vm_map_header
*map_header
,
244 vm_prot_t
*cur_protection
,
245 vm_prot_t
*max_protection
,
246 vm_inherit_t inheritance
,
249 static kern_return_t
vm_map_remap_range_allocate(
251 vm_map_address_t
*address
,
253 vm_map_offset_t mask
,
255 vm_map_entry_t
*map_entry
);
257 static void vm_map_region_look_for_page(
261 vm_object_offset_t offset
,
264 vm_region_extended_info_t extended
);
266 static int vm_map_region_count_obj_refs(
267 vm_map_entry_t entry
,
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
279 #define vm_map_entry_copy(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; \
289 #define vm_map_entry_copy_full(NEW,OLD) (*(NEW) = *(OLD))
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.
297 * Synchronization is required prior to most operations.
299 * Maps consist of an ordered doubly-linked list of simple
300 * entries; a single hint is used to speed up lookups.
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).
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
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.
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 */
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.
346 vm_object_t vm_submap_object
;
351 * Initialize the vm_map module. Must be called before
352 * any other vm_map routines.
354 * Map and entry structures are allocated from zones -- we must
355 * initialize those zones.
357 * There are three zones of interest:
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.
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
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 */
376 #define NO_COALESCE_LIMIT (1024 * 128)
379 * Threshold for aggressive (eager) page map entering for vm copyout
380 * operations. Any copyout larger will NOT be aggressively entered.
382 static vm_map_size_t vm_map_aggressive_enter_max
; /* set by bootstrap */
384 /* Skip acquiring locks if we're in the midst of a kernel core dump */
385 extern unsigned int not_in_kdp
;
391 vm_map_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map
), 40*1024,
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");
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");
402 vm_map_copy_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_copy
),
403 16*1024, PAGE_SIZE
, "map copies");
406 * Cram the map and kentry zones with initial data.
407 * Set kentry_zone non-collectible to aid zone_gc().
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
);
420 map_data_size
= vm_map_round_page(10 * sizeof(struct vm_map
));
421 map_data
= pmap_steal_memory(map_data_size
);
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.
432 kentry_count
= pmap_free_pages() / 8;
436 vm_map_round_page(kentry_count
* sizeof(struct vm_map_entry
));
437 kentry_data
= pmap_steal_memory(kentry_data_size
);
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.
454 register vm_map_t result
;
456 result
= (vm_map_t
) zalloc(vm_map_zone
);
457 if (result
== VM_MAP_NULL
)
458 panic("vm_map_create");
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
;
466 result
->ref_count
= 1;
468 result
->res_count
= 1;
469 result
->sw_state
= MAP_SW_IN
;
470 #endif /* TASK_SWAPPER */
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);
487 * vm_map_entry_create: [ internal use only ]
489 * Allocates a VM map entry for insertion in the
490 * given map (or map copy). No fields are filled.
492 #define vm_map_entry_create(map) \
493 _vm_map_entry_create(&(map)->hdr)
495 #define vm_map_copy_entry_create(copy) \
496 _vm_map_entry_create(&(copy)->cpy_hdr)
498 static vm_map_entry_t
499 _vm_map_entry_create(
500 register struct vm_map_header
*map_header
)
502 register zone_t zone
;
503 register vm_map_entry_t entry
;
505 if (map_header
->entries_pageable
)
506 zone
= vm_map_entry_zone
;
508 zone
= vm_map_kentry_zone
;
510 entry
= (vm_map_entry_t
) zalloc(zone
);
511 if (entry
== VM_MAP_ENTRY_NULL
)
512 panic("vm_map_entry_create");
518 * vm_map_entry_dispose: [ internal use only ]
520 * Inverse of vm_map_entry_create.
522 #define vm_map_entry_dispose(map, entry) \
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)); \
531 #define vm_map_copy_entry_dispose(map, entry) \
532 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
535 _vm_map_entry_dispose(
536 register struct vm_map_header
*map_header
,
537 register vm_map_entry_t entry
)
539 register zone_t zone
;
541 if (map_header
->entries_pageable
)
542 zone
= vm_map_entry_zone
;
544 zone
= vm_map_kentry_zone
;
550 static boolean_t
first_free_is_valid(vm_map_t map
); /* forward */
551 static boolean_t first_free_check
= FALSE
;
556 vm_map_entry_t entry
, next
;
558 if (!first_free_check
)
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
))) {
567 next
= entry
->vme_next
;
568 if (entry
== vm_map_to_entry(map
))
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
);
578 #endif /* MACH_ASSERT */
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.
587 #define UPDATE_FIRST_FREE(map, new_first_free) \
590 vm_map_entry_t UFF_first_free; \
591 vm_map_entry_t UFF_next_entry; \
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)) \
605 UFF_map->first_free = UFF_first_free; \
606 assert(first_free_is_valid(UFF_map)); \
610 * vm_map_entry_{un,}link:
612 * Insert/remove entries from maps (or map copies).
614 #define vm_map_entry_link(map, after_where, entry) \
617 vm_map_entry_t VMEL_entry; \
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); \
625 #define vm_map_copy_entry_link(copy, after_where, entry) \
626 _vm_map_entry_link(&(copy)->cpy_hdr, after_where, (entry))
628 #define _vm_map_entry_link(hdr, after_where, entry) \
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); \
636 #define vm_map_entry_unlink(map, entry) \
639 vm_map_entry_t VMEU_entry; \
640 vm_map_entry_t VMEU_first_free; \
642 VMEU_entry = (entry); \
643 if (VMEU_entry->vme_start <= VMEU_map->first_free->vme_start) \
644 VMEU_first_free = VMEU_entry->vme_prev; \
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); \
651 #define vm_map_copy_entry_unlink(copy, entry) \
652 _vm_map_entry_unlink(&(copy)->cpy_hdr, (entry))
654 #define _vm_map_entry_unlink(hdr, entry) \
657 (entry)->vme_next->vme_prev = (entry)->vme_prev; \
658 (entry)->vme_prev->vme_next = (entry)->vme_next; \
661 #if MACH_ASSERT && TASK_SWAPPER
663 * vm_map_res_reference:
665 * Adds another valid residence count to the given map.
667 * Map is locked so this function can be called from
671 void vm_map_res_reference(register vm_map_t map
)
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
);
680 mutex_lock(&map
->s_lock
);
688 * vm_map_reference_swap:
690 * Adds valid reference and residence counts to the given map.
692 * The map may not be in memory (i.e. zero residence count).
695 void vm_map_reference_swap(register vm_map_t map
)
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
);
702 vm_map_res_reference(map
);
703 mutex_unlock(&map
->s_lock
);
707 * vm_map_res_deallocate:
709 * Decrement residence count on a map; possibly causing swapout.
711 * The map must be in memory (i.e. non-zero residence count).
713 * The map is locked, so this function is callable from vm_map_deallocate.
716 void vm_map_res_deallocate(register vm_map_t map
)
718 assert(map
->res_count
> 0);
719 if (--map
->res_count
== 0) {
720 mutex_unlock(&map
->s_lock
);
724 mutex_lock(&map
->s_lock
);
726 assert(map
->ref_count
>= map
->res_count
);
728 #endif /* MACH_ASSERT && TASK_SWAPPER */
733 * Actually destroy a map.
737 register vm_map_t map
)
740 (void) vm_map_delete(map
, map
->min_offset
,
741 map
->max_offset
, VM_MAP_NO_FLAGS
,
746 if (map
->hdr
.nentries
!=0)
747 vm_map_remove_commpage64(map
);
750 assert(map
->hdr
.nentries
==0);
753 pmap_destroy(map
->pmap
);
755 zfree(vm_map_zone
, map
);
760 * vm_map_swapin/vm_map_swapout
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.
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.
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.
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
796 * Because vm_map_swapin() is potentially an expensive operation, it
797 * should be used with caution.
800 * 1) A map with a residence count of zero is either swapped, or
802 * 2) A map with a non-zero residence count is either resident,
803 * or being swapped in.
806 int vm_map_swap_enable
= 1;
808 void vm_map_swapin (vm_map_t map
)
810 register vm_map_entry_t entry
;
812 if (!vm_map_swap_enable
) /* debug */
817 * First deal with various races.
819 if (map
->sw_state
== MAP_SW_IN
)
821 * we raced with swapout and won. Returning will incr.
822 * the res_count, turning the swapout into a nop.
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.
833 assert(map
->res_count
== 0);
836 * There are no intermediate states of a map going out or
837 * coming in, since the map is locked during the transition.
839 assert(map
->sw_state
== MAP_SW_OUT
);
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.
850 entry
= vm_map_first_entry(map
);
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
);
860 vm_object_t object
= entry
->object
.vm_object
;
861 vm_object_lock(object
);
863 * This call may iterate through the
866 vm_object_res_reference(object
);
867 vm_object_unlock(object
);
870 entry
= entry
->vme_next
;
872 assert(map
->sw_state
== MAP_SW_OUT
);
873 map
->sw_state
= MAP_SW_IN
;
876 void vm_map_swapout(vm_map_t map
)
878 register vm_map_entry_t entry
;
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.
886 mutex_lock(&map
->s_lock
);
887 if (map
->res_count
!= 0) {
888 mutex_unlock(&map
->s_lock
);
891 mutex_unlock(&map
->s_lock
);
894 * There are no intermediate states of a map going out or
895 * coming in, since the map is locked during the transition.
897 assert(map
->sw_state
== MAP_SW_IN
);
899 if (!vm_map_swap_enable
)
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.
911 entry
= vm_map_first_entry(map
);
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
);
921 vm_object_t object
= entry
->object
.vm_object
;
922 vm_object_lock(object
);
924 * This call may take a long time,
925 * since it could actively push
926 * out pages (if we implement it
929 vm_object_res_deallocate(object
);
930 vm_object_unlock(object
);
933 entry
= entry
->vme_next
;
935 assert(map
->sw_state
== MAP_SW_IN
);
936 map
->sw_state
= MAP_SW_OUT
;
939 #endif /* TASK_SWAPPER */
945 * Saves the specified entry as the hint for
946 * future lookups. Performs necessary interlocks.
948 #define SAVE_HINT(map,value) \
950 mutex_lock(&(map)->s_lock); \
951 (map)->hint = (value); \
952 mutex_unlock(&(map)->s_lock); \
956 * vm_map_lookup_entry: [ internal use only ]
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.
967 register vm_map_t map
,
968 register vm_map_offset_t address
,
969 vm_map_entry_t
*entry
) /* OUT */
971 register vm_map_entry_t cur
;
972 register vm_map_entry_t last
;
975 * Start looking either from the head of the
976 * list, or from the hint.
979 mutex_lock(&map
->s_lock
);
982 mutex_unlock(&map
->s_lock
);
984 if (cur
== vm_map_to_entry(map
))
987 if (address
>= cur
->vme_start
) {
989 * Go from hint to end of list.
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).
999 last
= vm_map_to_entry(map
);
1000 if ((cur
!= last
) && (cur
->vme_end
> address
)) {
1007 * Go from start to hint, *inclusively*
1009 last
= cur
->vme_next
;
1010 cur
= vm_map_first_entry(map
);
1017 while (cur
!= last
) {
1018 if (cur
->vme_end
> address
) {
1019 if (address
>= cur
->vme_start
) {
1021 * Save this lookup for future
1027 SAVE_HINT(map
, cur
);
1032 cur
= cur
->vme_next
;
1034 *entry
= cur
->vme_prev
;
1036 SAVE_HINT(map
, *entry
);
1041 * Routine: vm_map_find_space
1043 * Allocate a range in the specified virtual address map,
1044 * returning the entry allocated for that range.
1045 * Used by kmem_alloc, etc.
1047 * The map must be NOT be locked. It will be returned locked
1048 * on KERN_SUCCESS, unlocked on failure.
1050 * If an entry is allocated, the object/offset fields
1051 * are initialized to zero.
1055 register vm_map_t map
,
1056 vm_map_offset_t
*address
, /* OUT */
1058 vm_map_offset_t mask
,
1059 vm_map_entry_t
*o_entry
) /* OUT */
1061 register vm_map_entry_t entry
, new_entry
;
1062 register vm_map_offset_t start
;
1063 register vm_map_offset_t end
;
1067 return KERN_INVALID_ARGUMENT
;
1070 new_entry
= vm_map_entry_create(map
);
1073 * Look for the first possible address; if there's already
1074 * something at this address, we have to start after it.
1079 assert(first_free_is_valid(map
));
1080 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1081 start
= map
->min_offset
;
1083 start
= entry
->vme_end
;
1086 * In any case, the "entry" always precedes
1087 * the proposed new region throughout the loop:
1091 register vm_map_entry_t next
;
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.
1099 end
= ((start
+ mask
) & ~mask
);
1101 vm_map_entry_dispose(map
, new_entry
);
1103 return(KERN_NO_SPACE
);
1108 if ((end
> map
->max_offset
) || (end
< start
)) {
1109 vm_map_entry_dispose(map
, new_entry
);
1111 return(KERN_NO_SPACE
);
1115 * If there are no more entries, we must win.
1118 next
= entry
->vme_next
;
1119 if (next
== vm_map_to_entry(map
))
1123 * If there is another entry, it must be
1124 * after the end of the potential new region.
1127 if (next
->vme_start
>= end
)
1131 * Didn't fit -- move to the next entry.
1135 start
= entry
->vme_end
;
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
1145 * the map should be locked.
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
));
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;
1161 new_entry
->needs_copy
= FALSE
;
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;
1170 new_entry
->in_transition
= FALSE
;
1171 new_entry
->needs_wakeup
= FALSE
;
1174 * Insert the new entry into the list
1177 vm_map_entry_link(map
, entry
, new_entry
);
1182 * Update the lookup hint
1184 SAVE_HINT(map
, new_entry
);
1186 *o_entry
= new_entry
;
1187 return(KERN_SUCCESS
);
1190 int vm_map_pmap_enter_print
= FALSE
;
1191 int vm_map_pmap_enter_enable
= FALSE
;
1194 * Routine: vm_map_pmap_enter [internal only]
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.
1204 * In/out conditions:
1205 * The source map should not be locked on entry.
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
)
1216 unsigned int cache_attr
;
1221 while (addr
< end_addr
) {
1222 register vm_page_t m
;
1224 vm_object_lock(object
);
1225 vm_object_paging_begin(object
);
1227 m
= vm_page_lookup(object
, offset
);
1230 * The user should never see encrypted data, so do not
1231 * enter an encrypted page in the page table.
1233 if (m
== VM_PAGE_NULL
|| m
->busy
|| m
->encrypted
||
1234 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
||
1235 protection
& m
->page_lock
))) {
1237 vm_object_paging_end(object
);
1238 vm_object_unlock(object
);
1242 assert(!m
->fictitious
); /* XXX is this possible ??? */
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
);
1251 if (m
->no_isync
== TRUE
) {
1252 pmap_sync_page_data_phys(m
->phys_page
);
1253 m
->no_isync
= FALSE
;
1256 cache_attr
= ((unsigned int)object
->wimg_bits
) & VM_WIMG_MASK
;
1257 vm_object_unlock(object
);
1259 PMAP_ENTER(map
->pmap
, addr
, m
,
1260 protection
, cache_attr
, FALSE
);
1262 vm_object_lock(object
);
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
);
1272 offset
+= PAGE_SIZE_64
;
1277 boolean_t
vm_map_pmap_is_empty(
1279 vm_map_offset_t start
,
1280 vm_map_offset_t end
);
1281 boolean_t
vm_map_pmap_is_empty(
1283 vm_map_offset_t start
,
1284 vm_map_offset_t end
)
1286 vm_map_offset_t offset
;
1289 if (map
->pmap
== NULL
) {
1292 for (offset
= start
;
1294 offset
+= PAGE_SIZE
) {
1295 phys_page
= pmap_find_phys(map
->pmap
, offset
);
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
);
1307 * Routine: vm_map_enter
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.
1314 * Arguments are as defined in the vm_map call.
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;
1322 vm_map_offset_t
*address
, /* IN/OUT */
1324 vm_map_offset_t mask
,
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
)
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);
1349 return KERN_INVALID_ARGUMENT
;
1352 VM_GET_FLAGS_ALIAS(flags
, alias
);
1354 #define RETURN(value) { result = value; goto BailOut; }
1356 assert(page_aligned(*address
));
1357 assert(page_aligned(size
));
1360 * Only zero-fill objects are allowed to be purgable.
1361 * LP64todo - limit purgable objects to 32-bits for now
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
;
1371 if (!anywhere
&& overwrite
) {
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.
1381 zap_old_map
= vm_map_create(PMAP_NULL
,
1396 * Calculate the first possible address.
1399 if (start
< map
->min_offset
)
1400 start
= map
->min_offset
;
1401 if (start
> map
->max_offset
)
1402 RETURN(KERN_NO_SPACE
);
1405 * Look for the first possible address;
1406 * if there's already something at this
1407 * address, we have to start after it.
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
;
1415 vm_map_entry_t tmp_entry
;
1416 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
1417 start
= tmp_entry
->vme_end
;
1422 * In any case, the "entry" always precedes
1423 * the proposed new region throughout the
1428 register vm_map_entry_t next
;
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.
1436 end
= ((start
+ mask
) & ~mask
);
1438 RETURN(KERN_NO_SPACE
);
1442 if ((end
> map
->max_offset
) || (end
< start
)) {
1443 if (map
->wait_for_space
) {
1444 if (size
<= (map
->max_offset
-
1446 assert_wait((event_t
)map
,
1450 thread_block(THREAD_CONTINUE_NULL
);
1454 RETURN(KERN_NO_SPACE
);
1458 * If there are no more entries, we must win.
1461 next
= entry
->vme_next
;
1462 if (next
== vm_map_to_entry(map
))
1466 * If there is another entry, it must be
1467 * after the end of the potential new region.
1470 if (next
->vme_start
>= end
)
1474 * Didn't fit -- move to the next entry.
1478 start
= entry
->vme_end
;
1482 vm_map_entry_t temp_entry
;
1486 * the address doesn't itself violate
1487 * the mask requirement.
1492 if ((start
& mask
) != 0)
1493 RETURN(KERN_NO_SPACE
);
1496 * ... the address is within bounds
1501 if ((start
< map
->min_offset
) ||
1502 (end
> map
->max_offset
) ||
1504 RETURN(KERN_INVALID_ADDRESS
);
1507 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
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".
1513 (void) vm_map_delete(map
, start
, end
,
1514 VM_MAP_REMOVE_SAVE_ENTRIES
,
1519 * ... the starting address isn't allocated
1522 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
1523 RETURN(KERN_NO_SPACE
);
1528 * ... the next region doesn't overlap the
1532 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
1533 (entry
->vme_next
->vme_start
< end
))
1534 RETURN(KERN_NO_SPACE
);
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
1544 * the map should be locked.
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"
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;
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
,
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
))) {
1584 * Coalesced the two objects - can extend
1585 * the previous map entry to include the
1588 map
->size
+= (end
- entry
->vme_end
);
1589 entry
->vme_end
= end
;
1590 UPDATE_FIRST_FREE(map
, map
->first_free
);
1591 RETURN(KERN_SUCCESS
);
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
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
;
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
;
1613 } while (object
== VM_OBJECT_NULL
&&
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
));
1622 new_mapping_established
= TRUE
;
1624 /* Wire down the new entry if the user
1625 * requested all new map entries be wired.
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
);
1634 if ((object
!= VM_OBJECT_NULL
) &&
1635 (vm_map_pmap_enter_enable
) &&
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
);
1645 if (result
== KERN_SUCCESS
&&
1647 !(flags
& VM_FLAGS_NO_PMAP_CHECK
)) {
1648 assert(vm_map_pmap_is_empty(map
, *address
, *address
+size
));
1651 if (result
!= KERN_SUCCESS
) {
1652 if (new_mapping_established
) {
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.
1659 zap_new_map
= vm_map_create(PMAP_NULL
,
1667 (void) vm_map_delete(map
, *address
, *address
+size
,
1668 VM_MAP_REMOVE_SAVE_ENTRIES
,
1671 if (zap_old_map
!= VM_MAP_NULL
&&
1672 zap_old_map
->hdr
.nentries
!= 0) {
1673 vm_map_entry_t entry1
, entry2
;
1676 * The new mapping failed. Attempt to restore
1677 * the old mappings, saved in the "zap_old_map".
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
) ||
1691 * Part of that range has already been
1692 * re-mapped: we can't restore the old
1695 vm_map_enter_restore_failures
++;
1698 * Transfer the saved map entries from
1699 * "zap_old_map" to the original "map",
1700 * inserting them all after "entry1".
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
,
1707 vm_map_entry_link(map
, entry1
, entry2
);
1710 if (map
->wiring_required
) {
1712 * XXX TODO: we should rewire the
1716 vm_map_enter_restore_successes
++;
1726 * Get rid of the "zap_maps" and all the map entries that
1727 * they may still contain.
1729 if (zap_old_map
!= VM_MAP_NULL
) {
1730 vm_map_destroy(zap_old_map
);
1731 zap_old_map
= VM_MAP_NULL
;
1733 if (zap_new_map
!= VM_MAP_NULL
) {
1734 vm_map_destroy(zap_new_map
);
1735 zap_new_map
= VM_MAP_NULL
;
1747 extern vm_offset_t avail_start
, avail_end
;
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
1757 * Memory obtained from this call should be freed in the
1758 * normal way, viz., via vm_deallocate.
1763 vm_map_offset_t
*addr
,
1767 vm_object_t cpm_obj
;
1771 vm_map_offset_t va
, start
, end
, offset
;
1773 vm_map_offset_t prev_addr
;
1774 #endif /* MACH_ASSERT */
1776 boolean_t anywhere
= ((VM_FLAGS_ANYWHERE
& flags
) != 0);
1778 if (!vm_allocate_cpm_enabled
)
1779 return KERN_FAILURE
;
1783 return KERN_SUCCESS
;
1787 *addr
= vm_map_min(map
);
1789 *addr
= vm_map_trunc_page(*addr
);
1790 size
= vm_map_round_page(size
);
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.
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
)
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
);
1813 * Insert pages into object.
1816 vm_object_lock(cpm_obj
);
1817 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
1819 pages
= NEXT_PAGE(m
);
1821 assert(!m
->gobbled
);
1823 assert(!m
->pageout
);
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.
1831 ASSERT_PAGE_DECRYPTED(m
);
1833 assert(m
->phys_page
>=avail_start
&& m
->phys_page
<=avail_end
);
1836 vm_page_insert(m
, cpm_obj
, offset
);
1838 assert(cpm_obj
->resident_page_count
== size
/ PAGE_SIZE
);
1839 vm_object_unlock(cpm_obj
);
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.
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-
1852 vm_object_reference(cpm_obj
);
1855 * Insert object into map.
1865 (vm_object_offset_t
)0,
1869 VM_INHERIT_DEFAULT
);
1871 if (kr
!= KERN_SUCCESS
) {
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.
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 */
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.
1892 pmap
= vm_map_pmap(map
);
1893 pmap_pageable(pmap
, start
, end
, FALSE
);
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
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
,
1914 * Verify ordering in address space.
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",
1926 assert(!m
->fictitious
);
1927 assert(!m
->private);
1930 assert(!m
->cleaning
);
1931 assert(!m
->precious
);
1932 assert(!m
->clustered
);
1934 if (m
->phys_page
!= prev_addr
+ 1) {
1935 printf("start 0x%x end 0x%x va 0x%x\n",
1937 printf("obj 0x%x off 0x%x\n", cpm_obj
, offset
);
1938 printf("m 0x%x prev_address 0x%x\n", m
,
1940 panic("vm_allocate_cpm: pages not contig!");
1943 prev_addr
= m
->phys_page
;
1945 #endif /* MACH_ASSERT */
1947 vm_object_deallocate(cpm_obj
); /* kill extra ref */
1956 * Interface is defined in all cases, but unless the kernel
1957 * is built explicitly for this option, the interface does
1963 __unused vm_map_t map
,
1964 __unused vm_map_offset_t
*addr
,
1965 __unused vm_map_size_t size
,
1968 return KERN_FAILURE
;
1973 * vm_map_clip_start: [ internal use only ]
1975 * Asserts that the given entry begins at or after
1976 * the specified address; if necessary,
1977 * it splits the entry into two.
1980 #define vm_map_clip_start(map, entry, startaddr) \
1982 vm_map_t VMCS_map; \
1983 vm_map_entry_t VMCS_entry; \
1984 vm_map_offset_t VMCS_startaddr; \
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; \
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)); \
2002 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
2004 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2007 #define vm_map_clip_start(map, entry, startaddr) \
2009 vm_map_t VMCS_map; \
2010 vm_map_entry_t VMCS_entry; \
2011 vm_map_offset_t VMCS_startaddr; \
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);\
2018 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2022 #define vm_map_copy_clip_start(copy, entry, startaddr) \
2024 if ((startaddr) > (entry)->vme_start) \
2025 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
2029 * This routine is called only when it is known that
2030 * the entry must be split.
2034 register struct vm_map_header
*map_header
,
2035 register vm_map_entry_t entry
,
2036 register vm_map_offset_t start
)
2038 register vm_map_entry_t new_entry
;
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
2048 new_entry
= _vm_map_entry_create(map_header
);
2049 vm_map_entry_copy_full(new_entry
, entry
);
2051 new_entry
->vme_end
= start
;
2052 entry
->offset
+= (start
- entry
->vme_start
);
2053 entry
->vme_start
= start
;
2055 _vm_map_entry_link(map_header
, entry
->vme_prev
, new_entry
);
2057 if (entry
->is_sub_map
)
2058 vm_map_reference(new_entry
->object
.sub_map
);
2060 vm_object_reference(new_entry
->object
.vm_object
);
2065 * vm_map_clip_end: [ internal use only ]
2067 * Asserts that the given entry ends at or before
2068 * the specified address; if necessary,
2069 * it splits the entry into two.
2072 #define vm_map_clip_end(map, entry, endaddr) \
2074 vm_map_t VMCE_map; \
2075 vm_map_entry_t VMCE_entry; \
2076 vm_map_offset_t VMCE_endaddr; \
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; \
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)); \
2094 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
2096 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2099 #define vm_map_clip_end(map, entry, endaddr) \
2101 vm_map_t VMCE_map; \
2102 vm_map_entry_t VMCE_entry; \
2103 vm_map_offset_t VMCE_endaddr; \
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); \
2110 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2114 #define vm_map_copy_clip_end(copy, entry, endaddr) \
2116 if ((endaddr) < (entry)->vme_end) \
2117 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
2121 * This routine is called only when it is known that
2122 * the entry must be split.
2126 register struct vm_map_header
*map_header
,
2127 register vm_map_entry_t entry
,
2128 register vm_map_offset_t end
)
2130 register vm_map_entry_t new_entry
;
2133 * Create a new entry and insert it
2134 * AFTER the specified entry
2137 new_entry
= _vm_map_entry_create(map_header
);
2138 vm_map_entry_copy_full(new_entry
, entry
);
2140 new_entry
->vme_start
= entry
->vme_end
= end
;
2141 new_entry
->offset
+= (end
- entry
->vme_start
);
2143 _vm_map_entry_link(map_header
, entry
, new_entry
);
2145 if (entry
->is_sub_map
)
2146 vm_map_reference(new_entry
->object
.sub_map
);
2148 vm_object_reference(new_entry
->object
.vm_object
);
2153 * VM_MAP_RANGE_CHECK: [ internal use only ]
2155 * Asserts that the starting and ending region
2156 * addresses fall within the valid range of the map.
2158 #define VM_MAP_RANGE_CHECK(map, start, end) \
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); \
2169 * vm_map_range_check: [ internal use only ]
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
2180 * The map is locked for reading on entry and is left locked.
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
)
2190 register vm_map_offset_t prev
;
2193 * Basic sanity checks first
2195 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
2199 * Check first if the region starts within a valid
2200 * mapping for the map.
2202 if (!vm_map_lookup_entry(map
, start
, &cur
))
2206 * Optimize for the case that the region is contained
2207 * in a single map entry.
2209 if (entry
!= (vm_map_entry_t
*) NULL
)
2211 if (end
<= cur
->vme_end
)
2215 * If the region is not wholly contained within a
2216 * single entry, walk the entries looking for holes.
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
)
2223 prev
= cur
->vme_end
;
2224 cur
= cur
->vme_next
;
2230 * vm_map_submap: [ kernel use only ]
2232 * Mark the given range as handled by a subordinate map.
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.
2238 * Only a limited number of operations can be performed
2239 * within this rage after calling vm_map_submap:
2241 * [Don't try vm_map_copyin!]
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.]
2250 vm_map_offset_t start
,
2251 vm_map_offset_t end
,
2253 vm_map_offset_t offset
,
2259 vm_map_entry_t entry
;
2260 register kern_return_t result
= KERN_INVALID_ARGUMENT
;
2261 register vm_object_t object
;
2265 submap
->mapped
= TRUE
;
2267 VM_MAP_RANGE_CHECK(map
, start
, end
);
2269 if (vm_map_lookup_entry(map
, start
, &entry
)) {
2270 vm_map_clip_start(map
, entry
, start
);
2273 entry
= entry
->vme_next
;
2275 if(entry
== vm_map_to_entry(map
)) {
2277 return KERN_INVALID_ARGUMENT
;
2280 vm_map_clip_end(map
, entry
, end
);
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
);
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
) {
2302 return(KERN_NO_SPACE
);
2305 result
= pmap_nest(map
->pmap
, (entry
->object
.sub_map
)->pmap
,
2308 (uint64_t)(end
- start
));
2310 panic("vm_map_submap: pmap_nest failed, rc = %08X\n", result
);
2311 entry
->use_pmap
= TRUE
;
2315 pmap_remove(map
->pmap
, (addr64_t
)start
, (addr64_t
)end
);
2317 result
= KERN_SUCCESS
;
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.
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
)
2340 register vm_map_entry_t current
;
2341 register vm_map_offset_t prev
;
2342 vm_map_entry_t entry
;
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
);
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.
2356 if (start
>= map
->max_offset
) {
2358 return(KERN_INVALID_ADDRESS
);
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
2369 if (!(clip
= vm_map_lookup_entry(map
, start
, &entry
))) {
2371 return(KERN_INVALID_ADDRESS
);
2375 * Make a first pass to check for protection and address
2380 prev
= current
->vme_start
;
2381 while ((current
!= vm_map_to_entry(map
)) &&
2382 (current
->vme_start
< end
)) {
2385 * If there is a hole, return an error.
2387 if (current
->vme_start
!= prev
) {
2389 return(KERN_INVALID_ADDRESS
);
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
) {
2397 return(KERN_PROTECTION_FAILURE
);
2400 if ((new_prot
& new_max
) != new_prot
) {
2402 return(KERN_PROTECTION_FAILURE
);
2406 prev
= current
->vme_end
;
2407 current
= current
->vme_next
;
2411 return(KERN_INVALID_ADDRESS
);
2415 * Go back and fix up protections.
2416 * Clip to start here if the range starts within
2422 vm_map_clip_start(map
, entry
, start
);
2424 while ((current
!= vm_map_to_entry(map
)) &&
2425 (current
->vme_start
< end
)) {
2429 vm_map_clip_end(map
, current
, end
);
2431 old_prot
= current
->protection
;
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
;
2444 current
->protection
=
2445 (current
->max_protection
=
2446 new_prot
& ~VM_PROT_COPY
) &
2449 current
->protection
= new_prot
& ~VM_PROT_COPY
;
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.
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
;
2468 vm_map_entry_t local_entry
;
2470 pmap_base_addr
= 0xF0000000 & current
->vme_start
;
2471 pmap_end_addr
= (pmap_base_addr
+ 0x10000000) - 1;
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
;
2481 pmap_unnest(map
->pmap
, (addr64_t
)pmap_base_addr
);
2484 if (!(current
->protection
& VM_PROT_WRITE
)) {
2485 /* Look one level in we support nested pmaps */
2486 /* from mapped submaps which are direct entries */
2488 if(current
->is_sub_map
&& current
->use_pmap
) {
2489 pmap_protect(current
->object
.sub_map
->pmap
,
2492 current
->protection
);
2494 pmap_protect(map
->pmap
, current
->vme_start
,
2496 current
->protection
);
2500 current
= current
->vme_next
;
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
;
2511 return(KERN_SUCCESS
);
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.
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
)
2529 register vm_map_entry_t entry
;
2530 vm_map_entry_t temp_entry
;
2534 VM_MAP_RANGE_CHECK(map
, start
, end
);
2536 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
2538 vm_map_clip_start(map
, entry
, start
);
2541 temp_entry
= temp_entry
->vme_next
;
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
) {
2551 return(KERN_INVALID_ARGUMENT
);
2555 entry
= entry
->vme_next
;
2560 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2561 vm_map_clip_end(map
, entry
, end
);
2563 entry
->inheritance
= new_inheritance
;
2565 entry
= entry
->vme_next
;
2569 return(KERN_SUCCESS
);
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.
2582 * The map must not be locked, but a reference must remain to the
2583 * map throughout the call.
2585 static kern_return_t
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
,
2593 vm_map_offset_t pmap_addr
)
2595 register vm_map_entry_t entry
;
2596 struct vm_map_entry
*first_entry
, tmp_entry
;
2598 register vm_map_offset_t s
,e
;
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
;
2608 if(map_pmap
== NULL
)
2610 last_timestamp
= map
->timestamp
;
2612 VM_MAP_RANGE_CHECK(map
, start
, end
);
2613 assert(page_aligned(start
));
2614 assert(page_aligned(end
));
2616 /* We wired what the caller asked for, zero pages */
2618 return KERN_SUCCESS
;
2621 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
2622 entry
= first_entry
;
2623 /* vm_map_clip_start will be done later. */
2625 /* Start address is not in map */
2627 return(KERN_INVALID_ADDRESS
);
2631 need_wakeup
= FALSE
;
2632 cur_thread
= current_thread();
2633 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2635 * If another thread is wiring/unwiring this entry then
2636 * block after informing other thread to wake us up.
2638 if (entry
->in_transition
) {
2639 wait_result_t wait_result
;
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.
2646 s
= entry
->vme_start
< start
? start
: entry
->vme_start
;
2648 entry
->needs_wakeup
= TRUE
;
2651 * wake up anybody waiting on entries that we have
2655 vm_map_entry_wakeup(map
);
2656 need_wakeup
= FALSE
;
2659 * User wiring is interruptible
2661 wait_result
= vm_map_entry_wait(map
,
2662 (user_wire
) ? THREAD_ABORTSAFE
:
2664 if (user_wire
&& wait_result
== THREAD_INTERRUPTED
) {
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
2672 vm_map_unwire(map
, start
, s
, user_wire
);
2673 return(KERN_FAILURE
);
2677 * Cannot avoid a lookup here. reset timestamp.
2679 last_timestamp
= map
->timestamp
;
2682 * The entry could have been clipped, look it up again.
2683 * Worse that can happen is, it may not exist anymore.
2685 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
2687 panic("vm_map_wire: re-lookup failed");
2690 * User: undo everything upto the previous
2691 * entry. let vm_map_unwire worry about
2692 * checking the validity of the range.
2695 vm_map_unwire(map
, start
, s
, user_wire
);
2696 return(KERN_FAILURE
);
2698 entry
= first_entry
;
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
;
2709 vm_map_clip_start(map
, entry
, start
);
2710 vm_map_clip_end(map
, entry
, end
);
2712 sub_start
= entry
->offset
;
2713 sub_end
= entry
->vme_end
- entry
->vme_start
;
2714 sub_end
+= entry
->offset
;
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 */
2724 pmap_addr
= sub_start
;
2731 if (entry
->wired_count
) {
2732 if (entry
->wired_count
2734 panic("vm_map_wire: too many wirings");
2737 entry
->user_wired_count
2738 >= MAX_WIRE_COUNT
) {
2740 vm_map_unwire(map
, start
,
2741 entry
->vme_start
, user_wire
);
2742 return(KERN_FAILURE
);
2745 entry
->user_wired_count
++;
2747 (entry
->user_wired_count
== 0))
2748 entry
->wired_count
++;
2749 entry
= entry
->vme_next
;
2754 vm_map_offset_t offset_hi
;
2755 vm_map_offset_t offset_lo
;
2756 vm_object_offset_t offset
;
2759 vm_behavior_t behavior
;
2760 vm_map_entry_t local_entry
;
2761 vm_map_version_t version
;
2762 vm_map_t lookup_map
;
2764 /* call vm_map_lookup_locked to */
2765 /* cause any needs copy to be */
2767 local_start
= entry
->vme_start
;
2769 vm_map_lock_write_to_read(map
);
2770 if(vm_map_lookup_locked(
2771 &lookup_map
, local_start
,
2774 &offset
, &prot
, &wired
,
2775 &behavior
, &offset_lo
,
2776 &offset_hi
, &real_map
)) {
2778 vm_map_unlock_read(lookup_map
);
2779 vm_map_unwire(map
, start
,
2780 entry
->vme_start
, user_wire
);
2781 return(KERN_FAILURE
);
2783 if(real_map
!= lookup_map
)
2784 vm_map_unlock(real_map
);
2785 vm_map_unlock_read(lookup_map
);
2787 vm_object_unlock(object
);
2789 if (!vm_map_lookup_entry(map
,
2790 local_start
, &local_entry
)) {
2792 vm_map_unwire(map
, start
,
2793 entry
->vme_start
, user_wire
);
2794 return(KERN_FAILURE
);
2796 /* did we have a change of type? */
2797 if (!local_entry
->is_sub_map
) {
2798 last_timestamp
= map
->timestamp
;
2801 entry
= local_entry
;
2803 entry
->user_wired_count
++;
2805 (entry
->user_wired_count
== 1))
2806 entry
->wired_count
++;
2808 entry
->in_transition
= TRUE
;
2811 rc
= vm_map_wire_nested(
2812 entry
->object
.sub_map
,
2815 user_wire
, pmap
, pmap_addr
);
2819 local_start
= entry
->vme_start
;
2821 entry
->user_wired_count
++;
2823 (entry
->user_wired_count
== 1))
2824 entry
->wired_count
++;
2826 rc
= vm_map_wire_nested(entry
->object
.sub_map
,
2829 user_wire
, map_pmap
, pmap_addr
);
2832 s
= entry
->vme_start
;
2836 * Find the entry again. It could have been clipped
2837 * after we unlocked the map.
2839 if (!vm_map_lookup_entry(map
, local_start
,
2841 panic("vm_map_wire: re-lookup failed");
2842 entry
= first_entry
;
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
;
2853 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
2855 entry
->user_wired_count
--;
2857 (entry
->user_wired_count
== 0))
2858 entry
->wired_count
--;
2860 entry
= entry
->vme_next
;
2862 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2865 vm_map_entry_wakeup(map
);
2867 * undo everything upto the previous entry.
2869 (void)vm_map_unwire(map
, start
, s
, user_wire
);
2876 * If this entry is already wired then increment
2877 * the appropriate wire reference count.
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");
2885 entry
->user_wired_count
>= MAX_WIRE_COUNT
) {
2887 vm_map_unwire(map
, start
,
2888 entry
->vme_start
, user_wire
);
2889 return(KERN_FAILURE
);
2892 * entry is already wired down, get our reference
2893 * after clipping to our range.
2895 vm_map_clip_start(map
, entry
, start
);
2896 vm_map_clip_end(map
, entry
, end
);
2898 entry
->user_wired_count
++;
2899 if ((!user_wire
) || (entry
->user_wired_count
== 1))
2900 entry
->wired_count
++;
2902 entry
= entry
->vme_next
;
2907 * Unwired entry or wire request transmitted via submap
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
2917 size
= entry
->vme_end
- entry
->vme_start
;
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.
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;
2932 vm_map_clip_start(map
, entry
, start
);
2933 vm_map_clip_end(map
, entry
, end
);
2935 s
= entry
->vme_start
;
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
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
))) {
2950 * Found a hole or protection problem.
2951 * Unwire the region we wired so far.
2953 if (start
!= entry
->vme_start
) {
2955 vm_map_unwire(map
, start
, s
, user_wire
);
2959 return((entry
->protection
&access_type
) != access_type
?
2960 KERN_PROTECTION_FAILURE
: KERN_INVALID_ADDRESS
);
2963 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
2966 entry
->user_wired_count
++;
2967 if ((!user_wire
) || (entry
->user_wired_count
== 1))
2968 entry
->wired_count
++;
2970 entry
->in_transition
= TRUE
;
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.
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.
2990 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
2991 interruptible_state
= thread_interrupt_level(THREAD_UNINT
);
2993 interruptible_state
= THREAD_UNINT
;
2996 rc
= vm_fault_wire(map
,
2997 &tmp_entry
, map_pmap
, pmap_addr
);
2999 rc
= vm_fault_wire(map
,
3000 &tmp_entry
, map
->pmap
,
3001 tmp_entry
.vme_start
);
3003 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
3004 thread_interrupt_level(interruptible_state
);
3008 if (last_timestamp
+1 != map
->timestamp
) {
3010 * Find the entry again. It could have been clipped
3011 * after we unlocked the map.
3013 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3015 panic("vm_map_wire: re-lookup failed");
3017 entry
= first_entry
;
3020 last_timestamp
= map
->timestamp
;
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
;
3030 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3032 entry
->user_wired_count
--;
3034 (entry
->user_wired_count
== 0))
3035 entry
->wired_count
--;
3037 entry
= entry
->vme_next
;
3040 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3043 vm_map_entry_wakeup(map
);
3045 * undo everything upto the previous entry.
3047 (void)vm_map_unwire(map
, start
, s
, user_wire
);
3050 } /* end while loop through map entries */
3054 * wake up anybody waiting on entries we wired.
3057 vm_map_entry_wakeup(map
);
3059 return(KERN_SUCCESS
);
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
)
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
3084 VM_MAP_RANGE_CHECK(map
, start
, end
);
3085 mapping_prealloc(end
- start
);
3087 kret
= vm_map_wire_nested(map
, start
, end
, access_type
,
3088 user_wire
, (pmap_t
)NULL
, 0);
3098 * Sets the pageability of the specified address range in the target
3099 * as pageable. Regions specified must have been wired previously.
3101 * The map must not be locked, but a reference must remain to the map
3102 * throughout the call.
3104 * Kernel will panic on failures. User unwire ignores holes and
3105 * unwired and intransition entries to avoid losing memory by leaving
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
,
3115 vm_map_offset_t pmap_addr
)
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
;
3124 if(map_pmap
== NULL
)
3126 last_timestamp
= map
->timestamp
;
3128 VM_MAP_RANGE_CHECK(map
, start
, end
);
3129 assert(page_aligned(start
));
3130 assert(page_aligned(end
));
3132 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3133 entry
= first_entry
;
3134 /* vm_map_clip_start will be done later. */
3137 /* Start address is not in map. */
3139 return(KERN_INVALID_ADDRESS
);
3142 need_wakeup
= FALSE
;
3143 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3144 if (entry
->in_transition
) {
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
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.
3159 panic("vm_map_unwire: in_transition entry");
3161 entry
= entry
->vme_next
;
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
;
3172 vm_map_clip_start(map
, entry
, start
);
3173 vm_map_clip_end(map
, entry
, end
);
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
;
3187 if (entry
->wired_count
== 0 ||
3188 (user_wire
&& entry
->user_wired_count
== 0)) {
3190 panic("vm_map_unwire: entry is unwired");
3191 entry
= entry
->vme_next
;
3197 * Holes: Next entry should be contiguous unless
3198 * this is the end of the region.
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
)))) {
3205 panic("vm_map_unwire: non-contiguous region");
3207 entry = entry->vme_next;
3212 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3213 entry
->wired_count
--;
3215 if (entry
->wired_count
!= 0) {
3216 entry
= entry
->vme_next
;
3220 entry
->in_transition
= TRUE
;
3221 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
3224 * We can unlock the map now. The in_transition state
3225 * guarantees existance of the entry.
3228 vm_map_unwire_nested(entry
->object
.sub_map
,
3229 sub_start
, sub_end
, user_wire
, pmap
, pmap_addr
);
3232 if (last_timestamp
+1 != map
->timestamp
) {
3234 * Find the entry again. It could have been
3235 * clipped or deleted after we unlocked the map.
3237 if (!vm_map_lookup_entry(map
,
3238 tmp_entry
.vme_start
,
3241 panic("vm_map_unwire: re-lookup failed");
3242 entry
= first_entry
->vme_next
;
3244 entry
= first_entry
;
3246 last_timestamp
= map
->timestamp
;
3249 * clear transition bit for all constituent entries
3250 * that were in the original entry (saved in
3251 * tmp_entry). Also check for waiters.
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
;
3261 entry
= entry
->vme_next
;
3266 vm_map_unwire_nested(entry
->object
.sub_map
,
3267 sub_start
, sub_end
, user_wire
, map_pmap
,
3271 if (last_timestamp
+1 != map
->timestamp
) {
3273 * Find the entry again. It could have been
3274 * clipped or deleted after we unlocked the map.
3276 if (!vm_map_lookup_entry(map
,
3277 tmp_entry
.vme_start
,
3280 panic("vm_map_unwire: re-lookup failed");
3281 entry
= first_entry
->vme_next
;
3283 entry
= first_entry
;
3285 last_timestamp
= map
->timestamp
;
3290 if ((entry
->wired_count
== 0) ||
3291 (user_wire
&& entry
->user_wired_count
== 0)) {
3293 panic("vm_map_unwire: entry is unwired");
3295 entry
= entry
->vme_next
;
3299 assert(entry
->wired_count
> 0 &&
3300 (!user_wire
|| entry
->user_wired_count
> 0));
3302 vm_map_clip_start(map
, entry
, start
);
3303 vm_map_clip_end(map
, entry
, end
);
3307 * Holes: Next entry should be contiguous unless
3308 * this is the end of the region.
3310 if (((entry
->vme_end
< end
) &&
3311 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3312 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
3315 panic("vm_map_unwire: non-contiguous region");
3316 entry
= entry
->vme_next
;
3320 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3321 entry
->wired_count
--;
3323 if (entry
->wired_count
!= 0) {
3324 entry
= entry
->vme_next
;
3328 entry
->in_transition
= TRUE
;
3329 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
3332 * We can unlock the map now. The in_transition state
3333 * guarantees existance of the entry.
3337 vm_fault_unwire(map
,
3338 &tmp_entry
, FALSE
, map_pmap
, pmap_addr
);
3340 vm_fault_unwire(map
,
3341 &tmp_entry
, FALSE
, map
->pmap
,
3342 tmp_entry
.vme_start
);
3346 if (last_timestamp
+1 != map
->timestamp
) {
3348 * Find the entry again. It could have been clipped
3349 * or deleted after we unlocked the map.
3351 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3354 panic("vm_map_unwire: re-lookup failed");
3355 entry
= first_entry
->vme_next
;
3357 entry
= first_entry
;
3359 last_timestamp
= map
->timestamp
;
3362 * clear transition bit for all constituent entries that
3363 * were in the original entry (saved in tmp_entry). Also
3364 * check for waiters.
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
;
3374 entry
= entry
->vme_next
;
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
3386 vm_map_simplify_range(map
, start
, end
);
3390 * wake up anybody waiting on entries that we have unwired.
3393 vm_map_entry_wakeup(map
);
3394 return(KERN_SUCCESS
);
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
)
3405 return vm_map_unwire_nested(map
, start
, end
,
3406 user_wire
, (pmap_t
)NULL
, 0);
3411 * vm_map_entry_delete: [ internal use only ]
3413 * Deallocate the given entry from the target map.
3416 vm_map_entry_delete(
3417 register vm_map_t map
,
3418 register vm_map_entry_t entry
)
3420 register vm_map_offset_t s
, e
;
3421 register vm_object_t object
;
3422 register vm_map_t submap
;
3424 s
= entry
->vme_start
;
3426 assert(page_aligned(s
));
3427 assert(page_aligned(e
));
3428 assert(entry
->wired_count
== 0);
3429 assert(entry
->user_wired_count
== 0);
3431 if (entry
->is_sub_map
) {
3433 submap
= entry
->object
.sub_map
;
3436 object
= entry
->object
.vm_object
;
3439 vm_map_entry_unlink(map
, entry
);
3442 vm_map_entry_dispose(map
, entry
);
3446 * Deallocate the object only after removing all
3447 * pmap entries pointing to its pages.
3450 vm_map_deallocate(submap
);
3452 vm_object_deallocate(object
);
3457 vm_map_submap_pmap_clean(
3459 vm_map_offset_t start
,
3460 vm_map_offset_t end
,
3462 vm_map_offset_t offset
)
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
;
3469 submap_end
= offset
+ (end
- start
);
3470 submap_start
= offset
;
3471 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
3473 remove_size
= (entry
->vme_end
- entry
->vme_start
);
3474 if(offset
> entry
->vme_start
)
3475 remove_size
-= offset
- entry
->vme_start
;
3478 if(submap_end
< entry
->vme_end
) {
3480 entry
->vme_end
- submap_end
;
3482 if(entry
->is_sub_map
) {
3483 vm_map_submap_pmap_clean(
3486 start
+ remove_size
,
3487 entry
->object
.sub_map
,
3491 if((map
->mapped
) && (map
->ref_count
)
3492 && (entry
->object
.vm_object
!= NULL
)) {
3493 vm_object_pmap_protect(
3494 entry
->object
.vm_object
,
3501 pmap_remove(map
->pmap
,
3503 (addr64_t
)(start
+ remove_size
));
3508 entry
= entry
->vme_next
;
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
;
3516 if(entry
->is_sub_map
) {
3517 vm_map_submap_pmap_clean(
3519 (start
+ entry
->vme_start
) - offset
,
3520 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
3521 entry
->object
.sub_map
,
3524 if((map
->mapped
) && (map
->ref_count
)
3525 && (entry
->object
.vm_object
!= NULL
)) {
3526 vm_object_pmap_protect(
3527 entry
->object
.vm_object
,
3534 pmap_remove(map
->pmap
,
3535 (addr64_t
)((start
+ entry
->vme_start
)
3537 (addr64_t
)(((start
+ entry
->vme_start
)
3538 - offset
) + remove_size
));
3541 entry
= entry
->vme_next
;
3547 * vm_map_delete: [ internal use only ]
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.
3555 * This routine is called with map locked and leaves map locked.
3557 static kern_return_t
3560 vm_map_offset_t start
,
3561 vm_map_offset_t end
,
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 */
3573 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
3574 THREAD_ABORTSAFE
: THREAD_UNINT
;
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.
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
3587 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
3590 * Find the start of the region, and clip it
3592 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3593 entry
= first_entry
;
3594 vm_map_clip_start(map
, entry
, start
);
3597 * Fix the lookup hint now, rather than each
3598 * time through the loop.
3600 SAVE_HINT(map
, entry
->vme_prev
);
3602 entry
= first_entry
->vme_next
;
3605 need_wakeup
= FALSE
;
3607 * Step through all entries in this region
3609 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3611 vm_map_clip_end(map
, entry
, end
);
3612 if (entry
->in_transition
) {
3613 wait_result_t wait_result
;
3616 * Another thread is wiring/unwiring this entry.
3617 * Let the other thread know we are waiting.
3619 s
= entry
->vme_start
;
3620 entry
->needs_wakeup
= TRUE
;
3623 * wake up anybody waiting on entries that we have
3624 * already unwired/deleted.
3627 vm_map_entry_wakeup(map
);
3628 need_wakeup
= FALSE
;
3631 wait_result
= vm_map_entry_wait(map
, interruptible
);
3633 if (interruptible
&&
3634 wait_result
== THREAD_INTERRUPTED
) {
3636 * We do not clear the needs_wakeup flag,
3637 * since we cannot tell if we were the only one.
3640 return KERN_ABORTED
;
3644 * The entry could have been clipped or it
3645 * may not exist anymore. Look it up again.
3647 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
3648 assert((map
!= kernel_map
) &&
3649 (!entry
->is_sub_map
));
3651 * User: use the next entry
3653 entry
= first_entry
->vme_next
;
3655 entry
= first_entry
;
3656 SAVE_HINT(map
, entry
->vme_prev
);
3658 last_timestamp
= map
->timestamp
;
3660 } /* end in_transition */
3662 if (entry
->wired_count
) {
3664 * Remove a kernel wiring if requested or if
3665 * there are user wirings.
3667 if ((flags
& VM_MAP_REMOVE_KUNWIRE
) ||
3668 (entry
->user_wired_count
> 0))
3669 entry
->wired_count
--;
3671 /* remove all user wire references */
3672 entry
->user_wired_count
= 0;
3674 if (entry
->wired_count
!= 0) {
3675 assert((map
!= kernel_map
) &&
3676 (!entry
->is_sub_map
));
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
3684 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
3685 wait_result_t wait_result
;
3687 s
= entry
->vme_start
;
3688 entry
->needs_wakeup
= TRUE
;
3689 wait_result
= vm_map_entry_wait(map
,
3692 if (interruptible
&&
3693 wait_result
== THREAD_INTERRUPTED
) {
3695 * We do not clear the
3696 * needs_wakeup flag, since we
3697 * cannot tell if we were the
3701 return KERN_ABORTED
;
3705 * The entry could have been clipped or
3706 * it may not exist anymore. Look it
3709 if (!vm_map_lookup_entry(map
, s
,
3711 assert((map
!= kernel_map
) &&
3712 (!entry
->is_sub_map
));
3714 * User: use the next entry
3716 entry
= first_entry
->vme_next
;
3718 entry
= first_entry
;
3719 SAVE_HINT(map
, entry
->vme_prev
);
3721 last_timestamp
= map
->timestamp
;
3725 return KERN_FAILURE
;
3729 entry
->in_transition
= TRUE
;
3731 * copy current entry. see comment in vm_map_wire()
3734 s
= entry
->vme_start
;
3738 * We can unlock the map now. The in_transition
3739 * state guarentees existance of the entry.
3742 vm_fault_unwire(map
, &tmp_entry
,
3743 tmp_entry
.object
.vm_object
== kernel_object
,
3744 map
->pmap
, tmp_entry
.vme_start
);
3747 if (last_timestamp
+1 != map
->timestamp
) {
3749 * Find the entry again. It could have
3750 * been clipped after we unlocked the map.
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
;
3757 SAVE_HINT(map
, entry
->vme_prev
);
3760 SAVE_HINT(map
, entry
->vme_prev
);
3761 first_entry
= entry
;
3764 last_timestamp
= map
->timestamp
;
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
;
3775 entry
= entry
->vme_next
;
3778 * We have unwired the entry(s). Go back and
3781 entry
= first_entry
;
3785 /* entry is unwired */
3786 assert(entry
->wired_count
== 0);
3787 assert(entry
->user_wired_count
== 0);
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
) {
3795 pmap_unnest(map
->pmap
, (addr64_t
)entry
->vme_start
);
3797 if((map
->mapped
) && (map
->ref_count
)) {
3798 /* clean up parent map/maps */
3799 vm_map_submap_pmap_clean(
3800 map
, entry
->vme_start
,
3802 entry
->object
.sub_map
,
3806 vm_map_submap_pmap_clean(
3807 map
, entry
->vme_start
, entry
->vme_end
,
3808 entry
->object
.sub_map
,
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
,
3821 pmap_remove(map
->pmap
,
3829 * All pmap mappings for this map entry must have been
3832 assert(vm_map_pmap_is_empty(map
,
3836 next
= entry
->vme_next
;
3837 s
= next
->vme_start
;
3838 last_timestamp
= map
->timestamp
;
3840 if ((flags
& VM_MAP_REMOVE_SAVE_ENTRIES
) &&
3841 zap_map
!= VM_MAP_NULL
) {
3843 * The caller wants to save the affected VM map entries
3844 * into the "zap_map". The caller will take care of
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
),
3854 vm_map_entry_delete(map
, entry
);
3855 /* vm_map_entry_delete unlocks the map */
3861 if(entry
== vm_map_to_entry(map
)) {
3864 if (last_timestamp
+1 != map
->timestamp
) {
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
3873 if (!vm_map_lookup_entry(map
, s
, &entry
)){
3874 entry
= entry
->vme_next
;
3876 SAVE_HINT(map
, entry
->vme_prev
);
3879 * others can not only allocate behind us, we can
3880 * also see coalesce while we don't have the map lock
3882 if(entry
== vm_map_to_entry(map
)) {
3885 vm_map_clip_start(map
, entry
, s
);
3887 last_timestamp
= map
->timestamp
;
3890 if (map
->wait_for_space
)
3891 thread_wakeup((event_t
) map
);
3893 * wake up anybody waiting on entries that we have already deleted.
3896 vm_map_entry_wakeup(map
);
3898 return KERN_SUCCESS
;
3904 * Remove the given address range from the target map.
3905 * This is the exported form of vm_map_delete.
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
)
3914 register kern_return_t result
;
3917 VM_MAP_RANGE_CHECK(map
, start
, end
);
3918 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
3926 * Routine: vm_map_copy_discard
3929 * Dispose of a map copy object (returned by
3933 vm_map_copy_discard(
3936 TR_DECL("vm_map_copy_discard");
3938 /* tr3("enter: copy 0x%x type %d", copy, copy->type);*/
3940 if (copy
== VM_MAP_COPY_NULL
)
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
);
3949 vm_map_copy_entry_unlink(copy
, entry
);
3950 vm_object_deallocate(entry
->object
.vm_object
);
3951 vm_map_copy_entry_dispose(copy
, entry
);
3954 case VM_MAP_COPY_OBJECT
:
3955 vm_object_deallocate(copy
->cpy_object
);
3957 case VM_MAP_COPY_KERNEL_BUFFER
:
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.
3964 kfree(copy
, copy
->cpy_kalloc_size
);
3967 zfree(vm_map_copy_zone
, copy
);
3971 * Routine: vm_map_copy_copy
3974 * Move the information in a map copy object to
3975 * a new map copy object, leaving the old one
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.
3991 vm_map_copy_t new_copy
;
3993 if (copy
== VM_MAP_COPY_NULL
)
3994 return VM_MAP_COPY_NULL
;
3997 * Allocate a new copy object, and copy the information
3998 * from the old one into it.
4001 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
4004 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
4006 * The links in the entry chain must be
4007 * changed to point to the new copy object.
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
);
4016 * Change the old copy object into one that contains
4017 * nothing to be deallocated.
4019 copy
->type
= VM_MAP_COPY_OBJECT
;
4020 copy
->cpy_object
= VM_OBJECT_NULL
;
4023 * Return the new object.
4028 static kern_return_t
4029 vm_map_overwrite_submap_recurse(
4031 vm_map_offset_t dst_addr
,
4032 vm_map_size_t dst_size
)
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
;
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.
4049 dst_end
= vm_map_round_page(dst_addr
+ dst_size
);
4050 vm_map_lock(dst_map
);
4053 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4054 vm_map_unlock(dst_map
);
4055 return(KERN_INVALID_ADDRESS
);
4058 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(dst_addr
));
4060 for (entry
= tmp_entry
;;) {
4061 vm_map_entry_t next
;
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
;
4069 if (entry
->in_transition
) {
4071 * Say that we are waiting, and wait for entry.
4073 entry
->needs_wakeup
= TRUE
;
4074 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4079 encountered_sub_map
= TRUE
;
4080 sub_start
= entry
->offset
;
4082 if(entry
->vme_end
< dst_end
)
4083 sub_end
= entry
->vme_end
;
4086 sub_end
-= entry
->vme_start
;
4087 sub_end
+= entry
->offset
;
4088 local_end
= entry
->vme_end
;
4089 vm_map_unlock(dst_map
);
4091 result
= vm_map_overwrite_submap_recurse(
4092 entry
->object
.sub_map
,
4094 sub_end
- sub_start
);
4096 if(result
!= KERN_SUCCESS
)
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
,
4103 vm_map_unlock(dst_map
);
4104 return(KERN_INVALID_ADDRESS
);
4107 next
= entry
->vme_next
;
4110 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4111 vm_map_unlock(dst_map
);
4112 return(KERN_PROTECTION_FAILURE
);
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.
4120 if (entry
->in_transition
) {
4123 * Say that we are waiting, and wait for entry.
4125 entry
->needs_wakeup
= TRUE
;
4126 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4132 * our range is contained completely within this map entry
4134 if (dst_end
<= entry
->vme_end
) {
4135 vm_map_unlock(dst_map
);
4136 return KERN_SUCCESS
;
4139 * check that range specified is contiguous region
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
);
4148 * Check for permanent objects in the destination.
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
);
4162 vm_map_unlock(dst_map
);
4163 return(KERN_SUCCESS
);
4167 * Routine: vm_map_copy_overwrite
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.
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.
4180 * The attributes (protection and inheritance) of the
4181 * destination region are preserved.
4183 * If successful, consumes the copy object.
4184 * Otherwise, the caller is responsible for it.
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.
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.
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.
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
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
4217 static kern_return_t
4218 vm_map_copy_overwrite_nested(
4220 vm_map_address_t dst_addr
,
4222 boolean_t interruptible
,
4225 vm_map_offset_t dst_end
;
4226 vm_map_entry_t tmp_entry
;
4227 vm_map_entry_t entry
;
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
;
4238 * Check for null copy object.
4241 if (copy
== VM_MAP_COPY_NULL
)
4242 return(KERN_SUCCESS
);
4245 * Check for special kernel buffer allocated
4246 * by new_ipc_kmsg_copyin.
4249 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
4250 return(vm_map_copyout_kernel_buffer(
4256 * Only works for entry lists at the moment. Will
4257 * support page lists later.
4260 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
4262 if (copy
->size
== 0) {
4263 vm_map_copy_discard(copy
);
4264 return(KERN_SUCCESS
);
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.
4274 if (!page_aligned(copy
->size
) ||
4275 !page_aligned (copy
->offset
) ||
4276 !page_aligned (dst_addr
))
4279 dst_end
= vm_map_round_page(dst_addr
+ copy
->size
);
4281 dst_end
= dst_addr
+ copy
->size
;
4284 vm_map_lock(dst_map
);
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.
4290 if (dst_addr
>= dst_map
->max_offset
) {
4291 vm_map_unlock(dst_map
);
4292 return(KERN_INVALID_ADDRESS
);
4296 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4297 vm_map_unlock(dst_map
);
4298 return(KERN_INVALID_ADDRESS
);
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
;
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
;
4309 if (entry
->in_transition
) {
4312 * Say that we are waiting, and wait for entry.
4314 entry
->needs_wakeup
= TRUE
;
4315 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
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- */
4326 encountered_sub_map
= TRUE
;
4327 sub_start
= entry
->offset
;
4329 if(entry
->vme_end
< dst_end
)
4330 sub_end
= entry
->vme_end
;
4333 sub_end
-= entry
->vme_start
;
4334 sub_end
+= entry
->offset
;
4335 vm_map_unlock(dst_map
);
4337 kr
= vm_map_overwrite_submap_recurse(
4338 entry
->object
.sub_map
,
4340 sub_end
- sub_start
);
4341 if(kr
!= KERN_SUCCESS
)
4343 vm_map_lock(dst_map
);
4346 if (dst_end
<= entry
->vme_end
)
4347 goto start_overwrite
;
4348 if(!vm_map_lookup_entry(dst_map
, local_end
,
4350 vm_map_unlock(dst_map
);
4351 return(KERN_INVALID_ADDRESS
);
4353 next
= entry
->vme_next
;
4356 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4357 vm_map_unlock(dst_map
);
4358 return(KERN_PROTECTION_FAILURE
);
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.
4366 if (entry
->in_transition
) {
4369 * Say that we are waiting, and wait for entry.
4371 entry
->needs_wakeup
= TRUE
;
4372 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4378 * our range is contained completely within this map entry
4380 if (dst_end
<= entry
->vme_end
)
4383 * check that range specified is contiguous region
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
);
4393 * Check for permanent objects in the destination.
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
;
4406 * If there are permanent objects in the destination, then
4407 * the copy cannot be interrupted.
4410 if (interruptible
&& contains_permanent_objects
) {
4411 vm_map_unlock(dst_map
);
4412 return(KERN_FAILURE
); /* XXX */
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
4425 total_size
= copy
->size
;
4426 if(encountered_sub_map
) {
4428 /* re-calculate tmp_entry since we've had the map */
4430 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
4431 vm_map_unlock(dst_map
);
4432 return(KERN_INVALID_ADDRESS
);
4435 copy_size
= copy
->size
;
4438 base_addr
= dst_addr
;
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
;
4446 int remaining_entries
= 0;
4449 for (entry
= tmp_entry
; copy_size
== 0;) {
4450 vm_map_entry_t next
;
4452 next
= entry
->vme_next
;
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
) {
4464 * Say that we are waiting, and wait for entry.
4466 entry
->needs_wakeup
= TRUE
;
4467 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4469 if(!vm_map_lookup_entry(dst_map
, base_addr
,
4471 vm_map_unlock(dst_map
);
4472 return(KERN_INVALID_ADDRESS
);
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
;
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
;
4491 if(entry
->vme_start
< base_addr
)
4492 sub_start
= base_addr
;
4494 sub_start
= entry
->vme_start
;
4496 dst_map
, entry
, sub_end
);
4498 dst_map
, entry
, sub_start
);
4499 entry
->is_sub_map
= FALSE
;
4501 entry
->object
.sub_map
);
4502 entry
->object
.sub_map
= NULL
;
4503 entry
->is_shared
= FALSE
;
4504 entry
->needs_copy
= FALSE
;
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
;
4515 /* first take care of any non-sub_map */
4516 /* entries to send */
4517 if(base_addr
< entry
->vme_start
) {
4520 entry
->vme_start
- base_addr
;
4523 sub_start
= entry
->offset
;
4525 if(entry
->vme_end
< dst_end
)
4526 sub_end
= entry
->vme_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
;
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
;
4541 new_offset
= copy
->offset
;
4542 copy_entry
= vm_map_copy_first_entry(copy
);
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
)
4550 vm_map_copy_clip_end(copy
,
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
;
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
);
4564 copy
->cpy_hdr
.links
.prev
;
4565 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4566 copy
->size
= copy_size
;
4568 copy
->cpy_hdr
.nentries
;
4569 remaining_entries
-= nentries
;
4570 copy
->cpy_hdr
.nentries
= nentries
;
4573 local_size
+= entry_size
;
4574 new_offset
+= entry_size
;
4577 copy_entry
= copy_entry
->vme_next
;
4581 if((entry
->use_pmap
) && (pmap
== NULL
)) {
4582 kr
= vm_map_copy_overwrite_nested(
4583 entry
->object
.sub_map
,
4587 entry
->object
.sub_map
->pmap
);
4588 } else if (pmap
!= NULL
) {
4589 kr
= vm_map_copy_overwrite_nested(
4590 entry
->object
.sub_map
,
4593 interruptible
, pmap
);
4595 kr
= vm_map_copy_overwrite_nested(
4596 entry
->object
.sub_map
,
4602 if(kr
!= KERN_SUCCESS
) {
4603 if(next_copy
!= NULL
) {
4604 copy
->cpy_hdr
.nentries
+=
4606 copy
->cpy_hdr
.links
.prev
->vme_next
=
4608 copy
->cpy_hdr
.links
.prev
4610 copy
->size
= total_size
;
4614 if (dst_end
<= local_end
) {
4615 return(KERN_SUCCESS
);
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
;
4627 total_size
-= copy_size
;
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
);
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
);
4649 if (dst_end
<= entry
->vme_end
) {
4650 copy_size
= dst_end
- base_addr
;
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
);
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
;
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
)
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
;
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
);
4692 copy
->cpy_hdr
.links
.prev
;
4693 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4694 copy
->size
= copy_size
;
4696 copy
->cpy_hdr
.nentries
;
4697 remaining_entries
-= nentries
;
4698 copy
->cpy_hdr
.nentries
= nentries
;
4701 local_size
+= entry_size
;
4702 new_offset
+= entry_size
;
4705 copy_entry
= copy_entry
->vme_next
;
4715 local_pmap
= dst_map
->pmap
;
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
+=
4723 copy
->cpy_hdr
.links
.prev
->vme_next
=
4725 copy
->cpy_hdr
.links
.prev
=
4727 copy
->size
+= copy_size
;
4731 vm_map_unlock(dst_map
);
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 !
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
+=
4749 copy
->cpy_hdr
.links
.prev
->vme_next
=
4751 copy
->cpy_hdr
.links
.prev
=
4753 copy
->size
+= copy_size
;
4758 total_size
-= copy_size
;
4761 base_addr
+= copy_size
;
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
;
4771 vm_map_lock(dst_map
);
4773 if (!vm_map_lookup_entry(dst_map
,
4774 base_addr
, &tmp_entry
)) {
4775 vm_map_unlock(dst_map
);
4776 return(KERN_INVALID_ADDRESS
);
4778 if (tmp_entry
->in_transition
) {
4779 entry
->needs_wakeup
= TRUE
;
4780 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4785 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(base_addr
));
4791 * Throw away the vm_map_copy object
4793 vm_map_copy_discard(copy
);
4795 return(KERN_SUCCESS
);
4796 }/* vm_map_copy_overwrite */
4799 vm_map_copy_overwrite(
4801 vm_map_offset_t dst_addr
,
4803 boolean_t interruptible
)
4805 return vm_map_copy_overwrite_nested(
4806 dst_map
, dst_addr
, copy
, interruptible
, (pmap_t
) NULL
);
4811 * Routine: vm_map_copy_overwrite_unaligned [internal use only]
4814 * Physically copy unaligned data
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.
4829 * dst_map is locked on entry and is return locked on success,
4830 * unlocked on error.
4833 static kern_return_t
4834 vm_map_copy_overwrite_unaligned(
4836 vm_map_entry_t entry
,
4838 vm_map_offset_t start
)
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
,
4851 kern_return_t kr
= KERN_SUCCESS
;
4853 vm_map_lock_write_to_read(dst_map
);
4855 src_offset
= copy
->offset
- vm_object_trunc_page(copy
->offset
);
4856 amount_left
= copy
->size
;
4858 * unaligned so we never clipped this entry, we need the offset into
4859 * the vm_object not just the data.
4861 while (amount_left
> 0) {
4863 if (entry
== vm_map_to_entry(dst_map
)) {
4864 vm_map_unlock_read(dst_map
);
4865 return KERN_INVALID_ADDRESS
;
4868 /* "start" must be within the current map entry */
4869 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
4871 dst_offset
= start
- entry
->vme_start
;
4873 dst_size
= entry
->vme_end
- start
;
4875 src_size
= copy_entry
->vme_end
-
4876 (copy_entry
->vme_start
+ src_offset
);
4878 if (dst_size
< src_size
) {
4880 * we can only copy dst_size bytes before
4881 * we have to get the next destination entry
4883 copy_size
= dst_size
;
4886 * we can only copy src_size bytes before
4887 * we have to get the next source copy entry
4889 copy_size
= src_size
;
4892 if (copy_size
> amount_left
) {
4893 copy_size
= amount_left
;
4896 * Entry needs copy, create a shadow shadow object for
4897 * Copy on write region.
4899 if (entry
->needs_copy
&&
4900 ((entry
->protection
& VM_PROT_WRITE
) != 0))
4902 if (vm_map_lock_read_to_write(dst_map
)) {
4903 vm_map_lock_read(dst_map
);
4906 vm_object_shadow(&entry
->object
.vm_object
,
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
);
4913 dst_object
= entry
->object
.vm_object
;
4915 * unlike with the virtual (aligned) copy we're going
4916 * to fault on it therefore we need a target object.
4918 if (dst_object
== VM_OBJECT_NULL
) {
4919 if (vm_map_lock_read_to_write(dst_map
)) {
4920 vm_map_lock_read(dst_map
);
4923 dst_object
= vm_object_allocate((vm_map_size_t
)
4924 entry
->vme_end
- entry
->vme_start
);
4925 entry
->object
.vm_object
= dst_object
;
4927 vm_map_lock_write_to_read(dst_map
);
4930 * Take an object reference and unlock map. The "entry" may
4931 * disappear or change when the map is unlocked.
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
);
4939 * Copy as much as possible in one pass
4942 copy_entry
->object
.vm_object
,
4943 copy_entry
->offset
+ src_offset
,
4946 entry_offset
+ dst_offset
,
4952 src_offset
+= copy_size
;
4953 amount_left
-= copy_size
;
4955 * Release the object reference
4957 vm_object_deallocate(dst_object
);
4959 * If a hard error occurred, return it now
4961 if (kr
!= KERN_SUCCESS
)
4964 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
4965 || amount_left
== 0)
4968 * all done with this copy entry, dispose.
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
);
4974 if ((copy_entry
= vm_map_copy_first_entry(copy
))
4975 == vm_map_copy_to_entry(copy
) && amount_left
) {
4977 * not finished copying but run out of source
4979 return KERN_INVALID_ADDRESS
;
4984 if (amount_left
== 0)
4985 return KERN_SUCCESS
;
4987 vm_map_lock_read(dst_map
);
4988 if (version
.main_timestamp
== dst_map
->timestamp
) {
4989 if (start
== entry_end
) {
4991 * destination region is split. Use the version
4992 * information to avoid a lookup in the normal
4995 entry
= entry
->vme_next
;
4997 * should be contiguous. Fail if we encounter
4998 * a hole in the destination.
5000 if (start
!= entry
->vme_start
) {
5001 vm_map_unlock_read(dst_map
);
5002 return KERN_INVALID_ADDRESS
;
5007 * Map version check failed.
5008 * we must lookup the entry because somebody
5009 * might have changed the map behind our backs.
5012 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
5014 vm_map_unlock_read(dst_map
);
5015 return KERN_INVALID_ADDRESS
;
5020 return KERN_SUCCESS
;
5021 }/* vm_map_copy_overwrite_unaligned */
5024 * Routine: vm_map_copy_overwrite_aligned [internal use only]
5027 * Does all the vm_trickery possible for whole pages.
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.
5042 static kern_return_t
5043 vm_map_copy_overwrite_aligned(
5045 vm_map_entry_t tmp_entry
,
5047 vm_map_offset_t start
,
5048 #if !BAD_OPTIMIZATION
5050 #endif /* !BAD_OPTIMIZATION */
5054 vm_map_entry_t copy_entry
;
5055 vm_map_size_t copy_size
;
5057 vm_map_entry_t entry
;
5059 while ((copy_entry
= vm_map_copy_first_entry(copy
))
5060 != vm_map_copy_to_entry(copy
))
5062 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
5065 if (entry
== vm_map_to_entry(dst_map
)) {
5066 vm_map_unlock(dst_map
);
5067 return KERN_INVALID_ADDRESS
;
5069 size
= (entry
->vme_end
- entry
->vme_start
);
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
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
);
5082 assert(entry
!= vm_map_to_entry(dst_map
));
5085 * Check protection again
5088 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
5089 vm_map_unlock(dst_map
);
5090 return(KERN_PROTECTION_FAILURE
);
5094 * Adjust to source size first
5097 if (copy_size
< size
) {
5098 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
5103 * Adjust to destination size
5106 if (size
< copy_size
) {
5107 vm_map_copy_clip_end(copy
, copy_entry
,
5108 copy_entry
->vme_start
+ size
);
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
);
5117 * If the destination contains temporary unshared memory,
5118 * we can perform the copy by throwing it away and
5119 * installing the source data.
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
;
5132 * Ensure that the source and destination aren't
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
);
5140 if (old_object
!= VM_OBJECT_NULL
)
5141 vm_object_deallocate(old_object
);
5143 start
= tmp_entry
->vme_end
;
5144 tmp_entry
= tmp_entry
->vme_next
;
5148 if (old_object
!= VM_OBJECT_NULL
) {
5149 if(entry
->is_sub_map
) {
5150 if(entry
->use_pmap
) {
5152 pmap_unnest(dst_map
->pmap
,
5155 if(dst_map
->mapped
) {
5156 /* clean up parent */
5158 vm_map_submap_pmap_clean(
5159 dst_map
, entry
->vme_start
,
5161 entry
->object
.sub_map
,
5165 vm_map_submap_pmap_clean(
5166 dst_map
, entry
->vme_start
,
5168 entry
->object
.sub_map
,
5172 entry
->object
.sub_map
);
5174 if(dst_map
->mapped
) {
5175 vm_object_pmap_protect(
5176 entry
->object
.vm_object
,
5184 pmap_remove(dst_map
->pmap
,
5185 (addr64_t
)(entry
->vme_start
),
5186 (addr64_t
)(entry
->vme_end
));
5188 vm_object_deallocate(old_object
);
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
;
5200 vm_map_copy_entry_unlink(copy
, copy_entry
);
5201 vm_map_copy_entry_dispose(copy
, copy_entry
);
5202 #if BAD_OPTIMIZATION
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
5214 * Try to aggressively enter physical mappings
5215 * (but avoid uninstantiated objects)
5217 if (object
!= VM_OBJECT_NULL
) {
5218 vm_map_offset_t va
= entry
->vme_start
;
5220 while (va
< entry
->vme_end
) {
5221 register vm_page_t m
;
5225 * Look for the page in the top object
5227 prot
= entry
->protection
;
5228 vm_object_lock(object
);
5229 vm_object_paging_begin(object
);
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.
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))) {
5247 vm_object_unlock(object
);
5250 * Honor COW obligations
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. */
5260 PMAP_ENTER(pmap
, va
, m
, prot
,
5262 (m
->object
->wimg_bits
))
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
);
5273 vm_object_paging_end(object
);
5274 vm_object_unlock(object
);
5276 offset
+= PAGE_SIZE_64
;
5278 } /* end while (va < entry->vme_end) */
5279 } /* end if (object) */
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.
5289 start
= tmp_entry
->vme_end
;
5290 tmp_entry
= tmp_entry
->vme_next
;
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
;
5298 * Take an object reference, and record
5299 * the map version information so that the
5300 * map can be safely unlocked.
5303 vm_object_reference(dst_object
);
5305 /* account for unlock bumping up timestamp */
5306 version
.main_timestamp
= dst_map
->timestamp
+ 1;
5308 vm_map_unlock(dst_map
);
5311 * Copy as much as possible in one pass
5316 copy_entry
->object
.vm_object
,
5326 * Release the object reference
5329 vm_object_deallocate(dst_object
);
5332 * If a hard error occurred, return it now
5335 if (r
!= KERN_SUCCESS
)
5338 if (copy_size
!= 0) {
5340 * Dispose of the copied region
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
);
5351 * Pick up in the destination map where we left off.
5353 * Use the version information to avoid a lookup
5354 * in the normal case.
5358 vm_map_lock(dst_map
);
5359 if (version
.main_timestamp
== dst_map
->timestamp
) {
5360 /* We can safely use saved tmp_entry value */
5362 vm_map_clip_end(dst_map
, tmp_entry
, start
);
5363 tmp_entry
= tmp_entry
->vme_next
;
5365 /* Must do lookup of tmp_entry */
5367 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
5368 vm_map_unlock(dst_map
);
5369 return(KERN_INVALID_ADDRESS
);
5371 vm_map_clip_start(dst_map
, tmp_entry
, start
);
5376 return(KERN_SUCCESS
);
5377 }/* vm_map_copy_overwrite_aligned */
5380 * Routine: vm_map_copyin_kernel_buffer [internal use only]
5383 * Copy in data to a kernel buffer from space in the
5384 * source map. The original space may be optionally
5387 * If successful, returns a new copy object.
5389 static kern_return_t
5390 vm_map_copyin_kernel_buffer(
5392 vm_map_offset_t src_addr
,
5394 boolean_t src_destroy
,
5395 vm_map_copy_t
*copy_result
)
5399 vm_map_size_t kalloc_size
= sizeof(struct vm_map_copy
) + len
;
5401 copy
= (vm_map_copy_t
) kalloc(kalloc_size
);
5402 if (copy
== VM_MAP_COPY_NULL
) {
5403 return KERN_RESOURCE_SHORTAGE
;
5405 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
5408 copy
->cpy_kdata
= (void *) (copy
+ 1);
5409 copy
->cpy_kalloc_size
= kalloc_size
;
5411 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, len
);
5412 if (kr
!= KERN_SUCCESS
) {
5413 kfree(copy
, kalloc_size
);
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);
5424 *copy_result
= copy
;
5425 return KERN_SUCCESS
;
5429 * Routine: vm_map_copyout_kernel_buffer [internal use only]
5432 * Copy out data from a kernel buffer into space in the
5433 * destination map. The space may be otpionally dynamically
5436 * If successful, consumes the copy object.
5437 * Otherwise, the caller is responsible for it.
5439 static int vm_map_copyout_kernel_buffer_failures
= 0;
5440 static kern_return_t
5441 vm_map_copyout_kernel_buffer(
5443 vm_map_address_t
*addr
, /* IN/OUT */
5445 boolean_t overwrite
)
5447 kern_return_t kr
= KERN_SUCCESS
;
5448 thread_t thread
= current_thread();
5453 * Allocate space in the target map for the data
5456 kr
= vm_map_enter(map
,
5458 vm_map_round_page(copy
->size
),
5459 (vm_map_offset_t
) 0,
5462 (vm_object_offset_t
) 0,
5466 VM_INHERIT_DEFAULT
);
5467 if (kr
!= KERN_SUCCESS
)
5472 * Copyout the data from the kernel buffer to the target map.
5474 if (thread
->map
== map
) {
5477 * If the target map is the current map, just do
5480 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5481 kr
= KERN_INVALID_ADDRESS
;
5488 * If the target map is another map, assume the
5489 * target's address space identity for the duration
5492 vm_map_reference(map
);
5493 oldmap
= vm_map_switch(map
);
5495 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5496 vm_map_copyout_kernel_buffer_failures
++;
5497 kr
= KERN_INVALID_ADDRESS
;
5500 (void) vm_map_switch(oldmap
);
5501 vm_map_deallocate(map
);
5504 if (kr
!= KERN_SUCCESS
) {
5505 /* the copy failed, clean up */
5508 * Deallocate the space we allocated in the target map.
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
)),
5518 /* copy was successful, dicard the copy structure */
5519 kfree(copy
, copy
->cpy_kalloc_size
);
5526 * Macro: vm_map_copy_insert
5529 * Link a copy chain ("copy") into a map at the
5530 * specified location (after "where").
5532 * The copy chain is destroyed.
5534 * The arguments are evaluated multiple times.
5536 #define vm_map_copy_insert(map, where, copy) \
5538 vm_map_t VMCI_map; \
5539 vm_map_entry_t VMCI_where; \
5540 vm_map_copy_t VMCI_copy; \
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); \
5554 * Routine: vm_map_copyout
5557 * Copy out a copy chain ("copy") into newly-allocated
5558 * space in the destination map.
5560 * If successful, consumes the copy object.
5561 * Otherwise, the caller is responsible for it.
5566 vm_map_address_t
*dst_addr
, /* OUT */
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
;
5575 vm_map_entry_t entry
;
5578 * Check for null copy object.
5581 if (copy
== VM_MAP_COPY_NULL
) {
5583 return(KERN_SUCCESS
);
5587 * Check for special copy object, created
5588 * by vm_map_copyin_object.
5591 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
5592 vm_object_t object
= copy
->cpy_object
;
5594 vm_object_offset_t offset
;
5596 offset
= vm_object_trunc_page(copy
->offset
);
5597 size
= vm_map_round_page(copy
->size
+
5598 (vm_map_size_t
)(copy
->offset
- offset
));
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
)
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
);
5614 * Check for special kernel buffer allocated
5615 * by new_ipc_kmsg_copyin.
5618 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
5619 return(vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
5624 * Find space for the data
5627 vm_copy_start
= vm_object_trunc_page(copy
->offset
);
5628 size
= vm_map_round_page((vm_map_size_t
)copy
->offset
+ copy
->size
)
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
;
5639 vm_map_entry_t next
= last
->vme_next
;
5640 vm_map_offset_t end
= start
+ size
;
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
);
5652 vm_map_unlock(dst_map
);
5653 return(KERN_NO_SPACE
);
5656 if ((next
== vm_map_to_entry(dst_map
)) ||
5657 (next
->vme_start
>= end
))
5661 start
= last
->vme_end
;
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.
5670 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
5672 * Mismatches occur when dealing with the default
5676 vm_map_entry_t next
, new;
5679 * Find the zone that the copies were allocated from
5681 old_zone
= (copy
->cpy_hdr
.entries_pageable
)
5683 : vm_map_kentry_zone
;
5684 entry
= vm_map_copy_first_entry(copy
);
5687 * Reinitialize the copy so that vm_map_copy_entry_link
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
);
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
),
5706 next
= entry
->vme_next
;
5707 zfree(old_zone
, entry
);
5713 * Adjust the addresses in the copy chain, and
5714 * reset the region attributes.
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
;
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
;
5730 * If the entry is now wired,
5731 * map the pages into the destination map.
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
;
5738 object
= entry
->object
.vm_object
;
5739 offset
= entry
->offset
;
5740 va
= entry
->vme_start
;
5742 pmap_pageable(dst_map
->pmap
,
5747 while (va
< entry
->vme_end
) {
5748 register vm_page_t m
;
5751 * Look up the page in the object.
5752 * Assert that the page will be found in the
5755 * the object was newly created by
5756 * vm_object_copy_slowly, and has
5757 * copies of all of the pages from
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
5767 vm_object_lock(object
);
5768 vm_object_paging_begin(object
);
5770 m
= vm_page_lookup(object
, offset
);
5771 if (m
== VM_PAGE_NULL
|| m
->wire_count
== 0 ||
5773 panic("vm_map_copyout: wiring 0x%x", m
);
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
5783 ASSERT_PAGE_DECRYPTED(m
);
5786 vm_object_unlock(object
);
5788 PMAP_ENTER(dst_map
->pmap
, va
, m
, entry
->protection
,
5790 (m
->object
->wimg_bits
))
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
);
5800 offset
+= PAGE_SIZE_64
;
5804 else if (size
<= vm_map_aggressive_enter_max
) {
5806 register vm_map_offset_t va
;
5807 vm_object_offset_t offset
;
5808 register vm_object_t object
;
5811 object
= entry
->object
.vm_object
;
5812 if (object
!= VM_OBJECT_NULL
) {
5814 offset
= entry
->offset
;
5815 va
= entry
->vme_start
;
5816 while (va
< entry
->vme_end
) {
5817 register vm_page_t m
;
5820 * Look up the page in the object.
5821 * Assert that the page will be found
5822 * in the top object if at all...
5824 vm_object_lock(object
);
5825 vm_object_paging_begin(object
);
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.
5836 if (((m
= vm_page_lookup(object
,
5839 !m
->busy
&& !m
->fictitious
&&
5841 !m
->absent
&& !m
->error
) {
5843 vm_object_unlock(object
);
5845 /* honor cow obligations */
5846 prot
= entry
->protection
;
5847 if (entry
->needs_copy
)
5848 prot
&= ~VM_PROT_WRITE
;
5850 PMAP_ENTER(dst_map
->pmap
, va
,
5853 (m
->object
->wimg_bits
))
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
);
5864 vm_object_paging_end(object
);
5865 vm_object_unlock(object
);
5867 offset
+= PAGE_SIZE_64
;
5875 * Correct the page alignment for the result
5878 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
5881 * Update the hints and the map size
5884 SAVE_HINT(dst_map
, vm_map_copy_last_entry(copy
));
5886 dst_map
->size
+= size
;
5892 vm_map_copy_insert(dst_map
, last
, copy
);
5894 vm_map_unlock(dst_map
);
5897 * XXX If wiring_required, call vm_map_pageable
5900 return(KERN_SUCCESS
);
5904 * Routine: vm_map_copyin
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).
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).
5918 * In/out conditions:
5919 * The source map should not be locked on entry.
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
;
5930 vm_map_copyin_common(
5932 vm_map_address_t src_addr
,
5934 boolean_t src_destroy
,
5935 __unused boolean_t src_volatile
,
5936 vm_map_copy_t
*copy_result
, /* OUT */
5937 boolean_t use_maxprot
)
5939 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
5940 * in multi-level lookup, this
5941 * entry contains the actual
5945 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
5947 vm_map_offset_t src_start
; /* Start of current entry --
5948 * where copy is taking place now
5950 vm_map_offset_t src_end
; /* End of entire region to be
5952 vm_map_t base_map
= src_map
;
5953 boolean_t map_share
=FALSE
;
5954 submap_map_t
*parent_maps
= NULL
;
5957 vm_map_copy_t copy
; /* Resulting copy */
5958 vm_map_address_t copy_addr
;
5961 * Check for copies of zero bytes.
5965 *copy_result
= VM_MAP_COPY_NULL
;
5966 return(KERN_SUCCESS
);
5970 * Check that the end address doesn't overflow
5972 src_end
= src_addr
+ len
;
5973 if (src_end
< src_addr
)
5974 return KERN_INVALID_ADDRESS
;
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.
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
);
5987 * Compute (page aligned) start and end of region
5989 src_start
= vm_map_trunc_page(src_addr
);
5990 src_end
= vm_map_round_page(src_end
);
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);
5995 * Allocate a header element for the list.
5997 * Use the start and end in the header to
5998 * remember the endpoints prior to rounding.
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
;
6008 copy
->offset
= src_addr
;
6011 new_entry
= vm_map_copy_entry_create(copy
);
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); \
6022 submap_map_t *_ptr; \
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)); \
6035 * Find the beginning of the region.
6038 vm_map_lock(src_map
);
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
);
6045 /* set for later submap fix-up */
6046 copy_addr
= src_start
;
6049 * Go through entries until we get to the end.
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
6061 vm_object_t src_object
; /* Object to copy */
6062 vm_object_offset_t src_offset
;
6064 boolean_t src_needs_copy
; /* Should source map
6066 * for copy-on-write?
6069 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
6071 boolean_t was_wired
; /* Was source wired? */
6072 vm_map_version_t version
; /* Version before locks
6073 * dropped to make copy
6075 kern_return_t result
; /* Return value from
6076 * copy_strategically.
6078 while(tmp_entry
->is_sub_map
) {
6079 vm_map_size_t submap_len
;
6082 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
6083 ptr
->next
= parent_maps
;
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
;
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
);
6106 if(!tmp_entry
->is_sub_map
)
6107 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6108 src_entry
= tmp_entry
;
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
);
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.
6127 if (new_entry
== VM_MAP_ENTRY_NULL
) {
6128 version
.main_timestamp
= src_map
->timestamp
;
6129 vm_map_unlock(src_map
);
6131 new_entry
= vm_map_copy_entry_create(copy
);
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
,
6137 RETURN(KERN_INVALID_ADDRESS
);
6139 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6140 continue; /* restart w/ new tmp_entry */
6145 * Verify that the region can be read.
6147 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
6149 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
6150 RETURN(KERN_PROTECTION_FAILURE
);
6153 * Clip against the endpoints of the entire region.
6156 vm_map_clip_end(src_map
, src_entry
, src_end
);
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);
6163 vm_map_entry_copy(new_entry
, src_entry
);
6164 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
6167 * Attempt non-blocking copy-on-write optimizations.
6171 (src_object
== VM_OBJECT_NULL
||
6172 (src_object
->internal
&& !src_object
->true_share
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.
6182 vm_object_reference(src_object
);
6185 * Copy is always unwired. vm_map_copy_entry
6186 * set its wired count to zero.
6189 goto CopySuccessful
;
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
,
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
,
6204 &new_entry_needs_copy
)) {
6206 new_entry
->needs_copy
= new_entry_needs_copy
;
6209 * Handle copy-on-write obligations
6212 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
6213 vm_object_pmap_protect(
6217 (src_entry
->is_shared
?
6220 src_entry
->vme_start
,
6221 src_entry
->protection
&
6223 tmp_entry
->needs_copy
= TRUE
;
6227 * The map has never been unlocked, so it's safe
6228 * to move to the next entry rather than doing
6232 goto CopySuccessful
;
6236 * Take an object reference, so that we may
6237 * release the map lock(s).
6240 assert(src_object
!= VM_OBJECT_NULL
);
6241 vm_object_reference(src_object
);
6244 * Record the timestamp for later verification.
6248 version
.main_timestamp
= src_map
->timestamp
;
6249 vm_map_unlock(src_map
); /* Increments timestamp once! */
6257 vm_object_lock(src_object
);
6258 result
= vm_object_copy_slowly(
6263 &new_entry
->object
.vm_object
);
6264 new_entry
->offset
= 0;
6265 new_entry
->needs_copy
= FALSE
;
6268 else if (src_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
6269 (tmp_entry
->is_shared
|| map_share
)) {
6270 vm_object_t new_object
;
6272 vm_object_lock(src_object
);
6273 new_object
= vm_object_copy_delayed(
6277 if (new_object
== VM_OBJECT_NULL
)
6280 new_entry
->object
.vm_object
= new_object
;
6281 new_entry
->needs_copy
= TRUE
;
6282 result
= KERN_SUCCESS
;
6285 result
= vm_object_copy_strategically(src_object
,
6288 &new_entry
->object
.vm_object
,
6290 &new_entry_needs_copy
);
6292 new_entry
->needs_copy
= new_entry_needs_copy
;
6295 if (result
!= KERN_SUCCESS
&&
6296 result
!= KERN_MEMORY_RESTART_COPY
) {
6297 vm_map_lock(src_map
);
6302 * Throw away the extra reference
6305 vm_object_deallocate(src_object
);
6308 * Verify that the map has not substantially
6309 * changed while the copy was being made.
6312 vm_map_lock(src_map
);
6314 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
)
6315 goto VerificationSuccessful
;
6318 * Simple version comparison failed.
6320 * Retry the lookup and verify that the
6321 * same object/offset are still present.
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.]
6329 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
6330 RETURN(KERN_INVALID_ADDRESS
);
6333 src_entry
= tmp_entry
;
6334 vm_map_clip_start(src_map
, src_entry
, src_start
);
6336 if ((((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
) &&
6338 ((src_entry
->max_protection
& VM_PROT_READ
) == 0))
6339 goto VerificationFailed
;
6341 if (src_entry
->vme_end
< new_entry
->vme_end
)
6342 src_size
= (new_entry
->vme_end
= src_entry
->vme_end
) - src_start
;
6344 if ((src_entry
->object
.vm_object
!= src_object
) ||
6345 (src_entry
->offset
!= src_offset
) ) {
6348 * Verification failed.
6350 * Start over with this top-level entry.
6353 VerificationFailed
: ;
6355 vm_object_deallocate(new_entry
->object
.vm_object
);
6356 tmp_entry
= src_entry
;
6361 * Verification succeeded.
6364 VerificationSuccessful
: ;
6366 if (result
== KERN_MEMORY_RESTART_COPY
)
6376 * Link in the new copy entry.
6379 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
6383 * Determine whether the entire region
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
) {
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
)
6408 src_entry
= tmp_entry
->vme_prev
;
6412 if ((src_start
>= src_end
) && (src_end
!= 0))
6416 * Verify that there are no gaps in the region
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
);
6426 * If the source should be destroyed, do it now, since the
6427 * copy was successful.
6430 (void) vm_map_delete(src_map
,
6431 vm_map_trunc_page(src_addr
),
6433 (src_map
== kernel_map
) ?
6434 VM_MAP_REMOVE_KUNWIRE
:
6439 vm_map_unlock(src_map
);
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 */
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
;
6454 *copy_result
= copy
;
6455 return(KERN_SUCCESS
);
6461 * vm_map_copyin_object:
6463 * Create a copy object from an object.
6464 * Our caller donates an object reference.
6468 vm_map_copyin_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 */
6474 vm_map_copy_t copy
; /* Resulting copy */
6477 * We drop the object into a special copy object
6478 * that contains the object directly.
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
;
6487 *copy_result
= copy
;
6488 return(KERN_SUCCESS
);
6494 vm_map_entry_t old_entry
,
6498 vm_map_entry_t new_entry
;
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.
6510 object
= old_entry
->object
.vm_object
;
6511 if (old_entry
->is_sub_map
) {
6512 assert(old_entry
->wired_count
== 0);
6514 if(old_entry
->use_pmap
) {
6515 kern_return_t result
;
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
));
6523 panic("vm_map_fork_share: pmap_nest failed!");
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
) {
6536 * We are already using an asymmetric
6537 * copy, and therefore we already have
6541 assert(! old_entry
->needs_copy
);
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
&&
6548 (vm_map_size_t
)(old_entry
->vme_end
-
6549 old_entry
->vme_start
)))) {
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).
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
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.)
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
6628 assert(!(object
->shadowed
&& old_entry
->is_shared
));
6629 vm_object_shadow(&old_entry
->object
.vm_object
,
6631 (vm_map_size_t
) (old_entry
->vme_end
-
6632 old_entry
->vme_start
));
6635 * If we're making a shadow for other than
6636 * copy on write reasons, then we have
6637 * to remove write permission.
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
,
6646 (old_entry
->vme_end
-
6647 old_entry
->vme_start
),
6649 old_entry
->vme_start
,
6650 old_entry
->protection
& ~VM_PROT_WRITE
);
6652 pmap_protect(old_map
->pmap
,
6653 old_entry
->vme_start
,
6655 old_entry
->protection
& ~VM_PROT_WRITE
);
6659 old_entry
->needs_copy
= FALSE
;
6660 object
= old_entry
->object
.vm_object
;
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
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
);
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
;
6683 vm_object_unlock(object
);
6687 * Clone the entry, using object ref from above.
6688 * Mark both entries as shared.
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
;
6697 * Insert the entry into the new map -- we
6698 * know we're inserting at the end of the new
6702 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
6705 * Update the physical map
6708 if (old_entry
->is_sub_map
) {
6709 /* Bill Angell pmap support goes here */
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
);
6720 vm_map_entry_t
*old_entry_p
,
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
;
6727 vm_map_entry_t last
= vm_map_last_entry(new_map
);
6729 vm_map_unlock(old_map
);
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
6736 if (vm_map_copyin_maxprot(old_map
, start
, entry_size
, FALSE
, ©
)
6739 * The map might have changed while it
6740 * was unlocked, check it again. Skip
6741 * any blank space or permanently
6742 * unreadable region.
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
;
6749 *old_entry_p
= last
;
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.
6762 * Insert the copy into the new map
6765 vm_map_copy_insert(new_map
, last
, copy
);
6768 * Pick up the traversal at the end of
6769 * the copied region.
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
;
6777 vm_map_clip_start(old_map
, last
, start
);
6779 *old_entry_p
= last
;
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.
6791 * The source map must not be locked.
6797 pmap_t new_pmap
= pmap_create((vm_map_size_t
) 0);
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
;
6805 vm_map_reference_swap(old_map
);
6806 vm_map_lock(old_map
);
6808 new_map
= vm_map_create(new_pmap
,
6809 old_map
->min_offset
,
6810 old_map
->max_offset
,
6811 old_map
->hdr
.entries_pageable
);
6814 old_entry
= vm_map_first_entry(old_map
);
6815 old_entry
!= vm_map_to_entry(old_map
);
6818 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
6820 switch (old_entry
->inheritance
) {
6821 case VM_INHERIT_NONE
:
6824 case VM_INHERIT_SHARE
:
6825 vm_map_fork_share(old_map
, old_entry
, new_map
);
6826 new_size
+= entry_size
;
6829 case VM_INHERIT_COPY
:
6832 * Inline the copy_quickly case;
6833 * upon failure, fall back on call
6834 * to vm_map_fork_copy.
6837 if(old_entry
->is_sub_map
)
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
;
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
;
6850 if (! vm_object_copy_quickly(
6851 &new_entry
->object
.vm_object
,
6853 (old_entry
->vme_end
-
6854 old_entry
->vme_start
),
6856 &new_entry_needs_copy
)) {
6857 vm_map_entry_dispose(new_map
, new_entry
);
6858 goto slow_vm_map_fork_copy
;
6862 * Handle copy-on-write obligations
6865 if (src_needs_copy
&& !old_entry
->needs_copy
) {
6866 vm_object_pmap_protect(
6867 old_entry
->object
.vm_object
,
6869 (old_entry
->vme_end
-
6870 old_entry
->vme_start
),
6871 ((old_entry
->is_shared
6875 old_entry
->vme_start
,
6876 old_entry
->protection
& ~VM_PROT_WRITE
);
6878 old_entry
->needs_copy
= TRUE
;
6880 new_entry
->needs_copy
= new_entry_needs_copy
;
6883 * Insert the entry at the end
6887 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
),
6889 new_size
+= entry_size
;
6892 slow_vm_map_fork_copy
:
6893 if (vm_map_fork_copy(old_map
, &old_entry
, new_map
)) {
6894 new_size
+= entry_size
;
6898 old_entry
= old_entry
->vme_next
;
6901 new_map
->size
= new_size
;
6902 vm_map_unlock(old_map
);
6903 vm_map_deallocate(old_map
);
6910 * vm_map_lookup_locked:
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
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"
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
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
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 */
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
;
6961 * If the map has an interesting hint, try it before calling
6962 * full blown lookup routine.
6965 mutex_lock(&map
->s_lock
);
6967 mutex_unlock(&map
->s_lock
);
6969 if ((entry
== vm_map_to_entry(map
)) ||
6970 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
6971 vm_map_entry_t tmp_entry
;
6974 * Entry was either not a valid hint, or the vaddr
6975 * was not contained in the entry, so do a full lookup.
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
;
6988 if(map
== old_map
) {
6989 old_start
= entry
->vme_start
;
6990 old_end
= entry
->vme_end
;
6994 * Handle submaps. Drop lock on upper map, submap is
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
;
7006 local_vaddr
= vaddr
;
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
;
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
)
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
;
7034 vm_map_lock_read(entry
->object
.sub_map
);
7035 if((cow_sub_map_parent
!= map
) &&
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
);
7050 *var_map
= map
= entry
->object
.sub_map
;
7052 /* calculate the offset in the submap for vaddr */
7053 local_vaddr
= (local_vaddr
- entry
->vme_start
) + entry
->offset
;
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
);
7060 if((*real_map
!= map
)
7061 && (*real_map
!= cow_sub_map_parent
)) {
7062 vm_map_unlock(*real_map
);
7065 return KERN_INVALID_ADDRESS
;
7067 /* find the attenuated shadow of the underlying object */
7068 /* on our target map */
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;
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
;
7087 old_start
+= start_delta
;
7088 old_end
-= end_delta
;
7090 if(submap_entry
->is_sub_map
) {
7091 entry
= submap_entry
;
7092 vaddr
= local_vaddr
;
7093 goto submap_recurse
;
7096 if(((fault_type
& VM_PROT_WRITE
) && cow_sub_map_parent
)) {
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
;
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
;
7111 if (submap_entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7112 submap_entry
->object
.vm_object
=
7115 (submap_entry
->vme_end
7116 - submap_entry
->vme_start
));
7117 submap_entry
->offset
= 0;
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
);
7126 /* This is the COW case, lets connect */
7127 /* an entry in our space to the underlying */
7128 /* object in the submap, bypassing the */
7132 if(submap_entry
->wired_count
!= 0) {
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
,
7142 copied_slowly
= TRUE
;
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
7157 PMAP_NULL
: map
->pmap
,
7158 submap_entry
->vme_start
,
7159 submap_entry
->protection
&
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, */
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
;
7179 if(!vm_map_lookup_entry(map
,
7181 vm_object_deallocate(
7183 vm_map_lock_write_to_read(map
);
7184 return KERN_INVALID_ADDRESS
;
7187 /* clip out the portion of space */
7188 /* mapped by the sub map which */
7189 /* corresponds to the underlying */
7191 vm_map_clip_start(map
, entry
, local_start
);
7192 vm_map_clip_end(map
, entry
, local_end
);
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
;
7201 entry
->protection
|= VM_PROT_WRITE
;
7202 entry
->max_protection
|= VM_PROT_WRITE
;
7205 entry
->needs_copy
= FALSE
;
7206 entry
->is_shared
= FALSE
;
7208 entry
->offset
= submap_entry
->offset
;
7209 entry
->needs_copy
= TRUE
;
7210 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7211 entry
->inheritance
= VM_INHERIT_COPY
;
7213 entry
->is_shared
= TRUE
;
7215 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7216 entry
->inheritance
= VM_INHERIT_COPY
;
7218 vm_map_lock_write_to_read(map
);
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
);
7225 entry
= submap_entry
;
7226 vaddr
= local_vaddr
;
7231 * Check whether this task is allowed to have
7235 prot
= entry
->protection
;
7236 if ((fault_type
& (prot
)) != fault_type
) {
7237 if (*real_map
!= map
) {
7238 vm_map_unlock(*real_map
);
7241 return KERN_PROTECTION_FAILURE
;
7245 * If this page is not pageable, we have to get
7246 * it for all possible accesses.
7249 *wired
= (entry
->wired_count
!= 0);
7251 prot
= fault_type
= entry
->protection
;
7254 * If the entry was copy-on-write, we either ...
7257 if (entry
->needs_copy
) {
7259 * If we want to write the page, we may as well
7260 * handle that now since we've got the map locked.
7262 * If we don't need to write the page, we just
7263 * demote the permissions allowed.
7266 if ((fault_type
& VM_PROT_WRITE
) || *wired
) {
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.
7274 if (vm_map_lock_read_to_write(map
)) {
7275 vm_map_lock_read(map
);
7278 vm_object_shadow(&entry
->object
.vm_object
,
7280 (vm_map_size_t
) (entry
->vme_end
-
7283 entry
->object
.vm_object
->shadowed
= TRUE
;
7284 entry
->needs_copy
= FALSE
;
7285 vm_map_lock_write_to_read(map
);
7289 * We're attempting to read a copy-on-write
7290 * page -- don't allow writes.
7293 prot
&= (~VM_PROT_WRITE
);
7298 * Create an object if necessary.
7300 if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7302 if (vm_map_lock_read_to_write(map
)) {
7303 vm_map_lock_read(map
);
7307 entry
->object
.vm_object
= vm_object_allocate(
7308 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
7310 vm_map_lock_write_to_read(map
);
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.
7319 *offset
= (vaddr
- entry
->vme_start
) + entry
->offset
;
7320 *object
= entry
->object
.vm_object
;
7322 *behavior
= entry
->behavior
;
7323 *lo_offset
= entry
->offset
;
7324 *hi_offset
= (entry
->vme_end
- entry
->vme_start
) + entry
->offset
;
7327 * Lock the object to prevent it from disappearing
7330 vm_object_lock(*object
);
7333 * Save the version number
7336 out_version
->main_timestamp
= map
->timestamp
;
7338 return KERN_SUCCESS
;
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.
7351 register vm_map_t map
,
7352 register vm_map_version_t
*version
) /* REF */
7356 vm_map_lock_read(map
);
7357 result
= (map
->timestamp
== version
->main_timestamp
);
7360 vm_map_unlock_read(map
);
7366 * vm_map_verify_done:
7368 * Releases locks acquired by a vm_map_verify.
7370 * This is now a macro in vm/vm_map.h. It does a
7371 * vm_map_unlock_read on the map.
7376 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
7377 * Goes away after regular vm_region_recurse function migrates to
7379 * vm_region_recurse: A form of vm_region which follows the
7380 * submaps in a target map
7385 vm_map_region_recurse_64(
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 */
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
;
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
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.
7411 vm_map_entry_t curr_entry
;
7412 vm_map_offset_t curr_offset
;
7414 unsigned int curr_depth
;
7415 vm_map_offset_t curr_max_offset
;
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.
7423 vm_map_entry_t next_entry
;
7424 vm_map_offset_t next_offset
;
7426 unsigned int next_depth
;
7427 vm_map_offset_t next_max_offset
;
7429 if (map
== VM_MAP_NULL
) {
7430 /* no address space to work on */
7431 return KERN_INVALID_ARGUMENT
;
7434 if (*count
< VM_REGION_SUBMAP_INFO_COUNT_64
) {
7435 /* "info" structure is not big enough and would overflow */
7436 return KERN_INVALID_ARGUMENT
;
7439 *count
= VM_REGION_SUBMAP_INFO_COUNT_64
;
7441 user_address
= *address
;
7442 user_max_depth
= *nesting_depth
;
7448 curr_max_offset
= curr_map
->max_offset
;
7454 next_max_offset
= curr_max_offset
;
7457 vm_map_lock_read(curr_map
);
7461 if (vm_map_lookup_entry(curr_map
,
7462 user_address
- curr_offset
,
7464 /* tmp_entry contains the address we're looking for */
7465 curr_entry
= tmp_entry
;
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.
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 */
7477 vm_map_unlock_read(curr_map
);
7483 curr_max_offset
= 0;
7489 * Is the next entry at this level closer to the address (or
7490 * deeper in the submap chain) than the one we had
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
) {
7498 * tmp_entry is beyond the scope of what we mapped of
7499 * this submap in the upper level: ignore it.
7501 } else if ((next_entry
== NULL
) ||
7502 (tmp_entry
->vme_start
+ curr_offset
<=
7503 next_entry
->vme_start
+ next_offset
)) {
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".
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
);
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
;
7522 if (!curr_entry
->is_sub_map
||
7523 curr_depth
>= user_max_depth
) {
7525 * We hit a leaf map or we reached the maximum depth
7526 * we could, so stop looking. Keep the current map
7533 * Get down to the next submap level.
7537 * Lock the next level and unlock the current level,
7538 * unless we need to keep it locked to access the "next_entry"
7542 vm_map_lock_read(curr_entry
->object
.sub_map
);
7544 if (curr_map
== next_map
) {
7545 /* keep "next_map" locked in case we need it */
7547 /* release this map */
7548 vm_map_unlock_read(curr_map
);
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).
7561 (curr_entry
->vme_start
- curr_entry
->offset
);
7562 /* switch to the submap */
7563 curr_map
= curr_entry
->object
.sub_map
;
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
7570 * The relevant portion of the map starts at
7571 * "curr_entry->offset" up to the size of "curr_entry".
7574 curr_entry
->vme_end
- curr_entry
->vme_start
+
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
;
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
;
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
);
7604 next_max_offset
= 0;
7606 *nesting_depth
= curr_depth
;
7607 *size
= curr_entry
->vme_end
- curr_entry
->vme_start
;
7608 *address
= curr_entry
->vme_start
+ curr_offset
;
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
;
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;
7628 if (!curr_entry
->is_sub_map
) {
7629 vm_map_region_walk(curr_map
,
7630 curr_entry
->vme_start
,
7633 (curr_entry
->vme_end
-
7634 curr_entry
->vme_start
),
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
;
7642 submap_info
->ref_count
= extended
.ref_count
;
7644 if (curr_entry
->use_pmap
) {
7645 submap_info
->share_mode
= SM_TRUESHARED
;
7647 submap_info
->share_mode
= SM_PRIVATE
;
7649 submap_info
->ref_count
=
7650 curr_entry
->object
.sub_map
->ref_count
;
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
;
7663 vm_map_unlock_read(curr_map
);
7666 return KERN_SUCCESS
;
7672 * User call to obtain information about a region in
7673 * a task's address map. Currently, only one flavor is
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.
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 */
7691 vm_map_entry_t tmp_entry
;
7692 vm_map_entry_t entry
;
7693 vm_map_offset_t start
;
7695 if (map
== VM_MAP_NULL
)
7696 return(KERN_INVALID_ARGUMENT
);
7700 case VM_REGION_BASIC_INFO
:
7701 /* legacy for old 32-bit objects info */
7703 vm_region_basic_info_t basic
;
7705 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
7706 return(KERN_INVALID_ARGUMENT
);
7708 basic
= (vm_region_basic_info_t
) info
;
7709 *count
= VM_REGION_BASIC_INFO_COUNT
;
7711 vm_map_lock_read(map
);
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
);
7723 start
= entry
->vme_start
;
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
;
7733 *size
= (entry
->vme_end
- start
);
7735 if (object_name
) *object_name
= IP_NULL
;
7736 if (entry
->is_sub_map
) {
7737 basic
->shared
= FALSE
;
7739 basic
->shared
= entry
->is_shared
;
7742 vm_map_unlock_read(map
);
7743 return(KERN_SUCCESS
);
7746 case VM_REGION_BASIC_INFO_64
:
7748 vm_region_basic_info_64_t basic
;
7750 if (*count
< VM_REGION_BASIC_INFO_COUNT_64
)
7751 return(KERN_INVALID_ARGUMENT
);
7753 basic
= (vm_region_basic_info_64_t
) info
;
7754 *count
= VM_REGION_BASIC_INFO_COUNT_64
;
7756 vm_map_lock_read(map
);
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
);
7768 start
= entry
->vme_start
;
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
;
7778 *size
= (entry
->vme_end
- start
);
7780 if (object_name
) *object_name
= IP_NULL
;
7781 if (entry
->is_sub_map
) {
7782 basic
->shared
= FALSE
;
7784 basic
->shared
= entry
->is_shared
;
7787 vm_map_unlock_read(map
);
7788 return(KERN_SUCCESS
);
7790 case VM_REGION_EXTENDED_INFO
:
7792 vm_region_extended_info_t extended
;
7794 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
7795 return(KERN_INVALID_ARGUMENT
);
7797 extended
= (vm_region_extended_info_t
) info
;
7798 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
7800 vm_map_lock_read(map
);
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
);
7811 start
= entry
->vme_start
;
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;
7822 vm_map_region_walk(map
, start
, entry
, entry
->offset
, entry
->vme_end
- start
, extended
);
7824 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
7825 extended
->share_mode
= SM_PRIVATE
;
7828 *object_name
= IP_NULL
;
7830 *size
= (entry
->vme_end
- start
);
7832 vm_map_unlock_read(map
);
7833 return(KERN_SUCCESS
);
7835 case VM_REGION_TOP_INFO
:
7837 vm_region_top_info_t top
;
7839 if (*count
< VM_REGION_TOP_INFO_COUNT
)
7840 return(KERN_INVALID_ARGUMENT
);
7842 top
= (vm_region_top_info_t
) info
;
7843 *count
= VM_REGION_TOP_INFO_COUNT
;
7845 vm_map_lock_read(map
);
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
);
7857 start
= entry
->vme_start
;
7859 top
->private_pages_resident
= 0;
7860 top
->shared_pages_resident
= 0;
7862 vm_map_region_top_walk(entry
, top
);
7865 *object_name
= IP_NULL
;
7867 *size
= (entry
->vme_end
- start
);
7869 vm_map_unlock_read(map
);
7870 return(KERN_SUCCESS
);
7873 return(KERN_INVALID_ARGUMENT
);
7878 vm_map_region_top_walk(
7879 vm_map_entry_t entry
,
7880 vm_region_top_info_t top
)
7882 register struct vm_object
*obj
, *tmp_obj
;
7883 register int ref_count
;
7885 if (entry
->object
.vm_object
== 0 || entry
->is_sub_map
) {
7886 top
->share_mode
= SM_EMPTY
;
7892 obj
= entry
->object
.vm_object
;
7894 vm_object_lock(obj
);
7896 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
7901 top
->private_pages_resident
= obj
->resident_page_count
;
7903 top
->shared_pages_resident
= obj
->resident_page_count
;
7904 top
->ref_count
= ref_count
;
7905 top
->share_mode
= SM_COW
;
7907 while ((tmp_obj
= obj
->shadow
)) {
7908 vm_object_lock(tmp_obj
);
7909 vm_object_unlock(obj
);
7912 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
7915 top
->shared_pages_resident
+= obj
->resident_page_count
;
7916 top
->ref_count
+= ref_count
- 1;
7919 if (entry
->needs_copy
) {
7920 top
->share_mode
= SM_COW
;
7921 top
->shared_pages_resident
= obj
->resident_page_count
;
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
;
7928 top
->share_mode
= SM_SHARED
;
7929 top
->shared_pages_resident
= obj
->resident_page_count
;
7932 top
->ref_count
= ref_count
;
7934 top
->obj_id
= (int)obj
;
7936 vm_object_unlock(obj
);
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
)
7949 register struct vm_object
*obj
, *tmp_obj
;
7950 register vm_map_offset_t last_offset
;
7952 register int ref_count
;
7953 struct vm_object
*shadow_object
;
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;
7964 obj
= entry
->object
.vm_object
;
7966 vm_object_lock(obj
);
7968 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
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
);
7974 shadow_object
= obj
->shadow
;
7976 if (shadow_object
!= VM_OBJECT_NULL
) {
7977 vm_object_lock(shadow_object
);
7979 shadow_object
!= VM_OBJECT_NULL
;
7981 vm_object_t next_shadow
;
7983 next_shadow
= shadow_object
->shadow
;
7985 vm_object_lock(next_shadow
);
7987 vm_object_unlock(shadow_object
);
7988 shadow_object
= next_shadow
;
7991 extended
->shadow_depth
= shadow_depth
;
7993 if (extended
->shadow_depth
|| entry
->needs_copy
)
7994 extended
->share_mode
= SM_COW
;
7997 extended
->share_mode
= SM_PRIVATE
;
7999 if (obj
->true_share
)
8000 extended
->share_mode
= SM_TRUESHARED
;
8002 extended
->share_mode
= SM_SHARED
;
8005 extended
->ref_count
= ref_count
- extended
->shadow_depth
;
8007 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
8008 if ((tmp_obj
= obj
->shadow
) == 0)
8010 vm_object_lock(tmp_obj
);
8011 vm_object_unlock(obj
);
8013 if ((ref_count
= tmp_obj
->ref_count
) > 1 && tmp_obj
->paging_in_progress
)
8016 extended
->ref_count
+= ref_count
;
8019 vm_object_unlock(obj
);
8021 if (extended
->share_mode
== SM_SHARED
) {
8022 register vm_map_entry_t cur
;
8023 register vm_map_entry_t last
;
8026 obj
= entry
->object
.vm_object
;
8027 last
= vm_map_to_entry(map
);
8030 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
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
);
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
;
8044 /* object is locked on entry and locked on return */
8048 vm_map_region_look_for_page(
8049 __unused vm_map_t map
,
8050 __unused vm_map_offset_t va
,
8052 vm_object_offset_t offset
,
8055 vm_region_extended_info_t extended
)
8057 register vm_page_t p
;
8058 register vm_object_t shadow
;
8059 register int ref_count
;
8060 vm_object_t caller_object
;
8062 shadow
= object
->shadow
;
8063 caller_object
= object
;
8068 if ( !(object
->pager_trusted
) && !(object
->internal
))
8069 extended
->external_pager
= 1;
8071 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
8072 if (shadow
&& (max_refcnt
== 1))
8073 extended
->pages_shared_now_private
++;
8075 if (!p
->fictitious
&&
8076 (p
->dirty
|| pmap_is_modified(p
->phys_page
)))
8077 extended
->pages_dirtied
++;
8079 extended
->pages_resident
++;
8081 if(object
!= caller_object
)
8082 vm_object_unlock(object
);
8086 if (object
->existence_map
) {
8087 if (vm_external_state_get(object
->existence_map
, offset
) == VM_EXTERNAL_STATE_EXISTS
) {
8089 extended
->pages_swapped_out
++;
8091 if(object
!= caller_object
)
8092 vm_object_unlock(object
);
8098 vm_object_lock(shadow
);
8100 if ((ref_count
= shadow
->ref_count
) > 1 && shadow
->paging_in_progress
)
8103 if (++depth
> extended
->shadow_depth
)
8104 extended
->shadow_depth
= depth
;
8106 if (ref_count
> max_refcnt
)
8107 max_refcnt
= ref_count
;
8109 if(object
!= caller_object
)
8110 vm_object_unlock(object
);
8112 offset
= offset
+ object
->shadow_offset
;
8114 shadow
= object
->shadow
;
8117 if(object
!= caller_object
)
8118 vm_object_unlock(object
);
8124 vm_map_region_count_obj_refs(
8125 vm_map_entry_t entry
,
8128 register int ref_count
;
8129 register vm_object_t chk_obj
;
8130 register vm_object_t tmp_obj
;
8132 if (entry
->object
.vm_object
== 0)
8135 if (entry
->is_sub_map
)
8140 chk_obj
= entry
->object
.vm_object
;
8141 vm_object_lock(chk_obj
);
8144 if (chk_obj
== object
)
8146 tmp_obj
= chk_obj
->shadow
;
8148 vm_object_lock(tmp_obj
);
8149 vm_object_unlock(chk_obj
);
8159 * Routine: vm_map_simplify
8162 * Attempt to simplify the map representation in
8163 * the vicinity of the given starting address.
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.
8172 vm_map_simplify_entry(
8174 vm_map_entry_t this_entry
)
8176 vm_map_entry_t prev_entry
;
8178 counter(c_vm_map_simplify_entry_called
++);
8180 prev_entry
= this_entry
->vme_prev
;
8182 if ((this_entry
!= vm_map_to_entry(map
)) &&
8183 (prev_entry
!= vm_map_to_entry(map
)) &&
8185 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
8187 (prev_entry
->is_sub_map
== FALSE
) &&
8188 (this_entry
->is_sub_map
== FALSE
) &&
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
) &&
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
) &&
8203 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
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
)
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
++);
8227 vm_map_offset_t start
)
8229 vm_map_entry_t this_entry
;
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
);
8236 counter(c_vm_map_simplify_called
++);
8241 vm_map_simplify_range(
8243 vm_map_offset_t start
,
8244 vm_map_offset_t end
)
8246 vm_map_entry_t entry
;
8249 * The map should be locked (for "write") by the caller.
8253 /* invalid address range */
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
);
8263 /* start with next entry */
8264 entry
= entry
->vme_next
;
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
;
8278 * Routine: vm_map_machine_attribute
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.
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]
8292 vm_map_machine_attribute(
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 */
8300 vm_map_size_t sync_size
;
8301 vm_map_entry_t entry
;
8303 if (start
< vm_map_min(map
) || end
> vm_map_max(map
))
8304 return KERN_INVALID_ADDRESS
;
8306 /* Figure how much memory we need to flush (in page increments) */
8307 sync_size
= end
- start
;
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
,
8320 ret
= KERN_SUCCESS
; /* Assume it all worked */
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
;
8329 sub_size
= entry
->vme_end
- start
;
8330 sync_size
-= sub_size
;
8332 if(entry
->is_sub_map
) {
8333 vm_map_offset_t sub_start
;
8334 vm_map_offset_t sub_end
;
8336 sub_start
= (start
- entry
->vme_start
)
8338 sub_end
= sub_start
+ sub_size
;
8339 vm_map_machine_attribute(
8340 entry
->object
.sub_map
,
8345 if(entry
->object
.vm_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
;
8354 offset
= (start
- entry
->vme_start
)
8356 base_offset
= offset
;
8357 object
= entry
->object
.vm_object
;
8358 base_object
= object
;
8361 vm_object_lock(object
);
8367 if (m
&& !m
->fictitious
) {
8369 pmap_attribute_cache_sync(
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
);
8384 if (base_object
!= object
) {
8385 vm_object_unlock(object
);
8386 vm_object_lock(base_object
);
8387 object
= base_object
;
8389 /* Bump to the next page */
8390 base_offset
+= PAGE_SIZE
;
8391 offset
= base_offset
;
8393 vm_object_unlock(object
);
8399 return KERN_FAILURE
;
8410 * vm_map_behavior_set:
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
8418 vm_map_behavior_set(
8420 vm_map_offset_t start
,
8421 vm_map_offset_t end
,
8422 vm_behavior_t new_behavior
)
8424 register vm_map_entry_t entry
;
8425 vm_map_entry_t temp_entry
;
8428 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
8429 (integer_t
)map
, start
, end
, new_behavior
, 0);
8431 switch (new_behavior
) {
8432 case VM_BEHAVIOR_DEFAULT
:
8433 case VM_BEHAVIOR_RANDOM
:
8434 case VM_BEHAVIOR_SEQUENTIAL
:
8435 case VM_BEHAVIOR_RSEQNTL
:
8437 case VM_BEHAVIOR_WILLNEED
:
8438 case VM_BEHAVIOR_DONTNEED
:
8439 new_behavior
= VM_BEHAVIOR_DEFAULT
;
8442 return(KERN_INVALID_ARGUMENT
);
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.
8454 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
8456 vm_map_clip_start(map
, entry
, start
);
8460 return(KERN_INVALID_ADDRESS
);
8463 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
8464 vm_map_clip_end(map
, entry
, end
);
8466 entry
->behavior
= new_behavior
;
8468 entry
= entry
->vme_next
;
8472 return(KERN_SUCCESS
);
8476 #include <mach_kdb.h>
8478 #include <ddb/db_output.h>
8479 #include <vm/vm_print.h>
8481 #define printf db_printf
8484 * Forward declarations for internal functions.
8486 extern void vm_map_links_print(
8487 struct vm_map_links
*links
);
8489 extern void vm_map_header_print(
8490 struct vm_map_header
*header
);
8492 extern void vm_map_entry_print(
8493 vm_map_entry_t entry
);
8495 extern void vm_follow_entry(
8496 vm_map_entry_t entry
);
8498 extern void vm_follow_map(
8502 * vm_map_links_print: [ debug ]
8506 struct vm_map_links
*links
)
8508 iprintf("prev = %08X next = %08X start = %016llX end = %016llX\n",
8511 (unsigned long long)links
->start
,
8512 (unsigned long long)links
->end
);
8516 * vm_map_header_print: [ debug ]
8519 vm_map_header_print(
8520 struct vm_map_header
*header
)
8522 vm_map_links_print(&header
->links
);
8523 iprintf("nentries = %08X, %sentries_pageable\n",
8525 (header
->entries_pageable
? "" : "!"));
8529 * vm_follow_entry: [ debug ]
8533 vm_map_entry_t entry
)
8537 iprintf("map entry %08X\n", entry
);
8541 shadows
= vm_follow_object(entry
->object
.vm_object
);
8542 iprintf("Total objects : %d\n",shadows
);
8548 * vm_map_entry_print: [ debug ]
8552 register vm_map_entry_t entry
)
8554 static const char *inheritance_name
[4] =
8555 { "share", "copy", "none", "?"};
8556 static const char *behavior_name
[4] =
8557 { "dflt", "rand", "seqtl", "rseqntl" };
8559 iprintf("map entry %08X - prev = %08X next = %08X\n", entry
, entry
->vme_prev
, entry
->vme_next
);
8563 vm_map_links_print(&entry
->links
);
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
,
8569 entry
->max_protection
,
8570 inheritance_name
[(entry
->inheritance
& 0x3)]);
8572 iprintf("behavior = %s, wired_count = %d, user_wired_count = %d\n",
8573 behavior_name
[(entry
->behavior
& 0x3)],
8575 entry
->user_wired_count
);
8576 iprintf("%sin_transition, %sneeds_wakeup\n",
8577 (entry
->in_transition
? "" : "!"),
8578 (entry
->needs_wakeup
? "" : "!"));
8580 if (entry
->is_sub_map
) {
8581 iprintf("submap = %08X - offset = %016llX\n",
8582 entry
->object
.sub_map
,
8583 (unsigned long long)entry
->offset
);
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
? "" : "!"));
8597 * vm_follow_map: [ debug ]
8603 register vm_map_entry_t entry
;
8605 iprintf("task map %08X\n", map
);
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
);
8619 * vm_map_print: [ debug ]
8625 register vm_map_entry_t entry
;
8629 #endif /* TASK_SWAPPER */
8631 map
= (vm_map_t
)(long)
8632 inmap
; /* Make sure we have the right type */
8634 iprintf("task map %08X\n", map
);
8638 vm_map_header_print(&map
->hdr
);
8640 iprintf("pmap = %08X size = %08X ref = %d hint = %08X first_free = %08X\n",
8647 iprintf("%swait_for_space, %swiring_required, timestamp = %d\n",
8648 (map
->wait_for_space
? "" : "!"),
8649 (map
->wiring_required
? "" : "!"),
8653 switch (map
->sw_state
) {
8664 iprintf("res = %d, sw_state = %s\n", map
->res_count
, swstate
);
8665 #endif /* TASK_SWAPPER */
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
);
8677 * Routine: vm_map_copy_print
8679 * Pretty-print a copy object for ddb.
8687 vm_map_entry_t entry
;
8689 copy
= (vm_map_copy_t
)(long)
8690 incopy
; /* Make sure we have the right type */
8692 printf("copy object 0x%x\n", copy
);
8696 iprintf("type=%d", copy
->type
);
8697 switch (copy
->type
) {
8698 case VM_MAP_COPY_ENTRY_LIST
:
8699 printf("[entry_list]");
8702 case VM_MAP_COPY_OBJECT
:
8706 case VM_MAP_COPY_KERNEL_BUFFER
:
8707 printf("[kernel_buffer]");
8711 printf("[bad type]");
8714 printf(", offset=0x%llx", (unsigned long long)copy
->offset
);
8715 printf(", size=0x%x\n", copy
->size
);
8717 switch (copy
->type
) {
8718 case VM_MAP_COPY_ENTRY_LIST
:
8719 vm_map_header_print(©
->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
);
8727 case VM_MAP_COPY_OBJECT
:
8728 iprintf("object=0x%x\n", copy
->cpy_object
);
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
);
8742 * db_vm_map_total_size(map) [ debug ]
8744 * return the total virtual size (in bytes) of the map
8747 db_vm_map_total_size(
8750 vm_map_entry_t entry
;
8751 vm_map_size_t total
;
8754 map
= (vm_map_t
)(long)
8755 inmap
; /* Make sure we have the right type */
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
;
8767 #endif /* MACH_KDB */
8770 * Routine: vm_map_entry_insert
8772 * Descritpion: This routine inserts a new vm_entry in a locked map.
8775 vm_map_entry_insert(
8777 vm_map_entry_t insp_entry
,
8778 vm_map_offset_t start
,
8779 vm_map_offset_t end
,
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
)
8791 vm_map_entry_t new_entry
;
8793 assert(insp_entry
!= (vm_map_entry_t
)0);
8795 new_entry
= vm_map_entry_create(map
);
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
));
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
;
8818 * Insert the new entry into the list.
8821 vm_map_entry_link(map
, insp_entry
, new_entry
);
8822 map
->size
+= end
- start
;
8825 * Update the free space hint and the lookup hint.
8828 SAVE_HINT(map
, new_entry
);
8833 * Routine: vm_map_remap_extract
8835 * Descritpion: This routine returns a vm_entry list from a map.
8837 static kern_return_t
8838 vm_map_remap_extract(
8840 vm_map_offset_t addr
,
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
,
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 */
8860 vm_map_version_t version
;
8861 boolean_t src_needs_copy
;
8862 boolean_t new_entry_needs_copy
;
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
);
8871 * Compute start and end of region.
8873 src_start
= vm_map_trunc_page(addr
);
8874 src_end
= vm_map_round_page(src_start
+ size
);
8877 * Initialize map_header.
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
;
8884 *cur_protection
= VM_PROT_ALL
;
8885 *max_protection
= VM_PROT_ALL
;
8889 result
= KERN_SUCCESS
;
8892 * The specified source virtual space might correspond to
8893 * multiple map entries, need to loop on them.
8896 while (mapped_size
!= size
) {
8897 vm_map_size_t entry_size
;
8900 * Find the beginning of the region.
8902 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
8903 result
= KERN_INVALID_ADDRESS
;
8907 if (src_start
< src_entry
->vme_start
||
8908 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
8909 result
= KERN_INVALID_ADDRESS
;
8913 if(src_entry
->is_sub_map
) {
8914 result
= KERN_INVALID_ADDRESS
;
8918 tmp_size
= size
- mapped_size
;
8919 if (src_end
> src_entry
->vme_end
)
8920 tmp_size
-= (src_end
- src_entry
->vme_end
);
8922 entry_size
= (vm_map_size_t
)(src_entry
->vme_end
-
8923 src_entry
->vme_start
);
8925 if(src_entry
->is_sub_map
) {
8926 vm_map_reference(src_entry
->object
.sub_map
);
8927 object
= VM_OBJECT_NULL
;
8929 object
= src_entry
->object
.vm_object
;
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
) {
8938 * We are already using an asymmetric
8939 * copy, and therefore we already have
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
)) {
8948 vm_object_shadow(&src_entry
->object
.vm_object
,
8952 if (!src_entry
->needs_copy
&&
8953 (src_entry
->protection
& VM_PROT_WRITE
)) {
8955 vm_object_pmap_protect(
8956 src_entry
->object
.vm_object
,
8960 src_entry
->vme_start
,
8961 src_entry
->protection
&
8964 pmap_protect(vm_map_pmap(map
),
8965 src_entry
->vme_start
,
8967 src_entry
->protection
&
8972 object
= src_entry
->object
.vm_object
;
8973 src_entry
->needs_copy
= FALSE
;
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
;
8985 vm_object_unlock(object
);
8988 offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
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 */
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
;
9000 * The new region has to be copied now if required.
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
;
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
,
9016 (new_entry
->vme_end
-
9017 new_entry
->vme_start
),
9019 &new_entry_needs_copy
)) {
9021 new_entry
->needs_copy
= new_entry_needs_copy
;
9022 new_entry
->is_shared
= FALSE
;
9025 * Handle copy_on_write semantics.
9027 if (src_needs_copy
&& !src_entry
->needs_copy
) {
9028 vm_object_pmap_protect(object
,
9031 ((src_entry
->is_shared
9033 PMAP_NULL
: map
->pmap
),
9034 src_entry
->vme_start
,
9035 src_entry
->protection
&
9038 src_entry
->needs_copy
= TRUE
;
9041 * Throw away the old object reference of the new entry.
9043 vm_object_deallocate(object
);
9046 new_entry
->is_shared
= FALSE
;
9049 * The map can be safely unlocked since we
9050 * already hold a reference on the object.
9052 * Record the timestamp of the map for later
9053 * verification, and unlock the map.
9055 version
.main_timestamp
= map
->timestamp
;
9056 vm_map_unlock(map
); /* Increments timestamp once! */
9061 if (src_entry
->wired_count
> 0) {
9062 vm_object_lock(object
);
9063 result
= vm_object_copy_slowly(
9068 &new_entry
->object
.vm_object
);
9070 new_entry
->offset
= 0;
9071 new_entry
->needs_copy
= FALSE
;
9073 result
= vm_object_copy_strategically(
9077 &new_entry
->object
.vm_object
,
9079 &new_entry_needs_copy
);
9081 new_entry
->needs_copy
= new_entry_needs_copy
;
9085 * Throw away the old object reference of the new entry.
9087 vm_object_deallocate(object
);
9089 if (result
!= KERN_SUCCESS
&&
9090 result
!= KERN_MEMORY_RESTART_COPY
) {
9091 _vm_map_entry_dispose(map_header
, new_entry
);
9096 * Verify that the map has not substantially
9097 * changed while the copy was being made.
9101 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
9103 * Simple version comparison failed.
9105 * Retry the lookup and verify that the
9106 * same object/offset are still present.
9108 vm_object_deallocate(new_entry
->
9110 _vm_map_entry_dispose(map_header
, new_entry
);
9111 if (result
== KERN_MEMORY_RESTART_COPY
)
9112 result
= KERN_SUCCESS
;
9116 if (result
== KERN_MEMORY_RESTART_COPY
) {
9117 vm_object_reference(object
);
9122 _vm_map_entry_link(map_header
,
9123 map_header
->links
.prev
, new_entry
);
9125 *cur_protection
&= src_entry
->protection
;
9126 *max_protection
&= src_entry
->max_protection
;
9128 map_address
+= tmp_size
;
9129 mapped_size
+= tmp_size
;
9130 src_start
+= tmp_size
;
9135 if (result
!= KERN_SUCCESS
) {
9137 * Free all allocated elements.
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
);
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()
9164 vm_map_t target_map
,
9165 vm_map_address_t
*address
,
9167 vm_map_offset_t mask
,
9170 vm_map_offset_t memory_address
,
9172 vm_prot_t
*cur_protection
,
9173 vm_prot_t
*max_protection
,
9174 vm_inherit_t inheritance
)
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
;
9182 if (target_map
== VM_MAP_NULL
)
9183 return KERN_INVALID_ARGUMENT
;
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
)
9193 return KERN_INVALID_ARGUMENT
;
9196 size
= vm_map_round_page(size
);
9198 result
= vm_map_remap_extract(src_map
, memory_address
,
9199 size
, copy
, &map_header
,
9206 if (result
!= KERN_SUCCESS
) {
9211 * Allocate/check a range of free virtual address
9212 * space for the target
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
);
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
);
9230 if (!entry
->is_sub_map
) {
9231 vm_object_deallocate(entry
->object
.vm_object
);
9233 vm_map_deallocate(entry
->object
.sub_map
);
9235 _vm_map_entry_dispose(&map_header
, entry
);
9239 if (result
== KERN_SUCCESS
) {
9240 target_map
->size
+= size
;
9241 SAVE_HINT(target_map
, insp_entry
);
9243 vm_map_unlock(target_map
);
9245 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
9246 result
= vm_map_wire(target_map
, *address
,
9247 *address
+ size
, *cur_protection
, TRUE
);
9252 * Routine: vm_map_remap_range_allocate
9255 * Allocate a range in the specified virtual address map.
9256 * returns the address and the map entry just before the allocated
9259 * Map must be locked.
9262 static kern_return_t
9263 vm_map_remap_range_allocate(
9265 vm_map_address_t
*address
, /* IN/OUT */
9267 vm_map_offset_t mask
,
9269 vm_map_entry_t
*map_entry
) /* OUT */
9271 register vm_map_entry_t entry
;
9272 register vm_map_offset_t start
;
9273 register vm_map_offset_t end
;
9282 * Calculate the first possible address.
9285 if (start
< map
->min_offset
)
9286 start
= map
->min_offset
;
9287 if (start
> map
->max_offset
)
9288 return(KERN_NO_SPACE
);
9291 * Look for the first possible address;
9292 * if there's already something at this
9293 * address, we have to start after it.
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
;
9301 vm_map_entry_t tmp_entry
;
9302 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
9303 start
= tmp_entry
->vme_end
;
9308 * In any case, the "entry" always precedes
9309 * the proposed new region throughout the
9314 register vm_map_entry_t next
;
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.
9322 end
= ((start
+ mask
) & ~mask
);
9324 return(KERN_NO_SPACE
);
9328 if ((end
> map
->max_offset
) || (end
< start
)) {
9329 if (map
->wait_for_space
) {
9330 if (size
<= (map
->max_offset
-
9332 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
9334 thread_block(THREAD_CONTINUE_NULL
);
9340 return(KERN_NO_SPACE
);
9344 * If there are no more entries, we must win.
9347 next
= entry
->vme_next
;
9348 if (next
== vm_map_to_entry(map
))
9352 * If there is another entry, it must be
9353 * after the end of the potential new region.
9356 if (next
->vme_start
>= end
)
9360 * Didn't fit -- move to the next entry.
9364 start
= entry
->vme_end
;
9368 vm_map_entry_t temp_entry
;
9372 * the address doesn't itself violate
9373 * the mask requirement.
9376 if ((start
& mask
) != 0)
9377 return(KERN_NO_SPACE
);
9381 * ... the address is within bounds
9386 if ((start
< map
->min_offset
) ||
9387 (end
> map
->max_offset
) ||
9389 return(KERN_INVALID_ADDRESS
);
9393 * ... the starting address isn't allocated
9396 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
9397 return(KERN_NO_SPACE
);
9402 * ... the next region doesn't overlap the
9406 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
9407 (entry
->vme_next
->vme_start
< end
))
9408 return(KERN_NO_SPACE
);
9411 return(KERN_SUCCESS
);
9417 * Set the address map for the current thread to the specified map
9425 thread_t thread
= current_thread();
9426 vm_map_t oldmap
= thread
->map
;
9428 mp_disable_preemption();
9429 mycpu
= cpu_number();
9432 * Deactivate the current map and activate the requested map
9434 PMAP_SWITCH_USER(thread
, map
, mycpu
);
9436 mp_enable_preemption();
9442 * Routine: vm_map_write_user
9445 * Copy out data from a kernel space into space in the
9446 * destination map. The space must already exist in the
9448 * NOTE: This routine should only be called by threads
9449 * which can block on a page fault. i.e. kernel mode user
9457 vm_map_address_t dst_addr
,
9460 kern_return_t kr
= KERN_SUCCESS
;
9462 if(current_map() == map
) {
9463 if (copyout(src_p
, dst_addr
, size
)) {
9464 kr
= KERN_INVALID_ADDRESS
;
9469 /* take on the identity of the target map while doing */
9472 vm_map_reference(map
);
9473 oldmap
= vm_map_switch(map
);
9474 if (copyout(src_p
, dst_addr
, size
)) {
9475 kr
= KERN_INVALID_ADDRESS
;
9477 vm_map_switch(oldmap
);
9478 vm_map_deallocate(map
);
9484 * Routine: vm_map_read_user
9487 * Copy in data from a user space source map into the
9488 * kernel map. The space must already exist in the
9490 * NOTE: This routine should only be called by threads
9491 * which can block on a page fault. i.e. kernel mode user
9498 vm_map_address_t src_addr
,
9502 kern_return_t kr
= KERN_SUCCESS
;
9504 if(current_map() == map
) {
9505 if (copyin(src_addr
, dst_p
, size
)) {
9506 kr
= KERN_INVALID_ADDRESS
;
9511 /* take on the identity of the target map while doing */
9514 vm_map_reference(map
);
9515 oldmap
= vm_map_switch(map
);
9516 if (copyin(src_addr
, dst_p
, size
)) {
9517 kr
= KERN_INVALID_ADDRESS
;
9519 vm_map_switch(oldmap
);
9520 vm_map_deallocate(map
);
9527 * vm_map_check_protection:
9529 * Assert that the target map allows the specified
9530 * privilege on the entire address region given.
9531 * The entire region must be allocated.
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
;
9539 register vm_map_entry_t entry
;
9540 vm_map_entry_t tmp_entry
;
9544 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
9550 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
9557 while (start
< end
) {
9558 if (entry
== vm_map_to_entry(map
)) {
9567 if (start
< entry
->vme_start
) {
9573 * Check protection associated with entry.
9576 if ((entry
->protection
& protection
) != protection
) {
9581 /* go to next entry */
9583 start
= entry
->vme_end
;
9584 entry
= entry
->vme_next
;
9591 vm_map_purgable_control(
9593 vm_map_offset_t address
,
9594 vm_purgable_t control
,
9597 vm_map_entry_t entry
;
9602 * Vet all the input parameters and current type and state of the
9603 * underlaying object. Return with an error if anything is amiss.
9605 if (map
== VM_MAP_NULL
)
9606 return(KERN_INVALID_ARGUMENT
);
9608 if (control
!= VM_PURGABLE_SET_STATE
&&
9609 control
!= VM_PURGABLE_GET_STATE
)
9610 return(KERN_INVALID_ARGUMENT
);
9612 if (control
== VM_PURGABLE_SET_STATE
&&
9613 (*state
< VM_PURGABLE_STATE_MIN
||
9614 *state
> VM_PURGABLE_STATE_MAX
))
9615 return(KERN_INVALID_ARGUMENT
);
9619 if (!vm_map_lookup_entry(map
, address
, &entry
) || entry
->is_sub_map
) {
9622 * Must pass a valid non-submap address.
9625 return(KERN_INVALID_ADDRESS
);
9628 if ((entry
->protection
& VM_PROT_WRITE
) == 0) {
9630 * Can't apply purgable controls to something you can't write.
9633 return(KERN_PROTECTION_FAILURE
);
9636 object
= entry
->object
.vm_object
;
9637 if (object
== VM_OBJECT_NULL
) {
9639 * Object must already be present or it can't be purgable.
9642 return KERN_INVALID_ARGUMENT
;
9645 vm_object_lock(object
);
9647 if (entry
->offset
!= 0 ||
9648 entry
->vme_end
- entry
->vme_start
!= object
->size
) {
9650 * Can only apply purgable controls to the whole (existing)
9654 vm_object_unlock(object
);
9655 return KERN_INVALID_ARGUMENT
;
9660 kr
= vm_object_purgable_control(object
, control
, state
);
9662 vm_object_unlock(object
);
9669 vm_map_t target_map
,
9670 vm_map_offset_t offset
,
9674 vm_map_entry_t map_entry
;
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
;
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
;
9692 vm_map_unlock(target_map
);
9693 target_map
= map_entry
->object
.sub_map
;
9694 goto restart_page_query
;
9697 vm_map_unlock(target_map
);
9698 return KERN_FAILURE
;
9700 vm_object_lock(object
);
9701 vm_map_unlock(target_map
);
9703 m
= vm_page_lookup(object
, offset
);
9704 if (m
!= VM_PAGE_NULL
) {
9705 *disposition
|= VM_PAGE_QUERY_PAGE_PRESENT
;
9708 if(object
->shadow
) {
9709 offset
+= object
->shadow_offset
;
9710 vm_object_unlock(object
);
9711 object
= object
->shadow
;
9712 vm_object_lock(object
);
9715 vm_object_unlock(object
);
9716 return KERN_FAILURE
;
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 */
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 */
9730 *ref_count
= object
->ref_count
;
9732 if (m
->fictitious
) {
9733 *disposition
|= VM_PAGE_QUERY_PAGE_FICTITIOUS
;
9734 vm_object_unlock(object
);
9735 return KERN_SUCCESS
;
9739 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9740 else if(pmap_is_modified(m
->phys_page
))
9741 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9744 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9745 else if(pmap_is_referenced(m
->phys_page
))
9746 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9748 vm_object_unlock(object
);
9749 return KERN_SUCCESS
;
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
)
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;
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
;
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
;
9789 if(!vm_map_lookup_entry(target_map
, start
, &entry
)) {
9790 /* if the src is not contained, the entry preceeds */
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
;
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
);
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
;
9824 entry
->object
.sub_map
= new_submap
;
9825 vm_map_reference(new_submap
);
9826 vm_map_deallocate(old_submap
);
9828 entry
= entry
->vme_next
;
9829 addr
= entry
->vme_start
;
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);
9838 pmap_nest(target_map
->pmap
, new_submap
->pmap
,
9839 (addr64_t
)start
, (addr64_t
)start
,
9840 (uint64_t)(end
- start
));
9843 vm_map_submap_pmap_clean(target_map
,
9844 start
, end
, old_submap
, 0);
9846 vm_map_unlock(old_submap
);
9847 vm_map_deallocate(old_submap
);
9848 vm_map_unlock(target_map
);
9849 return KERN_SUCCESS
;
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.
9862 * interpretation of sync_flags
9863 * VM_SYNC_INVALIDATE - discard pages, only return precious
9866 * VM_SYNC_INVALIDATE & (VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS)
9867 * - discard pages, write dirty or precious
9868 * pages back to memory manager.
9870 * VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS
9871 * - write dirty or precious pages back to
9872 * the memory manager.
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.
9880 * The memory object attributes have not yet been implemented, this
9881 * function will have to deal with the invalidate attribute
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.
9893 vm_map_address_t address
,
9895 vm_sync_t sync_flags
)
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
;
9907 if ((sync_flags
& VM_SYNC_ASYNCHRONOUS
) &&
9908 (sync_flags
& VM_SYNC_SYNCHRONOUS
))
9909 return(KERN_INVALID_ARGUMENT
);
9912 * align address and size on page boundaries
9914 size
= vm_map_round_page(address
+ size
) - vm_map_trunc_page(address
);
9915 address
= vm_map_trunc_page(address
);
9917 if (map
== VM_MAP_NULL
)
9918 return(KERN_INVALID_TASK
);
9921 return(KERN_SUCCESS
);
9926 while (amount_left
> 0) {
9927 vm_object_size_t flush_size
;
9931 if (!vm_map_lookup_entry(map
,
9932 vm_map_trunc_page(address
), &entry
)) {
9937 * hole in the address map.
9942 * Check for empty map.
9944 if (entry
== vm_map_to_entry(map
) &&
9945 entry
->vme_next
== entry
) {
9950 * Check that we don't wrap and that
9951 * we have at least one real map entry.
9953 if ((map
->hdr
.nentries
== 0) ||
9954 (entry
->vme_next
->vme_start
< address
)) {
9959 * Move up to the next entry if needed
9961 skip
= (entry
->vme_next
->vme_start
- address
);
9962 if (skip
>= amount_left
)
9965 amount_left
-= skip
;
9966 address
= entry
->vme_next
->vme_start
;
9971 offset
= address
- entry
->vme_start
;
9974 * do we have more to flush than is contained in this
9977 if (amount_left
+ entry
->vme_start
+ offset
> entry
->vme_end
) {
9978 flush_size
= entry
->vme_end
-
9979 (entry
->vme_start
+ offset
);
9981 flush_size
= amount_left
;
9983 amount_left
-= flush_size
;
9984 address
+= flush_size
;
9986 if (entry
->is_sub_map
== TRUE
) {
9988 vm_map_offset_t local_offset
;
9990 local_map
= entry
->object
.sub_map
;
9991 local_offset
= entry
->offset
;
9997 sync_flags
) == KERN_INVALID_ADDRESS
) {
10002 object
= entry
->object
.vm_object
;
10005 * We can't sync this object if the object has not been
10008 if (object
== VM_OBJECT_NULL
) {
10009 vm_map_unlock(map
);
10012 offset
+= entry
->offset
;
10013 modifiable
= (entry
->protection
& VM_PROT_WRITE
)
10016 vm_object_lock(object
);
10018 if (sync_flags
& (VM_SYNC_KILLPAGES
| VM_SYNC_DEACTIVATE
)) {
10019 boolean_t kill_pages
= 0;
10021 if (sync_flags
& VM_SYNC_KILLPAGES
) {
10022 if (object
->ref_count
== 1 && !entry
->needs_copy
&& !object
->shadow
)
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
);
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.
10039 if ((object
->pager
== MEMORY_OBJECT_NULL
) ||
10040 (object
->internal
) || (object
->private)) {
10041 vm_object_unlock(object
);
10042 vm_map_unlock(map
);
10046 * keep reference on the object until syncing is done
10048 assert(object
->ref_count
> 0);
10049 object
->ref_count
++;
10050 vm_object_res_reference(object
);
10051 vm_object_unlock(object
);
10053 vm_map_unlock(map
);
10055 do_sync_req
= vm_object_sync(object
,
10058 sync_flags
& VM_SYNC_INVALIDATE
,
10060 (sync_flags
& VM_SYNC_SYNCHRONOUS
||
10061 sync_flags
& VM_SYNC_ASYNCHRONOUS
)),
10062 sync_flags
& VM_SYNC_SYNCHRONOUS
);
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)
10067 if (!do_sync_req
&& !modifiable
) {
10068 vm_object_deallocate(object
);
10071 msync_req_alloc(new_msr
);
10073 vm_object_lock(object
);
10074 offset
+= object
->paging_offset
;
10076 new_msr
->offset
= offset
;
10077 new_msr
->length
= flush_size
;
10078 new_msr
->object
= object
;
10079 new_msr
->flag
= VM_MSYNC_SYNCHRONIZING
;
10081 queue_iterate(&object
->msr_q
, msr
, msync_req_t
, msr_q
) {
10083 * need to check for overlapping entry, if found, wait
10084 * on overlapping msr to be done, then reiterate
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
))))
10093 assert_wait((event_t
) msr
,THREAD_INTERRUPTIBLE
);
10095 vm_object_unlock(object
);
10096 thread_block(THREAD_CONTINUE_NULL
);
10097 vm_object_lock(object
);
10101 }/* queue_iterate */
10103 queue_enter(&object
->msr_q
, new_msr
, msync_req_t
, msr_q
);
10104 vm_object_unlock(object
);
10106 queue_enter(&req_q
, new_msr
, msync_req_t
, req_q
);
10108 (void) memory_object_synchronize(
10112 sync_flags
& ~VM_SYNC_CONTIGUOUS
);
10116 * wait for memory_object_sychronize_completed messages from pager(s)
10119 while (!queue_empty(&req_q
)) {
10120 msr
= (msync_req_t
)queue_first(&req_q
);
10122 while(msr
->flag
!= VM_MSYNC_DONE
) {
10123 assert_wait((event_t
) msr
, THREAD_INTERRUPTIBLE
);
10125 thread_block(THREAD_CONTINUE_NULL
);
10128 queue_remove(&req_q
, msr
, msync_req_t
, req_q
);
10130 vm_object_deallocate(msr
->object
);
10131 msync_req_free(msr
);
10132 }/* queue_iterate */
10134 /* for proper msync() behaviour */
10135 if (had_hole
== TRUE
&& (sync_flags
& VM_SYNC_CONTIGUOUS
))
10136 return(KERN_INVALID_ADDRESS
);
10138 return(KERN_SUCCESS
);
10141 /* Takes existing source and destination sub-maps and clones the contents of */
10142 /* the source map */
10145 ipc_port_t src_region
,
10146 ipc_port_t dst_region
)
10148 vm_named_entry_t src_object
;
10149 vm_named_entry_t dst_object
;
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
;
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
;
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
;
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
;
10178 if(entry
== vm_map_to_entry(dst_map
)) {
10179 max_off
= src_map
->max_offset
;
10181 max_off
= entry
->vme_start
;
10183 vm_map_lookup_entry(src_map
, addr
, &entry
);
10184 if(entry
== vm_map_to_entry(src_map
)) {
10185 entry
= entry
->vme_next
;
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
);
10199 vm_object_reference(
10200 new_entry
->object
.vm_object
);
10203 dst_map
->size
+= new_entry
->vme_end
- new_entry
->vme_start
;
10204 entry
= entry
->vme_next
;
10206 vm_map_unlock(src_map
);
10207 return KERN_SUCCESS
;
10211 * Routine: convert_port_entry_to_map
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.
10223 convert_port_entry_to_map(
10227 vm_named_entry_t named_entry
;
10229 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10232 if(ip_active(port
) && (ip_kotype(port
)
10233 == IKOT_NAMED_ENTRY
)) {
10235 (vm_named_entry_t
)port
->ip_kobject
;
10236 if (!(mutex_try(&(named_entry
)->Lock
))) {
10241 named_entry
->ref_count
++;
10242 mutex_unlock(&(named_entry
)->Lock
);
10244 if ((named_entry
->is_sub_map
) &&
10245 (named_entry
->protection
10246 & VM_PROT_WRITE
)) {
10247 map
= named_entry
->backing
.map
;
10249 mach_destroy_memory_entry(port
);
10250 return VM_MAP_NULL
;
10252 vm_map_reference_swap(map
);
10253 mach_destroy_memory_entry(port
);
10257 return VM_MAP_NULL
;
10261 map
= convert_port_to_map(port
);
10267 * Routine: convert_port_entry_to_object
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.
10278 convert_port_entry_to_object(
10281 vm_object_t object
;
10282 vm_named_entry_t named_entry
;
10284 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10287 if(ip_active(port
) && (ip_kotype(port
)
10288 == IKOT_NAMED_ENTRY
)) {
10290 (vm_named_entry_t
)port
->ip_kobject
;
10291 if (!(mutex_try(&(named_entry
)->Lock
))) {
10296 named_entry
->ref_count
++;
10297 mutex_unlock(&(named_entry
)->Lock
);
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
;
10305 mach_destroy_memory_entry(port
);
10306 return (vm_object_t
)NULL
;
10308 vm_object_reference(named_entry
->backing
.object
);
10309 mach_destroy_memory_entry(port
);
10313 return (vm_object_t
)NULL
;
10316 return (vm_object_t
)NULL
;
10323 * Export routines to other components for the things we access locally through
10330 return (current_map_fast());
10334 * vm_map_reference:
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.
10340 #undef vm_map_reference
10343 register vm_map_t map
)
10345 if (map
== VM_MAP_NULL
)
10348 mutex_lock(&map
->s_lock
);
10350 assert(map
->res_count
> 0);
10351 assert(map
->ref_count
>= map
->res_count
);
10355 mutex_unlock(&map
->s_lock
);
10359 * vm_map_deallocate:
10361 * Removes a reference from the specified map,
10362 * destroying it if no references remain.
10363 * The map should not be locked.
10367 register vm_map_t map
)
10371 if (map
== VM_MAP_NULL
)
10374 mutex_lock(&map
->s_lock
);
10375 ref
= --map
->ref_count
;
10377 vm_map_res_deallocate(map
);
10378 mutex_unlock(&map
->s_lock
);
10381 assert(map
->ref_count
== 0);
10382 mutex_unlock(&map
->s_lock
);
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.
10393 vm_map_destroy(map
);
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.
10402 extern vm_map_t com_region_map64
; /* the submap for 64-bit commpage */
10403 SInt32 commpage64s_in_use
= 0;
10409 vm_map_entry_t entry
;
10410 vm_object_t object
;
10414 /* The commpage is necessarily the last entry in the map.
10415 * See if one is already there (not sure if this can happen???)
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
);
10425 entry
= vm_map_first_entry(com_region_map64
); /* the 64-bit commpage */
10426 object
= entry
->object
.vm_object
;
10427 vm_object_reference(object
);
10429 /* We bypass vm_map_enter() because we are adding the entry past the
10430 * map's max_offset.
10432 entry
= vm_map_entry_insert(
10434 vm_map_last_entry(map
), /* insert after last entry */
10435 _COMM_PAGE_BASE_ADDRESS
,
10436 _COMM_PAGE_BASE_ADDRESS
+_COMM_PAGE_AREA_USED
,
10439 FALSE
, /* needs_copy */
10440 FALSE
, /* is_shared */
10441 FALSE
, /* in_transition */
10444 VM_BEHAVIOR_DEFAULT
,
10446 1 ); /* wired_count */
10448 vm_map_unlock(map
);
10450 OSIncrementAtomic(&commpage64s_in_use
);
10454 /* LP64todo - remove this! */
10457 vm_map_remove_commpage64(
10460 vm_map_entry_t entry
;
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
))
10471 /* clearing the wired count isn't strictly correct */
10472 entry
->wired_count
= 0;
10473 vm_map_entry_delete(map
,entry
);
10477 vm_map_unlock(map
);
10480 OSDecrementAtomic(&commpage64s_in_use
);
10483 #endif /* __PPC__ */