2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
54 * Author: Avadis Tevanian, Jr., Michael Wayne Young
57 * Virtual memory mapping module.
61 #include <task_swapper.h>
62 #include <mach_assert.h>
64 #include <mach/kern_return.h>
65 #include <mach/port.h>
66 #include <mach/vm_attributes.h>
67 #include <mach/vm_param.h>
68 #include <mach/vm_behavior.h>
69 #include <kern/assert.h>
70 #include <kern/counters.h>
71 #include <kern/zalloc.h>
72 #include <vm/vm_init.h>
73 #include <vm/vm_fault.h>
74 #include <vm/vm_map.h>
75 #include <vm/vm_object.h>
76 #include <vm/vm_page.h>
77 #include <vm/vm_kern.h>
78 #include <ipc/ipc_port.h>
79 #include <kern/sched_prim.h>
80 #include <kern/misc_protos.h>
81 #include <mach/vm_map_server.h>
82 #include <mach/mach_host_server.h>
86 /* Internal prototypes
88 extern boolean_t
vm_map_range_check(
92 vm_map_entry_t
*entry
);
94 extern vm_map_entry_t
_vm_map_entry_create(
95 struct vm_map_header
*map_header
);
97 extern void _vm_map_entry_dispose(
98 struct vm_map_header
*map_header
,
99 vm_map_entry_t entry
);
101 extern void vm_map_pmap_enter(
104 vm_offset_t end_addr
,
106 vm_object_offset_t offset
,
107 vm_prot_t protection
);
109 extern void _vm_map_clip_end(
110 struct vm_map_header
*map_header
,
111 vm_map_entry_t entry
,
114 extern void vm_map_entry_delete(
116 vm_map_entry_t entry
);
118 extern kern_return_t
vm_map_delete(
124 extern void vm_map_copy_steal_pages(
127 extern kern_return_t
vm_map_copy_overwrite_unaligned(
129 vm_map_entry_t entry
,
133 extern kern_return_t
vm_map_copy_overwrite_aligned(
135 vm_map_entry_t tmp_entry
,
140 extern kern_return_t
vm_map_copyin_kernel_buffer(
142 vm_offset_t src_addr
,
144 boolean_t src_destroy
,
145 vm_map_copy_t
*copy_result
); /* OUT */
147 extern kern_return_t
vm_map_copyout_kernel_buffer(
149 vm_offset_t
*addr
, /* IN/OUT */
151 boolean_t overwrite
);
153 extern kern_return_t
vm_map_copyin_page_list_cont(
154 vm_map_copyin_args_t cont_args
,
155 vm_map_copy_t
*copy_result
); /* OUT */
157 extern void vm_map_fork_share(
159 vm_map_entry_t old_entry
,
162 extern boolean_t
vm_map_fork_copy(
164 vm_map_entry_t
*old_entry_p
,
167 extern kern_return_t
vm_remap_range_allocate(
169 vm_offset_t
*address
, /* IN/OUT */
173 vm_map_entry_t
*map_entry
); /* OUT */
175 extern void _vm_map_clip_start(
176 struct vm_map_header
*map_header
,
177 vm_map_entry_t entry
,
180 void vm_region_top_walk(
181 vm_map_entry_t entry
,
182 vm_region_top_info_t top
);
185 vm_map_entry_t entry
,
186 vm_region_extended_info_t extended
,
187 vm_object_offset_t offset
,
193 * Macros to copy a vm_map_entry. We must be careful to correctly
194 * manage the wired page count. vm_map_entry_copy() creates a new
195 * map entry to the same memory - the wired count in the new entry
196 * must be set to zero. vm_map_entry_copy_full() creates a new
197 * entry that is identical to the old entry. This preserves the
198 * wire count; it's used for map splitting and zone changing in
201 #define vm_map_entry_copy(NEW,OLD) \
204 (NEW)->is_shared = FALSE; \
205 (NEW)->needs_wakeup = FALSE; \
206 (NEW)->in_transition = FALSE; \
207 (NEW)->wired_count = 0; \
208 (NEW)->user_wired_count = 0; \
211 #define vm_map_entry_copy_full(NEW,OLD) (*(NEW) = *(OLD))
214 * Virtual memory maps provide for the mapping, protection,
215 * and sharing of virtual memory objects. In addition,
216 * this module provides for an efficient virtual copy of
217 * memory from one map to another.
219 * Synchronization is required prior to most operations.
221 * Maps consist of an ordered doubly-linked list of simple
222 * entries; a single hint is used to speed up lookups.
224 * Sharing maps have been deleted from this version of Mach.
225 * All shared objects are now mapped directly into the respective
226 * maps. This requires a change in the copy on write strategy;
227 * the asymmetric (delayed) strategy is used for shared temporary
228 * objects instead of the symmetric (shadow) strategy. All maps
229 * are now "top level" maps (either task map, kernel map or submap
230 * of the kernel map).
232 * Since portions of maps are specified by start/end addreses,
233 * which may not align with existing map entries, all
234 * routines merely "clip" entries to these start/end values.
235 * [That is, an entry is split into two, bordering at a
236 * start or end value.] Note that these clippings may not
237 * always be necessary (as the two resulting entries are then
238 * not changed); however, the clipping is done for convenience.
239 * No attempt is currently made to "glue back together" two
242 * The symmetric (shadow) copy strategy implements virtual copy
243 * by copying VM object references from one map to
244 * another, and then marking both regions as copy-on-write.
245 * It is important to note that only one writeable reference
246 * to a VM object region exists in any map when this strategy
247 * is used -- this means that shadow object creation can be
248 * delayed until a write operation occurs. The symmetric (delayed)
249 * strategy allows multiple maps to have writeable references to
250 * the same region of a vm object, and hence cannot delay creating
251 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
252 * Copying of permanent objects is completely different; see
253 * vm_object_copy_strategically() in vm_object.c.
256 zone_t vm_map_zone
; /* zone for vm_map structures */
257 zone_t vm_map_entry_zone
; /* zone for vm_map_entry structures */
258 zone_t vm_map_kentry_zone
; /* zone for kernel entry structures */
259 zone_t vm_map_copy_zone
; /* zone for vm_map_copy structures */
263 * Placeholder object for submap operations. This object is dropped
264 * into the range by a call to vm_map_find, and removed when
265 * vm_map_submap creates the submap.
268 vm_object_t vm_submap_object
;
273 * Initialize the vm_map module. Must be called before
274 * any other vm_map routines.
276 * Map and entry structures are allocated from zones -- we must
277 * initialize those zones.
279 * There are three zones of interest:
281 * vm_map_zone: used to allocate maps.
282 * vm_map_entry_zone: used to allocate map entries.
283 * vm_map_kentry_zone: used to allocate map entries for the kernel.
285 * The kernel allocates map entries from a special zone that is initially
286 * "crammed" with memory. It would be difficult (perhaps impossible) for
287 * the kernel to allocate more memory to a entry zone when it became
288 * empty since the very act of allocating memory implies the creation
292 vm_offset_t map_data
;
293 vm_size_t map_data_size
;
294 vm_offset_t kentry_data
;
295 vm_size_t kentry_data_size
;
296 int kentry_count
= 2048; /* to init kentry_data_size */
299 * Threshold for aggressive (eager) page map entering for vm copyout
300 * operations. Any copyout larger will NOT be aggressively entered.
302 vm_size_t vm_map_aggressive_enter_max
; /* set by bootstrap */
308 vm_map_zone
= zinit((vm_size_t
) sizeof(struct vm_map
), 40*1024,
311 vm_map_entry_zone
= zinit((vm_size_t
) sizeof(struct vm_map_entry
),
312 1024*1024, PAGE_SIZE
*5,
313 "non-kernel map entries");
315 vm_map_kentry_zone
= zinit((vm_size_t
) sizeof(struct vm_map_entry
),
316 kentry_data_size
, kentry_data_size
,
317 "kernel map entries");
319 vm_map_copy_zone
= zinit((vm_size_t
) sizeof(struct vm_map_copy
),
320 16*1024, PAGE_SIZE
, "map copies");
323 * Cram the map and kentry zones with initial data.
324 * Set kentry_zone non-collectible to aid zone_gc().
326 zone_change(vm_map_zone
, Z_COLLECT
, FALSE
);
327 zone_change(vm_map_kentry_zone
, Z_COLLECT
, FALSE
);
328 zone_change(vm_map_kentry_zone
, Z_EXPAND
, FALSE
);
329 zcram(vm_map_zone
, map_data
, map_data_size
);
330 zcram(vm_map_kentry_zone
, kentry_data
, kentry_data_size
);
337 map_data_size
= round_page(10 * sizeof(struct vm_map
));
338 map_data
= pmap_steal_memory(map_data_size
);
342 * Limiting worst case: vm_map_kentry_zone needs to map each "available"
343 * physical page (i.e. that beyond the kernel image and page tables)
344 * individually; we guess at most one entry per eight pages in the
345 * real world. This works out to roughly .1 of 1% of physical memory,
346 * or roughly 1900 entries (64K) for a 64M machine with 4K pages.
349 kentry_count
= pmap_free_pages() / 8;
353 round_page(kentry_count
* sizeof(struct vm_map_entry
));
354 kentry_data
= pmap_steal_memory(kentry_data_size
);
360 * Creates and returns a new empty VM map with
361 * the given physical map structure, and having
362 * the given lower and upper address bounds.
371 register vm_map_t result
;
373 result
= (vm_map_t
) zalloc(vm_map_zone
);
374 if (result
== VM_MAP_NULL
)
375 panic("vm_map_create");
377 vm_map_first_entry(result
) = vm_map_to_entry(result
);
378 vm_map_last_entry(result
) = vm_map_to_entry(result
);
379 result
->hdr
.nentries
= 0;
380 result
->hdr
.entries_pageable
= pageable
;
383 result
->ref_count
= 1;
385 result
->res_count
= 1;
386 result
->sw_state
= MAP_SW_IN
;
387 #endif /* TASK_SWAPPER */
389 result
->min_offset
= min
;
390 result
->max_offset
= max
;
391 result
->wiring_required
= FALSE
;
392 result
->no_zero_fill
= FALSE
;
393 result
->wait_for_space
= FALSE
;
394 result
->first_free
= vm_map_to_entry(result
);
395 result
->hint
= vm_map_to_entry(result
);
396 vm_map_lock_init(result
);
397 mutex_init(&result
->s_lock
, ETAP_VM_RESULT
);
403 * vm_map_entry_create: [ internal use only ]
405 * Allocates a VM map entry for insertion in the
406 * given map (or map copy). No fields are filled.
408 #define vm_map_entry_create(map) \
409 _vm_map_entry_create(&(map)->hdr)
411 #define vm_map_copy_entry_create(copy) \
412 _vm_map_entry_create(&(copy)->cpy_hdr)
415 _vm_map_entry_create(
416 register struct vm_map_header
*map_header
)
418 register zone_t zone
;
419 register vm_map_entry_t entry
;
421 if (map_header
->entries_pageable
)
422 zone
= vm_map_entry_zone
;
424 zone
= vm_map_kentry_zone
;
426 entry
= (vm_map_entry_t
) zalloc(zone
);
427 if (entry
== VM_MAP_ENTRY_NULL
)
428 panic("vm_map_entry_create");
434 * vm_map_entry_dispose: [ internal use only ]
436 * Inverse of vm_map_entry_create.
438 #define vm_map_entry_dispose(map, entry) \
440 if((entry) == (map)->first_free) \
441 (map)->first_free = vm_map_to_entry(map); \
442 if((entry) == (map)->hint) \
443 (map)->hint = vm_map_to_entry(map); \
444 _vm_map_entry_dispose(&(map)->hdr, (entry)); \
447 #define vm_map_copy_entry_dispose(map, entry) \
448 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
451 _vm_map_entry_dispose(
452 register struct vm_map_header
*map_header
,
453 register vm_map_entry_t entry
)
455 register zone_t zone
;
457 if (map_header
->entries_pageable
)
458 zone
= vm_map_entry_zone
;
460 zone
= vm_map_kentry_zone
;
462 zfree(zone
, (vm_offset_t
) entry
);
465 boolean_t
first_free_is_valid(vm_map_t map
); /* forward */
466 boolean_t first_free_check
= FALSE
;
471 vm_map_entry_t entry
, next
;
473 if (!first_free_check
)
476 entry
= vm_map_to_entry(map
);
477 next
= entry
->vme_next
;
478 while (trunc_page(next
->vme_start
) == trunc_page(entry
->vme_end
) ||
479 (trunc_page(next
->vme_start
) == trunc_page(entry
->vme_start
) &&
480 next
!= vm_map_to_entry(map
))) {
482 next
= entry
->vme_next
;
483 if (entry
== vm_map_to_entry(map
))
486 if (map
->first_free
!= entry
) {
487 printf("Bad first_free for map 0x%x: 0x%x should be 0x%x\n",
488 map
, map
->first_free
, entry
);
497 * Updates the map->first_free pointer to the
498 * entry immediately before the first hole in the map.
499 * The map should be locked.
501 #define UPDATE_FIRST_FREE(map, new_first_free) \
504 vm_map_entry_t UFF_first_free; \
505 vm_map_entry_t UFF_next_entry; \
507 UFF_first_free = (new_first_free); \
508 UFF_next_entry = UFF_first_free->vme_next; \
509 while (trunc_page(UFF_next_entry->vme_start) == \
510 trunc_page(UFF_first_free->vme_end) || \
511 (trunc_page(UFF_next_entry->vme_start) == \
512 trunc_page(UFF_first_free->vme_start) && \
513 UFF_next_entry != vm_map_to_entry(UFF_map))) { \
514 UFF_first_free = UFF_next_entry; \
515 UFF_next_entry = UFF_first_free->vme_next; \
516 if (UFF_first_free == vm_map_to_entry(UFF_map)) \
519 UFF_map->first_free = UFF_first_free; \
520 assert(first_free_is_valid(UFF_map)); \
524 * vm_map_entry_{un,}link:
526 * Insert/remove entries from maps (or map copies).
528 #define vm_map_entry_link(map, after_where, entry) \
531 vm_map_entry_t VMEL_entry; \
533 VMEL_entry = (entry); \
534 _vm_map_entry_link(&VMEL_map->hdr, after_where, VMEL_entry); \
535 UPDATE_FIRST_FREE(VMEL_map, VMEL_map->first_free); \
539 #define vm_map_copy_entry_link(copy, after_where, entry) \
540 _vm_map_entry_link(&(copy)->cpy_hdr, after_where, (entry))
542 #define _vm_map_entry_link(hdr, after_where, entry) \
545 (entry)->vme_prev = (after_where); \
546 (entry)->vme_next = (after_where)->vme_next; \
547 (entry)->vme_prev->vme_next = (entry)->vme_next->vme_prev = (entry); \
550 #define vm_map_entry_unlink(map, entry) \
553 vm_map_entry_t VMEU_entry; \
554 vm_map_entry_t VMEU_first_free; \
556 VMEU_entry = (entry); \
557 if (VMEU_entry->vme_start <= VMEU_map->first_free->vme_start) \
558 VMEU_first_free = VMEU_entry->vme_prev; \
560 VMEU_first_free = VMEU_map->first_free; \
561 _vm_map_entry_unlink(&VMEU_map->hdr, VMEU_entry); \
562 UPDATE_FIRST_FREE(VMEU_map, VMEU_first_free); \
565 #define vm_map_copy_entry_unlink(copy, entry) \
566 _vm_map_entry_unlink(&(copy)->cpy_hdr, (entry))
568 #define _vm_map_entry_unlink(hdr, entry) \
571 (entry)->vme_next->vme_prev = (entry)->vme_prev; \
572 (entry)->vme_prev->vme_next = (entry)->vme_next; \
576 * kernel_vm_map_reference:
578 * kernel internal export version for iokit and bsd components
579 * in lieu of component interface semantics.
583 kernel_vm_map_reference(
584 register vm_map_t map
)
586 if (map
== VM_MAP_NULL
)
589 mutex_lock(&map
->s_lock
);
591 assert(map
->res_count
> 0);
592 assert(map
->ref_count
>= map
->res_count
);
596 mutex_unlock(&map
->s_lock
);
599 #if MACH_ASSERT && TASK_SWAPPER
603 * Adds valid reference and residence counts to the given map.
604 * The map must be in memory (i.e. non-zero residence count).
609 register vm_map_t map
)
611 if (map
== VM_MAP_NULL
)
614 mutex_lock(&map
->s_lock
);
615 assert(map
->res_count
> 0);
616 assert(map
->ref_count
>= map
->res_count
);
619 mutex_unlock(&map
->s_lock
);
623 * vm_map_res_reference:
625 * Adds another valid residence count to the given map.
627 * Map is locked so this function can be called from
631 void vm_map_res_reference(register vm_map_t map
)
633 /* assert map is locked */
634 assert(map
->res_count
>= 0);
635 assert(map
->ref_count
>= map
->res_count
);
636 if (map
->res_count
== 0) {
637 mutex_unlock(&map
->s_lock
);
640 mutex_lock(&map
->s_lock
);
648 * vm_map_reference_swap:
650 * Adds valid reference and residence counts to the given map.
652 * The map may not be in memory (i.e. zero residence count).
655 void vm_map_reference_swap(register vm_map_t map
)
657 assert(map
!= VM_MAP_NULL
);
658 mutex_lock(&map
->s_lock
);
659 assert(map
->res_count
>= 0);
660 assert(map
->ref_count
>= map
->res_count
);
662 vm_map_res_reference(map
);
663 mutex_unlock(&map
->s_lock
);
667 * vm_map_res_deallocate:
669 * Decrement residence count on a map; possibly causing swapout.
671 * The map must be in memory (i.e. non-zero residence count).
673 * The map is locked, so this function is callable from vm_map_deallocate.
676 void vm_map_res_deallocate(register vm_map_t map
)
678 assert(map
->res_count
> 0);
679 if (--map
->res_count
== 0) {
680 mutex_unlock(&map
->s_lock
);
684 mutex_lock(&map
->s_lock
);
686 assert(map
->ref_count
>= map
->res_count
);
688 #endif /* MACH_ASSERT && TASK_SWAPPER */
693 * Removes a reference from the specified map,
694 * destroying it if no references remain.
695 * The map should not be locked.
699 register vm_map_t map
)
703 if (map
== VM_MAP_NULL
)
706 mutex_lock(&map
->s_lock
);
707 ref
= --map
->ref_count
;
709 vm_map_res_deallocate(map
);
710 mutex_unlock(&map
->s_lock
);
713 assert(map
->ref_count
== 0);
714 mutex_unlock(&map
->s_lock
);
718 * The map residence count isn't decremented here because
719 * the vm_map_delete below will traverse the entire map,
720 * deleting entries, and the residence counts on objects
721 * and sharing maps will go away then.
731 * Actually destroy a map.
735 register vm_map_t map
)
738 (void) vm_map_delete(map
, map
->min_offset
,
739 map
->max_offset
, VM_MAP_NO_FLAGS
);
742 pmap_destroy(map
->pmap
);
744 zfree(vm_map_zone
, (vm_offset_t
) map
);
749 * vm_map_swapin/vm_map_swapout
751 * Swap a map in and out, either referencing or releasing its resources.
752 * These functions are internal use only; however, they must be exported
753 * because they may be called from macros, which are exported.
755 * In the case of swapout, there could be races on the residence count,
756 * so if the residence count is up, we return, assuming that a
757 * vm_map_deallocate() call in the near future will bring us back.
760 * -- We use the map write lock for synchronization among races.
761 * -- The map write lock, and not the simple s_lock, protects the
762 * swap state of the map.
763 * -- If a map entry is a share map, then we hold both locks, in
764 * hierarchical order.
766 * Synchronization Notes:
767 * 1) If a vm_map_swapin() call happens while swapout in progress, it
768 * will block on the map lock and proceed when swapout is through.
769 * 2) A vm_map_reference() call at this time is illegal, and will
770 * cause a panic. vm_map_reference() is only allowed on resident
771 * maps, since it refuses to block.
772 * 3) A vm_map_swapin() call during a swapin will block, and
773 * proceeed when the first swapin is done, turning into a nop.
774 * This is the reason the res_count is not incremented until
775 * after the swapin is complete.
776 * 4) There is a timing hole after the checks of the res_count, before
777 * the map lock is taken, during which a swapin may get the lock
778 * before a swapout about to happen. If this happens, the swapin
779 * will detect the state and increment the reference count, causing
780 * the swapout to be a nop, thereby delaying it until a later
781 * vm_map_deallocate. If the swapout gets the lock first, then
782 * the swapin will simply block until the swapout is done, and
785 * Because vm_map_swapin() is potentially an expensive operation, it
786 * should be used with caution.
789 * 1) A map with a residence count of zero is either swapped, or
791 * 2) A map with a non-zero residence count is either resident,
792 * or being swapped in.
795 int vm_map_swap_enable
= 1;
797 void vm_map_swapin (vm_map_t map
)
799 register vm_map_entry_t entry
;
801 if (!vm_map_swap_enable
) /* debug */
806 * First deal with various races.
808 if (map
->sw_state
== MAP_SW_IN
)
810 * we raced with swapout and won. Returning will incr.
811 * the res_count, turning the swapout into a nop.
816 * The residence count must be zero. If we raced with another
817 * swapin, the state would have been IN; if we raced with a
818 * swapout (after another competing swapin), we must have lost
819 * the race to get here (see above comment), in which case
820 * res_count is still 0.
822 assert(map
->res_count
== 0);
825 * There are no intermediate states of a map going out or
826 * coming in, since the map is locked during the transition.
828 assert(map
->sw_state
== MAP_SW_OUT
);
831 * We now operate upon each map entry. If the entry is a sub-
832 * or share-map, we call vm_map_res_reference upon it.
833 * If the entry is an object, we call vm_object_res_reference
834 * (this may iterate through the shadow chain).
835 * Note that we hold the map locked the entire time,
836 * even if we get back here via a recursive call in
837 * vm_map_res_reference.
839 entry
= vm_map_first_entry(map
);
841 while (entry
!= vm_map_to_entry(map
)) {
842 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
843 if (entry
->is_sub_map
) {
844 vm_map_t lmap
= entry
->object
.sub_map
;
845 mutex_lock(&lmap
->s_lock
);
846 vm_map_res_reference(lmap
);
847 mutex_unlock(&lmap
->s_lock
);
849 vm_object_t object
= entry
->object
.vm_object
;
850 vm_object_lock(object
);
852 * This call may iterate through the
855 vm_object_res_reference(object
);
856 vm_object_unlock(object
);
859 entry
= entry
->vme_next
;
861 assert(map
->sw_state
== MAP_SW_OUT
);
862 map
->sw_state
= MAP_SW_IN
;
865 void vm_map_swapout(vm_map_t map
)
867 register vm_map_entry_t entry
;
871 * First deal with various races.
872 * If we raced with a swapin and lost, the residence count
873 * will have been incremented to 1, and we simply return.
875 mutex_lock(&map
->s_lock
);
876 if (map
->res_count
!= 0) {
877 mutex_unlock(&map
->s_lock
);
880 mutex_unlock(&map
->s_lock
);
883 * There are no intermediate states of a map going out or
884 * coming in, since the map is locked during the transition.
886 assert(map
->sw_state
== MAP_SW_IN
);
888 if (!vm_map_swap_enable
)
892 * We now operate upon each map entry. If the entry is a sub-
893 * or share-map, we call vm_map_res_deallocate upon it.
894 * If the entry is an object, we call vm_object_res_deallocate
895 * (this may iterate through the shadow chain).
896 * Note that we hold the map locked the entire time,
897 * even if we get back here via a recursive call in
898 * vm_map_res_deallocate.
900 entry
= vm_map_first_entry(map
);
902 while (entry
!= vm_map_to_entry(map
)) {
903 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
904 if (entry
->is_sub_map
) {
905 vm_map_t lmap
= entry
->object
.sub_map
;
906 mutex_lock(&lmap
->s_lock
);
907 vm_map_res_deallocate(lmap
);
908 mutex_unlock(&lmap
->s_lock
);
910 vm_object_t object
= entry
->object
.vm_object
;
911 vm_object_lock(object
);
913 * This call may take a long time,
914 * since it could actively push
915 * out pages (if we implement it
918 vm_object_res_deallocate(object
);
919 vm_object_unlock(object
);
922 entry
= entry
->vme_next
;
924 assert(map
->sw_state
== MAP_SW_IN
);
925 map
->sw_state
= MAP_SW_OUT
;
928 #endif /* TASK_SWAPPER */
934 * Saves the specified entry as the hint for
935 * future lookups. Performs necessary interlocks.
937 #define SAVE_HINT(map,value) \
938 mutex_lock(&(map)->s_lock); \
939 (map)->hint = (value); \
940 mutex_unlock(&(map)->s_lock);
943 * vm_map_lookup_entry: [ internal use only ]
945 * Finds the map entry containing (or
946 * immediately preceding) the specified address
947 * in the given map; the entry is returned
948 * in the "entry" parameter. The boolean
949 * result indicates whether the address is
950 * actually contained in the map.
954 register vm_map_t map
,
955 register vm_offset_t address
,
956 vm_map_entry_t
*entry
) /* OUT */
958 register vm_map_entry_t cur
;
959 register vm_map_entry_t last
;
962 * Start looking either from the head of the
963 * list, or from the hint.
966 mutex_lock(&map
->s_lock
);
968 mutex_unlock(&map
->s_lock
);
970 if (cur
== vm_map_to_entry(map
))
973 if (address
>= cur
->vme_start
) {
975 * Go from hint to end of list.
977 * But first, make a quick check to see if
978 * we are already looking at the entry we
979 * want (which is usually the case).
980 * Note also that we don't need to save the hint
981 * here... it is the same hint (unless we are
982 * at the header, in which case the hint didn't
983 * buy us anything anyway).
985 last
= vm_map_to_entry(map
);
986 if ((cur
!= last
) && (cur
->vme_end
> address
)) {
993 * Go from start to hint, *inclusively*
995 last
= cur
->vme_next
;
996 cur
= vm_map_first_entry(map
);
1003 while (cur
!= last
) {
1004 if (cur
->vme_end
> address
) {
1005 if (address
>= cur
->vme_start
) {
1007 * Save this lookup for future
1012 SAVE_HINT(map
, cur
);
1017 cur
= cur
->vme_next
;
1019 *entry
= cur
->vme_prev
;
1020 SAVE_HINT(map
, *entry
);
1025 * Routine: vm_map_find_space
1027 * Allocate a range in the specified virtual address map,
1028 * returning the entry allocated for that range.
1029 * Used by kmem_alloc, etc.
1031 * The map must be NOT be locked. It will be returned locked
1032 * on KERN_SUCCESS, unlocked on failure.
1034 * If an entry is allocated, the object/offset fields
1035 * are initialized to zero.
1039 register vm_map_t map
,
1040 vm_offset_t
*address
, /* OUT */
1043 vm_map_entry_t
*o_entry
) /* OUT */
1045 register vm_map_entry_t entry
, new_entry
;
1046 register vm_offset_t start
;
1047 register vm_offset_t end
;
1049 new_entry
= vm_map_entry_create(map
);
1052 * Look for the first possible address; if there's already
1053 * something at this address, we have to start after it.
1058 assert(first_free_is_valid(map
));
1059 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1060 start
= map
->min_offset
;
1062 start
= entry
->vme_end
;
1065 * In any case, the "entry" always precedes
1066 * the proposed new region throughout the loop:
1070 register vm_map_entry_t next
;
1073 * Find the end of the proposed new region.
1074 * Be sure we didn't go beyond the end, or
1075 * wrap around the address.
1078 end
= ((start
+ mask
) & ~mask
);
1080 vm_map_entry_dispose(map
, new_entry
);
1082 return(KERN_NO_SPACE
);
1087 if ((end
> map
->max_offset
) || (end
< start
)) {
1088 vm_map_entry_dispose(map
, new_entry
);
1090 return(KERN_NO_SPACE
);
1094 * If there are no more entries, we must win.
1097 next
= entry
->vme_next
;
1098 if (next
== vm_map_to_entry(map
))
1102 * If there is another entry, it must be
1103 * after the end of the potential new region.
1106 if (next
->vme_start
>= end
)
1110 * Didn't fit -- move to the next entry.
1114 start
= entry
->vme_end
;
1119 * "start" and "end" should define the endpoints of the
1120 * available new range, and
1121 * "entry" should refer to the region before the new
1124 * the map should be locked.
1129 new_entry
->vme_start
= start
;
1130 new_entry
->vme_end
= end
;
1131 assert(page_aligned(new_entry
->vme_start
));
1132 assert(page_aligned(new_entry
->vme_end
));
1134 new_entry
->is_shared
= FALSE
;
1135 new_entry
->is_sub_map
= FALSE
;
1136 new_entry
->use_pmap
= FALSE
;
1137 new_entry
->object
.vm_object
= VM_OBJECT_NULL
;
1138 new_entry
->offset
= (vm_object_offset_t
) 0;
1140 new_entry
->needs_copy
= FALSE
;
1142 new_entry
->inheritance
= VM_INHERIT_DEFAULT
;
1143 new_entry
->protection
= VM_PROT_DEFAULT
;
1144 new_entry
->max_protection
= VM_PROT_ALL
;
1145 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
1146 new_entry
->wired_count
= 0;
1147 new_entry
->user_wired_count
= 0;
1149 new_entry
->in_transition
= FALSE
;
1150 new_entry
->needs_wakeup
= FALSE
;
1153 * Insert the new entry into the list
1156 vm_map_entry_link(map
, entry
, new_entry
);
1161 * Update the lookup hint
1163 SAVE_HINT(map
, new_entry
);
1165 *o_entry
= new_entry
;
1166 return(KERN_SUCCESS
);
1169 int vm_map_pmap_enter_print
= FALSE
;
1170 int vm_map_pmap_enter_enable
= FALSE
;
1173 * Routine: vm_map_pmap_enter
1176 * Force pages from the specified object to be entered into
1177 * the pmap at the specified address if they are present.
1178 * As soon as a page not found in the object the scan ends.
1183 * In/out conditions:
1184 * The source map should not be locked on entry.
1189 register vm_offset_t addr
,
1190 register vm_offset_t end_addr
,
1191 register vm_object_t object
,
1192 vm_object_offset_t offset
,
1193 vm_prot_t protection
)
1195 while (addr
< end_addr
) {
1196 register vm_page_t m
;
1198 vm_object_lock(object
);
1199 vm_object_paging_begin(object
);
1201 m
= vm_page_lookup(object
, offset
);
1202 if (m
== VM_PAGE_NULL
|| m
->busy
||
1203 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
||
1204 protection
& m
->page_lock
))) {
1206 vm_object_paging_end(object
);
1207 vm_object_unlock(object
);
1211 assert(!m
->fictitious
); /* XXX is this possible ??? */
1213 if (vm_map_pmap_enter_print
) {
1214 printf("vm_map_pmap_enter:");
1215 printf("map: %x, addr: %x, object: %x, offset: %x\n",
1216 map
, addr
, object
, offset
);
1220 vm_object_unlock(object
);
1222 PMAP_ENTER(map
->pmap
, addr
, m
,
1225 vm_object_lock(object
);
1226 PAGE_WAKEUP_DONE(m
);
1227 vm_page_lock_queues();
1228 if (!m
->active
&& !m
->inactive
)
1229 vm_page_activate(m
);
1230 vm_page_unlock_queues();
1231 vm_object_paging_end(object
);
1232 vm_object_unlock(object
);
1234 offset
+= PAGE_SIZE_64
;
1240 * Routine: vm_map_enter
1243 * Allocate a range in the specified virtual address map.
1244 * The resulting range will refer to memory defined by
1245 * the given memory object and offset into that object.
1247 * Arguments are as defined in the vm_map call.
1251 register vm_map_t map
,
1252 vm_offset_t
*address
, /* IN/OUT */
1257 vm_object_offset_t offset
,
1258 boolean_t needs_copy
,
1259 vm_prot_t cur_protection
,
1260 vm_prot_t max_protection
,
1261 vm_inherit_t inheritance
)
1263 vm_map_entry_t entry
;
1264 register vm_offset_t start
;
1265 register vm_offset_t end
;
1266 kern_return_t result
= KERN_SUCCESS
;
1268 boolean_t anywhere
= VM_FLAGS_ANYWHERE
& flags
;
1271 VM_GET_FLAGS_ALIAS(flags
, alias
);
1273 #define RETURN(value) { result = value; goto BailOut; }
1275 assert(page_aligned(*address
));
1276 assert(page_aligned(size
));
1285 * Calculate the first possible address.
1288 if (start
< map
->min_offset
)
1289 start
= map
->min_offset
;
1290 if (start
> map
->max_offset
)
1291 RETURN(KERN_NO_SPACE
);
1294 * Look for the first possible address;
1295 * if there's already something at this
1296 * address, we have to start after it.
1299 assert(first_free_is_valid(map
));
1300 if (start
== map
->min_offset
) {
1301 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
1302 start
= entry
->vme_end
;
1304 vm_map_entry_t tmp_entry
;
1305 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
1306 start
= tmp_entry
->vme_end
;
1311 * In any case, the "entry" always precedes
1312 * the proposed new region throughout the
1317 register vm_map_entry_t next
;
1320 * Find the end of the proposed new region.
1321 * Be sure we didn't go beyond the end, or
1322 * wrap around the address.
1325 end
= ((start
+ mask
) & ~mask
);
1327 RETURN(KERN_NO_SPACE
);
1331 if ((end
> map
->max_offset
) || (end
< start
)) {
1332 if (map
->wait_for_space
) {
1333 if (size
<= (map
->max_offset
-
1335 assert_wait((event_t
)map
,
1338 thread_block((void (*)(void))0);
1342 RETURN(KERN_NO_SPACE
);
1346 * If there are no more entries, we must win.
1349 next
= entry
->vme_next
;
1350 if (next
== vm_map_to_entry(map
))
1354 * If there is another entry, it must be
1355 * after the end of the potential new region.
1358 if (next
->vme_start
>= end
)
1362 * Didn't fit -- move to the next entry.
1366 start
= entry
->vme_end
;
1370 vm_map_entry_t temp_entry
;
1374 * the address doesn't itself violate
1375 * the mask requirement.
1379 if ((start
& mask
) != 0)
1380 RETURN(KERN_NO_SPACE
);
1383 * ... the address is within bounds
1388 if ((start
< map
->min_offset
) ||
1389 (end
> map
->max_offset
) ||
1391 RETURN(KERN_INVALID_ADDRESS
);
1395 * ... the starting address isn't allocated
1398 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
1399 RETURN(KERN_NO_SPACE
);
1404 * ... the next region doesn't overlap the
1408 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
1409 (entry
->vme_next
->vme_start
< end
))
1410 RETURN(KERN_NO_SPACE
);
1415 * "start" and "end" should define the endpoints of the
1416 * available new range, and
1417 * "entry" should refer to the region before the new
1420 * the map should be locked.
1424 * See whether we can avoid creating a new entry (and object) by
1425 * extending one of our neighbors. [So far, we only attempt to
1426 * extend from below.]
1429 if ((object
== VM_OBJECT_NULL
) &&
1430 (entry
!= vm_map_to_entry(map
)) &&
1431 (entry
->vme_end
== start
) &&
1432 (!entry
->is_shared
) &&
1433 (!entry
->is_sub_map
) &&
1434 (entry
->alias
== alias
) &&
1435 (entry
->inheritance
== inheritance
) &&
1436 (entry
->protection
== cur_protection
) &&
1437 (entry
->max_protection
== max_protection
) &&
1438 (entry
->behavior
== VM_BEHAVIOR_DEFAULT
) &&
1439 (entry
->in_transition
== 0) &&
1440 (entry
->wired_count
== 0)) { /* implies user_wired_count == 0 */
1441 if (vm_object_coalesce(entry
->object
.vm_object
,
1444 (vm_object_offset_t
) 0,
1445 (vm_size_t
)(entry
->vme_end
- entry
->vme_start
),
1446 (vm_size_t
)(end
- entry
->vme_end
))) {
1449 * Coalesced the two objects - can extend
1450 * the previous map entry to include the
1453 map
->size
+= (end
- entry
->vme_end
);
1454 entry
->vme_end
= end
;
1455 UPDATE_FIRST_FREE(map
, map
->first_free
);
1456 RETURN(KERN_SUCCESS
);
1461 * Create a new entry
1465 register vm_map_entry_t new_entry
;
1467 new_entry
= vm_map_entry_insert(map
, entry
, start
, end
, object
,
1468 offset
, needs_copy
, FALSE
, FALSE
,
1469 cur_protection
, max_protection
,
1470 VM_BEHAVIOR_DEFAULT
, inheritance
, 0);
1471 new_entry
->alias
= alias
;
1474 /* Wire down the new entry if the user
1475 * requested all new map entries be wired.
1477 if (map
->wiring_required
) {
1478 result
= vm_map_wire(map
, start
, end
,
1479 new_entry
->protection
, TRUE
);
1483 if ((object
!= VM_OBJECT_NULL
) &&
1484 (vm_map_pmap_enter_enable
) &&
1487 (size
< (128*1024))) {
1488 vm_map_pmap_enter(map
, start
, end
,
1489 object
, offset
, cur_protection
);
1503 * vm_map_clip_start: [ internal use only ]
1505 * Asserts that the given entry begins at or after
1506 * the specified address; if necessary,
1507 * it splits the entry into two.
1510 #define vm_map_clip_start(map, entry, startaddr) \
1512 vm_map_t VMCS_map; \
1513 vm_map_entry_t VMCS_entry; \
1514 vm_offset_t VMCS_startaddr; \
1516 VMCS_entry = (entry); \
1517 VMCS_startaddr = (startaddr); \
1518 if (VMCS_startaddr > VMCS_entry->vme_start) { \
1519 if(entry->use_pmap) { \
1520 vm_offset_t pmap_base_addr; \
1521 vm_offset_t pmap_end_addr; \
1523 pmap_base_addr = 0xF0000000 & entry->vme_start; \
1524 pmap_end_addr = (pmap_base_addr + 0x10000000) - 1; \
1525 pmap_unnest(map->pmap, pmap_base_addr, \
1526 (pmap_end_addr - pmap_base_addr) + 1); \
1527 entry->use_pmap = FALSE; \
1529 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
1531 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
1534 #define vm_map_clip_start(map, entry, startaddr) \
1536 vm_map_t VMCS_map; \
1537 vm_map_entry_t VMCS_entry; \
1538 vm_offset_t VMCS_startaddr; \
1540 VMCS_entry = (entry); \
1541 VMCS_startaddr = (startaddr); \
1542 if (VMCS_startaddr > VMCS_entry->vme_start) { \
1543 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
1545 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
1549 #define vm_map_copy_clip_start(copy, entry, startaddr) \
1551 if ((startaddr) > (entry)->vme_start) \
1552 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
1556 * This routine is called only when it is known that
1557 * the entry must be split.
1561 register struct vm_map_header
*map_header
,
1562 register vm_map_entry_t entry
,
1563 register vm_offset_t start
)
1565 register vm_map_entry_t new_entry
;
1568 * Split off the front portion --
1569 * note that we must insert the new
1570 * entry BEFORE this one, so that
1571 * this entry has the specified starting
1575 new_entry
= _vm_map_entry_create(map_header
);
1576 vm_map_entry_copy_full(new_entry
, entry
);
1578 new_entry
->vme_end
= start
;
1579 entry
->offset
+= (start
- entry
->vme_start
);
1580 entry
->vme_start
= start
;
1582 _vm_map_entry_link(map_header
, entry
->vme_prev
, new_entry
);
1584 if (entry
->is_sub_map
)
1585 vm_map_reference(new_entry
->object
.sub_map
);
1587 vm_object_reference(new_entry
->object
.vm_object
);
1592 * vm_map_clip_end: [ internal use only ]
1594 * Asserts that the given entry ends at or before
1595 * the specified address; if necessary,
1596 * it splits the entry into two.
1599 #define vm_map_clip_end(map, entry, endaddr) \
1601 vm_map_t VMCE_map; \
1602 vm_map_entry_t VMCE_entry; \
1603 vm_offset_t VMCE_endaddr; \
1605 VMCE_entry = (entry); \
1606 VMCE_endaddr = (endaddr); \
1607 if (VMCE_endaddr < VMCE_entry->vme_end) { \
1608 if(entry->use_pmap) { \
1609 vm_offset_t pmap_base_addr; \
1610 vm_offset_t pmap_end_addr; \
1612 pmap_base_addr = 0xF0000000 & entry->vme_start; \
1613 pmap_end_addr = (pmap_base_addr + 0x10000000) - 1; \
1614 pmap_unnest(map->pmap, pmap_base_addr, \
1615 (pmap_end_addr - pmap_base_addr) + 1); \
1616 entry->use_pmap = FALSE; \
1618 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
1620 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
1623 #define vm_map_clip_end(map, entry, endaddr) \
1625 vm_map_t VMCE_map; \
1626 vm_map_entry_t VMCE_entry; \
1627 vm_offset_t VMCE_endaddr; \
1629 VMCE_entry = (entry); \
1630 VMCE_endaddr = (endaddr); \
1631 if (VMCE_endaddr < VMCE_entry->vme_end) { \
1632 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
1634 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
1638 #define vm_map_copy_clip_end(copy, entry, endaddr) \
1640 if ((endaddr) < (entry)->vme_end) \
1641 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
1645 * This routine is called only when it is known that
1646 * the entry must be split.
1650 register struct vm_map_header
*map_header
,
1651 register vm_map_entry_t entry
,
1652 register vm_offset_t end
)
1654 register vm_map_entry_t new_entry
;
1657 * Create a new entry and insert it
1658 * AFTER the specified entry
1661 new_entry
= _vm_map_entry_create(map_header
);
1662 vm_map_entry_copy_full(new_entry
, entry
);
1664 new_entry
->vme_start
= entry
->vme_end
= end
;
1665 new_entry
->offset
+= (end
- entry
->vme_start
);
1667 _vm_map_entry_link(map_header
, entry
, new_entry
);
1669 if (entry
->is_sub_map
)
1670 vm_map_reference(new_entry
->object
.sub_map
);
1672 vm_object_reference(new_entry
->object
.vm_object
);
1677 * VM_MAP_RANGE_CHECK: [ internal use only ]
1679 * Asserts that the starting and ending region
1680 * addresses fall within the valid range of the map.
1682 #define VM_MAP_RANGE_CHECK(map, start, end) \
1684 if (start < vm_map_min(map)) \
1685 start = vm_map_min(map); \
1686 if (end > vm_map_max(map)) \
1687 end = vm_map_max(map); \
1693 * vm_map_range_check: [ internal use only ]
1695 * Check that the region defined by the specified start and
1696 * end addresses are wholly contained within a single map
1697 * entry or set of adjacent map entries of the spacified map,
1698 * i.e. the specified region contains no unmapped space.
1699 * If any or all of the region is unmapped, FALSE is returned.
1700 * Otherwise, TRUE is returned and if the output argument 'entry'
1701 * is not NULL it points to the map entry containing the start
1704 * The map is locked for reading on entry and is left locked.
1708 register vm_map_t map
,
1709 register vm_offset_t start
,
1710 register vm_offset_t end
,
1711 vm_map_entry_t
*entry
)
1714 register vm_offset_t prev
;
1717 * Basic sanity checks first
1719 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
1723 * Check first if the region starts within a valid
1724 * mapping for the map.
1726 if (!vm_map_lookup_entry(map
, start
, &cur
))
1730 * Optimize for the case that the region is contained
1731 * in a single map entry.
1733 if (entry
!= (vm_map_entry_t
*) NULL
)
1735 if (end
<= cur
->vme_end
)
1739 * If the region is not wholly contained within a
1740 * single entry, walk the entries looking for holes.
1742 prev
= cur
->vme_end
;
1743 cur
= cur
->vme_next
;
1744 while ((cur
!= vm_map_to_entry(map
)) && (prev
== cur
->vme_start
)) {
1745 if (end
<= cur
->vme_end
)
1747 prev
= cur
->vme_end
;
1748 cur
= cur
->vme_next
;
1754 * vm_map_submap: [ kernel use only ]
1756 * Mark the given range as handled by a subordinate map.
1758 * This range must have been created with vm_map_find using
1759 * the vm_submap_object, and no other operations may have been
1760 * performed on this range prior to calling vm_map_submap.
1762 * Only a limited number of operations can be performed
1763 * within this rage after calling vm_map_submap:
1765 * [Don't try vm_map_copyin!]
1767 * To remove a submapping, one must first remove the
1768 * range from the superior map, and then destroy the
1769 * submap (if desired). [Better yet, don't try it.]
1773 register vm_map_t map
,
1774 register vm_offset_t start
,
1775 register vm_offset_t end
,
1780 vm_map_entry_t entry
;
1781 register kern_return_t result
= KERN_INVALID_ARGUMENT
;
1782 register vm_object_t object
;
1786 VM_MAP_RANGE_CHECK(map
, start
, end
);
1788 if (vm_map_lookup_entry(map
, start
, &entry
)) {
1789 vm_map_clip_start(map
, entry
, start
);
1792 entry
= entry
->vme_next
;
1794 if(entry
== vm_map_to_entry(map
)) {
1796 return KERN_INVALID_ARGUMENT
;
1799 vm_map_clip_end(map
, entry
, end
);
1801 if ((entry
->vme_start
== start
) && (entry
->vme_end
== end
) &&
1802 (!entry
->is_sub_map
) &&
1803 ((object
= entry
->object
.vm_object
) == vm_submap_object
) &&
1804 (object
->resident_page_count
== 0) &&
1805 (object
->copy
== VM_OBJECT_NULL
) &&
1806 (object
->shadow
== VM_OBJECT_NULL
) &&
1807 (!object
->pager_created
)) {
1808 entry
->offset
= (vm_object_offset_t
)offset
;
1809 entry
->object
.vm_object
= VM_OBJECT_NULL
;
1810 vm_object_deallocate(object
);
1811 entry
->is_sub_map
= TRUE
;
1812 vm_map_reference(entry
->object
.sub_map
= submap
);
1814 if ((use_pmap
) && (offset
== 0)) {
1815 /* nest if platform code will allow */
1816 result
= pmap_nest(map
->pmap
, (entry
->object
.sub_map
)->pmap
,
1817 start
, end
- start
);
1819 panic("pmap_nest failed!");
1820 entry
->use_pmap
= TRUE
;
1824 pmap_remove(map
->pmap
, start
, end
);
1826 result
= KERN_SUCCESS
;
1836 * Sets the protection of the specified address
1837 * region in the target map. If "set_max" is
1838 * specified, the maximum protection is to be set;
1839 * otherwise, only the current protection is affected.
1843 register vm_map_t map
,
1844 register vm_offset_t start
,
1845 register vm_offset_t end
,
1846 register vm_prot_t new_prot
,
1847 register boolean_t set_max
)
1849 register vm_map_entry_t current
;
1850 register vm_offset_t prev
;
1851 vm_map_entry_t entry
;
1856 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
1857 (integer_t
)map
, start
, end
, new_prot
, set_max
);
1862 * Lookup the entry. If it doesn't start in a valid
1863 * entry, return an error. Remember if we need to
1864 * clip the entry. We don't do it here because we don't
1865 * want to make any changes until we've scanned the
1866 * entire range below for address and protection
1869 if (!(clip
= vm_map_lookup_entry(map
, start
, &entry
))) {
1871 return(KERN_INVALID_ADDRESS
);
1875 * Make a first pass to check for protection and address
1880 prev
= current
->vme_start
;
1881 while ((current
!= vm_map_to_entry(map
)) &&
1882 (current
->vme_start
< end
)) {
1885 * If there is a hole, return an error.
1887 if (current
->vme_start
!= prev
) {
1889 return(KERN_INVALID_ADDRESS
);
1892 new_max
= current
->max_protection
;
1893 if(new_prot
& VM_PROT_COPY
) {
1894 new_max
|= VM_PROT_WRITE
;
1895 if ((new_prot
& (new_max
| VM_PROT_COPY
)) != new_prot
) {
1897 return(KERN_PROTECTION_FAILURE
);
1900 if ((new_prot
& new_max
) != new_prot
) {
1902 return(KERN_PROTECTION_FAILURE
);
1906 prev
= current
->vme_end
;
1907 current
= current
->vme_next
;
1911 return(KERN_INVALID_ADDRESS
);
1915 * Go back and fix up protections.
1916 * Clip to start here if the range starts within
1922 vm_map_clip_start(map
, entry
, start
);
1924 while ((current
!= vm_map_to_entry(map
)) &&
1925 (current
->vme_start
< end
)) {
1929 vm_map_clip_end(map
, current
, end
);
1931 old_prot
= current
->protection
;
1933 if(new_prot
& VM_PROT_COPY
) {
1934 /* caller is asking specifically to copy the */
1935 /* mapped data, this implies that max protection */
1936 /* will include write. Caller must be prepared */
1937 /* for loss of shared memory communication in the */
1938 /* target area after taking this step */
1939 current
->needs_copy
= TRUE
;
1940 current
->max_protection
|= VM_PROT_WRITE
;
1944 current
->protection
=
1945 (current
->max_protection
=
1946 new_prot
& ~VM_PROT_COPY
) &
1949 current
->protection
= new_prot
& ~VM_PROT_COPY
;
1952 * Update physical map if necessary.
1953 * If the request is to turn off write protection,
1954 * we won't do it for real (in pmap). This is because
1955 * it would cause copy-on-write to fail. We've already
1956 * set, the new protection in the map, so if a
1957 * write-protect fault occurred, it will be fixed up
1958 * properly, COW or not.
1960 /* the 256M hack for existing hardware limitations */
1961 if (current
->protection
!= old_prot
) {
1962 if(current
->is_sub_map
&& current
->use_pmap
) {
1963 vm_offset_t pmap_base_addr
;
1964 vm_offset_t pmap_end_addr
;
1965 vm_map_entry_t local_entry
;
1967 pmap_base_addr
= 0xF0000000 & current
->vme_start
;
1968 pmap_end_addr
= (pmap_base_addr
+ 0x10000000) - 1;
1970 if(!vm_map_lookup_entry(map
,
1971 pmap_base_addr
, &local_entry
))
1972 panic("vm_map_protect: nested pmap area is missing");
1973 while ((local_entry
!= vm_map_to_entry(map
)) &&
1974 (local_entry
->vme_start
< pmap_end_addr
)) {
1975 local_entry
->use_pmap
= FALSE
;
1976 local_entry
= local_entry
->vme_next
;
1978 pmap_unnest(map
->pmap
, pmap_base_addr
,
1979 (pmap_end_addr
- pmap_base_addr
) + 1);
1982 if (!(current
->protection
& VM_PROT_WRITE
)) {
1983 /* Look one level in we support nested pmaps */
1984 /* from mapped submaps which are direct entries */
1986 if(current
->is_sub_map
&& current
->use_pmap
) {
1987 pmap_protect(current
->object
.sub_map
->pmap
,
1990 current
->protection
);
1992 pmap_protect(map
->pmap
, current
->vme_start
,
1994 current
->protection
);
1998 current
= current
->vme_next
;
2002 return(KERN_SUCCESS
);
2008 * Sets the inheritance of the specified address
2009 * range in the target map. Inheritance
2010 * affects how the map will be shared with
2011 * child maps at the time of vm_map_fork.
2015 register vm_map_t map
,
2016 register vm_offset_t start
,
2017 register vm_offset_t end
,
2018 register vm_inherit_t new_inheritance
)
2020 register vm_map_entry_t entry
;
2021 vm_map_entry_t temp_entry
;
2025 VM_MAP_RANGE_CHECK(map
, start
, end
);
2027 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
2029 vm_map_clip_start(map
, entry
, start
);
2032 temp_entry
= temp_entry
->vme_next
;
2036 /* first check entire range for submaps which can't support the */
2037 /* given inheritance. */
2038 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2039 if(entry
->is_sub_map
) {
2040 if(new_inheritance
== VM_INHERIT_COPY
)
2041 return(KERN_INVALID_ARGUMENT
);
2044 entry
= entry
->vme_next
;
2049 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2050 vm_map_clip_end(map
, entry
, end
);
2052 entry
->inheritance
= new_inheritance
;
2054 entry
= entry
->vme_next
;
2058 return(KERN_SUCCESS
);
2064 * Sets the pageability of the specified address range in the
2065 * target map as wired. Regions specified as not pageable require
2066 * locked-down physical memory and physical page maps. The
2067 * access_type variable indicates types of accesses that must not
2068 * generate page faults. This is checked against protection of
2069 * memory being locked-down.
2071 * The map must not be locked, but a reference must remain to the
2072 * map throughout the call.
2076 register vm_map_t map
,
2077 register vm_offset_t start
,
2078 register vm_offset_t end
,
2079 register vm_prot_t access_type
,
2080 boolean_t user_wire
,
2083 register vm_map_entry_t entry
;
2084 struct vm_map_entry
*first_entry
, tmp_entry
;
2086 register vm_offset_t s
,e
;
2088 boolean_t need_wakeup
;
2089 boolean_t main_map
= FALSE
;
2090 unsigned int last_timestamp
;
2094 if(map_pmap
== NULL
)
2096 last_timestamp
= map
->timestamp
;
2098 VM_MAP_RANGE_CHECK(map
, start
, end
);
2099 assert(page_aligned(start
));
2100 assert(page_aligned(end
));
2102 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
2103 entry
= first_entry
;
2104 /* vm_map_clip_start will be done later. */
2106 /* Start address is not in map */
2108 return(KERN_INVALID_ADDRESS
);
2112 need_wakeup
= FALSE
;
2113 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2115 * If another thread is wiring/unwiring this entry then
2116 * block after informing other thread to wake us up.
2118 if (entry
->in_transition
) {
2120 * We have not clipped the entry. Make sure that
2121 * the start address is in range so that the lookup
2122 * below will succeed.
2124 s
= entry
->vme_start
< start
? start
: entry
->vme_start
;
2126 entry
->needs_wakeup
= TRUE
;
2129 * wake up anybody waiting on entries that we have
2133 vm_map_entry_wakeup(map
);
2134 need_wakeup
= FALSE
;
2137 * User wiring is interruptible
2139 vm_map_entry_wait(map
,
2140 (user_wire
) ? THREAD_ABORTSAFE
:
2142 if (user_wire
&& current_thread()->wait_result
==
2143 THREAD_INTERRUPTED
) {
2145 * undo the wirings we have done so far
2146 * We do not clear the needs_wakeup flag,
2147 * because we cannot tell if we were the
2150 vm_map_unwire(map
, start
, s
, user_wire
);
2151 return(KERN_FAILURE
);
2156 * Cannot avoid a lookup here. reset timestamp.
2158 last_timestamp
= map
->timestamp
;
2161 * The entry could have been clipped, look it up again.
2162 * Worse that can happen is, it may not exist anymore.
2164 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
2166 panic("vm_map_wire: re-lookup failed");
2169 * User: undo everything upto the previous
2170 * entry. let vm_map_unwire worry about
2171 * checking the validity of the range.
2174 vm_map_unwire(map
, start
, s
, user_wire
);
2175 return(KERN_FAILURE
);
2177 entry
= first_entry
;
2181 if(entry
->is_sub_map
) {
2182 vm_offset_t sub_start
;
2183 vm_offset_t sub_end
;
2184 vm_offset_t local_end
;
2187 vm_map_clip_start(map
, entry
, start
);
2188 vm_map_clip_end(map
, entry
, end
);
2190 sub_start
+= entry
->offset
;
2191 sub_end
= entry
->vme_end
- entry
->vme_start
;
2192 sub_end
+= entry
->offset
;
2194 local_end
= entry
->vme_end
;
2195 if(map_pmap
== NULL
) {
2196 if(entry
->use_pmap
) {
2197 pmap
= entry
->object
.sub_map
->pmap
;
2201 if (entry
->wired_count
) {
2202 if (entry
->wired_count
2204 panic("vm_map_wire: too many wirings");
2207 entry
->user_wired_count
2208 >= MAX_WIRE_COUNT
) {
2210 vm_map_unwire(map
, start
,
2211 entry
->vme_start
, user_wire
);
2212 return(KERN_FAILURE
);
2215 (entry
->user_wired_count
++ == 0))
2216 entry
->wired_count
++;
2217 entry
= entry
->vme_next
;
2222 vm_object_offset_t offset_hi
;
2223 vm_object_offset_t offset_lo
;
2224 vm_object_offset_t offset
;
2227 vm_behavior_t behavior
;
2228 vm_offset_t local_start
;
2229 vm_map_entry_t local_entry
;
2230 vm_map_version_t version
;
2231 vm_map_t lookup_map
;
2233 /* call vm_map_lookup_locked to */
2234 /* cause any needs copy to be */
2236 local_start
= entry
->vme_start
;
2238 vm_map_lock_write_to_read(map
);
2239 if(vm_map_lookup_locked(
2240 &lookup_map
, local_start
,
2243 &offset
, &prot
, &wired
,
2244 &behavior
, &offset_lo
,
2245 &offset_hi
, &pmap_map
)) {
2247 vm_map_unlock(lookup_map
);
2248 vm_map_unwire(map
, start
,
2249 entry
->vme_start
, user_wire
);
2250 return(KERN_FAILURE
);
2252 if(pmap_map
!= lookup_map
)
2253 vm_map_unlock(pmap_map
);
2254 if(lookup_map
!= map
) {
2255 vm_map_unlock(lookup_map
);
2262 version
.main_timestamp
;
2263 vm_object_unlock(object
);
2264 if (vm_map_lookup_entry(map
,
2265 local_start
, &local_entry
)) {
2267 vm_map_unwire(map
, start
,
2268 entry
->vme_start
, user_wire
);
2269 return(KERN_FAILURE
);
2271 /* did we have a change of type? */
2272 if (!local_entry
->is_sub_map
)
2274 entry
= local_entry
;
2276 entry
->user_wired_count
++;
2277 entry
->wired_count
++;
2279 entry
->in_transition
= TRUE
;
2282 rc
= vm_map_wire_nested(
2283 entry
->object
.sub_map
,
2288 last_timestamp
= map
->timestamp
;
2292 rc
= vm_map_wire_nested(entry
->object
.sub_map
,
2297 last_timestamp
= map
->timestamp
;
2299 s
= entry
->vme_start
;
2301 if (last_timestamp
+1 != map
->timestamp
) {
2303 * Find the entry again. It could have been clipped
2304 * after we unlocked the map.
2306 if (!vm_map_lookup_entry(map
, local_end
,
2308 panic("vm_map_wire: re-lookup failed");
2310 entry
= first_entry
;
2313 last_timestamp
= map
->timestamp
;
2314 while ((entry
!= vm_map_to_entry(map
)) &&
2315 (entry
->vme_start
< e
)) {
2316 assert(entry
->in_transition
);
2317 entry
->in_transition
= FALSE
;
2318 if (entry
->needs_wakeup
) {
2319 entry
->needs_wakeup
= FALSE
;
2322 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
2325 entry
->user_wired_count
--;
2326 entry
->wired_count
--;
2329 entry
= entry
->vme_next
;
2331 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2334 vm_map_entry_wakeup(map
);
2336 * undo everything upto the previous entry.
2338 (void)vm_map_unwire(map
, start
, s
, user_wire
);
2345 * If this entry is already wired then increment
2346 * the appropriate wire reference count.
2348 if (entry
->wired_count
&& main_map
) {
2349 /* sanity check: wired_count is a short */
2350 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
2351 panic("vm_map_wire: too many wirings");
2354 entry
->user_wired_count
>= MAX_WIRE_COUNT
) {
2356 vm_map_unwire(map
, start
,
2357 entry
->vme_start
, user_wire
);
2358 return(KERN_FAILURE
);
2361 * entry is already wired down, get our reference
2362 * after clipping to our range.
2364 vm_map_clip_start(map
, entry
, start
);
2365 vm_map_clip_end(map
, entry
, end
);
2366 if (!user_wire
|| (entry
->user_wired_count
++ == 0))
2367 entry
->wired_count
++;
2369 entry
= entry
->vme_next
;
2374 * Unwired entry or wire request transmitted via submap
2379 * Perform actions of vm_map_lookup that need the write
2380 * lock on the map: create a shadow object for a
2381 * copy-on-write region, or an object for a zero-fill
2384 size
= entry
->vme_end
- entry
->vme_start
;
2386 * If wiring a copy-on-write page, we need to copy it now
2387 * even if we're only (currently) requesting read access.
2388 * This is aggressive, but once it's wired we can't move it.
2390 if (entry
->needs_copy
) {
2391 vm_object_shadow(&entry
->object
.vm_object
,
2392 &entry
->offset
, size
);
2393 entry
->needs_copy
= FALSE
;
2394 } else if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
2395 entry
->object
.vm_object
= vm_object_allocate(size
);
2396 entry
->offset
= (vm_object_offset_t
)0;
2399 vm_map_clip_start(map
, entry
, start
);
2400 vm_map_clip_end(map
, entry
, end
);
2402 s
= entry
->vme_start
;
2406 * Check for holes and protection mismatch.
2407 * Holes: Next entry should be contiguous unless this
2408 * is the end of the region.
2409 * Protection: Access requested must be allowed, unless
2410 * wiring is by protection class
2412 if ((((entry
->vme_end
< end
) &&
2413 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
2414 (entry
->vme_next
->vme_start
> entry
->vme_end
))) ||
2415 ((entry
->protection
& access_type
) != access_type
))) {
2417 * Found a hole or protection problem.
2418 * Unwire the region we wired so far.
2420 if (start
!= entry
->vme_start
) {
2422 vm_map_unwire(map
, start
, s
, user_wire
);
2426 return((entry
->protection
&access_type
) != access_type
?
2427 KERN_PROTECTION_FAILURE
: KERN_INVALID_ADDRESS
);
2430 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
2434 entry
->user_wired_count
++;
2435 entry
->wired_count
++;
2438 entry
->in_transition
= TRUE
;
2441 * This entry might get split once we unlock the map.
2442 * In vm_fault_wire(), we need the current range as
2443 * defined by this entry. In order for this to work
2444 * along with a simultaneous clip operation, we make a
2445 * temporary copy of this entry and use that for the
2446 * wiring. Note that the underlying objects do not
2447 * change during a clip.
2452 * The in_transition state guarentees that the entry
2453 * (or entries for this range, if split occured) will be
2454 * there when the map lock is acquired for the second time.
2458 rc
= vm_fault_wire(map
, &tmp_entry
, map_pmap
);
2460 rc
= vm_fault_wire(map
, &tmp_entry
, map
->pmap
);
2463 if (last_timestamp
+1 != map
->timestamp
) {
2465 * Find the entry again. It could have been clipped
2466 * after we unlocked the map.
2468 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
2470 panic("vm_map_wire: re-lookup failed");
2472 entry
= first_entry
;
2475 last_timestamp
= map
->timestamp
;
2477 while ((entry
!= vm_map_to_entry(map
)) &&
2478 (entry
->vme_start
< tmp_entry
.vme_end
)) {
2479 assert(entry
->in_transition
);
2480 entry
->in_transition
= FALSE
;
2481 if (entry
->needs_wakeup
) {
2482 entry
->needs_wakeup
= FALSE
;
2485 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2488 entry
->user_wired_count
--;
2489 entry
->wired_count
--;
2492 entry
= entry
->vme_next
;
2495 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2498 vm_map_entry_wakeup(map
);
2500 * undo everything upto the previous entry.
2502 (void)vm_map_unwire(map
, start
, s
, user_wire
);
2505 } /* end while loop through map entries */
2509 * wake up anybody waiting on entries we wired.
2512 vm_map_entry_wakeup(map
);
2514 return(KERN_SUCCESS
);
2520 register vm_map_t map
,
2521 register vm_offset_t start
,
2522 register vm_offset_t end
,
2523 register vm_prot_t access_type
,
2524 boolean_t user_wire
)
2531 * the calls to mapping_prealloc and mapping_relpre
2532 * (along with the VM_MAP_RANGE_CHECK to insure a
2533 * resonable range was passed in) are
2534 * currently necessary because
2535 * we haven't enabled kernel pre-emption
2536 * and/or the pmap_enter cannot purge and re-use
2539 VM_MAP_RANGE_CHECK(map
, start
, end
);
2540 mapping_prealloc(end
- start
);
2542 kret
= vm_map_wire_nested(map
, start
, end
, access_type
,
2543 user_wire
, (pmap_t
)NULL
);
2553 * Sets the pageability of the specified address range in the target
2554 * as pageable. Regions specified must have been wired previously.
2556 * The map must not be locked, but a reference must remain to the map
2557 * throughout the call.
2559 * Kernel will panic on failures. User unwire ignores holes and
2560 * unwired and intransition entries to avoid losing memory by leaving
2564 vm_map_unwire_nested(
2565 register vm_map_t map
,
2566 register vm_offset_t start
,
2567 register vm_offset_t end
,
2568 boolean_t user_wire
,
2571 register vm_map_entry_t entry
;
2572 struct vm_map_entry
*first_entry
, tmp_entry
;
2573 boolean_t need_wakeup
;
2574 boolean_t main_map
= FALSE
;
2575 unsigned int last_timestamp
;
2578 if(map_pmap
== NULL
)
2580 last_timestamp
= map
->timestamp
;
2582 VM_MAP_RANGE_CHECK(map
, start
, end
);
2583 assert(page_aligned(start
));
2584 assert(page_aligned(end
));
2586 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
2587 entry
= first_entry
;
2588 /* vm_map_clip_start will be done later. */
2591 /* Start address is not in map. */
2593 return(KERN_INVALID_ADDRESS
);
2596 need_wakeup
= FALSE
;
2597 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2598 if (entry
->in_transition
) {
2601 * Another thread is wiring down this entry. Note
2602 * that if it is not for the other thread we would
2603 * be unwiring an unwired entry. This is not
2604 * permitted. If we wait, we will be unwiring memory
2608 * Another thread is unwiring this entry. We did not
2609 * have a reference to it, because if we did, this
2610 * entry will not be getting unwired now.
2613 panic("vm_map_unwire: in_transition entry");
2615 entry
= entry
->vme_next
;
2619 if(entry
->is_sub_map
) {
2620 vm_offset_t sub_start
;
2621 vm_offset_t sub_end
;
2622 vm_offset_t local_end
;
2626 vm_map_clip_start(map
, entry
, start
);
2627 vm_map_clip_end(map
, entry
, end
);
2629 sub_start
= entry
->offset
;
2630 sub_end
= entry
->vme_end
- entry
->vme_start
;
2631 sub_end
+= entry
->offset
;
2632 local_end
= entry
->vme_end
;
2633 if(map_pmap
== NULL
) {
2634 if(entry
->use_pmap
) {
2635 pmap
= entry
->object
.sub_map
->pmap
;
2639 if (entry
->wired_count
== 0 ||
2640 (user_wire
&& entry
->user_wired_count
== 0)) {
2642 panic("vm_map_unwire: entry is unwired");
2643 entry
= entry
->vme_next
;
2649 * Holes: Next entry should be contiguous unless
2650 * this is the end of the region.
2652 if (((entry
->vme_end
< end
) &&
2653 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
2654 (entry
->vme_next
->vme_start
2655 > entry
->vme_end
)))) {
2657 panic("vm_map_unwire: non-contiguous region");
2659 entry = entry->vme_next;
2664 if (!user_wire
|| (--entry
->user_wired_count
== 0))
2665 entry
->wired_count
--;
2667 if (entry
->wired_count
!= 0) {
2668 entry
= entry
->vme_next
;
2672 entry
->in_transition
= TRUE
;
2673 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
2676 * We can unlock the map now. The in_transition state
2677 * guarantees existance of the entry.
2680 vm_map_unwire_nested(entry
->object
.sub_map
,
2681 sub_start
, sub_end
, user_wire
, pmap
);
2684 if (last_timestamp
+1 != map
->timestamp
) {
2686 * Find the entry again. It could have been
2687 * clipped or deleted after we unlocked the map.
2689 if (!vm_map_lookup_entry(map
,
2690 tmp_entry
.vme_start
,
2693 panic("vm_map_unwire: re-lookup failed");
2694 entry
= first_entry
->vme_next
;
2696 entry
= first_entry
;
2698 last_timestamp
= map
->timestamp
;
2701 * clear transition bit for all constituent entries
2702 * that were in the original entry (saved in
2703 * tmp_entry). Also check for waiters.
2705 while ((entry
!= vm_map_to_entry(map
)) &&
2706 (entry
->vme_start
< tmp_entry
.vme_end
)) {
2707 assert(entry
->in_transition
);
2708 entry
->in_transition
= FALSE
;
2709 if (entry
->needs_wakeup
) {
2710 entry
->needs_wakeup
= FALSE
;
2713 entry
= entry
->vme_next
;
2718 vm_map_unwire_nested(entry
->object
.sub_map
,
2719 sub_start
, sub_end
, user_wire
, pmap
);
2722 if (last_timestamp
+1 != map
->timestamp
) {
2724 * Find the entry again. It could have been
2725 * clipped or deleted after we unlocked the map.
2727 if (!vm_map_lookup_entry(map
,
2728 tmp_entry
.vme_start
,
2731 panic("vm_map_unwire: re-lookup failed");
2732 entry
= first_entry
->vme_next
;
2734 entry
= first_entry
;
2736 last_timestamp
= map
->timestamp
;
2741 if (main_map
&& (entry
->wired_count
== 0 ||
2742 (user_wire
&& entry
->user_wired_count
== 0))) {
2744 panic("vm_map_unwire: entry is unwired");
2746 entry
= entry
->vme_next
;
2750 assert(entry
->wired_count
> 0 &&
2751 (!user_wire
|| entry
->user_wired_count
> 0));
2753 vm_map_clip_start(map
, entry
, start
);
2754 vm_map_clip_end(map
, entry
, end
);
2758 * Holes: Next entry should be contiguous unless
2759 * this is the end of the region.
2761 if (((entry
->vme_end
< end
) &&
2762 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
2763 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
2766 panic("vm_map_unwire: non-contiguous region");
2767 entry
= entry
->vme_next
;
2772 if (!user_wire
|| (--entry
->user_wired_count
== 0))
2773 entry
->wired_count
--;
2775 if (entry
->wired_count
!= 0) {
2776 entry
= entry
->vme_next
;
2781 entry
->in_transition
= TRUE
;
2782 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
2785 * We can unlock the map now. The in_transition state
2786 * guarantees existance of the entry.
2790 vm_fault_unwire(map
, &tmp_entry
, FALSE
, map_pmap
);
2792 vm_fault_unwire(map
, &tmp_entry
, FALSE
, map
->pmap
);
2796 if (last_timestamp
+1 != map
->timestamp
) {
2798 * Find the entry again. It could have been clipped
2799 * or deleted after we unlocked the map.
2801 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
2804 panic("vm_map_unwire: re-lookup failed");
2805 entry
= first_entry
->vme_next
;
2807 entry
= first_entry
;
2809 last_timestamp
= map
->timestamp
;
2812 * clear transition bit for all constituent entries that
2813 * were in the original entry (saved in tmp_entry). Also
2814 * check for waiters.
2816 while ((entry
!= vm_map_to_entry(map
)) &&
2817 (entry
->vme_start
< tmp_entry
.vme_end
)) {
2818 assert(entry
->in_transition
);
2819 entry
->in_transition
= FALSE
;
2820 if (entry
->needs_wakeup
) {
2821 entry
->needs_wakeup
= FALSE
;
2824 entry
= entry
->vme_next
;
2829 * wake up anybody waiting on entries that we have unwired.
2832 vm_map_entry_wakeup(map
);
2833 return(KERN_SUCCESS
);
2839 register vm_map_t map
,
2840 register vm_offset_t start
,
2841 register vm_offset_t end
,
2842 boolean_t user_wire
)
2844 return vm_map_unwire_nested(map
, start
, end
, user_wire
, (pmap_t
)NULL
);
2849 * vm_map_entry_delete: [ internal use only ]
2851 * Deallocate the given entry from the target map.
2854 vm_map_entry_delete(
2855 register vm_map_t map
,
2856 register vm_map_entry_t entry
)
2858 register vm_offset_t s
, e
;
2859 register vm_object_t object
;
2860 register vm_map_t submap
;
2861 extern vm_object_t kernel_object
;
2863 s
= entry
->vme_start
;
2865 assert(page_aligned(s
));
2866 assert(page_aligned(e
));
2867 assert(entry
->wired_count
== 0);
2868 assert(entry
->user_wired_count
== 0);
2870 if (entry
->is_sub_map
) {
2872 submap
= entry
->object
.sub_map
;
2875 object
= entry
->object
.vm_object
;
2878 vm_map_entry_unlink(map
, entry
);
2881 vm_map_entry_dispose(map
, entry
);
2885 * Deallocate the object only after removing all
2886 * pmap entries pointing to its pages.
2889 vm_map_deallocate(submap
);
2891 vm_object_deallocate(object
);
2896 vm_map_submap_pmap_clean(
2903 vm_offset_t submap_start
;
2904 vm_offset_t submap_end
;
2906 vm_size_t remove_size
;
2907 vm_map_entry_t entry
;
2909 submap_end
= offset
+ (end
- start
);
2910 submap_start
= offset
;
2911 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
2913 remove_size
= (entry
->vme_end
- entry
->vme_start
);
2914 if(offset
> entry
->vme_start
)
2915 remove_size
-= offset
- entry
->vme_start
;
2918 if(submap_end
< entry
->vme_end
) {
2920 entry
->vme_end
- submap_end
;
2922 if(entry
->is_sub_map
) {
2923 vm_map_submap_pmap_clean(
2926 start
+ remove_size
,
2927 entry
->object
.sub_map
,
2930 pmap_remove(map
->pmap
, start
, start
+ remove_size
);
2934 entry
= entry
->vme_next
;
2936 while((entry
!= vm_map_to_entry(sub_map
))
2937 && (entry
->vme_start
< submap_end
)) {
2938 remove_size
= (entry
->vme_end
- entry
->vme_start
);
2939 if(submap_end
< entry
->vme_end
) {
2940 remove_size
-= entry
->vme_end
- submap_end
;
2942 if(entry
->is_sub_map
) {
2943 vm_map_submap_pmap_clean(
2945 (start
+ entry
->vme_start
) - offset
,
2946 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
2947 entry
->object
.sub_map
,
2950 pmap_remove(map
->pmap
,
2951 (start
+ entry
->vme_start
) - offset
,
2952 ((start
+ entry
->vme_start
) - offset
) + remove_size
);
2954 entry
= entry
->vme_next
;
2960 * vm_map_delete: [ internal use only ]
2962 * Deallocates the given address range from the target map.
2963 * Removes all user wirings. Unwires one kernel wiring if
2964 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
2965 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
2966 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
2968 * This routine is called with map locked and leaves map locked.
2972 register vm_map_t map
,
2974 register vm_offset_t end
,
2977 vm_map_entry_t entry
, next
;
2978 struct vm_map_entry
*first_entry
, tmp_entry
;
2979 register vm_offset_t s
, e
;
2980 register vm_object_t object
;
2981 boolean_t need_wakeup
;
2982 unsigned int last_timestamp
= ~0; /* unlikely value */
2984 extern vm_map_t kernel_map
;
2986 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
2987 THREAD_ABORTSAFE
: THREAD_UNINT
;
2990 * All our DMA I/O operations in IOKit are currently done by
2991 * wiring through the map entries of the task requesting the I/O.
2992 * Because of this, we must always wait for kernel wirings
2993 * to go away on the entries before deleting them.
2995 * Any caller who wants to actually remove a kernel wiring
2996 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
2997 * properly remove one wiring instead of blasting through
3000 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
3003 * Find the start of the region, and clip it
3005 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3006 entry
= first_entry
;
3007 vm_map_clip_start(map
, entry
, start
);
3010 * Fix the lookup hint now, rather than each
3011 * time through the loop.
3013 SAVE_HINT(map
, entry
->vme_prev
);
3015 entry
= first_entry
->vme_next
;
3018 need_wakeup
= FALSE
;
3020 * Step through all entries in this region
3022 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3024 vm_map_clip_end(map
, entry
, end
);
3025 if (entry
->in_transition
) {
3027 * Another thread is wiring/unwiring this entry.
3028 * Let the other thread know we are waiting.
3030 s
= entry
->vme_start
;
3031 entry
->needs_wakeup
= TRUE
;
3034 * wake up anybody waiting on entries that we have
3035 * already unwired/deleted.
3038 vm_map_entry_wakeup(map
);
3039 need_wakeup
= FALSE
;
3042 vm_map_entry_wait(map
, interruptible
);
3044 if (interruptible
&&
3045 current_thread()->wait_result
== THREAD_INTERRUPTED
)
3047 * We do not clear the needs_wakeup flag,
3048 * since we cannot tell if we were the only one.
3050 return KERN_ABORTED
;
3054 * Cannot avoid a lookup here. reset timestamp.
3056 last_timestamp
= map
->timestamp
;
3059 * The entry could have been clipped or it
3060 * may not exist anymore. Look it up again.
3062 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
3063 assert((map
!= kernel_map
) &&
3064 (!entry
->is_sub_map
));
3066 * User: use the next entry
3068 entry
= first_entry
->vme_next
;
3070 entry
= first_entry
;
3071 SAVE_HINT(map
, entry
->vme_prev
);
3074 } /* end in_transition */
3076 if (entry
->wired_count
) {
3078 * Remove a kernel wiring if requested or if
3079 * there are user wirings.
3081 if ((flags
& VM_MAP_REMOVE_KUNWIRE
) ||
3082 (entry
->user_wired_count
> 0))
3083 entry
->wired_count
--;
3085 /* remove all user wire references */
3086 entry
->user_wired_count
= 0;
3088 if (entry
->wired_count
!= 0) {
3089 assert((map
!= kernel_map
) &&
3090 (!entry
->is_sub_map
));
3092 * Cannot continue. Typical case is when
3093 * a user thread has physical io pending on
3094 * on this page. Either wait for the
3095 * kernel wiring to go away or return an
3098 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
3100 s
= entry
->vme_start
;
3101 entry
->needs_wakeup
= TRUE
;
3102 vm_map_entry_wait(map
, interruptible
);
3104 if (interruptible
&&
3105 current_thread()->wait_result
==
3108 * We do not clear the
3109 * needs_wakeup flag, since we
3110 * cannot tell if we were the
3113 return KERN_ABORTED
;
3117 * Cannot avoid a lookup here. reset
3120 last_timestamp
= map
->timestamp
;
3123 * The entry could have been clipped or
3124 * it may not exist anymore. Look it
3127 if (!vm_map_lookup_entry(map
, s
,
3129 assert((map
!= kernel_map
) &&
3130 (!entry
->is_sub_map
));
3132 * User: use the next entry
3134 entry
= first_entry
->vme_next
;
3136 entry
= first_entry
;
3137 SAVE_HINT(map
, entry
->vme_prev
);
3142 return KERN_FAILURE
;
3146 entry
->in_transition
= TRUE
;
3148 * copy current entry. see comment in vm_map_wire()
3151 s
= entry
->vme_start
;
3155 * We can unlock the map now. The in_transition
3156 * state guarentees existance of the entry.
3159 vm_fault_unwire(map
, &tmp_entry
,
3160 tmp_entry
.object
.vm_object
== kernel_object
,
3164 if (last_timestamp
+1 != map
->timestamp
) {
3166 * Find the entry again. It could have
3167 * been clipped after we unlocked the map.
3169 if (!vm_map_lookup_entry(map
, s
, &first_entry
)){
3170 assert((map
!= kernel_map
) &&
3171 (!entry
->is_sub_map
));
3172 first_entry
= first_entry
->vme_next
;
3174 SAVE_HINT(map
, entry
->vme_prev
);
3177 SAVE_HINT(map
, entry
->vme_prev
);
3178 first_entry
= entry
;
3181 last_timestamp
= map
->timestamp
;
3183 entry
= first_entry
;
3184 while ((entry
!= vm_map_to_entry(map
)) &&
3185 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3186 assert(entry
->in_transition
);
3187 entry
->in_transition
= FALSE
;
3188 if (entry
->needs_wakeup
) {
3189 entry
->needs_wakeup
= FALSE
;
3192 entry
= entry
->vme_next
;
3195 * We have unwired the entry(s). Go back and
3198 entry
= first_entry
;
3202 /* entry is unwired */
3203 assert(entry
->wired_count
== 0);
3204 assert(entry
->user_wired_count
== 0);
3206 if ((!entry
->is_sub_map
&&
3207 entry
->object
.vm_object
!= kernel_object
) ||
3208 entry
->is_sub_map
) {
3209 if(entry
->is_sub_map
) {
3210 if(entry
->use_pmap
) {
3212 pmap_unnest(map
->pmap
, entry
->vme_start
,
3213 entry
->vme_end
- entry
->vme_start
);
3216 vm_map_submap_pmap_clean(
3217 map
, entry
->vme_start
, entry
->vme_end
,
3218 entry
->object
.sub_map
,
3222 pmap_remove(map
->pmap
,
3223 entry
->vme_start
, entry
->vme_end
);
3227 next
= entry
->vme_next
;
3228 s
= next
->vme_start
;
3229 last_timestamp
= map
->timestamp
;
3230 vm_map_entry_delete(map
, entry
);
3231 /* vm_map_entry_delete unlocks the map */
3235 if(entry
== vm_map_to_entry(map
)) {
3238 if (last_timestamp
+1 != map
->timestamp
) {
3240 * we are responsible for deleting everything
3241 * from the give space, if someone has interfered
3242 * we pick up where we left off, back fills should
3243 * be all right for anyone except map_delete and
3244 * we have to assume that the task has been fully
3245 * disabled before we get here
3247 if (!vm_map_lookup_entry(map
, s
, &entry
)){
3248 entry
= entry
->vme_next
;
3250 SAVE_HINT(map
, entry
->vme_prev
);
3253 * others can not only allocate behind us, we can
3254 * also see coalesce while we don't have the map lock
3256 if(entry
== vm_map_to_entry(map
)) {
3259 vm_map_clip_start(map
, entry
, s
);
3261 last_timestamp
= map
->timestamp
;
3264 if (map
->wait_for_space
)
3265 thread_wakeup((event_t
) map
);
3267 * wake up anybody waiting on entries that we have already deleted.
3270 vm_map_entry_wakeup(map
);
3272 return KERN_SUCCESS
;
3278 * Remove the given address range from the target map.
3279 * This is the exported form of vm_map_delete.
3283 register vm_map_t map
,
3284 register vm_offset_t start
,
3285 register vm_offset_t end
,
3286 register boolean_t flags
)
3288 register kern_return_t result
;
3291 VM_MAP_RANGE_CHECK(map
, start
, end
);
3292 result
= vm_map_delete(map
, start
, end
, flags
);
3300 * vm_map_copy_steal_pages:
3302 * Steal all the pages from a vm_map_copy page_list by copying ones
3303 * that have not already been stolen.
3306 vm_map_copy_steal_pages(
3309 register vm_page_t m
, new_m
;
3313 assert(copy
->type
== VM_MAP_COPY_PAGE_LIST
);
3314 for (i
= 0; i
< copy
->cpy_npages
; i
++) {
3317 * If the page is not tabled, then it's already stolen.
3319 m
= copy
->cpy_page_list
[i
];
3324 * Page was not stolen, get a new
3325 * one and do the copy now.
3327 while ((new_m
= vm_page_grab()) == VM_PAGE_NULL
) {
3331 vm_page_gobble(new_m
); /* mark as consumed internally */
3332 vm_page_copy(m
, new_m
);
3335 vm_object_lock(object
);
3336 vm_page_lock_queues();
3337 if (!m
->active
&& !m
->inactive
)
3338 vm_page_activate(m
);
3339 vm_page_unlock_queues();
3340 PAGE_WAKEUP_DONE(m
);
3341 vm_object_paging_end(object
);
3342 vm_object_unlock(object
);
3344 copy
->cpy_page_list
[i
] = new_m
;
3346 copy
->cpy_page_loose
= TRUE
;
3350 * vm_map_copy_page_discard:
3352 * Get rid of the pages in a page_list copy. If the pages are
3353 * stolen, they are freed. If the pages are not stolen, they
3354 * are unbusied, and associated state is cleaned up.
3357 vm_map_copy_page_discard(
3360 assert(copy
->type
== VM_MAP_COPY_PAGE_LIST
);
3361 while (copy
->cpy_npages
> 0) {
3364 if ((m
= copy
->cpy_page_list
[--(copy
->cpy_npages
)]) !=
3368 * If it's not in the table, then it's
3369 * a stolen page that goes back
3370 * to the free list. Else it belongs
3371 * to some object, and we hold a
3372 * paging reference on that object.
3382 vm_object_lock(object
);
3383 vm_page_lock_queues();
3384 if (!m
->active
&& !m
->inactive
)
3385 vm_page_activate(m
);
3386 vm_page_unlock_queues();
3390 kr
= vm_page_unpin(m
);
3391 assert(kr
== KERN_SUCCESS
);
3393 PAGE_WAKEUP_DONE(m
);
3395 vm_object_paging_end(object
);
3396 vm_object_unlock(object
);
3403 * Routine: vm_map_copy_discard
3406 * Dispose of a map copy object (returned by
3410 vm_map_copy_discard(
3413 TR_DECL("vm_map_copy_discard");
3415 /* tr3("enter: copy 0x%x type %d", copy, copy->type);*/
3417 if (copy
== VM_MAP_COPY_NULL
)
3420 switch (copy
->type
) {
3421 case VM_MAP_COPY_ENTRY_LIST
:
3422 while (vm_map_copy_first_entry(copy
) !=
3423 vm_map_copy_to_entry(copy
)) {
3424 vm_map_entry_t entry
= vm_map_copy_first_entry(copy
);
3426 vm_map_copy_entry_unlink(copy
, entry
);
3427 vm_object_deallocate(entry
->object
.vm_object
);
3428 vm_map_copy_entry_dispose(copy
, entry
);
3431 case VM_MAP_COPY_OBJECT
:
3432 vm_object_deallocate(copy
->cpy_object
);
3434 case VM_MAP_COPY_PAGE_LIST
:
3437 * To clean this up, we have to unbusy all the pages
3438 * and release the paging references in their objects.
3440 if (copy
->cpy_npages
> 0)
3441 vm_map_copy_page_discard(copy
);
3444 * If there's a continuation, abort it. The
3445 * abort routine releases any storage.
3447 if (vm_map_copy_has_cont(copy
)) {
3449 assert(vm_map_copy_cont_is_valid(copy
));
3451 * Special case: recognize
3452 * vm_map_copy_discard_cont and optimize
3453 * here to avoid tail recursion.
3455 if (copy
->cpy_cont
== vm_map_copy_discard_cont
) {
3456 register vm_map_copy_t new_copy
;
3458 new_copy
= (vm_map_copy_t
) copy
->cpy_cont_args
;
3459 zfree(vm_map_copy_zone
, (vm_offset_t
) copy
);
3461 goto free_next_copy
;
3463 vm_map_copy_abort_cont(copy
);
3469 case VM_MAP_COPY_KERNEL_BUFFER
:
3472 * The vm_map_copy_t and possibly the data buffer were
3473 * allocated by a single call to kalloc(), i.e. the
3474 * vm_map_copy_t was not allocated out of the zone.
3476 kfree((vm_offset_t
) copy
, copy
->cpy_kalloc_size
);
3479 zfree(vm_map_copy_zone
, (vm_offset_t
) copy
);
3483 * Routine: vm_map_copy_copy
3486 * Move the information in a map copy object to
3487 * a new map copy object, leaving the old one
3490 * This is used by kernel routines that need
3491 * to look at out-of-line data (in copyin form)
3492 * before deciding whether to return SUCCESS.
3493 * If the routine returns FAILURE, the original
3494 * copy object will be deallocated; therefore,
3495 * these routines must make a copy of the copy
3496 * object and leave the original empty so that
3497 * deallocation will not fail.
3503 vm_map_copy_t new_copy
;
3505 if (copy
== VM_MAP_COPY_NULL
)
3506 return VM_MAP_COPY_NULL
;
3509 * Allocate a new copy object, and copy the information
3510 * from the old one into it.
3513 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
3516 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
3518 * The links in the entry chain must be
3519 * changed to point to the new copy object.
3521 vm_map_copy_first_entry(copy
)->vme_prev
3522 = vm_map_copy_to_entry(new_copy
);
3523 vm_map_copy_last_entry(copy
)->vme_next
3524 = vm_map_copy_to_entry(new_copy
);
3528 * Change the old copy object into one that contains
3529 * nothing to be deallocated.
3531 copy
->type
= VM_MAP_COPY_OBJECT
;
3532 copy
->cpy_object
= VM_OBJECT_NULL
;
3535 * Return the new object.
3541 * Routine: vm_map_copy_discard_cont
3544 * A version of vm_map_copy_discard that can be called
3545 * as a continuation from a vm_map_copy page list.
3548 vm_map_copy_discard_cont(
3549 vm_map_copyin_args_t cont_args
,
3550 vm_map_copy_t
*copy_result
) /* OUT */
3552 vm_map_copy_discard((vm_map_copy_t
) cont_args
);
3553 if (copy_result
!= (vm_map_copy_t
*)0)
3554 *copy_result
= VM_MAP_COPY_NULL
;
3555 return(KERN_SUCCESS
);
3559 vm_map_overwrite_submap_recurse(
3561 vm_offset_t dst_addr
,
3564 vm_offset_t dst_end
;
3565 vm_map_entry_t tmp_entry
;
3566 vm_map_entry_t entry
;
3567 kern_return_t result
;
3568 boolean_t encountered_sub_map
= FALSE
;
3573 * Verify that the destination is all writeable
3574 * initially. We have to trunc the destination
3575 * address and round the copy size or we'll end up
3576 * splitting entries in strange ways.
3579 dst_end
= round_page(dst_addr
+ dst_size
);
3582 vm_map_lock(dst_map
);
3583 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
3584 vm_map_unlock(dst_map
);
3585 return(KERN_INVALID_ADDRESS
);
3588 vm_map_clip_start(dst_map
, tmp_entry
, trunc_page(dst_addr
));
3590 for (entry
= tmp_entry
;;) {
3591 vm_map_entry_t next
;
3593 next
= entry
->vme_next
;
3594 while(entry
->is_sub_map
) {
3595 vm_offset_t sub_start
;
3596 vm_offset_t sub_end
;
3597 vm_offset_t local_end
;
3599 if (entry
->in_transition
) {
3601 * Say that we are waiting, and wait for entry.
3603 entry
->needs_wakeup
= TRUE
;
3604 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
3609 encountered_sub_map
= TRUE
;
3610 sub_start
= entry
->offset
;
3612 if(entry
->vme_end
< dst_end
)
3613 sub_end
= entry
->vme_end
;
3616 sub_end
-= entry
->vme_start
;
3617 sub_end
+= entry
->offset
;
3618 local_end
= entry
->vme_end
;
3619 vm_map_unlock(dst_map
);
3621 result
= vm_map_overwrite_submap_recurse(
3622 entry
->object
.sub_map
,
3624 sub_end
- sub_start
);
3626 if(result
!= KERN_SUCCESS
)
3628 if (dst_end
<= entry
->vme_end
)
3629 return KERN_SUCCESS
;
3630 vm_map_lock(dst_map
);
3631 if(!vm_map_lookup_entry(dst_map
, local_end
,
3633 vm_map_unlock(dst_map
);
3634 return(KERN_INVALID_ADDRESS
);
3637 next
= entry
->vme_next
;
3640 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
3641 vm_map_unlock(dst_map
);
3642 return(KERN_PROTECTION_FAILURE
);
3646 * If the entry is in transition, we must wait
3647 * for it to exit that state. Anything could happen
3648 * when we unlock the map, so start over.
3650 if (entry
->in_transition
) {
3653 * Say that we are waiting, and wait for entry.
3655 entry
->needs_wakeup
= TRUE
;
3656 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
3662 * our range is contained completely within this map entry
3664 if (dst_end
<= entry
->vme_end
) {
3665 vm_map_unlock(dst_map
);
3666 return KERN_SUCCESS
;
3669 * check that range specified is contiguous region
3671 if ((next
== vm_map_to_entry(dst_map
)) ||
3672 (next
->vme_start
!= entry
->vme_end
)) {
3673 vm_map_unlock(dst_map
);
3674 return(KERN_INVALID_ADDRESS
);
3678 * Check for permanent objects in the destination.
3680 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
3681 ((!entry
->object
.vm_object
->internal
) ||
3682 (entry
->object
.vm_object
->true_share
))) {
3683 if(encountered_sub_map
) {
3684 vm_map_unlock(dst_map
);
3685 return(KERN_FAILURE
);
3692 vm_map_unlock(dst_map
);
3693 return(KERN_SUCCESS
);
3697 * Routine: vm_map_copy_overwrite
3700 * Copy the memory described by the map copy
3701 * object (copy; returned by vm_map_copyin) onto
3702 * the specified destination region (dst_map, dst_addr).
3703 * The destination must be writeable.
3705 * Unlike vm_map_copyout, this routine actually
3706 * writes over previously-mapped memory. If the
3707 * previous mapping was to a permanent (user-supplied)
3708 * memory object, it is preserved.
3710 * The attributes (protection and inheritance) of the
3711 * destination region are preserved.
3713 * If successful, consumes the copy object.
3714 * Otherwise, the caller is responsible for it.
3716 * Implementation notes:
3717 * To overwrite aligned temporary virtual memory, it is
3718 * sufficient to remove the previous mapping and insert
3719 * the new copy. This replacement is done either on
3720 * the whole region (if no permanent virtual memory
3721 * objects are embedded in the destination region) or
3722 * in individual map entries.
3724 * To overwrite permanent virtual memory , it is necessary
3725 * to copy each page, as the external memory management
3726 * interface currently does not provide any optimizations.
3728 * Unaligned memory also has to be copied. It is possible
3729 * to use 'vm_trickery' to copy the aligned data. This is
3730 * not done but not hard to implement.
3732 * Once a page of permanent memory has been overwritten,
3733 * it is impossible to interrupt this function; otherwise,
3734 * the call would be neither atomic nor location-independent.
3735 * The kernel-state portion of a user thread must be
3738 * It may be expensive to forward all requests that might
3739 * overwrite permanent memory (vm_write, vm_copy) to
3740 * uninterruptible kernel threads. This routine may be
3741 * called by interruptible threads; however, success is
3742 * not guaranteed -- if the request cannot be performed
3743 * atomically and interruptibly, an error indication is
3748 vm_map_copy_overwrite_nested(
3750 vm_offset_t dst_addr
,
3752 boolean_t interruptible
,
3755 vm_offset_t dst_end
;
3756 vm_map_entry_t tmp_entry
;
3757 vm_map_entry_t entry
;
3759 boolean_t aligned
= TRUE
;
3760 boolean_t contains_permanent_objects
= FALSE
;
3761 boolean_t encountered_sub_map
= FALSE
;
3762 vm_offset_t base_addr
;
3763 vm_size_t copy_size
;
3764 vm_size_t total_size
;
3768 * Check for null copy object.
3771 if (copy
== VM_MAP_COPY_NULL
)
3772 return(KERN_SUCCESS
);
3775 * Check for special kernel buffer allocated
3776 * by new_ipc_kmsg_copyin.
3779 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
3780 return(vm_map_copyout_kernel_buffer(dst_map
, &dst_addr
,
3785 * Only works for entry lists at the moment. Will
3786 * support page lists later.
3789 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
3791 if (copy
->size
== 0) {
3792 vm_map_copy_discard(copy
);
3793 return(KERN_SUCCESS
);
3797 * Verify that the destination is all writeable
3798 * initially. We have to trunc the destination
3799 * address and round the copy size or we'll end up
3800 * splitting entries in strange ways.
3803 if (!page_aligned(copy
->size
) ||
3804 !page_aligned (copy
->offset
) ||
3805 !page_aligned (dst_addr
))
3808 dst_end
= round_page(dst_addr
+ copy
->size
);
3810 dst_end
= dst_addr
+ copy
->size
;
3814 vm_map_lock(dst_map
);
3815 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
3816 vm_map_unlock(dst_map
);
3817 return(KERN_INVALID_ADDRESS
);
3819 vm_map_clip_start(dst_map
, tmp_entry
, trunc_page(dst_addr
));
3820 for (entry
= tmp_entry
;;) {
3821 vm_map_entry_t next
= entry
->vme_next
;
3823 while(entry
->is_sub_map
) {
3824 vm_offset_t sub_start
;
3825 vm_offset_t sub_end
;
3826 vm_offset_t local_end
;
3828 if (entry
->in_transition
) {
3831 * Say that we are waiting, and wait for entry.
3833 entry
->needs_wakeup
= TRUE
;
3834 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
3839 local_end
= entry
->vme_end
;
3840 if (!(entry
->needs_copy
)) {
3841 /* if needs_copy we are a COW submap */
3842 /* in such a case we just replace so */
3843 /* there is no need for the follow- */
3845 encountered_sub_map
= TRUE
;
3846 sub_start
= entry
->offset
;
3848 if(entry
->vme_end
< dst_end
)
3849 sub_end
= entry
->vme_end
;
3852 sub_end
-= entry
->vme_start
;
3853 sub_end
+= entry
->offset
;
3854 vm_map_unlock(dst_map
);
3856 kr
= vm_map_overwrite_submap_recurse(
3857 entry
->object
.sub_map
,
3859 sub_end
- sub_start
);
3860 if(kr
!= KERN_SUCCESS
)
3862 vm_map_lock(dst_map
);
3865 if (dst_end
<= entry
->vme_end
)
3866 goto start_overwrite
;
3867 if(!vm_map_lookup_entry(dst_map
, local_end
,
3869 vm_map_unlock(dst_map
);
3870 return(KERN_INVALID_ADDRESS
);
3872 next
= entry
->vme_next
;
3875 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
3876 vm_map_unlock(dst_map
);
3877 return(KERN_PROTECTION_FAILURE
);
3881 * If the entry is in transition, we must wait
3882 * for it to exit that state. Anything could happen
3883 * when we unlock the map, so start over.
3885 if (entry
->in_transition
) {
3888 * Say that we are waiting, and wait for entry.
3890 entry
->needs_wakeup
= TRUE
;
3891 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
3897 * our range is contained completely within this map entry
3899 if (dst_end
<= entry
->vme_end
)
3902 * check that range specified is contiguous region
3904 if ((next
== vm_map_to_entry(dst_map
)) ||
3905 (next
->vme_start
!= entry
->vme_end
)) {
3906 vm_map_unlock(dst_map
);
3907 return(KERN_INVALID_ADDRESS
);
3912 * Check for permanent objects in the destination.
3914 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
3915 ((!entry
->object
.vm_object
->internal
) ||
3916 (entry
->object
.vm_object
->true_share
))) {
3917 contains_permanent_objects
= TRUE
;
3925 * If there are permanent objects in the destination, then
3926 * the copy cannot be interrupted.
3929 if (interruptible
&& contains_permanent_objects
) {
3930 vm_map_unlock(dst_map
);
3931 return(KERN_FAILURE
); /* XXX */
3936 * Make a second pass, overwriting the data
3937 * At the beginning of each loop iteration,
3938 * the next entry to be overwritten is "tmp_entry"
3939 * (initially, the value returned from the lookup above),
3940 * and the starting address expected in that entry
3944 total_size
= copy
->size
;
3945 if(encountered_sub_map
) {
3947 /* re-calculate tmp_entry since we've had the map */
3949 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
3950 vm_map_unlock(dst_map
);
3951 return(KERN_INVALID_ADDRESS
);
3954 copy_size
= copy
->size
;
3957 base_addr
= dst_addr
;
3959 /* deconstruct the copy object and do in parts */
3960 /* only in sub_map, interruptable case */
3961 vm_map_entry_t copy_entry
;
3962 vm_map_entry_t previous_prev
;
3963 vm_map_entry_t next_copy
;
3965 int remaining_entries
;
3968 for (entry
= tmp_entry
; copy_size
== 0;) {
3969 vm_map_entry_t next
;
3971 next
= entry
->vme_next
;
3973 /* tmp_entry and base address are moved along */
3974 /* each time we encounter a sub-map. Otherwise */
3975 /* entry can outpase tmp_entry, and the copy_size */
3976 /* may reflect the distance between them */
3977 /* if the current entry is found to be in transition */
3978 /* we will start over at the beginning or the last */
3979 /* encounter of a submap as dictated by base_addr */
3980 /* we will zero copy_size accordingly. */
3981 if (entry
->in_transition
) {
3983 * Say that we are waiting, and wait for entry.
3985 entry
->needs_wakeup
= TRUE
;
3986 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
3988 vm_map_lock(dst_map
);
3989 if(!vm_map_lookup_entry(dst_map
, base_addr
,
3991 vm_map_unlock(dst_map
);
3992 return(KERN_INVALID_ADDRESS
);
3998 if(entry
->is_sub_map
) {
3999 vm_offset_t sub_start
;
4000 vm_offset_t sub_end
;
4001 vm_offset_t local_end
;
4003 if (entry
->needs_copy
) {
4004 /* if this is a COW submap */
4005 /* just back the range with a */
4006 /* anonymous entry */
4007 if(entry
->vme_end
< dst_end
)
4008 sub_end
= entry
->vme_end
;
4011 if(entry
->vme_start
< base_addr
)
4012 sub_start
= base_addr
;
4014 sub_start
= entry
->vme_start
;
4016 dst_map
, entry
, sub_end
);
4018 dst_map
, entry
, sub_start
);
4019 entry
->is_sub_map
= FALSE
;
4021 entry
->object
.sub_map
);
4022 entry
->object
.sub_map
= NULL
;
4023 entry
->is_shared
= FALSE
;
4024 entry
->needs_copy
= FALSE
;
4026 entry
->protection
= VM_PROT_ALL
;
4027 entry
->max_protection
= VM_PROT_ALL
;
4028 entry
->wired_count
= 0;
4029 entry
->user_wired_count
= 0;
4030 if(entry
->inheritance
4031 == VM_INHERIT_SHARE
)
4032 entry
->inheritance
= VM_INHERIT_COPY
;
4035 /* first take care of any non-sub_map */
4036 /* entries to send */
4037 if(base_addr
< entry
->vme_start
) {
4040 entry
->vme_start
- base_addr
;
4043 sub_start
= entry
->offset
;
4045 if(entry
->vme_end
< dst_end
)
4046 sub_end
= entry
->vme_end
;
4049 sub_end
-= entry
->vme_start
;
4050 sub_end
+= entry
->offset
;
4051 local_end
= entry
->vme_end
;
4052 vm_map_unlock(dst_map
);
4053 copy_size
= sub_end
- sub_start
;
4055 /* adjust the copy object */
4056 if (total_size
> copy_size
) {
4057 vm_size_t local_size
= 0;
4058 vm_size_t entry_size
;
4061 new_offset
= copy
->offset
;
4062 copy_entry
= vm_map_copy_first_entry(copy
);
4064 vm_map_copy_to_entry(copy
)){
4065 entry_size
= copy_entry
->vme_end
-
4066 copy_entry
->vme_start
;
4067 if((local_size
< copy_size
) &&
4068 ((local_size
+ entry_size
)
4070 vm_map_copy_clip_end(copy
,
4072 copy_entry
->vme_start
+
4073 (copy_size
- local_size
));
4074 entry_size
= copy_entry
->vme_end
-
4075 copy_entry
->vme_start
;
4076 local_size
+= entry_size
;
4077 new_offset
+= entry_size
;
4079 if(local_size
>= copy_size
) {
4080 next_copy
= copy_entry
->vme_next
;
4081 copy_entry
->vme_next
=
4082 vm_map_copy_to_entry(copy
);
4084 copy
->cpy_hdr
.links
.prev
;
4085 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4086 copy
->size
= copy_size
;
4088 copy
->cpy_hdr
.nentries
;
4089 remaining_entries
-= nentries
;
4090 copy
->cpy_hdr
.nentries
= nentries
;
4093 local_size
+= entry_size
;
4094 new_offset
+= entry_size
;
4097 copy_entry
= copy_entry
->vme_next
;
4101 if((entry
->use_pmap
) && (pmap
== NULL
)) {
4102 kr
= vm_map_copy_overwrite_nested(
4103 entry
->object
.sub_map
,
4107 entry
->object
.sub_map
->pmap
);
4108 } else if (pmap
!= NULL
) {
4109 kr
= vm_map_copy_overwrite_nested(
4110 entry
->object
.sub_map
,
4113 interruptible
, pmap
);
4115 kr
= vm_map_copy_overwrite_nested(
4116 entry
->object
.sub_map
,
4122 if(kr
!= KERN_SUCCESS
) {
4123 if(next_copy
!= NULL
) {
4124 copy
->cpy_hdr
.nentries
+=
4126 copy
->cpy_hdr
.links
.prev
->vme_next
=
4128 copy
->cpy_hdr
.links
.prev
4130 copy
->size
= total_size
;
4134 if (dst_end
<= local_end
) {
4135 return(KERN_SUCCESS
);
4137 /* otherwise copy no longer exists, it was */
4138 /* destroyed after successful copy_overwrite */
4139 copy
= (vm_map_copy_t
)
4140 zalloc(vm_map_copy_zone
);
4141 vm_map_copy_first_entry(copy
) =
4142 vm_map_copy_last_entry(copy
) =
4143 vm_map_copy_to_entry(copy
);
4144 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
4145 copy
->offset
= new_offset
;
4147 total_size
-= copy_size
;
4149 /* put back remainder of copy in container */
4150 if(next_copy
!= NULL
) {
4151 copy
->cpy_hdr
.nentries
= remaining_entries
;
4152 copy
->cpy_hdr
.links
.next
= next_copy
;
4153 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4154 copy
->size
= total_size
;
4155 next_copy
->vme_prev
=
4156 vm_map_copy_to_entry(copy
);
4159 base_addr
= local_end
;
4160 vm_map_lock(dst_map
);
4161 if(!vm_map_lookup_entry(dst_map
,
4162 local_end
, &tmp_entry
)) {
4163 vm_map_unlock(dst_map
);
4164 return(KERN_INVALID_ADDRESS
);
4169 if (dst_end
<= entry
->vme_end
) {
4170 copy_size
= dst_end
- base_addr
;
4174 if ((next
== vm_map_to_entry(dst_map
)) ||
4175 (next
->vme_start
!= entry
->vme_end
)) {
4176 vm_map_unlock(dst_map
);
4177 return(KERN_INVALID_ADDRESS
);
4186 /* adjust the copy object */
4187 if (total_size
> copy_size
) {
4188 vm_size_t local_size
= 0;
4189 vm_size_t entry_size
;
4191 new_offset
= copy
->offset
;
4192 copy_entry
= vm_map_copy_first_entry(copy
);
4193 while(copy_entry
!= vm_map_copy_to_entry(copy
)) {
4194 entry_size
= copy_entry
->vme_end
-
4195 copy_entry
->vme_start
;
4196 if((local_size
< copy_size
) &&
4197 ((local_size
+ entry_size
)
4199 vm_map_copy_clip_end(copy
, copy_entry
,
4200 copy_entry
->vme_start
+
4201 (copy_size
- local_size
));
4202 entry_size
= copy_entry
->vme_end
-
4203 copy_entry
->vme_start
;
4204 local_size
+= entry_size
;
4205 new_offset
+= entry_size
;
4207 if(local_size
>= copy_size
) {
4208 next_copy
= copy_entry
->vme_next
;
4209 copy_entry
->vme_next
=
4210 vm_map_copy_to_entry(copy
);
4212 copy
->cpy_hdr
.links
.prev
;
4213 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4214 copy
->size
= copy_size
;
4216 copy
->cpy_hdr
.nentries
;
4217 remaining_entries
-= nentries
;
4218 copy
->cpy_hdr
.nentries
= nentries
;
4221 local_size
+= entry_size
;
4222 new_offset
+= entry_size
;
4225 copy_entry
= copy_entry
->vme_next
;
4235 local_pmap
= dst_map
->pmap
;
4237 if ((kr
= vm_map_copy_overwrite_aligned(
4238 dst_map
, tmp_entry
, copy
,
4239 base_addr
, local_pmap
)) != KERN_SUCCESS
) {
4240 if(next_copy
!= NULL
) {
4241 copy
->cpy_hdr
.nentries
+=
4243 copy
->cpy_hdr
.links
.prev
->vme_next
=
4245 copy
->cpy_hdr
.links
.prev
=
4247 copy
->size
+= copy_size
;
4251 vm_map_unlock(dst_map
);
4256 * if the copy and dst address are misaligned but the same
4257 * offset within the page we can copy_not_aligned the
4258 * misaligned parts and copy aligned the rest. If they are
4259 * aligned but len is unaligned we simply need to copy
4260 * the end bit unaligned. We'll need to split the misaligned
4261 * bits of the region in this case !
4263 /* ALWAYS UNLOCKS THE dst_map MAP */
4264 if ((kr
= vm_map_copy_overwrite_unaligned( dst_map
,
4265 tmp_entry
, copy
, base_addr
)) != KERN_SUCCESS
) {
4266 if(next_copy
!= NULL
) {
4267 copy
->cpy_hdr
.nentries
+=
4269 copy
->cpy_hdr
.links
.prev
->vme_next
=
4271 copy
->cpy_hdr
.links
.prev
=
4273 copy
->size
+= copy_size
;
4278 total_size
-= copy_size
;
4281 base_addr
+= copy_size
;
4283 copy
->offset
= new_offset
;
4284 if(next_copy
!= NULL
) {
4285 copy
->cpy_hdr
.nentries
= remaining_entries
;
4286 copy
->cpy_hdr
.links
.next
= next_copy
;
4287 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4288 next_copy
->vme_prev
= vm_map_copy_to_entry(copy
);
4289 copy
->size
= total_size
;
4291 vm_map_lock(dst_map
);
4293 if (!vm_map_lookup_entry(dst_map
,
4294 base_addr
, &tmp_entry
)) {
4295 vm_map_unlock(dst_map
);
4296 return(KERN_INVALID_ADDRESS
);
4298 if (tmp_entry
->in_transition
) {
4299 entry
->needs_wakeup
= TRUE
;
4300 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4305 vm_map_clip_start(dst_map
, tmp_entry
, trunc_page(base_addr
));
4311 * Throw away the vm_map_copy object
4313 vm_map_copy_discard(copy
);
4315 return(KERN_SUCCESS
);
4316 }/* vm_map_copy_overwrite */
4319 vm_map_copy_overwrite(
4321 vm_offset_t dst_addr
,
4323 boolean_t interruptible
)
4325 return vm_map_copy_overwrite_nested(
4326 dst_map
, dst_addr
, copy
, interruptible
, (pmap_t
) NULL
);
4331 * Routine: vm_map_copy_overwrite_unaligned
4334 * Physically copy unaligned data
4337 * Unaligned parts of pages have to be physically copied. We use
4338 * a modified form of vm_fault_copy (which understands none-aligned
4339 * page offsets and sizes) to do the copy. We attempt to copy as
4340 * much memory in one go as possibly, however vm_fault_copy copies
4341 * within 1 memory object so we have to find the smaller of "amount left"
4342 * "source object data size" and "target object data size". With
4343 * unaligned data we don't need to split regions, therefore the source
4344 * (copy) object should be one map entry, the target range may be split
4345 * over multiple map entries however. In any event we are pessimistic
4346 * about these assumptions.
4349 * dst_map is locked on entry and is return locked on success,
4350 * unlocked on error.
4354 vm_map_copy_overwrite_unaligned(
4356 vm_map_entry_t entry
,
4360 vm_map_entry_t copy_entry
= vm_map_copy_first_entry(copy
);
4361 vm_map_version_t version
;
4362 vm_object_t dst_object
;
4363 vm_object_offset_t dst_offset
;
4364 vm_object_offset_t src_offset
;
4365 vm_object_offset_t entry_offset
;
4366 vm_offset_t entry_end
;
4371 kern_return_t kr
= KERN_SUCCESS
;
4373 vm_map_lock_write_to_read(dst_map
);
4375 src_offset
= copy
->offset
- trunc_page_64(copy
->offset
);
4376 amount_left
= copy
->size
;
4378 * unaligned so we never clipped this entry, we need the offset into
4379 * the vm_object not just the data.
4381 while (amount_left
> 0) {
4383 if (entry
== vm_map_to_entry(dst_map
)) {
4384 vm_map_unlock_read(dst_map
);
4385 return KERN_INVALID_ADDRESS
;
4388 /* "start" must be within the current map entry */
4389 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
4391 dst_offset
= start
- entry
->vme_start
;
4393 dst_size
= entry
->vme_end
- start
;
4395 src_size
= copy_entry
->vme_end
-
4396 (copy_entry
->vme_start
+ src_offset
);
4398 if (dst_size
< src_size
) {
4400 * we can only copy dst_size bytes before
4401 * we have to get the next destination entry
4403 copy_size
= dst_size
;
4406 * we can only copy src_size bytes before
4407 * we have to get the next source copy entry
4409 copy_size
= src_size
;
4412 if (copy_size
> amount_left
) {
4413 copy_size
= amount_left
;
4416 * Entry needs copy, create a shadow shadow object for
4417 * Copy on write region.
4419 if (entry
->needs_copy
&&
4420 ((entry
->protection
& VM_PROT_WRITE
) != 0))
4422 if (vm_map_lock_read_to_write(dst_map
)) {
4423 vm_map_lock_read(dst_map
);
4426 vm_object_shadow(&entry
->object
.vm_object
,
4428 (vm_size_t
)(entry
->vme_end
4429 - entry
->vme_start
));
4430 entry
->needs_copy
= FALSE
;
4431 vm_map_lock_write_to_read(dst_map
);
4433 dst_object
= entry
->object
.vm_object
;
4435 * unlike with the virtual (aligned) copy we're going
4436 * to fault on it therefore we need a target object.
4438 if (dst_object
== VM_OBJECT_NULL
) {
4439 if (vm_map_lock_read_to_write(dst_map
)) {
4440 vm_map_lock_read(dst_map
);
4443 dst_object
= vm_object_allocate((vm_size_t
)
4444 entry
->vme_end
- entry
->vme_start
);
4445 entry
->object
.vm_object
= dst_object
;
4447 vm_map_lock_write_to_read(dst_map
);
4450 * Take an object reference and unlock map. The "entry" may
4451 * disappear or change when the map is unlocked.
4453 vm_object_reference(dst_object
);
4454 version
.main_timestamp
= dst_map
->timestamp
;
4455 entry_offset
= entry
->offset
;
4456 entry_end
= entry
->vme_end
;
4457 vm_map_unlock_read(dst_map
);
4459 * Copy as much as possible in one pass
4462 copy_entry
->object
.vm_object
,
4463 copy_entry
->offset
+ src_offset
,
4466 entry_offset
+ dst_offset
,
4472 src_offset
+= copy_size
;
4473 amount_left
-= copy_size
;
4475 * Release the object reference
4477 vm_object_deallocate(dst_object
);
4479 * If a hard error occurred, return it now
4481 if (kr
!= KERN_SUCCESS
)
4484 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
4485 || amount_left
== 0)
4488 * all done with this copy entry, dispose.
4490 vm_map_copy_entry_unlink(copy
, copy_entry
);
4491 vm_object_deallocate(copy_entry
->object
.vm_object
);
4492 vm_map_copy_entry_dispose(copy
, copy_entry
);
4494 if ((copy_entry
= vm_map_copy_first_entry(copy
))
4495 == vm_map_copy_to_entry(copy
) && amount_left
) {
4497 * not finished copying but run out of source
4499 return KERN_INVALID_ADDRESS
;
4504 if (amount_left
== 0)
4505 return KERN_SUCCESS
;
4507 vm_map_lock_read(dst_map
);
4508 if (version
.main_timestamp
== dst_map
->timestamp
) {
4509 if (start
== entry_end
) {
4511 * destination region is split. Use the version
4512 * information to avoid a lookup in the normal
4515 entry
= entry
->vme_next
;
4517 * should be contiguous. Fail if we encounter
4518 * a hole in the destination.
4520 if (start
!= entry
->vme_start
) {
4521 vm_map_unlock_read(dst_map
);
4522 return KERN_INVALID_ADDRESS
;
4527 * Map version check failed.
4528 * we must lookup the entry because somebody
4529 * might have changed the map behind our backs.
4532 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
4534 vm_map_unlock_read(dst_map
);
4535 return KERN_INVALID_ADDRESS
;
4541 vm_map_unlock_read(dst_map
);
4543 return KERN_SUCCESS
;
4544 }/* vm_map_copy_overwrite_unaligned */
4547 * Routine: vm_map_copy_overwrite_aligned
4550 * Does all the vm_trickery possible for whole pages.
4554 * If there are no permanent objects in the destination,
4555 * and the source and destination map entry zones match,
4556 * and the destination map entry is not shared,
4557 * then the map entries can be deleted and replaced
4558 * with those from the copy. The following code is the
4559 * basic idea of what to do, but there are lots of annoying
4560 * little details about getting protection and inheritance
4561 * right. Should add protection, inheritance, and sharing checks
4562 * to the above pass and make sure that no wiring is involved.
4566 vm_map_copy_overwrite_aligned(
4568 vm_map_entry_t tmp_entry
,
4574 vm_map_entry_t copy_entry
;
4575 vm_size_t copy_size
;
4577 vm_map_entry_t entry
;
4579 while ((copy_entry
= vm_map_copy_first_entry(copy
))
4580 != vm_map_copy_to_entry(copy
))
4582 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
4585 if (entry
== vm_map_to_entry(dst_map
)) {
4586 vm_map_unlock(dst_map
);
4587 return KERN_INVALID_ADDRESS
;
4589 size
= (entry
->vme_end
- entry
->vme_start
);
4591 * Make sure that no holes popped up in the
4592 * address map, and that the protection is
4593 * still valid, in case the map was unlocked
4597 if ((entry
->vme_start
!= start
) || ((entry
->is_sub_map
)
4598 && !entry
->needs_copy
)) {
4599 vm_map_unlock(dst_map
);
4600 return(KERN_INVALID_ADDRESS
);
4602 assert(entry
!= vm_map_to_entry(dst_map
));
4605 * Check protection again
4608 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4609 vm_map_unlock(dst_map
);
4610 return(KERN_PROTECTION_FAILURE
);
4614 * Adjust to source size first
4617 if (copy_size
< size
) {
4618 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
4623 * Adjust to destination size
4626 if (size
< copy_size
) {
4627 vm_map_copy_clip_end(copy
, copy_entry
,
4628 copy_entry
->vme_start
+ size
);
4632 assert((entry
->vme_end
- entry
->vme_start
) == size
);
4633 assert((tmp_entry
->vme_end
- tmp_entry
->vme_start
) == size
);
4634 assert((copy_entry
->vme_end
- copy_entry
->vme_start
) == size
);
4637 * If the destination contains temporary unshared memory,
4638 * we can perform the copy by throwing it away and
4639 * installing the source data.
4642 object
= entry
->object
.vm_object
;
4643 if ((!entry
->is_shared
&&
4644 ((object
== VM_OBJECT_NULL
) ||
4645 (object
->internal
&& !object
->true_share
))) ||
4646 entry
->needs_copy
) {
4647 vm_object_t old_object
= entry
->object
.vm_object
;
4648 vm_object_offset_t old_offset
= entry
->offset
;
4649 vm_object_offset_t offset
;
4652 * Ensure that the source and destination aren't
4655 if (old_object
== copy_entry
->object
.vm_object
&&
4656 old_offset
== copy_entry
->offset
) {
4657 vm_map_copy_entry_unlink(copy
, copy_entry
);
4658 vm_map_copy_entry_dispose(copy
, copy_entry
);
4660 if (old_object
!= VM_OBJECT_NULL
)
4661 vm_object_deallocate(old_object
);
4663 start
= tmp_entry
->vme_end
;
4664 tmp_entry
= tmp_entry
->vme_next
;
4668 if (old_object
!= VM_OBJECT_NULL
) {
4669 if(entry
->is_sub_map
) {
4670 if(entry
->use_pmap
) {
4672 pmap_unnest(dst_map
->pmap
,
4674 entry
->vme_end
- entry
->vme_start
);
4677 vm_map_submap_pmap_clean(
4678 dst_map
, entry
->vme_start
,
4680 entry
->object
.sub_map
,
4684 entry
->object
.sub_map
);
4686 vm_object_pmap_protect(
4691 tmp_entry
->vme_start
,
4694 vm_object_deallocate(old_object
);
4698 entry
->is_sub_map
= FALSE
;
4699 entry
->object
= copy_entry
->object
;
4700 object
= entry
->object
.vm_object
;
4701 entry
->needs_copy
= copy_entry
->needs_copy
;
4702 entry
->wired_count
= 0;
4703 entry
->user_wired_count
= 0;
4704 offset
= entry
->offset
= copy_entry
->offset
;
4706 vm_map_copy_entry_unlink(copy
, copy_entry
);
4707 vm_map_copy_entry_dispose(copy
, copy_entry
);
4708 #if BAD_OPTIMIZATION
4710 * if we turn this optimization back on
4711 * we need to revisit our use of pmap mappings
4712 * large copies will cause us to run out and panic
4713 * this optimization only saved on average 2 us per page if ALL
4714 * the pages in the source were currently mapped
4715 * and ALL the pages in the dest were touched, if there were fewer
4716 * than 2/3 of the pages touched, this optimization actually cost more cycles
4720 * Try to aggressively enter physical mappings
4721 * (but avoid uninstantiated objects)
4723 if (object
!= VM_OBJECT_NULL
) {
4724 vm_offset_t va
= entry
->vme_start
;
4726 while (va
< entry
->vme_end
) {
4727 register vm_page_t m
;
4731 * Look for the page in the top object
4733 prot
= entry
->protection
;
4734 vm_object_lock(object
);
4735 vm_object_paging_begin(object
);
4737 if ((m
= vm_page_lookup(object
,offset
)) !=
4738 VM_PAGE_NULL
&& !m
->busy
&&
4740 (!m
->unusual
|| (!m
->error
&&
4741 !m
->restart
&& !m
->absent
&&
4742 (prot
& m
->page_lock
) == 0))) {
4745 vm_object_unlock(object
);
4748 * Honor COW obligations
4750 if (entry
->needs_copy
)
4751 prot
&= ~VM_PROT_WRITE
;
4753 PMAP_ENTER(pmap
, va
, m
,
4756 vm_object_lock(object
);
4757 vm_page_lock_queues();
4758 if (!m
->active
&& !m
->inactive
)
4759 vm_page_activate(m
);
4760 vm_page_unlock_queues();
4761 PAGE_WAKEUP_DONE(m
);
4763 vm_object_paging_end(object
);
4764 vm_object_unlock(object
);
4766 offset
+= PAGE_SIZE_64
;
4768 } /* end while (va < entry->vme_end) */
4769 } /* end if (object) */
4772 * Set up for the next iteration. The map
4773 * has not been unlocked, so the next
4774 * address should be at the end of this
4775 * entry, and the next map entry should be
4776 * the one following it.
4779 start
= tmp_entry
->vme_end
;
4780 tmp_entry
= tmp_entry
->vme_next
;
4782 vm_map_version_t version
;
4783 vm_object_t dst_object
= entry
->object
.vm_object
;
4784 vm_object_offset_t dst_offset
= entry
->offset
;
4788 * Take an object reference, and record
4789 * the map version information so that the
4790 * map can be safely unlocked.
4793 vm_object_reference(dst_object
);
4795 version
.main_timestamp
= dst_map
->timestamp
;
4797 vm_map_unlock(dst_map
);
4800 * Copy as much as possible in one pass
4805 copy_entry
->object
.vm_object
,
4815 * Release the object reference
4818 vm_object_deallocate(dst_object
);
4821 * If a hard error occurred, return it now
4824 if (r
!= KERN_SUCCESS
)
4827 if (copy_size
!= 0) {
4829 * Dispose of the copied region
4832 vm_map_copy_clip_end(copy
, copy_entry
,
4833 copy_entry
->vme_start
+ copy_size
);
4834 vm_map_copy_entry_unlink(copy
, copy_entry
);
4835 vm_object_deallocate(copy_entry
->object
.vm_object
);
4836 vm_map_copy_entry_dispose(copy
, copy_entry
);
4840 * Pick up in the destination map where we left off.
4842 * Use the version information to avoid a lookup
4843 * in the normal case.
4847 vm_map_lock(dst_map
);
4848 if ((version
.main_timestamp
+ 1) == dst_map
->timestamp
) {
4849 /* We can safely use saved tmp_entry value */
4851 vm_map_clip_end(dst_map
, tmp_entry
, start
);
4852 tmp_entry
= tmp_entry
->vme_next
;
4854 /* Must do lookup of tmp_entry */
4856 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
4857 vm_map_unlock(dst_map
);
4858 return(KERN_INVALID_ADDRESS
);
4860 vm_map_clip_start(dst_map
, tmp_entry
, start
);
4865 return(KERN_SUCCESS
);
4866 }/* vm_map_copy_overwrite_aligned */
4869 * Routine: vm_map_copyin_kernel_buffer
4872 * Copy in data to a kernel buffer from space in the
4873 * source map. The original space may be otpionally
4876 * If successful, returns a new copy object.
4879 vm_map_copyin_kernel_buffer(
4881 vm_offset_t src_addr
,
4883 boolean_t src_destroy
,
4884 vm_map_copy_t
*copy_result
)
4888 vm_size_t kalloc_size
= sizeof(struct vm_map_copy
) + len
;
4890 copy
= (vm_map_copy_t
) kalloc(kalloc_size
);
4891 if (copy
== VM_MAP_COPY_NULL
) {
4892 return KERN_RESOURCE_SHORTAGE
;
4894 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
4897 copy
->cpy_kdata
= (vm_offset_t
) (copy
+ 1);
4898 copy
->cpy_kalloc_size
= kalloc_size
;
4900 if (src_map
== kernel_map
) {
4901 bcopy((char *)src_addr
, (char *)copy
->cpy_kdata
, len
);
4902 flags
= VM_MAP_REMOVE_KUNWIRE
| VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
4903 VM_MAP_REMOVE_INTERRUPTIBLE
;
4906 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, len
);
4907 if (kr
!= KERN_SUCCESS
) {
4908 kfree((vm_offset_t
)copy
, kalloc_size
);
4911 flags
= VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
4912 VM_MAP_REMOVE_INTERRUPTIBLE
;
4915 (void) vm_map_remove(src_map
, trunc_page(src_addr
),
4916 round_page(src_addr
+ len
),
4919 *copy_result
= copy
;
4920 return KERN_SUCCESS
;
4924 * Routine: vm_map_copyout_kernel_buffer
4927 * Copy out data from a kernel buffer into space in the
4928 * destination map. The space may be otpionally dynamically
4931 * If successful, consumes the copy object.
4932 * Otherwise, the caller is responsible for it.
4935 vm_map_copyout_kernel_buffer(
4937 vm_offset_t
*addr
, /* IN/OUT */
4939 boolean_t overwrite
)
4941 kern_return_t kr
= KERN_SUCCESS
;
4942 thread_act_t thr_act
= current_act();
4947 * Allocate space in the target map for the data
4950 kr
= vm_map_enter(map
,
4952 round_page(copy
->size
),
4956 (vm_object_offset_t
) 0,
4960 VM_INHERIT_DEFAULT
);
4961 if (kr
!= KERN_SUCCESS
)
4966 * Copyout the data from the kernel buffer to the target map.
4968 if (thr_act
->map
== map
) {
4971 * If the target map is the current map, just do
4974 if (copyout((char *)copy
->cpy_kdata
, (char *)*addr
,
4976 kr
= KERN_INVALID_ADDRESS
;
4983 * If the target map is another map, assume the
4984 * target's address space identity for the duration
4987 vm_map_reference(map
);
4988 oldmap
= vm_map_switch(map
);
4990 if (copyout((char *)copy
->cpy_kdata
, (char *)*addr
,
4992 kr
= KERN_INVALID_ADDRESS
;
4995 (void) vm_map_switch(oldmap
);
4996 vm_map_deallocate(map
);
4999 kfree((vm_offset_t
)copy
, copy
->cpy_kalloc_size
);
5005 * Macro: vm_map_copy_insert
5008 * Link a copy chain ("copy") into a map at the
5009 * specified location (after "where").
5011 * The copy chain is destroyed.
5013 * The arguments are evaluated multiple times.
5015 #define vm_map_copy_insert(map, where, copy) \
5017 vm_map_t VMCI_map; \
5018 vm_map_entry_t VMCI_where; \
5019 vm_map_copy_t VMCI_copy; \
5021 VMCI_where = (where); \
5022 VMCI_copy = (copy); \
5023 ((VMCI_where->vme_next)->vme_prev = vm_map_copy_last_entry(VMCI_copy))\
5024 ->vme_next = (VMCI_where->vme_next); \
5025 ((VMCI_where)->vme_next = vm_map_copy_first_entry(VMCI_copy)) \
5026 ->vme_prev = VMCI_where; \
5027 VMCI_map->hdr.nentries += VMCI_copy->cpy_hdr.nentries; \
5028 UPDATE_FIRST_FREE(VMCI_map, VMCI_map->first_free); \
5029 zfree(vm_map_copy_zone, (vm_offset_t) VMCI_copy); \
5033 * Routine: vm_map_copyout
5036 * Copy out a copy chain ("copy") into newly-allocated
5037 * space in the destination map.
5039 * If successful, consumes the copy object.
5040 * Otherwise, the caller is responsible for it.
5044 register vm_map_t dst_map
,
5045 vm_offset_t
*dst_addr
, /* OUT */
5046 register vm_map_copy_t copy
)
5049 vm_size_t adjustment
;
5051 vm_object_offset_t vm_copy_start
;
5052 vm_map_entry_t last
;
5054 vm_map_entry_t entry
;
5057 * Check for null copy object.
5060 if (copy
== VM_MAP_COPY_NULL
) {
5062 return(KERN_SUCCESS
);
5066 * Check for special copy object, created
5067 * by vm_map_copyin_object.
5070 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
5071 vm_object_t object
= copy
->cpy_object
;
5073 vm_object_offset_t offset
;
5075 offset
= trunc_page_64(copy
->offset
);
5076 size
= round_page(copy
->size
+
5077 (vm_size_t
)(copy
->offset
- offset
));
5079 kr
= vm_map_enter(dst_map
, dst_addr
, size
,
5080 (vm_offset_t
) 0, TRUE
,
5081 object
, offset
, FALSE
,
5082 VM_PROT_DEFAULT
, VM_PROT_ALL
,
5083 VM_INHERIT_DEFAULT
);
5084 if (kr
!= KERN_SUCCESS
)
5086 /* Account for non-pagealigned copy object */
5087 *dst_addr
+= (vm_offset_t
)(copy
->offset
- offset
);
5088 zfree(vm_map_copy_zone
, (vm_offset_t
) copy
);
5089 return(KERN_SUCCESS
);
5093 * Check for special kernel buffer allocated
5094 * by new_ipc_kmsg_copyin.
5097 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
5098 return(vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
5102 if (copy
->type
== VM_MAP_COPY_PAGE_LIST
)
5103 return(vm_map_copyout_page_list(dst_map
, dst_addr
, copy
));
5106 * Find space for the data
5109 vm_copy_start
= trunc_page_64(copy
->offset
);
5110 size
= round_page((vm_size_t
)copy
->offset
+ copy
->size
)
5115 vm_map_lock(dst_map
);
5116 assert(first_free_is_valid(dst_map
));
5117 start
= ((last
= dst_map
->first_free
) == vm_map_to_entry(dst_map
)) ?
5118 vm_map_min(dst_map
) : last
->vme_end
;
5121 vm_map_entry_t next
= last
->vme_next
;
5122 vm_offset_t end
= start
+ size
;
5124 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
5125 if (dst_map
->wait_for_space
) {
5126 if (size
<= (dst_map
->max_offset
- dst_map
->min_offset
)) {
5127 assert_wait((event_t
) dst_map
,
5128 THREAD_INTERRUPTIBLE
);
5129 vm_map_unlock(dst_map
);
5130 thread_block((void (*)(void))0);
5134 vm_map_unlock(dst_map
);
5135 return(KERN_NO_SPACE
);
5138 if ((next
== vm_map_to_entry(dst_map
)) ||
5139 (next
->vme_start
>= end
))
5143 start
= last
->vme_end
;
5147 * Since we're going to just drop the map
5148 * entries from the copy into the destination
5149 * map, they must come from the same pool.
5152 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
5154 * Mismatches occur when dealing with the default
5158 vm_map_entry_t next
, new;
5161 * Find the zone that the copies were allocated from
5163 old_zone
= (copy
->cpy_hdr
.entries_pageable
)
5165 : vm_map_kentry_zone
;
5166 entry
= vm_map_copy_first_entry(copy
);
5169 * Reinitialize the copy so that vm_map_copy_entry_link
5172 copy
->cpy_hdr
.nentries
= 0;
5173 copy
->cpy_hdr
.entries_pageable
= dst_map
->hdr
.entries_pageable
;
5174 vm_map_copy_first_entry(copy
) =
5175 vm_map_copy_last_entry(copy
) =
5176 vm_map_copy_to_entry(copy
);
5181 while (entry
!= vm_map_copy_to_entry(copy
)) {
5182 new = vm_map_copy_entry_create(copy
);
5183 vm_map_entry_copy_full(new, entry
);
5184 new->use_pmap
= FALSE
; /* clr address space specifics */
5185 vm_map_copy_entry_link(copy
,
5186 vm_map_copy_last_entry(copy
),
5188 next
= entry
->vme_next
;
5189 zfree(old_zone
, (vm_offset_t
) entry
);
5195 * Adjust the addresses in the copy chain, and
5196 * reset the region attributes.
5199 adjustment
= start
- vm_copy_start
;
5200 for (entry
= vm_map_copy_first_entry(copy
);
5201 entry
!= vm_map_copy_to_entry(copy
);
5202 entry
= entry
->vme_next
) {
5203 entry
->vme_start
+= adjustment
;
5204 entry
->vme_end
+= adjustment
;
5206 entry
->inheritance
= VM_INHERIT_DEFAULT
;
5207 entry
->protection
= VM_PROT_DEFAULT
;
5208 entry
->max_protection
= VM_PROT_ALL
;
5209 entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
5212 * If the entry is now wired,
5213 * map the pages into the destination map.
5215 if (entry
->wired_count
!= 0) {
5216 register vm_offset_t va
;
5217 vm_object_offset_t offset
;
5218 register vm_object_t object
;
5220 object
= entry
->object
.vm_object
;
5221 offset
= entry
->offset
;
5222 va
= entry
->vme_start
;
5224 pmap_pageable(dst_map
->pmap
,
5229 while (va
< entry
->vme_end
) {
5230 register vm_page_t m
;
5233 * Look up the page in the object.
5234 * Assert that the page will be found in the
5237 * the object was newly created by
5238 * vm_object_copy_slowly, and has
5239 * copies of all of the pages from
5242 * the object was moved from the old
5243 * map entry; because the old map
5244 * entry was wired, all of the pages
5245 * were in the top-level object.
5246 * (XXX not true if we wire pages for
5249 vm_object_lock(object
);
5250 vm_object_paging_begin(object
);
5252 m
= vm_page_lookup(object
, offset
);
5253 if (m
== VM_PAGE_NULL
|| m
->wire_count
== 0 ||
5255 panic("vm_map_copyout: wiring 0x%x", m
);
5258 vm_object_unlock(object
);
5260 PMAP_ENTER(dst_map
->pmap
, va
, m
,
5261 entry
->protection
, TRUE
);
5263 vm_object_lock(object
);
5264 PAGE_WAKEUP_DONE(m
);
5265 /* the page is wired, so we don't have to activate */
5266 vm_object_paging_end(object
);
5267 vm_object_unlock(object
);
5269 offset
+= PAGE_SIZE_64
;
5273 else if (size
<= vm_map_aggressive_enter_max
) {
5275 register vm_offset_t va
;
5276 vm_object_offset_t offset
;
5277 register vm_object_t object
;
5280 object
= entry
->object
.vm_object
;
5281 if (object
!= VM_OBJECT_NULL
) {
5283 offset
= entry
->offset
;
5284 va
= entry
->vme_start
;
5285 while (va
< entry
->vme_end
) {
5286 register vm_page_t m
;
5289 * Look up the page in the object.
5290 * Assert that the page will be found
5291 * in the top object if at all...
5293 vm_object_lock(object
);
5294 vm_object_paging_begin(object
);
5296 if (((m
= vm_page_lookup(object
,
5299 !m
->busy
&& !m
->fictitious
&&
5300 !m
->absent
&& !m
->error
) {
5302 vm_object_unlock(object
);
5304 /* honor cow obligations */
5305 prot
= entry
->protection
;
5306 if (entry
->needs_copy
)
5307 prot
&= ~VM_PROT_WRITE
;
5309 PMAP_ENTER(dst_map
->pmap
, va
,
5312 vm_object_lock(object
);
5313 vm_page_lock_queues();
5314 if (!m
->active
&& !m
->inactive
)
5315 vm_page_activate(m
);
5316 vm_page_unlock_queues();
5317 PAGE_WAKEUP_DONE(m
);
5319 vm_object_paging_end(object
);
5320 vm_object_unlock(object
);
5322 offset
+= PAGE_SIZE_64
;
5330 * Correct the page alignment for the result
5333 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
5336 * Update the hints and the map size
5339 SAVE_HINT(dst_map
, vm_map_copy_last_entry(copy
));
5341 dst_map
->size
+= size
;
5347 vm_map_copy_insert(dst_map
, last
, copy
);
5349 vm_map_unlock(dst_map
);
5352 * XXX If wiring_required, call vm_map_pageable
5355 return(KERN_SUCCESS
);
5358 boolean_t vm_map_aggressive_enter
; /* not used yet */
5362 * vm_map_copyout_page_list:
5364 * Version of vm_map_copyout() for page list vm map copies.
5368 vm_map_copyout_page_list(
5369 register vm_map_t dst_map
,
5370 vm_offset_t
*dst_addr
, /* OUT */
5371 register vm_map_copy_t copy
)
5376 vm_object_offset_t offset
;
5377 vm_map_entry_t last
;
5380 vm_page_t
*page_list
, m
;
5381 vm_map_entry_t entry
;
5382 vm_object_offset_t old_last_offset
;
5383 boolean_t cont_invoked
, needs_wakeup
;
5384 kern_return_t result
= KERN_SUCCESS
;
5385 vm_map_copy_t orig_copy
;
5386 vm_object_offset_t dst_offset
;
5387 boolean_t must_wire
;
5388 boolean_t aggressive_enter
;
5391 * Check for null copy object.
5394 if (copy
== VM_MAP_COPY_NULL
) {
5396 return(KERN_SUCCESS
);
5399 assert(copy
->type
== VM_MAP_COPY_PAGE_LIST
);
5402 * Make sure the pages are stolen, because we are
5403 * going to put them in a new object. Assume that
5404 * all pages are identical to first in this regard.
5407 page_list
= ©
->cpy_page_list
[0];
5408 if (!copy
->cpy_page_loose
)
5409 vm_map_copy_steal_pages(copy
);
5412 * Find space for the data
5415 size
= round_page_64(copy
->offset
+ (vm_object_offset_t
)copy
->size
) -
5416 trunc_page_64(copy
->offset
);
5418 vm_map_lock(dst_map
);
5419 must_wire
= dst_map
->wiring_required
;
5421 assert(first_free_is_valid(dst_map
));
5422 last
= dst_map
->first_free
;
5423 if (last
== vm_map_to_entry(dst_map
)) {
5424 start
= vm_map_min(dst_map
);
5426 start
= last
->vme_end
;
5430 vm_map_entry_t next
= last
->vme_next
;
5433 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
5434 if (dst_map
->wait_for_space
) {
5435 if (size
<= (dst_map
->max_offset
-
5436 dst_map
->min_offset
)) {
5437 assert_wait((event_t
) dst_map
,
5438 THREAD_INTERRUPTIBLE
);
5439 vm_map_unlock(dst_map
);
5440 thread_block((void (*)(void))0);
5444 vm_map_unlock(dst_map
);
5445 return(KERN_NO_SPACE
);
5448 if ((next
== vm_map_to_entry(dst_map
)) ||
5449 (next
->vme_start
>= end
)) {
5454 start
= last
->vme_end
;
5458 * See whether we can avoid creating a new entry (and object) by
5459 * extending one of our neighbors. [So far, we only attempt to
5460 * extend from below.]
5462 * The code path below here is a bit twisted. If any of the
5463 * extension checks fails, we branch to create_object. If
5464 * it all works, we fall out the bottom and goto insert_pages.
5466 if (last
== vm_map_to_entry(dst_map
) ||
5467 last
->vme_end
!= start
||
5468 last
->is_shared
!= FALSE
||
5469 last
->is_sub_map
!= FALSE
||
5470 last
->inheritance
!= VM_INHERIT_DEFAULT
||
5471 last
->protection
!= VM_PROT_DEFAULT
||
5472 last
->max_protection
!= VM_PROT_ALL
||
5473 last
->behavior
!= VM_BEHAVIOR_DEFAULT
||
5474 last
->in_transition
||
5475 (must_wire
? (last
->wired_count
!= 1 ||
5476 last
->user_wired_count
!= 0) :
5477 (last
->wired_count
!= 0))) {
5482 * If this entry needs an object, make one.
5484 if (last
->object
.vm_object
== VM_OBJECT_NULL
) {
5485 object
= vm_object_allocate(
5486 (vm_size_t
)(last
->vme_end
- last
->vme_start
+ size
));
5487 last
->object
.vm_object
= object
;
5491 vm_object_offset_t prev_offset
= last
->offset
;
5492 vm_size_t prev_size
= start
- last
->vme_start
;
5496 * This is basically vm_object_coalesce.
5499 object
= last
->object
.vm_object
;
5500 vm_object_lock(object
);
5503 * Try to collapse the object first
5505 vm_object_collapse(object
);
5509 * Can't coalesce if pages not mapped to
5510 * last may be in use anyway:
5511 * . more than one reference
5513 * . shadows another object
5514 * . has a copy elsewhere
5515 * . paging references (pages might be in page-list)
5518 if ((object
->ref_count
> 1) ||
5519 object
->pager_created
||
5520 (object
->shadow
!= VM_OBJECT_NULL
) ||
5521 (object
->copy
!= VM_OBJECT_NULL
) ||
5522 (object
->paging_in_progress
!= 0)) {
5523 vm_object_unlock(object
);
5528 * Extend the object if necessary. Don't have to call
5529 * vm_object_page_remove because the pages aren't mapped,
5530 * and vm_page_replace will free up any old ones it encounters.
5532 new_size
= prev_offset
+ prev_size
+ size
;
5533 if (new_size
> object
->size
) {
5536 * We cannot extend an object that has existence info,
5537 * since the existence info might then fail to cover
5538 * the entire object.
5540 * This assertion must be true because the object
5541 * has no pager, and we only create existence info
5542 * for objects with pagers.
5544 assert(object
->existence_map
== VM_EXTERNAL_NULL
);
5545 #endif /* MACH_PAGEMAP */
5546 object
->size
= new_size
;
5548 vm_object_unlock(object
);
5552 * Coalesced the two objects - can extend
5553 * the previous map entry to include the
5556 dst_map
->size
+= size
;
5557 last
->vme_end
= end
;
5558 UPDATE_FIRST_FREE(dst_map
, dst_map
->first_free
);
5560 SAVE_HINT(dst_map
, last
);
5569 object
= vm_object_allocate(size
);
5574 last
= vm_map_entry_insert(dst_map
, last
, start
, start
+ size
,
5575 object
, 0, FALSE
, FALSE
, TRUE
,
5576 VM_PROT_DEFAULT
, VM_PROT_ALL
,
5577 VM_BEHAVIOR_DEFAULT
,
5578 VM_INHERIT_DEFAULT
, (must_wire
? 1 : 0));
5581 * Transfer pages into new object.
5582 * Scan page list in vm_map_copy.
5585 dst_offset
= copy
->offset
& PAGE_MASK_64
;
5586 cont_invoked
= FALSE
;
5588 last
->in_transition
= TRUE
;
5589 old_last_offset
= last
->offset
5590 + (start
- last
->vme_start
);
5592 aggressive_enter
= (size
<= vm_map_aggressive_enter_max
);
5594 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE_64
) {
5596 assert(m
&& !m
->tabled
);
5599 * Must clear busy bit in page before inserting it.
5600 * Ok to skip wakeup logic because nobody else
5601 * can possibly know about this page. Also set
5602 * dirty bit on the assumption that the page is
5603 * not a page of zeros.
5608 vm_object_lock(object
);
5609 vm_page_lock_queues();
5610 vm_page_replace(m
, object
, old_last_offset
+ offset
);
5613 } else if (aggressive_enter
) {
5614 vm_page_activate(m
);
5616 vm_page_unlock_queues();
5617 vm_object_unlock(object
);
5619 if (aggressive_enter
|| must_wire
) {
5620 PMAP_ENTER(dst_map
->pmap
,
5621 last
->vme_start
+ m
->offset
- last
->offset
,
5622 m
, last
->protection
, must_wire
);
5625 *page_list
++ = VM_PAGE_NULL
;
5626 assert(copy
!= VM_MAP_COPY_NULL
);
5627 assert(copy
->type
== VM_MAP_COPY_PAGE_LIST
);
5628 if (--(copy
->cpy_npages
) == 0 &&
5629 vm_map_copy_has_cont(copy
)) {
5630 vm_map_copy_t new_copy
;
5633 * Ok to unlock map because entry is
5634 * marked in_transition.
5636 cont_invoked
= TRUE
;
5637 vm_map_unlock(dst_map
);
5638 vm_map_copy_invoke_cont(copy
, &new_copy
, &result
);
5640 if (result
== KERN_SUCCESS
) {
5643 * If we got back a copy with real pages,
5644 * steal them now. Either all of the
5645 * pages in the list are tabled or none
5646 * of them are; mixtures are not possible.
5648 * Save original copy for consume on
5649 * success logic at end of routine.
5651 if (copy
!= orig_copy
)
5652 vm_map_copy_discard(copy
);
5654 if ((copy
= new_copy
) != VM_MAP_COPY_NULL
) {
5655 page_list
= ©
->cpy_page_list
[0];
5656 if (!copy
->cpy_page_loose
)
5657 vm_map_copy_steal_pages(copy
);
5662 * Continuation failed.
5664 vm_map_lock(dst_map
);
5668 vm_map_lock(dst_map
);
5672 *dst_addr
= start
+ dst_offset
;
5675 * Clear the in transition bits. This is easy if we
5676 * didn't have a continuation.
5679 needs_wakeup
= FALSE
;
5680 if (!cont_invoked
) {
5682 * We didn't unlock the map, so nobody could
5685 last
->in_transition
= FALSE
;
5686 assert(!last
->needs_wakeup
);
5689 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
5690 panic("vm_map_copyout_page_list: missing entry");
5693 * Clear transition bit for all constituent entries that
5694 * were in the original entry. Also check for waiters.
5696 while ((entry
!= vm_map_to_entry(dst_map
)) &&
5697 (entry
->vme_start
< end
)) {
5698 assert(entry
->in_transition
);
5699 entry
->in_transition
= FALSE
;
5700 if (entry
->needs_wakeup
) {
5701 entry
->needs_wakeup
= FALSE
;
5702 needs_wakeup
= TRUE
;
5704 entry
= entry
->vme_next
;
5708 if (result
!= KERN_SUCCESS
)
5709 (void) vm_map_delete(dst_map
, start
, end
, VM_MAP_NO_FLAGS
);
5711 vm_map_unlock(dst_map
);
5714 vm_map_entry_wakeup(dst_map
);
5717 * Consume on success logic.
5719 if (copy
!= VM_MAP_COPY_NULL
&& copy
!= orig_copy
) {
5720 zfree(vm_map_copy_zone
, (vm_offset_t
) copy
);
5722 if (result
== KERN_SUCCESS
) {
5723 assert(orig_copy
!= VM_MAP_COPY_NULL
);
5724 assert(orig_copy
->type
== VM_MAP_COPY_PAGE_LIST
);
5725 zfree(vm_map_copy_zone
, (vm_offset_t
) orig_copy
);
5732 * Routine: vm_map_copyin
5735 * Copy the specified region (src_addr, len) from the
5736 * source address space (src_map), possibly removing
5737 * the region from the source address space (src_destroy).
5740 * A vm_map_copy_t object (copy_result), suitable for
5741 * insertion into another address space (using vm_map_copyout),
5742 * copying over another address space region (using
5743 * vm_map_copy_overwrite). If the copy is unused, it
5744 * should be destroyed (using vm_map_copy_discard).
5746 * In/out conditions:
5747 * The source map should not be locked on entry.
5750 typedef struct submap_map
{
5751 vm_map_t parent_map
;
5752 vm_offset_t base_start
;
5753 vm_offset_t base_end
;
5754 struct submap_map
*next
;
5758 vm_map_copyin_common(
5760 vm_offset_t src_addr
,
5762 boolean_t src_destroy
,
5763 boolean_t src_volatile
,
5764 vm_map_copy_t
*copy_result
, /* OUT */
5765 boolean_t use_maxprot
)
5767 extern int msg_ool_size_small
;
5769 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
5770 * in multi-level lookup, this
5771 * entry contains the actual
5775 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
5777 vm_offset_t src_start
; /* Start of current entry --
5778 * where copy is taking place now
5780 vm_offset_t src_end
; /* End of entire region to be
5782 vm_offset_t base_start
; /* submap fields to save offsets */
5783 /* in original map */
5784 vm_offset_t base_end
;
5785 vm_map_t base_map
=src_map
;
5786 vm_map_entry_t base_entry
;
5787 boolean_t map_share
=FALSE
;
5788 submap_map_t
*parent_maps
= NULL
;
5791 vm_map_copy_t copy
; /* Resulting copy */
5792 vm_offset_t copy_addr
;
5795 * Check for copies of zero bytes.
5799 *copy_result
= VM_MAP_COPY_NULL
;
5800 return(KERN_SUCCESS
);
5804 * If the copy is sufficiently small, use a kernel buffer instead
5805 * of making a virtual copy. The theory being that the cost of
5806 * setting up VM (and taking C-O-W faults) dominates the copy costs
5807 * for small regions.
5809 if ((len
< msg_ool_size_small
) && !use_maxprot
)
5810 return vm_map_copyin_kernel_buffer(src_map
, src_addr
, len
,
5811 src_destroy
, copy_result
);
5814 * Compute start and end of region
5817 src_start
= trunc_page(src_addr
);
5818 src_end
= round_page(src_addr
+ len
);
5820 XPR(XPR_VM_MAP
, "vm_map_copyin_common map 0x%x addr 0x%x len 0x%x dest %d\n", (natural_t
)src_map
, src_addr
, len
, src_destroy
, 0);
5823 * Check that the end address doesn't overflow
5826 if (src_end
<= src_start
)
5827 if ((src_end
< src_start
) || (src_start
!= 0))
5828 return(KERN_INVALID_ADDRESS
);
5831 * Allocate a header element for the list.
5833 * Use the start and end in the header to
5834 * remember the endpoints prior to rounding.
5837 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
5838 vm_map_copy_first_entry(copy
) =
5839 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
5840 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
5841 copy
->cpy_hdr
.nentries
= 0;
5842 copy
->cpy_hdr
.entries_pageable
= TRUE
;
5844 copy
->offset
= src_addr
;
5847 new_entry
= vm_map_copy_entry_create(copy
);
5851 vm_map_unlock(src_map); \
5852 if (new_entry != VM_MAP_ENTRY_NULL) \
5853 vm_map_copy_entry_dispose(copy,new_entry); \
5854 vm_map_copy_discard(copy); \
5856 submap_map_t *ptr; \
5858 for(ptr = parent_maps; ptr != NULL; ptr = parent_maps) { \
5859 parent_maps=parent_maps->next; \
5860 kfree((vm_offset_t)ptr, sizeof(submap_map_t)); \
5867 * Find the beginning of the region.
5870 vm_map_lock(src_map
);
5872 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
))
5873 RETURN(KERN_INVALID_ADDRESS
);
5874 if(!tmp_entry
->is_sub_map
) {
5875 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
5877 /* set for later submap fix-up */
5878 copy_addr
= src_start
;
5881 * Go through entries until we get to the end.
5886 vm_map_entry_t src_entry
= tmp_entry
; /* Top-level entry */
5887 vm_size_t src_size
; /* Size of source
5888 * map entry (in both
5893 vm_object_t src_object
; /* Object to copy */
5894 vm_object_offset_t src_offset
;
5896 boolean_t src_needs_copy
; /* Should source map
5898 * for copy-on-write?
5901 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
5903 boolean_t was_wired
; /* Was source wired? */
5904 vm_map_version_t version
; /* Version before locks
5905 * dropped to make copy
5907 kern_return_t result
; /* Return value from
5908 * copy_strategically.
5910 while(tmp_entry
->is_sub_map
) {
5911 vm_size_t submap_len
;
5914 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
5915 ptr
->next
= parent_maps
;
5917 ptr
->parent_map
= src_map
;
5918 ptr
->base_start
= src_start
;
5919 ptr
->base_end
= src_end
;
5920 submap_len
= tmp_entry
->vme_end
- src_start
;
5921 if(submap_len
> (src_end
-src_start
))
5922 submap_len
= src_end
-src_start
;
5923 ptr
->base_start
+= submap_len
;
5925 src_start
-= tmp_entry
->vme_start
;
5926 src_start
+= tmp_entry
->offset
;
5927 src_end
= src_start
+ submap_len
;
5928 src_map
= tmp_entry
->object
.sub_map
;
5929 vm_map_lock(src_map
);
5930 vm_map_unlock(ptr
->parent_map
);
5931 if (!vm_map_lookup_entry(
5932 src_map
, src_start
, &tmp_entry
))
5933 RETURN(KERN_INVALID_ADDRESS
);
5935 if(!tmp_entry
->is_sub_map
)
5936 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
5937 src_entry
= tmp_entry
;
5940 * Create a new address map entry to hold the result.
5941 * Fill in the fields from the appropriate source entries.
5942 * We must unlock the source map to do this if we need
5943 * to allocate a map entry.
5945 if (new_entry
== VM_MAP_ENTRY_NULL
) {
5946 version
.main_timestamp
= src_map
->timestamp
;
5947 vm_map_unlock(src_map
);
5949 new_entry
= vm_map_copy_entry_create(copy
);
5951 vm_map_lock(src_map
);
5952 if ((version
.main_timestamp
+ 1) != src_map
->timestamp
) {
5953 if (!vm_map_lookup_entry(src_map
, src_start
,
5955 RETURN(KERN_INVALID_ADDRESS
);
5957 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
5958 continue; /* restart w/ new tmp_entry */
5963 * Verify that the region can be read.
5965 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
5967 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
5968 RETURN(KERN_PROTECTION_FAILURE
);
5971 * Clip against the endpoints of the entire region.
5974 vm_map_clip_end(src_map
, src_entry
, src_end
);
5976 src_size
= src_entry
->vme_end
- src_start
;
5977 src_object
= src_entry
->object
.vm_object
;
5978 src_offset
= src_entry
->offset
;
5979 was_wired
= (src_entry
->wired_count
!= 0);
5981 vm_map_entry_copy(new_entry
, src_entry
);
5982 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
5985 * Attempt non-blocking copy-on-write optimizations.
5989 (src_object
== VM_OBJECT_NULL
||
5990 (src_object
->internal
&& !src_object
->true_share
5993 * If we are destroying the source, and the object
5994 * is internal, we can move the object reference
5995 * from the source to the copy. The copy is
5996 * copy-on-write only if the source is.
5997 * We make another reference to the object, because
5998 * destroying the source entry will deallocate it.
6000 vm_object_reference(src_object
);
6003 * Copy is always unwired. vm_map_copy_entry
6004 * set its wired count to zero.
6007 goto CopySuccessful
;
6012 XPR(XPR_VM_MAP
, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
6013 src_object
, new_entry
, new_entry
->object
.vm_object
,
6016 vm_object_copy_quickly(
6017 &new_entry
->object
.vm_object
,
6021 &new_entry_needs_copy
)) {
6023 new_entry
->needs_copy
= new_entry_needs_copy
;
6026 * Handle copy-on-write obligations
6029 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
6030 if (tmp_entry
->is_shared
||
6031 tmp_entry
->object
.vm_object
->true_share
||
6033 vm_map_unlock(src_map
);
6034 new_entry
->object
.vm_object
=
6035 vm_object_copy_delayed(
6039 /* dec ref gained in copy_quickly */
6040 vm_object_lock(src_object
);
6041 src_object
->ref_count
--;
6042 vm_object_res_deallocate(src_object
);
6043 vm_object_unlock(src_object
);
6044 vm_map_lock(src_map
);
6046 * it turns out that we have
6047 * finished our copy. No matter
6048 * what the state of the map
6049 * we will lock it again here
6050 * knowing that if there is
6051 * additional data to copy
6052 * it will be checked at
6053 * the top of the loop
6055 * Don't do timestamp check
6059 vm_object_pmap_protect(
6063 (src_entry
->is_shared
?
6066 src_entry
->vme_start
,
6067 src_entry
->protection
&
6070 tmp_entry
->needs_copy
= TRUE
;
6075 * The map has never been unlocked, so it's safe
6076 * to move to the next entry rather than doing
6080 goto CopySuccessful
;
6083 new_entry
->needs_copy
= FALSE
;
6086 * Take an object reference, so that we may
6087 * release the map lock(s).
6090 assert(src_object
!= VM_OBJECT_NULL
);
6091 vm_object_reference(src_object
);
6094 * Record the timestamp for later verification.
6098 version
.main_timestamp
= src_map
->timestamp
;
6099 vm_map_unlock(src_map
);
6106 vm_object_lock(src_object
);
6107 result
= vm_object_copy_slowly(
6112 &new_entry
->object
.vm_object
);
6113 new_entry
->offset
= 0;
6114 new_entry
->needs_copy
= FALSE
;
6116 result
= vm_object_copy_strategically(src_object
,
6119 &new_entry
->object
.vm_object
,
6121 &new_entry_needs_copy
);
6123 new_entry
->needs_copy
= new_entry_needs_copy
;
6127 if (result
!= KERN_SUCCESS
&&
6128 result
!= KERN_MEMORY_RESTART_COPY
) {
6129 vm_map_lock(src_map
);
6134 * Throw away the extra reference
6137 vm_object_deallocate(src_object
);
6140 * Verify that the map has not substantially
6141 * changed while the copy was being made.
6144 vm_map_lock(src_map
); /* Increments timestamp once! */
6146 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
)
6147 goto VerificationSuccessful
;
6150 * Simple version comparison failed.
6152 * Retry the lookup and verify that the
6153 * same object/offset are still present.
6155 * [Note: a memory manager that colludes with
6156 * the calling task can detect that we have
6157 * cheated. While the map was unlocked, the
6158 * mapping could have been changed and restored.]
6161 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
6162 RETURN(KERN_INVALID_ADDRESS
);
6165 src_entry
= tmp_entry
;
6166 vm_map_clip_start(src_map
, src_entry
, src_start
);
6168 if ((src_entry
->protection
& VM_PROT_READ
== VM_PROT_NONE
&&
6170 src_entry
->max_protection
& VM_PROT_READ
== 0)
6171 goto VerificationFailed
;
6173 if (src_entry
->vme_end
< new_entry
->vme_end
)
6174 src_size
= (new_entry
->vme_end
= src_entry
->vme_end
) - src_start
;
6176 if ((src_entry
->object
.vm_object
!= src_object
) ||
6177 (src_entry
->offset
!= src_offset
) ) {
6180 * Verification failed.
6182 * Start over with this top-level entry.
6185 VerificationFailed
: ;
6187 vm_object_deallocate(new_entry
->object
.vm_object
);
6188 tmp_entry
= src_entry
;
6193 * Verification succeeded.
6196 VerificationSuccessful
: ;
6198 if (result
== KERN_MEMORY_RESTART_COPY
)
6208 * Link in the new copy entry.
6211 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
6215 * Determine whether the entire region
6218 src_start
= new_entry
->vme_end
;
6219 new_entry
= VM_MAP_ENTRY_NULL
;
6220 while ((src_start
>= src_end
) && (src_end
!= 0)) {
6221 if (src_map
!= base_map
) {
6225 assert(ptr
!= NULL
);
6226 parent_maps
= parent_maps
->next
;
6227 vm_map_lock(ptr
->parent_map
);
6228 vm_map_unlock(src_map
);
6229 src_map
= ptr
->parent_map
;
6230 src_start
= ptr
->base_start
;
6231 src_end
= ptr
->base_end
;
6232 if ((src_end
> src_start
) &&
6233 !vm_map_lookup_entry(
6234 src_map
, src_start
, &tmp_entry
))
6235 RETURN(KERN_INVALID_ADDRESS
);
6236 kfree((vm_offset_t
)ptr
, sizeof(submap_map_t
));
6237 if(parent_maps
== NULL
)
6239 src_entry
= tmp_entry
->vme_prev
;
6243 if ((src_start
>= src_end
) && (src_end
!= 0))
6247 * Verify that there are no gaps in the region
6250 tmp_entry
= src_entry
->vme_next
;
6251 if ((tmp_entry
->vme_start
!= src_start
) ||
6252 (tmp_entry
== vm_map_to_entry(src_map
)))
6253 RETURN(KERN_INVALID_ADDRESS
);
6257 * If the source should be destroyed, do it now, since the
6258 * copy was successful.
6261 (void) vm_map_delete(src_map
,
6262 trunc_page(src_addr
),
6264 (src_map
== kernel_map
) ?
6265 VM_MAP_REMOVE_KUNWIRE
:
6269 vm_map_unlock(src_map
);
6271 /* Fix-up start and end points in copy. This is necessary */
6272 /* when the various entries in the copy object were picked */
6273 /* up from different sub-maps */
6275 tmp_entry
= vm_map_copy_first_entry(copy
);
6276 while (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
6277 tmp_entry
->vme_end
= copy_addr
+
6278 (tmp_entry
->vme_end
- tmp_entry
->vme_start
);
6279 tmp_entry
->vme_start
= copy_addr
;
6280 copy_addr
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
6281 tmp_entry
= (struct vm_map_entry
*)tmp_entry
->vme_next
;
6284 *copy_result
= copy
;
6285 return(KERN_SUCCESS
);
6291 * vm_map_copyin_object:
6293 * Create a copy object from an object.
6294 * Our caller donates an object reference.
6298 vm_map_copyin_object(
6300 vm_object_offset_t offset
, /* offset of region in object */
6301 vm_object_size_t size
, /* size of region in object */
6302 vm_map_copy_t
*copy_result
) /* OUT */
6304 vm_map_copy_t copy
; /* Resulting copy */
6307 * We drop the object into a special copy object
6308 * that contains the object directly.
6311 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6312 copy
->type
= VM_MAP_COPY_OBJECT
;
6313 copy
->cpy_object
= object
;
6314 copy
->cpy_index
= 0;
6315 copy
->offset
= offset
;
6318 *copy_result
= copy
;
6319 return(KERN_SUCCESS
);
6323 * vm_map_copyin_page_list_cont:
6325 * Continuation routine for vm_map_copyin_page_list.
6327 * If vm_map_copyin_page_list can't fit the entire vm range
6328 * into a single page list object, it creates a continuation.
6329 * When the target of the operation has used the pages in the
6330 * initial page list, it invokes the continuation, which calls
6331 * this routine. If an error happens, the continuation is aborted
6332 * (abort arg to this routine is TRUE). To avoid deadlocks, the
6333 * pages are discarded from the initial page list before invoking
6336 * NOTE: This is not the same sort of continuation used by
6341 vm_map_copyin_page_list_cont(
6342 vm_map_copyin_args_t cont_args
,
6343 vm_map_copy_t
*copy_result
) /* OUT */
6345 kern_return_t result
= KERN_SUCCESS
;
6346 register boolean_t abort
, src_destroy
, src_destroy_only
;
6349 * Check for cases that only require memory destruction.
6351 abort
= (copy_result
== (vm_map_copy_t
*) 0);
6352 src_destroy
= (cont_args
->destroy_len
!= (vm_size_t
) 0);
6353 src_destroy_only
= (cont_args
->src_len
== (vm_size_t
) 0);
6355 if (abort
|| src_destroy_only
) {
6357 result
= vm_map_remove(cont_args
->map
,
6358 cont_args
->destroy_addr
,
6359 cont_args
->destroy_addr
+ cont_args
->destroy_len
,
6362 *copy_result
= VM_MAP_COPY_NULL
;
6365 result
= vm_map_copyin_page_list(cont_args
->map
,
6366 cont_args
->src_addr
, cont_args
->src_len
,
6367 cont_args
->options
, copy_result
, TRUE
);
6370 (cont_args
->options
& VM_MAP_COPYIN_OPT_STEAL_PAGES
) &&
6371 vm_map_copy_has_cont(*copy_result
)) {
6372 vm_map_copyin_args_t new_args
;
6374 * Transfer old destroy info.
6376 new_args
= (vm_map_copyin_args_t
)
6377 (*copy_result
)->cpy_cont_args
;
6378 new_args
->destroy_addr
= cont_args
->destroy_addr
;
6379 new_args
->destroy_len
= cont_args
->destroy_len
;
6383 vm_map_deallocate(cont_args
->map
);
6384 kfree((vm_offset_t
)cont_args
, sizeof(vm_map_copyin_args_data_t
));
6390 * vm_map_copyin_page_list:
6392 * This is a variant of vm_map_copyin that copies in a list of pages.
6393 * If steal_pages is TRUE, the pages are only in the returned list.
6394 * If steal_pages is FALSE, the pages are busy and still in their
6395 * objects. A continuation may be returned if not all the pages fit:
6396 * the recipient of this copy_result must be prepared to deal with it.
6400 vm_map_copyin_page_list(
6402 vm_offset_t src_addr
,
6405 vm_map_copy_t
*copy_result
, /* OUT */
6408 vm_map_entry_t src_entry
;
6410 vm_offset_t src_start
;
6411 vm_offset_t src_end
;
6413 register vm_object_t src_object
;
6414 register vm_object_offset_t src_offset
;
6415 vm_object_offset_t src_last_offset
;
6416 register vm_map_copy_t copy
; /* Resulting copy */
6417 kern_return_t result
= KERN_SUCCESS
;
6418 boolean_t need_map_lookup
;
6419 vm_map_copyin_args_t cont_args
;
6420 kern_return_t error_code
;
6423 boolean_t no_zero_fill
;
6425 submap_map_t
*parent_maps
= NULL
;
6426 vm_map_t base_map
= src_map
;
6428 prot
= (options
& VM_MAP_COPYIN_OPT_VM_PROT
);
6429 no_zero_fill
= (options
& VM_MAP_COPYIN_OPT_NO_ZERO_FILL
);
6432 * If steal_pages is FALSE, this leaves busy pages in
6433 * the object. A continuation must be used if src_destroy
6434 * is true in this case (!steal_pages && src_destroy).
6436 * XXX Still have a more general problem of what happens
6437 * XXX if the same page occurs twice in a list. Deadlock
6438 * XXX can happen if vm_fault_page was called. A
6439 * XXX possible solution is to use a continuation if vm_fault_page
6440 * XXX is called and we cross a map entry boundary.
6444 * Check for copies of zero bytes.
6448 *copy_result
= VM_MAP_COPY_NULL
;
6449 return(KERN_SUCCESS
);
6453 * Compute start and end of region
6456 src_start
= trunc_page(src_addr
);
6457 src_end
= round_page(src_addr
+ len
);
6460 * If the region is not page aligned, override the no_zero_fill
6464 if (options
& VM_MAP_COPYIN_OPT_NO_ZERO_FILL
) {
6465 if (!page_aligned(src_addr
) || !page_aligned(src_addr
+len
))
6466 options
&= ~VM_MAP_COPYIN_OPT_NO_ZERO_FILL
;
6470 * Check that the end address doesn't overflow
6473 if (src_end
<= src_start
&& (src_end
< src_start
|| src_start
!= 0)) {
6474 return KERN_INVALID_ADDRESS
;
6478 * Allocate a header element for the page list.
6480 * Record original offset and size, as caller may not
6484 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6485 copy
->type
= VM_MAP_COPY_PAGE_LIST
;
6486 copy
->cpy_npages
= 0;
6487 copy
->cpy_page_loose
= FALSE
;
6488 copy
->offset
= src_addr
;
6490 copy
->cpy_cont
= VM_MAP_COPY_CONT_NULL
;
6491 copy
->cpy_cont_args
= VM_MAP_COPYIN_ARGS_NULL
;
6494 * Find the beginning of the region.
6499 vm_map_lock(src_map
);
6501 if (!vm_map_lookup_entry(src_map
, src_start
, &src_entry
)) {
6502 result
= KERN_INVALID_ADDRESS
;
6505 need_map_lookup
= FALSE
;
6508 * Go through entries until we get to the end.
6512 if ((src_entry
->protection
& prot
) != prot
) {
6513 result
= KERN_PROTECTION_FAILURE
;
6517 /* translate down through submaps to find the target entry */
6518 while(src_entry
->is_sub_map
) {
6519 vm_size_t submap_len
;
6522 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
6523 ptr
->next
= parent_maps
;
6525 ptr
->parent_map
= src_map
;
6526 ptr
->base_start
= src_start
;
6527 ptr
->base_end
= src_end
;
6528 submap_len
= src_entry
->vme_end
- src_entry
->vme_start
;
6529 if(submap_len
> (src_end
-src_start
))
6530 submap_len
= src_end
-src_start
;
6531 ptr
->base_start
+= submap_len
;
6533 src_start
-= src_entry
->vme_start
;
6534 src_start
+= src_entry
->offset
;
6535 src_end
= src_start
+ submap_len
;
6536 src_map
= src_entry
->object
.sub_map
;
6537 vm_map_lock(src_map
);
6538 vm_map_unlock(ptr
->parent_map
);
6539 if (!vm_map_lookup_entry(
6540 src_map
, src_start
, &src_entry
)) {
6541 result
= KERN_INVALID_ADDRESS
;
6544 vm_map_clip_start(src_map
, src_entry
, src_start
);
6547 wired
= (src_entry
->wired_count
!= 0);
6549 if (src_end
> src_entry
->vme_end
)
6550 src_size
= src_entry
->vme_end
- src_start
;
6552 src_size
= src_end
- src_start
;
6554 src_object
= src_entry
->object
.vm_object
;
6557 * If src_object is NULL, allocate it now;
6558 * we're going to fault on it shortly.
6560 if (src_object
== VM_OBJECT_NULL
) {
6561 src_object
= vm_object_allocate((vm_size_t
)
6562 src_entry
->vme_end
-
6563 src_entry
->vme_start
);
6564 src_entry
->object
.vm_object
= src_object
;
6566 else if (src_entry
->needs_copy
&& (prot
& VM_PROT_WRITE
)) {
6568 &src_entry
->object
.vm_object
,
6570 (vm_size_t
) (src_entry
->vme_end
-
6571 src_entry
->vme_start
));
6573 src_entry
->needs_copy
= FALSE
;
6575 /* reset src_object */
6576 src_object
= src_entry
->object
.vm_object
;
6580 * calculate src_offset now, since vm_object_shadow
6581 * may have changed src_entry->offset.
6583 src_offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
6586 * Iterate over pages. Fault in ones that aren't present.
6588 src_last_offset
= src_offset
+ src_size
;
6589 for (; (src_offset
< src_last_offset
);
6590 src_offset
+= PAGE_SIZE_64
, src_start
+= PAGE_SIZE
) {
6592 if (copy
->cpy_npages
== VM_MAP_COPY_PAGE_LIST_MAX
) {
6593 vm_offset_t src_delta
;
6596 * At this point we have the max number of
6597 * pages busy for this thread that we're
6598 * willing to allow. Stop here and record
6599 * arguments for the remainder. Note:
6600 * this means that this routine isn't atomic,
6601 * but that's the breaks. Note that only
6602 * the first vm_map_copy_t that comes back
6603 * from this routine has the right offset
6604 * and size; those from continuations are
6605 * page rounded, and short by the amount
6608 * Reset src_end so the src_destroy
6609 * code at the bottom doesn't do
6613 src_delta
= src_end
- src_start
;
6614 while (src_map
!= base_map
) {
6617 if(!need_map_lookup
) {
6618 vm_map_unlock(src_map
);
6621 assert(ptr
!= NULL
);
6622 parent_maps
= parent_maps
->next
;
6623 src_map
= ptr
->parent_map
;
6624 src_start
= ptr
->base_start
- src_delta
;
6625 src_delta
= ptr
->base_end
- src_start
;
6626 kfree((vm_offset_t
)ptr
, sizeof(submap_map_t
));
6628 need_map_lookup
= TRUE
;
6630 src_end
= src_start
;
6633 cont_args
= (vm_map_copyin_args_t
)
6634 kalloc(sizeof(vm_map_copyin_args_data_t
));
6635 cont_args
->map
= src_map
;
6636 vm_map_reference(src_map
);
6637 cont_args
->src_addr
= src_start
;
6638 cont_args
->src_len
= len
- (src_start
- src_addr
);
6639 if (options
& VM_MAP_COPYIN_OPT_SRC_DESTROY
) {
6640 cont_args
->destroy_addr
= cont_args
->src_addr
;
6641 cont_args
->destroy_len
= cont_args
->src_len
;
6643 cont_args
->destroy_addr
= (vm_offset_t
) 0;
6644 cont_args
->destroy_len
= (vm_offset_t
) 0;
6646 cont_args
->options
= options
;
6648 copy
->cpy_cont_args
= cont_args
;
6649 copy
->cpy_cont
= vm_map_copyin_page_list_cont
;
6655 * Try to find the page of data. Have to
6656 * fault it in if there's no page, or something
6657 * going on with the page, or the object has
6660 vm_object_lock(src_object
);
6661 vm_object_paging_begin(src_object
);
6662 if (((m
= vm_page_lookup(src_object
, src_offset
)) !=
6664 !m
->busy
&& !m
->fictitious
&& !m
->unusual
&&
6665 ((prot
& VM_PROT_WRITE
) == 0 ||
6666 (m
->object
->copy
== VM_OBJECT_NULL
))) {
6669 !(options
& VM_MAP_COPYIN_OPT_STEAL_PAGES
)) {
6672 * The page is present and will not be
6673 * replaced, prep it. Thus allowing
6674 * mutiple access on this page
6678 kr
= vm_page_prep(m
);
6679 assert(kr
== KERN_SUCCESS
);
6680 kr
= vm_page_pin(m
);
6681 assert(kr
== KERN_SUCCESS
);
6684 * This is the page. Mark it busy
6685 * and keep the paging reference on
6686 * the object whilst we do our thing.
6692 vm_prot_t result_prot
;
6695 boolean_t data_supply
;
6698 * Have to fault the page in; must
6699 * unlock the map to do so. While
6700 * the map is unlocked, anything
6701 * can happen, we must lookup the
6702 * map entry before continuing.
6704 vm_map_unlock(src_map
);
6705 need_map_lookup
= TRUE
;
6706 data_supply
= src_object
->silent_overwrite
&&
6707 (prot
& VM_PROT_WRITE
) &&
6708 src_start
>= src_addr
&&
6709 src_start
+ PAGE_SIZE
<=
6716 "vm_map_copyin_page_list -> vm_fault_page\n",
6718 kr
= vm_fault_page(src_object
, src_offset
,
6719 prot
, FALSE
, THREAD_UNINT
,
6722 (src_entry
->vme_end
-
6723 src_entry
->vme_start
),
6724 VM_BEHAVIOR_SEQUENTIAL
,
6725 &result_prot
, &m
, &top_page
,
6728 options
& VM_MAP_COPYIN_OPT_NO_ZERO_FILL
,
6731 * Cope with what happened.
6734 case VM_FAULT_SUCCESS
:
6737 * If we lost write access,
6740 if ((prot
& VM_PROT_WRITE
) &&
6741 !(result_prot
& VM_PROT_WRITE
)) {
6742 vm_object_lock(src_object
);
6743 vm_object_paging_begin(src_object
);
6747 case VM_FAULT_MEMORY_SHORTAGE
:
6750 case VM_FAULT_INTERRUPTED
: /* ??? */
6751 case VM_FAULT_RETRY
:
6752 vm_object_lock(src_object
);
6753 vm_object_paging_begin(src_object
);
6755 case VM_FAULT_FICTITIOUS_SHORTAGE
:
6756 vm_page_more_fictitious();
6757 vm_object_lock(src_object
);
6758 vm_object_paging_begin(src_object
);
6760 case VM_FAULT_MEMORY_ERROR
:
6762 * Something broke. If this
6763 * is a continuation, return
6764 * a partial result if possible,
6765 * else fail the whole thing.
6766 * In the continuation case, the
6767 * next continuation call will
6768 * get this error if it persists.
6770 vm_map_lock(src_map
);
6772 copy
->cpy_npages
!= 0)
6773 goto make_continuation
;
6775 result
= error_code
? error_code
: KERN_MEMORY_ERROR
;
6779 if (top_page
!= VM_PAGE_NULL
) {
6780 vm_object_lock(src_object
);
6781 VM_PAGE_FREE(top_page
);
6782 vm_object_paging_end(src_object
);
6783 vm_object_unlock(src_object
);
6789 * The page is busy, its object is locked, and
6790 * we have a paging reference on it. Either
6791 * the map is locked, or need_map_lookup is
6796 * Put the page in the page list.
6798 copy
->cpy_page_list
[copy
->cpy_npages
++] = m
;
6799 vm_object_unlock(m
->object
);
6802 * Pmap enter support. Only used for
6803 * device I/O for colocated server.
6805 * WARNING: This code assumes that this
6806 * option is only used for well behaved
6807 * memory. If the mapping has changed,
6808 * the following code will make mistakes.
6810 * XXXO probably ought to do pmap_extract first,
6811 * XXXO to avoid needless pmap_enter, but this
6812 * XXXO can't detect protection mismatch??
6815 if (options
& VM_MAP_COPYIN_OPT_PMAP_ENTER
) {
6817 * XXX Only used on kernel map.
6818 * XXX Must not remove VM_PROT_WRITE on
6819 * XXX an I/O only requiring VM_PROT_READ
6820 * XXX as another I/O may be active on same page
6821 * XXX assume that if mapping exists, it must
6822 * XXX have the equivalent of at least VM_PROT_READ,
6823 * XXX but don't assume it has VM_PROT_WRITE as the
6824 * XXX pmap might not all the rights of the object
6826 assert(vm_map_pmap(src_map
) == kernel_pmap
);
6828 if ((prot
& VM_PROT_WRITE
) ||
6829 (pmap_extract(vm_map_pmap(src_map
),
6830 src_start
) != m
->phys_addr
))
6832 PMAP_ENTER(vm_map_pmap(src_map
), src_start
,
6835 if(need_map_lookup
) {
6836 need_map_lookup
= FALSE
;
6837 vm_map_lock(src_map
);
6838 if (!vm_map_lookup_entry(src_map
, src_start
, &src_entry
)) {
6839 result
= KERN_INVALID_ADDRESS
;
6846 * Verify that there are no gaps in the region
6848 src_start
= src_entry
->vme_end
;
6849 if (src_start
< src_end
) {
6850 src_entry
= src_entry
->vme_next
;
6851 if (need_map_lookup
) {
6852 need_map_lookup
= FALSE
;
6853 vm_map_lock(src_map
);
6854 if(!vm_map_lookup_entry(src_map
,
6855 src_start
, &src_entry
)) {
6856 result
= KERN_INVALID_ADDRESS
;
6859 } else if (src_entry
->vme_start
!= src_start
) {
6860 result
= KERN_INVALID_ADDRESS
;
6866 * DETERMINE whether the entire region
6870 while ((src_start
>= src_end
) && (src_end
!= 0)) {
6871 if (src_map
!= base_map
) {
6875 assert(ptr
!= NULL
);
6876 parent_maps
= parent_maps
->next
;
6877 src_start
= ptr
->base_start
;
6878 src_end
= ptr
->base_end
;
6879 if(need_map_lookup
) {
6880 need_map_lookup
= FALSE
;
6883 vm_map_unlock(src_map
);
6885 src_map
= ptr
->parent_map
;
6886 vm_map_lock(src_map
);
6887 if((src_start
< src_end
) &&
6888 (!vm_map_lookup_entry(ptr
->parent_map
,
6889 src_start
, &src_entry
))) {
6890 result
= KERN_INVALID_ADDRESS
;
6891 kfree((vm_offset_t
)ptr
, sizeof(submap_map_t
));
6894 kfree((vm_offset_t
)ptr
, sizeof(submap_map_t
));
6898 if ((src_start
>= src_end
) && (src_end
!= 0)) {
6899 if (need_map_lookup
)
6900 vm_map_lock(src_map
);
6907 * If steal_pages is true, make sure all
6908 * pages in the copy are not in any object
6909 * We try to remove them from the original
6910 * object, but we may have to copy them.
6912 * At this point every page in the list is busy
6913 * and holds a paging reference to its object.
6914 * When we're done stealing, every page is busy,
6915 * and in no object (m->tabled == FALSE).
6917 src_start
= trunc_page(src_addr
);
6918 if (options
& VM_MAP_COPYIN_OPT_STEAL_PAGES
) {
6920 vm_offset_t page_vaddr
;
6921 vm_offset_t unwire_end
;
6922 vm_offset_t map_entry_end
;
6923 boolean_t share_map
= FALSE
;
6925 unwire_end
= src_start
;
6926 map_entry_end
= src_start
;
6927 for (i
= 0; i
< copy
->cpy_npages
; i
++) {
6931 * Remove the page from its object if it
6932 * can be stolen. It can be stolen if:
6934 * (1) The source is being destroyed,
6935 * the object is internal (hence
6936 * temporary), and not shared.
6937 * (2) The page is not precious.
6939 * The not shared check consists of two
6940 * parts: (a) there are no objects that
6941 * shadow this object. (b) it is not the
6942 * object in any shared map entries (i.e.,
6943 * use_shared_copy is not set).
6945 * The first check (a) means that we can't
6946 * steal pages from objects that are not
6947 * at the top of their shadow chains. This
6948 * should not be a frequent occurrence.
6950 * Stealing wired pages requires telling the
6951 * pmap module to let go of them.
6953 * NOTE: stealing clean pages from objects
6954 * whose mappings survive requires a call to
6955 * the pmap module. Maybe later.
6957 m
= copy
->cpy_page_list
[i
];
6958 src_object
= m
->object
;
6959 vm_object_lock(src_object
);
6961 page_vaddr
= src_start
+ (i
* PAGE_SIZE
);
6962 if(page_vaddr
> map_entry_end
) {
6963 if (!vm_map_lookup_entry(src_map
, page_vaddr
, &src_entry
))
6965 else if (src_entry
->is_sub_map
) {
6966 map_entry_end
= src_entry
->vme_end
;
6969 map_entry_end
= src_entry
->vme_end
;
6975 if ((options
& VM_MAP_COPYIN_OPT_SRC_DESTROY
) &&
6976 src_object
->internal
&&
6977 !src_object
->true_share
&&
6978 (!src_object
->shadowed
) &&
6979 (src_object
->copy_strategy
==
6980 MEMORY_OBJECT_COPY_SYMMETRIC
) &&
6984 if (m
->wire_count
> 0) {
6986 assert(m
->wire_count
== 1);
6988 * In order to steal a wired
6989 * page, we have to unwire it
6990 * first. We do this inline
6991 * here because we have the page.
6993 * Step 1: Unwire the map entry.
6994 * Also tell the pmap module
6995 * that this piece of the
6998 vm_object_unlock(src_object
);
6999 if (page_vaddr
>= unwire_end
) {
7000 if (!vm_map_lookup_entry(src_map
,
7001 page_vaddr
, &src_entry
))
7002 panic("vm_map_copyin_page_list: missing wired map entry");
7004 vm_map_clip_start(src_map
, src_entry
,
7006 vm_map_clip_end(src_map
, src_entry
,
7007 src_start
+ src_size
);
7009 /* revisit why this assert fails CDY
7010 assert(src_entry->wired_count > 0);
7012 src_entry
->wired_count
= 0;
7013 src_entry
->user_wired_count
= 0;
7014 unwire_end
= src_entry
->vme_end
;
7015 pmap_pageable(vm_map_pmap(src_map
),
7016 page_vaddr
, unwire_end
, TRUE
);
7020 * Step 2: Unwire the page.
7021 * pmap_remove handles this for us.
7023 vm_object_lock(src_object
);
7027 * Don't need to remove the mapping;
7028 * vm_map_delete will handle it.
7030 * Steal the page. Setting the wire count
7031 * to zero is vm_page_unwire without
7032 * activating the page.
7034 vm_page_lock_queues();
7036 if (m
->wire_count
> 0) {
7038 vm_page_wire_count
--;
7040 VM_PAGE_QUEUES_REMOVE(m
);
7042 vm_page_unlock_queues();
7045 * Have to copy this page. Have to
7046 * unlock the map while copying,
7047 * hence no further page stealing.
7048 * Hence just copy all the pages.
7049 * Unlock the map while copying;
7050 * This means no further page stealing.
7052 vm_object_unlock(src_object
);
7053 vm_map_unlock(src_map
);
7054 vm_map_copy_steal_pages(copy
);
7055 vm_map_lock(src_map
);
7059 vm_object_paging_end(src_object
);
7060 vm_object_unlock(src_object
);
7063 copy
->cpy_page_loose
= TRUE
;
7066 * If the source should be destroyed, do it now, since the
7067 * copy was successful.
7070 if (options
& VM_MAP_COPYIN_OPT_SRC_DESTROY
) {
7071 (void) vm_map_delete(src_map
, src_start
,
7072 src_end
, VM_MAP_NO_FLAGS
);
7076 * Not stealing pages leaves busy or prepped pages in the map.
7077 * This will cause source destruction to hang. Use
7078 * a continuation to prevent this.
7080 if ((options
& VM_MAP_COPYIN_OPT_SRC_DESTROY
) &&
7081 !vm_map_copy_has_cont(copy
)) {
7082 cont_args
= (vm_map_copyin_args_t
)
7083 kalloc(sizeof(vm_map_copyin_args_data_t
));
7084 vm_map_reference(src_map
);
7085 cont_args
->map
= src_map
;
7086 cont_args
->src_addr
= (vm_offset_t
) 0;
7087 cont_args
->src_len
= (vm_size_t
) 0;
7088 cont_args
->destroy_addr
= src_start
;
7089 cont_args
->destroy_len
= src_end
- src_start
;
7090 cont_args
->options
= options
;
7092 copy
->cpy_cont_args
= cont_args
;
7093 copy
->cpy_cont
= vm_map_copyin_page_list_cont
;
7097 vm_map_unlock(src_map
);
7099 *copy_result
= copy
;
7106 vm_map_unlock(src_map
);
7107 vm_map_copy_discard(copy
);
7109 for(ptr
= parent_maps
; ptr
!= NULL
; ptr
= parent_maps
) {
7110 parent_maps
=parent_maps
->next
;
7111 kfree((vm_offset_t
)ptr
, sizeof(submap_map_t
));
7120 vm_map_entry_t old_entry
,
7124 vm_map_entry_t new_entry
;
7125 kern_return_t result
;
7128 * New sharing code. New map entry
7129 * references original object. Internal
7130 * objects use asynchronous copy algorithm for
7131 * future copies. First make sure we have
7132 * the right object. If we need a shadow,
7133 * or someone else already has one, then
7134 * make a new shadow and share it.
7137 object
= old_entry
->object
.vm_object
;
7138 if (old_entry
->is_sub_map
) {
7139 assert(old_entry
->wired_count
== 0);
7141 if(old_entry
->use_pmap
) {
7142 result
= pmap_nest(new_map
->pmap
,
7143 (old_entry
->object
.sub_map
)->pmap
,
7144 old_entry
->vme_start
,
7145 old_entry
->vme_end
- old_entry
->vme_start
);
7147 panic("vm_map_fork_share: pmap_nest failed!");
7150 } else if (object
== VM_OBJECT_NULL
) {
7151 object
= vm_object_allocate((vm_size_t
)(old_entry
->vme_end
-
7152 old_entry
->vme_start
));
7153 old_entry
->offset
= 0;
7154 old_entry
->object
.vm_object
= object
;
7155 assert(!old_entry
->needs_copy
);
7156 } else if (object
->copy_strategy
!=
7157 MEMORY_OBJECT_COPY_SYMMETRIC
) {
7160 * We are already using an asymmetric
7161 * copy, and therefore we already have
7165 assert(! old_entry
->needs_copy
);
7167 else if (old_entry
->needs_copy
|| /* case 1 */
7168 object
->shadowed
|| /* case 2 */
7169 (!object
->true_share
&& /* case 3 */
7170 !old_entry
->is_shared
&&
7172 (vm_size_t
)(old_entry
->vme_end
-
7173 old_entry
->vme_start
)))) {
7176 * We need to create a shadow.
7177 * There are three cases here.
7178 * In the first case, we need to
7179 * complete a deferred symmetrical
7180 * copy that we participated in.
7181 * In the second and third cases,
7182 * we need to create the shadow so
7183 * that changes that we make to the
7184 * object do not interfere with
7185 * any symmetrical copies which
7186 * have occured (case 2) or which
7187 * might occur (case 3).
7189 * The first case is when we had
7190 * deferred shadow object creation
7191 * via the entry->needs_copy mechanism.
7192 * This mechanism only works when
7193 * only one entry points to the source
7194 * object, and we are about to create
7195 * a second entry pointing to the
7196 * same object. The problem is that
7197 * there is no way of mapping from
7198 * an object to the entries pointing
7199 * to it. (Deferred shadow creation
7200 * works with one entry because occurs
7201 * at fault time, and we walk from the
7202 * entry to the object when handling
7205 * The second case is when the object
7206 * to be shared has already been copied
7207 * with a symmetric copy, but we point
7208 * directly to the object without
7209 * needs_copy set in our entry. (This
7210 * can happen because different ranges
7211 * of an object can be pointed to by
7212 * different entries. In particular,
7213 * a single entry pointing to an object
7214 * can be split by a call to vm_inherit,
7215 * which, combined with task_create, can
7216 * result in the different entries
7217 * having different needs_copy values.)
7218 * The shadowed flag in the object allows
7219 * us to detect this case. The problem
7220 * with this case is that if this object
7221 * has or will have shadows, then we
7222 * must not perform an asymmetric copy
7223 * of this object, since such a copy
7224 * allows the object to be changed, which
7225 * will break the previous symmetrical
7226 * copies (which rely upon the object
7227 * not changing). In a sense, the shadowed
7228 * flag says "don't change this object".
7229 * We fix this by creating a shadow
7230 * object for this object, and sharing
7231 * that. This works because we are free
7232 * to change the shadow object (and thus
7233 * to use an asymmetric copy strategy);
7234 * this is also semantically correct,
7235 * since this object is temporary, and
7236 * therefore a copy of the object is
7237 * as good as the object itself. (This
7238 * is not true for permanent objects,
7239 * since the pager needs to see changes,
7240 * which won't happen if the changes
7241 * are made to a copy.)
7243 * The third case is when the object
7244 * to be shared has parts sticking
7245 * outside of the entry we're working
7246 * with, and thus may in the future
7247 * be subject to a symmetrical copy.
7248 * (This is a preemptive version of
7252 assert(!(object
->shadowed
&& old_entry
->is_shared
));
7253 vm_object_shadow(&old_entry
->object
.vm_object
,
7255 (vm_size_t
) (old_entry
->vme_end
-
7256 old_entry
->vme_start
));
7259 * If we're making a shadow for other than
7260 * copy on write reasons, then we have
7261 * to remove write permission.
7264 /* CDY FIX this! page_protect! */
7265 if (!old_entry
->needs_copy
&&
7266 (old_entry
->protection
& VM_PROT_WRITE
)) {
7267 if(old_entry
->is_sub_map
&& old_entry
->use_pmap
) {
7268 pmap_protect(old_entry
->object
.sub_map
->pmap
,
7269 old_entry
->vme_start
,
7271 old_entry
->protection
& ~VM_PROT_WRITE
);
7273 pmap_protect(vm_map_pmap(old_map
),
7274 old_entry
->vme_start
,
7276 old_entry
->protection
& ~VM_PROT_WRITE
);
7280 old_entry
->needs_copy
= FALSE
;
7281 object
= old_entry
->object
.vm_object
;
7285 * If object was using a symmetric copy strategy,
7286 * change its copy strategy to the default
7287 * asymmetric copy strategy, which is copy_delay
7288 * in the non-norma case and copy_call in the
7289 * norma case. Bump the reference count for the
7293 if(old_entry
->is_sub_map
) {
7294 vm_map_lock(old_entry
->object
.sub_map
);
7295 vm_map_reference(old_entry
->object
.sub_map
);
7296 vm_map_unlock(old_entry
->object
.sub_map
);
7298 vm_object_lock(object
);
7299 object
->ref_count
++;
7300 vm_object_res_reference(object
);
7301 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
7302 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
7304 vm_object_unlock(object
);
7308 * Clone the entry, using object ref from above.
7309 * Mark both entries as shared.
7312 new_entry
= vm_map_entry_create(new_map
);
7313 vm_map_entry_copy(new_entry
, old_entry
);
7314 old_entry
->is_shared
= TRUE
;
7315 new_entry
->is_shared
= TRUE
;
7318 * Insert the entry into the new map -- we
7319 * know we're inserting at the end of the new
7323 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
7326 * Update the physical map
7329 if (old_entry
->is_sub_map
) {
7330 /* Bill Angell pmap support goes here */
7332 pmap_copy(new_map
->pmap
, old_map
->pmap
, new_entry
->vme_start
,
7333 old_entry
->vme_end
- old_entry
->vme_start
,
7334 old_entry
->vme_start
);
7341 vm_map_entry_t
*old_entry_p
,
7344 vm_map_entry_t old_entry
= *old_entry_p
;
7345 vm_size_t entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
7346 vm_offset_t start
= old_entry
->vme_start
;
7348 vm_map_entry_t last
= vm_map_last_entry(new_map
);
7350 vm_map_unlock(old_map
);
7352 * Use maxprot version of copyin because we
7353 * care about whether this memory can ever
7354 * be accessed, not just whether it's accessible
7357 if (vm_map_copyin_maxprot(old_map
, start
, entry_size
, FALSE
, ©
)
7360 * The map might have changed while it
7361 * was unlocked, check it again. Skip
7362 * any blank space or permanently
7363 * unreadable region.
7365 vm_map_lock(old_map
);
7366 if (!vm_map_lookup_entry(old_map
, start
, &last
) ||
7367 last
->max_protection
& VM_PROT_READ
==
7369 last
= last
->vme_next
;
7371 *old_entry_p
= last
;
7374 * XXX For some error returns, want to
7375 * XXX skip to the next element. Note
7376 * that INVALID_ADDRESS and
7377 * PROTECTION_FAILURE are handled above.
7384 * Insert the copy into the new map
7387 vm_map_copy_insert(new_map
, last
, copy
);
7390 * Pick up the traversal at the end of
7391 * the copied region.
7394 vm_map_lock(old_map
);
7395 start
+= entry_size
;
7396 if (! vm_map_lookup_entry(old_map
, start
, &last
)) {
7397 last
= last
->vme_next
;
7399 vm_map_clip_start(old_map
, last
, start
);
7401 *old_entry_p
= last
;
7409 * Create and return a new map based on the old
7410 * map, according to the inheritance values on the
7411 * regions in that map.
7413 * The source map must not be locked.
7419 pmap_t new_pmap
= pmap_create((vm_size_t
) 0);
7421 vm_map_entry_t old_entry
;
7422 vm_size_t new_size
= 0, entry_size
;
7423 vm_map_entry_t new_entry
;
7424 boolean_t src_needs_copy
;
7425 boolean_t new_entry_needs_copy
;
7427 vm_map_reference_swap(old_map
);
7428 vm_map_lock(old_map
);
7430 new_map
= vm_map_create(new_pmap
,
7431 old_map
->min_offset
,
7432 old_map
->max_offset
,
7433 old_map
->hdr
.entries_pageable
);
7436 old_entry
= vm_map_first_entry(old_map
);
7437 old_entry
!= vm_map_to_entry(old_map
);
7440 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
7442 switch (old_entry
->inheritance
) {
7443 case VM_INHERIT_NONE
:
7446 case VM_INHERIT_SHARE
:
7447 vm_map_fork_share(old_map
, old_entry
, new_map
);
7448 new_size
+= entry_size
;
7451 case VM_INHERIT_COPY
:
7454 * Inline the copy_quickly case;
7455 * upon failure, fall back on call
7456 * to vm_map_fork_copy.
7459 if(old_entry
->is_sub_map
)
7461 if (old_entry
->wired_count
!= 0) {
7462 goto slow_vm_map_fork_copy
;
7465 new_entry
= vm_map_entry_create(new_map
);
7466 vm_map_entry_copy(new_entry
, old_entry
);
7467 /* clear address space specifics */
7468 new_entry
->use_pmap
= FALSE
;
7470 if (! vm_object_copy_quickly(
7471 &new_entry
->object
.vm_object
,
7473 (old_entry
->vme_end
-
7474 old_entry
->vme_start
),
7476 &new_entry_needs_copy
)) {
7477 vm_map_entry_dispose(new_map
, new_entry
);
7478 goto slow_vm_map_fork_copy
;
7482 * Handle copy-on-write obligations
7485 if (src_needs_copy
&& !old_entry
->needs_copy
) {
7486 vm_object_pmap_protect(
7487 old_entry
->object
.vm_object
,
7489 (old_entry
->vme_end
-
7490 old_entry
->vme_start
),
7491 ((old_entry
->is_shared
7492 || old_entry
->is_sub_map
)
7495 old_entry
->vme_start
,
7496 old_entry
->protection
& ~VM_PROT_WRITE
);
7498 old_entry
->needs_copy
= TRUE
;
7500 new_entry
->needs_copy
= new_entry_needs_copy
;
7503 * Insert the entry at the end
7507 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
),
7509 new_size
+= entry_size
;
7512 slow_vm_map_fork_copy
:
7513 if (vm_map_fork_copy(old_map
, &old_entry
, new_map
)) {
7514 new_size
+= entry_size
;
7518 old_entry
= old_entry
->vme_next
;
7521 new_map
->size
= new_size
;
7522 vm_map_unlock(old_map
);
7523 vm_map_deallocate(old_map
);
7530 * vm_map_lookup_locked:
7532 * Finds the VM object, offset, and
7533 * protection for a given virtual address in the
7534 * specified map, assuming a page fault of the
7537 * Returns the (object, offset, protection) for
7538 * this address, whether it is wired down, and whether
7539 * this map has the only reference to the data in question.
7540 * In order to later verify this lookup, a "version"
7543 * The map MUST be locked by the caller and WILL be
7544 * locked on exit. In order to guarantee the
7545 * existence of the returned object, it is returned
7548 * If a lookup is requested with "write protection"
7549 * specified, the map may be changed to perform virtual
7550 * copying operations, although the data referenced will
7554 vm_map_lookup_locked(
7555 vm_map_t
*var_map
, /* IN/OUT */
7556 register vm_offset_t vaddr
,
7557 register vm_prot_t fault_type
,
7558 vm_map_version_t
*out_version
, /* OUT */
7559 vm_object_t
*object
, /* OUT */
7560 vm_object_offset_t
*offset
, /* OUT */
7561 vm_prot_t
*out_prot
, /* OUT */
7562 boolean_t
*wired
, /* OUT */
7563 int *behavior
, /* OUT */
7564 vm_object_offset_t
*lo_offset
, /* OUT */
7565 vm_object_offset_t
*hi_offset
, /* OUT */
7568 vm_map_entry_t entry
;
7569 register vm_map_t map
= *var_map
;
7570 vm_map_t old_map
= *var_map
;
7571 vm_map_t cow_sub_map_parent
= VM_MAP_NULL
;
7572 vm_offset_t cow_parent_vaddr
;
7573 vm_offset_t old_start
;
7574 vm_offset_t old_end
;
7575 register vm_prot_t prot
;
7581 * If the map has an interesting hint, try it before calling
7582 * full blown lookup routine.
7585 mutex_lock(&map
->s_lock
);
7587 mutex_unlock(&map
->s_lock
);
7589 if ((entry
== vm_map_to_entry(map
)) ||
7590 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
7591 vm_map_entry_t tmp_entry
;
7594 * Entry was either not a valid hint, or the vaddr
7595 * was not contained in the entry, so do a full lookup.
7597 if (!vm_map_lookup_entry(map
, vaddr
, &tmp_entry
)) {
7598 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
))
7599 vm_map_unlock(cow_sub_map_parent
);
7600 if((*pmap_map
!= map
)
7601 && (*pmap_map
!= cow_sub_map_parent
))
7602 vm_map_unlock(*pmap_map
);
7603 return KERN_INVALID_ADDRESS
;
7608 if(map
== old_map
) {
7609 old_start
= entry
->vme_start
;
7610 old_end
= entry
->vme_end
;
7614 * Handle submaps. Drop lock on upper map, submap is
7619 if (entry
->is_sub_map
) {
7620 vm_offset_t local_vaddr
;
7621 vm_offset_t end_delta
;
7622 vm_offset_t start_delta
;
7623 vm_offset_t object_start_delta
;
7624 vm_map_entry_t submap_entry
;
7625 boolean_t mapped_needs_copy
=FALSE
;
7627 local_vaddr
= vaddr
;
7629 if ((!entry
->needs_copy
) && (entry
->use_pmap
)) {
7630 /* if pmap_map equals map we unlock below */
7631 if ((*pmap_map
!= map
) &&
7632 (*pmap_map
!= cow_sub_map_parent
))
7633 vm_map_unlock(*pmap_map
);
7634 *pmap_map
= entry
->object
.sub_map
;
7637 if(entry
->needs_copy
) {
7638 if (!mapped_needs_copy
) {
7639 if (vm_map_lock_read_to_write(map
)) {
7640 vm_map_lock_read(map
);
7641 if(*pmap_map
== entry
->object
.sub_map
)
7645 vm_map_lock_read(entry
->object
.sub_map
);
7646 cow_sub_map_parent
= map
;
7647 /* reset base to map before cow object */
7648 /* this is the map which will accept */
7649 /* the new cow object */
7650 old_start
= entry
->vme_start
;
7651 old_end
= entry
->vme_end
;
7652 cow_parent_vaddr
= vaddr
;
7653 mapped_needs_copy
= TRUE
;
7655 vm_map_lock_read(entry
->object
.sub_map
);
7656 if((cow_sub_map_parent
!= map
) &&
7661 vm_map_lock_read(entry
->object
.sub_map
);
7662 /* leave map locked if it is a target */
7663 /* cow sub_map above otherwise, just */
7664 /* follow the maps down to the object */
7665 /* here we unlock knowing we are not */
7666 /* revisiting the map. */
7667 if((*pmap_map
!= map
) && (map
!= cow_sub_map_parent
))
7668 vm_map_unlock_read(map
);
7671 *var_map
= map
= entry
->object
.sub_map
;
7673 /* calculate the offset in the submap for vaddr */
7674 local_vaddr
= (local_vaddr
- entry
->vme_start
) + entry
->offset
;
7677 if(!vm_map_lookup_entry(map
, local_vaddr
, &submap_entry
)) {
7678 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
)){
7679 vm_map_unlock(cow_sub_map_parent
);
7681 if((*pmap_map
!= map
)
7682 && (*pmap_map
!= cow_sub_map_parent
)) {
7683 vm_map_unlock(*pmap_map
);
7686 return KERN_INVALID_ADDRESS
;
7688 /* find the attenuated shadow of the underlying object */
7689 /* on our target map */
7691 /* in english the submap object may extend beyond the */
7692 /* region mapped by the entry or, may only fill a portion */
7693 /* of it. For our purposes, we only care if the object */
7694 /* doesn't fill. In this case the area which will */
7695 /* ultimately be clipped in the top map will only need */
7696 /* to be as big as the portion of the underlying entry */
7697 /* which is mapped */
7698 start_delta
= submap_entry
->vme_start
> entry
->offset
?
7699 submap_entry
->vme_start
- entry
->offset
: 0;
7702 (entry
->offset
+ start_delta
+ (old_end
- old_start
)) <=
7703 submap_entry
->vme_end
?
7704 0 : (entry
->offset
+
7705 (old_end
- old_start
))
7706 - submap_entry
->vme_end
;
7708 old_start
+= start_delta
;
7709 old_end
-= end_delta
;
7711 if(submap_entry
->is_sub_map
) {
7712 entry
= submap_entry
;
7713 vaddr
= local_vaddr
;
7714 goto submap_recurse
;
7717 if(((fault_type
& VM_PROT_WRITE
) && cow_sub_map_parent
)) {
7719 vm_object_t copy_object
;
7720 vm_offset_t local_start
;
7721 vm_offset_t local_end
;
7723 if (vm_map_lock_read_to_write(map
)) {
7724 vm_map_lock_read(map
);
7725 old_start
-= start_delta
;
7726 old_end
+= end_delta
;
7729 if (submap_entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7730 submap_entry
->object
.vm_object
=
7733 (submap_entry
->vme_end
7734 - submap_entry
->vme_start
));
7735 submap_entry
->offset
= 0;
7737 local_start
= local_vaddr
-
7738 (cow_parent_vaddr
- old_start
);
7739 local_end
= local_vaddr
+
7740 (old_end
- cow_parent_vaddr
);
7741 vm_map_clip_start(map
, submap_entry
, local_start
);
7742 vm_map_clip_end(map
, submap_entry
, local_end
);
7744 /* This is the COW case, lets connect */
7745 /* an entry in our space to the underlying */
7746 /* object in the submap, bypassing the */
7749 /* set up shadow object */
7750 copy_object
= submap_entry
->object
.vm_object
;
7751 submap_entry
->object
.vm_object
->shadowed
= TRUE
;
7752 submap_entry
->needs_copy
= TRUE
;
7753 vm_object_pmap_protect(submap_entry
->object
.vm_object
,
7754 submap_entry
->offset
,
7755 submap_entry
->vme_end
-
7756 submap_entry
->vme_start
,
7757 submap_entry
->is_shared
?
7758 PMAP_NULL
: map
->pmap
,
7759 submap_entry
->vme_start
,
7760 submap_entry
->protection
&
7764 /* This works diffently than the */
7765 /* normal submap case. We go back */
7766 /* to the parent of the cow map and*/
7767 /* clip out the target portion of */
7768 /* the sub_map, substituting the */
7769 /* new copy object, */
7772 local_start
= old_start
;
7773 local_end
= old_end
;
7774 map
= cow_sub_map_parent
;
7775 *var_map
= cow_sub_map_parent
;
7776 vaddr
= cow_parent_vaddr
;
7777 cow_sub_map_parent
= NULL
;
7779 if(!vm_map_lookup_entry(map
,
7781 vm_object_deallocate(
7783 vm_map_lock_write_to_read(map
);
7784 return KERN_INVALID_ADDRESS
;
7787 /* clip out the portion of space */
7788 /* mapped by the sub map which */
7789 /* corresponds to the underlying */
7791 vm_map_clip_start(map
, entry
, local_start
);
7792 vm_map_clip_end(map
, entry
, local_end
);
7795 /* substitute copy object for */
7796 /* shared map entry */
7797 vm_map_deallocate(entry
->object
.sub_map
);
7798 entry
->is_sub_map
= FALSE
;
7799 vm_object_reference(copy_object
);
7800 entry
->object
.vm_object
= copy_object
;
7801 entry
->offset
= submap_entry
->offset
;
7803 entry
->protection
|= VM_PROT_WRITE
;
7804 entry
->max_protection
|= VM_PROT_WRITE
;
7805 entry
->needs_copy
= TRUE
;
7806 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7807 entry
->inheritance
= VM_INHERIT_COPY
;
7809 entry
->is_shared
= TRUE
;
7811 vm_map_lock_write_to_read(map
);
7813 if((cow_sub_map_parent
)
7814 && (cow_sub_map_parent
!= *pmap_map
)
7815 && (cow_sub_map_parent
!= map
)) {
7816 vm_map_unlock(cow_sub_map_parent
);
7818 entry
= submap_entry
;
7819 vaddr
= local_vaddr
;
7824 * Check whether this task is allowed to have
7828 prot
= entry
->protection
;
7829 if ((fault_type
& (prot
)) != fault_type
) {
7830 if (*pmap_map
!= map
) {
7831 vm_map_unlock(*pmap_map
);
7834 return KERN_PROTECTION_FAILURE
;
7838 * If this page is not pageable, we have to get
7839 * it for all possible accesses.
7842 if (*wired
= (entry
->wired_count
!= 0))
7843 prot
= fault_type
= entry
->protection
;
7846 * If the entry was copy-on-write, we either ...
7849 if (entry
->needs_copy
) {
7851 * If we want to write the page, we may as well
7852 * handle that now since we've got the map locked.
7854 * If we don't need to write the page, we just
7855 * demote the permissions allowed.
7858 if (fault_type
& VM_PROT_WRITE
|| *wired
) {
7860 * Make a new object, and place it in the
7861 * object chain. Note that no new references
7862 * have appeared -- one just moved from the
7863 * map to the new object.
7866 if (vm_map_lock_read_to_write(map
)) {
7867 vm_map_lock_read(map
);
7870 vm_object_shadow(&entry
->object
.vm_object
,
7872 (vm_size_t
) (entry
->vme_end
-
7875 entry
->object
.vm_object
->shadowed
= TRUE
;
7876 entry
->needs_copy
= FALSE
;
7877 vm_map_lock_write_to_read(map
);
7881 * We're attempting to read a copy-on-write
7882 * page -- don't allow writes.
7885 prot
&= (~VM_PROT_WRITE
);
7890 * Create an object if necessary.
7892 if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7894 if (vm_map_lock_read_to_write(map
)) {
7895 vm_map_lock_read(map
);
7899 entry
->object
.vm_object
= vm_object_allocate(
7900 (vm_size_t
)(entry
->vme_end
- entry
->vme_start
));
7902 vm_map_lock_write_to_read(map
);
7906 * Return the object/offset from this entry. If the entry
7907 * was copy-on-write or empty, it has been fixed up. Also
7908 * return the protection.
7911 *offset
= (vaddr
- entry
->vme_start
) + entry
->offset
;
7912 *object
= entry
->object
.vm_object
;
7914 *behavior
= entry
->behavior
;
7915 *lo_offset
= entry
->offset
;
7916 *hi_offset
= (entry
->vme_end
- entry
->vme_start
) + entry
->offset
;
7919 * Lock the object to prevent it from disappearing
7922 vm_object_lock(*object
);
7925 * Save the version number
7928 out_version
->main_timestamp
= map
->timestamp
;
7930 return KERN_SUCCESS
;
7937 * Verifies that the map in question has not changed
7938 * since the given version. If successful, the map
7939 * will not change until vm_map_verify_done() is called.
7943 register vm_map_t map
,
7944 register vm_map_version_t
*version
) /* REF */
7948 vm_map_lock_read(map
);
7949 result
= (map
->timestamp
== version
->main_timestamp
);
7952 vm_map_unlock_read(map
);
7958 * vm_map_verify_done:
7960 * Releases locks acquired by a vm_map_verify.
7962 * This is now a macro in vm/vm_map.h. It does a
7963 * vm_map_unlock_read on the map.
7970 * User call to obtain information about a region in
7971 * a task's address map. Currently, only one flavor is
7974 * XXX The reserved and behavior fields cannot be filled
7975 * in until the vm merge from the IK is completed, and
7976 * vm_reserve is implemented.
7978 * XXX Dependency: syscall_vm_region() also supports only one flavor.
7984 vm_offset_t
*address
, /* IN/OUT */
7985 vm_size_t
*size
, /* OUT */
7986 vm_region_flavor_t flavor
, /* IN */
7987 vm_region_info_t info
, /* OUT */
7988 mach_msg_type_number_t
*count
, /* IN/OUT */
7989 ipc_port_t
*object_name
) /* OUT */
7991 vm_map_entry_t tmp_entry
;
7993 vm_map_entry_t entry
;
7996 vm_region_basic_info_t basic
;
7997 vm_region_extended_info_t extended
;
7998 vm_region_top_info_t top
;
8000 if (map
== VM_MAP_NULL
)
8001 return(KERN_INVALID_ARGUMENT
);
8005 case VM_REGION_BASIC_INFO
:
8007 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
8008 return(KERN_INVALID_ARGUMENT
);
8010 basic
= (vm_region_basic_info_t
) info
;
8011 *count
= VM_REGION_BASIC_INFO_COUNT
;
8013 vm_map_lock_read(map
);
8016 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8017 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8018 vm_map_unlock_read(map
);
8019 return(KERN_INVALID_ADDRESS
);
8025 start
= entry
->vme_start
;
8027 basic
->offset
= entry
->offset
;
8028 basic
->protection
= entry
->protection
;
8029 basic
->inheritance
= entry
->inheritance
;
8030 basic
->max_protection
= entry
->max_protection
;
8031 basic
->behavior
= entry
->behavior
;
8032 basic
->user_wired_count
= entry
->user_wired_count
;
8033 basic
->reserved
= entry
->is_sub_map
;
8035 *size
= (entry
->vme_end
- start
);
8037 if (object_name
) *object_name
= IP_NULL
;
8038 if (entry
->is_sub_map
) {
8039 basic
->shared
= FALSE
;
8041 basic
->shared
= entry
->is_shared
;
8044 vm_map_unlock_read(map
);
8045 return(KERN_SUCCESS
);
8047 case VM_REGION_EXTENDED_INFO
:
8050 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
8051 return(KERN_INVALID_ARGUMENT
);
8053 extended
= (vm_region_extended_info_t
) info
;
8054 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
8056 vm_map_lock_read(map
);
8059 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8060 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8061 vm_map_unlock_read(map
);
8062 return(KERN_INVALID_ADDRESS
);
8067 start
= entry
->vme_start
;
8069 extended
->protection
= entry
->protection
;
8070 extended
->user_tag
= entry
->alias
;
8071 extended
->pages_resident
= 0;
8072 extended
->pages_swapped_out
= 0;
8073 extended
->pages_shared_now_private
= 0;
8074 extended
->pages_referenced
= 0;
8075 extended
->external_pager
= 0;
8076 extended
->shadow_depth
= 0;
8078 vm_region_walk(entry
, extended
, entry
->offset
, entry
->vme_end
- start
, map
, start
);
8080 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
8081 extended
->share_mode
= SM_PRIVATE
;
8084 *object_name
= IP_NULL
;
8086 *size
= (entry
->vme_end
- start
);
8088 vm_map_unlock_read(map
);
8089 return(KERN_SUCCESS
);
8091 case VM_REGION_TOP_INFO
:
8094 if (*count
< VM_REGION_TOP_INFO_COUNT
)
8095 return(KERN_INVALID_ARGUMENT
);
8097 top
= (vm_region_top_info_t
) info
;
8098 *count
= VM_REGION_TOP_INFO_COUNT
;
8100 vm_map_lock_read(map
);
8103 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8104 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8105 vm_map_unlock_read(map
);
8106 return(KERN_INVALID_ADDRESS
);
8112 start
= entry
->vme_start
;
8114 top
->private_pages_resident
= 0;
8115 top
->shared_pages_resident
= 0;
8117 vm_region_top_walk(entry
, top
);
8120 *object_name
= IP_NULL
;
8122 *size
= (entry
->vme_end
- start
);
8124 vm_map_unlock_read(map
);
8125 return(KERN_SUCCESS
);
8128 return(KERN_INVALID_ARGUMENT
);
8133 * vm_region_recurse: A form of vm_region which follows the
8134 * submaps in a target map
8141 vm_offset_t
*address
, /* IN/OUT */
8142 vm_size_t
*size
, /* OUT */
8143 natural_t
*nesting_depth
, /* IN/OUT */
8144 vm_region_recurse_info_t info
, /* IN/OUT */
8145 mach_msg_type_number_t
*count
) /* IN/OUT */
8147 vm_map_entry_t tmp_entry
;
8149 vm_map_entry_t entry
;
8153 unsigned int recurse_count
;
8156 vm_map_entry_t base_entry
;
8157 vm_offset_t base_next
;
8158 vm_offset_t base_addr
;
8159 vm_offset_t baddr_start_delta
;
8160 vm_region_submap_info_t submap_info
;
8161 vm_region_extended_info_data_t extended
;
8163 if (map
== VM_MAP_NULL
)
8164 return(KERN_INVALID_ARGUMENT
);
8166 submap_info
= (vm_region_submap_info_t
) info
;
8167 *count
= VM_REGION_SUBMAP_INFO_COUNT
;
8169 if (*count
< VM_REGION_SUBMAP_INFO_COUNT
)
8170 return(KERN_INVALID_ARGUMENT
);
8174 recurse_count
= *nesting_depth
;
8176 LOOKUP_NEXT_BASE_ENTRY
:
8177 vm_map_lock_read(map
);
8178 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8179 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8180 vm_map_unlock_read(map
);
8181 return(KERN_INVALID_ADDRESS
);
8186 *size
= entry
->vme_end
- entry
->vme_start
;
8187 start
= entry
->vme_start
;
8189 baddr_start_delta
= *address
- start
;
8190 base_next
= entry
->vme_end
;
8193 while(entry
->is_sub_map
&& recurse_count
) {
8195 vm_map_lock_read(entry
->object
.sub_map
);
8198 if(entry
== base_entry
) {
8199 start
= entry
->offset
;
8200 start
+= *address
- entry
->vme_start
;
8203 submap
= entry
->object
.sub_map
;
8204 vm_map_unlock_read(map
);
8207 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8208 if ((entry
= tmp_entry
->vme_next
)
8209 == vm_map_to_entry(map
)) {
8210 vm_map_unlock_read(map
);
8215 goto LOOKUP_NEXT_BASE_ENTRY
;
8221 if(start
<= entry
->vme_start
) {
8222 vm_offset_t old_start
= start
;
8223 if(baddr_start_delta
) {
8224 base_addr
+= (baddr_start_delta
);
8225 *size
-= baddr_start_delta
;
8226 baddr_start_delta
= 0;
8229 (base_addr
+= (entry
->vme_start
- start
))) {
8230 vm_map_unlock_read(map
);
8235 goto LOOKUP_NEXT_BASE_ENTRY
;
8237 *size
-= entry
->vme_start
- start
;
8238 if (*size
> (entry
->vme_end
- entry
->vme_start
)) {
8239 *size
= entry
->vme_end
- entry
->vme_start
;
8243 if(baddr_start_delta
) {
8244 if((start
- entry
->vme_start
)
8245 < baddr_start_delta
) {
8246 base_addr
+= start
- entry
->vme_start
;
8247 *size
-= start
- entry
->vme_start
;
8249 base_addr
+= baddr_start_delta
;
8250 *size
+= baddr_start_delta
;
8252 baddr_start_delta
= 0;
8254 base_addr
+= entry
->vme_start
;
8255 if(base_addr
>= base_next
) {
8256 vm_map_unlock_read(map
);
8261 goto LOOKUP_NEXT_BASE_ENTRY
;
8263 if (*size
> (entry
->vme_end
- start
))
8264 *size
= entry
->vme_end
- start
;
8266 start
= entry
->vme_start
- start
;
8269 start
+= entry
->offset
;
8272 *nesting_depth
-= recurse_count
;
8273 if(entry
!= base_entry
) {
8274 start
= entry
->vme_start
+ (start
- entry
->offset
);
8278 submap_info
->user_tag
= entry
->alias
;
8279 submap_info
->offset
= entry
->offset
;
8280 submap_info
->protection
= entry
->protection
;
8281 submap_info
->inheritance
= entry
->inheritance
;
8282 submap_info
->max_protection
= entry
->max_protection
;
8283 submap_info
->behavior
= entry
->behavior
;
8284 submap_info
->user_wired_count
= entry
->user_wired_count
;
8285 submap_info
->is_submap
= entry
->is_sub_map
;
8286 submap_info
->object_id
= (vm_offset_t
)entry
->object
.vm_object
;
8287 *address
= base_addr
;
8290 extended
.pages_resident
= 0;
8291 extended
.pages_swapped_out
= 0;
8292 extended
.pages_shared_now_private
= 0;
8293 extended
.pages_referenced
= 0;
8294 extended
.external_pager
= 0;
8295 extended
.shadow_depth
= 0;
8297 if(!entry
->is_sub_map
) {
8298 vm_region_walk(entry
, &extended
, entry
->offset
,
8299 entry
->vme_end
- start
, map
, start
);
8300 submap_info
->share_mode
= extended
.share_mode
;
8301 if (extended
.external_pager
&& extended
.ref_count
== 2
8302 && extended
.share_mode
== SM_SHARED
)
8303 submap_info
->share_mode
= SM_PRIVATE
;
8304 submap_info
->ref_count
= extended
.ref_count
;
8307 submap_info
->share_mode
= SM_TRUESHARED
;
8309 submap_info
->share_mode
= SM_PRIVATE
;
8310 submap_info
->ref_count
= entry
->object
.sub_map
->ref_count
;
8313 submap_info
->pages_resident
= extended
.pages_resident
;
8314 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
8315 submap_info
->pages_shared_now_private
=
8316 extended
.pages_shared_now_private
;
8317 submap_info
->pages_referenced
= extended
.pages_referenced
;
8318 submap_info
->external_pager
= extended
.external_pager
;
8319 submap_info
->shadow_depth
= extended
.shadow_depth
;
8321 vm_map_unlock_read(map
);
8322 return(KERN_SUCCESS
);
8326 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
8327 * Goes away after regular vm_region_recurse function migrates to
8329 * vm_region_recurse: A form of vm_region which follows the
8330 * submaps in a target map
8335 vm_region_recurse_64(
8337 vm_offset_t
*address
, /* IN/OUT */
8338 vm_size_t
*size
, /* OUT */
8339 natural_t
*nesting_depth
, /* IN/OUT */
8340 vm_region_recurse_info_t info
, /* IN/OUT */
8341 mach_msg_type_number_t
*count
) /* IN/OUT */
8343 vm_map_entry_t tmp_entry
;
8345 vm_map_entry_t entry
;
8349 unsigned int recurse_count
;
8352 vm_map_entry_t base_entry
;
8353 vm_offset_t base_next
;
8354 vm_offset_t base_addr
;
8355 vm_offset_t baddr_start_delta
;
8356 vm_region_submap_info_64_t submap_info
;
8357 vm_region_extended_info_data_t extended
;
8359 if (map
== VM_MAP_NULL
)
8360 return(KERN_INVALID_ARGUMENT
);
8362 submap_info
= (vm_region_submap_info_64_t
) info
;
8363 *count
= VM_REGION_SUBMAP_INFO_COUNT
;
8365 if (*count
< VM_REGION_SUBMAP_INFO_COUNT
)
8366 return(KERN_INVALID_ARGUMENT
);
8370 recurse_count
= *nesting_depth
;
8372 LOOKUP_NEXT_BASE_ENTRY
:
8373 vm_map_lock_read(map
);
8374 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8375 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8376 vm_map_unlock_read(map
);
8377 return(KERN_INVALID_ADDRESS
);
8382 *size
= entry
->vme_end
- entry
->vme_start
;
8383 start
= entry
->vme_start
;
8385 baddr_start_delta
= *address
- start
;
8386 base_next
= entry
->vme_end
;
8389 while(entry
->is_sub_map
&& recurse_count
) {
8391 vm_map_lock_read(entry
->object
.sub_map
);
8394 if(entry
== base_entry
) {
8395 start
= entry
->offset
;
8396 start
+= *address
- entry
->vme_start
;
8399 submap
= entry
->object
.sub_map
;
8400 vm_map_unlock_read(map
);
8403 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8404 if ((entry
= tmp_entry
->vme_next
)
8405 == vm_map_to_entry(map
)) {
8406 vm_map_unlock_read(map
);
8411 goto LOOKUP_NEXT_BASE_ENTRY
;
8417 if(start
<= entry
->vme_start
) {
8418 vm_offset_t old_start
= start
;
8419 if(baddr_start_delta
) {
8420 base_addr
+= (baddr_start_delta
);
8421 *size
-= baddr_start_delta
;
8422 baddr_start_delta
= 0;
8425 (base_addr
+= (entry
->vme_start
- start
))) {
8426 vm_map_unlock_read(map
);
8431 goto LOOKUP_NEXT_BASE_ENTRY
;
8433 *size
-= entry
->vme_start
- start
;
8434 if (*size
> (entry
->vme_end
- entry
->vme_start
)) {
8435 *size
= entry
->vme_end
- entry
->vme_start
;
8439 if(baddr_start_delta
) {
8440 if((start
- entry
->vme_start
)
8441 < baddr_start_delta
) {
8442 base_addr
+= start
- entry
->vme_start
;
8443 *size
-= start
- entry
->vme_start
;
8445 base_addr
+= baddr_start_delta
;
8446 *size
+= baddr_start_delta
;
8448 baddr_start_delta
= 0;
8450 base_addr
+= entry
->vme_start
;
8451 if(base_addr
>= base_next
) {
8452 vm_map_unlock_read(map
);
8457 goto LOOKUP_NEXT_BASE_ENTRY
;
8459 if (*size
> (entry
->vme_end
- start
))
8460 *size
= entry
->vme_end
- start
;
8462 start
= entry
->vme_start
- start
;
8465 start
+= entry
->offset
;
8468 *nesting_depth
-= recurse_count
;
8469 if(entry
!= base_entry
) {
8470 start
= entry
->vme_start
+ (start
- entry
->offset
);
8474 submap_info
->user_tag
= entry
->alias
;
8475 submap_info
->offset
= entry
->offset
;
8476 submap_info
->protection
= entry
->protection
;
8477 submap_info
->inheritance
= entry
->inheritance
;
8478 submap_info
->max_protection
= entry
->max_protection
;
8479 submap_info
->behavior
= entry
->behavior
;
8480 submap_info
->user_wired_count
= entry
->user_wired_count
;
8481 submap_info
->is_submap
= entry
->is_sub_map
;
8482 submap_info
->object_id
= (vm_offset_t
)entry
->object
.vm_object
;
8483 *address
= base_addr
;
8486 extended
.pages_resident
= 0;
8487 extended
.pages_swapped_out
= 0;
8488 extended
.pages_shared_now_private
= 0;
8489 extended
.pages_referenced
= 0;
8490 extended
.external_pager
= 0;
8491 extended
.shadow_depth
= 0;
8493 if(!entry
->is_sub_map
) {
8494 vm_region_walk(entry
, &extended
, entry
->offset
,
8495 entry
->vme_end
- start
, map
, start
);
8496 submap_info
->share_mode
= extended
.share_mode
;
8497 if (extended
.external_pager
&& extended
.ref_count
== 2
8498 && extended
.share_mode
== SM_SHARED
)
8499 submap_info
->share_mode
= SM_PRIVATE
;
8500 submap_info
->ref_count
= extended
.ref_count
;
8503 submap_info
->share_mode
= SM_TRUESHARED
;
8505 submap_info
->share_mode
= SM_PRIVATE
;
8506 submap_info
->ref_count
= entry
->object
.sub_map
->ref_count
;
8509 submap_info
->pages_resident
= extended
.pages_resident
;
8510 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
8511 submap_info
->pages_shared_now_private
=
8512 extended
.pages_shared_now_private
;
8513 submap_info
->pages_referenced
= extended
.pages_referenced
;
8514 submap_info
->external_pager
= extended
.external_pager
;
8515 submap_info
->shadow_depth
= extended
.shadow_depth
;
8517 vm_map_unlock_read(map
);
8518 return(KERN_SUCCESS
);
8523 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
8524 * Goes away after regular vm_region function migrates to
8532 vm_offset_t
*address
, /* IN/OUT */
8533 vm_size_t
*size
, /* OUT */
8534 vm_region_flavor_t flavor
, /* IN */
8535 vm_region_info_t info
, /* OUT */
8536 mach_msg_type_number_t
*count
, /* IN/OUT */
8537 ipc_port_t
*object_name
) /* OUT */
8539 vm_map_entry_t tmp_entry
;
8541 vm_map_entry_t entry
;
8544 vm_region_basic_info_64_t basic
;
8545 vm_region_extended_info_t extended
;
8546 vm_region_top_info_t top
;
8548 if (map
== VM_MAP_NULL
)
8549 return(KERN_INVALID_ARGUMENT
);
8553 case VM_REGION_BASIC_INFO
:
8555 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
8556 return(KERN_INVALID_ARGUMENT
);
8558 basic
= (vm_region_basic_info_64_t
) info
;
8559 *count
= VM_REGION_BASIC_INFO_COUNT
;
8561 vm_map_lock_read(map
);
8564 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8565 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8566 vm_map_unlock_read(map
);
8567 return(KERN_INVALID_ADDRESS
);
8573 start
= entry
->vme_start
;
8575 basic
->offset
= entry
->offset
;
8576 basic
->protection
= entry
->protection
;
8577 basic
->inheritance
= entry
->inheritance
;
8578 basic
->max_protection
= entry
->max_protection
;
8579 basic
->behavior
= entry
->behavior
;
8580 basic
->user_wired_count
= entry
->user_wired_count
;
8581 basic
->reserved
= entry
->is_sub_map
;
8583 *size
= (entry
->vme_end
- start
);
8585 if (object_name
) *object_name
= IP_NULL
;
8586 if (entry
->is_sub_map
) {
8587 basic
->shared
= FALSE
;
8589 basic
->shared
= entry
->is_shared
;
8592 vm_map_unlock_read(map
);
8593 return(KERN_SUCCESS
);
8595 case VM_REGION_EXTENDED_INFO
:
8598 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
8599 return(KERN_INVALID_ARGUMENT
);
8601 extended
= (vm_region_extended_info_t
) info
;
8602 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
8604 vm_map_lock_read(map
);
8607 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8608 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8609 vm_map_unlock_read(map
);
8610 return(KERN_INVALID_ADDRESS
);
8615 start
= entry
->vme_start
;
8617 extended
->protection
= entry
->protection
;
8618 extended
->user_tag
= entry
->alias
;
8619 extended
->pages_resident
= 0;
8620 extended
->pages_swapped_out
= 0;
8621 extended
->pages_shared_now_private
= 0;
8622 extended
->pages_referenced
= 0;
8623 extended
->external_pager
= 0;
8624 extended
->shadow_depth
= 0;
8626 vm_region_walk(entry
, extended
, entry
->offset
, entry
->vme_end
- start
, map
, start
);
8628 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
8629 extended
->share_mode
= SM_PRIVATE
;
8632 *object_name
= IP_NULL
;
8634 *size
= (entry
->vme_end
- start
);
8636 vm_map_unlock_read(map
);
8637 return(KERN_SUCCESS
);
8639 case VM_REGION_TOP_INFO
:
8642 if (*count
< VM_REGION_TOP_INFO_COUNT
)
8643 return(KERN_INVALID_ARGUMENT
);
8645 top
= (vm_region_top_info_t
) info
;
8646 *count
= VM_REGION_TOP_INFO_COUNT
;
8648 vm_map_lock_read(map
);
8651 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8652 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8653 vm_map_unlock_read(map
);
8654 return(KERN_INVALID_ADDRESS
);
8660 start
= entry
->vme_start
;
8662 top
->private_pages_resident
= 0;
8663 top
->shared_pages_resident
= 0;
8665 vm_region_top_walk(entry
, top
);
8668 *object_name
= IP_NULL
;
8670 *size
= (entry
->vme_end
- start
);
8672 vm_map_unlock_read(map
);
8673 return(KERN_SUCCESS
);
8676 return(KERN_INVALID_ARGUMENT
);
8682 vm_map_entry_t entry
,
8683 vm_region_top_info_t top
)
8685 register struct vm_object
*obj
, *tmp_obj
;
8687 if (entry
->object
.vm_object
== 0) {
8688 top
->share_mode
= SM_EMPTY
;
8693 if (entry
->is_sub_map
)
8694 vm_region_top_walk((vm_map_entry_t
)entry
->object
.sub_map
, top
);
8696 obj
= entry
->object
.vm_object
;
8698 vm_object_lock(obj
);
8701 if (obj
->ref_count
== 1)
8702 top
->private_pages_resident
= obj
->resident_page_count
;
8704 top
->shared_pages_resident
= obj
->resident_page_count
;
8705 top
->ref_count
= obj
->ref_count
;
8706 top
->share_mode
= SM_COW
;
8708 while (tmp_obj
= obj
->shadow
) {
8709 vm_object_lock(tmp_obj
);
8710 vm_object_unlock(obj
);
8713 top
->shared_pages_resident
+= obj
->resident_page_count
;
8714 top
->ref_count
+= obj
->ref_count
- 1;
8717 if (entry
->needs_copy
) {
8718 top
->share_mode
= SM_COW
;
8719 top
->shared_pages_resident
= obj
->resident_page_count
;
8721 if (obj
->ref_count
== 1 ||
8722 (obj
->ref_count
== 2 && !(obj
->pager_trusted
) && !(obj
->internal
))) {
8723 top
->share_mode
= SM_PRIVATE
;
8724 top
->private_pages_resident
= obj
->resident_page_count
;
8726 top
->share_mode
= SM_SHARED
;
8727 top
->shared_pages_resident
= obj
->resident_page_count
;
8730 top
->ref_count
= obj
->ref_count
;
8732 top
->obj_id
= (int)obj
;
8734 vm_object_unlock(obj
);
8740 vm_map_entry_t entry
,
8741 vm_region_extended_info_t extended
,
8742 vm_object_offset_t offset
,
8747 register struct vm_object
*obj
, *tmp_obj
;
8748 register vm_offset_t last_offset
;
8750 void vm_region_look_for_page();
8752 if (entry
->object
.vm_object
== 0) {
8753 extended
->share_mode
= SM_EMPTY
;
8754 extended
->ref_count
= 0;
8757 if (entry
->is_sub_map
)
8758 vm_region_walk((vm_map_entry_t
)entry
->object
.sub_map
, extended
, offset
+ entry
->offset
,
8761 obj
= entry
->object
.vm_object
;
8763 vm_object_lock(obj
);
8765 for (last_offset
= offset
+ range
; offset
< last_offset
; offset
+= PAGE_SIZE_64
, va
+= PAGE_SIZE
)
8766 vm_region_look_for_page(obj
, extended
, offset
, obj
->ref_count
, 0, map
, va
);
8768 if (extended
->shadow_depth
|| entry
->needs_copy
)
8769 extended
->share_mode
= SM_COW
;
8771 if (obj
->ref_count
== 1)
8772 extended
->share_mode
= SM_PRIVATE
;
8774 if (obj
->true_share
)
8775 extended
->share_mode
= SM_TRUESHARED
;
8777 extended
->share_mode
= SM_SHARED
;
8780 extended
->ref_count
= obj
->ref_count
- extended
->shadow_depth
;
8782 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
8783 if ((tmp_obj
= obj
->shadow
) == 0)
8785 vm_object_lock(tmp_obj
);
8786 vm_object_unlock(obj
);
8787 extended
->ref_count
+= tmp_obj
->ref_count
;
8790 vm_object_unlock(obj
);
8792 if (extended
->share_mode
== SM_SHARED
) {
8793 register vm_map_entry_t cur
;
8794 register vm_map_entry_t last
;
8797 obj
= entry
->object
.vm_object
;
8798 last
= vm_map_to_entry(map
);
8801 for (cur
= vm_map_first_entry(map
); cur
!= last
; cur
= cur
->vme_next
)
8802 my_refs
+= vm_region_count_obj_refs(cur
, obj
);
8804 if (my_refs
== obj
->ref_count
)
8805 extended
->share_mode
= SM_PRIVATE_ALIASED
;
8806 else if (my_refs
> 1)
8807 extended
->share_mode
= SM_SHARED_ALIASED
;
8815 vm_region_look_for_page(
8817 vm_region_extended_info_t extended
,
8818 vm_object_offset_t offset
,
8824 register vm_page_t p
;
8825 register vm_object_t shadow
;
8827 shadow
= object
->shadow
;
8829 if ( !(object
->pager_trusted
) && !(object
->internal
))
8830 extended
->external_pager
= 1;
8832 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
8833 if (shadow
&& (max_refcnt
== 1))
8834 extended
->pages_shared_now_private
++;
8836 if (pmap_extract(vm_map_pmap(map
), va
))
8837 extended
->pages_referenced
++;
8838 extended
->pages_resident
++;
8842 if (object
->existence_map
) {
8843 if (vm_external_state_get(object
->existence_map
, offset
) == VM_EXTERNAL_STATE_EXISTS
) {
8844 if (shadow
&& (max_refcnt
== 1))
8845 extended
->pages_shared_now_private
++;
8846 extended
->pages_swapped_out
++;
8852 vm_object_lock(shadow
);
8854 if (++depth
> extended
->shadow_depth
)
8855 extended
->shadow_depth
= depth
;
8857 if (shadow
->ref_count
> max_refcnt
)
8858 max_refcnt
= shadow
->ref_count
;
8860 vm_region_look_for_page(shadow
, extended
, offset
+ object
->shadow_offset
,
8861 max_refcnt
, depth
, map
, va
);
8862 vm_object_unlock(shadow
);
8869 vm_region_count_obj_refs(
8870 vm_map_entry_t entry
,
8873 register int ref_count
;
8874 register vm_object_t chk_obj
;
8875 register vm_object_t tmp_obj
;
8877 if (entry
->object
.vm_object
== 0)
8880 if (entry
->is_sub_map
)
8881 ref_count
= vm_region_count_obj_refs((vm_map_entry_t
)entry
->object
.sub_map
, object
);
8885 chk_obj
= entry
->object
.vm_object
;
8886 vm_object_lock(chk_obj
);
8889 if (chk_obj
== object
)
8891 if (tmp_obj
= chk_obj
->shadow
)
8892 vm_object_lock(tmp_obj
);
8893 vm_object_unlock(chk_obj
);
8903 * Routine: vm_map_simplify
8906 * Attempt to simplify the map representation in
8907 * the vicinity of the given starting address.
8909 * This routine is intended primarily to keep the
8910 * kernel maps more compact -- they generally don't
8911 * benefit from the "expand a map entry" technology
8912 * at allocation time because the adjacent entry
8913 * is often wired down.
8920 vm_map_entry_t this_entry
;
8921 vm_map_entry_t prev_entry
;
8922 vm_map_entry_t next_entry
;
8926 (vm_map_lookup_entry(map
, start
, &this_entry
)) &&
8927 ((prev_entry
= this_entry
->vme_prev
) != vm_map_to_entry(map
)) &&
8929 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
8931 (prev_entry
->is_shared
== FALSE
) &&
8932 (prev_entry
->is_sub_map
== FALSE
) &&
8934 (this_entry
->is_shared
== FALSE
) &&
8935 (this_entry
->is_sub_map
== FALSE
) &&
8937 (prev_entry
->inheritance
== this_entry
->inheritance
) &&
8938 (prev_entry
->protection
== this_entry
->protection
) &&
8939 (prev_entry
->max_protection
== this_entry
->max_protection
) &&
8940 (prev_entry
->behavior
== this_entry
->behavior
) &&
8941 (prev_entry
->wired_count
== this_entry
->wired_count
) &&
8942 (prev_entry
->user_wired_count
== this_entry
->user_wired_count
)&&
8943 (prev_entry
->in_transition
== FALSE
) &&
8944 (this_entry
->in_transition
== FALSE
) &&
8946 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
8948 (prev_entry
->object
.vm_object
== this_entry
->object
.vm_object
)&&
8949 ((prev_entry
->offset
+
8950 (prev_entry
->vme_end
- prev_entry
->vme_start
))
8951 == this_entry
->offset
)
8953 SAVE_HINT(map
, prev_entry
);
8954 vm_map_entry_unlink(map
, this_entry
);
8955 prev_entry
->vme_end
= this_entry
->vme_end
;
8956 UPDATE_FIRST_FREE(map
, map
->first_free
);
8957 vm_object_deallocate(this_entry
->object
.vm_object
);
8958 vm_map_entry_dispose(map
, this_entry
);
8959 counter(c_vm_map_simplified_lower
++);
8962 (vm_map_lookup_entry(map
, start
, &this_entry
)) &&
8963 ((next_entry
= this_entry
->vme_next
) != vm_map_to_entry(map
)) &&
8965 (next_entry
->vme_start
== this_entry
->vme_end
) &&
8967 (next_entry
->is_shared
== FALSE
) &&
8968 (next_entry
->is_sub_map
== FALSE
) &&
8970 (next_entry
->is_shared
== FALSE
) &&
8971 (next_entry
->is_sub_map
== FALSE
) &&
8973 (next_entry
->inheritance
== this_entry
->inheritance
) &&
8974 (next_entry
->protection
== this_entry
->protection
) &&
8975 (next_entry
->max_protection
== this_entry
->max_protection
) &&
8976 (next_entry
->behavior
== this_entry
->behavior
) &&
8977 (next_entry
->wired_count
== this_entry
->wired_count
) &&
8978 (next_entry
->user_wired_count
== this_entry
->user_wired_count
)&&
8979 (this_entry
->in_transition
== FALSE
) &&
8980 (next_entry
->in_transition
== FALSE
) &&
8982 (next_entry
->needs_copy
== this_entry
->needs_copy
) &&
8984 (next_entry
->object
.vm_object
== this_entry
->object
.vm_object
)&&
8985 ((this_entry
->offset
+
8986 (this_entry
->vme_end
- this_entry
->vme_start
))
8987 == next_entry
->offset
)
8989 vm_map_entry_unlink(map
, next_entry
);
8990 this_entry
->vme_end
= next_entry
->vme_end
;
8991 UPDATE_FIRST_FREE(map
, map
->first_free
);
8992 vm_object_deallocate(next_entry
->object
.vm_object
);
8993 vm_map_entry_dispose(map
, next_entry
);
8994 counter(c_vm_map_simplified_upper
++);
8996 counter(c_vm_map_simplify_called
++);
9002 * Routine: vm_map_machine_attribute
9004 * Provide machine-specific attributes to mappings,
9005 * such as cachability etc. for machines that provide
9006 * them. NUMA architectures and machines with big/strange
9007 * caches will use this.
9009 * Responsibilities for locking and checking are handled here,
9010 * everything else in the pmap module. If any non-volatile
9011 * information must be kept, the pmap module should handle
9012 * it itself. [This assumes that attributes do not
9013 * need to be inherited, which seems ok to me]
9016 vm_map_machine_attribute(
9018 vm_offset_t address
,
9020 vm_machine_attribute_t attribute
,
9021 vm_machine_attribute_val_t
* value
) /* IN/OUT */
9025 if (address
< vm_map_min(map
) ||
9026 (address
+ size
) > vm_map_max(map
))
9027 return KERN_INVALID_ADDRESS
;
9031 ret
= pmap_attribute(map
->pmap
, address
, size
, attribute
, value
);
9039 * vm_map_behavior_set:
9041 * Sets the paging reference behavior of the specified address
9042 * range in the target map. Paging reference behavior affects
9043 * how pagein operations resulting from faults on the map will be
9047 vm_map_behavior_set(
9051 vm_behavior_t new_behavior
)
9053 register vm_map_entry_t entry
;
9054 vm_map_entry_t temp_entry
;
9057 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
9058 (integer_t
)map
, start
, end
, new_behavior
, 0);
9060 switch (new_behavior
) {
9061 case VM_BEHAVIOR_DEFAULT
:
9062 case VM_BEHAVIOR_RANDOM
:
9063 case VM_BEHAVIOR_SEQUENTIAL
:
9064 case VM_BEHAVIOR_RSEQNTL
:
9067 return(KERN_INVALID_ARGUMENT
);
9073 * The entire address range must be valid for the map.
9074 * Note that vm_map_range_check() does a
9075 * vm_map_lookup_entry() internally and returns the
9076 * entry containing the start of the address range if
9077 * the entire range is valid.
9079 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
9081 vm_map_clip_start(map
, entry
, start
);
9085 return(KERN_INVALID_ADDRESS
);
9088 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
9089 vm_map_clip_end(map
, entry
, end
);
9091 entry
->behavior
= new_behavior
;
9093 entry
= entry
->vme_next
;
9097 return(KERN_SUCCESS
);
9102 vm_map_copy_cont_is_valid(
9105 vm_map_copy_cont_t cont
;
9107 assert(copy
->type
== VM_MAP_COPY_PAGE_LIST
);
9108 cont
= copy
->cpy_cont
;
9110 cont
!= vm_map_copy_discard_cont
&&
9111 cont
!= vm_map_copyin_page_list_cont
) {
9112 printf("vm_map_copy_cont_is_valid: bogus cont 0x%x\n", cont
);
9113 assert((integer_t
) cont
== 0xdeadbeef);
9118 #include <mach_kdb.h>
9120 #include <ddb/db_output.h>
9121 #include <vm/vm_print.h>
9123 #define printf db_printf
9126 * Forward declarations for internal functions.
9128 extern void vm_map_links_print(
9129 struct vm_map_links
*links
);
9131 extern void vm_map_header_print(
9132 struct vm_map_header
*header
);
9134 extern void vm_map_entry_print(
9135 vm_map_entry_t entry
);
9137 extern void vm_follow_entry(
9138 vm_map_entry_t entry
);
9140 extern void vm_follow_map(
9144 * vm_map_links_print: [ debug ]
9148 struct vm_map_links
*links
)
9150 iprintf("prev=0x%x, next=0x%x, start=0x%x, end=0x%x\n",
9158 * vm_map_header_print: [ debug ]
9161 vm_map_header_print(
9162 struct vm_map_header
*header
)
9164 vm_map_links_print(&header
->links
);
9165 iprintf("nentries=0x%x, %sentries_pageable\n",
9167 (header
->entries_pageable
? "" : "!"));
9171 * vm_follow_entry: [ debug ]
9175 vm_map_entry_t entry
)
9177 extern int db_indent
;
9180 iprintf("map entry 0x%x:\n", entry
);
9184 shadows
= vm_follow_object(entry
->object
.vm_object
);
9185 iprintf("Total objects : %d\n",shadows
);
9191 * vm_map_entry_print: [ debug ]
9195 register vm_map_entry_t entry
)
9197 extern int db_indent
;
9198 static char *inheritance_name
[4] = { "share", "copy", "none", "?"};
9199 static char *behavior_name
[4] = { "dflt", "rand", "seqtl", "rseqntl" };
9201 iprintf("map entry 0x%x:\n", entry
);
9205 vm_map_links_print(&entry
->links
);
9207 iprintf("start=0x%x, end=0x%x, prot=%x/%x/%s\n",
9211 entry
->max_protection
,
9212 inheritance_name
[(entry
->inheritance
& 0x3)]);
9214 iprintf("behavior=%s, wired_count=%d, user_wired_count=%d\n",
9215 behavior_name
[(entry
->behavior
& 0x3)],
9217 entry
->user_wired_count
);
9218 iprintf("%sin_transition, %sneeds_wakeup\n",
9219 (entry
->in_transition
? "" : "!"),
9220 (entry
->needs_wakeup
? "" : "!"));
9222 if (entry
->is_sub_map
) {
9223 iprintf("submap=0x%x, offset=0x%x\n",
9224 entry
->object
.sub_map
,
9227 iprintf("object=0x%x, offset=0x%x, ",
9228 entry
->object
.vm_object
,
9230 printf("%sis_shared, %sneeds_copy\n",
9231 (entry
->is_shared
? "" : "!"),
9232 (entry
->needs_copy
? "" : "!"));
9239 * vm_follow_map: [ debug ]
9245 register vm_map_entry_t entry
;
9246 extern int db_indent
;
9248 iprintf("task map 0x%x:\n", map
);
9252 for (entry
= vm_map_first_entry(map
);
9253 entry
&& entry
!= vm_map_to_entry(map
);
9254 entry
= entry
->vme_next
) {
9255 vm_follow_entry(entry
);
9262 * vm_map_print: [ debug ]
9266 register vm_map_t map
)
9268 register vm_map_entry_t entry
;
9269 extern int db_indent
;
9272 iprintf("task map 0x%x:\n", map
);
9276 vm_map_header_print(&map
->hdr
);
9278 iprintf("pmap=0x%x, size=%d, ref=%d, hint=0x%x, first_free=0x%x\n",
9285 iprintf("%swait_for_space, %swiring_required, timestamp=%d\n",
9286 (map
->wait_for_space
? "" : "!"),
9287 (map
->wiring_required
? "" : "!"),
9291 switch (map
->sw_state
) {
9302 iprintf("res=%d, sw_state=%s\n", map
->res_count
, swstate
);
9303 #endif /* TASK_SWAPPER */
9305 for (entry
= vm_map_first_entry(map
);
9306 entry
&& entry
!= vm_map_to_entry(map
);
9307 entry
= entry
->vme_next
) {
9308 vm_map_entry_print(entry
);
9315 * Routine: vm_map_copy_print
9317 * Pretty-print a copy object for ddb.
9324 extern int db_indent
;
9326 vm_map_entry_t entry
;
9328 printf("copy object 0x%x\n", copy
);
9332 iprintf("type=%d", copy
->type
);
9333 switch (copy
->type
) {
9334 case VM_MAP_COPY_ENTRY_LIST
:
9335 printf("[entry_list]");
9338 case VM_MAP_COPY_OBJECT
:
9342 case VM_MAP_COPY_PAGE_LIST
:
9343 printf("[page_list]");
9346 case VM_MAP_COPY_KERNEL_BUFFER
:
9347 printf("[kernel_buffer]");
9351 printf("[bad type]");
9354 printf(", offset=0x%x", copy
->offset
);
9355 printf(", size=0x%x\n", copy
->size
);
9357 switch (copy
->type
) {
9358 case VM_MAP_COPY_ENTRY_LIST
:
9359 vm_map_header_print(©
->cpy_hdr
);
9360 for (entry
= vm_map_copy_first_entry(copy
);
9361 entry
&& entry
!= vm_map_copy_to_entry(copy
);
9362 entry
= entry
->vme_next
) {
9363 vm_map_entry_print(entry
);
9367 case VM_MAP_COPY_OBJECT
:
9368 iprintf("object=0x%x\n", copy
->cpy_object
);
9371 case VM_MAP_COPY_KERNEL_BUFFER
:
9372 iprintf("kernel buffer=0x%x", copy
->cpy_kdata
);
9373 printf(", kalloc_size=0x%x\n", copy
->cpy_kalloc_size
);
9376 case VM_MAP_COPY_PAGE_LIST
:
9377 iprintf("npages=%d", copy
->cpy_npages
);
9378 printf(", cont=%x", copy
->cpy_cont
);
9379 printf(", cont_args=%x\n", copy
->cpy_cont_args
);
9380 if (copy
->cpy_npages
< 0) {
9382 } else if (copy
->cpy_npages
> VM_MAP_COPY_PAGE_LIST_MAX
) {
9383 npages
= VM_MAP_COPY_PAGE_LIST_MAX
;
9385 npages
= copy
->cpy_npages
;
9387 iprintf("copy->cpy_page_list[0..%d] = {", npages
);
9388 for (i
= 0; i
< npages
- 1; i
++) {
9389 printf("0x%x, ", copy
->cpy_page_list
[i
]);
9392 printf("0x%x", copy
->cpy_page_list
[npages
- 1]);
9402 * db_vm_map_total_size(map) [ debug ]
9404 * return the total virtual size (in bytes) of the map
9407 db_vm_map_total_size(
9410 vm_map_entry_t entry
;
9414 for (entry
= vm_map_first_entry(map
);
9415 entry
!= vm_map_to_entry(map
);
9416 entry
= entry
->vme_next
) {
9417 total
+= entry
->vme_end
- entry
->vme_start
;
9423 #endif /* MACH_KDB */
9426 * Routine: vm_map_entry_insert
9428 * Descritpion: This routine inserts a new vm_entry in a locked map.
9431 vm_map_entry_insert(
9433 vm_map_entry_t insp_entry
,
9437 vm_object_offset_t offset
,
9438 boolean_t needs_copy
,
9439 boolean_t is_shared
,
9440 boolean_t in_transition
,
9441 vm_prot_t cur_protection
,
9442 vm_prot_t max_protection
,
9443 vm_behavior_t behavior
,
9444 vm_inherit_t inheritance
,
9445 unsigned wired_count
)
9447 vm_map_entry_t new_entry
;
9449 assert(insp_entry
!= (vm_map_entry_t
)0);
9451 new_entry
= vm_map_entry_create(map
);
9453 new_entry
->vme_start
= start
;
9454 new_entry
->vme_end
= end
;
9455 assert(page_aligned(new_entry
->vme_start
));
9456 assert(page_aligned(new_entry
->vme_end
));
9458 new_entry
->object
.vm_object
= object
;
9459 new_entry
->offset
= offset
;
9460 new_entry
->is_shared
= is_shared
;
9461 new_entry
->is_sub_map
= FALSE
;
9462 new_entry
->needs_copy
= needs_copy
;
9463 new_entry
->in_transition
= in_transition
;
9464 new_entry
->needs_wakeup
= FALSE
;
9465 new_entry
->inheritance
= inheritance
;
9466 new_entry
->protection
= cur_protection
;
9467 new_entry
->max_protection
= max_protection
;
9468 new_entry
->behavior
= behavior
;
9469 new_entry
->wired_count
= wired_count
;
9470 new_entry
->user_wired_count
= 0;
9471 new_entry
->use_pmap
= FALSE
;
9474 * Insert the new entry into the list.
9477 vm_map_entry_link(map
, insp_entry
, new_entry
);
9478 map
->size
+= end
- start
;
9481 * Update the free space hint and the lookup hint.
9484 SAVE_HINT(map
, new_entry
);
9489 * Routine: vm_remap_extract
9491 * Descritpion: This routine returns a vm_entry list from a map.
9499 struct vm_map_header
*map_header
,
9500 vm_prot_t
*cur_protection
,
9501 vm_prot_t
*max_protection
,
9502 /* What, no behavior? */
9503 vm_inherit_t inheritance
,
9506 kern_return_t result
;
9507 vm_size_t mapped_size
;
9509 vm_map_entry_t src_entry
; /* result of last map lookup */
9510 vm_map_entry_t new_entry
;
9511 vm_object_offset_t offset
;
9512 vm_offset_t map_address
;
9513 vm_offset_t src_start
; /* start of entry to map */
9514 vm_offset_t src_end
; /* end of region to be mapped */
9516 vm_map_version_t version
;
9517 boolean_t src_needs_copy
;
9518 boolean_t new_entry_needs_copy
;
9520 assert(map
!= VM_MAP_NULL
);
9521 assert(size
!= 0 && size
== round_page(size
));
9522 assert(inheritance
== VM_INHERIT_NONE
||
9523 inheritance
== VM_INHERIT_COPY
||
9524 inheritance
== VM_INHERIT_SHARE
);
9527 * Compute start and end of region.
9529 src_start
= trunc_page(addr
);
9530 src_end
= round_page(src_start
+ size
);
9533 * Initialize map_header.
9535 map_header
->links
.next
= (struct vm_map_entry
*)&map_header
->links
;
9536 map_header
->links
.prev
= (struct vm_map_entry
*)&map_header
->links
;
9537 map_header
->nentries
= 0;
9538 map_header
->entries_pageable
= pageable
;
9540 *cur_protection
= VM_PROT_ALL
;
9541 *max_protection
= VM_PROT_ALL
;
9545 result
= KERN_SUCCESS
;
9548 * The specified source virtual space might correspond to
9549 * multiple map entries, need to loop on them.
9552 while (mapped_size
!= size
) {
9553 vm_size_t entry_size
;
9556 * Find the beginning of the region.
9558 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
9559 result
= KERN_INVALID_ADDRESS
;
9563 if (src_start
< src_entry
->vme_start
||
9564 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
9565 result
= KERN_INVALID_ADDRESS
;
9569 if(src_entry
->is_sub_map
) {
9570 result
= KERN_INVALID_ADDRESS
;
9574 tmp_size
= size
- mapped_size
;
9575 if (src_end
> src_entry
->vme_end
)
9576 tmp_size
-= (src_end
- src_entry
->vme_end
);
9578 entry_size
= (vm_size_t
)(src_entry
->vme_end
-
9579 src_entry
->vme_start
);
9581 if(src_entry
->is_sub_map
) {
9582 vm_map_reference(src_entry
->object
.sub_map
);
9584 object
= src_entry
->object
.vm_object
;
9586 if (object
== VM_OBJECT_NULL
) {
9587 object
= vm_object_allocate(entry_size
);
9588 src_entry
->offset
= 0;
9589 src_entry
->object
.vm_object
= object
;
9590 } else if (object
->copy_strategy
!=
9591 MEMORY_OBJECT_COPY_SYMMETRIC
) {
9593 * We are already using an asymmetric
9594 * copy, and therefore we already have
9597 assert(!src_entry
->needs_copy
);
9598 } else if (src_entry
->needs_copy
|| object
->shadowed
||
9599 (object
->internal
&& !object
->true_share
&&
9600 !src_entry
->is_shared
&&
9601 object
->size
> entry_size
)) {
9603 vm_object_shadow(&src_entry
->object
.vm_object
,
9607 if (!src_entry
->needs_copy
&&
9608 (src_entry
->protection
& VM_PROT_WRITE
)) {
9609 pmap_protect(vm_map_pmap(map
),
9610 src_entry
->vme_start
,
9612 src_entry
->protection
&
9616 object
= src_entry
->object
.vm_object
;
9617 src_entry
->needs_copy
= FALSE
;
9621 vm_object_lock(object
);
9622 object
->ref_count
++; /* object ref. for new entry */
9623 VM_OBJ_RES_INCR(object
);
9624 if (object
->copy_strategy
==
9625 MEMORY_OBJECT_COPY_SYMMETRIC
) {
9626 object
->copy_strategy
=
9627 MEMORY_OBJECT_COPY_DELAY
;
9629 vm_object_unlock(object
);
9632 offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
9634 new_entry
= _vm_map_entry_create(map_header
);
9635 vm_map_entry_copy(new_entry
, src_entry
);
9636 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
9638 new_entry
->vme_start
= map_address
;
9639 new_entry
->vme_end
= map_address
+ tmp_size
;
9640 new_entry
->inheritance
= inheritance
;
9641 new_entry
->offset
= offset
;
9644 * The new region has to be copied now if required.
9648 src_entry
->is_shared
= TRUE
;
9649 new_entry
->is_shared
= TRUE
;
9650 if (!(new_entry
->is_sub_map
))
9651 new_entry
->needs_copy
= FALSE
;
9653 } else if (src_entry
->is_sub_map
) {
9654 /* make this a COW sub_map if not already */
9655 new_entry
->needs_copy
= TRUE
;
9656 } else if (src_entry
->wired_count
== 0 &&
9657 vm_object_copy_quickly(&new_entry
->object
.vm_object
,
9659 (new_entry
->vme_end
-
9660 new_entry
->vme_start
),
9662 &new_entry_needs_copy
)) {
9664 new_entry
->needs_copy
= new_entry_needs_copy
;
9665 new_entry
->is_shared
= FALSE
;
9668 * Handle copy_on_write semantics.
9670 if (src_needs_copy
&& !src_entry
->needs_copy
) {
9671 vm_object_pmap_protect(object
,
9674 (src_entry
->is_shared
?
9675 PMAP_NULL
: map
->pmap
),
9676 src_entry
->vme_start
,
9677 src_entry
->protection
&
9680 src_entry
->needs_copy
= TRUE
;
9683 * Throw away the old object reference of the new entry.
9685 vm_object_deallocate(object
);
9688 new_entry
->is_shared
= FALSE
;
9691 * The map can be safely unlocked since we
9692 * already hold a reference on the object.
9694 * Record the timestamp of the map for later
9695 * verification, and unlock the map.
9697 version
.main_timestamp
= map
->timestamp
;
9703 if (src_entry
->wired_count
> 0) {
9704 vm_object_lock(object
);
9705 result
= vm_object_copy_slowly(
9710 &new_entry
->object
.vm_object
);
9712 new_entry
->offset
= 0;
9713 new_entry
->needs_copy
= FALSE
;
9715 result
= vm_object_copy_strategically(
9719 &new_entry
->object
.vm_object
,
9721 &new_entry_needs_copy
);
9723 new_entry
->needs_copy
= new_entry_needs_copy
;
9727 * Throw away the old object reference of the new entry.
9729 vm_object_deallocate(object
);
9731 if (result
!= KERN_SUCCESS
&&
9732 result
!= KERN_MEMORY_RESTART_COPY
) {
9733 _vm_map_entry_dispose(map_header
, new_entry
);
9738 * Verify that the map has not substantially
9739 * changed while the copy was being made.
9742 vm_map_lock(map
); /* Increments timestamp once! */
9743 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
9745 * Simple version comparison failed.
9747 * Retry the lookup and verify that the
9748 * same object/offset are still present.
9750 vm_object_deallocate(new_entry
->
9752 _vm_map_entry_dispose(map_header
, new_entry
);
9753 if (result
== KERN_MEMORY_RESTART_COPY
)
9754 result
= KERN_SUCCESS
;
9758 if (result
== KERN_MEMORY_RESTART_COPY
) {
9759 vm_object_reference(object
);
9764 _vm_map_entry_link(map_header
,
9765 map_header
->links
.prev
, new_entry
);
9767 *cur_protection
&= src_entry
->protection
;
9768 *max_protection
&= src_entry
->max_protection
;
9770 map_address
+= tmp_size
;
9771 mapped_size
+= tmp_size
;
9772 src_start
+= tmp_size
;
9777 if (result
!= KERN_SUCCESS
) {
9779 * Free all allocated elements.
9781 for (src_entry
= map_header
->links
.next
;
9782 src_entry
!= (struct vm_map_entry
*)&map_header
->links
;
9783 src_entry
= new_entry
) {
9784 new_entry
= src_entry
->vme_next
;
9785 _vm_map_entry_unlink(map_header
, src_entry
);
9786 vm_object_deallocate(src_entry
->object
.vm_object
);
9787 _vm_map_entry_dispose(map_header
, src_entry
);
9796 * Map portion of a task's address space.
9797 * Mapped region must not overlap more than
9798 * one vm memory object. Protections and
9799 * inheritance attributes remain the same
9800 * as in the original task and are out parameters.
9801 * Source and Target task can be identical
9802 * Other attributes are identical as for vm_map()
9806 vm_map_t target_map
,
9807 vm_offset_t
*address
,
9812 vm_offset_t memory_address
,
9814 vm_prot_t
*cur_protection
,
9815 vm_prot_t
*max_protection
,
9816 vm_inherit_t inheritance
)
9818 kern_return_t result
;
9819 vm_map_entry_t entry
;
9820 vm_map_entry_t insp_entry
;
9821 vm_map_entry_t new_entry
;
9822 struct vm_map_header map_header
;
9824 if (target_map
== VM_MAP_NULL
)
9825 return KERN_INVALID_ARGUMENT
;
9827 switch (inheritance
) {
9828 case VM_INHERIT_NONE
:
9829 case VM_INHERIT_COPY
:
9830 case VM_INHERIT_SHARE
:
9831 if (size
!= 0 && src_map
!= VM_MAP_NULL
)
9835 return KERN_INVALID_ARGUMENT
;
9838 size
= round_page(size
);
9840 result
= vm_remap_extract(src_map
, memory_address
,
9841 size
, copy
, &map_header
,
9847 vm_map_deallocate(src_map
);
9849 if (result
!= KERN_SUCCESS
) {
9854 * Allocate/check a range of free virtual address
9855 * space for the target
9857 *address
= trunc_page(*address
);
9858 vm_map_lock(target_map
);
9859 result
= vm_remap_range_allocate(target_map
, address
, size
,
9860 mask
, anywhere
, &insp_entry
);
9862 for (entry
= map_header
.links
.next
;
9863 entry
!= (struct vm_map_entry
*)&map_header
.links
;
9864 entry
= new_entry
) {
9865 new_entry
= entry
->vme_next
;
9866 _vm_map_entry_unlink(&map_header
, entry
);
9867 if (result
== KERN_SUCCESS
) {
9868 entry
->vme_start
+= *address
;
9869 entry
->vme_end
+= *address
;
9870 vm_map_entry_link(target_map
, insp_entry
, entry
);
9873 if (!entry
->is_sub_map
) {
9874 vm_object_deallocate(entry
->object
.vm_object
);
9876 vm_map_deallocate(entry
->object
.sub_map
);
9878 _vm_map_entry_dispose(&map_header
, entry
);
9882 if (result
== KERN_SUCCESS
) {
9883 target_map
->size
+= size
;
9884 SAVE_HINT(target_map
, insp_entry
);
9886 vm_map_unlock(target_map
);
9888 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
9889 result
= vm_map_wire(target_map
, *address
,
9890 *address
+ size
, *cur_protection
, TRUE
);
9895 * Routine: vm_remap_range_allocate
9898 * Allocate a range in the specified virtual address map.
9899 * returns the address and the map entry just before the allocated
9902 * Map must be locked.
9906 vm_remap_range_allocate(
9908 vm_offset_t
*address
, /* IN/OUT */
9912 vm_map_entry_t
*map_entry
) /* OUT */
9914 register vm_map_entry_t entry
;
9915 register vm_offset_t start
;
9916 register vm_offset_t end
;
9917 kern_return_t result
= KERN_SUCCESS
;
9926 * Calculate the first possible address.
9929 if (start
< map
->min_offset
)
9930 start
= map
->min_offset
;
9931 if (start
> map
->max_offset
)
9932 return(KERN_NO_SPACE
);
9935 * Look for the first possible address;
9936 * if there's already something at this
9937 * address, we have to start after it.
9940 assert(first_free_is_valid(map
));
9941 if (start
== map
->min_offset
) {
9942 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
9943 start
= entry
->vme_end
;
9945 vm_map_entry_t tmp_entry
;
9946 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
9947 start
= tmp_entry
->vme_end
;
9952 * In any case, the "entry" always precedes
9953 * the proposed new region throughout the
9958 register vm_map_entry_t next
;
9961 * Find the end of the proposed new region.
9962 * Be sure we didn't go beyond the end, or
9963 * wrap around the address.
9966 end
= ((start
+ mask
) & ~mask
);
9968 return(KERN_NO_SPACE
);
9972 if ((end
> map
->max_offset
) || (end
< start
)) {
9973 if (map
->wait_for_space
) {
9974 if (size
<= (map
->max_offset
-
9976 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
9978 thread_block((void (*)(void))0);
9984 return(KERN_NO_SPACE
);
9988 * If there are no more entries, we must win.
9991 next
= entry
->vme_next
;
9992 if (next
== vm_map_to_entry(map
))
9996 * If there is another entry, it must be
9997 * after the end of the potential new region.
10000 if (next
->vme_start
>= end
)
10004 * Didn't fit -- move to the next entry.
10008 start
= entry
->vme_end
;
10012 vm_map_entry_t temp_entry
;
10016 * the address doesn't itself violate
10017 * the mask requirement.
10020 if ((start
& mask
) != 0)
10021 return(KERN_NO_SPACE
);
10025 * ... the address is within bounds
10028 end
= start
+ size
;
10030 if ((start
< map
->min_offset
) ||
10031 (end
> map
->max_offset
) ||
10033 return(KERN_INVALID_ADDRESS
);
10037 * ... the starting address isn't allocated
10040 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
10041 return(KERN_NO_SPACE
);
10043 entry
= temp_entry
;
10046 * ... the next region doesn't overlap the
10050 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
10051 (entry
->vme_next
->vme_start
< end
))
10052 return(KERN_NO_SPACE
);
10054 *map_entry
= entry
;
10055 return(KERN_SUCCESS
);
10061 * Set the address map for the current thr_act to the specified map
10069 thread_act_t thr_act
= current_act();
10070 vm_map_t oldmap
= thr_act
->map
;
10072 mp_disable_preemption();
10073 mycpu
= cpu_number();
10076 * Deactivate the current map and activate the requested map
10078 PMAP_SWITCH_USER(thr_act
, map
, mycpu
);
10080 mp_enable_preemption();
10086 * Routine: vm_map_write_user
10089 * Copy out data from a kernel space into space in the
10090 * destination map. The space must already exist in the
10092 * NOTE: This routine should only be called by threads
10093 * which can block on a page fault. i.e. kernel mode user
10100 vm_offset_t src_addr
,
10101 vm_offset_t dst_addr
,
10104 thread_act_t thr_act
= current_act();
10105 kern_return_t kr
= KERN_SUCCESS
;
10107 if(thr_act
->map
== map
) {
10108 if (copyout((char *)src_addr
, (char *)dst_addr
, size
)) {
10109 kr
= KERN_INVALID_ADDRESS
;
10114 /* take on the identity of the target map while doing */
10117 vm_map_reference(map
);
10118 oldmap
= vm_map_switch(map
);
10119 if (copyout((char *)src_addr
, (char *)dst_addr
, size
)) {
10120 kr
= KERN_INVALID_ADDRESS
;
10122 vm_map_switch(oldmap
);
10123 vm_map_deallocate(map
);
10129 * Routine: vm_map_read_user
10132 * Copy in data from a user space source map into the
10133 * kernel map. The space must already exist in the
10135 * NOTE: This routine should only be called by threads
10136 * which can block on a page fault. i.e. kernel mode user
10143 vm_offset_t src_addr
,
10144 vm_offset_t dst_addr
,
10147 thread_act_t thr_act
= current_act();
10148 kern_return_t kr
= KERN_SUCCESS
;
10150 if(thr_act
->map
== map
) {
10151 if (copyin((char *)src_addr
, (char *)dst_addr
, size
)) {
10152 kr
= KERN_INVALID_ADDRESS
;
10157 /* take on the identity of the target map while doing */
10160 vm_map_reference(map
);
10161 oldmap
= vm_map_switch(map
);
10162 if (copyin((char *)src_addr
, (char *)dst_addr
, size
)) {
10163 kr
= KERN_INVALID_ADDRESS
;
10165 vm_map_switch(oldmap
);
10166 vm_map_deallocate(map
);
10171 /* Takes existing source and destination sub-maps and clones the contents of */
10172 /* the source map */
10176 ipc_port_t src_region
,
10177 ipc_port_t dst_region
)
10179 vm_named_entry_t src_object
;
10180 vm_named_entry_t dst_object
;
10184 vm_offset_t max_off
;
10185 vm_map_entry_t entry
;
10186 vm_map_entry_t new_entry
;
10187 vm_map_entry_t insert_point
;
10189 src_object
= (vm_named_entry_t
)src_region
->ip_kobject
;
10190 dst_object
= (vm_named_entry_t
)dst_region
->ip_kobject
;
10191 if((!src_object
->is_sub_map
) || (!dst_object
->is_sub_map
)) {
10192 return KERN_INVALID_ARGUMENT
;
10194 src_map
= (vm_map_t
)src_object
->backing
.map
;
10195 dst_map
= (vm_map_t
)dst_object
->backing
.map
;
10196 /* destination map is assumed to be unavailable to any other */
10197 /* activity. i.e. it is new */
10198 vm_map_lock(src_map
);
10199 if((src_map
->min_offset
!= dst_map
->min_offset
)
10200 || (src_map
->max_offset
!= dst_map
->max_offset
)) {
10201 vm_map_unlock(src_map
);
10202 return KERN_INVALID_ARGUMENT
;
10204 addr
= src_map
->min_offset
;
10205 vm_map_lookup_entry(dst_map
, addr
, &entry
);
10206 if(entry
== vm_map_to_entry(dst_map
)) {
10207 entry
= entry
->vme_next
;
10209 if(entry
== vm_map_to_entry(dst_map
)) {
10210 max_off
= src_map
->max_offset
;
10212 max_off
= entry
->vme_start
;
10214 vm_map_lookup_entry(src_map
, addr
, &entry
);
10215 if(entry
== vm_map_to_entry(src_map
)) {
10216 entry
= entry
->vme_next
;
10218 vm_map_lookup_entry(dst_map
, addr
, &insert_point
);
10219 while((entry
!= vm_map_to_entry(src_map
)) &&
10220 (entry
->vme_end
<= max_off
)) {
10221 addr
= entry
->vme_start
;
10222 new_entry
= vm_map_entry_create(dst_map
);
10223 vm_map_entry_copy(new_entry
, entry
);
10224 vm_map_entry_link(dst_map
, insert_point
, new_entry
);
10225 insert_point
= new_entry
;
10226 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
10227 if (new_entry
->is_sub_map
) {
10228 vm_map_reference(new_entry
->object
.sub_map
);
10230 vm_object_reference(
10231 new_entry
->object
.vm_object
);
10234 dst_map
->size
+= new_entry
->vme_end
- new_entry
->vme_start
;
10235 entry
= entry
->vme_next
;
10237 vm_map_unlock(src_map
);
10238 return KERN_SUCCESS
;
10242 * Export routines to other components for the things we access locally through
10249 return (current_map_fast());
10253 * vm_map_check_protection:
10255 * Assert that the target map allows the specified
10256 * privilege on the entire address region given.
10257 * The entire region must be allocated.
10259 boolean_t
vm_map_check_protection(map
, start
, end
, protection
)
10260 register vm_map_t map
;
10261 register vm_offset_t start
;
10262 register vm_offset_t end
;
10263 register vm_prot_t protection
;
10265 register vm_map_entry_t entry
;
10266 vm_map_entry_t tmp_entry
;
10270 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
10272 vm_map_unlock(map
);
10276 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
10277 vm_map_unlock(map
);
10283 while (start
< end
) {
10284 if (entry
== vm_map_to_entry(map
)) {
10285 vm_map_unlock(map
);
10290 * No holes allowed!
10293 if (start
< entry
->vme_start
) {
10294 vm_map_unlock(map
);
10299 * Check protection associated with entry.
10302 if ((entry
->protection
& protection
) != protection
) {
10303 vm_map_unlock(map
);
10307 /* go to next entry */
10309 start
= entry
->vme_end
;
10310 entry
= entry
->vme_next
;
10312 vm_map_unlock(map
);