2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
60 * Author: Avadis Tevanian, Jr., Michael Wayne Young
63 * Virtual memory mapping module.
66 #include <task_swapper.h>
67 #include <mach_assert.h>
68 #include <libkern/OSAtomic.h>
70 #include <mach/kern_return.h>
71 #include <mach/port.h>
72 #include <mach/vm_attributes.h>
73 #include <mach/vm_param.h>
74 #include <mach/vm_behavior.h>
75 #include <mach/vm_statistics.h>
76 #include <mach/memory_object.h>
77 #include <machine/cpu_capabilities.h>
79 #include <kern/assert.h>
80 #include <kern/counters.h>
81 #include <kern/kalloc.h>
82 #include <kern/zalloc.h>
85 #include <vm/vm_init.h>
86 #include <vm/vm_fault.h>
87 #include <vm/vm_map.h>
88 #include <vm/vm_object.h>
89 #include <vm/vm_page.h>
90 #include <vm/vm_kern.h>
91 #include <ipc/ipc_port.h>
92 #include <kern/sched_prim.h>
93 #include <kern/misc_protos.h>
95 #include <machine/db_machdep.h>
98 #include <mach/vm_map_server.h>
99 #include <mach/mach_host_server.h>
100 #include <vm/vm_shared_memory_server.h>
101 #include <vm/vm_protos.h> // for vm_map_commpage64 and vm_map_remove_compage64
104 #include <ppc/mappings.h>
107 #include <vm/vm_protos.h>
109 /* Internal prototypes
112 static void vm_map_simplify_range(
114 vm_map_offset_t start
,
115 vm_map_offset_t end
); /* forward */
117 static boolean_t
vm_map_range_check(
119 vm_map_offset_t start
,
121 vm_map_entry_t
*entry
);
123 static vm_map_entry_t
_vm_map_entry_create(
124 struct vm_map_header
*map_header
);
126 static void _vm_map_entry_dispose(
127 struct vm_map_header
*map_header
,
128 vm_map_entry_t entry
);
130 static void vm_map_pmap_enter(
132 vm_map_offset_t addr
,
133 vm_map_offset_t end_addr
,
135 vm_object_offset_t offset
,
136 vm_prot_t protection
);
138 static void _vm_map_clip_end(
139 struct vm_map_header
*map_header
,
140 vm_map_entry_t entry
,
141 vm_map_offset_t end
);
143 static void _vm_map_clip_start(
144 struct vm_map_header
*map_header
,
145 vm_map_entry_t entry
,
146 vm_map_offset_t start
);
148 static void vm_map_entry_delete(
150 vm_map_entry_t entry
);
152 static kern_return_t
vm_map_delete(
154 vm_map_offset_t start
,
159 static kern_return_t
vm_map_copy_overwrite_unaligned(
161 vm_map_entry_t entry
,
163 vm_map_address_t start
);
165 static kern_return_t
vm_map_copy_overwrite_aligned(
167 vm_map_entry_t tmp_entry
,
169 vm_map_offset_t start
,
172 static kern_return_t
vm_map_copyin_kernel_buffer(
174 vm_map_address_t src_addr
,
176 boolean_t src_destroy
,
177 vm_map_copy_t
*copy_result
); /* OUT */
179 static kern_return_t
vm_map_copyout_kernel_buffer(
181 vm_map_address_t
*addr
, /* IN/OUT */
183 boolean_t overwrite
);
185 static void vm_map_fork_share(
187 vm_map_entry_t old_entry
,
190 static boolean_t
vm_map_fork_copy(
192 vm_map_entry_t
*old_entry_p
,
195 static void vm_map_region_top_walk(
196 vm_map_entry_t entry
,
197 vm_region_top_info_t top
);
199 static void vm_map_region_walk(
202 vm_map_entry_t entry
,
203 vm_object_offset_t offset
,
204 vm_object_size_t range
,
205 vm_region_extended_info_t extended
);
207 static kern_return_t
vm_map_wire_nested(
209 vm_map_offset_t start
,
211 vm_prot_t access_type
,
214 vm_map_offset_t pmap_addr
);
216 static kern_return_t
vm_map_unwire_nested(
218 vm_map_offset_t start
,
222 vm_map_offset_t pmap_addr
);
224 static kern_return_t
vm_map_overwrite_submap_recurse(
226 vm_map_offset_t dst_addr
,
227 vm_map_size_t dst_size
);
229 static kern_return_t
vm_map_copy_overwrite_nested(
231 vm_map_offset_t dst_addr
,
233 boolean_t interruptible
,
236 static kern_return_t
vm_map_remap_extract(
238 vm_map_offset_t addr
,
241 struct vm_map_header
*map_header
,
242 vm_prot_t
*cur_protection
,
243 vm_prot_t
*max_protection
,
244 vm_inherit_t inheritance
,
247 static kern_return_t
vm_map_remap_range_allocate(
249 vm_map_address_t
*address
,
251 vm_map_offset_t mask
,
253 vm_map_entry_t
*map_entry
);
255 static void vm_map_region_look_for_page(
259 vm_object_offset_t offset
,
262 vm_region_extended_info_t extended
);
264 static int vm_map_region_count_obj_refs(
265 vm_map_entry_t entry
,
269 * Macros to copy a vm_map_entry. We must be careful to correctly
270 * manage the wired page count. vm_map_entry_copy() creates a new
271 * map entry to the same memory - the wired count in the new entry
272 * must be set to zero. vm_map_entry_copy_full() creates a new
273 * entry that is identical to the old entry. This preserves the
274 * wire count; it's used for map splitting and zone changing in
277 #define vm_map_entry_copy(NEW,OLD) \
280 (NEW)->is_shared = FALSE; \
281 (NEW)->needs_wakeup = FALSE; \
282 (NEW)->in_transition = FALSE; \
283 (NEW)->wired_count = 0; \
284 (NEW)->user_wired_count = 0; \
287 #define vm_map_entry_copy_full(NEW,OLD) (*(NEW) = *(OLD))
290 * Virtual memory maps provide for the mapping, protection,
291 * and sharing of virtual memory objects. In addition,
292 * this module provides for an efficient virtual copy of
293 * memory from one map to another.
295 * Synchronization is required prior to most operations.
297 * Maps consist of an ordered doubly-linked list of simple
298 * entries; a single hint is used to speed up lookups.
300 * Sharing maps have been deleted from this version of Mach.
301 * All shared objects are now mapped directly into the respective
302 * maps. This requires a change in the copy on write strategy;
303 * the asymmetric (delayed) strategy is used for shared temporary
304 * objects instead of the symmetric (shadow) strategy. All maps
305 * are now "top level" maps (either task map, kernel map or submap
306 * of the kernel map).
308 * Since portions of maps are specified by start/end addreses,
309 * which may not align with existing map entries, all
310 * routines merely "clip" entries to these start/end values.
311 * [That is, an entry is split into two, bordering at a
312 * start or end value.] Note that these clippings may not
313 * always be necessary (as the two resulting entries are then
314 * not changed); however, the clipping is done for convenience.
315 * No attempt is currently made to "glue back together" two
318 * The symmetric (shadow) copy strategy implements virtual copy
319 * by copying VM object references from one map to
320 * another, and then marking both regions as copy-on-write.
321 * It is important to note that only one writeable reference
322 * to a VM object region exists in any map when this strategy
323 * is used -- this means that shadow object creation can be
324 * delayed until a write operation occurs. The symmetric (delayed)
325 * strategy allows multiple maps to have writeable references to
326 * the same region of a vm object, and hence cannot delay creating
327 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
328 * Copying of permanent objects is completely different; see
329 * vm_object_copy_strategically() in vm_object.c.
332 static zone_t vm_map_zone
; /* zone for vm_map structures */
333 static zone_t vm_map_entry_zone
; /* zone for vm_map_entry structures */
334 static zone_t vm_map_kentry_zone
; /* zone for kernel entry structures */
335 static zone_t vm_map_copy_zone
; /* zone for vm_map_copy structures */
339 * Placeholder object for submap operations. This object is dropped
340 * into the range by a call to vm_map_find, and removed when
341 * vm_map_submap creates the submap.
344 vm_object_t vm_submap_object
;
349 * Initialize the vm_map module. Must be called before
350 * any other vm_map routines.
352 * Map and entry structures are allocated from zones -- we must
353 * initialize those zones.
355 * There are three zones of interest:
357 * vm_map_zone: used to allocate maps.
358 * vm_map_entry_zone: used to allocate map entries.
359 * vm_map_kentry_zone: used to allocate map entries for the kernel.
361 * The kernel allocates map entries from a special zone that is initially
362 * "crammed" with memory. It would be difficult (perhaps impossible) for
363 * the kernel to allocate more memory to a entry zone when it became
364 * empty since the very act of allocating memory implies the creation
368 static void *map_data
;
369 static vm_map_size_t map_data_size
;
370 static void *kentry_data
;
371 static vm_map_size_t kentry_data_size
;
372 static int kentry_count
= 2048; /* to init kentry_data_size */
374 #define NO_COALESCE_LIMIT (1024 * 128)
377 * Threshold for aggressive (eager) page map entering for vm copyout
378 * operations. Any copyout larger will NOT be aggressively entered.
380 static vm_map_size_t vm_map_aggressive_enter_max
; /* set by bootstrap */
382 /* Skip acquiring locks if we're in the midst of a kernel core dump */
383 extern unsigned int not_in_kdp
;
389 vm_map_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map
), 40*1024,
392 vm_map_entry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
393 1024*1024, PAGE_SIZE
*5,
394 "non-kernel map entries");
396 vm_map_kentry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
397 kentry_data_size
, kentry_data_size
,
398 "kernel map entries");
400 vm_map_copy_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_copy
),
401 16*1024, PAGE_SIZE
, "map copies");
404 * Cram the map and kentry zones with initial data.
405 * Set kentry_zone non-collectible to aid zone_gc().
407 zone_change(vm_map_zone
, Z_COLLECT
, FALSE
);
408 zone_change(vm_map_kentry_zone
, Z_COLLECT
, FALSE
);
409 zone_change(vm_map_kentry_zone
, Z_EXPAND
, FALSE
);
410 zcram(vm_map_zone
, map_data
, map_data_size
);
411 zcram(vm_map_kentry_zone
, kentry_data
, kentry_data_size
);
418 map_data_size
= vm_map_round_page(10 * sizeof(struct vm_map
));
419 map_data
= pmap_steal_memory(map_data_size
);
423 * Limiting worst case: vm_map_kentry_zone needs to map each "available"
424 * physical page (i.e. that beyond the kernel image and page tables)
425 * individually; we guess at most one entry per eight pages in the
426 * real world. This works out to roughly .1 of 1% of physical memory,
427 * or roughly 1900 entries (64K) for a 64M machine with 4K pages.
430 kentry_count
= pmap_free_pages() / 8;
434 vm_map_round_page(kentry_count
* sizeof(struct vm_map_entry
));
435 kentry_data
= pmap_steal_memory(kentry_data_size
);
441 * Creates and returns a new empty VM map with
442 * the given physical map structure, and having
443 * the given lower and upper address bounds.
452 register vm_map_t result
;
454 result
= (vm_map_t
) zalloc(vm_map_zone
);
455 if (result
== VM_MAP_NULL
)
456 panic("vm_map_create");
458 vm_map_first_entry(result
) = vm_map_to_entry(result
);
459 vm_map_last_entry(result
) = vm_map_to_entry(result
);
460 result
->hdr
.nentries
= 0;
461 result
->hdr
.entries_pageable
= pageable
;
464 result
->ref_count
= 1;
466 result
->res_count
= 1;
467 result
->sw_state
= MAP_SW_IN
;
468 #endif /* TASK_SWAPPER */
470 result
->min_offset
= min
;
471 result
->max_offset
= max
;
472 result
->wiring_required
= FALSE
;
473 result
->no_zero_fill
= FALSE
;
474 result
->mapped
= FALSE
;
475 result
->wait_for_space
= FALSE
;
476 result
->first_free
= vm_map_to_entry(result
);
477 result
->hint
= vm_map_to_entry(result
);
478 vm_map_lock_init(result
);
479 mutex_init(&result
->s_lock
, 0);
485 * vm_map_entry_create: [ internal use only ]
487 * Allocates a VM map entry for insertion in the
488 * given map (or map copy). No fields are filled.
490 #define vm_map_entry_create(map) \
491 _vm_map_entry_create(&(map)->hdr)
493 #define vm_map_copy_entry_create(copy) \
494 _vm_map_entry_create(&(copy)->cpy_hdr)
496 static vm_map_entry_t
497 _vm_map_entry_create(
498 register struct vm_map_header
*map_header
)
500 register zone_t zone
;
501 register vm_map_entry_t entry
;
503 if (map_header
->entries_pageable
)
504 zone
= vm_map_entry_zone
;
506 zone
= vm_map_kentry_zone
;
508 entry
= (vm_map_entry_t
) zalloc(zone
);
509 if (entry
== VM_MAP_ENTRY_NULL
)
510 panic("vm_map_entry_create");
516 * vm_map_entry_dispose: [ internal use only ]
518 * Inverse of vm_map_entry_create.
520 #define vm_map_entry_dispose(map, entry) \
522 if((entry) == (map)->first_free) \
523 (map)->first_free = vm_map_to_entry(map); \
524 if((entry) == (map)->hint) \
525 (map)->hint = vm_map_to_entry(map); \
526 _vm_map_entry_dispose(&(map)->hdr, (entry)); \
529 #define vm_map_copy_entry_dispose(map, entry) \
530 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
533 _vm_map_entry_dispose(
534 register struct vm_map_header
*map_header
,
535 register vm_map_entry_t entry
)
537 register zone_t zone
;
539 if (map_header
->entries_pageable
)
540 zone
= vm_map_entry_zone
;
542 zone
= vm_map_kentry_zone
;
548 static boolean_t
first_free_is_valid(vm_map_t map
); /* forward */
549 static boolean_t first_free_check
= FALSE
;
554 vm_map_entry_t entry
, next
;
556 if (!first_free_check
)
559 entry
= vm_map_to_entry(map
);
560 next
= entry
->vme_next
;
561 while (vm_map_trunc_page(next
->vme_start
) == vm_map_trunc_page(entry
->vme_end
) ||
562 (vm_map_trunc_page(next
->vme_start
) == vm_map_trunc_page(entry
->vme_start
) &&
563 next
!= vm_map_to_entry(map
))) {
565 next
= entry
->vme_next
;
566 if (entry
== vm_map_to_entry(map
))
569 if (map
->first_free
!= entry
) {
570 printf("Bad first_free for map 0x%x: 0x%x should be 0x%x\n",
571 map
, map
->first_free
, entry
);
576 #endif /* MACH_ASSERT */
581 * Updates the map->first_free pointer to the
582 * entry immediately before the first hole in the map.
583 * The map should be locked.
585 #define UPDATE_FIRST_FREE(map, new_first_free) \
588 vm_map_entry_t UFF_first_free; \
589 vm_map_entry_t UFF_next_entry; \
591 UFF_first_free = (new_first_free); \
592 UFF_next_entry = UFF_first_free->vme_next; \
593 while (vm_map_trunc_page(UFF_next_entry->vme_start) == \
594 vm_map_trunc_page(UFF_first_free->vme_end) || \
595 (vm_map_trunc_page(UFF_next_entry->vme_start) == \
596 vm_map_trunc_page(UFF_first_free->vme_start) && \
597 UFF_next_entry != vm_map_to_entry(UFF_map))) { \
598 UFF_first_free = UFF_next_entry; \
599 UFF_next_entry = UFF_first_free->vme_next; \
600 if (UFF_first_free == vm_map_to_entry(UFF_map)) \
603 UFF_map->first_free = UFF_first_free; \
604 assert(first_free_is_valid(UFF_map)); \
608 * vm_map_entry_{un,}link:
610 * Insert/remove entries from maps (or map copies).
612 #define vm_map_entry_link(map, after_where, entry) \
615 vm_map_entry_t VMEL_entry; \
617 VMEL_entry = (entry); \
618 _vm_map_entry_link(&VMEL_map->hdr, after_where, VMEL_entry); \
619 UPDATE_FIRST_FREE(VMEL_map, VMEL_map->first_free); \
623 #define vm_map_copy_entry_link(copy, after_where, entry) \
624 _vm_map_entry_link(&(copy)->cpy_hdr, after_where, (entry))
626 #define _vm_map_entry_link(hdr, after_where, entry) \
629 (entry)->vme_prev = (after_where); \
630 (entry)->vme_next = (after_where)->vme_next; \
631 (entry)->vme_prev->vme_next = (entry)->vme_next->vme_prev = (entry); \
634 #define vm_map_entry_unlink(map, entry) \
637 vm_map_entry_t VMEU_entry; \
638 vm_map_entry_t VMEU_first_free; \
640 VMEU_entry = (entry); \
641 if (VMEU_entry->vme_start <= VMEU_map->first_free->vme_start) \
642 VMEU_first_free = VMEU_entry->vme_prev; \
644 VMEU_first_free = VMEU_map->first_free; \
645 _vm_map_entry_unlink(&VMEU_map->hdr, VMEU_entry); \
646 UPDATE_FIRST_FREE(VMEU_map, VMEU_first_free); \
649 #define vm_map_copy_entry_unlink(copy, entry) \
650 _vm_map_entry_unlink(&(copy)->cpy_hdr, (entry))
652 #define _vm_map_entry_unlink(hdr, entry) \
655 (entry)->vme_next->vme_prev = (entry)->vme_prev; \
656 (entry)->vme_prev->vme_next = (entry)->vme_next; \
659 #if MACH_ASSERT && TASK_SWAPPER
661 * vm_map_res_reference:
663 * Adds another valid residence count to the given map.
665 * Map is locked so this function can be called from
669 void vm_map_res_reference(register vm_map_t map
)
671 /* assert map is locked */
672 assert(map
->res_count
>= 0);
673 assert(map
->ref_count
>= map
->res_count
);
674 if (map
->res_count
== 0) {
675 mutex_unlock(&map
->s_lock
);
678 mutex_lock(&map
->s_lock
);
686 * vm_map_reference_swap:
688 * Adds valid reference and residence counts to the given map.
690 * The map may not be in memory (i.e. zero residence count).
693 void vm_map_reference_swap(register vm_map_t map
)
695 assert(map
!= VM_MAP_NULL
);
696 mutex_lock(&map
->s_lock
);
697 assert(map
->res_count
>= 0);
698 assert(map
->ref_count
>= map
->res_count
);
700 vm_map_res_reference(map
);
701 mutex_unlock(&map
->s_lock
);
705 * vm_map_res_deallocate:
707 * Decrement residence count on a map; possibly causing swapout.
709 * The map must be in memory (i.e. non-zero residence count).
711 * The map is locked, so this function is callable from vm_map_deallocate.
714 void vm_map_res_deallocate(register vm_map_t map
)
716 assert(map
->res_count
> 0);
717 if (--map
->res_count
== 0) {
718 mutex_unlock(&map
->s_lock
);
722 mutex_lock(&map
->s_lock
);
724 assert(map
->ref_count
>= map
->res_count
);
726 #endif /* MACH_ASSERT && TASK_SWAPPER */
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
,
744 if (map
->hdr
.nentries
!=0)
745 vm_map_remove_commpage64(map
);
748 assert(map
->hdr
.nentries
==0);
751 pmap_destroy(map
->pmap
);
753 zfree(vm_map_zone
, map
);
758 * vm_map_swapin/vm_map_swapout
760 * Swap a map in and out, either referencing or releasing its resources.
761 * These functions are internal use only; however, they must be exported
762 * because they may be called from macros, which are exported.
764 * In the case of swapout, there could be races on the residence count,
765 * so if the residence count is up, we return, assuming that a
766 * vm_map_deallocate() call in the near future will bring us back.
769 * -- We use the map write lock for synchronization among races.
770 * -- The map write lock, and not the simple s_lock, protects the
771 * swap state of the map.
772 * -- If a map entry is a share map, then we hold both locks, in
773 * hierarchical order.
775 * Synchronization Notes:
776 * 1) If a vm_map_swapin() call happens while swapout in progress, it
777 * will block on the map lock and proceed when swapout is through.
778 * 2) A vm_map_reference() call at this time is illegal, and will
779 * cause a panic. vm_map_reference() is only allowed on resident
780 * maps, since it refuses to block.
781 * 3) A vm_map_swapin() call during a swapin will block, and
782 * proceeed when the first swapin is done, turning into a nop.
783 * This is the reason the res_count is not incremented until
784 * after the swapin is complete.
785 * 4) There is a timing hole after the checks of the res_count, before
786 * the map lock is taken, during which a swapin may get the lock
787 * before a swapout about to happen. If this happens, the swapin
788 * will detect the state and increment the reference count, causing
789 * the swapout to be a nop, thereby delaying it until a later
790 * vm_map_deallocate. If the swapout gets the lock first, then
791 * the swapin will simply block until the swapout is done, and
794 * Because vm_map_swapin() is potentially an expensive operation, it
795 * should be used with caution.
798 * 1) A map with a residence count of zero is either swapped, or
800 * 2) A map with a non-zero residence count is either resident,
801 * or being swapped in.
804 int vm_map_swap_enable
= 1;
806 void vm_map_swapin (vm_map_t map
)
808 register vm_map_entry_t entry
;
810 if (!vm_map_swap_enable
) /* debug */
815 * First deal with various races.
817 if (map
->sw_state
== MAP_SW_IN
)
819 * we raced with swapout and won. Returning will incr.
820 * the res_count, turning the swapout into a nop.
825 * The residence count must be zero. If we raced with another
826 * swapin, the state would have been IN; if we raced with a
827 * swapout (after another competing swapin), we must have lost
828 * the race to get here (see above comment), in which case
829 * res_count is still 0.
831 assert(map
->res_count
== 0);
834 * There are no intermediate states of a map going out or
835 * coming in, since the map is locked during the transition.
837 assert(map
->sw_state
== MAP_SW_OUT
);
840 * We now operate upon each map entry. If the entry is a sub-
841 * or share-map, we call vm_map_res_reference upon it.
842 * If the entry is an object, we call vm_object_res_reference
843 * (this may iterate through the shadow chain).
844 * Note that we hold the map locked the entire time,
845 * even if we get back here via a recursive call in
846 * vm_map_res_reference.
848 entry
= vm_map_first_entry(map
);
850 while (entry
!= vm_map_to_entry(map
)) {
851 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
852 if (entry
->is_sub_map
) {
853 vm_map_t lmap
= entry
->object
.sub_map
;
854 mutex_lock(&lmap
->s_lock
);
855 vm_map_res_reference(lmap
);
856 mutex_unlock(&lmap
->s_lock
);
858 vm_object_t object
= entry
->object
.vm_object
;
859 vm_object_lock(object
);
861 * This call may iterate through the
864 vm_object_res_reference(object
);
865 vm_object_unlock(object
);
868 entry
= entry
->vme_next
;
870 assert(map
->sw_state
== MAP_SW_OUT
);
871 map
->sw_state
= MAP_SW_IN
;
874 void vm_map_swapout(vm_map_t map
)
876 register vm_map_entry_t entry
;
880 * First deal with various races.
881 * If we raced with a swapin and lost, the residence count
882 * will have been incremented to 1, and we simply return.
884 mutex_lock(&map
->s_lock
);
885 if (map
->res_count
!= 0) {
886 mutex_unlock(&map
->s_lock
);
889 mutex_unlock(&map
->s_lock
);
892 * There are no intermediate states of a map going out or
893 * coming in, since the map is locked during the transition.
895 assert(map
->sw_state
== MAP_SW_IN
);
897 if (!vm_map_swap_enable
)
901 * We now operate upon each map entry. If the entry is a sub-
902 * or share-map, we call vm_map_res_deallocate upon it.
903 * If the entry is an object, we call vm_object_res_deallocate
904 * (this may iterate through the shadow chain).
905 * Note that we hold the map locked the entire time,
906 * even if we get back here via a recursive call in
907 * vm_map_res_deallocate.
909 entry
= vm_map_first_entry(map
);
911 while (entry
!= vm_map_to_entry(map
)) {
912 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
913 if (entry
->is_sub_map
) {
914 vm_map_t lmap
= entry
->object
.sub_map
;
915 mutex_lock(&lmap
->s_lock
);
916 vm_map_res_deallocate(lmap
);
917 mutex_unlock(&lmap
->s_lock
);
919 vm_object_t object
= entry
->object
.vm_object
;
920 vm_object_lock(object
);
922 * This call may take a long time,
923 * since it could actively push
924 * out pages (if we implement it
927 vm_object_res_deallocate(object
);
928 vm_object_unlock(object
);
931 entry
= entry
->vme_next
;
933 assert(map
->sw_state
== MAP_SW_IN
);
934 map
->sw_state
= MAP_SW_OUT
;
937 #endif /* TASK_SWAPPER */
943 * Saves the specified entry as the hint for
944 * future lookups. Performs necessary interlocks.
946 #define SAVE_HINT(map,value) \
948 mutex_lock(&(map)->s_lock); \
949 (map)->hint = (value); \
950 mutex_unlock(&(map)->s_lock); \
954 * vm_map_lookup_entry: [ internal use only ]
956 * Finds the map entry containing (or
957 * immediately preceding) the specified address
958 * in the given map; the entry is returned
959 * in the "entry" parameter. The boolean
960 * result indicates whether the address is
961 * actually contained in the map.
965 register vm_map_t map
,
966 register vm_map_offset_t address
,
967 vm_map_entry_t
*entry
) /* OUT */
969 register vm_map_entry_t cur
;
970 register vm_map_entry_t last
;
973 * Start looking either from the head of the
974 * list, or from the hint.
977 mutex_lock(&map
->s_lock
);
980 mutex_unlock(&map
->s_lock
);
982 if (cur
== vm_map_to_entry(map
))
985 if (address
>= cur
->vme_start
) {
987 * Go from hint to end of list.
989 * But first, make a quick check to see if
990 * we are already looking at the entry we
991 * want (which is usually the case).
992 * Note also that we don't need to save the hint
993 * here... it is the same hint (unless we are
994 * at the header, in which case the hint didn't
995 * buy us anything anyway).
997 last
= vm_map_to_entry(map
);
998 if ((cur
!= last
) && (cur
->vme_end
> address
)) {
1005 * Go from start to hint, *inclusively*
1007 last
= cur
->vme_next
;
1008 cur
= vm_map_first_entry(map
);
1015 while (cur
!= last
) {
1016 if (cur
->vme_end
> address
) {
1017 if (address
>= cur
->vme_start
) {
1019 * Save this lookup for future
1025 SAVE_HINT(map
, cur
);
1030 cur
= cur
->vme_next
;
1032 *entry
= cur
->vme_prev
;
1034 SAVE_HINT(map
, *entry
);
1039 * Routine: vm_map_find_space
1041 * Allocate a range in the specified virtual address map,
1042 * returning the entry allocated for that range.
1043 * Used by kmem_alloc, etc.
1045 * The map must be NOT be locked. It will be returned locked
1046 * on KERN_SUCCESS, unlocked on failure.
1048 * If an entry is allocated, the object/offset fields
1049 * are initialized to zero.
1053 register vm_map_t map
,
1054 vm_map_offset_t
*address
, /* OUT */
1056 vm_map_offset_t mask
,
1057 vm_map_entry_t
*o_entry
) /* OUT */
1059 register vm_map_entry_t entry
, new_entry
;
1060 register vm_map_offset_t start
;
1061 register vm_map_offset_t end
;
1065 return KERN_INVALID_ARGUMENT
;
1068 new_entry
= vm_map_entry_create(map
);
1071 * Look for the first possible address; if there's already
1072 * something at this address, we have to start after it.
1077 assert(first_free_is_valid(map
));
1078 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1079 start
= map
->min_offset
;
1081 start
= entry
->vme_end
;
1084 * In any case, the "entry" always precedes
1085 * the proposed new region throughout the loop:
1089 register vm_map_entry_t next
;
1092 * Find the end of the proposed new region.
1093 * Be sure we didn't go beyond the end, or
1094 * wrap around the address.
1097 end
= ((start
+ mask
) & ~mask
);
1099 vm_map_entry_dispose(map
, new_entry
);
1101 return(KERN_NO_SPACE
);
1106 if ((end
> map
->max_offset
) || (end
< start
)) {
1107 vm_map_entry_dispose(map
, new_entry
);
1109 return(KERN_NO_SPACE
);
1113 * If there are no more entries, we must win.
1116 next
= entry
->vme_next
;
1117 if (next
== vm_map_to_entry(map
))
1121 * If there is another entry, it must be
1122 * after the end of the potential new region.
1125 if (next
->vme_start
>= end
)
1129 * Didn't fit -- move to the next entry.
1133 start
= entry
->vme_end
;
1138 * "start" and "end" should define the endpoints of the
1139 * available new range, and
1140 * "entry" should refer to the region before the new
1143 * the map should be locked.
1148 new_entry
->vme_start
= start
;
1149 new_entry
->vme_end
= end
;
1150 assert(page_aligned(new_entry
->vme_start
));
1151 assert(page_aligned(new_entry
->vme_end
));
1153 new_entry
->is_shared
= FALSE
;
1154 new_entry
->is_sub_map
= FALSE
;
1155 new_entry
->use_pmap
= FALSE
;
1156 new_entry
->object
.vm_object
= VM_OBJECT_NULL
;
1157 new_entry
->offset
= (vm_object_offset_t
) 0;
1159 new_entry
->needs_copy
= FALSE
;
1161 new_entry
->inheritance
= VM_INHERIT_DEFAULT
;
1162 new_entry
->protection
= VM_PROT_DEFAULT
;
1163 new_entry
->max_protection
= VM_PROT_ALL
;
1164 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
1165 new_entry
->wired_count
= 0;
1166 new_entry
->user_wired_count
= 0;
1168 new_entry
->in_transition
= FALSE
;
1169 new_entry
->needs_wakeup
= FALSE
;
1172 * Insert the new entry into the list
1175 vm_map_entry_link(map
, entry
, new_entry
);
1180 * Update the lookup hint
1182 SAVE_HINT(map
, new_entry
);
1184 *o_entry
= new_entry
;
1185 return(KERN_SUCCESS
);
1188 int vm_map_pmap_enter_print
= FALSE
;
1189 int vm_map_pmap_enter_enable
= FALSE
;
1192 * Routine: vm_map_pmap_enter [internal only]
1195 * Force pages from the specified object to be entered into
1196 * the pmap at the specified address if they are present.
1197 * As soon as a page not found in the object the scan ends.
1202 * In/out conditions:
1203 * The source map should not be locked on entry.
1208 register vm_map_offset_t addr
,
1209 register vm_map_offset_t end_addr
,
1210 register vm_object_t object
,
1211 vm_object_offset_t offset
,
1212 vm_prot_t protection
)
1214 unsigned int cache_attr
;
1219 while (addr
< end_addr
) {
1220 register vm_page_t m
;
1222 vm_object_lock(object
);
1223 vm_object_paging_begin(object
);
1225 m
= vm_page_lookup(object
, offset
);
1228 * The user should never see encrypted data, so do not
1229 * enter an encrypted page in the page table.
1231 if (m
== VM_PAGE_NULL
|| m
->busy
|| m
->encrypted
||
1232 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
||
1233 protection
& m
->page_lock
))) {
1235 vm_object_paging_end(object
);
1236 vm_object_unlock(object
);
1240 assert(!m
->fictitious
); /* XXX is this possible ??? */
1242 if (vm_map_pmap_enter_print
) {
1243 printf("vm_map_pmap_enter:");
1244 printf("map: %x, addr: %llx, object: %x, offset: %llx\n",
1245 map
, (unsigned long long)addr
, object
, (unsigned long long)offset
);
1249 if (m
->no_isync
== TRUE
) {
1250 pmap_sync_page_data_phys(m
->phys_page
);
1251 m
->no_isync
= FALSE
;
1254 cache_attr
= ((unsigned int)object
->wimg_bits
) & VM_WIMG_MASK
;
1255 vm_object_unlock(object
);
1257 PMAP_ENTER(map
->pmap
, addr
, m
,
1258 protection
, cache_attr
, FALSE
);
1260 vm_object_lock(object
);
1262 PAGE_WAKEUP_DONE(m
);
1263 vm_page_lock_queues();
1264 if (!m
->active
&& !m
->inactive
)
1265 vm_page_activate(m
);
1266 vm_page_unlock_queues();
1267 vm_object_paging_end(object
);
1268 vm_object_unlock(object
);
1270 offset
+= PAGE_SIZE_64
;
1275 boolean_t
vm_map_pmap_is_empty(
1277 vm_map_offset_t start
,
1278 vm_map_offset_t end
);
1279 boolean_t
vm_map_pmap_is_empty(
1281 vm_map_offset_t start
,
1282 vm_map_offset_t end
)
1284 vm_map_offset_t offset
;
1287 if (map
->pmap
== NULL
) {
1290 for (offset
= start
;
1292 offset
+= PAGE_SIZE
) {
1293 phys_page
= pmap_find_phys(map
->pmap
, offset
);
1295 kprintf("vm_map_pmap_is_empty(%p,0x%llx,0x%llx): "
1296 "page %d at 0x%llx\n",
1297 map
, start
, end
, phys_page
, offset
);
1305 * Routine: vm_map_enter
1308 * Allocate a range in the specified virtual address map.
1309 * The resulting range will refer to memory defined by
1310 * the given memory object and offset into that object.
1312 * Arguments are as defined in the vm_map call.
1314 int _map_enter_debug
= 0;
1315 static unsigned int vm_map_enter_restore_successes
= 0;
1316 static unsigned int vm_map_enter_restore_failures
= 0;
1320 vm_map_offset_t
*address
, /* IN/OUT */
1322 vm_map_offset_t mask
,
1325 vm_object_offset_t offset
,
1326 boolean_t needs_copy
,
1327 vm_prot_t cur_protection
,
1328 vm_prot_t max_protection
,
1329 vm_inherit_t inheritance
)
1331 vm_map_entry_t entry
, new_entry
;
1332 vm_map_offset_t start
, tmp_start
;
1333 vm_map_offset_t end
, tmp_end
;
1334 kern_return_t result
= KERN_SUCCESS
;
1335 vm_map_t zap_old_map
= VM_MAP_NULL
;
1336 vm_map_t zap_new_map
= VM_MAP_NULL
;
1337 boolean_t map_locked
= FALSE
;
1338 boolean_t pmap_empty
= TRUE
;
1339 boolean_t new_mapping_established
= FALSE
;
1340 boolean_t anywhere
= ((flags
& VM_FLAGS_ANYWHERE
) != 0);
1341 boolean_t purgable
= ((flags
& VM_FLAGS_PURGABLE
) != 0);
1342 boolean_t overwrite
= ((flags
& VM_FLAGS_OVERWRITE
) != 0);
1347 return KERN_INVALID_ARGUMENT
;
1350 VM_GET_FLAGS_ALIAS(flags
, alias
);
1352 #define RETURN(value) { result = value; goto BailOut; }
1354 assert(page_aligned(*address
));
1355 assert(page_aligned(size
));
1358 * Only zero-fill objects are allowed to be purgable.
1359 * LP64todo - limit purgable objects to 32-bits for now
1363 (object
!= VM_OBJECT_NULL
&&
1364 (object
->size
!= size
||
1365 object
->purgable
== VM_OBJECT_NONPURGABLE
))
1366 || size
> VM_MAX_ADDRESS
)) /* LP64todo: remove when dp capable */
1367 return KERN_INVALID_ARGUMENT
;
1369 if (!anywhere
&& overwrite
) {
1371 * Create a temporary VM map to hold the old mappings in the
1372 * affected area while we create the new one.
1373 * This avoids releasing the VM map lock in
1374 * vm_map_entry_delete() and allows atomicity
1375 * when we want to replace some mappings with a new one.
1376 * It also allows us to restore the old VM mappings if the
1377 * new mapping fails.
1379 zap_old_map
= vm_map_create(PMAP_NULL
,
1394 * Calculate the first possible address.
1397 if (start
< map
->min_offset
)
1398 start
= map
->min_offset
;
1399 if (start
> map
->max_offset
)
1400 RETURN(KERN_NO_SPACE
);
1403 * Look for the first possible address;
1404 * if there's already something at this
1405 * address, we have to start after it.
1408 assert(first_free_is_valid(map
));
1409 if (start
== map
->min_offset
) {
1410 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
1411 start
= entry
->vme_end
;
1413 vm_map_entry_t tmp_entry
;
1414 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
1415 start
= tmp_entry
->vme_end
;
1420 * In any case, the "entry" always precedes
1421 * the proposed new region throughout the
1426 register vm_map_entry_t next
;
1429 * Find the end of the proposed new region.
1430 * Be sure we didn't go beyond the end, or
1431 * wrap around the address.
1434 end
= ((start
+ mask
) & ~mask
);
1436 RETURN(KERN_NO_SPACE
);
1440 if ((end
> map
->max_offset
) || (end
< start
)) {
1441 if (map
->wait_for_space
) {
1442 if (size
<= (map
->max_offset
-
1444 assert_wait((event_t
)map
,
1448 thread_block(THREAD_CONTINUE_NULL
);
1452 RETURN(KERN_NO_SPACE
);
1456 * If there are no more entries, we must win.
1459 next
= entry
->vme_next
;
1460 if (next
== vm_map_to_entry(map
))
1464 * If there is another entry, it must be
1465 * after the end of the potential new region.
1468 if (next
->vme_start
>= end
)
1472 * Didn't fit -- move to the next entry.
1476 start
= entry
->vme_end
;
1480 vm_map_entry_t temp_entry
;
1484 * the address doesn't itself violate
1485 * the mask requirement.
1490 if ((start
& mask
) != 0)
1491 RETURN(KERN_NO_SPACE
);
1494 * ... the address is within bounds
1499 if ((start
< map
->min_offset
) ||
1500 (end
> map
->max_offset
) ||
1502 RETURN(KERN_INVALID_ADDRESS
);
1505 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
1507 * Fixed mapping and "overwrite" flag: attempt to
1508 * remove all existing mappings in the specified
1509 * address range, saving them in our "zap_old_map".
1511 (void) vm_map_delete(map
, start
, end
,
1512 VM_MAP_REMOVE_SAVE_ENTRIES
,
1517 * ... the starting address isn't allocated
1520 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
1521 RETURN(KERN_NO_SPACE
);
1526 * ... the next region doesn't overlap the
1530 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
1531 (entry
->vme_next
->vme_start
< end
))
1532 RETURN(KERN_NO_SPACE
);
1537 * "start" and "end" should define the endpoints of the
1538 * available new range, and
1539 * "entry" should refer to the region before the new
1542 * the map should be locked.
1546 * See whether we can avoid creating a new entry (and object) by
1547 * extending one of our neighbors. [So far, we only attempt to
1548 * extend from below.] Note that we can never extend/join
1549 * purgable objects because they need to remain distinct
1550 * entities in order to implement their "volatile object"
1555 if (object
== VM_OBJECT_NULL
) {
1556 object
= vm_object_allocate(size
);
1557 object
->copy_strategy
= MEMORY_OBJECT_COPY_NONE
;
1558 object
->purgable
= VM_OBJECT_PURGABLE_NONVOLATILE
;
1559 offset
= (vm_object_offset_t
)0;
1561 } else if ((object
== VM_OBJECT_NULL
) &&
1562 (entry
!= vm_map_to_entry(map
)) &&
1563 (entry
->vme_end
== start
) &&
1564 (!entry
->is_shared
) &&
1565 (!entry
->is_sub_map
) &&
1566 (entry
->alias
== alias
) &&
1567 (entry
->inheritance
== inheritance
) &&
1568 (entry
->protection
== cur_protection
) &&
1569 (entry
->max_protection
== max_protection
) &&
1570 (entry
->behavior
== VM_BEHAVIOR_DEFAULT
) &&
1571 (entry
->in_transition
== 0) &&
1572 ((alias
== VM_MEMORY_REALLOC
) || ((entry
->vme_end
- entry
->vme_start
) + size
< NO_COALESCE_LIMIT
)) &&
1573 (entry
->wired_count
== 0)) { /* implies user_wired_count == 0 */
1574 if (vm_object_coalesce(entry
->object
.vm_object
,
1577 (vm_object_offset_t
) 0,
1578 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
),
1579 (vm_map_size_t
)(end
- entry
->vme_end
))) {
1582 * Coalesced the two objects - can extend
1583 * the previous map entry to include the
1586 map
->size
+= (end
- entry
->vme_end
);
1587 entry
->vme_end
= end
;
1588 UPDATE_FIRST_FREE(map
, map
->first_free
);
1589 RETURN(KERN_SUCCESS
);
1594 * Create a new entry
1595 * LP64todo - for now, we can only allocate 4GB internal objects
1596 * because the default pager can't page bigger ones. Remove this
1600 if (object
== VM_OBJECT_NULL
&& size
> (vm_map_size_t
)VM_MAX_ADDRESS
)
1601 tmp_end
= tmp_start
+ (vm_map_size_t
)VM_MAX_ADDRESS
;
1605 new_entry
= vm_map_entry_insert(map
, entry
, tmp_start
, tmp_end
,
1606 object
, offset
, needs_copy
, FALSE
, FALSE
,
1607 cur_protection
, max_protection
,
1608 VM_BEHAVIOR_DEFAULT
, inheritance
, 0);
1609 new_entry
->alias
= alias
;
1611 } while (object
== VM_OBJECT_NULL
&&
1613 (tmp_start
= tmp_end
) &&
1614 (tmp_end
= (end
- tmp_end
> (vm_map_size_t
)VM_MAX_ADDRESS
) ?
1615 tmp_end
+ (vm_map_size_t
)VM_MAX_ADDRESS
: end
));
1620 new_mapping_established
= TRUE
;
1622 /* Wire down the new entry if the user
1623 * requested all new map entries be wired.
1625 if (map
->wiring_required
) {
1626 pmap_empty
= FALSE
; /* pmap won't be empty */
1627 result
= vm_map_wire(map
, start
, end
,
1628 new_entry
->protection
, TRUE
);
1632 if ((object
!= VM_OBJECT_NULL
) &&
1633 (vm_map_pmap_enter_enable
) &&
1636 (size
< (128*1024))) {
1637 pmap_empty
= FALSE
; /* pmap won't be empty */
1638 vm_map_pmap_enter(map
, start
, end
,
1639 object
, offset
, cur_protection
);
1643 if (result
== KERN_SUCCESS
&&
1645 !(flags
& VM_FLAGS_NO_PMAP_CHECK
)) {
1646 assert(vm_map_pmap_is_empty(map
, *address
, *address
+size
));
1649 if (result
!= KERN_SUCCESS
) {
1650 if (new_mapping_established
) {
1652 * We have to get rid of the new mappings since we
1653 * won't make them available to the user.
1654 * Try and do that atomically, to minimize the risk
1655 * that someone else create new mappings that range.
1657 zap_new_map
= vm_map_create(PMAP_NULL
,
1665 (void) vm_map_delete(map
, *address
, *address
+size
,
1666 VM_MAP_REMOVE_SAVE_ENTRIES
,
1669 if (zap_old_map
!= VM_MAP_NULL
&&
1670 zap_old_map
->hdr
.nentries
!= 0) {
1671 vm_map_entry_t entry1
, entry2
;
1674 * The new mapping failed. Attempt to restore
1675 * the old mappings, saved in the "zap_old_map".
1682 /* first check if the coast is still clear */
1683 start
= vm_map_first_entry(zap_old_map
)->vme_start
;
1684 end
= vm_map_last_entry(zap_old_map
)->vme_end
;
1685 if (vm_map_lookup_entry(map
, start
, &entry1
) ||
1686 vm_map_lookup_entry(map
, end
, &entry2
) ||
1689 * Part of that range has already been
1690 * re-mapped: we can't restore the old
1693 vm_map_enter_restore_failures
++;
1696 * Transfer the saved map entries from
1697 * "zap_old_map" to the original "map",
1698 * inserting them all after "entry1".
1700 for (entry2
= vm_map_first_entry(zap_old_map
);
1701 entry2
!= vm_map_to_entry(zap_old_map
);
1702 entry2
= vm_map_first_entry(zap_old_map
)) {
1703 vm_map_entry_unlink(zap_old_map
,
1705 vm_map_entry_link(map
, entry1
, entry2
);
1708 if (map
->wiring_required
) {
1710 * XXX TODO: we should rewire the
1714 vm_map_enter_restore_successes
++;
1724 * Get rid of the "zap_maps" and all the map entries that
1725 * they may still contain.
1727 if (zap_old_map
!= VM_MAP_NULL
) {
1728 vm_map_destroy(zap_old_map
);
1729 zap_old_map
= VM_MAP_NULL
;
1731 if (zap_new_map
!= VM_MAP_NULL
) {
1732 vm_map_destroy(zap_new_map
);
1733 zap_new_map
= VM_MAP_NULL
;
1745 extern vm_offset_t avail_start
, avail_end
;
1749 * Allocate memory in the specified map, with the caveat that
1750 * the memory is physically contiguous. This call may fail
1751 * if the system can't find sufficient contiguous memory.
1752 * This call may cause or lead to heart-stopping amounts of
1755 * Memory obtained from this call should be freed in the
1756 * normal way, viz., via vm_deallocate.
1761 vm_map_offset_t
*addr
,
1765 vm_object_t cpm_obj
;
1769 vm_map_offset_t va
, start
, end
, offset
;
1771 vm_map_offset_t prev_addr
;
1772 #endif /* MACH_ASSERT */
1774 boolean_t anywhere
= ((VM_FLAGS_ANYWHERE
& flags
) != 0);
1776 if (!vm_allocate_cpm_enabled
)
1777 return KERN_FAILURE
;
1781 return KERN_SUCCESS
;
1785 *addr
= vm_map_min(map
);
1787 *addr
= vm_map_trunc_page(*addr
);
1788 size
= vm_map_round_page(size
);
1791 * LP64todo - cpm_allocate should probably allow
1792 * allocations of >4GB, but not with the current
1793 * algorithm, so just cast down the size for now.
1795 if (size
> VM_MAX_ADDRESS
)
1796 return KERN_RESOURCE_SHORTAGE
;
1797 if ((kr
= cpm_allocate(CAST_DOWN(vm_size_t
, size
),
1798 &pages
, TRUE
)) != KERN_SUCCESS
)
1801 cpm_obj
= vm_object_allocate((vm_object_size_t
)size
);
1802 assert(cpm_obj
!= VM_OBJECT_NULL
);
1803 assert(cpm_obj
->internal
);
1804 assert(cpm_obj
->size
== (vm_object_size_t
)size
);
1805 assert(cpm_obj
->can_persist
== FALSE
);
1806 assert(cpm_obj
->pager_created
== FALSE
);
1807 assert(cpm_obj
->pageout
== FALSE
);
1808 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
1811 * Insert pages into object.
1814 vm_object_lock(cpm_obj
);
1815 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
1817 pages
= NEXT_PAGE(m
);
1819 assert(!m
->gobbled
);
1821 assert(!m
->pageout
);
1825 * "m" is not supposed to be pageable, so it
1826 * should not be encrypted. It wouldn't be safe
1827 * to enter it in a new VM object while encrypted.
1829 ASSERT_PAGE_DECRYPTED(m
);
1831 assert(m
->phys_page
>=avail_start
&& m
->phys_page
<=avail_end
);
1834 vm_page_insert(m
, cpm_obj
, offset
);
1836 assert(cpm_obj
->resident_page_count
== size
/ PAGE_SIZE
);
1837 vm_object_unlock(cpm_obj
);
1840 * Hang onto a reference on the object in case a
1841 * multi-threaded application for some reason decides
1842 * to deallocate the portion of the address space into
1843 * which we will insert this object.
1845 * Unfortunately, we must insert the object now before
1846 * we can talk to the pmap module about which addresses
1847 * must be wired down. Hence, the race with a multi-
1850 vm_object_reference(cpm_obj
);
1853 * Insert object into map.
1863 (vm_object_offset_t
)0,
1867 VM_INHERIT_DEFAULT
);
1869 if (kr
!= KERN_SUCCESS
) {
1871 * A CPM object doesn't have can_persist set,
1872 * so all we have to do is deallocate it to
1873 * free up these pages.
1875 assert(cpm_obj
->pager_created
== FALSE
);
1876 assert(cpm_obj
->can_persist
== FALSE
);
1877 assert(cpm_obj
->pageout
== FALSE
);
1878 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
1879 vm_object_deallocate(cpm_obj
); /* kill acquired ref */
1880 vm_object_deallocate(cpm_obj
); /* kill creation ref */
1884 * Inform the physical mapping system that the
1885 * range of addresses may not fault, so that
1886 * page tables and such can be locked down as well.
1890 pmap
= vm_map_pmap(map
);
1891 pmap_pageable(pmap
, start
, end
, FALSE
);
1894 * Enter each page into the pmap, to avoid faults.
1895 * Note that this loop could be coded more efficiently,
1896 * if the need arose, rather than looking up each page
1899 for (offset
= 0, va
= start
; offset
< size
;
1900 va
+= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
1901 vm_object_lock(cpm_obj
);
1902 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
1903 vm_object_unlock(cpm_obj
);
1904 assert(m
!= VM_PAGE_NULL
);
1905 PMAP_ENTER(pmap
, va
, m
, VM_PROT_ALL
,
1906 ((unsigned int)(m
->object
->wimg_bits
)) & VM_WIMG_MASK
,
1912 * Verify ordering in address space.
1914 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
1915 vm_object_lock(cpm_obj
);
1916 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
1917 vm_object_unlock(cpm_obj
);
1918 if (m
== VM_PAGE_NULL
)
1919 panic("vm_allocate_cpm: obj 0x%x off 0x%x no page",
1924 assert(!m
->fictitious
);
1925 assert(!m
->private);
1928 assert(!m
->cleaning
);
1929 assert(!m
->precious
);
1930 assert(!m
->clustered
);
1932 if (m
->phys_page
!= prev_addr
+ 1) {
1933 printf("start 0x%x end 0x%x va 0x%x\n",
1935 printf("obj 0x%x off 0x%x\n", cpm_obj
, offset
);
1936 printf("m 0x%x prev_address 0x%x\n", m
,
1938 panic("vm_allocate_cpm: pages not contig!");
1941 prev_addr
= m
->phys_page
;
1943 #endif /* MACH_ASSERT */
1945 vm_object_deallocate(cpm_obj
); /* kill extra ref */
1954 * Interface is defined in all cases, but unless the kernel
1955 * is built explicitly for this option, the interface does
1961 __unused vm_map_t map
,
1962 __unused vm_map_offset_t
*addr
,
1963 __unused vm_map_size_t size
,
1966 return KERN_FAILURE
;
1971 * vm_map_clip_start: [ internal use only ]
1973 * Asserts that the given entry begins at or after
1974 * the specified address; if necessary,
1975 * it splits the entry into two.
1978 #define vm_map_clip_start(map, entry, startaddr) \
1980 vm_map_t VMCS_map; \
1981 vm_map_entry_t VMCS_entry; \
1982 vm_map_offset_t VMCS_startaddr; \
1984 VMCS_entry = (entry); \
1985 VMCS_startaddr = (startaddr); \
1986 if (VMCS_startaddr > VMCS_entry->vme_start) { \
1987 if(entry->use_pmap) { \
1988 vm_map_offset_t pmap_base_addr; \
1990 pmap_base_addr = 0xF0000000 & entry->vme_start; \
1991 pmap_unnest(map->pmap, (addr64_t)pmap_base_addr); \
1992 entry->use_pmap = FALSE; \
1993 } else if(entry->object.vm_object \
1994 && !entry->is_sub_map \
1995 && entry->object.vm_object->phys_contiguous) { \
1996 pmap_remove(map->pmap, \
1997 (addr64_t)(entry->vme_start), \
1998 (addr64_t)(entry->vme_end)); \
2000 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
2002 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2005 #define vm_map_clip_start(map, entry, startaddr) \
2007 vm_map_t VMCS_map; \
2008 vm_map_entry_t VMCS_entry; \
2009 vm_map_offset_t VMCS_startaddr; \
2011 VMCS_entry = (entry); \
2012 VMCS_startaddr = (startaddr); \
2013 if (VMCS_startaddr > VMCS_entry->vme_start) { \
2014 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
2016 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2020 #define vm_map_copy_clip_start(copy, entry, startaddr) \
2022 if ((startaddr) > (entry)->vme_start) \
2023 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
2027 * This routine is called only when it is known that
2028 * the entry must be split.
2032 register struct vm_map_header
*map_header
,
2033 register vm_map_entry_t entry
,
2034 register vm_map_offset_t start
)
2036 register vm_map_entry_t new_entry
;
2039 * Split off the front portion --
2040 * note that we must insert the new
2041 * entry BEFORE this one, so that
2042 * this entry has the specified starting
2046 new_entry
= _vm_map_entry_create(map_header
);
2047 vm_map_entry_copy_full(new_entry
, entry
);
2049 new_entry
->vme_end
= start
;
2050 entry
->offset
+= (start
- entry
->vme_start
);
2051 entry
->vme_start
= start
;
2053 _vm_map_entry_link(map_header
, entry
->vme_prev
, new_entry
);
2055 if (entry
->is_sub_map
)
2056 vm_map_reference(new_entry
->object
.sub_map
);
2058 vm_object_reference(new_entry
->object
.vm_object
);
2063 * vm_map_clip_end: [ internal use only ]
2065 * Asserts that the given entry ends at or before
2066 * the specified address; if necessary,
2067 * it splits the entry into two.
2070 #define vm_map_clip_end(map, entry, endaddr) \
2072 vm_map_t VMCE_map; \
2073 vm_map_entry_t VMCE_entry; \
2074 vm_map_offset_t VMCE_endaddr; \
2076 VMCE_entry = (entry); \
2077 VMCE_endaddr = (endaddr); \
2078 if (VMCE_endaddr < VMCE_entry->vme_end) { \
2079 if(entry->use_pmap) { \
2080 vm_map_offset_t pmap_base_addr; \
2082 pmap_base_addr = 0xF0000000 & entry->vme_start; \
2083 pmap_unnest(map->pmap, (addr64_t)pmap_base_addr); \
2084 entry->use_pmap = FALSE; \
2085 } else if(entry->object.vm_object \
2086 && !entry->is_sub_map \
2087 && entry->object.vm_object->phys_contiguous) { \
2088 pmap_remove(map->pmap, \
2089 (addr64_t)(entry->vme_start), \
2090 (addr64_t)(entry->vme_end)); \
2092 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
2094 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2097 #define vm_map_clip_end(map, entry, endaddr) \
2099 vm_map_t VMCE_map; \
2100 vm_map_entry_t VMCE_entry; \
2101 vm_map_offset_t VMCE_endaddr; \
2103 VMCE_entry = (entry); \
2104 VMCE_endaddr = (endaddr); \
2105 if (VMCE_endaddr < VMCE_entry->vme_end) { \
2106 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
2108 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2112 #define vm_map_copy_clip_end(copy, entry, endaddr) \
2114 if ((endaddr) < (entry)->vme_end) \
2115 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
2119 * This routine is called only when it is known that
2120 * the entry must be split.
2124 register struct vm_map_header
*map_header
,
2125 register vm_map_entry_t entry
,
2126 register vm_map_offset_t end
)
2128 register vm_map_entry_t new_entry
;
2131 * Create a new entry and insert it
2132 * AFTER the specified entry
2135 new_entry
= _vm_map_entry_create(map_header
);
2136 vm_map_entry_copy_full(new_entry
, entry
);
2138 new_entry
->vme_start
= entry
->vme_end
= end
;
2139 new_entry
->offset
+= (end
- entry
->vme_start
);
2141 _vm_map_entry_link(map_header
, entry
, new_entry
);
2143 if (entry
->is_sub_map
)
2144 vm_map_reference(new_entry
->object
.sub_map
);
2146 vm_object_reference(new_entry
->object
.vm_object
);
2151 * VM_MAP_RANGE_CHECK: [ internal use only ]
2153 * Asserts that the starting and ending region
2154 * addresses fall within the valid range of the map.
2156 #define VM_MAP_RANGE_CHECK(map, start, end) \
2158 if (start < vm_map_min(map)) \
2159 start = vm_map_min(map); \
2160 if (end > vm_map_max(map)) \
2161 end = vm_map_max(map); \
2167 * vm_map_range_check: [ internal use only ]
2169 * Check that the region defined by the specified start and
2170 * end addresses are wholly contained within a single map
2171 * entry or set of adjacent map entries of the spacified map,
2172 * i.e. the specified region contains no unmapped space.
2173 * If any or all of the region is unmapped, FALSE is returned.
2174 * Otherwise, TRUE is returned and if the output argument 'entry'
2175 * is not NULL it points to the map entry containing the start
2178 * The map is locked for reading on entry and is left locked.
2182 register vm_map_t map
,
2183 register vm_map_offset_t start
,
2184 register vm_map_offset_t end
,
2185 vm_map_entry_t
*entry
)
2188 register vm_map_offset_t prev
;
2191 * Basic sanity checks first
2193 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
2197 * Check first if the region starts within a valid
2198 * mapping for the map.
2200 if (!vm_map_lookup_entry(map
, start
, &cur
))
2204 * Optimize for the case that the region is contained
2205 * in a single map entry.
2207 if (entry
!= (vm_map_entry_t
*) NULL
)
2209 if (end
<= cur
->vme_end
)
2213 * If the region is not wholly contained within a
2214 * single entry, walk the entries looking for holes.
2216 prev
= cur
->vme_end
;
2217 cur
= cur
->vme_next
;
2218 while ((cur
!= vm_map_to_entry(map
)) && (prev
== cur
->vme_start
)) {
2219 if (end
<= cur
->vme_end
)
2221 prev
= cur
->vme_end
;
2222 cur
= cur
->vme_next
;
2228 * vm_map_submap: [ kernel use only ]
2230 * Mark the given range as handled by a subordinate map.
2232 * This range must have been created with vm_map_find using
2233 * the vm_submap_object, and no other operations may have been
2234 * performed on this range prior to calling vm_map_submap.
2236 * Only a limited number of operations can be performed
2237 * within this rage after calling vm_map_submap:
2239 * [Don't try vm_map_copyin!]
2241 * To remove a submapping, one must first remove the
2242 * range from the superior map, and then destroy the
2243 * submap (if desired). [Better yet, don't try it.]
2248 vm_map_offset_t start
,
2249 vm_map_offset_t end
,
2251 vm_map_offset_t offset
,
2257 vm_map_entry_t entry
;
2258 register kern_return_t result
= KERN_INVALID_ARGUMENT
;
2259 register vm_object_t object
;
2263 submap
->mapped
= TRUE
;
2265 VM_MAP_RANGE_CHECK(map
, start
, end
);
2267 if (vm_map_lookup_entry(map
, start
, &entry
)) {
2268 vm_map_clip_start(map
, entry
, start
);
2271 entry
= entry
->vme_next
;
2273 if(entry
== vm_map_to_entry(map
)) {
2275 return KERN_INVALID_ARGUMENT
;
2278 vm_map_clip_end(map
, entry
, end
);
2280 if ((entry
->vme_start
== start
) && (entry
->vme_end
== end
) &&
2281 (!entry
->is_sub_map
) &&
2282 ((object
= entry
->object
.vm_object
) == vm_submap_object
) &&
2283 (object
->resident_page_count
== 0) &&
2284 (object
->copy
== VM_OBJECT_NULL
) &&
2285 (object
->shadow
== VM_OBJECT_NULL
) &&
2286 (!object
->pager_created
)) {
2287 entry
->offset
= (vm_object_offset_t
)offset
;
2288 entry
->object
.vm_object
= VM_OBJECT_NULL
;
2289 vm_object_deallocate(object
);
2290 entry
->is_sub_map
= TRUE
;
2291 entry
->object
.sub_map
= submap
;
2292 vm_map_reference(submap
);
2294 if ((use_pmap
) && (offset
== 0)) {
2295 /* nest if platform code will allow */
2296 if(submap
->pmap
== NULL
) {
2297 submap
->pmap
= pmap_create((vm_map_size_t
) 0);
2298 if(submap
->pmap
== PMAP_NULL
) {
2300 return(KERN_NO_SPACE
);
2303 result
= pmap_nest(map
->pmap
, (entry
->object
.sub_map
)->pmap
,
2306 (uint64_t)(end
- start
));
2308 panic("vm_map_submap: pmap_nest failed, rc = %08X\n", result
);
2309 entry
->use_pmap
= TRUE
;
2313 pmap_remove(map
->pmap
, (addr64_t
)start
, (addr64_t
)end
);
2315 result
= KERN_SUCCESS
;
2325 * Sets the protection of the specified address
2326 * region in the target map. If "set_max" is
2327 * specified, the maximum protection is to be set;
2328 * otherwise, only the current protection is affected.
2332 register vm_map_t map
,
2333 register vm_map_offset_t start
,
2334 register vm_map_offset_t end
,
2335 register vm_prot_t new_prot
,
2336 register boolean_t set_max
)
2338 register vm_map_entry_t current
;
2339 register vm_map_offset_t prev
;
2340 vm_map_entry_t entry
;
2345 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
2346 (integer_t
)map
, start
, end
, new_prot
, set_max
);
2350 /* LP64todo - remove this check when vm_map_commpage64()
2351 * no longer has to stuff in a map_entry for the commpage
2352 * above the map's max_offset.
2354 if (start
>= map
->max_offset
) {
2356 return(KERN_INVALID_ADDRESS
);
2360 * Lookup the entry. If it doesn't start in a valid
2361 * entry, return an error. Remember if we need to
2362 * clip the entry. We don't do it here because we don't
2363 * want to make any changes until we've scanned the
2364 * entire range below for address and protection
2367 if (!(clip
= vm_map_lookup_entry(map
, start
, &entry
))) {
2369 return(KERN_INVALID_ADDRESS
);
2373 * Make a first pass to check for protection and address
2378 prev
= current
->vme_start
;
2379 while ((current
!= vm_map_to_entry(map
)) &&
2380 (current
->vme_start
< end
)) {
2383 * If there is a hole, return an error.
2385 if (current
->vme_start
!= prev
) {
2387 return(KERN_INVALID_ADDRESS
);
2390 new_max
= current
->max_protection
;
2391 if(new_prot
& VM_PROT_COPY
) {
2392 new_max
|= VM_PROT_WRITE
;
2393 if ((new_prot
& (new_max
| VM_PROT_COPY
)) != new_prot
) {
2395 return(KERN_PROTECTION_FAILURE
);
2398 if ((new_prot
& new_max
) != new_prot
) {
2400 return(KERN_PROTECTION_FAILURE
);
2404 prev
= current
->vme_end
;
2405 current
= current
->vme_next
;
2409 return(KERN_INVALID_ADDRESS
);
2413 * Go back and fix up protections.
2414 * Clip to start here if the range starts within
2420 vm_map_clip_start(map
, entry
, start
);
2422 while ((current
!= vm_map_to_entry(map
)) &&
2423 (current
->vme_start
< end
)) {
2427 vm_map_clip_end(map
, current
, end
);
2429 old_prot
= current
->protection
;
2431 if(new_prot
& VM_PROT_COPY
) {
2432 /* caller is asking specifically to copy the */
2433 /* mapped data, this implies that max protection */
2434 /* will include write. Caller must be prepared */
2435 /* for loss of shared memory communication in the */
2436 /* target area after taking this step */
2437 current
->needs_copy
= TRUE
;
2438 current
->max_protection
|= VM_PROT_WRITE
;
2442 current
->protection
=
2443 (current
->max_protection
=
2444 new_prot
& ~VM_PROT_COPY
) &
2447 current
->protection
= new_prot
& ~VM_PROT_COPY
;
2450 * Update physical map if necessary.
2451 * If the request is to turn off write protection,
2452 * we won't do it for real (in pmap). This is because
2453 * it would cause copy-on-write to fail. We've already
2454 * set, the new protection in the map, so if a
2455 * write-protect fault occurred, it will be fixed up
2456 * properly, COW or not.
2458 /* the 256M hack for existing hardware limitations */
2459 if (current
->protection
!= old_prot
) {
2460 if(current
->is_sub_map
&& current
->use_pmap
) {
2461 vm_map_offset_t pmap_base_addr
;
2462 vm_map_offset_t pmap_end_addr
;
2466 vm_map_entry_t local_entry
;
2468 pmap_base_addr
= 0xF0000000 & current
->vme_start
;
2469 pmap_end_addr
= (pmap_base_addr
+ 0x10000000) - 1;
2471 if(!vm_map_lookup_entry(map
,
2472 pmap_base_addr
, &local_entry
))
2473 panic("vm_map_protect: nested pmap area is missing");
2474 while ((local_entry
!= vm_map_to_entry(map
)) &&
2475 (local_entry
->vme_start
< pmap_end_addr
)) {
2476 local_entry
->use_pmap
= FALSE
;
2477 local_entry
= local_entry
->vme_next
;
2479 pmap_unnest(map
->pmap
, (addr64_t
)pmap_base_addr
);
2482 if (!(current
->protection
& VM_PROT_WRITE
)) {
2483 /* Look one level in we support nested pmaps */
2484 /* from mapped submaps which are direct entries */
2486 if(current
->is_sub_map
&& current
->use_pmap
) {
2487 pmap_protect(current
->object
.sub_map
->pmap
,
2490 current
->protection
);
2492 pmap_protect(map
->pmap
, current
->vme_start
,
2494 current
->protection
);
2498 current
= current
->vme_next
;
2502 while ((current
!= vm_map_to_entry(map
)) &&
2503 (current
->vme_start
<= end
)) {
2504 vm_map_simplify_entry(map
, current
);
2505 current
= current
->vme_next
;
2509 return(KERN_SUCCESS
);
2515 * Sets the inheritance of the specified address
2516 * range in the target map. Inheritance
2517 * affects how the map will be shared with
2518 * child maps at the time of vm_map_fork.
2522 register vm_map_t map
,
2523 register vm_map_offset_t start
,
2524 register vm_map_offset_t end
,
2525 register vm_inherit_t new_inheritance
)
2527 register vm_map_entry_t entry
;
2528 vm_map_entry_t temp_entry
;
2532 VM_MAP_RANGE_CHECK(map
, start
, end
);
2534 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
2536 vm_map_clip_start(map
, entry
, start
);
2539 temp_entry
= temp_entry
->vme_next
;
2543 /* first check entire range for submaps which can't support the */
2544 /* given inheritance. */
2545 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2546 if(entry
->is_sub_map
) {
2547 if(new_inheritance
== VM_INHERIT_COPY
) {
2549 return(KERN_INVALID_ARGUMENT
);
2553 entry
= entry
->vme_next
;
2558 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2559 vm_map_clip_end(map
, entry
, end
);
2561 entry
->inheritance
= new_inheritance
;
2563 entry
= entry
->vme_next
;
2567 return(KERN_SUCCESS
);
2573 * Sets the pageability of the specified address range in the
2574 * target map as wired. Regions specified as not pageable require
2575 * locked-down physical memory and physical page maps. The
2576 * access_type variable indicates types of accesses that must not
2577 * generate page faults. This is checked against protection of
2578 * memory being locked-down.
2580 * The map must not be locked, but a reference must remain to the
2581 * map throughout the call.
2583 static kern_return_t
2585 register vm_map_t map
,
2586 register vm_map_offset_t start
,
2587 register vm_map_offset_t end
,
2588 register vm_prot_t access_type
,
2589 boolean_t user_wire
,
2591 vm_map_offset_t pmap_addr
)
2593 register vm_map_entry_t entry
;
2594 struct vm_map_entry
*first_entry
, tmp_entry
;
2596 register vm_map_offset_t s
,e
;
2598 boolean_t need_wakeup
;
2599 boolean_t main_map
= FALSE
;
2600 wait_interrupt_t interruptible_state
;
2601 thread_t cur_thread
;
2602 unsigned int last_timestamp
;
2606 if(map_pmap
== NULL
)
2608 last_timestamp
= map
->timestamp
;
2610 VM_MAP_RANGE_CHECK(map
, start
, end
);
2611 assert(page_aligned(start
));
2612 assert(page_aligned(end
));
2614 /* We wired what the caller asked for, zero pages */
2616 return KERN_SUCCESS
;
2619 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
2620 entry
= first_entry
;
2621 /* vm_map_clip_start will be done later. */
2623 /* Start address is not in map */
2625 return(KERN_INVALID_ADDRESS
);
2629 need_wakeup
= FALSE
;
2630 cur_thread
= current_thread();
2631 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2633 * If another thread is wiring/unwiring this entry then
2634 * block after informing other thread to wake us up.
2636 if (entry
->in_transition
) {
2637 wait_result_t wait_result
;
2640 * We have not clipped the entry. Make sure that
2641 * the start address is in range so that the lookup
2642 * below will succeed.
2644 s
= entry
->vme_start
< start
? start
: entry
->vme_start
;
2646 entry
->needs_wakeup
= TRUE
;
2649 * wake up anybody waiting on entries that we have
2653 vm_map_entry_wakeup(map
);
2654 need_wakeup
= FALSE
;
2657 * User wiring is interruptible
2659 wait_result
= vm_map_entry_wait(map
,
2660 (user_wire
) ? THREAD_ABORTSAFE
:
2662 if (user_wire
&& wait_result
== THREAD_INTERRUPTED
) {
2664 * undo the wirings we have done so far
2665 * We do not clear the needs_wakeup flag,
2666 * because we cannot tell if we were the
2670 vm_map_unwire(map
, start
, s
, user_wire
);
2671 return(KERN_FAILURE
);
2675 * Cannot avoid a lookup here. reset timestamp.
2677 last_timestamp
= map
->timestamp
;
2680 * The entry could have been clipped, look it up again.
2681 * Worse that can happen is, it may not exist anymore.
2683 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
2685 panic("vm_map_wire: re-lookup failed");
2688 * User: undo everything upto the previous
2689 * entry. let vm_map_unwire worry about
2690 * checking the validity of the range.
2693 vm_map_unwire(map
, start
, s
, user_wire
);
2694 return(KERN_FAILURE
);
2696 entry
= first_entry
;
2700 if(entry
->is_sub_map
) {
2701 vm_map_offset_t sub_start
;
2702 vm_map_offset_t sub_end
;
2703 vm_map_offset_t local_start
;
2704 vm_map_offset_t local_end
;
2707 vm_map_clip_start(map
, entry
, start
);
2708 vm_map_clip_end(map
, entry
, end
);
2710 sub_start
= entry
->offset
;
2711 sub_end
= entry
->vme_end
- entry
->vme_start
;
2712 sub_end
+= entry
->offset
;
2714 local_end
= entry
->vme_end
;
2715 if(map_pmap
== NULL
) {
2716 if(entry
->use_pmap
) {
2717 pmap
= entry
->object
.sub_map
->pmap
;
2718 /* ppc implementation requires that */
2719 /* submaps pmap address ranges line */
2720 /* up with parent map */
2722 pmap_addr
= sub_start
;
2729 if (entry
->wired_count
) {
2730 if (entry
->wired_count
2732 panic("vm_map_wire: too many wirings");
2735 entry
->user_wired_count
2736 >= MAX_WIRE_COUNT
) {
2738 vm_map_unwire(map
, start
,
2739 entry
->vme_start
, user_wire
);
2740 return(KERN_FAILURE
);
2743 entry
->user_wired_count
++;
2745 (entry
->user_wired_count
== 0))
2746 entry
->wired_count
++;
2747 entry
= entry
->vme_next
;
2752 vm_map_offset_t offset_hi
;
2753 vm_map_offset_t offset_lo
;
2754 vm_object_offset_t offset
;
2757 vm_behavior_t behavior
;
2758 vm_map_entry_t local_entry
;
2759 vm_map_version_t version
;
2760 vm_map_t lookup_map
;
2762 /* call vm_map_lookup_locked to */
2763 /* cause any needs copy to be */
2765 local_start
= entry
->vme_start
;
2767 vm_map_lock_write_to_read(map
);
2768 if(vm_map_lookup_locked(
2769 &lookup_map
, local_start
,
2772 &offset
, &prot
, &wired
,
2773 &behavior
, &offset_lo
,
2774 &offset_hi
, &real_map
)) {
2776 vm_map_unlock_read(lookup_map
);
2777 vm_map_unwire(map
, start
,
2778 entry
->vme_start
, user_wire
);
2779 return(KERN_FAILURE
);
2781 if(real_map
!= lookup_map
)
2782 vm_map_unlock(real_map
);
2783 vm_map_unlock_read(lookup_map
);
2785 vm_object_unlock(object
);
2787 if (!vm_map_lookup_entry(map
,
2788 local_start
, &local_entry
)) {
2790 vm_map_unwire(map
, start
,
2791 entry
->vme_start
, user_wire
);
2792 return(KERN_FAILURE
);
2794 /* did we have a change of type? */
2795 if (!local_entry
->is_sub_map
) {
2796 last_timestamp
= map
->timestamp
;
2799 entry
= local_entry
;
2801 entry
->user_wired_count
++;
2803 (entry
->user_wired_count
== 1))
2804 entry
->wired_count
++;
2806 entry
->in_transition
= TRUE
;
2809 rc
= vm_map_wire_nested(
2810 entry
->object
.sub_map
,
2813 user_wire
, pmap
, pmap_addr
);
2817 local_start
= entry
->vme_start
;
2819 entry
->user_wired_count
++;
2821 (entry
->user_wired_count
== 1))
2822 entry
->wired_count
++;
2824 rc
= vm_map_wire_nested(entry
->object
.sub_map
,
2827 user_wire
, map_pmap
, pmap_addr
);
2830 s
= entry
->vme_start
;
2834 * Find the entry again. It could have been clipped
2835 * after we unlocked the map.
2837 if (!vm_map_lookup_entry(map
, local_start
,
2839 panic("vm_map_wire: re-lookup failed");
2840 entry
= first_entry
;
2842 last_timestamp
= map
->timestamp
;
2843 while ((entry
!= vm_map_to_entry(map
)) &&
2844 (entry
->vme_start
< e
)) {
2845 assert(entry
->in_transition
);
2846 entry
->in_transition
= FALSE
;
2847 if (entry
->needs_wakeup
) {
2848 entry
->needs_wakeup
= FALSE
;
2851 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
2853 entry
->user_wired_count
--;
2855 (entry
->user_wired_count
== 0))
2856 entry
->wired_count
--;
2858 entry
= entry
->vme_next
;
2860 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2863 vm_map_entry_wakeup(map
);
2865 * undo everything upto the previous entry.
2867 (void)vm_map_unwire(map
, start
, s
, user_wire
);
2874 * If this entry is already wired then increment
2875 * the appropriate wire reference count.
2877 if (entry
->wired_count
) {
2878 /* sanity check: wired_count is a short */
2879 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
2880 panic("vm_map_wire: too many wirings");
2883 entry
->user_wired_count
>= MAX_WIRE_COUNT
) {
2885 vm_map_unwire(map
, start
,
2886 entry
->vme_start
, user_wire
);
2887 return(KERN_FAILURE
);
2890 * entry is already wired down, get our reference
2891 * after clipping to our range.
2893 vm_map_clip_start(map
, entry
, start
);
2894 vm_map_clip_end(map
, entry
, end
);
2896 entry
->user_wired_count
++;
2897 if ((!user_wire
) || (entry
->user_wired_count
== 1))
2898 entry
->wired_count
++;
2900 entry
= entry
->vme_next
;
2905 * Unwired entry or wire request transmitted via submap
2910 * Perform actions of vm_map_lookup that need the write
2911 * lock on the map: create a shadow object for a
2912 * copy-on-write region, or an object for a zero-fill
2915 size
= entry
->vme_end
- entry
->vme_start
;
2917 * If wiring a copy-on-write page, we need to copy it now
2918 * even if we're only (currently) requesting read access.
2919 * This is aggressive, but once it's wired we can't move it.
2921 if (entry
->needs_copy
) {
2922 vm_object_shadow(&entry
->object
.vm_object
,
2923 &entry
->offset
, size
);
2924 entry
->needs_copy
= FALSE
;
2925 } else if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
2926 entry
->object
.vm_object
= vm_object_allocate(size
);
2927 entry
->offset
= (vm_object_offset_t
)0;
2930 vm_map_clip_start(map
, entry
, start
);
2931 vm_map_clip_end(map
, entry
, end
);
2933 s
= entry
->vme_start
;
2937 * Check for holes and protection mismatch.
2938 * Holes: Next entry should be contiguous unless this
2939 * is the end of the region.
2940 * Protection: Access requested must be allowed, unless
2941 * wiring is by protection class
2943 if ((((entry
->vme_end
< end
) &&
2944 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
2945 (entry
->vme_next
->vme_start
> entry
->vme_end
))) ||
2946 ((entry
->protection
& access_type
) != access_type
))) {
2948 * Found a hole or protection problem.
2949 * Unwire the region we wired so far.
2951 if (start
!= entry
->vme_start
) {
2953 vm_map_unwire(map
, start
, s
, user_wire
);
2957 return((entry
->protection
&access_type
) != access_type
?
2958 KERN_PROTECTION_FAILURE
: KERN_INVALID_ADDRESS
);
2961 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
2964 entry
->user_wired_count
++;
2965 if ((!user_wire
) || (entry
->user_wired_count
== 1))
2966 entry
->wired_count
++;
2968 entry
->in_transition
= TRUE
;
2971 * This entry might get split once we unlock the map.
2972 * In vm_fault_wire(), we need the current range as
2973 * defined by this entry. In order for this to work
2974 * along with a simultaneous clip operation, we make a
2975 * temporary copy of this entry and use that for the
2976 * wiring. Note that the underlying objects do not
2977 * change during a clip.
2982 * The in_transition state guarentees that the entry
2983 * (or entries for this range, if split occured) will be
2984 * there when the map lock is acquired for the second time.
2988 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
2989 interruptible_state
= thread_interrupt_level(THREAD_UNINT
);
2991 interruptible_state
= THREAD_UNINT
;
2994 rc
= vm_fault_wire(map
,
2995 &tmp_entry
, map_pmap
, pmap_addr
);
2997 rc
= vm_fault_wire(map
,
2998 &tmp_entry
, map
->pmap
,
2999 tmp_entry
.vme_start
);
3001 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
3002 thread_interrupt_level(interruptible_state
);
3006 if (last_timestamp
+1 != map
->timestamp
) {
3008 * Find the entry again. It could have been clipped
3009 * after we unlocked the map.
3011 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3013 panic("vm_map_wire: re-lookup failed");
3015 entry
= first_entry
;
3018 last_timestamp
= map
->timestamp
;
3020 while ((entry
!= vm_map_to_entry(map
)) &&
3021 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3022 assert(entry
->in_transition
);
3023 entry
->in_transition
= FALSE
;
3024 if (entry
->needs_wakeup
) {
3025 entry
->needs_wakeup
= FALSE
;
3028 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3030 entry
->user_wired_count
--;
3032 (entry
->user_wired_count
== 0))
3033 entry
->wired_count
--;
3035 entry
= entry
->vme_next
;
3038 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3041 vm_map_entry_wakeup(map
);
3043 * undo everything upto the previous entry.
3045 (void)vm_map_unwire(map
, start
, s
, user_wire
);
3048 } /* end while loop through map entries */
3052 * wake up anybody waiting on entries we wired.
3055 vm_map_entry_wakeup(map
);
3057 return(KERN_SUCCESS
);
3063 register vm_map_t map
,
3064 register vm_map_offset_t start
,
3065 register vm_map_offset_t end
,
3066 register vm_prot_t access_type
,
3067 boolean_t user_wire
)
3074 * the calls to mapping_prealloc and mapping_relpre
3075 * (along with the VM_MAP_RANGE_CHECK to insure a
3076 * resonable range was passed in) are
3077 * currently necessary because
3078 * we haven't enabled kernel pre-emption
3079 * and/or the pmap_enter cannot purge and re-use
3082 VM_MAP_RANGE_CHECK(map
, start
, end
);
3083 mapping_prealloc(end
- start
);
3085 kret
= vm_map_wire_nested(map
, start
, end
, access_type
,
3086 user_wire
, (pmap_t
)NULL
, 0);
3096 * Sets the pageability of the specified address range in the target
3097 * as pageable. Regions specified must have been wired previously.
3099 * The map must not be locked, but a reference must remain to the map
3100 * throughout the call.
3102 * Kernel will panic on failures. User unwire ignores holes and
3103 * unwired and intransition entries to avoid losing memory by leaving
3106 static kern_return_t
3107 vm_map_unwire_nested(
3108 register vm_map_t map
,
3109 register vm_map_offset_t start
,
3110 register vm_map_offset_t end
,
3111 boolean_t user_wire
,
3113 vm_map_offset_t pmap_addr
)
3115 register vm_map_entry_t entry
;
3116 struct vm_map_entry
*first_entry
, tmp_entry
;
3117 boolean_t need_wakeup
;
3118 boolean_t main_map
= FALSE
;
3119 unsigned int last_timestamp
;
3122 if(map_pmap
== NULL
)
3124 last_timestamp
= map
->timestamp
;
3126 VM_MAP_RANGE_CHECK(map
, start
, end
);
3127 assert(page_aligned(start
));
3128 assert(page_aligned(end
));
3130 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3131 entry
= first_entry
;
3132 /* vm_map_clip_start will be done later. */
3135 /* Start address is not in map. */
3137 return(KERN_INVALID_ADDRESS
);
3140 need_wakeup
= FALSE
;
3141 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3142 if (entry
->in_transition
) {
3145 * Another thread is wiring down this entry. Note
3146 * that if it is not for the other thread we would
3147 * be unwiring an unwired entry. This is not
3148 * permitted. If we wait, we will be unwiring memory
3152 * Another thread is unwiring this entry. We did not
3153 * have a reference to it, because if we did, this
3154 * entry will not be getting unwired now.
3157 panic("vm_map_unwire: in_transition entry");
3159 entry
= entry
->vme_next
;
3163 if(entry
->is_sub_map
) {
3164 vm_map_offset_t sub_start
;
3165 vm_map_offset_t sub_end
;
3166 vm_map_offset_t local_end
;
3170 vm_map_clip_start(map
, entry
, start
);
3171 vm_map_clip_end(map
, entry
, end
);
3173 sub_start
= entry
->offset
;
3174 sub_end
= entry
->vme_end
- entry
->vme_start
;
3175 sub_end
+= entry
->offset
;
3176 local_end
= entry
->vme_end
;
3177 if(map_pmap
== NULL
) {
3178 if(entry
->use_pmap
) {
3179 pmap
= entry
->object
.sub_map
->pmap
;
3180 pmap_addr
= sub_start
;
3185 if (entry
->wired_count
== 0 ||
3186 (user_wire
&& entry
->user_wired_count
== 0)) {
3188 panic("vm_map_unwire: entry is unwired");
3189 entry
= entry
->vme_next
;
3195 * Holes: Next entry should be contiguous unless
3196 * this is the end of the region.
3198 if (((entry
->vme_end
< end
) &&
3199 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3200 (entry
->vme_next
->vme_start
3201 > entry
->vme_end
)))) {
3203 panic("vm_map_unwire: non-contiguous region");
3205 entry = entry->vme_next;
3210 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3211 entry
->wired_count
--;
3213 if (entry
->wired_count
!= 0) {
3214 entry
= entry
->vme_next
;
3218 entry
->in_transition
= TRUE
;
3219 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
3222 * We can unlock the map now. The in_transition state
3223 * guarantees existance of the entry.
3226 vm_map_unwire_nested(entry
->object
.sub_map
,
3227 sub_start
, sub_end
, user_wire
, pmap
, pmap_addr
);
3230 if (last_timestamp
+1 != map
->timestamp
) {
3232 * Find the entry again. It could have been
3233 * clipped or deleted after we unlocked the map.
3235 if (!vm_map_lookup_entry(map
,
3236 tmp_entry
.vme_start
,
3239 panic("vm_map_unwire: re-lookup failed");
3240 entry
= first_entry
->vme_next
;
3242 entry
= first_entry
;
3244 last_timestamp
= map
->timestamp
;
3247 * clear transition bit for all constituent entries
3248 * that were in the original entry (saved in
3249 * tmp_entry). Also check for waiters.
3251 while ((entry
!= vm_map_to_entry(map
)) &&
3252 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3253 assert(entry
->in_transition
);
3254 entry
->in_transition
= FALSE
;
3255 if (entry
->needs_wakeup
) {
3256 entry
->needs_wakeup
= FALSE
;
3259 entry
= entry
->vme_next
;
3264 vm_map_unwire_nested(entry
->object
.sub_map
,
3265 sub_start
, sub_end
, user_wire
, map_pmap
,
3269 if (last_timestamp
+1 != map
->timestamp
) {
3271 * Find the entry again. It could have been
3272 * clipped or deleted after we unlocked the map.
3274 if (!vm_map_lookup_entry(map
,
3275 tmp_entry
.vme_start
,
3278 panic("vm_map_unwire: re-lookup failed");
3279 entry
= first_entry
->vme_next
;
3281 entry
= first_entry
;
3283 last_timestamp
= map
->timestamp
;
3288 if ((entry
->wired_count
== 0) ||
3289 (user_wire
&& entry
->user_wired_count
== 0)) {
3291 panic("vm_map_unwire: entry is unwired");
3293 entry
= entry
->vme_next
;
3297 assert(entry
->wired_count
> 0 &&
3298 (!user_wire
|| entry
->user_wired_count
> 0));
3300 vm_map_clip_start(map
, entry
, start
);
3301 vm_map_clip_end(map
, entry
, end
);
3305 * Holes: Next entry should be contiguous unless
3306 * this is the end of the region.
3308 if (((entry
->vme_end
< end
) &&
3309 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3310 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
3313 panic("vm_map_unwire: non-contiguous region");
3314 entry
= entry
->vme_next
;
3318 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3319 entry
->wired_count
--;
3321 if (entry
->wired_count
!= 0) {
3322 entry
= entry
->vme_next
;
3326 entry
->in_transition
= TRUE
;
3327 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
3330 * We can unlock the map now. The in_transition state
3331 * guarantees existance of the entry.
3335 vm_fault_unwire(map
,
3336 &tmp_entry
, FALSE
, map_pmap
, pmap_addr
);
3338 vm_fault_unwire(map
,
3339 &tmp_entry
, FALSE
, map
->pmap
,
3340 tmp_entry
.vme_start
);
3344 if (last_timestamp
+1 != map
->timestamp
) {
3346 * Find the entry again. It could have been clipped
3347 * or deleted after we unlocked the map.
3349 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3352 panic("vm_map_unwire: re-lookup failed");
3353 entry
= first_entry
->vme_next
;
3355 entry
= first_entry
;
3357 last_timestamp
= map
->timestamp
;
3360 * clear transition bit for all constituent entries that
3361 * were in the original entry (saved in tmp_entry). Also
3362 * check for waiters.
3364 while ((entry
!= vm_map_to_entry(map
)) &&
3365 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3366 assert(entry
->in_transition
);
3367 entry
->in_transition
= FALSE
;
3368 if (entry
->needs_wakeup
) {
3369 entry
->needs_wakeup
= FALSE
;
3372 entry
= entry
->vme_next
;
3377 * We might have fragmented the address space when we wired this
3378 * range of addresses. Attempt to re-coalesce these VM map entries
3379 * with their neighbors now that they're no longer wired.
3380 * Under some circumstances, address space fragmentation can
3381 * prevent VM object shadow chain collapsing, which can cause
3384 vm_map_simplify_range(map
, start
, end
);
3388 * wake up anybody waiting on entries that we have unwired.
3391 vm_map_entry_wakeup(map
);
3392 return(KERN_SUCCESS
);
3398 register vm_map_t map
,
3399 register vm_map_offset_t start
,
3400 register vm_map_offset_t end
,
3401 boolean_t user_wire
)
3403 return vm_map_unwire_nested(map
, start
, end
,
3404 user_wire
, (pmap_t
)NULL
, 0);
3409 * vm_map_entry_delete: [ internal use only ]
3411 * Deallocate the given entry from the target map.
3414 vm_map_entry_delete(
3415 register vm_map_t map
,
3416 register vm_map_entry_t entry
)
3418 register vm_map_offset_t s
, e
;
3419 register vm_object_t object
;
3420 register vm_map_t submap
;
3422 s
= entry
->vme_start
;
3424 assert(page_aligned(s
));
3425 assert(page_aligned(e
));
3426 assert(entry
->wired_count
== 0);
3427 assert(entry
->user_wired_count
== 0);
3429 if (entry
->is_sub_map
) {
3431 submap
= entry
->object
.sub_map
;
3434 object
= entry
->object
.vm_object
;
3437 vm_map_entry_unlink(map
, entry
);
3440 vm_map_entry_dispose(map
, entry
);
3444 * Deallocate the object only after removing all
3445 * pmap entries pointing to its pages.
3448 vm_map_deallocate(submap
);
3450 vm_object_deallocate(object
);
3455 vm_map_submap_pmap_clean(
3457 vm_map_offset_t start
,
3458 vm_map_offset_t end
,
3460 vm_map_offset_t offset
)
3462 vm_map_offset_t submap_start
;
3463 vm_map_offset_t submap_end
;
3464 vm_map_size_t remove_size
;
3465 vm_map_entry_t entry
;
3467 submap_end
= offset
+ (end
- start
);
3468 submap_start
= offset
;
3469 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
3471 remove_size
= (entry
->vme_end
- entry
->vme_start
);
3472 if(offset
> entry
->vme_start
)
3473 remove_size
-= offset
- entry
->vme_start
;
3476 if(submap_end
< entry
->vme_end
) {
3478 entry
->vme_end
- submap_end
;
3480 if(entry
->is_sub_map
) {
3481 vm_map_submap_pmap_clean(
3484 start
+ remove_size
,
3485 entry
->object
.sub_map
,
3489 if((map
->mapped
) && (map
->ref_count
)
3490 && (entry
->object
.vm_object
!= NULL
)) {
3491 vm_object_pmap_protect(
3492 entry
->object
.vm_object
,
3499 pmap_remove(map
->pmap
,
3501 (addr64_t
)(start
+ remove_size
));
3506 entry
= entry
->vme_next
;
3508 while((entry
!= vm_map_to_entry(sub_map
))
3509 && (entry
->vme_start
< submap_end
)) {
3510 remove_size
= (entry
->vme_end
- entry
->vme_start
);
3511 if(submap_end
< entry
->vme_end
) {
3512 remove_size
-= entry
->vme_end
- submap_end
;
3514 if(entry
->is_sub_map
) {
3515 vm_map_submap_pmap_clean(
3517 (start
+ entry
->vme_start
) - offset
,
3518 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
3519 entry
->object
.sub_map
,
3522 if((map
->mapped
) && (map
->ref_count
)
3523 && (entry
->object
.vm_object
!= NULL
)) {
3524 vm_object_pmap_protect(
3525 entry
->object
.vm_object
,
3532 pmap_remove(map
->pmap
,
3533 (addr64_t
)((start
+ entry
->vme_start
)
3535 (addr64_t
)(((start
+ entry
->vme_start
)
3536 - offset
) + remove_size
));
3539 entry
= entry
->vme_next
;
3545 * vm_map_delete: [ internal use only ]
3547 * Deallocates the given address range from the target map.
3548 * Removes all user wirings. Unwires one kernel wiring if
3549 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
3550 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
3551 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
3553 * This routine is called with map locked and leaves map locked.
3555 static kern_return_t
3558 vm_map_offset_t start
,
3559 vm_map_offset_t end
,
3563 vm_map_entry_t entry
, next
;
3564 struct vm_map_entry
*first_entry
, tmp_entry
;
3565 register vm_map_offset_t s
, e
;
3566 register vm_object_t object
;
3567 boolean_t need_wakeup
;
3568 unsigned int last_timestamp
= ~0; /* unlikely value */
3571 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
3572 THREAD_ABORTSAFE
: THREAD_UNINT
;
3575 * All our DMA I/O operations in IOKit are currently done by
3576 * wiring through the map entries of the task requesting the I/O.
3577 * Because of this, we must always wait for kernel wirings
3578 * to go away on the entries before deleting them.
3580 * Any caller who wants to actually remove a kernel wiring
3581 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
3582 * properly remove one wiring instead of blasting through
3585 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
3588 * Find the start of the region, and clip it
3590 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3591 entry
= first_entry
;
3592 vm_map_clip_start(map
, entry
, start
);
3595 * Fix the lookup hint now, rather than each
3596 * time through the loop.
3598 SAVE_HINT(map
, entry
->vme_prev
);
3600 entry
= first_entry
->vme_next
;
3603 need_wakeup
= FALSE
;
3605 * Step through all entries in this region
3607 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3609 vm_map_clip_end(map
, entry
, end
);
3610 if (entry
->in_transition
) {
3611 wait_result_t wait_result
;
3614 * Another thread is wiring/unwiring this entry.
3615 * Let the other thread know we are waiting.
3617 s
= entry
->vme_start
;
3618 entry
->needs_wakeup
= TRUE
;
3621 * wake up anybody waiting on entries that we have
3622 * already unwired/deleted.
3625 vm_map_entry_wakeup(map
);
3626 need_wakeup
= FALSE
;
3629 wait_result
= vm_map_entry_wait(map
, interruptible
);
3631 if (interruptible
&&
3632 wait_result
== THREAD_INTERRUPTED
) {
3634 * We do not clear the needs_wakeup flag,
3635 * since we cannot tell if we were the only one.
3638 return KERN_ABORTED
;
3642 * The entry could have been clipped or it
3643 * may not exist anymore. Look it up again.
3645 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
3646 assert((map
!= kernel_map
) &&
3647 (!entry
->is_sub_map
));
3649 * User: use the next entry
3651 entry
= first_entry
->vme_next
;
3653 entry
= first_entry
;
3654 SAVE_HINT(map
, entry
->vme_prev
);
3656 last_timestamp
= map
->timestamp
;
3658 } /* end in_transition */
3660 if (entry
->wired_count
) {
3662 * Remove a kernel wiring if requested or if
3663 * there are user wirings.
3665 if ((flags
& VM_MAP_REMOVE_KUNWIRE
) ||
3666 (entry
->user_wired_count
> 0))
3667 entry
->wired_count
--;
3669 /* remove all user wire references */
3670 entry
->user_wired_count
= 0;
3672 if (entry
->wired_count
!= 0) {
3673 assert((map
!= kernel_map
) &&
3674 (!entry
->is_sub_map
));
3676 * Cannot continue. Typical case is when
3677 * a user thread has physical io pending on
3678 * on this page. Either wait for the
3679 * kernel wiring to go away or return an
3682 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
3683 wait_result_t wait_result
;
3685 s
= entry
->vme_start
;
3686 entry
->needs_wakeup
= TRUE
;
3687 wait_result
= vm_map_entry_wait(map
,
3690 if (interruptible
&&
3691 wait_result
== THREAD_INTERRUPTED
) {
3693 * We do not clear the
3694 * needs_wakeup flag, since we
3695 * cannot tell if we were the
3699 return KERN_ABORTED
;
3703 * The entry could have been clipped or
3704 * it may not exist anymore. Look it
3707 if (!vm_map_lookup_entry(map
, s
,
3709 assert((map
!= kernel_map
) &&
3710 (!entry
->is_sub_map
));
3712 * User: use the next entry
3714 entry
= first_entry
->vme_next
;
3716 entry
= first_entry
;
3717 SAVE_HINT(map
, entry
->vme_prev
);
3719 last_timestamp
= map
->timestamp
;
3723 return KERN_FAILURE
;
3727 entry
->in_transition
= TRUE
;
3729 * copy current entry. see comment in vm_map_wire()
3732 s
= entry
->vme_start
;
3736 * We can unlock the map now. The in_transition
3737 * state guarentees existance of the entry.
3740 vm_fault_unwire(map
, &tmp_entry
,
3741 tmp_entry
.object
.vm_object
== kernel_object
,
3742 map
->pmap
, tmp_entry
.vme_start
);
3745 if (last_timestamp
+1 != map
->timestamp
) {
3747 * Find the entry again. It could have
3748 * been clipped after we unlocked the map.
3750 if (!vm_map_lookup_entry(map
, s
, &first_entry
)){
3751 assert((map
!= kernel_map
) &&
3752 (!entry
->is_sub_map
));
3753 first_entry
= first_entry
->vme_next
;
3755 SAVE_HINT(map
, entry
->vme_prev
);
3758 SAVE_HINT(map
, entry
->vme_prev
);
3759 first_entry
= entry
;
3762 last_timestamp
= map
->timestamp
;
3764 entry
= first_entry
;
3765 while ((entry
!= vm_map_to_entry(map
)) &&
3766 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3767 assert(entry
->in_transition
);
3768 entry
->in_transition
= FALSE
;
3769 if (entry
->needs_wakeup
) {
3770 entry
->needs_wakeup
= FALSE
;
3773 entry
= entry
->vme_next
;
3776 * We have unwired the entry(s). Go back and
3779 entry
= first_entry
;
3783 /* entry is unwired */
3784 assert(entry
->wired_count
== 0);
3785 assert(entry
->user_wired_count
== 0);
3787 if ((!entry
->is_sub_map
&&
3788 entry
->object
.vm_object
!= kernel_object
) ||
3789 entry
->is_sub_map
) {
3790 if(entry
->is_sub_map
) {
3791 if(entry
->use_pmap
) {
3793 pmap_unnest(map
->pmap
, (addr64_t
)entry
->vme_start
);
3795 if((map
->mapped
) && (map
->ref_count
)) {
3796 /* clean up parent map/maps */
3797 vm_map_submap_pmap_clean(
3798 map
, entry
->vme_start
,
3800 entry
->object
.sub_map
,
3804 vm_map_submap_pmap_clean(
3805 map
, entry
->vme_start
, entry
->vme_end
,
3806 entry
->object
.sub_map
,
3810 object
= entry
->object
.vm_object
;
3811 if((map
->mapped
) && (map
->ref_count
)) {
3812 vm_object_pmap_protect(
3813 object
, entry
->offset
,
3814 entry
->vme_end
- entry
->vme_start
,
3819 pmap_remove(map
->pmap
,
3827 * All pmap mappings for this map entry must have been
3830 assert(vm_map_pmap_is_empty(map
,
3834 next
= entry
->vme_next
;
3835 s
= next
->vme_start
;
3836 last_timestamp
= map
->timestamp
;
3838 if ((flags
& VM_MAP_REMOVE_SAVE_ENTRIES
) &&
3839 zap_map
!= VM_MAP_NULL
) {
3841 * The caller wants to save the affected VM map entries
3842 * into the "zap_map". The caller will take care of
3845 /* unlink the entry from "map" ... */
3846 vm_map_entry_unlink(map
, entry
);
3847 /* ... and add it to the end of the "zap_map" */
3848 vm_map_entry_link(zap_map
,
3849 vm_map_last_entry(zap_map
),
3852 vm_map_entry_delete(map
, entry
);
3853 /* vm_map_entry_delete unlocks the map */
3859 if(entry
== vm_map_to_entry(map
)) {
3862 if (last_timestamp
+1 != map
->timestamp
) {
3864 * we are responsible for deleting everything
3865 * from the give space, if someone has interfered
3866 * we pick up where we left off, back fills should
3867 * be all right for anyone except map_delete and
3868 * we have to assume that the task has been fully
3869 * disabled before we get here
3871 if (!vm_map_lookup_entry(map
, s
, &entry
)){
3872 entry
= entry
->vme_next
;
3874 SAVE_HINT(map
, entry
->vme_prev
);
3877 * others can not only allocate behind us, we can
3878 * also see coalesce while we don't have the map lock
3880 if(entry
== vm_map_to_entry(map
)) {
3883 vm_map_clip_start(map
, entry
, s
);
3885 last_timestamp
= map
->timestamp
;
3888 if (map
->wait_for_space
)
3889 thread_wakeup((event_t
) map
);
3891 * wake up anybody waiting on entries that we have already deleted.
3894 vm_map_entry_wakeup(map
);
3896 return KERN_SUCCESS
;
3902 * Remove the given address range from the target map.
3903 * This is the exported form of vm_map_delete.
3907 register vm_map_t map
,
3908 register vm_map_offset_t start
,
3909 register vm_map_offset_t end
,
3910 register boolean_t flags
)
3912 register kern_return_t result
;
3915 VM_MAP_RANGE_CHECK(map
, start
, end
);
3916 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
3924 * Routine: vm_map_copy_discard
3927 * Dispose of a map copy object (returned by
3931 vm_map_copy_discard(
3934 TR_DECL("vm_map_copy_discard");
3936 /* tr3("enter: copy 0x%x type %d", copy, copy->type);*/
3938 if (copy
== VM_MAP_COPY_NULL
)
3941 switch (copy
->type
) {
3942 case VM_MAP_COPY_ENTRY_LIST
:
3943 while (vm_map_copy_first_entry(copy
) !=
3944 vm_map_copy_to_entry(copy
)) {
3945 vm_map_entry_t entry
= vm_map_copy_first_entry(copy
);
3947 vm_map_copy_entry_unlink(copy
, entry
);
3948 vm_object_deallocate(entry
->object
.vm_object
);
3949 vm_map_copy_entry_dispose(copy
, entry
);
3952 case VM_MAP_COPY_OBJECT
:
3953 vm_object_deallocate(copy
->cpy_object
);
3955 case VM_MAP_COPY_KERNEL_BUFFER
:
3958 * The vm_map_copy_t and possibly the data buffer were
3959 * allocated by a single call to kalloc(), i.e. the
3960 * vm_map_copy_t was not allocated out of the zone.
3962 kfree(copy
, copy
->cpy_kalloc_size
);
3965 zfree(vm_map_copy_zone
, copy
);
3969 * Routine: vm_map_copy_copy
3972 * Move the information in a map copy object to
3973 * a new map copy object, leaving the old one
3976 * This is used by kernel routines that need
3977 * to look at out-of-line data (in copyin form)
3978 * before deciding whether to return SUCCESS.
3979 * If the routine returns FAILURE, the original
3980 * copy object will be deallocated; therefore,
3981 * these routines must make a copy of the copy
3982 * object and leave the original empty so that
3983 * deallocation will not fail.
3989 vm_map_copy_t new_copy
;
3991 if (copy
== VM_MAP_COPY_NULL
)
3992 return VM_MAP_COPY_NULL
;
3995 * Allocate a new copy object, and copy the information
3996 * from the old one into it.
3999 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
4002 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
4004 * The links in the entry chain must be
4005 * changed to point to the new copy object.
4007 vm_map_copy_first_entry(copy
)->vme_prev
4008 = vm_map_copy_to_entry(new_copy
);
4009 vm_map_copy_last_entry(copy
)->vme_next
4010 = vm_map_copy_to_entry(new_copy
);
4014 * Change the old copy object into one that contains
4015 * nothing to be deallocated.
4017 copy
->type
= VM_MAP_COPY_OBJECT
;
4018 copy
->cpy_object
= VM_OBJECT_NULL
;
4021 * Return the new object.
4026 static kern_return_t
4027 vm_map_overwrite_submap_recurse(
4029 vm_map_offset_t dst_addr
,
4030 vm_map_size_t dst_size
)
4032 vm_map_offset_t dst_end
;
4033 vm_map_entry_t tmp_entry
;
4034 vm_map_entry_t entry
;
4035 kern_return_t result
;
4036 boolean_t encountered_sub_map
= FALSE
;
4041 * Verify that the destination is all writeable
4042 * initially. We have to trunc the destination
4043 * address and round the copy size or we'll end up
4044 * splitting entries in strange ways.
4047 dst_end
= vm_map_round_page(dst_addr
+ dst_size
);
4048 vm_map_lock(dst_map
);
4051 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4052 vm_map_unlock(dst_map
);
4053 return(KERN_INVALID_ADDRESS
);
4056 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(dst_addr
));
4058 for (entry
= tmp_entry
;;) {
4059 vm_map_entry_t next
;
4061 next
= entry
->vme_next
;
4062 while(entry
->is_sub_map
) {
4063 vm_map_offset_t sub_start
;
4064 vm_map_offset_t sub_end
;
4065 vm_map_offset_t local_end
;
4067 if (entry
->in_transition
) {
4069 * Say that we are waiting, and wait for entry.
4071 entry
->needs_wakeup
= TRUE
;
4072 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4077 encountered_sub_map
= TRUE
;
4078 sub_start
= entry
->offset
;
4080 if(entry
->vme_end
< dst_end
)
4081 sub_end
= entry
->vme_end
;
4084 sub_end
-= entry
->vme_start
;
4085 sub_end
+= entry
->offset
;
4086 local_end
= entry
->vme_end
;
4087 vm_map_unlock(dst_map
);
4089 result
= vm_map_overwrite_submap_recurse(
4090 entry
->object
.sub_map
,
4092 sub_end
- sub_start
);
4094 if(result
!= KERN_SUCCESS
)
4096 if (dst_end
<= entry
->vme_end
)
4097 return KERN_SUCCESS
;
4098 vm_map_lock(dst_map
);
4099 if(!vm_map_lookup_entry(dst_map
, local_end
,
4101 vm_map_unlock(dst_map
);
4102 return(KERN_INVALID_ADDRESS
);
4105 next
= entry
->vme_next
;
4108 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4109 vm_map_unlock(dst_map
);
4110 return(KERN_PROTECTION_FAILURE
);
4114 * If the entry is in transition, we must wait
4115 * for it to exit that state. Anything could happen
4116 * when we unlock the map, so start over.
4118 if (entry
->in_transition
) {
4121 * Say that we are waiting, and wait for entry.
4123 entry
->needs_wakeup
= TRUE
;
4124 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4130 * our range is contained completely within this map entry
4132 if (dst_end
<= entry
->vme_end
) {
4133 vm_map_unlock(dst_map
);
4134 return KERN_SUCCESS
;
4137 * check that range specified is contiguous region
4139 if ((next
== vm_map_to_entry(dst_map
)) ||
4140 (next
->vme_start
!= entry
->vme_end
)) {
4141 vm_map_unlock(dst_map
);
4142 return(KERN_INVALID_ADDRESS
);
4146 * Check for permanent objects in the destination.
4148 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
4149 ((!entry
->object
.vm_object
->internal
) ||
4150 (entry
->object
.vm_object
->true_share
))) {
4151 if(encountered_sub_map
) {
4152 vm_map_unlock(dst_map
);
4153 return(KERN_FAILURE
);
4160 vm_map_unlock(dst_map
);
4161 return(KERN_SUCCESS
);
4165 * Routine: vm_map_copy_overwrite
4168 * Copy the memory described by the map copy
4169 * object (copy; returned by vm_map_copyin) onto
4170 * the specified destination region (dst_map, dst_addr).
4171 * The destination must be writeable.
4173 * Unlike vm_map_copyout, this routine actually
4174 * writes over previously-mapped memory. If the
4175 * previous mapping was to a permanent (user-supplied)
4176 * memory object, it is preserved.
4178 * The attributes (protection and inheritance) of the
4179 * destination region are preserved.
4181 * If successful, consumes the copy object.
4182 * Otherwise, the caller is responsible for it.
4184 * Implementation notes:
4185 * To overwrite aligned temporary virtual memory, it is
4186 * sufficient to remove the previous mapping and insert
4187 * the new copy. This replacement is done either on
4188 * the whole region (if no permanent virtual memory
4189 * objects are embedded in the destination region) or
4190 * in individual map entries.
4192 * To overwrite permanent virtual memory , it is necessary
4193 * to copy each page, as the external memory management
4194 * interface currently does not provide any optimizations.
4196 * Unaligned memory also has to be copied. It is possible
4197 * to use 'vm_trickery' to copy the aligned data. This is
4198 * not done but not hard to implement.
4200 * Once a page of permanent memory has been overwritten,
4201 * it is impossible to interrupt this function; otherwise,
4202 * the call would be neither atomic nor location-independent.
4203 * The kernel-state portion of a user thread must be
4206 * It may be expensive to forward all requests that might
4207 * overwrite permanent memory (vm_write, vm_copy) to
4208 * uninterruptible kernel threads. This routine may be
4209 * called by interruptible threads; however, success is
4210 * not guaranteed -- if the request cannot be performed
4211 * atomically and interruptibly, an error indication is
4215 static kern_return_t
4216 vm_map_copy_overwrite_nested(
4218 vm_map_address_t dst_addr
,
4220 boolean_t interruptible
,
4223 vm_map_offset_t dst_end
;
4224 vm_map_entry_t tmp_entry
;
4225 vm_map_entry_t entry
;
4227 boolean_t aligned
= TRUE
;
4228 boolean_t contains_permanent_objects
= FALSE
;
4229 boolean_t encountered_sub_map
= FALSE
;
4230 vm_map_offset_t base_addr
;
4231 vm_map_size_t copy_size
;
4232 vm_map_size_t total_size
;
4236 * Check for null copy object.
4239 if (copy
== VM_MAP_COPY_NULL
)
4240 return(KERN_SUCCESS
);
4243 * Check for special kernel buffer allocated
4244 * by new_ipc_kmsg_copyin.
4247 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
4248 return(vm_map_copyout_kernel_buffer(
4254 * Only works for entry lists at the moment. Will
4255 * support page lists later.
4258 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
4260 if (copy
->size
== 0) {
4261 vm_map_copy_discard(copy
);
4262 return(KERN_SUCCESS
);
4266 * Verify that the destination is all writeable
4267 * initially. We have to trunc the destination
4268 * address and round the copy size or we'll end up
4269 * splitting entries in strange ways.
4272 if (!page_aligned(copy
->size
) ||
4273 !page_aligned (copy
->offset
) ||
4274 !page_aligned (dst_addr
))
4277 dst_end
= vm_map_round_page(dst_addr
+ copy
->size
);
4279 dst_end
= dst_addr
+ copy
->size
;
4282 vm_map_lock(dst_map
);
4284 /* LP64todo - remove this check when vm_map_commpage64()
4285 * no longer has to stuff in a map_entry for the commpage
4286 * above the map's max_offset.
4288 if (dst_addr
>= dst_map
->max_offset
) {
4289 vm_map_unlock(dst_map
);
4290 return(KERN_INVALID_ADDRESS
);
4294 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4295 vm_map_unlock(dst_map
);
4296 return(KERN_INVALID_ADDRESS
);
4298 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(dst_addr
));
4299 for (entry
= tmp_entry
;;) {
4300 vm_map_entry_t next
= entry
->vme_next
;
4302 while(entry
->is_sub_map
) {
4303 vm_map_offset_t sub_start
;
4304 vm_map_offset_t sub_end
;
4305 vm_map_offset_t local_end
;
4307 if (entry
->in_transition
) {
4310 * Say that we are waiting, and wait for entry.
4312 entry
->needs_wakeup
= TRUE
;
4313 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4318 local_end
= entry
->vme_end
;
4319 if (!(entry
->needs_copy
)) {
4320 /* if needs_copy we are a COW submap */
4321 /* in such a case we just replace so */
4322 /* there is no need for the follow- */
4324 encountered_sub_map
= TRUE
;
4325 sub_start
= entry
->offset
;
4327 if(entry
->vme_end
< dst_end
)
4328 sub_end
= entry
->vme_end
;
4331 sub_end
-= entry
->vme_start
;
4332 sub_end
+= entry
->offset
;
4333 vm_map_unlock(dst_map
);
4335 kr
= vm_map_overwrite_submap_recurse(
4336 entry
->object
.sub_map
,
4338 sub_end
- sub_start
);
4339 if(kr
!= KERN_SUCCESS
)
4341 vm_map_lock(dst_map
);
4344 if (dst_end
<= entry
->vme_end
)
4345 goto start_overwrite
;
4346 if(!vm_map_lookup_entry(dst_map
, local_end
,
4348 vm_map_unlock(dst_map
);
4349 return(KERN_INVALID_ADDRESS
);
4351 next
= entry
->vme_next
;
4354 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4355 vm_map_unlock(dst_map
);
4356 return(KERN_PROTECTION_FAILURE
);
4360 * If the entry is in transition, we must wait
4361 * for it to exit that state. Anything could happen
4362 * when we unlock the map, so start over.
4364 if (entry
->in_transition
) {
4367 * Say that we are waiting, and wait for entry.
4369 entry
->needs_wakeup
= TRUE
;
4370 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4376 * our range is contained completely within this map entry
4378 if (dst_end
<= entry
->vme_end
)
4381 * check that range specified is contiguous region
4383 if ((next
== vm_map_to_entry(dst_map
)) ||
4384 (next
->vme_start
!= entry
->vme_end
)) {
4385 vm_map_unlock(dst_map
);
4386 return(KERN_INVALID_ADDRESS
);
4391 * Check for permanent objects in the destination.
4393 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
4394 ((!entry
->object
.vm_object
->internal
) ||
4395 (entry
->object
.vm_object
->true_share
))) {
4396 contains_permanent_objects
= TRUE
;
4404 * If there are permanent objects in the destination, then
4405 * the copy cannot be interrupted.
4408 if (interruptible
&& contains_permanent_objects
) {
4409 vm_map_unlock(dst_map
);
4410 return(KERN_FAILURE
); /* XXX */
4415 * Make a second pass, overwriting the data
4416 * At the beginning of each loop iteration,
4417 * the next entry to be overwritten is "tmp_entry"
4418 * (initially, the value returned from the lookup above),
4419 * and the starting address expected in that entry
4423 total_size
= copy
->size
;
4424 if(encountered_sub_map
) {
4426 /* re-calculate tmp_entry since we've had the map */
4428 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
4429 vm_map_unlock(dst_map
);
4430 return(KERN_INVALID_ADDRESS
);
4433 copy_size
= copy
->size
;
4436 base_addr
= dst_addr
;
4438 /* deconstruct the copy object and do in parts */
4439 /* only in sub_map, interruptable case */
4440 vm_map_entry_t copy_entry
;
4441 vm_map_entry_t previous_prev
= VM_MAP_ENTRY_NULL
;
4442 vm_map_entry_t next_copy
= VM_MAP_ENTRY_NULL
;
4444 int remaining_entries
= 0;
4447 for (entry
= tmp_entry
; copy_size
== 0;) {
4448 vm_map_entry_t next
;
4450 next
= entry
->vme_next
;
4452 /* tmp_entry and base address are moved along */
4453 /* each time we encounter a sub-map. Otherwise */
4454 /* entry can outpase tmp_entry, and the copy_size */
4455 /* may reflect the distance between them */
4456 /* if the current entry is found to be in transition */
4457 /* we will start over at the beginning or the last */
4458 /* encounter of a submap as dictated by base_addr */
4459 /* we will zero copy_size accordingly. */
4460 if (entry
->in_transition
) {
4462 * Say that we are waiting, and wait for entry.
4464 entry
->needs_wakeup
= TRUE
;
4465 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4467 if(!vm_map_lookup_entry(dst_map
, base_addr
,
4469 vm_map_unlock(dst_map
);
4470 return(KERN_INVALID_ADDRESS
);
4476 if(entry
->is_sub_map
) {
4477 vm_map_offset_t sub_start
;
4478 vm_map_offset_t sub_end
;
4479 vm_map_offset_t local_end
;
4481 if (entry
->needs_copy
) {
4482 /* if this is a COW submap */
4483 /* just back the range with a */
4484 /* anonymous entry */
4485 if(entry
->vme_end
< dst_end
)
4486 sub_end
= entry
->vme_end
;
4489 if(entry
->vme_start
< base_addr
)
4490 sub_start
= base_addr
;
4492 sub_start
= entry
->vme_start
;
4494 dst_map
, entry
, sub_end
);
4496 dst_map
, entry
, sub_start
);
4497 entry
->is_sub_map
= FALSE
;
4499 entry
->object
.sub_map
);
4500 entry
->object
.sub_map
= NULL
;
4501 entry
->is_shared
= FALSE
;
4502 entry
->needs_copy
= FALSE
;
4504 entry
->protection
= VM_PROT_ALL
;
4505 entry
->max_protection
= VM_PROT_ALL
;
4506 entry
->wired_count
= 0;
4507 entry
->user_wired_count
= 0;
4508 if(entry
->inheritance
4509 == VM_INHERIT_SHARE
)
4510 entry
->inheritance
= VM_INHERIT_COPY
;
4513 /* first take care of any non-sub_map */
4514 /* entries to send */
4515 if(base_addr
< entry
->vme_start
) {
4518 entry
->vme_start
- base_addr
;
4521 sub_start
= entry
->offset
;
4523 if(entry
->vme_end
< dst_end
)
4524 sub_end
= entry
->vme_end
;
4527 sub_end
-= entry
->vme_start
;
4528 sub_end
+= entry
->offset
;
4529 local_end
= entry
->vme_end
;
4530 vm_map_unlock(dst_map
);
4531 copy_size
= sub_end
- sub_start
;
4533 /* adjust the copy object */
4534 if (total_size
> copy_size
) {
4535 vm_map_size_t local_size
= 0;
4536 vm_map_size_t entry_size
;
4539 new_offset
= copy
->offset
;
4540 copy_entry
= vm_map_copy_first_entry(copy
);
4542 vm_map_copy_to_entry(copy
)){
4543 entry_size
= copy_entry
->vme_end
-
4544 copy_entry
->vme_start
;
4545 if((local_size
< copy_size
) &&
4546 ((local_size
+ entry_size
)
4548 vm_map_copy_clip_end(copy
,
4550 copy_entry
->vme_start
+
4551 (copy_size
- local_size
));
4552 entry_size
= copy_entry
->vme_end
-
4553 copy_entry
->vme_start
;
4554 local_size
+= entry_size
;
4555 new_offset
+= entry_size
;
4557 if(local_size
>= copy_size
) {
4558 next_copy
= copy_entry
->vme_next
;
4559 copy_entry
->vme_next
=
4560 vm_map_copy_to_entry(copy
);
4562 copy
->cpy_hdr
.links
.prev
;
4563 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4564 copy
->size
= copy_size
;
4566 copy
->cpy_hdr
.nentries
;
4567 remaining_entries
-= nentries
;
4568 copy
->cpy_hdr
.nentries
= nentries
;
4571 local_size
+= entry_size
;
4572 new_offset
+= entry_size
;
4575 copy_entry
= copy_entry
->vme_next
;
4579 if((entry
->use_pmap
) && (pmap
== NULL
)) {
4580 kr
= vm_map_copy_overwrite_nested(
4581 entry
->object
.sub_map
,
4585 entry
->object
.sub_map
->pmap
);
4586 } else if (pmap
!= NULL
) {
4587 kr
= vm_map_copy_overwrite_nested(
4588 entry
->object
.sub_map
,
4591 interruptible
, pmap
);
4593 kr
= vm_map_copy_overwrite_nested(
4594 entry
->object
.sub_map
,
4600 if(kr
!= KERN_SUCCESS
) {
4601 if(next_copy
!= NULL
) {
4602 copy
->cpy_hdr
.nentries
+=
4604 copy
->cpy_hdr
.links
.prev
->vme_next
=
4606 copy
->cpy_hdr
.links
.prev
4608 copy
->size
= total_size
;
4612 if (dst_end
<= local_end
) {
4613 return(KERN_SUCCESS
);
4615 /* otherwise copy no longer exists, it was */
4616 /* destroyed after successful copy_overwrite */
4617 copy
= (vm_map_copy_t
)
4618 zalloc(vm_map_copy_zone
);
4619 vm_map_copy_first_entry(copy
) =
4620 vm_map_copy_last_entry(copy
) =
4621 vm_map_copy_to_entry(copy
);
4622 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
4623 copy
->offset
= new_offset
;
4625 total_size
-= copy_size
;
4627 /* put back remainder of copy in container */
4628 if(next_copy
!= NULL
) {
4629 copy
->cpy_hdr
.nentries
= remaining_entries
;
4630 copy
->cpy_hdr
.links
.next
= next_copy
;
4631 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4632 copy
->size
= total_size
;
4633 next_copy
->vme_prev
=
4634 vm_map_copy_to_entry(copy
);
4637 base_addr
= local_end
;
4638 vm_map_lock(dst_map
);
4639 if(!vm_map_lookup_entry(dst_map
,
4640 local_end
, &tmp_entry
)) {
4641 vm_map_unlock(dst_map
);
4642 return(KERN_INVALID_ADDRESS
);
4647 if (dst_end
<= entry
->vme_end
) {
4648 copy_size
= dst_end
- base_addr
;
4652 if ((next
== vm_map_to_entry(dst_map
)) ||
4653 (next
->vme_start
!= entry
->vme_end
)) {
4654 vm_map_unlock(dst_map
);
4655 return(KERN_INVALID_ADDRESS
);
4664 /* adjust the copy object */
4665 if (total_size
> copy_size
) {
4666 vm_map_size_t local_size
= 0;
4667 vm_map_size_t entry_size
;
4669 new_offset
= copy
->offset
;
4670 copy_entry
= vm_map_copy_first_entry(copy
);
4671 while(copy_entry
!= vm_map_copy_to_entry(copy
)) {
4672 entry_size
= copy_entry
->vme_end
-
4673 copy_entry
->vme_start
;
4674 if((local_size
< copy_size
) &&
4675 ((local_size
+ entry_size
)
4677 vm_map_copy_clip_end(copy
, copy_entry
,
4678 copy_entry
->vme_start
+
4679 (copy_size
- local_size
));
4680 entry_size
= copy_entry
->vme_end
-
4681 copy_entry
->vme_start
;
4682 local_size
+= entry_size
;
4683 new_offset
+= entry_size
;
4685 if(local_size
>= copy_size
) {
4686 next_copy
= copy_entry
->vme_next
;
4687 copy_entry
->vme_next
=
4688 vm_map_copy_to_entry(copy
);
4690 copy
->cpy_hdr
.links
.prev
;
4691 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4692 copy
->size
= copy_size
;
4694 copy
->cpy_hdr
.nentries
;
4695 remaining_entries
-= nentries
;
4696 copy
->cpy_hdr
.nentries
= nentries
;
4699 local_size
+= entry_size
;
4700 new_offset
+= entry_size
;
4703 copy_entry
= copy_entry
->vme_next
;
4713 local_pmap
= dst_map
->pmap
;
4715 if ((kr
= vm_map_copy_overwrite_aligned(
4716 dst_map
, tmp_entry
, copy
,
4717 base_addr
, local_pmap
)) != KERN_SUCCESS
) {
4718 if(next_copy
!= NULL
) {
4719 copy
->cpy_hdr
.nentries
+=
4721 copy
->cpy_hdr
.links
.prev
->vme_next
=
4723 copy
->cpy_hdr
.links
.prev
=
4725 copy
->size
+= copy_size
;
4729 vm_map_unlock(dst_map
);
4734 * if the copy and dst address are misaligned but the same
4735 * offset within the page we can copy_not_aligned the
4736 * misaligned parts and copy aligned the rest. If they are
4737 * aligned but len is unaligned we simply need to copy
4738 * the end bit unaligned. We'll need to split the misaligned
4739 * bits of the region in this case !
4741 /* ALWAYS UNLOCKS THE dst_map MAP */
4742 if ((kr
= vm_map_copy_overwrite_unaligned( dst_map
,
4743 tmp_entry
, copy
, base_addr
)) != KERN_SUCCESS
) {
4744 if(next_copy
!= NULL
) {
4745 copy
->cpy_hdr
.nentries
+=
4747 copy
->cpy_hdr
.links
.prev
->vme_next
=
4749 copy
->cpy_hdr
.links
.prev
=
4751 copy
->size
+= copy_size
;
4756 total_size
-= copy_size
;
4759 base_addr
+= copy_size
;
4761 copy
->offset
= new_offset
;
4762 if(next_copy
!= NULL
) {
4763 copy
->cpy_hdr
.nentries
= remaining_entries
;
4764 copy
->cpy_hdr
.links
.next
= next_copy
;
4765 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4766 next_copy
->vme_prev
= vm_map_copy_to_entry(copy
);
4767 copy
->size
= total_size
;
4769 vm_map_lock(dst_map
);
4771 if (!vm_map_lookup_entry(dst_map
,
4772 base_addr
, &tmp_entry
)) {
4773 vm_map_unlock(dst_map
);
4774 return(KERN_INVALID_ADDRESS
);
4776 if (tmp_entry
->in_transition
) {
4777 entry
->needs_wakeup
= TRUE
;
4778 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4783 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(base_addr
));
4789 * Throw away the vm_map_copy object
4791 vm_map_copy_discard(copy
);
4793 return(KERN_SUCCESS
);
4794 }/* vm_map_copy_overwrite */
4797 vm_map_copy_overwrite(
4799 vm_map_offset_t dst_addr
,
4801 boolean_t interruptible
)
4803 return vm_map_copy_overwrite_nested(
4804 dst_map
, dst_addr
, copy
, interruptible
, (pmap_t
) NULL
);
4809 * Routine: vm_map_copy_overwrite_unaligned [internal use only]
4812 * Physically copy unaligned data
4815 * Unaligned parts of pages have to be physically copied. We use
4816 * a modified form of vm_fault_copy (which understands none-aligned
4817 * page offsets and sizes) to do the copy. We attempt to copy as
4818 * much memory in one go as possibly, however vm_fault_copy copies
4819 * within 1 memory object so we have to find the smaller of "amount left"
4820 * "source object data size" and "target object data size". With
4821 * unaligned data we don't need to split regions, therefore the source
4822 * (copy) object should be one map entry, the target range may be split
4823 * over multiple map entries however. In any event we are pessimistic
4824 * about these assumptions.
4827 * dst_map is locked on entry and is return locked on success,
4828 * unlocked on error.
4831 static kern_return_t
4832 vm_map_copy_overwrite_unaligned(
4834 vm_map_entry_t entry
,
4836 vm_map_offset_t start
)
4838 vm_map_entry_t copy_entry
= vm_map_copy_first_entry(copy
);
4839 vm_map_version_t version
;
4840 vm_object_t dst_object
;
4841 vm_object_offset_t dst_offset
;
4842 vm_object_offset_t src_offset
;
4843 vm_object_offset_t entry_offset
;
4844 vm_map_offset_t entry_end
;
4845 vm_map_size_t src_size
,
4849 kern_return_t kr
= KERN_SUCCESS
;
4851 vm_map_lock_write_to_read(dst_map
);
4853 src_offset
= copy
->offset
- vm_object_trunc_page(copy
->offset
);
4854 amount_left
= copy
->size
;
4856 * unaligned so we never clipped this entry, we need the offset into
4857 * the vm_object not just the data.
4859 while (amount_left
> 0) {
4861 if (entry
== vm_map_to_entry(dst_map
)) {
4862 vm_map_unlock_read(dst_map
);
4863 return KERN_INVALID_ADDRESS
;
4866 /* "start" must be within the current map entry */
4867 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
4869 dst_offset
= start
- entry
->vme_start
;
4871 dst_size
= entry
->vme_end
- start
;
4873 src_size
= copy_entry
->vme_end
-
4874 (copy_entry
->vme_start
+ src_offset
);
4876 if (dst_size
< src_size
) {
4878 * we can only copy dst_size bytes before
4879 * we have to get the next destination entry
4881 copy_size
= dst_size
;
4884 * we can only copy src_size bytes before
4885 * we have to get the next source copy entry
4887 copy_size
= src_size
;
4890 if (copy_size
> amount_left
) {
4891 copy_size
= amount_left
;
4894 * Entry needs copy, create a shadow shadow object for
4895 * Copy on write region.
4897 if (entry
->needs_copy
&&
4898 ((entry
->protection
& VM_PROT_WRITE
) != 0))
4900 if (vm_map_lock_read_to_write(dst_map
)) {
4901 vm_map_lock_read(dst_map
);
4904 vm_object_shadow(&entry
->object
.vm_object
,
4906 (vm_map_size_t
)(entry
->vme_end
4907 - entry
->vme_start
));
4908 entry
->needs_copy
= FALSE
;
4909 vm_map_lock_write_to_read(dst_map
);
4911 dst_object
= entry
->object
.vm_object
;
4913 * unlike with the virtual (aligned) copy we're going
4914 * to fault on it therefore we need a target object.
4916 if (dst_object
== VM_OBJECT_NULL
) {
4917 if (vm_map_lock_read_to_write(dst_map
)) {
4918 vm_map_lock_read(dst_map
);
4921 dst_object
= vm_object_allocate((vm_map_size_t
)
4922 entry
->vme_end
- entry
->vme_start
);
4923 entry
->object
.vm_object
= dst_object
;
4925 vm_map_lock_write_to_read(dst_map
);
4928 * Take an object reference and unlock map. The "entry" may
4929 * disappear or change when the map is unlocked.
4931 vm_object_reference(dst_object
);
4932 version
.main_timestamp
= dst_map
->timestamp
;
4933 entry_offset
= entry
->offset
;
4934 entry_end
= entry
->vme_end
;
4935 vm_map_unlock_read(dst_map
);
4937 * Copy as much as possible in one pass
4940 copy_entry
->object
.vm_object
,
4941 copy_entry
->offset
+ src_offset
,
4944 entry_offset
+ dst_offset
,
4950 src_offset
+= copy_size
;
4951 amount_left
-= copy_size
;
4953 * Release the object reference
4955 vm_object_deallocate(dst_object
);
4957 * If a hard error occurred, return it now
4959 if (kr
!= KERN_SUCCESS
)
4962 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
4963 || amount_left
== 0)
4966 * all done with this copy entry, dispose.
4968 vm_map_copy_entry_unlink(copy
, copy_entry
);
4969 vm_object_deallocate(copy_entry
->object
.vm_object
);
4970 vm_map_copy_entry_dispose(copy
, copy_entry
);
4972 if ((copy_entry
= vm_map_copy_first_entry(copy
))
4973 == vm_map_copy_to_entry(copy
) && amount_left
) {
4975 * not finished copying but run out of source
4977 return KERN_INVALID_ADDRESS
;
4982 if (amount_left
== 0)
4983 return KERN_SUCCESS
;
4985 vm_map_lock_read(dst_map
);
4986 if (version
.main_timestamp
== dst_map
->timestamp
) {
4987 if (start
== entry_end
) {
4989 * destination region is split. Use the version
4990 * information to avoid a lookup in the normal
4993 entry
= entry
->vme_next
;
4995 * should be contiguous. Fail if we encounter
4996 * a hole in the destination.
4998 if (start
!= entry
->vme_start
) {
4999 vm_map_unlock_read(dst_map
);
5000 return KERN_INVALID_ADDRESS
;
5005 * Map version check failed.
5006 * we must lookup the entry because somebody
5007 * might have changed the map behind our backs.
5010 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
5012 vm_map_unlock_read(dst_map
);
5013 return KERN_INVALID_ADDRESS
;
5018 return KERN_SUCCESS
;
5019 }/* vm_map_copy_overwrite_unaligned */
5022 * Routine: vm_map_copy_overwrite_aligned [internal use only]
5025 * Does all the vm_trickery possible for whole pages.
5029 * If there are no permanent objects in the destination,
5030 * and the source and destination map entry zones match,
5031 * and the destination map entry is not shared,
5032 * then the map entries can be deleted and replaced
5033 * with those from the copy. The following code is the
5034 * basic idea of what to do, but there are lots of annoying
5035 * little details about getting protection and inheritance
5036 * right. Should add protection, inheritance, and sharing checks
5037 * to the above pass and make sure that no wiring is involved.
5040 static kern_return_t
5041 vm_map_copy_overwrite_aligned(
5043 vm_map_entry_t tmp_entry
,
5045 vm_map_offset_t start
,
5046 #if !BAD_OPTIMIZATION
5048 #endif /* !BAD_OPTIMIZATION */
5052 vm_map_entry_t copy_entry
;
5053 vm_map_size_t copy_size
;
5055 vm_map_entry_t entry
;
5057 while ((copy_entry
= vm_map_copy_first_entry(copy
))
5058 != vm_map_copy_to_entry(copy
))
5060 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
5063 if (entry
== vm_map_to_entry(dst_map
)) {
5064 vm_map_unlock(dst_map
);
5065 return KERN_INVALID_ADDRESS
;
5067 size
= (entry
->vme_end
- entry
->vme_start
);
5069 * Make sure that no holes popped up in the
5070 * address map, and that the protection is
5071 * still valid, in case the map was unlocked
5075 if ((entry
->vme_start
!= start
) || ((entry
->is_sub_map
)
5076 && !entry
->needs_copy
)) {
5077 vm_map_unlock(dst_map
);
5078 return(KERN_INVALID_ADDRESS
);
5080 assert(entry
!= vm_map_to_entry(dst_map
));
5083 * Check protection again
5086 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
5087 vm_map_unlock(dst_map
);
5088 return(KERN_PROTECTION_FAILURE
);
5092 * Adjust to source size first
5095 if (copy_size
< size
) {
5096 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
5101 * Adjust to destination size
5104 if (size
< copy_size
) {
5105 vm_map_copy_clip_end(copy
, copy_entry
,
5106 copy_entry
->vme_start
+ size
);
5110 assert((entry
->vme_end
- entry
->vme_start
) == size
);
5111 assert((tmp_entry
->vme_end
- tmp_entry
->vme_start
) == size
);
5112 assert((copy_entry
->vme_end
- copy_entry
->vme_start
) == size
);
5115 * If the destination contains temporary unshared memory,
5116 * we can perform the copy by throwing it away and
5117 * installing the source data.
5120 object
= entry
->object
.vm_object
;
5121 if ((!entry
->is_shared
&&
5122 ((object
== VM_OBJECT_NULL
) ||
5123 (object
->internal
&& !object
->true_share
))) ||
5124 entry
->needs_copy
) {
5125 vm_object_t old_object
= entry
->object
.vm_object
;
5126 vm_object_offset_t old_offset
= entry
->offset
;
5127 vm_object_offset_t offset
;
5130 * Ensure that the source and destination aren't
5133 if (old_object
== copy_entry
->object
.vm_object
&&
5134 old_offset
== copy_entry
->offset
) {
5135 vm_map_copy_entry_unlink(copy
, copy_entry
);
5136 vm_map_copy_entry_dispose(copy
, copy_entry
);
5138 if (old_object
!= VM_OBJECT_NULL
)
5139 vm_object_deallocate(old_object
);
5141 start
= tmp_entry
->vme_end
;
5142 tmp_entry
= tmp_entry
->vme_next
;
5146 if (old_object
!= VM_OBJECT_NULL
) {
5147 if(entry
->is_sub_map
) {
5148 if(entry
->use_pmap
) {
5150 pmap_unnest(dst_map
->pmap
,
5153 if(dst_map
->mapped
) {
5154 /* clean up parent */
5156 vm_map_submap_pmap_clean(
5157 dst_map
, entry
->vme_start
,
5159 entry
->object
.sub_map
,
5163 vm_map_submap_pmap_clean(
5164 dst_map
, entry
->vme_start
,
5166 entry
->object
.sub_map
,
5170 entry
->object
.sub_map
);
5172 if(dst_map
->mapped
) {
5173 vm_object_pmap_protect(
5174 entry
->object
.vm_object
,
5182 pmap_remove(dst_map
->pmap
,
5183 (addr64_t
)(entry
->vme_start
),
5184 (addr64_t
)(entry
->vme_end
));
5186 vm_object_deallocate(old_object
);
5190 entry
->is_sub_map
= FALSE
;
5191 entry
->object
= copy_entry
->object
;
5192 object
= entry
->object
.vm_object
;
5193 entry
->needs_copy
= copy_entry
->needs_copy
;
5194 entry
->wired_count
= 0;
5195 entry
->user_wired_count
= 0;
5196 offset
= entry
->offset
= copy_entry
->offset
;
5198 vm_map_copy_entry_unlink(copy
, copy_entry
);
5199 vm_map_copy_entry_dispose(copy
, copy_entry
);
5200 #if BAD_OPTIMIZATION
5202 * if we turn this optimization back on
5203 * we need to revisit our use of pmap mappings
5204 * large copies will cause us to run out and panic
5205 * this optimization only saved on average 2 us per page if ALL
5206 * the pages in the source were currently mapped
5207 * and ALL the pages in the dest were touched, if there were fewer
5208 * than 2/3 of the pages touched, this optimization actually cost more cycles
5212 * Try to aggressively enter physical mappings
5213 * (but avoid uninstantiated objects)
5215 if (object
!= VM_OBJECT_NULL
) {
5216 vm_map_offset_t va
= entry
->vme_start
;
5218 while (va
< entry
->vme_end
) {
5219 register vm_page_t m
;
5223 * Look for the page in the top object
5225 prot
= entry
->protection
;
5226 vm_object_lock(object
);
5227 vm_object_paging_begin(object
);
5231 * If the page is encrypted, skip it:
5232 * we can't let the user see the encrypted
5233 * contents. The page will get decrypted
5234 * on demand when the user generates a
5235 * soft-fault when trying to access it.
5237 if ((m
= vm_page_lookup(object
,offset
)) !=
5238 VM_PAGE_NULL
&& !m
->busy
&&
5239 !m
->fictitious
&& !m
->encrypted
&&
5240 (!m
->unusual
|| (!m
->error
&&
5241 !m
->restart
&& !m
->absent
&&
5242 (prot
& m
->page_lock
) == 0))) {
5245 vm_object_unlock(object
);
5248 * Honor COW obligations
5250 if (entry
->needs_copy
)
5251 prot
&= ~VM_PROT_WRITE
;
5252 /* It is our policy to require */
5253 /* explicit sync from anyone */
5254 /* writing code and then */
5255 /* a pc to execute it. */
5258 PMAP_ENTER(pmap
, va
, m
, prot
,
5260 (m
->object
->wimg_bits
))
5264 vm_object_lock(object
);
5265 vm_page_lock_queues();
5266 if (!m
->active
&& !m
->inactive
)
5267 vm_page_activate(m
);
5268 vm_page_unlock_queues();
5269 PAGE_WAKEUP_DONE(m
);
5271 vm_object_paging_end(object
);
5272 vm_object_unlock(object
);
5274 offset
+= PAGE_SIZE_64
;
5276 } /* end while (va < entry->vme_end) */
5277 } /* end if (object) */
5280 * Set up for the next iteration. The map
5281 * has not been unlocked, so the next
5282 * address should be at the end of this
5283 * entry, and the next map entry should be
5284 * the one following it.
5287 start
= tmp_entry
->vme_end
;
5288 tmp_entry
= tmp_entry
->vme_next
;
5290 vm_map_version_t version
;
5291 vm_object_t dst_object
= entry
->object
.vm_object
;
5292 vm_object_offset_t dst_offset
= entry
->offset
;
5296 * Take an object reference, and record
5297 * the map version information so that the
5298 * map can be safely unlocked.
5301 vm_object_reference(dst_object
);
5303 /* account for unlock bumping up timestamp */
5304 version
.main_timestamp
= dst_map
->timestamp
+ 1;
5306 vm_map_unlock(dst_map
);
5309 * Copy as much as possible in one pass
5314 copy_entry
->object
.vm_object
,
5324 * Release the object reference
5327 vm_object_deallocate(dst_object
);
5330 * If a hard error occurred, return it now
5333 if (r
!= KERN_SUCCESS
)
5336 if (copy_size
!= 0) {
5338 * Dispose of the copied region
5341 vm_map_copy_clip_end(copy
, copy_entry
,
5342 copy_entry
->vme_start
+ copy_size
);
5343 vm_map_copy_entry_unlink(copy
, copy_entry
);
5344 vm_object_deallocate(copy_entry
->object
.vm_object
);
5345 vm_map_copy_entry_dispose(copy
, copy_entry
);
5349 * Pick up in the destination map where we left off.
5351 * Use the version information to avoid a lookup
5352 * in the normal case.
5356 vm_map_lock(dst_map
);
5357 if (version
.main_timestamp
== dst_map
->timestamp
) {
5358 /* We can safely use saved tmp_entry value */
5360 vm_map_clip_end(dst_map
, tmp_entry
, start
);
5361 tmp_entry
= tmp_entry
->vme_next
;
5363 /* Must do lookup of tmp_entry */
5365 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
5366 vm_map_unlock(dst_map
);
5367 return(KERN_INVALID_ADDRESS
);
5369 vm_map_clip_start(dst_map
, tmp_entry
, start
);
5374 return(KERN_SUCCESS
);
5375 }/* vm_map_copy_overwrite_aligned */
5378 * Routine: vm_map_copyin_kernel_buffer [internal use only]
5381 * Copy in data to a kernel buffer from space in the
5382 * source map. The original space may be optionally
5385 * If successful, returns a new copy object.
5387 static kern_return_t
5388 vm_map_copyin_kernel_buffer(
5390 vm_map_offset_t src_addr
,
5392 boolean_t src_destroy
,
5393 vm_map_copy_t
*copy_result
)
5397 vm_map_size_t kalloc_size
= sizeof(struct vm_map_copy
) + len
;
5399 copy
= (vm_map_copy_t
) kalloc(kalloc_size
);
5400 if (copy
== VM_MAP_COPY_NULL
) {
5401 return KERN_RESOURCE_SHORTAGE
;
5403 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
5406 copy
->cpy_kdata
= (void *) (copy
+ 1);
5407 copy
->cpy_kalloc_size
= kalloc_size
;
5409 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, len
);
5410 if (kr
!= KERN_SUCCESS
) {
5411 kfree(copy
, kalloc_size
);
5415 (void) vm_map_remove(src_map
, vm_map_trunc_page(src_addr
),
5416 vm_map_round_page(src_addr
+ len
),
5417 VM_MAP_REMOVE_INTERRUPTIBLE
|
5418 VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
5419 (src_map
== kernel_map
) ?
5420 VM_MAP_REMOVE_KUNWIRE
: 0);
5422 *copy_result
= copy
;
5423 return KERN_SUCCESS
;
5427 * Routine: vm_map_copyout_kernel_buffer [internal use only]
5430 * Copy out data from a kernel buffer into space in the
5431 * destination map. The space may be otpionally dynamically
5434 * If successful, consumes the copy object.
5435 * Otherwise, the caller is responsible for it.
5437 static int vm_map_copyout_kernel_buffer_failures
= 0;
5438 static kern_return_t
5439 vm_map_copyout_kernel_buffer(
5441 vm_map_address_t
*addr
, /* IN/OUT */
5443 boolean_t overwrite
)
5445 kern_return_t kr
= KERN_SUCCESS
;
5446 thread_t thread
= current_thread();
5451 * Allocate space in the target map for the data
5454 kr
= vm_map_enter(map
,
5456 vm_map_round_page(copy
->size
),
5457 (vm_map_offset_t
) 0,
5460 (vm_object_offset_t
) 0,
5464 VM_INHERIT_DEFAULT
);
5465 if (kr
!= KERN_SUCCESS
)
5470 * Copyout the data from the kernel buffer to the target map.
5472 if (thread
->map
== map
) {
5475 * If the target map is the current map, just do
5478 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5479 kr
= KERN_INVALID_ADDRESS
;
5486 * If the target map is another map, assume the
5487 * target's address space identity for the duration
5490 vm_map_reference(map
);
5491 oldmap
= vm_map_switch(map
);
5493 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5494 vm_map_copyout_kernel_buffer_failures
++;
5495 kr
= KERN_INVALID_ADDRESS
;
5498 (void) vm_map_switch(oldmap
);
5499 vm_map_deallocate(map
);
5502 if (kr
!= KERN_SUCCESS
) {
5503 /* the copy failed, clean up */
5506 * Deallocate the space we allocated in the target map.
5508 (void) vm_map_remove(map
,
5509 vm_map_trunc_page(*addr
),
5510 vm_map_round_page(*addr
+
5511 vm_map_round_page(copy
->size
)),
5516 /* copy was successful, dicard the copy structure */
5517 kfree(copy
, copy
->cpy_kalloc_size
);
5524 * Macro: vm_map_copy_insert
5527 * Link a copy chain ("copy") into a map at the
5528 * specified location (after "where").
5530 * The copy chain is destroyed.
5532 * The arguments are evaluated multiple times.
5534 #define vm_map_copy_insert(map, where, copy) \
5536 vm_map_t VMCI_map; \
5537 vm_map_entry_t VMCI_where; \
5538 vm_map_copy_t VMCI_copy; \
5540 VMCI_where = (where); \
5541 VMCI_copy = (copy); \
5542 ((VMCI_where->vme_next)->vme_prev = vm_map_copy_last_entry(VMCI_copy))\
5543 ->vme_next = (VMCI_where->vme_next); \
5544 ((VMCI_where)->vme_next = vm_map_copy_first_entry(VMCI_copy)) \
5545 ->vme_prev = VMCI_where; \
5546 VMCI_map->hdr.nentries += VMCI_copy->cpy_hdr.nentries; \
5547 UPDATE_FIRST_FREE(VMCI_map, VMCI_map->first_free); \
5548 zfree(vm_map_copy_zone, VMCI_copy); \
5552 * Routine: vm_map_copyout
5555 * Copy out a copy chain ("copy") into newly-allocated
5556 * space in the destination map.
5558 * If successful, consumes the copy object.
5559 * Otherwise, the caller is responsible for it.
5564 vm_map_address_t
*dst_addr
, /* OUT */
5568 vm_map_size_t adjustment
;
5569 vm_map_offset_t start
;
5570 vm_object_offset_t vm_copy_start
;
5571 vm_map_entry_t last
;
5573 vm_map_entry_t entry
;
5576 * Check for null copy object.
5579 if (copy
== VM_MAP_COPY_NULL
) {
5581 return(KERN_SUCCESS
);
5585 * Check for special copy object, created
5586 * by vm_map_copyin_object.
5589 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
5590 vm_object_t object
= copy
->cpy_object
;
5592 vm_object_offset_t offset
;
5594 offset
= vm_object_trunc_page(copy
->offset
);
5595 size
= vm_map_round_page(copy
->size
+
5596 (vm_map_size_t
)(copy
->offset
- offset
));
5598 kr
= vm_map_enter(dst_map
, dst_addr
, size
,
5599 (vm_map_offset_t
) 0, VM_FLAGS_ANYWHERE
,
5600 object
, offset
, FALSE
,
5601 VM_PROT_DEFAULT
, VM_PROT_ALL
,
5602 VM_INHERIT_DEFAULT
);
5603 if (kr
!= KERN_SUCCESS
)
5605 /* Account for non-pagealigned copy object */
5606 *dst_addr
+= (vm_map_offset_t
)(copy
->offset
- offset
);
5607 zfree(vm_map_copy_zone
, copy
);
5608 return(KERN_SUCCESS
);
5612 * Check for special kernel buffer allocated
5613 * by new_ipc_kmsg_copyin.
5616 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
5617 return(vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
5622 * Find space for the data
5625 vm_copy_start
= vm_object_trunc_page(copy
->offset
);
5626 size
= vm_map_round_page((vm_map_size_t
)copy
->offset
+ copy
->size
)
5631 vm_map_lock(dst_map
);
5632 assert(first_free_is_valid(dst_map
));
5633 start
= ((last
= dst_map
->first_free
) == vm_map_to_entry(dst_map
)) ?
5634 vm_map_min(dst_map
) : last
->vme_end
;
5637 vm_map_entry_t next
= last
->vme_next
;
5638 vm_map_offset_t end
= start
+ size
;
5640 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
5641 if (dst_map
->wait_for_space
) {
5642 if (size
<= (dst_map
->max_offset
- dst_map
->min_offset
)) {
5643 assert_wait((event_t
) dst_map
,
5644 THREAD_INTERRUPTIBLE
);
5645 vm_map_unlock(dst_map
);
5646 thread_block(THREAD_CONTINUE_NULL
);
5650 vm_map_unlock(dst_map
);
5651 return(KERN_NO_SPACE
);
5654 if ((next
== vm_map_to_entry(dst_map
)) ||
5655 (next
->vme_start
>= end
))
5659 start
= last
->vme_end
;
5663 * Since we're going to just drop the map
5664 * entries from the copy into the destination
5665 * map, they must come from the same pool.
5668 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
5670 * Mismatches occur when dealing with the default
5674 vm_map_entry_t next
, new;
5677 * Find the zone that the copies were allocated from
5679 old_zone
= (copy
->cpy_hdr
.entries_pageable
)
5681 : vm_map_kentry_zone
;
5682 entry
= vm_map_copy_first_entry(copy
);
5685 * Reinitialize the copy so that vm_map_copy_entry_link
5688 copy
->cpy_hdr
.nentries
= 0;
5689 copy
->cpy_hdr
.entries_pageable
= dst_map
->hdr
.entries_pageable
;
5690 vm_map_copy_first_entry(copy
) =
5691 vm_map_copy_last_entry(copy
) =
5692 vm_map_copy_to_entry(copy
);
5697 while (entry
!= vm_map_copy_to_entry(copy
)) {
5698 new = vm_map_copy_entry_create(copy
);
5699 vm_map_entry_copy_full(new, entry
);
5700 new->use_pmap
= FALSE
; /* clr address space specifics */
5701 vm_map_copy_entry_link(copy
,
5702 vm_map_copy_last_entry(copy
),
5704 next
= entry
->vme_next
;
5705 zfree(old_zone
, entry
);
5711 * Adjust the addresses in the copy chain, and
5712 * reset the region attributes.
5715 adjustment
= start
- vm_copy_start
;
5716 for (entry
= vm_map_copy_first_entry(copy
);
5717 entry
!= vm_map_copy_to_entry(copy
);
5718 entry
= entry
->vme_next
) {
5719 entry
->vme_start
+= adjustment
;
5720 entry
->vme_end
+= adjustment
;
5722 entry
->inheritance
= VM_INHERIT_DEFAULT
;
5723 entry
->protection
= VM_PROT_DEFAULT
;
5724 entry
->max_protection
= VM_PROT_ALL
;
5725 entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
5728 * If the entry is now wired,
5729 * map the pages into the destination map.
5731 if (entry
->wired_count
!= 0) {
5732 register vm_map_offset_t va
;
5733 vm_object_offset_t offset
;
5734 register vm_object_t object
;
5736 object
= entry
->object
.vm_object
;
5737 offset
= entry
->offset
;
5738 va
= entry
->vme_start
;
5740 pmap_pageable(dst_map
->pmap
,
5745 while (va
< entry
->vme_end
) {
5746 register vm_page_t m
;
5749 * Look up the page in the object.
5750 * Assert that the page will be found in the
5753 * the object was newly created by
5754 * vm_object_copy_slowly, and has
5755 * copies of all of the pages from
5758 * the object was moved from the old
5759 * map entry; because the old map
5760 * entry was wired, all of the pages
5761 * were in the top-level object.
5762 * (XXX not true if we wire pages for
5765 vm_object_lock(object
);
5766 vm_object_paging_begin(object
);
5768 m
= vm_page_lookup(object
, offset
);
5769 if (m
== VM_PAGE_NULL
|| m
->wire_count
== 0 ||
5771 panic("vm_map_copyout: wiring 0x%x", m
);
5775 * The page is assumed to be wired here, so it
5776 * shouldn't be encrypted. Otherwise, we
5777 * couldn't enter it in the page table, since
5778 * we don't want the user to see the encrypted
5781 ASSERT_PAGE_DECRYPTED(m
);
5784 vm_object_unlock(object
);
5786 PMAP_ENTER(dst_map
->pmap
, va
, m
, entry
->protection
,
5788 (m
->object
->wimg_bits
))
5792 vm_object_lock(object
);
5793 PAGE_WAKEUP_DONE(m
);
5794 /* the page is wired, so we don't have to activate */
5795 vm_object_paging_end(object
);
5796 vm_object_unlock(object
);
5798 offset
+= PAGE_SIZE_64
;
5802 else if (size
<= vm_map_aggressive_enter_max
) {
5804 register vm_map_offset_t va
;
5805 vm_object_offset_t offset
;
5806 register vm_object_t object
;
5809 object
= entry
->object
.vm_object
;
5810 if (object
!= VM_OBJECT_NULL
) {
5812 offset
= entry
->offset
;
5813 va
= entry
->vme_start
;
5814 while (va
< entry
->vme_end
) {
5815 register vm_page_t m
;
5818 * Look up the page in the object.
5819 * Assert that the page will be found
5820 * in the top object if at all...
5822 vm_object_lock(object
);
5823 vm_object_paging_begin(object
);
5827 * If the page is encrypted, skip it:
5828 * we can't let the user see the
5829 * encrypted contents. The page will
5830 * get decrypted on demand when the
5831 * user generates a soft-fault when
5832 * trying to access it.
5834 if (((m
= vm_page_lookup(object
,
5837 !m
->busy
&& !m
->fictitious
&&
5839 !m
->absent
&& !m
->error
) {
5841 vm_object_unlock(object
);
5843 /* honor cow obligations */
5844 prot
= entry
->protection
;
5845 if (entry
->needs_copy
)
5846 prot
&= ~VM_PROT_WRITE
;
5848 PMAP_ENTER(dst_map
->pmap
, va
,
5851 (m
->object
->wimg_bits
))
5855 vm_object_lock(object
);
5856 vm_page_lock_queues();
5857 if (!m
->active
&& !m
->inactive
)
5858 vm_page_activate(m
);
5859 vm_page_unlock_queues();
5860 PAGE_WAKEUP_DONE(m
);
5862 vm_object_paging_end(object
);
5863 vm_object_unlock(object
);
5865 offset
+= PAGE_SIZE_64
;
5873 * Correct the page alignment for the result
5876 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
5879 * Update the hints and the map size
5882 SAVE_HINT(dst_map
, vm_map_copy_last_entry(copy
));
5884 dst_map
->size
+= size
;
5890 vm_map_copy_insert(dst_map
, last
, copy
);
5892 vm_map_unlock(dst_map
);
5895 * XXX If wiring_required, call vm_map_pageable
5898 return(KERN_SUCCESS
);
5902 * Routine: vm_map_copyin
5905 * Copy the specified region (src_addr, len) from the
5906 * source address space (src_map), possibly removing
5907 * the region from the source address space (src_destroy).
5910 * A vm_map_copy_t object (copy_result), suitable for
5911 * insertion into another address space (using vm_map_copyout),
5912 * copying over another address space region (using
5913 * vm_map_copy_overwrite). If the copy is unused, it
5914 * should be destroyed (using vm_map_copy_discard).
5916 * In/out conditions:
5917 * The source map should not be locked on entry.
5920 typedef struct submap_map
{
5921 vm_map_t parent_map
;
5922 vm_map_offset_t base_start
;
5923 vm_map_offset_t base_end
;
5924 struct submap_map
*next
;
5928 vm_map_copyin_common(
5930 vm_map_address_t src_addr
,
5932 boolean_t src_destroy
,
5933 __unused boolean_t src_volatile
,
5934 vm_map_copy_t
*copy_result
, /* OUT */
5935 boolean_t use_maxprot
)
5937 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
5938 * in multi-level lookup, this
5939 * entry contains the actual
5943 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
5945 vm_map_offset_t src_start
; /* Start of current entry --
5946 * where copy is taking place now
5948 vm_map_offset_t src_end
; /* End of entire region to be
5950 vm_map_t base_map
= src_map
;
5951 boolean_t map_share
=FALSE
;
5952 submap_map_t
*parent_maps
= NULL
;
5955 vm_map_copy_t copy
; /* Resulting copy */
5956 vm_map_address_t copy_addr
;
5959 * Check for copies of zero bytes.
5963 *copy_result
= VM_MAP_COPY_NULL
;
5964 return(KERN_SUCCESS
);
5968 * Check that the end address doesn't overflow
5970 src_end
= src_addr
+ len
;
5971 if (src_end
< src_addr
)
5972 return KERN_INVALID_ADDRESS
;
5975 * If the copy is sufficiently small, use a kernel buffer instead
5976 * of making a virtual copy. The theory being that the cost of
5977 * setting up VM (and taking C-O-W faults) dominates the copy costs
5978 * for small regions.
5980 if ((len
< msg_ool_size_small
) && !use_maxprot
)
5981 return vm_map_copyin_kernel_buffer(src_map
, src_addr
, len
,
5982 src_destroy
, copy_result
);
5985 * Compute (page aligned) start and end of region
5987 src_start
= vm_map_trunc_page(src_addr
);
5988 src_end
= vm_map_round_page(src_end
);
5990 XPR(XPR_VM_MAP
, "vm_map_copyin_common map 0x%x addr 0x%x len 0x%x dest %d\n", (natural_t
)src_map
, src_addr
, len
, src_destroy
, 0);
5993 * Allocate a header element for the list.
5995 * Use the start and end in the header to
5996 * remember the endpoints prior to rounding.
5999 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6000 vm_map_copy_first_entry(copy
) =
6001 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
6002 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
6003 copy
->cpy_hdr
.nentries
= 0;
6004 copy
->cpy_hdr
.entries_pageable
= TRUE
;
6006 copy
->offset
= src_addr
;
6009 new_entry
= vm_map_copy_entry_create(copy
);
6013 vm_map_unlock(src_map); \
6014 if(src_map != base_map) \
6015 vm_map_deallocate(src_map); \
6016 if (new_entry != VM_MAP_ENTRY_NULL) \
6017 vm_map_copy_entry_dispose(copy,new_entry); \
6018 vm_map_copy_discard(copy); \
6020 submap_map_t *_ptr; \
6022 for(_ptr = parent_maps; _ptr != NULL; _ptr = parent_maps) { \
6023 parent_maps=parent_maps->next; \
6024 if (_ptr->parent_map != base_map) \
6025 vm_map_deallocate(_ptr->parent_map); \
6026 kfree(_ptr, sizeof(submap_map_t)); \
6033 * Find the beginning of the region.
6036 vm_map_lock(src_map
);
6038 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
))
6039 RETURN(KERN_INVALID_ADDRESS
);
6040 if(!tmp_entry
->is_sub_map
) {
6041 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6043 /* set for later submap fix-up */
6044 copy_addr
= src_start
;
6047 * Go through entries until we get to the end.
6052 vm_map_entry_t src_entry
= tmp_entry
; /* Top-level entry */
6053 vm_map_size_t src_size
; /* Size of source
6054 * map entry (in both
6059 vm_object_t src_object
; /* Object to copy */
6060 vm_object_offset_t src_offset
;
6062 boolean_t src_needs_copy
; /* Should source map
6064 * for copy-on-write?
6067 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
6069 boolean_t was_wired
; /* Was source wired? */
6070 vm_map_version_t version
; /* Version before locks
6071 * dropped to make copy
6073 kern_return_t result
; /* Return value from
6074 * copy_strategically.
6076 while(tmp_entry
->is_sub_map
) {
6077 vm_map_size_t submap_len
;
6080 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
6081 ptr
->next
= parent_maps
;
6083 ptr
->parent_map
= src_map
;
6084 ptr
->base_start
= src_start
;
6085 ptr
->base_end
= src_end
;
6086 submap_len
= tmp_entry
->vme_end
- src_start
;
6087 if(submap_len
> (src_end
-src_start
))
6088 submap_len
= src_end
-src_start
;
6089 ptr
->base_start
+= submap_len
;
6091 src_start
-= tmp_entry
->vme_start
;
6092 src_start
+= tmp_entry
->offset
;
6093 src_end
= src_start
+ submap_len
;
6094 src_map
= tmp_entry
->object
.sub_map
;
6095 vm_map_lock(src_map
);
6096 /* keep an outstanding reference for all maps in */
6097 /* the parents tree except the base map */
6098 vm_map_reference(src_map
);
6099 vm_map_unlock(ptr
->parent_map
);
6100 if (!vm_map_lookup_entry(
6101 src_map
, src_start
, &tmp_entry
))
6102 RETURN(KERN_INVALID_ADDRESS
);
6104 if(!tmp_entry
->is_sub_map
)
6105 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6106 src_entry
= tmp_entry
;
6108 if ((tmp_entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
6109 (tmp_entry
->object
.vm_object
->phys_contiguous
)) {
6110 /* This is not, supported for now.In future */
6111 /* we will need to detect the phys_contig */
6112 /* condition and then upgrade copy_slowly */
6113 /* to do physical copy from the device mem */
6114 /* based object. We can piggy-back off of */
6115 /* the was wired boolean to set-up the */
6116 /* proper handling */
6117 RETURN(KERN_PROTECTION_FAILURE
);
6120 * Create a new address map entry to hold the result.
6121 * Fill in the fields from the appropriate source entries.
6122 * We must unlock the source map to do this if we need
6123 * to allocate a map entry.
6125 if (new_entry
== VM_MAP_ENTRY_NULL
) {
6126 version
.main_timestamp
= src_map
->timestamp
;
6127 vm_map_unlock(src_map
);
6129 new_entry
= vm_map_copy_entry_create(copy
);
6131 vm_map_lock(src_map
);
6132 if ((version
.main_timestamp
+ 1) != src_map
->timestamp
) {
6133 if (!vm_map_lookup_entry(src_map
, src_start
,
6135 RETURN(KERN_INVALID_ADDRESS
);
6137 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6138 continue; /* restart w/ new tmp_entry */
6143 * Verify that the region can be read.
6145 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
6147 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
6148 RETURN(KERN_PROTECTION_FAILURE
);
6151 * Clip against the endpoints of the entire region.
6154 vm_map_clip_end(src_map
, src_entry
, src_end
);
6156 src_size
= src_entry
->vme_end
- src_start
;
6157 src_object
= src_entry
->object
.vm_object
;
6158 src_offset
= src_entry
->offset
;
6159 was_wired
= (src_entry
->wired_count
!= 0);
6161 vm_map_entry_copy(new_entry
, src_entry
);
6162 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
6165 * Attempt non-blocking copy-on-write optimizations.
6169 (src_object
== VM_OBJECT_NULL
||
6170 (src_object
->internal
&& !src_object
->true_share
6173 * If we are destroying the source, and the object
6174 * is internal, we can move the object reference
6175 * from the source to the copy. The copy is
6176 * copy-on-write only if the source is.
6177 * We make another reference to the object, because
6178 * destroying the source entry will deallocate it.
6180 vm_object_reference(src_object
);
6183 * Copy is always unwired. vm_map_copy_entry
6184 * set its wired count to zero.
6187 goto CopySuccessful
;
6192 XPR(XPR_VM_MAP
, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
6193 src_object
, new_entry
, new_entry
->object
.vm_object
,
6195 if ((src_object
== VM_OBJECT_NULL
||
6196 (!was_wired
&& !map_share
&& !tmp_entry
->is_shared
)) &&
6197 vm_object_copy_quickly(
6198 &new_entry
->object
.vm_object
,
6202 &new_entry_needs_copy
)) {
6204 new_entry
->needs_copy
= new_entry_needs_copy
;
6207 * Handle copy-on-write obligations
6210 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
6211 vm_object_pmap_protect(
6215 (src_entry
->is_shared
?
6218 src_entry
->vme_start
,
6219 src_entry
->protection
&
6221 tmp_entry
->needs_copy
= TRUE
;
6225 * The map has never been unlocked, so it's safe
6226 * to move to the next entry rather than doing
6230 goto CopySuccessful
;
6234 * Take an object reference, so that we may
6235 * release the map lock(s).
6238 assert(src_object
!= VM_OBJECT_NULL
);
6239 vm_object_reference(src_object
);
6242 * Record the timestamp for later verification.
6246 version
.main_timestamp
= src_map
->timestamp
;
6247 vm_map_unlock(src_map
); /* Increments timestamp once! */
6255 vm_object_lock(src_object
);
6256 result
= vm_object_copy_slowly(
6261 &new_entry
->object
.vm_object
);
6262 new_entry
->offset
= 0;
6263 new_entry
->needs_copy
= FALSE
;
6266 else if (src_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
6267 (tmp_entry
->is_shared
|| map_share
)) {
6268 vm_object_t new_object
;
6270 vm_object_lock(src_object
);
6271 new_object
= vm_object_copy_delayed(
6275 if (new_object
== VM_OBJECT_NULL
)
6278 new_entry
->object
.vm_object
= new_object
;
6279 new_entry
->needs_copy
= TRUE
;
6280 result
= KERN_SUCCESS
;
6283 result
= vm_object_copy_strategically(src_object
,
6286 &new_entry
->object
.vm_object
,
6288 &new_entry_needs_copy
);
6290 new_entry
->needs_copy
= new_entry_needs_copy
;
6293 if (result
!= KERN_SUCCESS
&&
6294 result
!= KERN_MEMORY_RESTART_COPY
) {
6295 vm_map_lock(src_map
);
6300 * Throw away the extra reference
6303 vm_object_deallocate(src_object
);
6306 * Verify that the map has not substantially
6307 * changed while the copy was being made.
6310 vm_map_lock(src_map
);
6312 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
)
6313 goto VerificationSuccessful
;
6316 * Simple version comparison failed.
6318 * Retry the lookup and verify that the
6319 * same object/offset are still present.
6321 * [Note: a memory manager that colludes with
6322 * the calling task can detect that we have
6323 * cheated. While the map was unlocked, the
6324 * mapping could have been changed and restored.]
6327 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
6328 RETURN(KERN_INVALID_ADDRESS
);
6331 src_entry
= tmp_entry
;
6332 vm_map_clip_start(src_map
, src_entry
, src_start
);
6334 if ((((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
) &&
6336 ((src_entry
->max_protection
& VM_PROT_READ
) == 0))
6337 goto VerificationFailed
;
6339 if (src_entry
->vme_end
< new_entry
->vme_end
)
6340 src_size
= (new_entry
->vme_end
= src_entry
->vme_end
) - src_start
;
6342 if ((src_entry
->object
.vm_object
!= src_object
) ||
6343 (src_entry
->offset
!= src_offset
) ) {
6346 * Verification failed.
6348 * Start over with this top-level entry.
6351 VerificationFailed
: ;
6353 vm_object_deallocate(new_entry
->object
.vm_object
);
6354 tmp_entry
= src_entry
;
6359 * Verification succeeded.
6362 VerificationSuccessful
: ;
6364 if (result
== KERN_MEMORY_RESTART_COPY
)
6374 * Link in the new copy entry.
6377 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
6381 * Determine whether the entire region
6384 src_start
= new_entry
->vme_end
;
6385 new_entry
= VM_MAP_ENTRY_NULL
;
6386 while ((src_start
>= src_end
) && (src_end
!= 0)) {
6387 if (src_map
!= base_map
) {
6391 assert(ptr
!= NULL
);
6392 parent_maps
= parent_maps
->next
;
6393 vm_map_unlock(src_map
);
6394 vm_map_deallocate(src_map
);
6395 vm_map_lock(ptr
->parent_map
);
6396 src_map
= ptr
->parent_map
;
6397 src_start
= ptr
->base_start
;
6398 src_end
= ptr
->base_end
;
6399 if ((src_end
> src_start
) &&
6400 !vm_map_lookup_entry(
6401 src_map
, src_start
, &tmp_entry
))
6402 RETURN(KERN_INVALID_ADDRESS
);
6403 kfree(ptr
, sizeof(submap_map_t
));
6404 if(parent_maps
== NULL
)
6406 src_entry
= tmp_entry
->vme_prev
;
6410 if ((src_start
>= src_end
) && (src_end
!= 0))
6414 * Verify that there are no gaps in the region
6417 tmp_entry
= src_entry
->vme_next
;
6418 if ((tmp_entry
->vme_start
!= src_start
) ||
6419 (tmp_entry
== vm_map_to_entry(src_map
)))
6420 RETURN(KERN_INVALID_ADDRESS
);
6424 * If the source should be destroyed, do it now, since the
6425 * copy was successful.
6428 (void) vm_map_delete(src_map
,
6429 vm_map_trunc_page(src_addr
),
6431 (src_map
== kernel_map
) ?
6432 VM_MAP_REMOVE_KUNWIRE
:
6437 vm_map_unlock(src_map
);
6439 /* Fix-up start and end points in copy. This is necessary */
6440 /* when the various entries in the copy object were picked */
6441 /* up from different sub-maps */
6443 tmp_entry
= vm_map_copy_first_entry(copy
);
6444 while (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
6445 tmp_entry
->vme_end
= copy_addr
+
6446 (tmp_entry
->vme_end
- tmp_entry
->vme_start
);
6447 tmp_entry
->vme_start
= copy_addr
;
6448 copy_addr
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
6449 tmp_entry
= (struct vm_map_entry
*)tmp_entry
->vme_next
;
6452 *copy_result
= copy
;
6453 return(KERN_SUCCESS
);
6459 * vm_map_copyin_object:
6461 * Create a copy object from an object.
6462 * Our caller donates an object reference.
6466 vm_map_copyin_object(
6468 vm_object_offset_t offset
, /* offset of region in object */
6469 vm_object_size_t size
, /* size of region in object */
6470 vm_map_copy_t
*copy_result
) /* OUT */
6472 vm_map_copy_t copy
; /* Resulting copy */
6475 * We drop the object into a special copy object
6476 * that contains the object directly.
6479 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6480 copy
->type
= VM_MAP_COPY_OBJECT
;
6481 copy
->cpy_object
= object
;
6482 copy
->offset
= offset
;
6485 *copy_result
= copy
;
6486 return(KERN_SUCCESS
);
6492 vm_map_entry_t old_entry
,
6496 vm_map_entry_t new_entry
;
6499 * New sharing code. New map entry
6500 * references original object. Internal
6501 * objects use asynchronous copy algorithm for
6502 * future copies. First make sure we have
6503 * the right object. If we need a shadow,
6504 * or someone else already has one, then
6505 * make a new shadow and share it.
6508 object
= old_entry
->object
.vm_object
;
6509 if (old_entry
->is_sub_map
) {
6510 assert(old_entry
->wired_count
== 0);
6512 if(old_entry
->use_pmap
) {
6513 kern_return_t result
;
6515 result
= pmap_nest(new_map
->pmap
,
6516 (old_entry
->object
.sub_map
)->pmap
,
6517 (addr64_t
)old_entry
->vme_start
,
6518 (addr64_t
)old_entry
->vme_start
,
6519 (uint64_t)(old_entry
->vme_end
- old_entry
->vme_start
));
6521 panic("vm_map_fork_share: pmap_nest failed!");
6524 } else if (object
== VM_OBJECT_NULL
) {
6525 object
= vm_object_allocate((vm_map_size_t
)(old_entry
->vme_end
-
6526 old_entry
->vme_start
));
6527 old_entry
->offset
= 0;
6528 old_entry
->object
.vm_object
= object
;
6529 assert(!old_entry
->needs_copy
);
6530 } else if (object
->copy_strategy
!=
6531 MEMORY_OBJECT_COPY_SYMMETRIC
) {
6534 * We are already using an asymmetric
6535 * copy, and therefore we already have
6539 assert(! old_entry
->needs_copy
);
6541 else if (old_entry
->needs_copy
|| /* case 1 */
6542 object
->shadowed
|| /* case 2 */
6543 (!object
->true_share
&& /* case 3 */
6544 !old_entry
->is_shared
&&
6546 (vm_map_size_t
)(old_entry
->vme_end
-
6547 old_entry
->vme_start
)))) {
6550 * We need to create a shadow.
6551 * There are three cases here.
6552 * In the first case, we need to
6553 * complete a deferred symmetrical
6554 * copy that we participated in.
6555 * In the second and third cases,
6556 * we need to create the shadow so
6557 * that changes that we make to the
6558 * object do not interfere with
6559 * any symmetrical copies which
6560 * have occured (case 2) or which
6561 * might occur (case 3).
6563 * The first case is when we had
6564 * deferred shadow object creation
6565 * via the entry->needs_copy mechanism.
6566 * This mechanism only works when
6567 * only one entry points to the source
6568 * object, and we are about to create
6569 * a second entry pointing to the
6570 * same object. The problem is that
6571 * there is no way of mapping from
6572 * an object to the entries pointing
6573 * to it. (Deferred shadow creation
6574 * works with one entry because occurs
6575 * at fault time, and we walk from the
6576 * entry to the object when handling
6579 * The second case is when the object
6580 * to be shared has already been copied
6581 * with a symmetric copy, but we point
6582 * directly to the object without
6583 * needs_copy set in our entry. (This
6584 * can happen because different ranges
6585 * of an object can be pointed to by
6586 * different entries. In particular,
6587 * a single entry pointing to an object
6588 * can be split by a call to vm_inherit,
6589 * which, combined with task_create, can
6590 * result in the different entries
6591 * having different needs_copy values.)
6592 * The shadowed flag in the object allows
6593 * us to detect this case. The problem
6594 * with this case is that if this object
6595 * has or will have shadows, then we
6596 * must not perform an asymmetric copy
6597 * of this object, since such a copy
6598 * allows the object to be changed, which
6599 * will break the previous symmetrical
6600 * copies (which rely upon the object
6601 * not changing). In a sense, the shadowed
6602 * flag says "don't change this object".
6603 * We fix this by creating a shadow
6604 * object for this object, and sharing
6605 * that. This works because we are free
6606 * to change the shadow object (and thus
6607 * to use an asymmetric copy strategy);
6608 * this is also semantically correct,
6609 * since this object is temporary, and
6610 * therefore a copy of the object is
6611 * as good as the object itself. (This
6612 * is not true for permanent objects,
6613 * since the pager needs to see changes,
6614 * which won't happen if the changes
6615 * are made to a copy.)
6617 * The third case is when the object
6618 * to be shared has parts sticking
6619 * outside of the entry we're working
6620 * with, and thus may in the future
6621 * be subject to a symmetrical copy.
6622 * (This is a preemptive version of
6626 assert(!(object
->shadowed
&& old_entry
->is_shared
));
6627 vm_object_shadow(&old_entry
->object
.vm_object
,
6629 (vm_map_size_t
) (old_entry
->vme_end
-
6630 old_entry
->vme_start
));
6633 * If we're making a shadow for other than
6634 * copy on write reasons, then we have
6635 * to remove write permission.
6638 if (!old_entry
->needs_copy
&&
6639 (old_entry
->protection
& VM_PROT_WRITE
)) {
6640 if(old_map
->mapped
) {
6641 vm_object_pmap_protect(
6642 old_entry
->object
.vm_object
,
6644 (old_entry
->vme_end
-
6645 old_entry
->vme_start
),
6647 old_entry
->vme_start
,
6648 old_entry
->protection
& ~VM_PROT_WRITE
);
6650 pmap_protect(old_map
->pmap
,
6651 old_entry
->vme_start
,
6653 old_entry
->protection
& ~VM_PROT_WRITE
);
6657 old_entry
->needs_copy
= FALSE
;
6658 object
= old_entry
->object
.vm_object
;
6662 * If object was using a symmetric copy strategy,
6663 * change its copy strategy to the default
6664 * asymmetric copy strategy, which is copy_delay
6665 * in the non-norma case and copy_call in the
6666 * norma case. Bump the reference count for the
6670 if(old_entry
->is_sub_map
) {
6671 vm_map_lock(old_entry
->object
.sub_map
);
6672 vm_map_reference(old_entry
->object
.sub_map
);
6673 vm_map_unlock(old_entry
->object
.sub_map
);
6675 vm_object_lock(object
);
6676 object
->ref_count
++;
6677 vm_object_res_reference(object
);
6678 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
6679 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
6681 vm_object_unlock(object
);
6685 * Clone the entry, using object ref from above.
6686 * Mark both entries as shared.
6689 new_entry
= vm_map_entry_create(new_map
);
6690 vm_map_entry_copy(new_entry
, old_entry
);
6691 old_entry
->is_shared
= TRUE
;
6692 new_entry
->is_shared
= TRUE
;
6695 * Insert the entry into the new map -- we
6696 * know we're inserting at the end of the new
6700 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
6703 * Update the physical map
6706 if (old_entry
->is_sub_map
) {
6707 /* Bill Angell pmap support goes here */
6709 pmap_copy(new_map
->pmap
, old_map
->pmap
, new_entry
->vme_start
,
6710 old_entry
->vme_end
- old_entry
->vme_start
,
6711 old_entry
->vme_start
);
6718 vm_map_entry_t
*old_entry_p
,
6721 vm_map_entry_t old_entry
= *old_entry_p
;
6722 vm_map_size_t entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
6723 vm_map_offset_t start
= old_entry
->vme_start
;
6725 vm_map_entry_t last
= vm_map_last_entry(new_map
);
6727 vm_map_unlock(old_map
);
6729 * Use maxprot version of copyin because we
6730 * care about whether this memory can ever
6731 * be accessed, not just whether it's accessible
6734 if (vm_map_copyin_maxprot(old_map
, start
, entry_size
, FALSE
, ©
)
6737 * The map might have changed while it
6738 * was unlocked, check it again. Skip
6739 * any blank space or permanently
6740 * unreadable region.
6742 vm_map_lock(old_map
);
6743 if (!vm_map_lookup_entry(old_map
, start
, &last
) ||
6744 (last
->max_protection
& VM_PROT_READ
) == VM_PROT_NONE
) {
6745 last
= last
->vme_next
;
6747 *old_entry_p
= last
;
6750 * XXX For some error returns, want to
6751 * XXX skip to the next element. Note
6752 * that INVALID_ADDRESS and
6753 * PROTECTION_FAILURE are handled above.
6760 * Insert the copy into the new map
6763 vm_map_copy_insert(new_map
, last
, copy
);
6766 * Pick up the traversal at the end of
6767 * the copied region.
6770 vm_map_lock(old_map
);
6771 start
+= entry_size
;
6772 if (! vm_map_lookup_entry(old_map
, start
, &last
)) {
6773 last
= last
->vme_next
;
6775 vm_map_clip_start(old_map
, last
, start
);
6777 *old_entry_p
= last
;
6785 * Create and return a new map based on the old
6786 * map, according to the inheritance values on the
6787 * regions in that map.
6789 * The source map must not be locked.
6795 pmap_t new_pmap
= pmap_create((vm_map_size_t
) 0);
6797 vm_map_entry_t old_entry
;
6798 vm_map_size_t new_size
= 0, entry_size
;
6799 vm_map_entry_t new_entry
;
6800 boolean_t src_needs_copy
;
6801 boolean_t new_entry_needs_copy
;
6803 vm_map_reference_swap(old_map
);
6804 vm_map_lock(old_map
);
6806 new_map
= vm_map_create(new_pmap
,
6807 old_map
->min_offset
,
6808 old_map
->max_offset
,
6809 old_map
->hdr
.entries_pageable
);
6812 old_entry
= vm_map_first_entry(old_map
);
6813 old_entry
!= vm_map_to_entry(old_map
);
6816 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
6818 switch (old_entry
->inheritance
) {
6819 case VM_INHERIT_NONE
:
6822 case VM_INHERIT_SHARE
:
6823 vm_map_fork_share(old_map
, old_entry
, new_map
);
6824 new_size
+= entry_size
;
6827 case VM_INHERIT_COPY
:
6830 * Inline the copy_quickly case;
6831 * upon failure, fall back on call
6832 * to vm_map_fork_copy.
6835 if(old_entry
->is_sub_map
)
6837 if ((old_entry
->wired_count
!= 0) ||
6838 ((old_entry
->object
.vm_object
!= NULL
) &&
6839 (old_entry
->object
.vm_object
->true_share
))) {
6840 goto slow_vm_map_fork_copy
;
6843 new_entry
= vm_map_entry_create(new_map
);
6844 vm_map_entry_copy(new_entry
, old_entry
);
6845 /* clear address space specifics */
6846 new_entry
->use_pmap
= FALSE
;
6848 if (! vm_object_copy_quickly(
6849 &new_entry
->object
.vm_object
,
6851 (old_entry
->vme_end
-
6852 old_entry
->vme_start
),
6854 &new_entry_needs_copy
)) {
6855 vm_map_entry_dispose(new_map
, new_entry
);
6856 goto slow_vm_map_fork_copy
;
6860 * Handle copy-on-write obligations
6863 if (src_needs_copy
&& !old_entry
->needs_copy
) {
6864 vm_object_pmap_protect(
6865 old_entry
->object
.vm_object
,
6867 (old_entry
->vme_end
-
6868 old_entry
->vme_start
),
6869 ((old_entry
->is_shared
6873 old_entry
->vme_start
,
6874 old_entry
->protection
& ~VM_PROT_WRITE
);
6876 old_entry
->needs_copy
= TRUE
;
6878 new_entry
->needs_copy
= new_entry_needs_copy
;
6881 * Insert the entry at the end
6885 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
),
6887 new_size
+= entry_size
;
6890 slow_vm_map_fork_copy
:
6891 if (vm_map_fork_copy(old_map
, &old_entry
, new_map
)) {
6892 new_size
+= entry_size
;
6896 old_entry
= old_entry
->vme_next
;
6899 new_map
->size
= new_size
;
6900 vm_map_unlock(old_map
);
6901 vm_map_deallocate(old_map
);
6908 * vm_map_lookup_locked:
6910 * Finds the VM object, offset, and
6911 * protection for a given virtual address in the
6912 * specified map, assuming a page fault of the
6915 * Returns the (object, offset, protection) for
6916 * this address, whether it is wired down, and whether
6917 * this map has the only reference to the data in question.
6918 * In order to later verify this lookup, a "version"
6921 * The map MUST be locked by the caller and WILL be
6922 * locked on exit. In order to guarantee the
6923 * existence of the returned object, it is returned
6926 * If a lookup is requested with "write protection"
6927 * specified, the map may be changed to perform virtual
6928 * copying operations, although the data referenced will
6932 vm_map_lookup_locked(
6933 vm_map_t
*var_map
, /* IN/OUT */
6934 vm_map_offset_t vaddr
,
6935 vm_prot_t fault_type
,
6936 vm_map_version_t
*out_version
, /* OUT */
6937 vm_object_t
*object
, /* OUT */
6938 vm_object_offset_t
*offset
, /* OUT */
6939 vm_prot_t
*out_prot
, /* OUT */
6940 boolean_t
*wired
, /* OUT */
6941 int *behavior
, /* OUT */
6942 vm_map_offset_t
*lo_offset
, /* OUT */
6943 vm_map_offset_t
*hi_offset
, /* OUT */
6946 vm_map_entry_t entry
;
6947 register vm_map_t map
= *var_map
;
6948 vm_map_t old_map
= *var_map
;
6949 vm_map_t cow_sub_map_parent
= VM_MAP_NULL
;
6950 vm_map_offset_t cow_parent_vaddr
= 0;
6951 vm_map_offset_t old_start
= 0;
6952 vm_map_offset_t old_end
= 0;
6953 register vm_prot_t prot
;
6959 * If the map has an interesting hint, try it before calling
6960 * full blown lookup routine.
6963 mutex_lock(&map
->s_lock
);
6965 mutex_unlock(&map
->s_lock
);
6967 if ((entry
== vm_map_to_entry(map
)) ||
6968 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
6969 vm_map_entry_t tmp_entry
;
6972 * Entry was either not a valid hint, or the vaddr
6973 * was not contained in the entry, so do a full lookup.
6975 if (!vm_map_lookup_entry(map
, vaddr
, &tmp_entry
)) {
6976 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
))
6977 vm_map_unlock(cow_sub_map_parent
);
6978 if((*real_map
!= map
)
6979 && (*real_map
!= cow_sub_map_parent
))
6980 vm_map_unlock(*real_map
);
6981 return KERN_INVALID_ADDRESS
;
6986 if(map
== old_map
) {
6987 old_start
= entry
->vme_start
;
6988 old_end
= entry
->vme_end
;
6992 * Handle submaps. Drop lock on upper map, submap is
6997 if (entry
->is_sub_map
) {
6998 vm_map_offset_t local_vaddr
;
6999 vm_map_offset_t end_delta
;
7000 vm_map_offset_t start_delta
;
7001 vm_map_entry_t submap_entry
;
7002 boolean_t mapped_needs_copy
=FALSE
;
7004 local_vaddr
= vaddr
;
7006 if ((!entry
->needs_copy
) && (entry
->use_pmap
)) {
7007 /* if real_map equals map we unlock below */
7008 if ((*real_map
!= map
) &&
7009 (*real_map
!= cow_sub_map_parent
))
7010 vm_map_unlock(*real_map
);
7011 *real_map
= entry
->object
.sub_map
;
7014 if(entry
->needs_copy
) {
7015 if (!mapped_needs_copy
) {
7016 if (vm_map_lock_read_to_write(map
)) {
7017 vm_map_lock_read(map
);
7018 if(*real_map
== entry
->object
.sub_map
)
7022 vm_map_lock_read(entry
->object
.sub_map
);
7023 cow_sub_map_parent
= map
;
7024 /* reset base to map before cow object */
7025 /* this is the map which will accept */
7026 /* the new cow object */
7027 old_start
= entry
->vme_start
;
7028 old_end
= entry
->vme_end
;
7029 cow_parent_vaddr
= vaddr
;
7030 mapped_needs_copy
= TRUE
;
7032 vm_map_lock_read(entry
->object
.sub_map
);
7033 if((cow_sub_map_parent
!= map
) &&
7038 vm_map_lock_read(entry
->object
.sub_map
);
7039 /* leave map locked if it is a target */
7040 /* cow sub_map above otherwise, just */
7041 /* follow the maps down to the object */
7042 /* here we unlock knowing we are not */
7043 /* revisiting the map. */
7044 if((*real_map
!= map
) && (map
!= cow_sub_map_parent
))
7045 vm_map_unlock_read(map
);
7048 *var_map
= map
= entry
->object
.sub_map
;
7050 /* calculate the offset in the submap for vaddr */
7051 local_vaddr
= (local_vaddr
- entry
->vme_start
) + entry
->offset
;
7054 if(!vm_map_lookup_entry(map
, local_vaddr
, &submap_entry
)) {
7055 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
)){
7056 vm_map_unlock(cow_sub_map_parent
);
7058 if((*real_map
!= map
)
7059 && (*real_map
!= cow_sub_map_parent
)) {
7060 vm_map_unlock(*real_map
);
7063 return KERN_INVALID_ADDRESS
;
7065 /* find the attenuated shadow of the underlying object */
7066 /* on our target map */
7068 /* in english the submap object may extend beyond the */
7069 /* region mapped by the entry or, may only fill a portion */
7070 /* of it. For our purposes, we only care if the object */
7071 /* doesn't fill. In this case the area which will */
7072 /* ultimately be clipped in the top map will only need */
7073 /* to be as big as the portion of the underlying entry */
7074 /* which is mapped */
7075 start_delta
= submap_entry
->vme_start
> entry
->offset
?
7076 submap_entry
->vme_start
- entry
->offset
: 0;
7079 (entry
->offset
+ start_delta
+ (old_end
- old_start
)) <=
7080 submap_entry
->vme_end
?
7081 0 : (entry
->offset
+
7082 (old_end
- old_start
))
7083 - submap_entry
->vme_end
;
7085 old_start
+= start_delta
;
7086 old_end
-= end_delta
;
7088 if(submap_entry
->is_sub_map
) {
7089 entry
= submap_entry
;
7090 vaddr
= local_vaddr
;
7091 goto submap_recurse
;
7094 if(((fault_type
& VM_PROT_WRITE
) && cow_sub_map_parent
)) {
7096 vm_object_t copy_object
;
7097 vm_map_offset_t local_start
;
7098 vm_map_offset_t local_end
;
7099 boolean_t copied_slowly
= FALSE
;
7101 if (vm_map_lock_read_to_write(map
)) {
7102 vm_map_lock_read(map
);
7103 old_start
-= start_delta
;
7104 old_end
+= end_delta
;
7109 if (submap_entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7110 submap_entry
->object
.vm_object
=
7113 (submap_entry
->vme_end
7114 - submap_entry
->vme_start
));
7115 submap_entry
->offset
= 0;
7117 local_start
= local_vaddr
-
7118 (cow_parent_vaddr
- old_start
);
7119 local_end
= local_vaddr
+
7120 (old_end
- cow_parent_vaddr
);
7121 vm_map_clip_start(map
, submap_entry
, local_start
);
7122 vm_map_clip_end(map
, submap_entry
, local_end
);
7124 /* This is the COW case, lets connect */
7125 /* an entry in our space to the underlying */
7126 /* object in the submap, bypassing the */
7130 if(submap_entry
->wired_count
!= 0) {
7132 submap_entry
->object
.vm_object
);
7133 vm_object_copy_slowly(
7134 submap_entry
->object
.vm_object
,
7135 submap_entry
->offset
,
7136 submap_entry
->vme_end
-
7137 submap_entry
->vme_start
,
7140 copied_slowly
= TRUE
;
7143 /* set up shadow object */
7144 copy_object
= submap_entry
->object
.vm_object
;
7145 vm_object_reference(copy_object
);
7146 submap_entry
->object
.vm_object
->shadowed
= TRUE
;
7147 submap_entry
->needs_copy
= TRUE
;
7148 vm_object_pmap_protect(
7149 submap_entry
->object
.vm_object
,
7150 submap_entry
->offset
,
7151 submap_entry
->vme_end
-
7152 submap_entry
->vme_start
,
7153 (submap_entry
->is_shared
7155 PMAP_NULL
: map
->pmap
,
7156 submap_entry
->vme_start
,
7157 submap_entry
->protection
&
7162 /* This works diffently than the */
7163 /* normal submap case. We go back */
7164 /* to the parent of the cow map and*/
7165 /* clip out the target portion of */
7166 /* the sub_map, substituting the */
7167 /* new copy object, */
7170 local_start
= old_start
;
7171 local_end
= old_end
;
7172 map
= cow_sub_map_parent
;
7173 *var_map
= cow_sub_map_parent
;
7174 vaddr
= cow_parent_vaddr
;
7175 cow_sub_map_parent
= NULL
;
7177 if(!vm_map_lookup_entry(map
,
7179 vm_object_deallocate(
7181 vm_map_lock_write_to_read(map
);
7182 return KERN_INVALID_ADDRESS
;
7185 /* clip out the portion of space */
7186 /* mapped by the sub map which */
7187 /* corresponds to the underlying */
7189 vm_map_clip_start(map
, entry
, local_start
);
7190 vm_map_clip_end(map
, entry
, local_end
);
7193 /* substitute copy object for */
7194 /* shared map entry */
7195 vm_map_deallocate(entry
->object
.sub_map
);
7196 entry
->is_sub_map
= FALSE
;
7197 entry
->object
.vm_object
= copy_object
;
7199 entry
->protection
|= VM_PROT_WRITE
;
7200 entry
->max_protection
|= VM_PROT_WRITE
;
7203 entry
->needs_copy
= FALSE
;
7204 entry
->is_shared
= FALSE
;
7206 entry
->offset
= submap_entry
->offset
;
7207 entry
->needs_copy
= TRUE
;
7208 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7209 entry
->inheritance
= VM_INHERIT_COPY
;
7211 entry
->is_shared
= TRUE
;
7213 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7214 entry
->inheritance
= VM_INHERIT_COPY
;
7216 vm_map_lock_write_to_read(map
);
7218 if((cow_sub_map_parent
)
7219 && (cow_sub_map_parent
!= *real_map
)
7220 && (cow_sub_map_parent
!= map
)) {
7221 vm_map_unlock(cow_sub_map_parent
);
7223 entry
= submap_entry
;
7224 vaddr
= local_vaddr
;
7229 * Check whether this task is allowed to have
7233 prot
= entry
->protection
;
7234 if ((fault_type
& (prot
)) != fault_type
) {
7235 if (*real_map
!= map
) {
7236 vm_map_unlock(*real_map
);
7239 return KERN_PROTECTION_FAILURE
;
7243 * If this page is not pageable, we have to get
7244 * it for all possible accesses.
7247 *wired
= (entry
->wired_count
!= 0);
7249 prot
= fault_type
= entry
->protection
;
7252 * If the entry was copy-on-write, we either ...
7255 if (entry
->needs_copy
) {
7257 * If we want to write the page, we may as well
7258 * handle that now since we've got the map locked.
7260 * If we don't need to write the page, we just
7261 * demote the permissions allowed.
7264 if ((fault_type
& VM_PROT_WRITE
) || *wired
) {
7266 * Make a new object, and place it in the
7267 * object chain. Note that no new references
7268 * have appeared -- one just moved from the
7269 * map to the new object.
7272 if (vm_map_lock_read_to_write(map
)) {
7273 vm_map_lock_read(map
);
7276 vm_object_shadow(&entry
->object
.vm_object
,
7278 (vm_map_size_t
) (entry
->vme_end
-
7281 entry
->object
.vm_object
->shadowed
= TRUE
;
7282 entry
->needs_copy
= FALSE
;
7283 vm_map_lock_write_to_read(map
);
7287 * We're attempting to read a copy-on-write
7288 * page -- don't allow writes.
7291 prot
&= (~VM_PROT_WRITE
);
7296 * Create an object if necessary.
7298 if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7300 if (vm_map_lock_read_to_write(map
)) {
7301 vm_map_lock_read(map
);
7305 entry
->object
.vm_object
= vm_object_allocate(
7306 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
7308 vm_map_lock_write_to_read(map
);
7312 * Return the object/offset from this entry. If the entry
7313 * was copy-on-write or empty, it has been fixed up. Also
7314 * return the protection.
7317 *offset
= (vaddr
- entry
->vme_start
) + entry
->offset
;
7318 *object
= entry
->object
.vm_object
;
7320 *behavior
= entry
->behavior
;
7321 *lo_offset
= entry
->offset
;
7322 *hi_offset
= (entry
->vme_end
- entry
->vme_start
) + entry
->offset
;
7325 * Lock the object to prevent it from disappearing
7328 vm_object_lock(*object
);
7331 * Save the version number
7334 out_version
->main_timestamp
= map
->timestamp
;
7336 return KERN_SUCCESS
;
7343 * Verifies that the map in question has not changed
7344 * since the given version. If successful, the map
7345 * will not change until vm_map_verify_done() is called.
7349 register vm_map_t map
,
7350 register vm_map_version_t
*version
) /* REF */
7354 vm_map_lock_read(map
);
7355 result
= (map
->timestamp
== version
->main_timestamp
);
7358 vm_map_unlock_read(map
);
7364 * vm_map_verify_done:
7366 * Releases locks acquired by a vm_map_verify.
7368 * This is now a macro in vm/vm_map.h. It does a
7369 * vm_map_unlock_read on the map.
7374 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
7375 * Goes away after regular vm_region_recurse function migrates to
7377 * vm_region_recurse: A form of vm_region which follows the
7378 * submaps in a target map
7383 vm_map_region_recurse_64(
7385 vm_map_offset_t
*address
, /* IN/OUT */
7386 vm_map_size_t
*size
, /* OUT */
7387 natural_t
*nesting_depth
, /* IN/OUT */
7388 vm_region_submap_info_64_t submap_info
, /* IN/OUT */
7389 mach_msg_type_number_t
*count
) /* IN/OUT */
7391 vm_region_extended_info_data_t extended
;
7392 vm_map_entry_t tmp_entry
;
7393 vm_map_offset_t user_address
;
7394 unsigned int user_max_depth
;
7397 * "curr_entry" is the VM map entry preceding or including the
7398 * address we're looking for.
7399 * "curr_map" is the map or sub-map containing "curr_entry".
7400 * "curr_offset" is the cumulated offset of "curr_map" in the
7401 * target task's address space.
7402 * "curr_depth" is the depth of "curr_map" in the chain of
7404 * "curr_max_offset" is the maximum offset we should take into
7405 * account in the current map. It may be smaller than the current
7406 * map's "max_offset" because we might not have mapped it all in
7407 * the upper level map.
7409 vm_map_entry_t curr_entry
;
7410 vm_map_offset_t curr_offset
;
7412 unsigned int curr_depth
;
7413 vm_map_offset_t curr_max_offset
;
7416 * "next_" is the same as "curr_" but for the VM region immediately
7417 * after the address we're looking for. We need to keep track of this
7418 * too because we want to return info about that region if the
7419 * address we're looking for is not mapped.
7421 vm_map_entry_t next_entry
;
7422 vm_map_offset_t next_offset
;
7424 unsigned int next_depth
;
7425 vm_map_offset_t next_max_offset
;
7427 if (map
== VM_MAP_NULL
) {
7428 /* no address space to work on */
7429 return KERN_INVALID_ARGUMENT
;
7432 if (*count
< VM_REGION_SUBMAP_INFO_COUNT_64
) {
7433 /* "info" structure is not big enough and would overflow */
7434 return KERN_INVALID_ARGUMENT
;
7437 *count
= VM_REGION_SUBMAP_INFO_COUNT_64
;
7439 user_address
= *address
;
7440 user_max_depth
= *nesting_depth
;
7446 curr_max_offset
= curr_map
->max_offset
;
7452 next_max_offset
= curr_max_offset
;
7455 vm_map_lock_read(curr_map
);
7459 if (vm_map_lookup_entry(curr_map
,
7460 user_address
- curr_offset
,
7462 /* tmp_entry contains the address we're looking for */
7463 curr_entry
= tmp_entry
;
7466 * The address is not mapped. "tmp_entry" is the
7467 * map entry preceding the address. We want the next
7468 * one, if it exists.
7470 curr_entry
= tmp_entry
->vme_next
;
7471 if (curr_entry
== vm_map_to_entry(curr_map
) ||
7472 curr_entry
->vme_start
>= curr_max_offset
) {
7473 /* no next entry at this level: stop looking */
7475 vm_map_unlock_read(curr_map
);
7481 curr_max_offset
= 0;
7487 * Is the next entry at this level closer to the address (or
7488 * deeper in the submap chain) than the one we had
7491 tmp_entry
= curr_entry
->vme_next
;
7492 if (tmp_entry
== vm_map_to_entry(curr_map
)) {
7493 /* no next entry at this level */
7494 } else if (tmp_entry
->vme_start
>= curr_max_offset
) {
7496 * tmp_entry is beyond the scope of what we mapped of
7497 * this submap in the upper level: ignore it.
7499 } else if ((next_entry
== NULL
) ||
7500 (tmp_entry
->vme_start
+ curr_offset
<=
7501 next_entry
->vme_start
+ next_offset
)) {
7503 * We didn't have a "next_entry" or this one is
7504 * closer to the address we're looking for:
7505 * use this "tmp_entry" as the new "next_entry".
7507 if (next_entry
!= NULL
) {
7508 /* unlock the last "next_map" */
7509 if (next_map
!= curr_map
&& not_in_kdp
) {
7510 vm_map_unlock_read(next_map
);
7513 next_entry
= tmp_entry
;
7514 next_map
= curr_map
;
7515 next_offset
= curr_offset
;
7516 next_depth
= curr_depth
;
7517 next_max_offset
= curr_max_offset
;
7520 if (!curr_entry
->is_sub_map
||
7521 curr_depth
>= user_max_depth
) {
7523 * We hit a leaf map or we reached the maximum depth
7524 * we could, so stop looking. Keep the current map
7531 * Get down to the next submap level.
7535 * Lock the next level and unlock the current level,
7536 * unless we need to keep it locked to access the "next_entry"
7540 vm_map_lock_read(curr_entry
->object
.sub_map
);
7542 if (curr_map
== next_map
) {
7543 /* keep "next_map" locked in case we need it */
7545 /* release this map */
7546 vm_map_unlock_read(curr_map
);
7550 * Adjust the offset. "curr_entry" maps the submap
7551 * at relative address "curr_entry->vme_start" in the
7552 * curr_map but skips the first "curr_entry->offset"
7553 * bytes of the submap.
7554 * "curr_offset" always represents the offset of a virtual
7555 * address in the curr_map relative to the absolute address
7556 * space (i.e. the top-level VM map).
7559 (curr_entry
->vme_start
- curr_entry
->offset
);
7560 /* switch to the submap */
7561 curr_map
= curr_entry
->object
.sub_map
;
7564 * "curr_max_offset" allows us to keep track of the
7565 * portion of the submap that is actually mapped at this level:
7566 * the rest of that submap is irrelevant to us, since it's not
7568 * The relevant portion of the map starts at
7569 * "curr_entry->offset" up to the size of "curr_entry".
7572 curr_entry
->vme_end
- curr_entry
->vme_start
+
7577 if (curr_entry
== NULL
) {
7578 /* no VM region contains the address... */
7579 if (next_entry
== NULL
) {
7580 /* ... and no VM region follows it either */
7581 return KERN_INVALID_ADDRESS
;
7583 /* ... gather info about the next VM region */
7584 curr_entry
= next_entry
;
7585 curr_map
= next_map
; /* still locked ... */
7586 curr_offset
= next_offset
;
7587 curr_depth
= next_depth
;
7588 curr_max_offset
= next_max_offset
;
7590 /* we won't need "next_entry" after all */
7591 if (next_entry
!= NULL
) {
7592 /* release "next_map" */
7593 if (next_map
!= curr_map
&& not_in_kdp
) {
7594 vm_map_unlock_read(next_map
);
7602 next_max_offset
= 0;
7604 *nesting_depth
= curr_depth
;
7605 *size
= curr_entry
->vme_end
- curr_entry
->vme_start
;
7606 *address
= curr_entry
->vme_start
+ curr_offset
;
7608 submap_info
->user_tag
= curr_entry
->alias
;
7609 submap_info
->offset
= curr_entry
->offset
;
7610 submap_info
->protection
= curr_entry
->protection
;
7611 submap_info
->inheritance
= curr_entry
->inheritance
;
7612 submap_info
->max_protection
= curr_entry
->max_protection
;
7613 submap_info
->behavior
= curr_entry
->behavior
;
7614 submap_info
->user_wired_count
= curr_entry
->user_wired_count
;
7615 submap_info
->is_submap
= curr_entry
->is_sub_map
;
7616 submap_info
->object_id
= (uint32_t) curr_entry
->object
.vm_object
;
7618 extended
.pages_resident
= 0;
7619 extended
.pages_swapped_out
= 0;
7620 extended
.pages_shared_now_private
= 0;
7621 extended
.pages_dirtied
= 0;
7622 extended
.external_pager
= 0;
7623 extended
.shadow_depth
= 0;
7626 if (!curr_entry
->is_sub_map
) {
7627 vm_map_region_walk(curr_map
,
7628 curr_entry
->vme_start
,
7631 (curr_entry
->vme_end
-
7632 curr_entry
->vme_start
),
7634 submap_info
->share_mode
= extended
.share_mode
;
7635 if (extended
.external_pager
&&
7636 extended
.ref_count
== 2 &&
7637 extended
.share_mode
== SM_SHARED
) {
7638 submap_info
->share_mode
= SM_PRIVATE
;
7640 submap_info
->ref_count
= extended
.ref_count
;
7642 if (curr_entry
->use_pmap
) {
7643 submap_info
->share_mode
= SM_TRUESHARED
;
7645 submap_info
->share_mode
= SM_PRIVATE
;
7647 submap_info
->ref_count
=
7648 curr_entry
->object
.sub_map
->ref_count
;
7652 submap_info
->pages_resident
= extended
.pages_resident
;
7653 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
7654 submap_info
->pages_shared_now_private
=
7655 extended
.pages_shared_now_private
;
7656 submap_info
->pages_dirtied
= extended
.pages_dirtied
;
7657 submap_info
->external_pager
= extended
.external_pager
;
7658 submap_info
->shadow_depth
= extended
.shadow_depth
;
7661 vm_map_unlock_read(curr_map
);
7664 return KERN_SUCCESS
;
7670 * User call to obtain information about a region in
7671 * a task's address map. Currently, only one flavor is
7674 * XXX The reserved and behavior fields cannot be filled
7675 * in until the vm merge from the IK is completed, and
7676 * vm_reserve is implemented.
7682 vm_map_offset_t
*address
, /* IN/OUT */
7683 vm_map_size_t
*size
, /* OUT */
7684 vm_region_flavor_t flavor
, /* IN */
7685 vm_region_info_t info
, /* OUT */
7686 mach_msg_type_number_t
*count
, /* IN/OUT */
7687 mach_port_t
*object_name
) /* OUT */
7689 vm_map_entry_t tmp_entry
;
7690 vm_map_entry_t entry
;
7691 vm_map_offset_t start
;
7693 if (map
== VM_MAP_NULL
)
7694 return(KERN_INVALID_ARGUMENT
);
7698 case VM_REGION_BASIC_INFO
:
7699 /* legacy for old 32-bit objects info */
7701 vm_region_basic_info_t basic
;
7703 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
7704 return(KERN_INVALID_ARGUMENT
);
7706 basic
= (vm_region_basic_info_t
) info
;
7707 *count
= VM_REGION_BASIC_INFO_COUNT
;
7709 vm_map_lock_read(map
);
7712 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7713 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7714 vm_map_unlock_read(map
);
7715 return(KERN_INVALID_ADDRESS
);
7721 start
= entry
->vme_start
;
7723 basic
->offset
= (uint32_t)entry
->offset
;
7724 basic
->protection
= entry
->protection
;
7725 basic
->inheritance
= entry
->inheritance
;
7726 basic
->max_protection
= entry
->max_protection
;
7727 basic
->behavior
= entry
->behavior
;
7728 basic
->user_wired_count
= entry
->user_wired_count
;
7729 basic
->reserved
= entry
->is_sub_map
;
7731 *size
= (entry
->vme_end
- start
);
7733 if (object_name
) *object_name
= IP_NULL
;
7734 if (entry
->is_sub_map
) {
7735 basic
->shared
= FALSE
;
7737 basic
->shared
= entry
->is_shared
;
7740 vm_map_unlock_read(map
);
7741 return(KERN_SUCCESS
);
7744 case VM_REGION_BASIC_INFO_64
:
7746 vm_region_basic_info_64_t basic
;
7748 if (*count
< VM_REGION_BASIC_INFO_COUNT_64
)
7749 return(KERN_INVALID_ARGUMENT
);
7751 basic
= (vm_region_basic_info_64_t
) info
;
7752 *count
= VM_REGION_BASIC_INFO_COUNT_64
;
7754 vm_map_lock_read(map
);
7757 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7758 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7759 vm_map_unlock_read(map
);
7760 return(KERN_INVALID_ADDRESS
);
7766 start
= entry
->vme_start
;
7768 basic
->offset
= entry
->offset
;
7769 basic
->protection
= entry
->protection
;
7770 basic
->inheritance
= entry
->inheritance
;
7771 basic
->max_protection
= entry
->max_protection
;
7772 basic
->behavior
= entry
->behavior
;
7773 basic
->user_wired_count
= entry
->user_wired_count
;
7774 basic
->reserved
= entry
->is_sub_map
;
7776 *size
= (entry
->vme_end
- start
);
7778 if (object_name
) *object_name
= IP_NULL
;
7779 if (entry
->is_sub_map
) {
7780 basic
->shared
= FALSE
;
7782 basic
->shared
= entry
->is_shared
;
7785 vm_map_unlock_read(map
);
7786 return(KERN_SUCCESS
);
7788 case VM_REGION_EXTENDED_INFO
:
7790 vm_region_extended_info_t extended
;
7792 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
7793 return(KERN_INVALID_ARGUMENT
);
7795 extended
= (vm_region_extended_info_t
) info
;
7796 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
7798 vm_map_lock_read(map
);
7801 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7802 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7803 vm_map_unlock_read(map
);
7804 return(KERN_INVALID_ADDRESS
);
7809 start
= entry
->vme_start
;
7811 extended
->protection
= entry
->protection
;
7812 extended
->user_tag
= entry
->alias
;
7813 extended
->pages_resident
= 0;
7814 extended
->pages_swapped_out
= 0;
7815 extended
->pages_shared_now_private
= 0;
7816 extended
->pages_dirtied
= 0;
7817 extended
->external_pager
= 0;
7818 extended
->shadow_depth
= 0;
7820 vm_map_region_walk(map
, start
, entry
, entry
->offset
, entry
->vme_end
- start
, extended
);
7822 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
7823 extended
->share_mode
= SM_PRIVATE
;
7826 *object_name
= IP_NULL
;
7828 *size
= (entry
->vme_end
- start
);
7830 vm_map_unlock_read(map
);
7831 return(KERN_SUCCESS
);
7833 case VM_REGION_TOP_INFO
:
7835 vm_region_top_info_t top
;
7837 if (*count
< VM_REGION_TOP_INFO_COUNT
)
7838 return(KERN_INVALID_ARGUMENT
);
7840 top
= (vm_region_top_info_t
) info
;
7841 *count
= VM_REGION_TOP_INFO_COUNT
;
7843 vm_map_lock_read(map
);
7846 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7847 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7848 vm_map_unlock_read(map
);
7849 return(KERN_INVALID_ADDRESS
);
7855 start
= entry
->vme_start
;
7857 top
->private_pages_resident
= 0;
7858 top
->shared_pages_resident
= 0;
7860 vm_map_region_top_walk(entry
, top
);
7863 *object_name
= IP_NULL
;
7865 *size
= (entry
->vme_end
- start
);
7867 vm_map_unlock_read(map
);
7868 return(KERN_SUCCESS
);
7871 return(KERN_INVALID_ARGUMENT
);
7876 vm_map_region_top_walk(
7877 vm_map_entry_t entry
,
7878 vm_region_top_info_t top
)
7880 register struct vm_object
*obj
, *tmp_obj
;
7881 register int ref_count
;
7883 if (entry
->object
.vm_object
== 0 || entry
->is_sub_map
) {
7884 top
->share_mode
= SM_EMPTY
;
7890 obj
= entry
->object
.vm_object
;
7892 vm_object_lock(obj
);
7894 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
7899 top
->private_pages_resident
= obj
->resident_page_count
;
7901 top
->shared_pages_resident
= obj
->resident_page_count
;
7902 top
->ref_count
= ref_count
;
7903 top
->share_mode
= SM_COW
;
7905 while ((tmp_obj
= obj
->shadow
)) {
7906 vm_object_lock(tmp_obj
);
7907 vm_object_unlock(obj
);
7910 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
7913 top
->shared_pages_resident
+= obj
->resident_page_count
;
7914 top
->ref_count
+= ref_count
- 1;
7917 if (entry
->needs_copy
) {
7918 top
->share_mode
= SM_COW
;
7919 top
->shared_pages_resident
= obj
->resident_page_count
;
7921 if (ref_count
== 1 ||
7922 (ref_count
== 2 && !(obj
->pager_trusted
) && !(obj
->internal
))) {
7923 top
->share_mode
= SM_PRIVATE
;
7924 top
->private_pages_resident
= obj
->resident_page_count
;
7926 top
->share_mode
= SM_SHARED
;
7927 top
->shared_pages_resident
= obj
->resident_page_count
;
7930 top
->ref_count
= ref_count
;
7932 top
->obj_id
= (int)obj
;
7934 vm_object_unlock(obj
);
7942 vm_map_entry_t entry
,
7943 vm_object_offset_t offset
,
7944 vm_object_size_t range
,
7945 vm_region_extended_info_t extended
)
7947 register struct vm_object
*obj
, *tmp_obj
;
7948 register vm_map_offset_t last_offset
;
7950 register int ref_count
;
7951 struct vm_object
*shadow_object
;
7954 if ((entry
->object
.vm_object
== 0) ||
7955 (entry
->is_sub_map
) ||
7956 (entry
->object
.vm_object
->phys_contiguous
)) {
7957 extended
->share_mode
= SM_EMPTY
;
7958 extended
->ref_count
= 0;
7962 obj
= entry
->object
.vm_object
;
7964 vm_object_lock(obj
);
7966 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
7969 for (last_offset
= offset
+ range
; offset
< last_offset
; offset
+= PAGE_SIZE_64
, va
+= PAGE_SIZE
)
7970 vm_map_region_look_for_page(map
, va
, obj
, offset
, ref_count
, 0, extended
);
7972 shadow_object
= obj
->shadow
;
7974 if (shadow_object
!= VM_OBJECT_NULL
) {
7975 vm_object_lock(shadow_object
);
7977 shadow_object
!= VM_OBJECT_NULL
;
7979 vm_object_t next_shadow
;
7981 next_shadow
= shadow_object
->shadow
;
7983 vm_object_lock(next_shadow
);
7985 vm_object_unlock(shadow_object
);
7986 shadow_object
= next_shadow
;
7989 extended
->shadow_depth
= shadow_depth
;
7991 if (extended
->shadow_depth
|| entry
->needs_copy
)
7992 extended
->share_mode
= SM_COW
;
7995 extended
->share_mode
= SM_PRIVATE
;
7997 if (obj
->true_share
)
7998 extended
->share_mode
= SM_TRUESHARED
;
8000 extended
->share_mode
= SM_SHARED
;
8003 extended
->ref_count
= ref_count
- extended
->shadow_depth
;
8005 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
8006 if ((tmp_obj
= obj
->shadow
) == 0)
8008 vm_object_lock(tmp_obj
);
8009 vm_object_unlock(obj
);
8011 if ((ref_count
= tmp_obj
->ref_count
) > 1 && tmp_obj
->paging_in_progress
)
8014 extended
->ref_count
+= ref_count
;
8017 vm_object_unlock(obj
);
8019 if (extended
->share_mode
== SM_SHARED
) {
8020 register vm_map_entry_t cur
;
8021 register vm_map_entry_t last
;
8024 obj
= entry
->object
.vm_object
;
8025 last
= vm_map_to_entry(map
);
8028 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
8030 for (cur
= vm_map_first_entry(map
); cur
!= last
; cur
= cur
->vme_next
)
8031 my_refs
+= vm_map_region_count_obj_refs(cur
, obj
);
8033 if (my_refs
== ref_count
)
8034 extended
->share_mode
= SM_PRIVATE_ALIASED
;
8035 else if (my_refs
> 1)
8036 extended
->share_mode
= SM_SHARED_ALIASED
;
8042 /* object is locked on entry and locked on return */
8046 vm_map_region_look_for_page(
8047 __unused vm_map_t map
,
8048 __unused vm_map_offset_t va
,
8050 vm_object_offset_t offset
,
8053 vm_region_extended_info_t extended
)
8055 register vm_page_t p
;
8056 register vm_object_t shadow
;
8057 register int ref_count
;
8058 vm_object_t caller_object
;
8060 shadow
= object
->shadow
;
8061 caller_object
= object
;
8066 if ( !(object
->pager_trusted
) && !(object
->internal
))
8067 extended
->external_pager
= 1;
8069 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
8070 if (shadow
&& (max_refcnt
== 1))
8071 extended
->pages_shared_now_private
++;
8073 if (!p
->fictitious
&&
8074 (p
->dirty
|| pmap_is_modified(p
->phys_page
)))
8075 extended
->pages_dirtied
++;
8077 extended
->pages_resident
++;
8079 if(object
!= caller_object
)
8080 vm_object_unlock(object
);
8084 if (object
->existence_map
) {
8085 if (vm_external_state_get(object
->existence_map
, offset
) == VM_EXTERNAL_STATE_EXISTS
) {
8087 extended
->pages_swapped_out
++;
8089 if(object
!= caller_object
)
8090 vm_object_unlock(object
);
8096 vm_object_lock(shadow
);
8098 if ((ref_count
= shadow
->ref_count
) > 1 && shadow
->paging_in_progress
)
8101 if (++depth
> extended
->shadow_depth
)
8102 extended
->shadow_depth
= depth
;
8104 if (ref_count
> max_refcnt
)
8105 max_refcnt
= ref_count
;
8107 if(object
!= caller_object
)
8108 vm_object_unlock(object
);
8110 offset
= offset
+ object
->shadow_offset
;
8112 shadow
= object
->shadow
;
8115 if(object
!= caller_object
)
8116 vm_object_unlock(object
);
8122 vm_map_region_count_obj_refs(
8123 vm_map_entry_t entry
,
8126 register int ref_count
;
8127 register vm_object_t chk_obj
;
8128 register vm_object_t tmp_obj
;
8130 if (entry
->object
.vm_object
== 0)
8133 if (entry
->is_sub_map
)
8138 chk_obj
= entry
->object
.vm_object
;
8139 vm_object_lock(chk_obj
);
8142 if (chk_obj
== object
)
8144 tmp_obj
= chk_obj
->shadow
;
8146 vm_object_lock(tmp_obj
);
8147 vm_object_unlock(chk_obj
);
8157 * Routine: vm_map_simplify
8160 * Attempt to simplify the map representation in
8161 * the vicinity of the given starting address.
8163 * This routine is intended primarily to keep the
8164 * kernel maps more compact -- they generally don't
8165 * benefit from the "expand a map entry" technology
8166 * at allocation time because the adjacent entry
8167 * is often wired down.
8170 vm_map_simplify_entry(
8172 vm_map_entry_t this_entry
)
8174 vm_map_entry_t prev_entry
;
8176 counter(c_vm_map_simplify_entry_called
++);
8178 prev_entry
= this_entry
->vme_prev
;
8180 if ((this_entry
!= vm_map_to_entry(map
)) &&
8181 (prev_entry
!= vm_map_to_entry(map
)) &&
8183 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
8185 (prev_entry
->is_sub_map
== FALSE
) &&
8186 (this_entry
->is_sub_map
== FALSE
) &&
8188 (prev_entry
->object
.vm_object
== this_entry
->object
.vm_object
) &&
8189 ((prev_entry
->offset
+ (prev_entry
->vme_end
-
8190 prev_entry
->vme_start
))
8191 == this_entry
->offset
) &&
8193 (prev_entry
->inheritance
== this_entry
->inheritance
) &&
8194 (prev_entry
->protection
== this_entry
->protection
) &&
8195 (prev_entry
->max_protection
== this_entry
->max_protection
) &&
8196 (prev_entry
->behavior
== this_entry
->behavior
) &&
8197 (prev_entry
->alias
== this_entry
->alias
) &&
8198 (prev_entry
->wired_count
== this_entry
->wired_count
) &&
8199 (prev_entry
->user_wired_count
== this_entry
->user_wired_count
) &&
8201 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
8203 (prev_entry
->use_pmap
== FALSE
) &&
8204 (this_entry
->use_pmap
== FALSE
) &&
8205 (prev_entry
->in_transition
== FALSE
) &&
8206 (this_entry
->in_transition
== FALSE
) &&
8207 (prev_entry
->needs_wakeup
== FALSE
) &&
8208 (this_entry
->needs_wakeup
== FALSE
) &&
8209 (prev_entry
->is_shared
== FALSE
) &&
8210 (this_entry
->is_shared
== FALSE
)
8212 _vm_map_entry_unlink(&map
->hdr
, prev_entry
);
8213 this_entry
->vme_start
= prev_entry
->vme_start
;
8214 this_entry
->offset
= prev_entry
->offset
;
8215 vm_object_deallocate(prev_entry
->object
.vm_object
);
8216 vm_map_entry_dispose(map
, prev_entry
);
8217 SAVE_HINT(map
, this_entry
);
8218 counter(c_vm_map_simplified
++);
8225 vm_map_offset_t start
)
8227 vm_map_entry_t this_entry
;
8230 if (vm_map_lookup_entry(map
, start
, &this_entry
)) {
8231 vm_map_simplify_entry(map
, this_entry
);
8232 vm_map_simplify_entry(map
, this_entry
->vme_next
);
8234 counter(c_vm_map_simplify_called
++);
8239 vm_map_simplify_range(
8241 vm_map_offset_t start
,
8242 vm_map_offset_t end
)
8244 vm_map_entry_t entry
;
8247 * The map should be locked (for "write") by the caller.
8251 /* invalid address range */
8255 if (!vm_map_lookup_entry(map
, start
, &entry
)) {
8256 /* "start" is not mapped and "entry" ends before "start" */
8257 if (entry
== vm_map_to_entry(map
)) {
8258 /* start with first entry in the map */
8259 entry
= vm_map_first_entry(map
);
8261 /* start with next entry */
8262 entry
= entry
->vme_next
;
8266 while (entry
!= vm_map_to_entry(map
) &&
8267 entry
->vme_start
<= end
) {
8268 /* try and coalesce "entry" with its previous entry */
8269 vm_map_simplify_entry(map
, entry
);
8270 entry
= entry
->vme_next
;
8276 * Routine: vm_map_machine_attribute
8278 * Provide machine-specific attributes to mappings,
8279 * such as cachability etc. for machines that provide
8280 * them. NUMA architectures and machines with big/strange
8281 * caches will use this.
8283 * Responsibilities for locking and checking are handled here,
8284 * everything else in the pmap module. If any non-volatile
8285 * information must be kept, the pmap module should handle
8286 * it itself. [This assumes that attributes do not
8287 * need to be inherited, which seems ok to me]
8290 vm_map_machine_attribute(
8292 vm_map_offset_t start
,
8293 vm_map_offset_t end
,
8294 vm_machine_attribute_t attribute
,
8295 vm_machine_attribute_val_t
* value
) /* IN/OUT */
8298 vm_map_size_t sync_size
;
8299 vm_map_entry_t entry
;
8301 if (start
< vm_map_min(map
) || end
> vm_map_max(map
))
8302 return KERN_INVALID_ADDRESS
;
8304 /* Figure how much memory we need to flush (in page increments) */
8305 sync_size
= end
- start
;
8309 if (attribute
!= MATTR_CACHE
) {
8310 /* If we don't have to find physical addresses, we */
8311 /* don't have to do an explicit traversal here. */
8312 ret
= pmap_attribute(map
->pmap
, start
, end
-start
,
8318 ret
= KERN_SUCCESS
; /* Assume it all worked */
8321 if (vm_map_lookup_entry(map
, start
, &entry
)) {
8322 vm_map_size_t sub_size
;
8323 if((entry
->vme_end
- start
) > sync_size
) {
8324 sub_size
= sync_size
;
8327 sub_size
= entry
->vme_end
- start
;
8328 sync_size
-= sub_size
;
8330 if(entry
->is_sub_map
) {
8331 vm_map_offset_t sub_start
;
8332 vm_map_offset_t sub_end
;
8334 sub_start
= (start
- entry
->vme_start
)
8336 sub_end
= sub_start
+ sub_size
;
8337 vm_map_machine_attribute(
8338 entry
->object
.sub_map
,
8343 if(entry
->object
.vm_object
) {
8346 vm_object_t base_object
;
8347 vm_object_t last_object
;
8348 vm_object_offset_t offset
;
8349 vm_object_offset_t base_offset
;
8350 vm_map_size_t range
;
8352 offset
= (start
- entry
->vme_start
)
8354 base_offset
= offset
;
8355 object
= entry
->object
.vm_object
;
8356 base_object
= object
;
8359 vm_object_lock(object
);
8365 if (m
&& !m
->fictitious
) {
8367 pmap_attribute_cache_sync(
8372 } else if (object
->shadow
) {
8373 offset
= offset
+ object
->shadow_offset
;
8374 last_object
= object
;
8375 object
= object
->shadow
;
8376 vm_object_lock(last_object
->shadow
);
8377 vm_object_unlock(last_object
);
8382 if (base_object
!= object
) {
8383 vm_object_unlock(object
);
8384 vm_object_lock(base_object
);
8385 object
= base_object
;
8387 /* Bump to the next page */
8388 base_offset
+= PAGE_SIZE
;
8389 offset
= base_offset
;
8391 vm_object_unlock(object
);
8397 return KERN_FAILURE
;
8408 * vm_map_behavior_set:
8410 * Sets the paging reference behavior of the specified address
8411 * range in the target map. Paging reference behavior affects
8412 * how pagein operations resulting from faults on the map will be
8416 vm_map_behavior_set(
8418 vm_map_offset_t start
,
8419 vm_map_offset_t end
,
8420 vm_behavior_t new_behavior
)
8422 register vm_map_entry_t entry
;
8423 vm_map_entry_t temp_entry
;
8426 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
8427 (integer_t
)map
, start
, end
, new_behavior
, 0);
8429 switch (new_behavior
) {
8430 case VM_BEHAVIOR_DEFAULT
:
8431 case VM_BEHAVIOR_RANDOM
:
8432 case VM_BEHAVIOR_SEQUENTIAL
:
8433 case VM_BEHAVIOR_RSEQNTL
:
8435 case VM_BEHAVIOR_WILLNEED
:
8436 case VM_BEHAVIOR_DONTNEED
:
8437 new_behavior
= VM_BEHAVIOR_DEFAULT
;
8440 return(KERN_INVALID_ARGUMENT
);
8446 * The entire address range must be valid for the map.
8447 * Note that vm_map_range_check() does a
8448 * vm_map_lookup_entry() internally and returns the
8449 * entry containing the start of the address range if
8450 * the entire range is valid.
8452 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
8454 vm_map_clip_start(map
, entry
, start
);
8458 return(KERN_INVALID_ADDRESS
);
8461 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
8462 vm_map_clip_end(map
, entry
, end
);
8464 entry
->behavior
= new_behavior
;
8466 entry
= entry
->vme_next
;
8470 return(KERN_SUCCESS
);
8474 #include <mach_kdb.h>
8476 #include <ddb/db_output.h>
8477 #include <vm/vm_print.h>
8479 #define printf db_printf
8482 * Forward declarations for internal functions.
8484 extern void vm_map_links_print(
8485 struct vm_map_links
*links
);
8487 extern void vm_map_header_print(
8488 struct vm_map_header
*header
);
8490 extern void vm_map_entry_print(
8491 vm_map_entry_t entry
);
8493 extern void vm_follow_entry(
8494 vm_map_entry_t entry
);
8496 extern void vm_follow_map(
8500 * vm_map_links_print: [ debug ]
8504 struct vm_map_links
*links
)
8506 iprintf("prev = %08X next = %08X start = %016llX end = %016llX\n",
8509 (unsigned long long)links
->start
,
8510 (unsigned long long)links
->end
);
8514 * vm_map_header_print: [ debug ]
8517 vm_map_header_print(
8518 struct vm_map_header
*header
)
8520 vm_map_links_print(&header
->links
);
8521 iprintf("nentries = %08X, %sentries_pageable\n",
8523 (header
->entries_pageable
? "" : "!"));
8527 * vm_follow_entry: [ debug ]
8531 vm_map_entry_t entry
)
8535 iprintf("map entry %08X\n", entry
);
8539 shadows
= vm_follow_object(entry
->object
.vm_object
);
8540 iprintf("Total objects : %d\n",shadows
);
8546 * vm_map_entry_print: [ debug ]
8550 register vm_map_entry_t entry
)
8552 static const char *inheritance_name
[4] =
8553 { "share", "copy", "none", "?"};
8554 static const char *behavior_name
[4] =
8555 { "dflt", "rand", "seqtl", "rseqntl" };
8557 iprintf("map entry %08X - prev = %08X next = %08X\n", entry
, entry
->vme_prev
, entry
->vme_next
);
8561 vm_map_links_print(&entry
->links
);
8563 iprintf("start = %016llX end = %016llX - prot=%x/%x/%s\n",
8564 (unsigned long long)entry
->vme_start
,
8565 (unsigned long long)entry
->vme_end
,
8567 entry
->max_protection
,
8568 inheritance_name
[(entry
->inheritance
& 0x3)]);
8570 iprintf("behavior = %s, wired_count = %d, user_wired_count = %d\n",
8571 behavior_name
[(entry
->behavior
& 0x3)],
8573 entry
->user_wired_count
);
8574 iprintf("%sin_transition, %sneeds_wakeup\n",
8575 (entry
->in_transition
? "" : "!"),
8576 (entry
->needs_wakeup
? "" : "!"));
8578 if (entry
->is_sub_map
) {
8579 iprintf("submap = %08X - offset = %016llX\n",
8580 entry
->object
.sub_map
,
8581 (unsigned long long)entry
->offset
);
8583 iprintf("object = %08X offset = %016llX - ",
8584 entry
->object
.vm_object
,
8585 (unsigned long long)entry
->offset
);
8586 printf("%sis_shared, %sneeds_copy\n",
8587 (entry
->is_shared
? "" : "!"),
8588 (entry
->needs_copy
? "" : "!"));
8595 * vm_follow_map: [ debug ]
8601 register vm_map_entry_t entry
;
8603 iprintf("task map %08X\n", map
);
8607 for (entry
= vm_map_first_entry(map
);
8608 entry
&& entry
!= vm_map_to_entry(map
);
8609 entry
= entry
->vme_next
) {
8610 vm_follow_entry(entry
);
8617 * vm_map_print: [ debug ]
8623 register vm_map_entry_t entry
;
8627 #endif /* TASK_SWAPPER */
8629 map
= (vm_map_t
)(long)
8630 inmap
; /* Make sure we have the right type */
8632 iprintf("task map %08X\n", map
);
8636 vm_map_header_print(&map
->hdr
);
8638 iprintf("pmap = %08X size = %08X ref = %d hint = %08X first_free = %08X\n",
8645 iprintf("%swait_for_space, %swiring_required, timestamp = %d\n",
8646 (map
->wait_for_space
? "" : "!"),
8647 (map
->wiring_required
? "" : "!"),
8651 switch (map
->sw_state
) {
8662 iprintf("res = %d, sw_state = %s\n", map
->res_count
, swstate
);
8663 #endif /* TASK_SWAPPER */
8665 for (entry
= vm_map_first_entry(map
);
8666 entry
&& entry
!= vm_map_to_entry(map
);
8667 entry
= entry
->vme_next
) {
8668 vm_map_entry_print(entry
);
8675 * Routine: vm_map_copy_print
8677 * Pretty-print a copy object for ddb.
8685 vm_map_entry_t entry
;
8687 copy
= (vm_map_copy_t
)(long)
8688 incopy
; /* Make sure we have the right type */
8690 printf("copy object 0x%x\n", copy
);
8694 iprintf("type=%d", copy
->type
);
8695 switch (copy
->type
) {
8696 case VM_MAP_COPY_ENTRY_LIST
:
8697 printf("[entry_list]");
8700 case VM_MAP_COPY_OBJECT
:
8704 case VM_MAP_COPY_KERNEL_BUFFER
:
8705 printf("[kernel_buffer]");
8709 printf("[bad type]");
8712 printf(", offset=0x%llx", (unsigned long long)copy
->offset
);
8713 printf(", size=0x%x\n", copy
->size
);
8715 switch (copy
->type
) {
8716 case VM_MAP_COPY_ENTRY_LIST
:
8717 vm_map_header_print(©
->cpy_hdr
);
8718 for (entry
= vm_map_copy_first_entry(copy
);
8719 entry
&& entry
!= vm_map_copy_to_entry(copy
);
8720 entry
= entry
->vme_next
) {
8721 vm_map_entry_print(entry
);
8725 case VM_MAP_COPY_OBJECT
:
8726 iprintf("object=0x%x\n", copy
->cpy_object
);
8729 case VM_MAP_COPY_KERNEL_BUFFER
:
8730 iprintf("kernel buffer=0x%x", copy
->cpy_kdata
);
8731 printf(", kalloc_size=0x%x\n", copy
->cpy_kalloc_size
);
8740 * db_vm_map_total_size(map) [ debug ]
8742 * return the total virtual size (in bytes) of the map
8745 db_vm_map_total_size(
8748 vm_map_entry_t entry
;
8749 vm_map_size_t total
;
8752 map
= (vm_map_t
)(long)
8753 inmap
; /* Make sure we have the right type */
8756 for (entry
= vm_map_first_entry(map
);
8757 entry
!= vm_map_to_entry(map
);
8758 entry
= entry
->vme_next
) {
8759 total
+= entry
->vme_end
- entry
->vme_start
;
8765 #endif /* MACH_KDB */
8768 * Routine: vm_map_entry_insert
8770 * Descritpion: This routine inserts a new vm_entry in a locked map.
8773 vm_map_entry_insert(
8775 vm_map_entry_t insp_entry
,
8776 vm_map_offset_t start
,
8777 vm_map_offset_t end
,
8779 vm_object_offset_t offset
,
8780 boolean_t needs_copy
,
8781 boolean_t is_shared
,
8782 boolean_t in_transition
,
8783 vm_prot_t cur_protection
,
8784 vm_prot_t max_protection
,
8785 vm_behavior_t behavior
,
8786 vm_inherit_t inheritance
,
8787 unsigned wired_count
)
8789 vm_map_entry_t new_entry
;
8791 assert(insp_entry
!= (vm_map_entry_t
)0);
8793 new_entry
= vm_map_entry_create(map
);
8795 new_entry
->vme_start
= start
;
8796 new_entry
->vme_end
= end
;
8797 assert(page_aligned(new_entry
->vme_start
));
8798 assert(page_aligned(new_entry
->vme_end
));
8800 new_entry
->object
.vm_object
= object
;
8801 new_entry
->offset
= offset
;
8802 new_entry
->is_shared
= is_shared
;
8803 new_entry
->is_sub_map
= FALSE
;
8804 new_entry
->needs_copy
= needs_copy
;
8805 new_entry
->in_transition
= in_transition
;
8806 new_entry
->needs_wakeup
= FALSE
;
8807 new_entry
->inheritance
= inheritance
;
8808 new_entry
->protection
= cur_protection
;
8809 new_entry
->max_protection
= max_protection
;
8810 new_entry
->behavior
= behavior
;
8811 new_entry
->wired_count
= wired_count
;
8812 new_entry
->user_wired_count
= 0;
8813 new_entry
->use_pmap
= FALSE
;
8816 * Insert the new entry into the list.
8819 vm_map_entry_link(map
, insp_entry
, new_entry
);
8820 map
->size
+= end
- start
;
8823 * Update the free space hint and the lookup hint.
8826 SAVE_HINT(map
, new_entry
);
8831 * Routine: vm_map_remap_extract
8833 * Descritpion: This routine returns a vm_entry list from a map.
8835 static kern_return_t
8836 vm_map_remap_extract(
8838 vm_map_offset_t addr
,
8841 struct vm_map_header
*map_header
,
8842 vm_prot_t
*cur_protection
,
8843 vm_prot_t
*max_protection
,
8844 /* What, no behavior? */
8845 vm_inherit_t inheritance
,
8848 kern_return_t result
;
8849 vm_map_size_t mapped_size
;
8850 vm_map_size_t tmp_size
;
8851 vm_map_entry_t src_entry
; /* result of last map lookup */
8852 vm_map_entry_t new_entry
;
8853 vm_object_offset_t offset
;
8854 vm_map_offset_t map_address
;
8855 vm_map_offset_t src_start
; /* start of entry to map */
8856 vm_map_offset_t src_end
; /* end of region to be mapped */
8858 vm_map_version_t version
;
8859 boolean_t src_needs_copy
;
8860 boolean_t new_entry_needs_copy
;
8862 assert(map
!= VM_MAP_NULL
);
8863 assert(size
!= 0 && size
== vm_map_round_page(size
));
8864 assert(inheritance
== VM_INHERIT_NONE
||
8865 inheritance
== VM_INHERIT_COPY
||
8866 inheritance
== VM_INHERIT_SHARE
);
8869 * Compute start and end of region.
8871 src_start
= vm_map_trunc_page(addr
);
8872 src_end
= vm_map_round_page(src_start
+ size
);
8875 * Initialize map_header.
8877 map_header
->links
.next
= (struct vm_map_entry
*)&map_header
->links
;
8878 map_header
->links
.prev
= (struct vm_map_entry
*)&map_header
->links
;
8879 map_header
->nentries
= 0;
8880 map_header
->entries_pageable
= pageable
;
8882 *cur_protection
= VM_PROT_ALL
;
8883 *max_protection
= VM_PROT_ALL
;
8887 result
= KERN_SUCCESS
;
8890 * The specified source virtual space might correspond to
8891 * multiple map entries, need to loop on them.
8894 while (mapped_size
!= size
) {
8895 vm_map_size_t entry_size
;
8898 * Find the beginning of the region.
8900 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
8901 result
= KERN_INVALID_ADDRESS
;
8905 if (src_start
< src_entry
->vme_start
||
8906 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
8907 result
= KERN_INVALID_ADDRESS
;
8911 if(src_entry
->is_sub_map
) {
8912 result
= KERN_INVALID_ADDRESS
;
8916 tmp_size
= size
- mapped_size
;
8917 if (src_end
> src_entry
->vme_end
)
8918 tmp_size
-= (src_end
- src_entry
->vme_end
);
8920 entry_size
= (vm_map_size_t
)(src_entry
->vme_end
-
8921 src_entry
->vme_start
);
8923 if(src_entry
->is_sub_map
) {
8924 vm_map_reference(src_entry
->object
.sub_map
);
8925 object
= VM_OBJECT_NULL
;
8927 object
= src_entry
->object
.vm_object
;
8929 if (object
== VM_OBJECT_NULL
) {
8930 object
= vm_object_allocate(entry_size
);
8931 src_entry
->offset
= 0;
8932 src_entry
->object
.vm_object
= object
;
8933 } else if (object
->copy_strategy
!=
8934 MEMORY_OBJECT_COPY_SYMMETRIC
) {
8936 * We are already using an asymmetric
8937 * copy, and therefore we already have
8940 assert(!src_entry
->needs_copy
);
8941 } else if (src_entry
->needs_copy
|| object
->shadowed
||
8942 (object
->internal
&& !object
->true_share
&&
8943 !src_entry
->is_shared
&&
8944 object
->size
> entry_size
)) {
8946 vm_object_shadow(&src_entry
->object
.vm_object
,
8950 if (!src_entry
->needs_copy
&&
8951 (src_entry
->protection
& VM_PROT_WRITE
)) {
8953 vm_object_pmap_protect(
8954 src_entry
->object
.vm_object
,
8958 src_entry
->vme_start
,
8959 src_entry
->protection
&
8962 pmap_protect(vm_map_pmap(map
),
8963 src_entry
->vme_start
,
8965 src_entry
->protection
&
8970 object
= src_entry
->object
.vm_object
;
8971 src_entry
->needs_copy
= FALSE
;
8975 vm_object_lock(object
);
8976 object
->ref_count
++; /* object ref. for new entry */
8977 VM_OBJ_RES_INCR(object
);
8978 if (object
->copy_strategy
==
8979 MEMORY_OBJECT_COPY_SYMMETRIC
) {
8980 object
->copy_strategy
=
8981 MEMORY_OBJECT_COPY_DELAY
;
8983 vm_object_unlock(object
);
8986 offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
8988 new_entry
= _vm_map_entry_create(map_header
);
8989 vm_map_entry_copy(new_entry
, src_entry
);
8990 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
8992 new_entry
->vme_start
= map_address
;
8993 new_entry
->vme_end
= map_address
+ tmp_size
;
8994 new_entry
->inheritance
= inheritance
;
8995 new_entry
->offset
= offset
;
8998 * The new region has to be copied now if required.
9002 src_entry
->is_shared
= TRUE
;
9003 new_entry
->is_shared
= TRUE
;
9004 if (!(new_entry
->is_sub_map
))
9005 new_entry
->needs_copy
= FALSE
;
9007 } else if (src_entry
->is_sub_map
) {
9008 /* make this a COW sub_map if not already */
9009 new_entry
->needs_copy
= TRUE
;
9010 object
= VM_OBJECT_NULL
;
9011 } else if (src_entry
->wired_count
== 0 &&
9012 vm_object_copy_quickly(&new_entry
->object
.vm_object
,
9014 (new_entry
->vme_end
-
9015 new_entry
->vme_start
),
9017 &new_entry_needs_copy
)) {
9019 new_entry
->needs_copy
= new_entry_needs_copy
;
9020 new_entry
->is_shared
= FALSE
;
9023 * Handle copy_on_write semantics.
9025 if (src_needs_copy
&& !src_entry
->needs_copy
) {
9026 vm_object_pmap_protect(object
,
9029 ((src_entry
->is_shared
9031 PMAP_NULL
: map
->pmap
),
9032 src_entry
->vme_start
,
9033 src_entry
->protection
&
9036 src_entry
->needs_copy
= TRUE
;
9039 * Throw away the old object reference of the new entry.
9041 vm_object_deallocate(object
);
9044 new_entry
->is_shared
= FALSE
;
9047 * The map can be safely unlocked since we
9048 * already hold a reference on the object.
9050 * Record the timestamp of the map for later
9051 * verification, and unlock the map.
9053 version
.main_timestamp
= map
->timestamp
;
9054 vm_map_unlock(map
); /* Increments timestamp once! */
9059 if (src_entry
->wired_count
> 0) {
9060 vm_object_lock(object
);
9061 result
= vm_object_copy_slowly(
9066 &new_entry
->object
.vm_object
);
9068 new_entry
->offset
= 0;
9069 new_entry
->needs_copy
= FALSE
;
9071 result
= vm_object_copy_strategically(
9075 &new_entry
->object
.vm_object
,
9077 &new_entry_needs_copy
);
9079 new_entry
->needs_copy
= new_entry_needs_copy
;
9083 * Throw away the old object reference of the new entry.
9085 vm_object_deallocate(object
);
9087 if (result
!= KERN_SUCCESS
&&
9088 result
!= KERN_MEMORY_RESTART_COPY
) {
9089 _vm_map_entry_dispose(map_header
, new_entry
);
9094 * Verify that the map has not substantially
9095 * changed while the copy was being made.
9099 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
9101 * Simple version comparison failed.
9103 * Retry the lookup and verify that the
9104 * same object/offset are still present.
9106 vm_object_deallocate(new_entry
->
9108 _vm_map_entry_dispose(map_header
, new_entry
);
9109 if (result
== KERN_MEMORY_RESTART_COPY
)
9110 result
= KERN_SUCCESS
;
9114 if (result
== KERN_MEMORY_RESTART_COPY
) {
9115 vm_object_reference(object
);
9120 _vm_map_entry_link(map_header
,
9121 map_header
->links
.prev
, new_entry
);
9123 *cur_protection
&= src_entry
->protection
;
9124 *max_protection
&= src_entry
->max_protection
;
9126 map_address
+= tmp_size
;
9127 mapped_size
+= tmp_size
;
9128 src_start
+= tmp_size
;
9133 if (result
!= KERN_SUCCESS
) {
9135 * Free all allocated elements.
9137 for (src_entry
= map_header
->links
.next
;
9138 src_entry
!= (struct vm_map_entry
*)&map_header
->links
;
9139 src_entry
= new_entry
) {
9140 new_entry
= src_entry
->vme_next
;
9141 _vm_map_entry_unlink(map_header
, src_entry
);
9142 vm_object_deallocate(src_entry
->object
.vm_object
);
9143 _vm_map_entry_dispose(map_header
, src_entry
);
9152 * Map portion of a task's address space.
9153 * Mapped region must not overlap more than
9154 * one vm memory object. Protections and
9155 * inheritance attributes remain the same
9156 * as in the original task and are out parameters.
9157 * Source and Target task can be identical
9158 * Other attributes are identical as for vm_map()
9162 vm_map_t target_map
,
9163 vm_map_address_t
*address
,
9165 vm_map_offset_t mask
,
9168 vm_map_offset_t memory_address
,
9170 vm_prot_t
*cur_protection
,
9171 vm_prot_t
*max_protection
,
9172 vm_inherit_t inheritance
)
9174 kern_return_t result
;
9175 vm_map_entry_t entry
;
9176 vm_map_entry_t insp_entry
;
9177 vm_map_entry_t new_entry
;
9178 struct vm_map_header map_header
;
9180 if (target_map
== VM_MAP_NULL
)
9181 return KERN_INVALID_ARGUMENT
;
9183 switch (inheritance
) {
9184 case VM_INHERIT_NONE
:
9185 case VM_INHERIT_COPY
:
9186 case VM_INHERIT_SHARE
:
9187 if (size
!= 0 && src_map
!= VM_MAP_NULL
)
9191 return KERN_INVALID_ARGUMENT
;
9194 size
= vm_map_round_page(size
);
9196 result
= vm_map_remap_extract(src_map
, memory_address
,
9197 size
, copy
, &map_header
,
9204 if (result
!= KERN_SUCCESS
) {
9209 * Allocate/check a range of free virtual address
9210 * space for the target
9212 *address
= vm_map_trunc_page(*address
);
9213 vm_map_lock(target_map
);
9214 result
= vm_map_remap_range_allocate(target_map
, address
, size
,
9215 mask
, anywhere
, &insp_entry
);
9217 for (entry
= map_header
.links
.next
;
9218 entry
!= (struct vm_map_entry
*)&map_header
.links
;
9219 entry
= new_entry
) {
9220 new_entry
= entry
->vme_next
;
9221 _vm_map_entry_unlink(&map_header
, entry
);
9222 if (result
== KERN_SUCCESS
) {
9223 entry
->vme_start
+= *address
;
9224 entry
->vme_end
+= *address
;
9225 vm_map_entry_link(target_map
, insp_entry
, entry
);
9228 if (!entry
->is_sub_map
) {
9229 vm_object_deallocate(entry
->object
.vm_object
);
9231 vm_map_deallocate(entry
->object
.sub_map
);
9233 _vm_map_entry_dispose(&map_header
, entry
);
9237 if (result
== KERN_SUCCESS
) {
9238 target_map
->size
+= size
;
9239 SAVE_HINT(target_map
, insp_entry
);
9241 vm_map_unlock(target_map
);
9243 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
9244 result
= vm_map_wire(target_map
, *address
,
9245 *address
+ size
, *cur_protection
, TRUE
);
9250 * Routine: vm_map_remap_range_allocate
9253 * Allocate a range in the specified virtual address map.
9254 * returns the address and the map entry just before the allocated
9257 * Map must be locked.
9260 static kern_return_t
9261 vm_map_remap_range_allocate(
9263 vm_map_address_t
*address
, /* IN/OUT */
9265 vm_map_offset_t mask
,
9267 vm_map_entry_t
*map_entry
) /* OUT */
9269 register vm_map_entry_t entry
;
9270 register vm_map_offset_t start
;
9271 register vm_map_offset_t end
;
9280 * Calculate the first possible address.
9283 if (start
< map
->min_offset
)
9284 start
= map
->min_offset
;
9285 if (start
> map
->max_offset
)
9286 return(KERN_NO_SPACE
);
9289 * Look for the first possible address;
9290 * if there's already something at this
9291 * address, we have to start after it.
9294 assert(first_free_is_valid(map
));
9295 if (start
== map
->min_offset
) {
9296 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
9297 start
= entry
->vme_end
;
9299 vm_map_entry_t tmp_entry
;
9300 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
9301 start
= tmp_entry
->vme_end
;
9306 * In any case, the "entry" always precedes
9307 * the proposed new region throughout the
9312 register vm_map_entry_t next
;
9315 * Find the end of the proposed new region.
9316 * Be sure we didn't go beyond the end, or
9317 * wrap around the address.
9320 end
= ((start
+ mask
) & ~mask
);
9322 return(KERN_NO_SPACE
);
9326 if ((end
> map
->max_offset
) || (end
< start
)) {
9327 if (map
->wait_for_space
) {
9328 if (size
<= (map
->max_offset
-
9330 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
9332 thread_block(THREAD_CONTINUE_NULL
);
9338 return(KERN_NO_SPACE
);
9342 * If there are no more entries, we must win.
9345 next
= entry
->vme_next
;
9346 if (next
== vm_map_to_entry(map
))
9350 * If there is another entry, it must be
9351 * after the end of the potential new region.
9354 if (next
->vme_start
>= end
)
9358 * Didn't fit -- move to the next entry.
9362 start
= entry
->vme_end
;
9366 vm_map_entry_t temp_entry
;
9370 * the address doesn't itself violate
9371 * the mask requirement.
9374 if ((start
& mask
) != 0)
9375 return(KERN_NO_SPACE
);
9379 * ... the address is within bounds
9384 if ((start
< map
->min_offset
) ||
9385 (end
> map
->max_offset
) ||
9387 return(KERN_INVALID_ADDRESS
);
9391 * ... the starting address isn't allocated
9394 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
9395 return(KERN_NO_SPACE
);
9400 * ... the next region doesn't overlap the
9404 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
9405 (entry
->vme_next
->vme_start
< end
))
9406 return(KERN_NO_SPACE
);
9409 return(KERN_SUCCESS
);
9415 * Set the address map for the current thread to the specified map
9423 thread_t thread
= current_thread();
9424 vm_map_t oldmap
= thread
->map
;
9426 mp_disable_preemption();
9427 mycpu
= cpu_number();
9430 * Deactivate the current map and activate the requested map
9432 PMAP_SWITCH_USER(thread
, map
, mycpu
);
9434 mp_enable_preemption();
9440 * Routine: vm_map_write_user
9443 * Copy out data from a kernel space into space in the
9444 * destination map. The space must already exist in the
9446 * NOTE: This routine should only be called by threads
9447 * which can block on a page fault. i.e. kernel mode user
9455 vm_map_address_t dst_addr
,
9458 kern_return_t kr
= KERN_SUCCESS
;
9460 if(current_map() == map
) {
9461 if (copyout(src_p
, dst_addr
, size
)) {
9462 kr
= KERN_INVALID_ADDRESS
;
9467 /* take on the identity of the target map while doing */
9470 vm_map_reference(map
);
9471 oldmap
= vm_map_switch(map
);
9472 if (copyout(src_p
, dst_addr
, size
)) {
9473 kr
= KERN_INVALID_ADDRESS
;
9475 vm_map_switch(oldmap
);
9476 vm_map_deallocate(map
);
9482 * Routine: vm_map_read_user
9485 * Copy in data from a user space source map into the
9486 * kernel map. The space must already exist in the
9488 * NOTE: This routine should only be called by threads
9489 * which can block on a page fault. i.e. kernel mode user
9496 vm_map_address_t src_addr
,
9500 kern_return_t kr
= KERN_SUCCESS
;
9502 if(current_map() == map
) {
9503 if (copyin(src_addr
, dst_p
, size
)) {
9504 kr
= KERN_INVALID_ADDRESS
;
9509 /* take on the identity of the target map while doing */
9512 vm_map_reference(map
);
9513 oldmap
= vm_map_switch(map
);
9514 if (copyin(src_addr
, dst_p
, size
)) {
9515 kr
= KERN_INVALID_ADDRESS
;
9517 vm_map_switch(oldmap
);
9518 vm_map_deallocate(map
);
9525 * vm_map_check_protection:
9527 * Assert that the target map allows the specified
9528 * privilege on the entire address region given.
9529 * The entire region must be allocated.
9531 boolean_t
vm_map_check_protection(map
, start
, end
, protection
)
9532 register vm_map_t map
;
9533 register vm_map_offset_t start
;
9534 register vm_map_offset_t end
;
9535 register vm_prot_t protection
;
9537 register vm_map_entry_t entry
;
9538 vm_map_entry_t tmp_entry
;
9542 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
9548 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
9555 while (start
< end
) {
9556 if (entry
== vm_map_to_entry(map
)) {
9565 if (start
< entry
->vme_start
) {
9571 * Check protection associated with entry.
9574 if ((entry
->protection
& protection
) != protection
) {
9579 /* go to next entry */
9581 start
= entry
->vme_end
;
9582 entry
= entry
->vme_next
;
9589 vm_map_purgable_control(
9591 vm_map_offset_t address
,
9592 vm_purgable_t control
,
9595 vm_map_entry_t entry
;
9600 * Vet all the input parameters and current type and state of the
9601 * underlaying object. Return with an error if anything is amiss.
9603 if (map
== VM_MAP_NULL
)
9604 return(KERN_INVALID_ARGUMENT
);
9606 if (control
!= VM_PURGABLE_SET_STATE
&&
9607 control
!= VM_PURGABLE_GET_STATE
)
9608 return(KERN_INVALID_ARGUMENT
);
9610 if (control
== VM_PURGABLE_SET_STATE
&&
9611 (*state
< VM_PURGABLE_STATE_MIN
||
9612 *state
> VM_PURGABLE_STATE_MAX
))
9613 return(KERN_INVALID_ARGUMENT
);
9617 if (!vm_map_lookup_entry(map
, address
, &entry
) || entry
->is_sub_map
) {
9620 * Must pass a valid non-submap address.
9623 return(KERN_INVALID_ADDRESS
);
9626 if ((entry
->protection
& VM_PROT_WRITE
) == 0) {
9628 * Can't apply purgable controls to something you can't write.
9631 return(KERN_PROTECTION_FAILURE
);
9634 object
= entry
->object
.vm_object
;
9635 if (object
== VM_OBJECT_NULL
) {
9637 * Object must already be present or it can't be purgable.
9640 return KERN_INVALID_ARGUMENT
;
9643 vm_object_lock(object
);
9645 if (entry
->offset
!= 0 ||
9646 entry
->vme_end
- entry
->vme_start
!= object
->size
) {
9648 * Can only apply purgable controls to the whole (existing)
9652 vm_object_unlock(object
);
9653 return KERN_INVALID_ARGUMENT
;
9658 kr
= vm_object_purgable_control(object
, control
, state
);
9660 vm_object_unlock(object
);
9667 vm_map_t target_map
,
9668 vm_map_offset_t offset
,
9672 vm_map_entry_t map_entry
;
9679 vm_map_lock(target_map
);
9680 if(!vm_map_lookup_entry(target_map
, offset
, &map_entry
)) {
9681 vm_map_unlock(target_map
);
9682 return KERN_FAILURE
;
9684 offset
-= map_entry
->vme_start
; /* adjust to offset within entry */
9685 offset
+= map_entry
->offset
; /* adjust to target object offset */
9686 if(map_entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
9687 if(!map_entry
->is_sub_map
) {
9688 object
= map_entry
->object
.vm_object
;
9690 vm_map_unlock(target_map
);
9691 target_map
= map_entry
->object
.sub_map
;
9692 goto restart_page_query
;
9695 vm_map_unlock(target_map
);
9696 return KERN_FAILURE
;
9698 vm_object_lock(object
);
9699 vm_map_unlock(target_map
);
9701 m
= vm_page_lookup(object
, offset
);
9702 if (m
!= VM_PAGE_NULL
) {
9703 *disposition
|= VM_PAGE_QUERY_PAGE_PRESENT
;
9706 if(object
->shadow
) {
9707 offset
+= object
->shadow_offset
;
9708 vm_object_unlock(object
);
9709 object
= object
->shadow
;
9710 vm_object_lock(object
);
9713 vm_object_unlock(object
);
9714 return KERN_FAILURE
;
9718 /* The ref_count is not strictly accurate, it measures the number */
9719 /* of entities holding a ref on the object, they may not be mapping */
9720 /* the object or may not be mapping the section holding the */
9721 /* target page but its still a ball park number and though an over- */
9722 /* count, it picks up the copy-on-write cases */
9724 /* We could also get a picture of page sharing from pmap_attributes */
9725 /* but this would under count as only faulted-in mappings would */
9728 *ref_count
= object
->ref_count
;
9730 if (m
->fictitious
) {
9731 *disposition
|= VM_PAGE_QUERY_PAGE_FICTITIOUS
;
9732 vm_object_unlock(object
);
9733 return KERN_SUCCESS
;
9737 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9738 else if(pmap_is_modified(m
->phys_page
))
9739 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9742 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9743 else if(pmap_is_referenced(m
->phys_page
))
9744 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9746 vm_object_unlock(object
);
9747 return KERN_SUCCESS
;
9752 /* For a given range, check all map entries. If the entry coresponds to */
9753 /* the old vm_region/map provided on the call, replace it with the */
9754 /* corresponding range in the new vm_region/map */
9755 kern_return_t
vm_map_region_replace(
9756 vm_map_t target_map
,
9757 ipc_port_t old_region
,
9758 ipc_port_t new_region
,
9759 vm_map_offset_t start
,
9760 vm_map_offset_t end
)
9762 vm_named_entry_t old_object
;
9763 vm_named_entry_t new_object
;
9764 vm_map_t old_submap
;
9765 vm_map_t new_submap
;
9766 vm_map_offset_t addr
;
9767 vm_map_entry_t entry
;
9768 int nested_pmap
= 0;
9771 vm_map_lock(target_map
);
9772 old_object
= (vm_named_entry_t
)old_region
->ip_kobject
;
9773 new_object
= (vm_named_entry_t
)new_region
->ip_kobject
;
9774 if((!old_object
->is_sub_map
) || (!new_object
->is_sub_map
)) {
9775 vm_map_unlock(target_map
);
9776 return KERN_INVALID_ARGUMENT
;
9778 old_submap
= (vm_map_t
)old_object
->backing
.map
;
9779 new_submap
= (vm_map_t
)new_object
->backing
.map
;
9780 vm_map_lock(old_submap
);
9781 if((old_submap
->min_offset
!= new_submap
->min_offset
) ||
9782 (old_submap
->max_offset
!= new_submap
->max_offset
)) {
9783 vm_map_unlock(old_submap
);
9784 vm_map_unlock(target_map
);
9785 return KERN_INVALID_ARGUMENT
;
9787 if(!vm_map_lookup_entry(target_map
, start
, &entry
)) {
9788 /* if the src is not contained, the entry preceeds */
9790 addr
= entry
->vme_start
;
9791 if(entry
== vm_map_to_entry(target_map
)) {
9792 vm_map_unlock(old_submap
);
9793 vm_map_unlock(target_map
);
9794 return KERN_SUCCESS
;
9797 if ((entry
->use_pmap
) &&
9798 (new_submap
->pmap
== NULL
)) {
9799 new_submap
->pmap
= pmap_create((vm_map_size_t
) 0);
9800 if(new_submap
->pmap
== PMAP_NULL
) {
9801 vm_map_unlock(old_submap
);
9802 vm_map_unlock(target_map
);
9803 return(KERN_NO_SPACE
);
9806 addr
= entry
->vme_start
;
9807 vm_map_reference(old_submap
);
9808 while((entry
!= vm_map_to_entry(target_map
)) &&
9809 (entry
->vme_start
< end
)) {
9810 if((entry
->is_sub_map
) &&
9811 (entry
->object
.sub_map
== old_submap
)) {
9812 if(entry
->use_pmap
) {
9813 if((start
& 0x0fffffff) ||
9814 ((end
- start
) != 0x10000000)) {
9815 vm_map_unlock(old_submap
);
9816 vm_map_deallocate(old_submap
);
9817 vm_map_unlock(target_map
);
9818 return KERN_INVALID_ARGUMENT
;
9822 entry
->object
.sub_map
= new_submap
;
9823 vm_map_reference(new_submap
);
9824 vm_map_deallocate(old_submap
);
9826 entry
= entry
->vme_next
;
9827 addr
= entry
->vme_start
;
9831 pmap_unnest(target_map
->pmap
, (addr64_t
)start
);
9832 if(target_map
->mapped
) {
9833 vm_map_submap_pmap_clean(target_map
,
9834 start
, end
, old_submap
, 0);
9836 pmap_nest(target_map
->pmap
, new_submap
->pmap
,
9837 (addr64_t
)start
, (addr64_t
)start
,
9838 (uint64_t)(end
- start
));
9841 vm_map_submap_pmap_clean(target_map
,
9842 start
, end
, old_submap
, 0);
9844 vm_map_unlock(old_submap
);
9845 vm_map_deallocate(old_submap
);
9846 vm_map_unlock(target_map
);
9847 return KERN_SUCCESS
;
9853 * Synchronises the memory range specified with its backing store
9854 * image by either flushing or cleaning the contents to the appropriate
9855 * memory manager engaging in a memory object synchronize dialog with
9856 * the manager. The client doesn't return until the manager issues
9857 * m_o_s_completed message. MIG Magically converts user task parameter
9858 * to the task's address map.
9860 * interpretation of sync_flags
9861 * VM_SYNC_INVALIDATE - discard pages, only return precious
9864 * VM_SYNC_INVALIDATE & (VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS)
9865 * - discard pages, write dirty or precious
9866 * pages back to memory manager.
9868 * VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS
9869 * - write dirty or precious pages back to
9870 * the memory manager.
9872 * VM_SYNC_CONTIGUOUS - does everything normally, but if there
9873 * is a hole in the region, and we would
9874 * have returned KERN_SUCCESS, return
9875 * KERN_INVALID_ADDRESS instead.
9878 * The memory object attributes have not yet been implemented, this
9879 * function will have to deal with the invalidate attribute
9882 * KERN_INVALID_TASK Bad task parameter
9883 * KERN_INVALID_ARGUMENT both sync and async were specified.
9884 * KERN_SUCCESS The usual.
9885 * KERN_INVALID_ADDRESS There was a hole in the region.
9891 vm_map_address_t address
,
9893 vm_sync_t sync_flags
)
9896 msync_req_t new_msr
;
9897 queue_chain_t req_q
; /* queue of requests for this msync */
9898 vm_map_entry_t entry
;
9899 vm_map_size_t amount_left
;
9900 vm_object_offset_t offset
;
9901 boolean_t do_sync_req
;
9902 boolean_t modifiable
;
9903 boolean_t had_hole
= FALSE
;
9905 if ((sync_flags
& VM_SYNC_ASYNCHRONOUS
) &&
9906 (sync_flags
& VM_SYNC_SYNCHRONOUS
))
9907 return(KERN_INVALID_ARGUMENT
);
9910 * align address and size on page boundaries
9912 size
= vm_map_round_page(address
+ size
) - vm_map_trunc_page(address
);
9913 address
= vm_map_trunc_page(address
);
9915 if (map
== VM_MAP_NULL
)
9916 return(KERN_INVALID_TASK
);
9919 return(KERN_SUCCESS
);
9924 while (amount_left
> 0) {
9925 vm_object_size_t flush_size
;
9929 if (!vm_map_lookup_entry(map
,
9930 vm_map_trunc_page(address
), &entry
)) {
9935 * hole in the address map.
9940 * Check for empty map.
9942 if (entry
== vm_map_to_entry(map
) &&
9943 entry
->vme_next
== entry
) {
9948 * Check that we don't wrap and that
9949 * we have at least one real map entry.
9951 if ((map
->hdr
.nentries
== 0) ||
9952 (entry
->vme_next
->vme_start
< address
)) {
9957 * Move up to the next entry if needed
9959 skip
= (entry
->vme_next
->vme_start
- address
);
9960 if (skip
>= amount_left
)
9963 amount_left
-= skip
;
9964 address
= entry
->vme_next
->vme_start
;
9969 offset
= address
- entry
->vme_start
;
9972 * do we have more to flush than is contained in this
9975 if (amount_left
+ entry
->vme_start
+ offset
> entry
->vme_end
) {
9976 flush_size
= entry
->vme_end
-
9977 (entry
->vme_start
+ offset
);
9979 flush_size
= amount_left
;
9981 amount_left
-= flush_size
;
9982 address
+= flush_size
;
9984 if (entry
->is_sub_map
== TRUE
) {
9986 vm_map_offset_t local_offset
;
9988 local_map
= entry
->object
.sub_map
;
9989 local_offset
= entry
->offset
;
9995 sync_flags
) == KERN_INVALID_ADDRESS
) {
10000 object
= entry
->object
.vm_object
;
10003 * We can't sync this object if the object has not been
10006 if (object
== VM_OBJECT_NULL
) {
10007 vm_map_unlock(map
);
10010 offset
+= entry
->offset
;
10011 modifiable
= (entry
->protection
& VM_PROT_WRITE
)
10014 vm_object_lock(object
);
10016 if (sync_flags
& (VM_SYNC_KILLPAGES
| VM_SYNC_DEACTIVATE
)) {
10017 boolean_t kill_pages
= 0;
10019 if (sync_flags
& VM_SYNC_KILLPAGES
) {
10020 if (object
->ref_count
== 1 && !entry
->needs_copy
&& !object
->shadow
)
10025 if (kill_pages
!= -1)
10026 vm_object_deactivate_pages(object
, offset
,
10027 (vm_object_size_t
)flush_size
, kill_pages
);
10028 vm_object_unlock(object
);
10029 vm_map_unlock(map
);
10033 * We can't sync this object if there isn't a pager.
10034 * Don't bother to sync internal objects, since there can't
10035 * be any "permanent" storage for these objects anyway.
10037 if ((object
->pager
== MEMORY_OBJECT_NULL
) ||
10038 (object
->internal
) || (object
->private)) {
10039 vm_object_unlock(object
);
10040 vm_map_unlock(map
);
10044 * keep reference on the object until syncing is done
10046 assert(object
->ref_count
> 0);
10047 object
->ref_count
++;
10048 vm_object_res_reference(object
);
10049 vm_object_unlock(object
);
10051 vm_map_unlock(map
);
10053 do_sync_req
= vm_object_sync(object
,
10056 sync_flags
& VM_SYNC_INVALIDATE
,
10058 (sync_flags
& VM_SYNC_SYNCHRONOUS
||
10059 sync_flags
& VM_SYNC_ASYNCHRONOUS
)),
10060 sync_flags
& VM_SYNC_SYNCHRONOUS
);
10062 * only send a m_o_s if we returned pages or if the entry
10063 * is writable (ie dirty pages may have already been sent back)
10065 if (!do_sync_req
&& !modifiable
) {
10066 vm_object_deallocate(object
);
10069 msync_req_alloc(new_msr
);
10071 vm_object_lock(object
);
10072 offset
+= object
->paging_offset
;
10074 new_msr
->offset
= offset
;
10075 new_msr
->length
= flush_size
;
10076 new_msr
->object
= object
;
10077 new_msr
->flag
= VM_MSYNC_SYNCHRONIZING
;
10079 queue_iterate(&object
->msr_q
, msr
, msync_req_t
, msr_q
) {
10081 * need to check for overlapping entry, if found, wait
10082 * on overlapping msr to be done, then reiterate
10085 if (msr
->flag
== VM_MSYNC_SYNCHRONIZING
&&
10086 ((offset
>= msr
->offset
&&
10087 offset
< (msr
->offset
+ msr
->length
)) ||
10088 (msr
->offset
>= offset
&&
10089 msr
->offset
< (offset
+ flush_size
))))
10091 assert_wait((event_t
) msr
,THREAD_INTERRUPTIBLE
);
10093 vm_object_unlock(object
);
10094 thread_block(THREAD_CONTINUE_NULL
);
10095 vm_object_lock(object
);
10099 }/* queue_iterate */
10101 queue_enter(&object
->msr_q
, new_msr
, msync_req_t
, msr_q
);
10102 vm_object_unlock(object
);
10104 queue_enter(&req_q
, new_msr
, msync_req_t
, req_q
);
10106 (void) memory_object_synchronize(
10110 sync_flags
& ~VM_SYNC_CONTIGUOUS
);
10114 * wait for memory_object_sychronize_completed messages from pager(s)
10117 while (!queue_empty(&req_q
)) {
10118 msr
= (msync_req_t
)queue_first(&req_q
);
10120 while(msr
->flag
!= VM_MSYNC_DONE
) {
10121 assert_wait((event_t
) msr
, THREAD_INTERRUPTIBLE
);
10123 thread_block(THREAD_CONTINUE_NULL
);
10126 queue_remove(&req_q
, msr
, msync_req_t
, req_q
);
10128 vm_object_deallocate(msr
->object
);
10129 msync_req_free(msr
);
10130 }/* queue_iterate */
10132 /* for proper msync() behaviour */
10133 if (had_hole
== TRUE
&& (sync_flags
& VM_SYNC_CONTIGUOUS
))
10134 return(KERN_INVALID_ADDRESS
);
10136 return(KERN_SUCCESS
);
10139 /* Takes existing source and destination sub-maps and clones the contents of */
10140 /* the source map */
10143 ipc_port_t src_region
,
10144 ipc_port_t dst_region
)
10146 vm_named_entry_t src_object
;
10147 vm_named_entry_t dst_object
;
10150 vm_map_offset_t addr
;
10151 vm_map_offset_t max_off
;
10152 vm_map_entry_t entry
;
10153 vm_map_entry_t new_entry
;
10154 vm_map_entry_t insert_point
;
10156 src_object
= (vm_named_entry_t
)src_region
->ip_kobject
;
10157 dst_object
= (vm_named_entry_t
)dst_region
->ip_kobject
;
10158 if((!src_object
->is_sub_map
) || (!dst_object
->is_sub_map
)) {
10159 return KERN_INVALID_ARGUMENT
;
10161 src_map
= (vm_map_t
)src_object
->backing
.map
;
10162 dst_map
= (vm_map_t
)dst_object
->backing
.map
;
10163 /* destination map is assumed to be unavailable to any other */
10164 /* activity. i.e. it is new */
10165 vm_map_lock(src_map
);
10166 if((src_map
->min_offset
!= dst_map
->min_offset
)
10167 || (src_map
->max_offset
!= dst_map
->max_offset
)) {
10168 vm_map_unlock(src_map
);
10169 return KERN_INVALID_ARGUMENT
;
10171 addr
= src_map
->min_offset
;
10172 vm_map_lookup_entry(dst_map
, addr
, &entry
);
10173 if(entry
== vm_map_to_entry(dst_map
)) {
10174 entry
= entry
->vme_next
;
10176 if(entry
== vm_map_to_entry(dst_map
)) {
10177 max_off
= src_map
->max_offset
;
10179 max_off
= entry
->vme_start
;
10181 vm_map_lookup_entry(src_map
, addr
, &entry
);
10182 if(entry
== vm_map_to_entry(src_map
)) {
10183 entry
= entry
->vme_next
;
10185 vm_map_lookup_entry(dst_map
, addr
, &insert_point
);
10186 while((entry
!= vm_map_to_entry(src_map
)) &&
10187 (entry
->vme_end
<= max_off
)) {
10188 addr
= entry
->vme_start
;
10189 new_entry
= vm_map_entry_create(dst_map
);
10190 vm_map_entry_copy(new_entry
, entry
);
10191 vm_map_entry_link(dst_map
, insert_point
, new_entry
);
10192 insert_point
= new_entry
;
10193 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
10194 if (new_entry
->is_sub_map
) {
10195 vm_map_reference(new_entry
->object
.sub_map
);
10197 vm_object_reference(
10198 new_entry
->object
.vm_object
);
10201 dst_map
->size
+= new_entry
->vme_end
- new_entry
->vme_start
;
10202 entry
= entry
->vme_next
;
10204 vm_map_unlock(src_map
);
10205 return KERN_SUCCESS
;
10209 * Routine: convert_port_entry_to_map
10211 * Convert from a port specifying an entry or a task
10212 * to a map. Doesn't consume the port ref; produces a map ref,
10213 * which may be null. Unlike convert_port_to_map, the
10214 * port may be task or a named entry backed.
10221 convert_port_entry_to_map(
10225 vm_named_entry_t named_entry
;
10227 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10230 if(ip_active(port
) && (ip_kotype(port
)
10231 == IKOT_NAMED_ENTRY
)) {
10233 (vm_named_entry_t
)port
->ip_kobject
;
10234 if (!(mutex_try(&(named_entry
)->Lock
))) {
10239 named_entry
->ref_count
++;
10240 mutex_unlock(&(named_entry
)->Lock
);
10242 if ((named_entry
->is_sub_map
) &&
10243 (named_entry
->protection
10244 & VM_PROT_WRITE
)) {
10245 map
= named_entry
->backing
.map
;
10247 mach_destroy_memory_entry(port
);
10248 return VM_MAP_NULL
;
10250 vm_map_reference_swap(map
);
10251 mach_destroy_memory_entry(port
);
10255 return VM_MAP_NULL
;
10259 map
= convert_port_to_map(port
);
10265 * Routine: convert_port_entry_to_object
10267 * Convert from a port specifying a named entry to an
10268 * object. Doesn't consume the port ref; produces a map ref,
10269 * which may be null.
10276 convert_port_entry_to_object(
10279 vm_object_t object
;
10280 vm_named_entry_t named_entry
;
10282 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10285 if(ip_active(port
) && (ip_kotype(port
)
10286 == IKOT_NAMED_ENTRY
)) {
10288 (vm_named_entry_t
)port
->ip_kobject
;
10289 if (!(mutex_try(&(named_entry
)->Lock
))) {
10294 named_entry
->ref_count
++;
10295 mutex_unlock(&(named_entry
)->Lock
);
10297 if ((!named_entry
->is_sub_map
) &&
10298 (!named_entry
->is_pager
) &&
10299 (named_entry
->protection
10300 & VM_PROT_WRITE
)) {
10301 object
= named_entry
->backing
.object
;
10303 mach_destroy_memory_entry(port
);
10304 return (vm_object_t
)NULL
;
10306 vm_object_reference(named_entry
->backing
.object
);
10307 mach_destroy_memory_entry(port
);
10311 return (vm_object_t
)NULL
;
10314 return (vm_object_t
)NULL
;
10321 * Export routines to other components for the things we access locally through
10328 return (current_map_fast());
10332 * vm_map_reference:
10334 * Most code internal to the osfmk will go through a
10335 * macro defining this. This is always here for the
10336 * use of other kernel components.
10338 #undef vm_map_reference
10341 register vm_map_t map
)
10343 if (map
== VM_MAP_NULL
)
10346 mutex_lock(&map
->s_lock
);
10348 assert(map
->res_count
> 0);
10349 assert(map
->ref_count
>= map
->res_count
);
10353 mutex_unlock(&map
->s_lock
);
10357 * vm_map_deallocate:
10359 * Removes a reference from the specified map,
10360 * destroying it if no references remain.
10361 * The map should not be locked.
10365 register vm_map_t map
)
10369 if (map
== VM_MAP_NULL
)
10372 mutex_lock(&map
->s_lock
);
10373 ref
= --map
->ref_count
;
10375 vm_map_res_deallocate(map
);
10376 mutex_unlock(&map
->s_lock
);
10379 assert(map
->ref_count
== 0);
10380 mutex_unlock(&map
->s_lock
);
10384 * The map residence count isn't decremented here because
10385 * the vm_map_delete below will traverse the entire map,
10386 * deleting entries, and the residence counts on objects
10387 * and sharing maps will go away then.
10391 vm_map_destroy(map
);
10396 /* LP64todo - this whole mechanism is temporary. It should be redone when
10397 * the pmap layer can handle 64-bit address spaces. Until then, we trump
10398 * up a map entry for the 64-bit commpage above the map's max_offset.
10400 extern vm_map_t com_region_map64
; /* the submap for 64-bit commpage */
10401 SInt32 commpage64s_in_use
= 0;
10407 vm_map_entry_t entry
;
10408 vm_object_t object
;
10412 /* The commpage is necessarily the last entry in the map.
10413 * See if one is already there (not sure if this can happen???)
10415 entry
= vm_map_last_entry(map
);
10416 if (entry
!= vm_map_to_entry(map
)) {
10417 if (entry
->vme_end
>= (vm_map_offset_t
)_COMM_PAGE_BASE_ADDRESS
) {
10418 vm_map_unlock(map
);
10423 entry
= vm_map_first_entry(com_region_map64
); /* the 64-bit commpage */
10424 object
= entry
->object
.vm_object
;
10425 vm_object_reference(object
);
10427 /* We bypass vm_map_enter() because we are adding the entry past the
10428 * map's max_offset.
10430 entry
= vm_map_entry_insert(
10432 vm_map_last_entry(map
), /* insert after last entry */
10433 _COMM_PAGE_BASE_ADDRESS
,
10434 _COMM_PAGE_BASE_ADDRESS
+_COMM_PAGE_AREA_USED
,
10437 FALSE
, /* needs_copy */
10438 FALSE
, /* is_shared */
10439 FALSE
, /* in_transition */
10442 VM_BEHAVIOR_DEFAULT
,
10444 1 ); /* wired_count */
10446 vm_map_unlock(map
);
10448 OSIncrementAtomic(&commpage64s_in_use
);
10452 /* LP64todo - remove this! */
10455 vm_map_remove_commpage64(
10458 vm_map_entry_t entry
;
10464 entry
= vm_map_last_entry(map
);
10465 if ((entry
== vm_map_to_entry(map
)) ||
10466 (entry
->vme_start
< (vm_map_offset_t
)_COMM_PAGE_BASE_ADDRESS
))
10469 /* clearing the wired count isn't strictly correct */
10470 entry
->wired_count
= 0;
10471 vm_map_entry_delete(map
,entry
);
10475 vm_map_unlock(map
);
10478 OSDecrementAtomic(&commpage64s_in_use
);
10481 #endif /* __PPC__ */