2 * Copyright (c) 2000-2012 Apple 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>
69 #include <vm/vm_options.h>
71 #include <libkern/OSAtomic.h>
73 #include <mach/kern_return.h>
74 #include <mach/port.h>
75 #include <mach/vm_attributes.h>
76 #include <mach/vm_param.h>
77 #include <mach/vm_behavior.h>
78 #include <mach/vm_statistics.h>
79 #include <mach/memory_object.h>
80 #include <mach/mach_vm.h>
81 #include <machine/cpu_capabilities.h>
84 #include <kern/assert.h>
85 #include <kern/counters.h>
86 #include <kern/kalloc.h>
87 #include <kern/zalloc.h>
90 #include <vm/vm_compressor_pager.h>
91 #include <vm/vm_init.h>
92 #include <vm/vm_fault.h>
93 #include <vm/vm_map.h>
94 #include <vm/vm_object.h>
95 #include <vm/vm_page.h>
96 #include <vm/vm_pageout.h>
97 #include <vm/vm_kern.h>
98 #include <ipc/ipc_port.h>
99 #include <kern/sched_prim.h>
100 #include <kern/misc_protos.h>
101 #include <kern/xpr.h>
103 #include <mach/vm_map_server.h>
104 #include <mach/mach_host_server.h>
105 #include <vm/vm_protos.h>
106 #include <vm/vm_purgeable_internal.h>
108 #include <vm/vm_protos.h>
109 #include <vm/vm_shared_region.h>
110 #include <vm/vm_map_store.h>
112 extern u_int32_t
random(void); /* from <libkern/libkern.h> */
113 /* Internal prototypes
116 static void vm_map_simplify_range(
118 vm_map_offset_t start
,
119 vm_map_offset_t end
); /* forward */
121 static boolean_t
vm_map_range_check(
123 vm_map_offset_t start
,
125 vm_map_entry_t
*entry
);
127 static vm_map_entry_t
_vm_map_entry_create(
128 struct vm_map_header
*map_header
, boolean_t map_locked
);
130 static void _vm_map_entry_dispose(
131 struct vm_map_header
*map_header
,
132 vm_map_entry_t entry
);
134 static void vm_map_pmap_enter(
136 vm_map_offset_t addr
,
137 vm_map_offset_t end_addr
,
139 vm_object_offset_t offset
,
140 vm_prot_t protection
);
142 static void _vm_map_clip_end(
143 struct vm_map_header
*map_header
,
144 vm_map_entry_t entry
,
145 vm_map_offset_t end
);
147 static void _vm_map_clip_start(
148 struct vm_map_header
*map_header
,
149 vm_map_entry_t entry
,
150 vm_map_offset_t start
);
152 static void vm_map_entry_delete(
154 vm_map_entry_t entry
);
156 static kern_return_t
vm_map_delete(
158 vm_map_offset_t start
,
163 static kern_return_t
vm_map_copy_overwrite_unaligned(
165 vm_map_entry_t entry
,
167 vm_map_address_t start
,
168 boolean_t discard_on_success
);
170 static kern_return_t
vm_map_copy_overwrite_aligned(
172 vm_map_entry_t tmp_entry
,
174 vm_map_offset_t start
,
177 static kern_return_t
vm_map_copyin_kernel_buffer(
179 vm_map_address_t src_addr
,
181 boolean_t src_destroy
,
182 vm_map_copy_t
*copy_result
); /* OUT */
184 static kern_return_t
vm_map_copyout_kernel_buffer(
186 vm_map_address_t
*addr
, /* IN/OUT */
189 boolean_t consume_on_success
);
191 static void vm_map_fork_share(
193 vm_map_entry_t old_entry
,
196 static boolean_t
vm_map_fork_copy(
198 vm_map_entry_t
*old_entry_p
,
201 void vm_map_region_top_walk(
202 vm_map_entry_t entry
,
203 vm_region_top_info_t top
);
205 void vm_map_region_walk(
208 vm_map_entry_t entry
,
209 vm_object_offset_t offset
,
210 vm_object_size_t range
,
211 vm_region_extended_info_t extended
,
212 boolean_t look_for_pages
,
213 mach_msg_type_number_t count
);
215 static kern_return_t
vm_map_wire_nested(
217 vm_map_offset_t start
,
219 vm_prot_t access_type
,
222 vm_map_offset_t pmap_addr
,
223 ppnum_t
*physpage_p
);
225 static kern_return_t
vm_map_unwire_nested(
227 vm_map_offset_t start
,
231 vm_map_offset_t pmap_addr
);
233 static kern_return_t
vm_map_overwrite_submap_recurse(
235 vm_map_offset_t dst_addr
,
236 vm_map_size_t dst_size
);
238 static kern_return_t
vm_map_copy_overwrite_nested(
240 vm_map_offset_t dst_addr
,
242 boolean_t interruptible
,
244 boolean_t discard_on_success
);
246 static kern_return_t
vm_map_remap_extract(
248 vm_map_offset_t addr
,
251 struct vm_map_header
*map_header
,
252 vm_prot_t
*cur_protection
,
253 vm_prot_t
*max_protection
,
254 vm_inherit_t inheritance
,
257 static kern_return_t
vm_map_remap_range_allocate(
259 vm_map_address_t
*address
,
261 vm_map_offset_t mask
,
263 vm_map_entry_t
*map_entry
);
265 static void vm_map_region_look_for_page(
269 vm_object_offset_t offset
,
272 vm_region_extended_info_t extended
,
273 mach_msg_type_number_t count
);
275 static int vm_map_region_count_obj_refs(
276 vm_map_entry_t entry
,
280 static kern_return_t
vm_map_willneed(
282 vm_map_offset_t start
,
283 vm_map_offset_t end
);
285 static kern_return_t
vm_map_reuse_pages(
287 vm_map_offset_t start
,
288 vm_map_offset_t end
);
290 static kern_return_t
vm_map_reusable_pages(
292 vm_map_offset_t start
,
293 vm_map_offset_t end
);
295 static kern_return_t
vm_map_can_reuse(
297 vm_map_offset_t start
,
298 vm_map_offset_t end
);
302 * Macros to copy a vm_map_entry. We must be careful to correctly
303 * manage the wired page count. vm_map_entry_copy() creates a new
304 * map entry to the same memory - the wired count in the new entry
305 * must be set to zero. vm_map_entry_copy_full() creates a new
306 * entry that is identical to the old entry. This preserves the
307 * wire count; it's used for map splitting and zone changing in
311 #define vm_map_entry_copy(NEW,OLD) \
313 boolean_t _vmec_reserved = (NEW)->from_reserved_zone; \
315 (NEW)->is_shared = FALSE; \
316 (NEW)->needs_wakeup = FALSE; \
317 (NEW)->in_transition = FALSE; \
318 (NEW)->wired_count = 0; \
319 (NEW)->user_wired_count = 0; \
320 (NEW)->permanent = FALSE; \
321 (NEW)->used_for_jit = FALSE; \
322 (NEW)->from_reserved_zone = _vmec_reserved; \
323 (NEW)->iokit_acct = FALSE; \
326 #define vm_map_entry_copy_full(NEW,OLD) \
328 boolean_t _vmecf_reserved = (NEW)->from_reserved_zone; \
330 (NEW)->from_reserved_zone = _vmecf_reserved; \
334 * Decide if we want to allow processes to execute from their data or stack areas.
335 * override_nx() returns true if we do. Data/stack execution can be enabled independently
336 * for 32 and 64 bit processes. Set the VM_ABI_32 or VM_ABI_64 flags in allow_data_exec
337 * or allow_stack_exec to enable data execution for that type of data area for that particular
338 * ABI (or both by or'ing the flags together). These are initialized in the architecture
339 * specific pmap files since the default behavior varies according to architecture. The
340 * main reason it varies is because of the need to provide binary compatibility with old
341 * applications that were written before these restrictions came into being. In the old
342 * days, an app could execute anything it could read, but this has slowly been tightened
343 * up over time. The default behavior is:
345 * 32-bit PPC apps may execute from both stack and data areas
346 * 32-bit Intel apps may exeucte from data areas but not stack
347 * 64-bit PPC/Intel apps may not execute from either data or stack
349 * An application on any architecture may override these defaults by explicitly
350 * adding PROT_EXEC permission to the page in question with the mprotect(2)
351 * system call. This code here just determines what happens when an app tries to
352 * execute from a page that lacks execute permission.
354 * Note that allow_data_exec or allow_stack_exec may also be modified by sysctl to change the
355 * default behavior for both 32 and 64 bit apps on a system-wide basis. Furthermore,
356 * a Mach-O header flag bit (MH_NO_HEAP_EXECUTION) can be used to forcibly disallow
357 * execution from data areas for a particular binary even if the arch normally permits it. As
358 * a final wrinkle, a posix_spawn attribute flag can be used to negate this opt-in header bit
359 * to support some complicated use cases, notably browsers with out-of-process plugins that
360 * are not all NX-safe.
363 extern int allow_data_exec
, allow_stack_exec
;
366 override_nx(vm_map_t map
, uint32_t user_tag
) /* map unused on arm */
371 * Determine if the app is running in 32 or 64 bit mode.
374 if (vm_map_is_64bit(map
))
375 current_abi
= VM_ABI_64
;
377 current_abi
= VM_ABI_32
;
380 * Determine if we should allow the execution based on whether it's a
381 * stack or data area and the current architecture.
384 if (user_tag
== VM_MEMORY_STACK
)
385 return allow_stack_exec
& current_abi
;
387 return (allow_data_exec
& current_abi
) && (map
->map_disallow_data_exec
== FALSE
);
392 * Virtual memory maps provide for the mapping, protection,
393 * and sharing of virtual memory objects. In addition,
394 * this module provides for an efficient virtual copy of
395 * memory from one map to another.
397 * Synchronization is required prior to most operations.
399 * Maps consist of an ordered doubly-linked list of simple
400 * entries; a single hint is used to speed up lookups.
402 * Sharing maps have been deleted from this version of Mach.
403 * All shared objects are now mapped directly into the respective
404 * maps. This requires a change in the copy on write strategy;
405 * the asymmetric (delayed) strategy is used for shared temporary
406 * objects instead of the symmetric (shadow) strategy. All maps
407 * are now "top level" maps (either task map, kernel map or submap
408 * of the kernel map).
410 * Since portions of maps are specified by start/end addreses,
411 * which may not align with existing map entries, all
412 * routines merely "clip" entries to these start/end values.
413 * [That is, an entry is split into two, bordering at a
414 * start or end value.] Note that these clippings may not
415 * always be necessary (as the two resulting entries are then
416 * not changed); however, the clipping is done for convenience.
417 * No attempt is currently made to "glue back together" two
420 * The symmetric (shadow) copy strategy implements virtual copy
421 * by copying VM object references from one map to
422 * another, and then marking both regions as copy-on-write.
423 * It is important to note that only one writeable reference
424 * to a VM object region exists in any map when this strategy
425 * is used -- this means that shadow object creation can be
426 * delayed until a write operation occurs. The symmetric (delayed)
427 * strategy allows multiple maps to have writeable references to
428 * the same region of a vm object, and hence cannot delay creating
429 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
430 * Copying of permanent objects is completely different; see
431 * vm_object_copy_strategically() in vm_object.c.
434 static zone_t vm_map_zone
; /* zone for vm_map structures */
435 static zone_t vm_map_entry_zone
; /* zone for vm_map_entry structures */
436 static zone_t vm_map_entry_reserved_zone
; /* zone with reserve for non-blocking
438 static zone_t vm_map_copy_zone
; /* zone for vm_map_copy structures */
442 * Placeholder object for submap operations. This object is dropped
443 * into the range by a call to vm_map_find, and removed when
444 * vm_map_submap creates the submap.
447 vm_object_t vm_submap_object
;
449 static void *map_data
;
450 static vm_size_t map_data_size
;
451 static void *kentry_data
;
452 static vm_size_t kentry_data_size
;
454 #define NO_COALESCE_LIMIT ((1024 * 128) - 1)
456 /* Skip acquiring locks if we're in the midst of a kernel core dump */
457 unsigned int not_in_kdp
= 1;
459 unsigned int vm_map_set_cache_attr_count
= 0;
462 vm_map_set_cache_attr(
466 vm_map_entry_t map_entry
;
468 kern_return_t kr
= KERN_SUCCESS
;
470 vm_map_lock_read(map
);
472 if (!vm_map_lookup_entry(map
, va
, &map_entry
) ||
473 map_entry
->is_sub_map
) {
475 * that memory is not properly mapped
477 kr
= KERN_INVALID_ARGUMENT
;
480 object
= map_entry
->object
.vm_object
;
482 if (object
== VM_OBJECT_NULL
) {
484 * there should be a VM object here at this point
486 kr
= KERN_INVALID_ARGUMENT
;
489 vm_object_lock(object
);
490 object
->set_cache_attr
= TRUE
;
491 vm_object_unlock(object
);
493 vm_map_set_cache_attr_count
++;
495 vm_map_unlock_read(map
);
501 #if CONFIG_CODE_DECRYPTION
503 * vm_map_apple_protected:
504 * This remaps the requested part of the object with an object backed by
505 * the decrypting pager.
506 * crypt_info contains entry points and session data for the crypt module.
507 * The crypt_info block will be copied by vm_map_apple_protected. The data structures
508 * referenced in crypt_info must remain valid until crypt_info->crypt_end() is called.
511 vm_map_apple_protected(
513 vm_map_offset_t start
,
515 struct pager_crypt_info
*crypt_info
)
517 boolean_t map_locked
;
519 vm_map_entry_t map_entry
;
520 memory_object_t protected_mem_obj
;
521 vm_object_t protected_object
;
522 vm_map_offset_t map_addr
;
524 vm_map_lock_read(map
);
527 /* lookup the protected VM object */
528 if (!vm_map_lookup_entry(map
,
531 map_entry
->vme_end
< end
||
532 map_entry
->is_sub_map
||
533 !(map_entry
->protection
& VM_PROT_EXECUTE
)) {
534 /* that memory is not properly mapped */
535 kr
= KERN_INVALID_ARGUMENT
;
538 protected_object
= map_entry
->object
.vm_object
;
539 if (protected_object
== VM_OBJECT_NULL
) {
540 /* there should be a VM object here at this point */
541 kr
= KERN_INVALID_ARGUMENT
;
545 /* make sure protected object stays alive while map is unlocked */
546 vm_object_reference(protected_object
);
548 vm_map_unlock_read(map
);
552 * Lookup (and create if necessary) the protected memory object
553 * matching that VM object.
554 * If successful, this also grabs a reference on the memory object,
555 * to guarantee that it doesn't go away before we get a chance to map
558 protected_mem_obj
= apple_protect_pager_setup(protected_object
, crypt_info
);
560 /* release extra ref on protected object */
561 vm_object_deallocate(protected_object
);
563 if (protected_mem_obj
== NULL
) {
568 /* map this memory object in place of the current one */
570 kr
= vm_map_enter_mem_object(map
,
573 (mach_vm_offset_t
) 0,
574 VM_FLAGS_FIXED
| VM_FLAGS_OVERWRITE
,
575 (ipc_port_t
) protected_mem_obj
,
577 (start
- map_entry
->vme_start
)),
579 map_entry
->protection
,
580 map_entry
->max_protection
,
581 map_entry
->inheritance
);
582 assert(map_addr
== start
);
584 * Release the reference obtained by apple_protect_pager_setup().
585 * The mapping (if it succeeded) is now holding a reference on the
588 memory_object_deallocate(protected_mem_obj
);
592 vm_map_unlock_read(map
);
596 #endif /* CONFIG_CODE_DECRYPTION */
599 lck_grp_t vm_map_lck_grp
;
600 lck_grp_attr_t vm_map_lck_grp_attr
;
601 lck_attr_t vm_map_lck_attr
;
602 lck_attr_t vm_map_lck_rw_attr
;
608 * Initialize the vm_map module. Must be called before
609 * any other vm_map routines.
611 * Map and entry structures are allocated from zones -- we must
612 * initialize those zones.
614 * There are three zones of interest:
616 * vm_map_zone: used to allocate maps.
617 * vm_map_entry_zone: used to allocate map entries.
618 * vm_map_entry_reserved_zone: fallback zone for kernel map entries
620 * The kernel allocates map entries from a special zone that is initially
621 * "crammed" with memory. It would be difficult (perhaps impossible) for
622 * the kernel to allocate more memory to a entry zone when it became
623 * empty since the very act of allocating memory implies the creation
630 vm_size_t entry_zone_alloc_size
;
631 const char *mez_name
= "VM map entries";
633 vm_map_zone
= zinit((vm_map_size_t
) sizeof(struct _vm_map
), 40*1024,
635 zone_change(vm_map_zone
, Z_NOENCRYPT
, TRUE
);
636 #if defined(__LP64__)
637 entry_zone_alloc_size
= PAGE_SIZE
* 5;
639 entry_zone_alloc_size
= PAGE_SIZE
* 6;
641 vm_map_entry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
642 1024*1024, entry_zone_alloc_size
,
644 zone_change(vm_map_entry_zone
, Z_NOENCRYPT
, TRUE
);
645 zone_change(vm_map_entry_zone
, Z_NOCALLOUT
, TRUE
);
646 zone_change(vm_map_entry_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
648 vm_map_entry_reserved_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
649 kentry_data_size
* 64, kentry_data_size
,
650 "Reserved VM map entries");
651 zone_change(vm_map_entry_reserved_zone
, Z_NOENCRYPT
, TRUE
);
653 vm_map_copy_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_copy
),
654 16*1024, PAGE_SIZE
, "VM map copies");
655 zone_change(vm_map_copy_zone
, Z_NOENCRYPT
, TRUE
);
658 * Cram the map and kentry zones with initial data.
659 * Set reserved_zone non-collectible to aid zone_gc().
661 zone_change(vm_map_zone
, Z_COLLECT
, FALSE
);
663 zone_change(vm_map_entry_reserved_zone
, Z_COLLECT
, FALSE
);
664 zone_change(vm_map_entry_reserved_zone
, Z_EXPAND
, FALSE
);
665 zone_change(vm_map_entry_reserved_zone
, Z_FOREIGN
, TRUE
);
666 zone_change(vm_map_entry_reserved_zone
, Z_NOCALLOUT
, TRUE
);
667 zone_change(vm_map_entry_reserved_zone
, Z_CALLERACCT
, FALSE
); /* don't charge caller */
668 zone_change(vm_map_copy_zone
, Z_CALLERACCT
, FALSE
); /* don't charge caller */
669 zone_change(vm_map_entry_reserved_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
671 zcram(vm_map_zone
, (vm_offset_t
)map_data
, map_data_size
);
672 zcram(vm_map_entry_reserved_zone
, (vm_offset_t
)kentry_data
, kentry_data_size
);
674 lck_grp_attr_setdefault(&vm_map_lck_grp_attr
);
675 lck_grp_init(&vm_map_lck_grp
, "vm_map", &vm_map_lck_grp_attr
);
676 lck_attr_setdefault(&vm_map_lck_attr
);
678 lck_attr_setdefault(&vm_map_lck_rw_attr
);
679 lck_attr_cleardebug(&vm_map_lck_rw_attr
);
682 default_freezer_init();
683 #endif /* CONFIG_FREEZE */
690 uint32_t kentry_initial_pages
;
692 map_data_size
= round_page(10 * sizeof(struct _vm_map
));
693 map_data
= pmap_steal_memory(map_data_size
);
696 * kentry_initial_pages corresponds to the number of kernel map entries
697 * required during bootstrap until the asynchronous replenishment
698 * scheme is activated and/or entries are available from the general
701 #if defined(__LP64__)
702 kentry_initial_pages
= 10;
704 kentry_initial_pages
= 6;
708 /* If using the guard allocator, reserve more memory for the kernel
709 * reserved map entry pool.
711 if (gzalloc_enabled())
712 kentry_initial_pages
*= 1024;
715 kentry_data_size
= kentry_initial_pages
* PAGE_SIZE
;
716 kentry_data
= pmap_steal_memory(kentry_data_size
);
719 void vm_kernel_reserved_entry_init(void) {
720 zone_prio_refill_configure(vm_map_entry_reserved_zone
, (6*PAGE_SIZE
)/sizeof(struct vm_map_entry
));
726 * Creates and returns a new empty VM map with
727 * the given physical map structure, and having
728 * the given lower and upper address bounds.
737 static int color_seed
= 0;
738 register vm_map_t result
;
740 result
= (vm_map_t
) zalloc(vm_map_zone
);
741 if (result
== VM_MAP_NULL
)
742 panic("vm_map_create");
744 vm_map_first_entry(result
) = vm_map_to_entry(result
);
745 vm_map_last_entry(result
) = vm_map_to_entry(result
);
746 result
->hdr
.nentries
= 0;
747 result
->hdr
.entries_pageable
= pageable
;
749 vm_map_store_init( &(result
->hdr
) );
751 result
->hdr
.page_shift
= PAGE_SHIFT
;
754 result
->user_wire_limit
= MACH_VM_MAX_ADDRESS
; /* default limit is unlimited */
755 result
->user_wire_size
= 0;
756 result
->ref_count
= 1;
758 result
->res_count
= 1;
759 result
->sw_state
= MAP_SW_IN
;
760 #endif /* TASK_SWAPPER */
762 result
->min_offset
= min
;
763 result
->max_offset
= max
;
764 result
->wiring_required
= FALSE
;
765 result
->no_zero_fill
= FALSE
;
766 result
->mapped_in_other_pmaps
= FALSE
;
767 result
->wait_for_space
= FALSE
;
768 result
->switch_protect
= FALSE
;
769 result
->disable_vmentry_reuse
= FALSE
;
770 result
->map_disallow_data_exec
= FALSE
;
771 result
->highest_entry_end
= 0;
772 result
->first_free
= vm_map_to_entry(result
);
773 result
->hint
= vm_map_to_entry(result
);
774 result
->color_rr
= (color_seed
++) & vm_color_mask
;
775 result
->jit_entry_exists
= FALSE
;
777 result
->default_freezer_handle
= NULL
;
779 vm_map_lock_init(result
);
780 lck_mtx_init_ext(&result
->s_lock
, &result
->s_lock_ext
, &vm_map_lck_grp
, &vm_map_lck_attr
);
786 * vm_map_entry_create: [ internal use only ]
788 * Allocates a VM map entry for insertion in the
789 * given map (or map copy). No fields are filled.
791 #define vm_map_entry_create(map, map_locked) _vm_map_entry_create(&(map)->hdr, map_locked)
793 #define vm_map_copy_entry_create(copy, map_locked) \
794 _vm_map_entry_create(&(copy)->cpy_hdr, map_locked)
795 unsigned reserved_zalloc_count
, nonreserved_zalloc_count
;
797 static vm_map_entry_t
798 _vm_map_entry_create(
799 struct vm_map_header
*map_header
, boolean_t __unused map_locked
)
802 vm_map_entry_t entry
;
804 zone
= vm_map_entry_zone
;
806 assert(map_header
->entries_pageable
? !map_locked
: TRUE
);
808 if (map_header
->entries_pageable
) {
809 entry
= (vm_map_entry_t
) zalloc(zone
);
812 entry
= (vm_map_entry_t
) zalloc_canblock(zone
, FALSE
);
814 if (entry
== VM_MAP_ENTRY_NULL
) {
815 zone
= vm_map_entry_reserved_zone
;
816 entry
= (vm_map_entry_t
) zalloc(zone
);
817 OSAddAtomic(1, &reserved_zalloc_count
);
819 OSAddAtomic(1, &nonreserved_zalloc_count
);
822 if (entry
== VM_MAP_ENTRY_NULL
)
823 panic("vm_map_entry_create");
824 entry
->from_reserved_zone
= (zone
== vm_map_entry_reserved_zone
);
826 vm_map_store_update( (vm_map_t
) NULL
, entry
, VM_MAP_ENTRY_CREATE
);
827 #if MAP_ENTRY_CREATION_DEBUG
828 entry
->vme_creation_maphdr
= map_header
;
829 fastbacktrace(&entry
->vme_creation_bt
[0],
830 (sizeof(entry
->vme_creation_bt
)/sizeof(uintptr_t)));
836 * vm_map_entry_dispose: [ internal use only ]
838 * Inverse of vm_map_entry_create.
840 * write map lock held so no need to
841 * do anything special to insure correctness
844 #define vm_map_entry_dispose(map, entry) \
845 _vm_map_entry_dispose(&(map)->hdr, (entry))
847 #define vm_map_copy_entry_dispose(map, entry) \
848 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
851 _vm_map_entry_dispose(
852 register struct vm_map_header
*map_header
,
853 register vm_map_entry_t entry
)
855 register zone_t zone
;
857 if (map_header
->entries_pageable
|| !(entry
->from_reserved_zone
))
858 zone
= vm_map_entry_zone
;
860 zone
= vm_map_entry_reserved_zone
;
862 if (!map_header
->entries_pageable
) {
863 if (zone
== vm_map_entry_zone
)
864 OSAddAtomic(-1, &nonreserved_zalloc_count
);
866 OSAddAtomic(-1, &reserved_zalloc_count
);
873 static boolean_t first_free_check
= FALSE
;
878 if (!first_free_check
)
881 return( first_free_is_valid_store( map
));
883 #endif /* MACH_ASSERT */
886 #define vm_map_copy_entry_link(copy, after_where, entry) \
887 _vm_map_store_entry_link(&(copy)->cpy_hdr, after_where, (entry))
889 #define vm_map_copy_entry_unlink(copy, entry) \
890 _vm_map_store_entry_unlink(&(copy)->cpy_hdr, (entry))
892 #if MACH_ASSERT && TASK_SWAPPER
894 * vm_map_res_reference:
896 * Adds another valid residence count to the given map.
898 * Map is locked so this function can be called from
902 void vm_map_res_reference(register vm_map_t map
)
904 /* assert map is locked */
905 assert(map
->res_count
>= 0);
906 assert(map
->ref_count
>= map
->res_count
);
907 if (map
->res_count
== 0) {
908 lck_mtx_unlock(&map
->s_lock
);
911 lck_mtx_lock(&map
->s_lock
);
919 * vm_map_reference_swap:
921 * Adds valid reference and residence counts to the given map.
923 * The map may not be in memory (i.e. zero residence count).
926 void vm_map_reference_swap(register vm_map_t map
)
928 assert(map
!= VM_MAP_NULL
);
929 lck_mtx_lock(&map
->s_lock
);
930 assert(map
->res_count
>= 0);
931 assert(map
->ref_count
>= map
->res_count
);
933 vm_map_res_reference(map
);
934 lck_mtx_unlock(&map
->s_lock
);
938 * vm_map_res_deallocate:
940 * Decrement residence count on a map; possibly causing swapout.
942 * The map must be in memory (i.e. non-zero residence count).
944 * The map is locked, so this function is callable from vm_map_deallocate.
947 void vm_map_res_deallocate(register vm_map_t map
)
949 assert(map
->res_count
> 0);
950 if (--map
->res_count
== 0) {
951 lck_mtx_unlock(&map
->s_lock
);
955 lck_mtx_lock(&map
->s_lock
);
957 assert(map
->ref_count
>= map
->res_count
);
959 #endif /* MACH_ASSERT && TASK_SWAPPER */
964 * Actually destroy a map.
973 /* clean up regular map entries */
974 (void) vm_map_delete(map
, map
->min_offset
, map
->max_offset
,
976 /* clean up leftover special mappings (commpage, etc...) */
977 (void) vm_map_delete(map
, 0x0, 0xFFFFFFFFFFFFF000ULL
,
981 if (map
->default_freezer_handle
) {
982 default_freezer_handle_deallocate(map
->default_freezer_handle
);
983 map
->default_freezer_handle
= NULL
;
988 assert(map
->hdr
.nentries
== 0);
991 pmap_destroy(map
->pmap
);
993 zfree(vm_map_zone
, map
);
998 * vm_map_swapin/vm_map_swapout
1000 * Swap a map in and out, either referencing or releasing its resources.
1001 * These functions are internal use only; however, they must be exported
1002 * because they may be called from macros, which are exported.
1004 * In the case of swapout, there could be races on the residence count,
1005 * so if the residence count is up, we return, assuming that a
1006 * vm_map_deallocate() call in the near future will bring us back.
1009 * -- We use the map write lock for synchronization among races.
1010 * -- The map write lock, and not the simple s_lock, protects the
1011 * swap state of the map.
1012 * -- If a map entry is a share map, then we hold both locks, in
1013 * hierarchical order.
1015 * Synchronization Notes:
1016 * 1) If a vm_map_swapin() call happens while swapout in progress, it
1017 * will block on the map lock and proceed when swapout is through.
1018 * 2) A vm_map_reference() call at this time is illegal, and will
1019 * cause a panic. vm_map_reference() is only allowed on resident
1020 * maps, since it refuses to block.
1021 * 3) A vm_map_swapin() call during a swapin will block, and
1022 * proceeed when the first swapin is done, turning into a nop.
1023 * This is the reason the res_count is not incremented until
1024 * after the swapin is complete.
1025 * 4) There is a timing hole after the checks of the res_count, before
1026 * the map lock is taken, during which a swapin may get the lock
1027 * before a swapout about to happen. If this happens, the swapin
1028 * will detect the state and increment the reference count, causing
1029 * the swapout to be a nop, thereby delaying it until a later
1030 * vm_map_deallocate. If the swapout gets the lock first, then
1031 * the swapin will simply block until the swapout is done, and
1034 * Because vm_map_swapin() is potentially an expensive operation, it
1035 * should be used with caution.
1038 * 1) A map with a residence count of zero is either swapped, or
1040 * 2) A map with a non-zero residence count is either resident,
1041 * or being swapped in.
1044 int vm_map_swap_enable
= 1;
1046 void vm_map_swapin (vm_map_t map
)
1048 register vm_map_entry_t entry
;
1050 if (!vm_map_swap_enable
) /* debug */
1055 * First deal with various races.
1057 if (map
->sw_state
== MAP_SW_IN
)
1059 * we raced with swapout and won. Returning will incr.
1060 * the res_count, turning the swapout into a nop.
1065 * The residence count must be zero. If we raced with another
1066 * swapin, the state would have been IN; if we raced with a
1067 * swapout (after another competing swapin), we must have lost
1068 * the race to get here (see above comment), in which case
1069 * res_count is still 0.
1071 assert(map
->res_count
== 0);
1074 * There are no intermediate states of a map going out or
1075 * coming in, since the map is locked during the transition.
1077 assert(map
->sw_state
== MAP_SW_OUT
);
1080 * We now operate upon each map entry. If the entry is a sub-
1081 * or share-map, we call vm_map_res_reference upon it.
1082 * If the entry is an object, we call vm_object_res_reference
1083 * (this may iterate through the shadow chain).
1084 * Note that we hold the map locked the entire time,
1085 * even if we get back here via a recursive call in
1086 * vm_map_res_reference.
1088 entry
= vm_map_first_entry(map
);
1090 while (entry
!= vm_map_to_entry(map
)) {
1091 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
1092 if (entry
->is_sub_map
) {
1093 vm_map_t lmap
= entry
->object
.sub_map
;
1094 lck_mtx_lock(&lmap
->s_lock
);
1095 vm_map_res_reference(lmap
);
1096 lck_mtx_unlock(&lmap
->s_lock
);
1098 vm_object_t object
= entry
->object
.vm_object
;
1099 vm_object_lock(object
);
1101 * This call may iterate through the
1104 vm_object_res_reference(object
);
1105 vm_object_unlock(object
);
1108 entry
= entry
->vme_next
;
1110 assert(map
->sw_state
== MAP_SW_OUT
);
1111 map
->sw_state
= MAP_SW_IN
;
1114 void vm_map_swapout(vm_map_t map
)
1116 register vm_map_entry_t entry
;
1120 * First deal with various races.
1121 * If we raced with a swapin and lost, the residence count
1122 * will have been incremented to 1, and we simply return.
1124 lck_mtx_lock(&map
->s_lock
);
1125 if (map
->res_count
!= 0) {
1126 lck_mtx_unlock(&map
->s_lock
);
1129 lck_mtx_unlock(&map
->s_lock
);
1132 * There are no intermediate states of a map going out or
1133 * coming in, since the map is locked during the transition.
1135 assert(map
->sw_state
== MAP_SW_IN
);
1137 if (!vm_map_swap_enable
)
1141 * We now operate upon each map entry. If the entry is a sub-
1142 * or share-map, we call vm_map_res_deallocate upon it.
1143 * If the entry is an object, we call vm_object_res_deallocate
1144 * (this may iterate through the shadow chain).
1145 * Note that we hold the map locked the entire time,
1146 * even if we get back here via a recursive call in
1147 * vm_map_res_deallocate.
1149 entry
= vm_map_first_entry(map
);
1151 while (entry
!= vm_map_to_entry(map
)) {
1152 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
1153 if (entry
->is_sub_map
) {
1154 vm_map_t lmap
= entry
->object
.sub_map
;
1155 lck_mtx_lock(&lmap
->s_lock
);
1156 vm_map_res_deallocate(lmap
);
1157 lck_mtx_unlock(&lmap
->s_lock
);
1159 vm_object_t object
= entry
->object
.vm_object
;
1160 vm_object_lock(object
);
1162 * This call may take a long time,
1163 * since it could actively push
1164 * out pages (if we implement it
1167 vm_object_res_deallocate(object
);
1168 vm_object_unlock(object
);
1171 entry
= entry
->vme_next
;
1173 assert(map
->sw_state
== MAP_SW_IN
);
1174 map
->sw_state
= MAP_SW_OUT
;
1177 #endif /* TASK_SWAPPER */
1180 * vm_map_lookup_entry: [ internal use only ]
1182 * Calls into the vm map store layer to find the map
1183 * entry containing (or immediately preceding) the
1184 * specified address in the given map; the entry is returned
1185 * in the "entry" parameter. The boolean
1186 * result indicates whether the address is
1187 * actually contained in the map.
1190 vm_map_lookup_entry(
1191 register vm_map_t map
,
1192 register vm_map_offset_t address
,
1193 vm_map_entry_t
*entry
) /* OUT */
1195 return ( vm_map_store_lookup_entry( map
, address
, entry
));
1199 * Routine: vm_map_find_space
1201 * Allocate a range in the specified virtual address map,
1202 * returning the entry allocated for that range.
1203 * Used by kmem_alloc, etc.
1205 * The map must be NOT be locked. It will be returned locked
1206 * on KERN_SUCCESS, unlocked on failure.
1208 * If an entry is allocated, the object/offset fields
1209 * are initialized to zero.
1213 register vm_map_t map
,
1214 vm_map_offset_t
*address
, /* OUT */
1216 vm_map_offset_t mask
,
1218 vm_map_entry_t
*o_entry
) /* OUT */
1220 register vm_map_entry_t entry
, new_entry
;
1221 register vm_map_offset_t start
;
1222 register vm_map_offset_t end
;
1226 return KERN_INVALID_ARGUMENT
;
1229 if (flags
& VM_FLAGS_GUARD_AFTER
) {
1230 /* account for the back guard page in the size */
1231 size
+= VM_MAP_PAGE_SIZE(map
);
1234 new_entry
= vm_map_entry_create(map
, FALSE
);
1237 * Look for the first possible address; if there's already
1238 * something at this address, we have to start after it.
1243 if( map
->disable_vmentry_reuse
== TRUE
) {
1244 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
1246 assert(first_free_is_valid(map
));
1247 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1248 start
= map
->min_offset
;
1250 start
= entry
->vme_end
;
1254 * In any case, the "entry" always precedes
1255 * the proposed new region throughout the loop:
1259 register vm_map_entry_t next
;
1262 * Find the end of the proposed new region.
1263 * Be sure we didn't go beyond the end, or
1264 * wrap around the address.
1267 if (flags
& VM_FLAGS_GUARD_BEFORE
) {
1268 /* reserve space for the front guard page */
1269 start
+= VM_MAP_PAGE_SIZE(map
);
1271 end
= ((start
+ mask
) & ~mask
);
1274 vm_map_entry_dispose(map
, new_entry
);
1276 return(KERN_NO_SPACE
);
1281 if ((end
> map
->max_offset
) || (end
< start
)) {
1282 vm_map_entry_dispose(map
, new_entry
);
1284 return(KERN_NO_SPACE
);
1288 * If there are no more entries, we must win.
1291 next
= entry
->vme_next
;
1292 if (next
== vm_map_to_entry(map
))
1296 * If there is another entry, it must be
1297 * after the end of the potential new region.
1300 if (next
->vme_start
>= end
)
1304 * Didn't fit -- move to the next entry.
1308 start
= entry
->vme_end
;
1313 * "start" and "end" should define the endpoints of the
1314 * available new range, and
1315 * "entry" should refer to the region before the new
1318 * the map should be locked.
1321 if (flags
& VM_FLAGS_GUARD_BEFORE
) {
1322 /* go back for the front guard page */
1323 start
-= VM_MAP_PAGE_SIZE(map
);
1327 assert(start
< end
);
1328 new_entry
->vme_start
= start
;
1329 new_entry
->vme_end
= end
;
1330 assert(page_aligned(new_entry
->vme_start
));
1331 assert(page_aligned(new_entry
->vme_end
));
1332 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_start
,
1333 VM_MAP_PAGE_MASK(map
)));
1334 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_end
,
1335 VM_MAP_PAGE_MASK(map
)));
1337 new_entry
->is_shared
= FALSE
;
1338 new_entry
->is_sub_map
= FALSE
;
1339 new_entry
->use_pmap
= TRUE
;
1340 new_entry
->object
.vm_object
= VM_OBJECT_NULL
;
1341 new_entry
->offset
= (vm_object_offset_t
) 0;
1343 new_entry
->needs_copy
= FALSE
;
1345 new_entry
->inheritance
= VM_INHERIT_DEFAULT
;
1346 new_entry
->protection
= VM_PROT_DEFAULT
;
1347 new_entry
->max_protection
= VM_PROT_ALL
;
1348 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
1349 new_entry
->wired_count
= 0;
1350 new_entry
->user_wired_count
= 0;
1352 new_entry
->in_transition
= FALSE
;
1353 new_entry
->needs_wakeup
= FALSE
;
1354 new_entry
->no_cache
= FALSE
;
1355 new_entry
->permanent
= FALSE
;
1356 new_entry
->superpage_size
= FALSE
;
1357 if (VM_MAP_PAGE_SHIFT(map
) != PAGE_SHIFT
) {
1358 new_entry
->map_aligned
= TRUE
;
1360 new_entry
->map_aligned
= FALSE
;
1363 new_entry
->used_for_jit
= 0;
1365 new_entry
->alias
= 0;
1366 new_entry
->zero_wired_pages
= FALSE
;
1367 new_entry
->iokit_acct
= FALSE
;
1369 VM_GET_FLAGS_ALIAS(flags
, new_entry
->alias
);
1372 * Insert the new entry into the list
1375 vm_map_store_entry_link(map
, entry
, new_entry
);
1380 * Update the lookup hint
1382 SAVE_HINT_MAP_WRITE(map
, new_entry
);
1384 *o_entry
= new_entry
;
1385 return(KERN_SUCCESS
);
1388 int vm_map_pmap_enter_print
= FALSE
;
1389 int vm_map_pmap_enter_enable
= FALSE
;
1392 * Routine: vm_map_pmap_enter [internal only]
1395 * Force pages from the specified object to be entered into
1396 * the pmap at the specified address if they are present.
1397 * As soon as a page not found in the object the scan ends.
1402 * In/out conditions:
1403 * The source map should not be locked on entry.
1405 __unused
static void
1408 register vm_map_offset_t addr
,
1409 register vm_map_offset_t end_addr
,
1410 register vm_object_t object
,
1411 vm_object_offset_t offset
,
1412 vm_prot_t protection
)
1420 while (addr
< end_addr
) {
1421 register vm_page_t m
;
1426 * From vm_map_enter(), we come into this function without the map
1427 * lock held or the object lock held.
1428 * We haven't taken a reference on the object either.
1429 * We should do a proper lookup on the map to make sure
1430 * that things are sane before we go locking objects that
1431 * could have been deallocated from under us.
1434 vm_object_lock(object
);
1436 m
= vm_page_lookup(object
, offset
);
1439 * The user should never see encrypted data, so do not
1440 * enter an encrypted page in the page table.
1442 if (m
== VM_PAGE_NULL
|| m
->busy
|| m
->encrypted
||
1444 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
))) {
1445 vm_object_unlock(object
);
1449 if (vm_map_pmap_enter_print
) {
1450 printf("vm_map_pmap_enter:");
1451 printf("map: %p, addr: %llx, object: %p, offset: %llx\n",
1452 map
, (unsigned long long)addr
, object
, (unsigned long long)offset
);
1454 type_of_fault
= DBG_CACHE_HIT_FAULT
;
1455 kr
= vm_fault_enter(m
, map
->pmap
, addr
, protection
, protection
,
1456 VM_PAGE_WIRED(m
), FALSE
, FALSE
, FALSE
,
1457 0, /* XXX need user tag / alias? */
1458 0, /* alternate accounting? */
1462 vm_object_unlock(object
);
1464 offset
+= PAGE_SIZE_64
;
1469 boolean_t
vm_map_pmap_is_empty(
1471 vm_map_offset_t start
,
1472 vm_map_offset_t end
);
1473 boolean_t
vm_map_pmap_is_empty(
1475 vm_map_offset_t start
,
1476 vm_map_offset_t end
)
1478 #ifdef MACHINE_PMAP_IS_EMPTY
1479 return pmap_is_empty(map
->pmap
, start
, end
);
1480 #else /* MACHINE_PMAP_IS_EMPTY */
1481 vm_map_offset_t offset
;
1484 if (map
->pmap
== NULL
) {
1488 for (offset
= start
;
1490 offset
+= PAGE_SIZE
) {
1491 phys_page
= pmap_find_phys(map
->pmap
, offset
);
1493 kprintf("vm_map_pmap_is_empty(%p,0x%llx,0x%llx): "
1494 "page %d at 0x%llx\n",
1495 map
, (long long)start
, (long long)end
,
1496 phys_page
, (long long)offset
);
1501 #endif /* MACHINE_PMAP_IS_EMPTY */
1504 #define MAX_TRIES_TO_GET_RANDOM_ADDRESS 1000
1506 vm_map_random_address_for_size(
1508 vm_map_offset_t
*address
,
1511 kern_return_t kr
= KERN_SUCCESS
;
1513 vm_map_offset_t random_addr
= 0;
1514 vm_map_offset_t hole_end
;
1516 vm_map_entry_t next_entry
= VM_MAP_ENTRY_NULL
;
1517 vm_map_entry_t prev_entry
= VM_MAP_ENTRY_NULL
;
1518 vm_map_size_t vm_hole_size
= 0;
1519 vm_map_size_t addr_space_size
;
1521 addr_space_size
= vm_map_max(map
) - vm_map_min(map
);
1523 assert(page_aligned(size
));
1525 while (tries
< MAX_TRIES_TO_GET_RANDOM_ADDRESS
) {
1526 random_addr
= ((vm_map_offset_t
)random()) << PAGE_SHIFT
;
1527 random_addr
= vm_map_trunc_page(
1528 vm_map_min(map
) +(random_addr
% addr_space_size
),
1529 VM_MAP_PAGE_MASK(map
));
1531 if (vm_map_lookup_entry(map
, random_addr
, &prev_entry
) == FALSE
) {
1532 if (prev_entry
== vm_map_to_entry(map
)) {
1533 next_entry
= vm_map_first_entry(map
);
1535 next_entry
= prev_entry
->vme_next
;
1537 if (next_entry
== vm_map_to_entry(map
)) {
1538 hole_end
= vm_map_max(map
);
1540 hole_end
= next_entry
->vme_start
;
1542 vm_hole_size
= hole_end
- random_addr
;
1543 if (vm_hole_size
>= size
) {
1544 *address
= random_addr
;
1551 if (tries
== MAX_TRIES_TO_GET_RANDOM_ADDRESS
) {
1558 * Routine: vm_map_enter
1561 * Allocate a range in the specified virtual address map.
1562 * The resulting range will refer to memory defined by
1563 * the given memory object and offset into that object.
1565 * Arguments are as defined in the vm_map call.
1567 int _map_enter_debug
= 0;
1568 static unsigned int vm_map_enter_restore_successes
= 0;
1569 static unsigned int vm_map_enter_restore_failures
= 0;
1573 vm_map_offset_t
*address
, /* IN/OUT */
1575 vm_map_offset_t mask
,
1578 vm_object_offset_t offset
,
1579 boolean_t needs_copy
,
1580 vm_prot_t cur_protection
,
1581 vm_prot_t max_protection
,
1582 vm_inherit_t inheritance
)
1584 vm_map_entry_t entry
, new_entry
;
1585 vm_map_offset_t start
, tmp_start
, tmp_offset
;
1586 vm_map_offset_t end
, tmp_end
;
1587 vm_map_offset_t tmp2_start
, tmp2_end
;
1588 vm_map_offset_t step
;
1589 kern_return_t result
= KERN_SUCCESS
;
1590 vm_map_t zap_old_map
= VM_MAP_NULL
;
1591 vm_map_t zap_new_map
= VM_MAP_NULL
;
1592 boolean_t map_locked
= FALSE
;
1593 boolean_t pmap_empty
= TRUE
;
1594 boolean_t new_mapping_established
= FALSE
;
1595 boolean_t keep_map_locked
= ((flags
& VM_FLAGS_KEEP_MAP_LOCKED
) != 0);
1596 boolean_t anywhere
= ((flags
& VM_FLAGS_ANYWHERE
) != 0);
1597 boolean_t purgable
= ((flags
& VM_FLAGS_PURGABLE
) != 0);
1598 boolean_t overwrite
= ((flags
& VM_FLAGS_OVERWRITE
) != 0);
1599 boolean_t no_cache
= ((flags
& VM_FLAGS_NO_CACHE
) != 0);
1600 boolean_t is_submap
= ((flags
& VM_FLAGS_SUBMAP
) != 0);
1601 boolean_t permanent
= ((flags
& VM_FLAGS_PERMANENT
) != 0);
1602 boolean_t entry_for_jit
= ((flags
& VM_FLAGS_MAP_JIT
) != 0);
1603 boolean_t iokit_acct
= ((flags
& VM_FLAGS_IOKIT_ACCT
) != 0);
1604 unsigned int superpage_size
= ((flags
& VM_FLAGS_SUPERPAGE_MASK
) >> VM_FLAGS_SUPERPAGE_SHIFT
);
1606 vm_map_offset_t effective_min_offset
, effective_max_offset
;
1608 boolean_t clear_map_aligned
= FALSE
;
1610 if (superpage_size
) {
1611 switch (superpage_size
) {
1613 * Note that the current implementation only supports
1614 * a single size for superpages, SUPERPAGE_SIZE, per
1615 * architecture. As soon as more sizes are supposed
1616 * to be supported, SUPERPAGE_SIZE has to be replaced
1617 * with a lookup of the size depending on superpage_size.
1620 case SUPERPAGE_SIZE_ANY
:
1621 /* handle it like 2 MB and round up to page size */
1622 size
= (size
+ 2*1024*1024 - 1) & ~(2*1024*1024 - 1);
1623 case SUPERPAGE_SIZE_2MB
:
1627 return KERN_INVALID_ARGUMENT
;
1629 mask
= SUPERPAGE_SIZE
-1;
1630 if (size
& (SUPERPAGE_SIZE
-1))
1631 return KERN_INVALID_ARGUMENT
;
1632 inheritance
= VM_INHERIT_NONE
; /* fork() children won't inherit superpages */
1639 /* submaps can not be purgeable */
1640 return KERN_INVALID_ARGUMENT
;
1642 if (object
== VM_OBJECT_NULL
) {
1643 /* submaps can not be created lazily */
1644 return KERN_INVALID_ARGUMENT
;
1647 if (flags
& VM_FLAGS_ALREADY
) {
1649 * VM_FLAGS_ALREADY says that it's OK if the same mapping
1650 * is already present. For it to be meaningul, the requested
1651 * mapping has to be at a fixed address (!VM_FLAGS_ANYWHERE) and
1652 * we shouldn't try and remove what was mapped there first
1653 * (!VM_FLAGS_OVERWRITE).
1655 if ((flags
& VM_FLAGS_ANYWHERE
) ||
1656 (flags
& VM_FLAGS_OVERWRITE
)) {
1657 return KERN_INVALID_ARGUMENT
;
1661 effective_min_offset
= map
->min_offset
;
1663 if (flags
& VM_FLAGS_BEYOND_MAX
) {
1665 * Allow an insertion beyond the map's max offset.
1667 if (vm_map_is_64bit(map
))
1668 effective_max_offset
= 0xFFFFFFFFFFFFF000ULL
;
1670 effective_max_offset
= 0x00000000FFFFF000ULL
;
1672 effective_max_offset
= map
->max_offset
;
1676 (offset
& PAGE_MASK_64
) != 0) {
1678 return KERN_INVALID_ARGUMENT
;
1681 VM_GET_FLAGS_ALIAS(flags
, alias
);
1683 #define RETURN(value) { result = value; goto BailOut; }
1685 assert(page_aligned(*address
));
1686 assert(page_aligned(size
));
1688 if (!VM_MAP_PAGE_ALIGNED(size
, VM_MAP_PAGE_MASK(map
))) {
1690 * In most cases, the caller rounds the size up to the
1692 * If we get a size that is explicitly not map-aligned here,
1693 * we'll have to respect the caller's wish and mark the
1694 * mapping as "not map-aligned" to avoid tripping the
1695 * map alignment checks later.
1697 clear_map_aligned
= TRUE
;
1700 !VM_MAP_PAGE_ALIGNED(*address
, VM_MAP_PAGE_MASK(map
))) {
1702 * We've been asked to map at a fixed address and that
1703 * address is not aligned to the map's specific alignment.
1704 * The caller should know what it's doing (i.e. most likely
1705 * mapping some fragmented copy map, transferring memory from
1706 * a VM map with a different alignment), so clear map_aligned
1707 * for this new VM map entry and proceed.
1709 clear_map_aligned
= TRUE
;
1713 * Only zero-fill objects are allowed to be purgable.
1714 * LP64todo - limit purgable objects to 32-bits for now
1718 (object
!= VM_OBJECT_NULL
&&
1719 (object
->vo_size
!= size
||
1720 object
->purgable
== VM_PURGABLE_DENY
))
1721 || size
> ANON_MAX_SIZE
)) /* LP64todo: remove when dp capable */
1722 return KERN_INVALID_ARGUMENT
;
1724 if (!anywhere
&& overwrite
) {
1726 * Create a temporary VM map to hold the old mappings in the
1727 * affected area while we create the new one.
1728 * This avoids releasing the VM map lock in
1729 * vm_map_entry_delete() and allows atomicity
1730 * when we want to replace some mappings with a new one.
1731 * It also allows us to restore the old VM mappings if the
1732 * new mapping fails.
1734 zap_old_map
= vm_map_create(PMAP_NULL
,
1737 map
->hdr
.entries_pageable
);
1738 vm_map_set_page_shift(zap_old_map
, VM_MAP_PAGE_SHIFT(map
));
1749 if (entry_for_jit
) {
1750 if (map
->jit_entry_exists
) {
1751 result
= KERN_INVALID_ARGUMENT
;
1755 * Get a random start address.
1757 result
= vm_map_random_address_for_size(map
, address
, size
);
1758 if (result
!= KERN_SUCCESS
) {
1766 * Calculate the first possible address.
1769 if (start
< effective_min_offset
)
1770 start
= effective_min_offset
;
1771 if (start
> effective_max_offset
)
1772 RETURN(KERN_NO_SPACE
);
1775 * Look for the first possible address;
1776 * if there's already something at this
1777 * address, we have to start after it.
1780 if( map
->disable_vmentry_reuse
== TRUE
) {
1781 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
1783 assert(first_free_is_valid(map
));
1785 entry
= map
->first_free
;
1787 if (entry
== vm_map_to_entry(map
)) {
1790 if (entry
->vme_next
== vm_map_to_entry(map
)){
1792 * Hole at the end of the map.
1796 if (start
< (entry
->vme_next
)->vme_start
) {
1797 start
= entry
->vme_end
;
1798 start
= vm_map_round_page(start
,
1799 VM_MAP_PAGE_MASK(map
));
1802 * Need to do a lookup.
1809 if (entry
== NULL
) {
1810 vm_map_entry_t tmp_entry
;
1811 if (vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
1812 assert(!entry_for_jit
);
1813 start
= tmp_entry
->vme_end
;
1814 start
= vm_map_round_page(start
,
1815 VM_MAP_PAGE_MASK(map
));
1822 * In any case, the "entry" always precedes
1823 * the proposed new region throughout the
1828 register vm_map_entry_t next
;
1831 * Find the end of the proposed new region.
1832 * Be sure we didn't go beyond the end, or
1833 * wrap around the address.
1836 end
= ((start
+ mask
) & ~mask
);
1837 end
= vm_map_round_page(end
,
1838 VM_MAP_PAGE_MASK(map
));
1840 RETURN(KERN_NO_SPACE
);
1842 assert(VM_MAP_PAGE_ALIGNED(start
,
1843 VM_MAP_PAGE_MASK(map
)));
1846 if ((end
> effective_max_offset
) || (end
< start
)) {
1847 if (map
->wait_for_space
) {
1848 assert(!keep_map_locked
);
1849 if (size
<= (effective_max_offset
-
1850 effective_min_offset
)) {
1851 assert_wait((event_t
)map
,
1855 thread_block(THREAD_CONTINUE_NULL
);
1859 RETURN(KERN_NO_SPACE
);
1863 * If there are no more entries, we must win.
1866 next
= entry
->vme_next
;
1867 if (next
== vm_map_to_entry(map
))
1871 * If there is another entry, it must be
1872 * after the end of the potential new region.
1875 if (next
->vme_start
>= end
)
1879 * Didn't fit -- move to the next entry.
1883 start
= entry
->vme_end
;
1884 start
= vm_map_round_page(start
,
1885 VM_MAP_PAGE_MASK(map
));
1888 assert(VM_MAP_PAGE_ALIGNED(*address
,
1889 VM_MAP_PAGE_MASK(map
)));
1893 * the address doesn't itself violate
1894 * the mask requirement.
1899 if ((start
& mask
) != 0)
1900 RETURN(KERN_NO_SPACE
);
1903 * ... the address is within bounds
1908 if ((start
< effective_min_offset
) ||
1909 (end
> effective_max_offset
) ||
1911 RETURN(KERN_INVALID_ADDRESS
);
1914 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
1916 * Fixed mapping and "overwrite" flag: attempt to
1917 * remove all existing mappings in the specified
1918 * address range, saving them in our "zap_old_map".
1920 (void) vm_map_delete(map
, start
, end
,
1921 (VM_MAP_REMOVE_SAVE_ENTRIES
|
1922 VM_MAP_REMOVE_NO_MAP_ALIGN
),
1927 * ... the starting address isn't allocated
1930 if (vm_map_lookup_entry(map
, start
, &entry
)) {
1931 if (! (flags
& VM_FLAGS_ALREADY
)) {
1932 RETURN(KERN_NO_SPACE
);
1935 * Check if what's already there is what we want.
1938 tmp_offset
= offset
;
1939 if (entry
->vme_start
< start
) {
1940 tmp_start
-= start
- entry
->vme_start
;
1941 tmp_offset
-= start
- entry
->vme_start
;
1944 for (; entry
->vme_start
< end
;
1945 entry
= entry
->vme_next
) {
1947 * Check if the mapping's attributes
1948 * match the existing map entry.
1950 if (entry
== vm_map_to_entry(map
) ||
1951 entry
->vme_start
!= tmp_start
||
1952 entry
->is_sub_map
!= is_submap
||
1953 entry
->offset
!= tmp_offset
||
1954 entry
->needs_copy
!= needs_copy
||
1955 entry
->protection
!= cur_protection
||
1956 entry
->max_protection
!= max_protection
||
1957 entry
->inheritance
!= inheritance
||
1958 entry
->iokit_acct
!= iokit_acct
||
1959 entry
->alias
!= alias
) {
1960 /* not the same mapping ! */
1961 RETURN(KERN_NO_SPACE
);
1964 * Check if the same object is being mapped.
1967 if (entry
->object
.sub_map
!=
1968 (vm_map_t
) object
) {
1969 /* not the same submap */
1970 RETURN(KERN_NO_SPACE
);
1973 if (entry
->object
.vm_object
!= object
) {
1974 /* not the same VM object... */
1977 obj2
= entry
->object
.vm_object
;
1978 if ((obj2
== VM_OBJECT_NULL
||
1980 (object
== VM_OBJECT_NULL
||
1981 object
->internal
)) {
1988 RETURN(KERN_NO_SPACE
);
1993 tmp_offset
+= entry
->vme_end
- entry
->vme_start
;
1994 tmp_start
+= entry
->vme_end
- entry
->vme_start
;
1995 if (entry
->vme_end
>= end
) {
1996 /* reached the end of our mapping */
2000 /* it all matches: let's use what's already there ! */
2001 RETURN(KERN_MEMORY_PRESENT
);
2005 * ... the next region doesn't overlap the
2009 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
2010 (entry
->vme_next
->vme_start
< end
))
2011 RETURN(KERN_NO_SPACE
);
2016 * "start" and "end" should define the endpoints of the
2017 * available new range, and
2018 * "entry" should refer to the region before the new
2021 * the map should be locked.
2025 * See whether we can avoid creating a new entry (and object) by
2026 * extending one of our neighbors. [So far, we only attempt to
2027 * extend from below.] Note that we can never extend/join
2028 * purgable objects because they need to remain distinct
2029 * entities in order to implement their "volatile object"
2033 if (purgable
|| entry_for_jit
) {
2034 if (object
== VM_OBJECT_NULL
) {
2035 object
= vm_object_allocate(size
);
2036 object
->copy_strategy
= MEMORY_OBJECT_COPY_NONE
;
2037 object
->true_share
= TRUE
;
2040 object
->purgable
= VM_PURGABLE_NONVOLATILE
;
2041 if (map
->pmap
== kernel_pmap
) {
2043 * Purgeable mappings made in a kernel
2044 * map are "owned" by the kernel itself
2045 * rather than the current user task
2046 * because they're likely to be used by
2047 * more than this user task (see
2048 * execargs_purgeable_allocate(), for
2051 owner
= kernel_task
;
2053 owner
= current_task();
2055 assert(object
->vo_purgeable_owner
== NULL
);
2056 assert(object
->resident_page_count
== 0);
2057 assert(object
->wired_page_count
== 0);
2058 vm_object_lock(object
);
2059 vm_purgeable_nonvolatile_enqueue(object
, owner
);
2060 vm_object_unlock(object
);
2062 offset
= (vm_object_offset_t
)0;
2064 } else if ((is_submap
== FALSE
) &&
2065 (object
== VM_OBJECT_NULL
) &&
2066 (entry
!= vm_map_to_entry(map
)) &&
2067 (entry
->vme_end
== start
) &&
2068 (!entry
->is_shared
) &&
2069 (!entry
->is_sub_map
) &&
2070 (!entry
->in_transition
) &&
2071 (!entry
->needs_wakeup
) &&
2072 (entry
->behavior
== VM_BEHAVIOR_DEFAULT
) &&
2073 (entry
->protection
== cur_protection
) &&
2074 (entry
->max_protection
== max_protection
) &&
2075 (entry
->inheritance
== inheritance
) &&
2076 ((alias
== VM_MEMORY_REALLOC
) || (entry
->alias
== alias
)) &&
2077 (entry
->no_cache
== no_cache
) &&
2078 (entry
->permanent
== permanent
) &&
2079 (!entry
->superpage_size
&& !superpage_size
) &&
2081 * No coalescing if not map-aligned, to avoid propagating
2082 * that condition any further than needed:
2084 (!entry
->map_aligned
|| !clear_map_aligned
) &&
2085 (!entry
->zero_wired_pages
) &&
2086 (!entry
->used_for_jit
&& !entry_for_jit
) &&
2087 (entry
->iokit_acct
== iokit_acct
) &&
2089 ((entry
->vme_end
- entry
->vme_start
) + size
<=
2090 (alias
== VM_MEMORY_REALLOC
?
2092 NO_COALESCE_LIMIT
)) &&
2094 (entry
->wired_count
== 0)) { /* implies user_wired_count == 0 */
2095 if (vm_object_coalesce(entry
->object
.vm_object
,
2098 (vm_object_offset_t
) 0,
2099 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
),
2100 (vm_map_size_t
)(end
- entry
->vme_end
))) {
2103 * Coalesced the two objects - can extend
2104 * the previous map entry to include the
2107 map
->size
+= (end
- entry
->vme_end
);
2108 assert(entry
->vme_start
< end
);
2109 assert(VM_MAP_PAGE_ALIGNED(end
,
2110 VM_MAP_PAGE_MASK(map
)));
2111 entry
->vme_end
= end
;
2112 vm_map_store_update_first_free(map
, map
->first_free
);
2113 new_mapping_established
= TRUE
;
2114 RETURN(KERN_SUCCESS
);
2118 step
= superpage_size
? SUPERPAGE_SIZE
: (end
- start
);
2121 for (tmp2_start
= start
; tmp2_start
<end
; tmp2_start
+= step
) {
2122 tmp2_end
= tmp2_start
+ step
;
2124 * Create a new entry
2125 * LP64todo - for now, we can only allocate 4GB internal objects
2126 * because the default pager can't page bigger ones. Remove this
2130 * The reserved "page zero" in each process's address space can
2131 * be arbitrarily large. Splitting it into separate 4GB objects and
2132 * therefore different VM map entries serves no purpose and just
2133 * slows down operations on the VM map, so let's not split the
2134 * allocation into 4GB chunks if the max protection is NONE. That
2135 * memory should never be accessible, so it will never get to the
2138 tmp_start
= tmp2_start
;
2139 if (object
== VM_OBJECT_NULL
&&
2140 size
> (vm_map_size_t
)ANON_CHUNK_SIZE
&&
2141 max_protection
!= VM_PROT_NONE
&&
2142 superpage_size
== 0)
2143 tmp_end
= tmp_start
+ (vm_map_size_t
)ANON_CHUNK_SIZE
;
2147 new_entry
= vm_map_entry_insert(map
, entry
, tmp_start
, tmp_end
,
2148 object
, offset
, needs_copy
,
2150 cur_protection
, max_protection
,
2151 VM_BEHAVIOR_DEFAULT
,
2152 (entry_for_jit
)? VM_INHERIT_NONE
: inheritance
,
2158 new_entry
->alias
= alias
;
2160 if (!(map
->jit_entry_exists
)){
2161 new_entry
->used_for_jit
= TRUE
;
2162 map
->jit_entry_exists
= TRUE
;
2166 assert(!new_entry
->iokit_acct
);
2168 object
!= VM_OBJECT_NULL
&&
2169 object
->purgable
!= VM_PURGABLE_DENY
) {
2170 assert(new_entry
->use_pmap
);
2171 assert(!new_entry
->iokit_acct
);
2173 * Turn off pmap accounting since
2174 * purgeable objects have their
2177 new_entry
->use_pmap
= FALSE
;
2178 } else if (!is_submap
&&
2180 /* alternate accounting */
2181 assert(!new_entry
->iokit_acct
);
2182 assert(new_entry
->use_pmap
);
2183 new_entry
->iokit_acct
= TRUE
;
2184 new_entry
->use_pmap
= FALSE
;
2185 vm_map_iokit_mapped_region(
2187 (new_entry
->vme_end
-
2188 new_entry
->vme_start
));
2189 } else if (!is_submap
) {
2190 assert(!new_entry
->iokit_acct
);
2191 assert(new_entry
->use_pmap
);
2196 boolean_t submap_is_64bit
;
2199 assert(new_entry
->is_sub_map
);
2200 assert(!new_entry
->use_pmap
);
2201 assert(!new_entry
->iokit_acct
);
2202 submap
= (vm_map_t
) object
;
2203 submap_is_64bit
= vm_map_is_64bit(submap
);
2204 use_pmap
= (alias
== VM_MEMORY_SHARED_PMAP
);
2205 #ifndef NO_NESTED_PMAP
2206 if (use_pmap
&& submap
->pmap
== NULL
) {
2207 ledger_t ledger
= map
->pmap
->ledger
;
2208 /* we need a sub pmap to nest... */
2209 submap
->pmap
= pmap_create(ledger
, 0,
2211 if (submap
->pmap
== NULL
) {
2212 /* let's proceed without nesting... */
2215 if (use_pmap
&& submap
->pmap
!= NULL
) {
2216 kr
= pmap_nest(map
->pmap
,
2220 tmp_end
- tmp_start
);
2221 if (kr
!= KERN_SUCCESS
) {
2222 printf("vm_map_enter: "
2223 "pmap_nest(0x%llx,0x%llx) "
2225 (long long)tmp_start
,
2229 /* we're now nested ! */
2230 new_entry
->use_pmap
= TRUE
;
2234 #endif /* NO_NESTED_PMAP */
2238 if (superpage_size
) {
2240 vm_object_t sp_object
;
2244 /* allocate one superpage */
2245 kr
= cpm_allocate(SUPERPAGE_SIZE
, &pages
, 0, SUPERPAGE_NBASEPAGES
-1, TRUE
, 0);
2246 if (kr
!= KERN_SUCCESS
) {
2247 new_mapping_established
= TRUE
; /* will cause deallocation of whole range */
2251 /* create one vm_object per superpage */
2252 sp_object
= vm_object_allocate((vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
2253 sp_object
->phys_contiguous
= TRUE
;
2254 sp_object
->vo_shadow_offset
= (vm_object_offset_t
)pages
->phys_page
*PAGE_SIZE
;
2255 entry
->object
.vm_object
= sp_object
;
2256 assert(entry
->use_pmap
);
2258 /* enter the base pages into the object */
2259 vm_object_lock(sp_object
);
2260 for (offset
= 0; offset
< SUPERPAGE_SIZE
; offset
+= PAGE_SIZE
) {
2262 pmap_zero_page(m
->phys_page
);
2263 pages
= NEXT_PAGE(m
);
2264 *(NEXT_PAGE_PTR(m
)) = VM_PAGE_NULL
;
2265 vm_page_insert(m
, sp_object
, offset
);
2267 vm_object_unlock(sp_object
);
2269 } while (tmp_end
!= tmp2_end
&&
2270 (tmp_start
= tmp_end
) &&
2271 (tmp_end
= (tmp2_end
- tmp_end
> (vm_map_size_t
)ANON_CHUNK_SIZE
) ?
2272 tmp_end
+ (vm_map_size_t
)ANON_CHUNK_SIZE
: tmp2_end
));
2275 new_mapping_established
= TRUE
;
2278 assert(map_locked
== TRUE
);
2280 if (result
== KERN_SUCCESS
) {
2281 vm_prot_t pager_prot
;
2282 memory_object_t pager
;
2286 !(flags
& VM_FLAGS_NO_PMAP_CHECK
)) {
2287 assert(vm_map_pmap_is_empty(map
,
2294 * For "named" VM objects, let the pager know that the
2295 * memory object is being mapped. Some pagers need to keep
2296 * track of this, to know when they can reclaim the memory
2297 * object, for example.
2298 * VM calls memory_object_map() for each mapping (specifying
2299 * the protection of each mapping) and calls
2300 * memory_object_last_unmap() when all the mappings are gone.
2302 pager_prot
= max_protection
;
2305 * Copy-On-Write mapping: won't modify
2306 * the memory object.
2308 pager_prot
&= ~VM_PROT_WRITE
;
2311 object
!= VM_OBJECT_NULL
&&
2313 object
->pager
!= MEMORY_OBJECT_NULL
) {
2314 vm_object_lock(object
);
2315 pager
= object
->pager
;
2316 if (object
->named
&&
2317 pager
!= MEMORY_OBJECT_NULL
) {
2318 assert(object
->pager_ready
);
2319 vm_object_mapping_wait(object
, THREAD_UNINT
);
2320 vm_object_mapping_begin(object
);
2321 vm_object_unlock(object
);
2323 kr
= memory_object_map(pager
, pager_prot
);
2324 assert(kr
== KERN_SUCCESS
);
2326 vm_object_lock(object
);
2327 vm_object_mapping_end(object
);
2329 vm_object_unlock(object
);
2333 assert(map_locked
== TRUE
);
2335 if (!keep_map_locked
) {
2341 * We can't hold the map lock if we enter this block.
2344 if (result
== KERN_SUCCESS
) {
2346 /* Wire down the new entry if the user
2347 * requested all new map entries be wired.
2349 if ((map
->wiring_required
)||(superpage_size
)) {
2350 assert(!keep_map_locked
);
2351 pmap_empty
= FALSE
; /* pmap won't be empty */
2352 kr
= vm_map_wire(map
, start
, end
,
2353 new_entry
->protection
, TRUE
);
2359 if (result
!= KERN_SUCCESS
) {
2360 if (new_mapping_established
) {
2362 * We have to get rid of the new mappings since we
2363 * won't make them available to the user.
2364 * Try and do that atomically, to minimize the risk
2365 * that someone else create new mappings that range.
2367 zap_new_map
= vm_map_create(PMAP_NULL
,
2370 map
->hdr
.entries_pageable
);
2371 vm_map_set_page_shift(zap_new_map
,
2372 VM_MAP_PAGE_SHIFT(map
));
2377 (void) vm_map_delete(map
, *address
, *address
+size
,
2378 (VM_MAP_REMOVE_SAVE_ENTRIES
|
2379 VM_MAP_REMOVE_NO_MAP_ALIGN
),
2382 if (zap_old_map
!= VM_MAP_NULL
&&
2383 zap_old_map
->hdr
.nentries
!= 0) {
2384 vm_map_entry_t entry1
, entry2
;
2387 * The new mapping failed. Attempt to restore
2388 * the old mappings, saved in the "zap_old_map".
2395 /* first check if the coast is still clear */
2396 start
= vm_map_first_entry(zap_old_map
)->vme_start
;
2397 end
= vm_map_last_entry(zap_old_map
)->vme_end
;
2398 if (vm_map_lookup_entry(map
, start
, &entry1
) ||
2399 vm_map_lookup_entry(map
, end
, &entry2
) ||
2402 * Part of that range has already been
2403 * re-mapped: we can't restore the old
2406 vm_map_enter_restore_failures
++;
2409 * Transfer the saved map entries from
2410 * "zap_old_map" to the original "map",
2411 * inserting them all after "entry1".
2413 for (entry2
= vm_map_first_entry(zap_old_map
);
2414 entry2
!= vm_map_to_entry(zap_old_map
);
2415 entry2
= vm_map_first_entry(zap_old_map
)) {
2416 vm_map_size_t entry_size
;
2418 entry_size
= (entry2
->vme_end
-
2420 vm_map_store_entry_unlink(zap_old_map
,
2422 zap_old_map
->size
-= entry_size
;
2423 vm_map_store_entry_link(map
, entry1
, entry2
);
2424 map
->size
+= entry_size
;
2427 if (map
->wiring_required
) {
2429 * XXX TODO: we should rewire the
2433 vm_map_enter_restore_successes
++;
2439 * The caller is responsible for releasing the lock if it requested to
2440 * keep the map locked.
2442 if (map_locked
&& !keep_map_locked
) {
2447 * Get rid of the "zap_maps" and all the map entries that
2448 * they may still contain.
2450 if (zap_old_map
!= VM_MAP_NULL
) {
2451 vm_map_destroy(zap_old_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
2452 zap_old_map
= VM_MAP_NULL
;
2454 if (zap_new_map
!= VM_MAP_NULL
) {
2455 vm_map_destroy(zap_new_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
2456 zap_new_map
= VM_MAP_NULL
;
2465 * Counters for the prefault optimization.
2467 int64_t vm_prefault_nb_pages
= 0;
2468 int64_t vm_prefault_nb_bailout
= 0;
2470 static kern_return_t
2471 vm_map_enter_mem_object_helper(
2472 vm_map_t target_map
,
2473 vm_map_offset_t
*address
,
2474 vm_map_size_t initial_size
,
2475 vm_map_offset_t mask
,
2478 vm_object_offset_t offset
,
2480 vm_prot_t cur_protection
,
2481 vm_prot_t max_protection
,
2482 vm_inherit_t inheritance
,
2483 upl_page_list_ptr_t page_list
,
2484 unsigned int page_list_count
)
2486 vm_map_address_t map_addr
;
2487 vm_map_size_t map_size
;
2489 vm_object_size_t size
;
2490 kern_return_t result
;
2491 boolean_t mask_cur_protection
, mask_max_protection
;
2492 boolean_t try_prefault
= (page_list_count
!= 0);
2493 vm_map_offset_t offset_in_mapping
;
2495 mask_cur_protection
= cur_protection
& VM_PROT_IS_MASK
;
2496 mask_max_protection
= max_protection
& VM_PROT_IS_MASK
;
2497 cur_protection
&= ~VM_PROT_IS_MASK
;
2498 max_protection
&= ~VM_PROT_IS_MASK
;
2501 * Check arguments for validity
2503 if ((target_map
== VM_MAP_NULL
) ||
2504 (cur_protection
& ~VM_PROT_ALL
) ||
2505 (max_protection
& ~VM_PROT_ALL
) ||
2506 (inheritance
> VM_INHERIT_LAST_VALID
) ||
2507 (try_prefault
&& (copy
|| !page_list
)) ||
2509 return KERN_INVALID_ARGUMENT
;
2511 map_addr
= vm_map_trunc_page(*address
,
2512 VM_MAP_PAGE_MASK(target_map
));
2513 map_size
= vm_map_round_page(initial_size
,
2514 VM_MAP_PAGE_MASK(target_map
));
2515 size
= vm_object_round_page(initial_size
);
2518 * Find the vm object (if any) corresponding to this port.
2520 if (!IP_VALID(port
)) {
2521 object
= VM_OBJECT_NULL
;
2524 } else if (ip_kotype(port
) == IKOT_NAMED_ENTRY
) {
2525 vm_named_entry_t named_entry
;
2527 named_entry
= (vm_named_entry_t
) port
->ip_kobject
;
2529 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2530 offset
+= named_entry
->data_offset
;
2533 /* a few checks to make sure user is obeying rules */
2535 if (offset
>= named_entry
->size
)
2536 return KERN_INVALID_RIGHT
;
2537 size
= named_entry
->size
- offset
;
2539 if (mask_max_protection
) {
2540 max_protection
&= named_entry
->protection
;
2542 if (mask_cur_protection
) {
2543 cur_protection
&= named_entry
->protection
;
2545 if ((named_entry
->protection
& max_protection
) !=
2547 return KERN_INVALID_RIGHT
;
2548 if ((named_entry
->protection
& cur_protection
) !=
2550 return KERN_INVALID_RIGHT
;
2551 if (offset
+ size
< offset
) {
2553 return KERN_INVALID_ARGUMENT
;
2555 if (named_entry
->size
< (offset
+ size
))
2556 return KERN_INVALID_ARGUMENT
;
2558 if (named_entry
->is_copy
) {
2559 /* for a vm_map_copy, we can only map it whole */
2560 if ((size
!= named_entry
->size
) &&
2561 (vm_map_round_page(size
,
2562 VM_MAP_PAGE_MASK(target_map
)) ==
2563 named_entry
->size
)) {
2564 /* XXX FBDP use the rounded size... */
2565 size
= vm_map_round_page(
2567 VM_MAP_PAGE_MASK(target_map
));
2570 if (!(flags
& VM_FLAGS_ANYWHERE
) &&
2572 size
!= named_entry
->size
)) {
2574 * XXX for a mapping at a "fixed" address,
2575 * we can't trim after mapping the whole
2576 * memory entry, so reject a request for a
2579 return KERN_INVALID_ARGUMENT
;
2583 /* the callers parameter offset is defined to be the */
2584 /* offset from beginning of named entry offset in object */
2585 offset
= offset
+ named_entry
->offset
;
2587 if (! VM_MAP_PAGE_ALIGNED(size
,
2588 VM_MAP_PAGE_MASK(target_map
))) {
2590 * Let's not map more than requested;
2591 * vm_map_enter() will handle this "not map-aligned"
2597 named_entry_lock(named_entry
);
2598 if (named_entry
->is_sub_map
) {
2601 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2602 panic("VM_FLAGS_RETURN_DATA_ADDR not expected for submap.");
2605 submap
= named_entry
->backing
.map
;
2606 vm_map_lock(submap
);
2607 vm_map_reference(submap
);
2608 vm_map_unlock(submap
);
2609 named_entry_unlock(named_entry
);
2611 result
= vm_map_enter(target_map
,
2615 flags
| VM_FLAGS_SUBMAP
,
2616 (vm_object_t
) submap
,
2622 if (result
!= KERN_SUCCESS
) {
2623 vm_map_deallocate(submap
);
2626 * No need to lock "submap" just to check its
2627 * "mapped" flag: that flag is never reset
2628 * once it's been set and if we race, we'll
2629 * just end up setting it twice, which is OK.
2631 if (submap
->mapped_in_other_pmaps
== FALSE
&&
2632 vm_map_pmap(submap
) != PMAP_NULL
&&
2633 vm_map_pmap(submap
) !=
2634 vm_map_pmap(target_map
)) {
2636 * This submap is being mapped in a map
2637 * that uses a different pmap.
2638 * Set its "mapped_in_other_pmaps" flag
2639 * to indicate that we now need to
2640 * remove mappings from all pmaps rather
2641 * than just the submap's pmap.
2643 vm_map_lock(submap
);
2644 submap
->mapped_in_other_pmaps
= TRUE
;
2645 vm_map_unlock(submap
);
2647 *address
= map_addr
;
2651 } else if (named_entry
->is_pager
) {
2652 unsigned int access
;
2653 vm_prot_t protections
;
2654 unsigned int wimg_mode
;
2656 protections
= named_entry
->protection
& VM_PROT_ALL
;
2657 access
= GET_MAP_MEM(named_entry
->protection
);
2659 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2660 panic("VM_FLAGS_RETURN_DATA_ADDR not expected for submap.");
2663 object
= vm_object_enter(named_entry
->backing
.pager
,
2665 named_entry
->internal
,
2668 if (object
== VM_OBJECT_NULL
) {
2669 named_entry_unlock(named_entry
);
2670 return KERN_INVALID_OBJECT
;
2673 /* JMM - drop reference on pager here */
2675 /* create an extra ref for the named entry */
2676 vm_object_lock(object
);
2677 vm_object_reference_locked(object
);
2678 named_entry
->backing
.object
= object
;
2679 named_entry
->is_pager
= FALSE
;
2680 named_entry_unlock(named_entry
);
2682 wimg_mode
= object
->wimg_bits
;
2684 if (access
== MAP_MEM_IO
) {
2685 wimg_mode
= VM_WIMG_IO
;
2686 } else if (access
== MAP_MEM_COPYBACK
) {
2687 wimg_mode
= VM_WIMG_USE_DEFAULT
;
2688 } else if (access
== MAP_MEM_INNERWBACK
) {
2689 wimg_mode
= VM_WIMG_INNERWBACK
;
2690 } else if (access
== MAP_MEM_WTHRU
) {
2691 wimg_mode
= VM_WIMG_WTHRU
;
2692 } else if (access
== MAP_MEM_WCOMB
) {
2693 wimg_mode
= VM_WIMG_WCOMB
;
2696 /* wait for object (if any) to be ready */
2697 if (!named_entry
->internal
) {
2698 while (!object
->pager_ready
) {
2701 VM_OBJECT_EVENT_PAGER_READY
,
2703 vm_object_lock(object
);
2707 if (object
->wimg_bits
!= wimg_mode
)
2708 vm_object_change_wimg_mode(object
, wimg_mode
);
2710 #if VM_OBJECT_TRACKING_OP_TRUESHARE
2711 if (!object
->true_share
&&
2712 vm_object_tracking_inited
) {
2713 void *bt
[VM_OBJECT_TRACKING_BTDEPTH
];
2716 num
= OSBacktrace(bt
,
2717 VM_OBJECT_TRACKING_BTDEPTH
);
2718 btlog_add_entry(vm_object_tracking_btlog
,
2720 VM_OBJECT_TRACKING_OP_TRUESHARE
,
2724 #endif /* VM_OBJECT_TRACKING_OP_TRUESHARE */
2726 object
->true_share
= TRUE
;
2728 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
)
2729 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
2730 vm_object_unlock(object
);
2732 } else if (named_entry
->is_copy
) {
2734 vm_map_copy_t copy_map
;
2735 vm_map_entry_t copy_entry
;
2736 vm_map_offset_t copy_addr
;
2738 if (flags
& ~(VM_FLAGS_FIXED
|
2740 VM_FLAGS_OVERWRITE
|
2741 VM_FLAGS_RETURN_DATA_ADDR
)) {
2742 named_entry_unlock(named_entry
);
2743 return KERN_INVALID_ARGUMENT
;
2746 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2747 offset_in_mapping
= offset
- vm_object_trunc_page(offset
);
2748 offset
= vm_object_trunc_page(offset
);
2749 map_size
= vm_object_round_page(offset
+ offset_in_mapping
+ initial_size
) - offset
;
2752 copy_map
= named_entry
->backing
.copy
;
2753 assert(copy_map
->type
== VM_MAP_COPY_ENTRY_LIST
);
2754 if (copy_map
->type
!= VM_MAP_COPY_ENTRY_LIST
) {
2755 /* unsupported type; should not happen */
2756 printf("vm_map_enter_mem_object: "
2757 "memory_entry->backing.copy "
2758 "unsupported type 0x%x\n",
2760 named_entry_unlock(named_entry
);
2761 return KERN_INVALID_ARGUMENT
;
2764 /* reserve a contiguous range */
2765 kr
= vm_map_enter(target_map
,
2767 /* map whole mem entry, trim later: */
2770 flags
& (VM_FLAGS_ANYWHERE
|
2771 VM_FLAGS_OVERWRITE
|
2772 VM_FLAGS_RETURN_DATA_ADDR
),
2779 if (kr
!= KERN_SUCCESS
) {
2780 named_entry_unlock(named_entry
);
2784 copy_addr
= map_addr
;
2786 for (copy_entry
= vm_map_copy_first_entry(copy_map
);
2787 copy_entry
!= vm_map_copy_to_entry(copy_map
);
2788 copy_entry
= copy_entry
->vme_next
) {
2789 int remap_flags
= 0;
2790 vm_map_t copy_submap
;
2791 vm_object_t copy_object
;
2792 vm_map_size_t copy_size
;
2793 vm_object_offset_t copy_offset
;
2795 copy_offset
= copy_entry
->offset
;
2796 copy_size
= (copy_entry
->vme_end
-
2797 copy_entry
->vme_start
);
2800 if ((copy_addr
+ copy_size
) >
2802 named_entry
->size
/* XXX full size */ )) {
2803 /* over-mapping too much !? */
2804 kr
= KERN_INVALID_ARGUMENT
;
2809 /* take a reference on the object */
2810 if (copy_entry
->is_sub_map
) {
2811 remap_flags
|= VM_FLAGS_SUBMAP
;
2813 copy_entry
->object
.sub_map
;
2814 vm_map_lock(copy_submap
);
2815 vm_map_reference(copy_submap
);
2816 vm_map_unlock(copy_submap
);
2817 copy_object
= (vm_object_t
) copy_submap
;
2820 copy_entry
->object
.vm_object
;
2821 vm_object_reference(copy_object
);
2824 /* over-map the object into destination */
2825 remap_flags
|= flags
;
2826 remap_flags
|= VM_FLAGS_FIXED
;
2827 remap_flags
|= VM_FLAGS_OVERWRITE
;
2828 remap_flags
&= ~VM_FLAGS_ANYWHERE
;
2829 kr
= vm_map_enter(target_map
,
2832 (vm_map_offset_t
) 0,
2840 if (kr
!= KERN_SUCCESS
) {
2841 if (copy_entry
->is_sub_map
) {
2842 vm_map_deallocate(copy_submap
);
2844 vm_object_deallocate(copy_object
);
2851 copy_addr
+= copy_size
;
2854 if (kr
== KERN_SUCCESS
) {
2855 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2856 *address
= map_addr
+ offset_in_mapping
;
2858 *address
= map_addr
;
2863 * Trim in front, from 0 to "offset".
2865 vm_map_remove(target_map
,
2871 if (offset
+ map_size
< named_entry
->size
) {
2873 * Trim in back, from
2874 * "offset + map_size" to
2875 * "named_entry->size".
2877 vm_map_remove(target_map
,
2885 named_entry_unlock(named_entry
);
2887 if (kr
!= KERN_SUCCESS
) {
2888 if (! (flags
& VM_FLAGS_OVERWRITE
)) {
2889 /* deallocate the contiguous range */
2890 (void) vm_deallocate(target_map
,
2899 /* This is the case where we are going to map */
2900 /* an already mapped object. If the object is */
2901 /* not ready it is internal. An external */
2902 /* object cannot be mapped until it is ready */
2903 /* we can therefore avoid the ready check */
2905 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2906 offset_in_mapping
= offset
- vm_object_trunc_page(offset
);
2907 offset
= vm_object_trunc_page(offset
);
2908 map_size
= vm_object_round_page(offset
+ offset_in_mapping
+ initial_size
) - offset
;
2911 object
= named_entry
->backing
.object
;
2912 assert(object
!= VM_OBJECT_NULL
);
2913 named_entry_unlock(named_entry
);
2914 vm_object_reference(object
);
2916 } else if (ip_kotype(port
) == IKOT_MEMORY_OBJECT
) {
2918 * JMM - This is temporary until we unify named entries
2919 * and raw memory objects.
2921 * Detected fake ip_kotype for a memory object. In
2922 * this case, the port isn't really a port at all, but
2923 * instead is just a raw memory object.
2925 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
2926 panic("VM_FLAGS_RETURN_DATA_ADDR not expected for raw memory object.");
2929 object
= vm_object_enter((memory_object_t
)port
,
2930 size
, FALSE
, FALSE
, FALSE
);
2931 if (object
== VM_OBJECT_NULL
)
2932 return KERN_INVALID_OBJECT
;
2934 /* wait for object (if any) to be ready */
2935 if (object
!= VM_OBJECT_NULL
) {
2936 if (object
== kernel_object
) {
2937 printf("Warning: Attempt to map kernel object"
2938 " by a non-private kernel entity\n");
2939 return KERN_INVALID_OBJECT
;
2941 if (!object
->pager_ready
) {
2942 vm_object_lock(object
);
2944 while (!object
->pager_ready
) {
2945 vm_object_wait(object
,
2946 VM_OBJECT_EVENT_PAGER_READY
,
2948 vm_object_lock(object
);
2950 vm_object_unlock(object
);
2954 return KERN_INVALID_OBJECT
;
2957 if (object
!= VM_OBJECT_NULL
&&
2959 object
->pager
!= MEMORY_OBJECT_NULL
&&
2960 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
2961 memory_object_t pager
;
2962 vm_prot_t pager_prot
;
2966 * For "named" VM objects, let the pager know that the
2967 * memory object is being mapped. Some pagers need to keep
2968 * track of this, to know when they can reclaim the memory
2969 * object, for example.
2970 * VM calls memory_object_map() for each mapping (specifying
2971 * the protection of each mapping) and calls
2972 * memory_object_last_unmap() when all the mappings are gone.
2974 pager_prot
= max_protection
;
2977 * Copy-On-Write mapping: won't modify the
2980 pager_prot
&= ~VM_PROT_WRITE
;
2982 vm_object_lock(object
);
2983 pager
= object
->pager
;
2984 if (object
->named
&&
2985 pager
!= MEMORY_OBJECT_NULL
&&
2986 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
2987 assert(object
->pager_ready
);
2988 vm_object_mapping_wait(object
, THREAD_UNINT
);
2989 vm_object_mapping_begin(object
);
2990 vm_object_unlock(object
);
2992 kr
= memory_object_map(pager
, pager_prot
);
2993 assert(kr
== KERN_SUCCESS
);
2995 vm_object_lock(object
);
2996 vm_object_mapping_end(object
);
2998 vm_object_unlock(object
);
3002 * Perform the copy if requested
3006 vm_object_t new_object
;
3007 vm_object_offset_t new_offset
;
3009 result
= vm_object_copy_strategically(object
, offset
, size
,
3010 &new_object
, &new_offset
,
3014 if (result
== KERN_MEMORY_RESTART_COPY
) {
3016 boolean_t src_needs_copy
;
3020 * We currently ignore src_needs_copy.
3021 * This really is the issue of how to make
3022 * MEMORY_OBJECT_COPY_SYMMETRIC safe for
3023 * non-kernel users to use. Solution forthcoming.
3024 * In the meantime, since we don't allow non-kernel
3025 * memory managers to specify symmetric copy,
3026 * we won't run into problems here.
3028 new_object
= object
;
3029 new_offset
= offset
;
3030 success
= vm_object_copy_quickly(&new_object
,
3035 result
= KERN_SUCCESS
;
3038 * Throw away the reference to the
3039 * original object, as it won't be mapped.
3042 vm_object_deallocate(object
);
3044 if (result
!= KERN_SUCCESS
)
3047 object
= new_object
;
3048 offset
= new_offset
;
3052 * If users want to try to prefault pages, the mapping and prefault
3053 * needs to be atomic.
3056 flags
|= VM_FLAGS_KEEP_MAP_LOCKED
;
3057 result
= vm_map_enter(target_map
,
3058 &map_addr
, map_size
,
3059 (vm_map_offset_t
)mask
,
3063 cur_protection
, max_protection
, inheritance
);
3064 if (result
!= KERN_SUCCESS
)
3065 vm_object_deallocate(object
);
3068 * Try to prefault, and do not forget to release the vm map lock.
3070 if (result
== KERN_SUCCESS
&& try_prefault
) {
3071 mach_vm_address_t va
= map_addr
;
3072 kern_return_t kr
= KERN_SUCCESS
;
3075 for (i
= 0; i
< page_list_count
; ++i
) {
3076 if (UPL_VALID_PAGE(page_list
, i
)) {
3078 * If this function call failed, we should stop
3079 * trying to optimize, other calls are likely
3080 * going to fail too.
3082 * We are not gonna report an error for such
3083 * failure though. That's an optimization, not
3084 * something critical.
3086 kr
= pmap_enter_options(target_map
->pmap
,
3087 va
, UPL_PHYS_PAGE(page_list
, i
),
3088 cur_protection
, VM_PROT_NONE
,
3089 0, TRUE
, PMAP_OPTIONS_NOWAIT
, NULL
);
3090 if (kr
!= KERN_SUCCESS
) {
3091 OSIncrementAtomic64(&vm_prefault_nb_bailout
);
3094 OSIncrementAtomic64(&vm_prefault_nb_pages
);
3097 /* Next virtual address */
3101 vm_map_unlock(target_map
);
3104 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
3105 *address
= map_addr
+ offset_in_mapping
;
3107 *address
= map_addr
;
3113 vm_map_enter_mem_object(
3114 vm_map_t target_map
,
3115 vm_map_offset_t
*address
,
3116 vm_map_size_t initial_size
,
3117 vm_map_offset_t mask
,
3120 vm_object_offset_t offset
,
3122 vm_prot_t cur_protection
,
3123 vm_prot_t max_protection
,
3124 vm_inherit_t inheritance
)
3126 return vm_map_enter_mem_object_helper(target_map
, address
, initial_size
, mask
, flags
,
3127 port
, offset
, copy
, cur_protection
, max_protection
,
3128 inheritance
, NULL
, 0);
3132 vm_map_enter_mem_object_prefault(
3133 vm_map_t target_map
,
3134 vm_map_offset_t
*address
,
3135 vm_map_size_t initial_size
,
3136 vm_map_offset_t mask
,
3139 vm_object_offset_t offset
,
3140 vm_prot_t cur_protection
,
3141 vm_prot_t max_protection
,
3142 upl_page_list_ptr_t page_list
,
3143 unsigned int page_list_count
)
3145 return vm_map_enter_mem_object_helper(target_map
, address
, initial_size
, mask
, flags
,
3146 port
, offset
, FALSE
, cur_protection
, max_protection
,
3147 VM_INHERIT_DEFAULT
, page_list
, page_list_count
);
3152 vm_map_enter_mem_object_control(
3153 vm_map_t target_map
,
3154 vm_map_offset_t
*address
,
3155 vm_map_size_t initial_size
,
3156 vm_map_offset_t mask
,
3158 memory_object_control_t control
,
3159 vm_object_offset_t offset
,
3161 vm_prot_t cur_protection
,
3162 vm_prot_t max_protection
,
3163 vm_inherit_t inheritance
)
3165 vm_map_address_t map_addr
;
3166 vm_map_size_t map_size
;
3168 vm_object_size_t size
;
3169 kern_return_t result
;
3170 memory_object_t pager
;
3171 vm_prot_t pager_prot
;
3175 * Check arguments for validity
3177 if ((target_map
== VM_MAP_NULL
) ||
3178 (cur_protection
& ~VM_PROT_ALL
) ||
3179 (max_protection
& ~VM_PROT_ALL
) ||
3180 (inheritance
> VM_INHERIT_LAST_VALID
) ||
3182 return KERN_INVALID_ARGUMENT
;
3184 map_addr
= vm_map_trunc_page(*address
,
3185 VM_MAP_PAGE_MASK(target_map
));
3186 map_size
= vm_map_round_page(initial_size
,
3187 VM_MAP_PAGE_MASK(target_map
));
3188 size
= vm_object_round_page(initial_size
);
3190 object
= memory_object_control_to_vm_object(control
);
3192 if (object
== VM_OBJECT_NULL
)
3193 return KERN_INVALID_OBJECT
;
3195 if (object
== kernel_object
) {
3196 printf("Warning: Attempt to map kernel object"
3197 " by a non-private kernel entity\n");
3198 return KERN_INVALID_OBJECT
;
3201 vm_object_lock(object
);
3202 object
->ref_count
++;
3203 vm_object_res_reference(object
);
3206 * For "named" VM objects, let the pager know that the
3207 * memory object is being mapped. Some pagers need to keep
3208 * track of this, to know when they can reclaim the memory
3209 * object, for example.
3210 * VM calls memory_object_map() for each mapping (specifying
3211 * the protection of each mapping) and calls
3212 * memory_object_last_unmap() when all the mappings are gone.
3214 pager_prot
= max_protection
;
3216 pager_prot
&= ~VM_PROT_WRITE
;
3218 pager
= object
->pager
;
3219 if (object
->named
&&
3220 pager
!= MEMORY_OBJECT_NULL
&&
3221 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
3222 assert(object
->pager_ready
);
3223 vm_object_mapping_wait(object
, THREAD_UNINT
);
3224 vm_object_mapping_begin(object
);
3225 vm_object_unlock(object
);
3227 kr
= memory_object_map(pager
, pager_prot
);
3228 assert(kr
== KERN_SUCCESS
);
3230 vm_object_lock(object
);
3231 vm_object_mapping_end(object
);
3233 vm_object_unlock(object
);
3236 * Perform the copy if requested
3240 vm_object_t new_object
;
3241 vm_object_offset_t new_offset
;
3243 result
= vm_object_copy_strategically(object
, offset
, size
,
3244 &new_object
, &new_offset
,
3248 if (result
== KERN_MEMORY_RESTART_COPY
) {
3250 boolean_t src_needs_copy
;
3254 * We currently ignore src_needs_copy.
3255 * This really is the issue of how to make
3256 * MEMORY_OBJECT_COPY_SYMMETRIC safe for
3257 * non-kernel users to use. Solution forthcoming.
3258 * In the meantime, since we don't allow non-kernel
3259 * memory managers to specify symmetric copy,
3260 * we won't run into problems here.
3262 new_object
= object
;
3263 new_offset
= offset
;
3264 success
= vm_object_copy_quickly(&new_object
,
3269 result
= KERN_SUCCESS
;
3272 * Throw away the reference to the
3273 * original object, as it won't be mapped.
3276 vm_object_deallocate(object
);
3278 if (result
!= KERN_SUCCESS
)
3281 object
= new_object
;
3282 offset
= new_offset
;
3285 result
= vm_map_enter(target_map
,
3286 &map_addr
, map_size
,
3287 (vm_map_offset_t
)mask
,
3291 cur_protection
, max_protection
, inheritance
);
3292 if (result
!= KERN_SUCCESS
)
3293 vm_object_deallocate(object
);
3294 *address
= map_addr
;
3303 extern pmap_paddr_t avail_start
, avail_end
;
3307 * Allocate memory in the specified map, with the caveat that
3308 * the memory is physically contiguous. This call may fail
3309 * if the system can't find sufficient contiguous memory.
3310 * This call may cause or lead to heart-stopping amounts of
3313 * Memory obtained from this call should be freed in the
3314 * normal way, viz., via vm_deallocate.
3319 vm_map_offset_t
*addr
,
3323 vm_object_t cpm_obj
;
3327 vm_map_offset_t va
, start
, end
, offset
;
3329 vm_map_offset_t prev_addr
= 0;
3330 #endif /* MACH_ASSERT */
3332 boolean_t anywhere
= ((VM_FLAGS_ANYWHERE
& flags
) != 0);
3336 return KERN_SUCCESS
;
3339 *addr
= vm_map_min(map
);
3341 *addr
= vm_map_trunc_page(*addr
,
3342 VM_MAP_PAGE_MASK(map
));
3343 size
= vm_map_round_page(size
,
3344 VM_MAP_PAGE_MASK(map
));
3347 * LP64todo - cpm_allocate should probably allow
3348 * allocations of >4GB, but not with the current
3349 * algorithm, so just cast down the size for now.
3351 if (size
> VM_MAX_ADDRESS
)
3352 return KERN_RESOURCE_SHORTAGE
;
3353 if ((kr
= cpm_allocate(CAST_DOWN(vm_size_t
, size
),
3354 &pages
, 0, 0, TRUE
, flags
)) != KERN_SUCCESS
)
3357 cpm_obj
= vm_object_allocate((vm_object_size_t
)size
);
3358 assert(cpm_obj
!= VM_OBJECT_NULL
);
3359 assert(cpm_obj
->internal
);
3360 assert(cpm_obj
->vo_size
== (vm_object_size_t
)size
);
3361 assert(cpm_obj
->can_persist
== FALSE
);
3362 assert(cpm_obj
->pager_created
== FALSE
);
3363 assert(cpm_obj
->pageout
== FALSE
);
3364 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
3367 * Insert pages into object.
3370 vm_object_lock(cpm_obj
);
3371 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
3373 pages
= NEXT_PAGE(m
);
3374 *(NEXT_PAGE_PTR(m
)) = VM_PAGE_NULL
;
3376 assert(!m
->gobbled
);
3378 assert(!m
->pageout
);
3380 assert(VM_PAGE_WIRED(m
));
3383 * "m" is not supposed to be pageable, so it
3384 * should not be encrypted. It wouldn't be safe
3385 * to enter it in a new VM object while encrypted.
3387 ASSERT_PAGE_DECRYPTED(m
);
3389 assert(m
->phys_page
>=(avail_start
>>PAGE_SHIFT
) && m
->phys_page
<=(avail_end
>>PAGE_SHIFT
));
3392 vm_page_insert(m
, cpm_obj
, offset
);
3394 assert(cpm_obj
->resident_page_count
== size
/ PAGE_SIZE
);
3395 vm_object_unlock(cpm_obj
);
3398 * Hang onto a reference on the object in case a
3399 * multi-threaded application for some reason decides
3400 * to deallocate the portion of the address space into
3401 * which we will insert this object.
3403 * Unfortunately, we must insert the object now before
3404 * we can talk to the pmap module about which addresses
3405 * must be wired down. Hence, the race with a multi-
3408 vm_object_reference(cpm_obj
);
3411 * Insert object into map.
3421 (vm_object_offset_t
)0,
3425 VM_INHERIT_DEFAULT
);
3427 if (kr
!= KERN_SUCCESS
) {
3429 * A CPM object doesn't have can_persist set,
3430 * so all we have to do is deallocate it to
3431 * free up these pages.
3433 assert(cpm_obj
->pager_created
== FALSE
);
3434 assert(cpm_obj
->can_persist
== FALSE
);
3435 assert(cpm_obj
->pageout
== FALSE
);
3436 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
3437 vm_object_deallocate(cpm_obj
); /* kill acquired ref */
3438 vm_object_deallocate(cpm_obj
); /* kill creation ref */
3442 * Inform the physical mapping system that the
3443 * range of addresses may not fault, so that
3444 * page tables and such can be locked down as well.
3448 pmap
= vm_map_pmap(map
);
3449 pmap_pageable(pmap
, start
, end
, FALSE
);
3452 * Enter each page into the pmap, to avoid faults.
3453 * Note that this loop could be coded more efficiently,
3454 * if the need arose, rather than looking up each page
3457 for (offset
= 0, va
= start
; offset
< size
;
3458 va
+= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
3461 vm_object_lock(cpm_obj
);
3462 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
3463 assert(m
!= VM_PAGE_NULL
);
3465 vm_page_zero_fill(m
);
3467 type_of_fault
= DBG_ZERO_FILL_FAULT
;
3469 vm_fault_enter(m
, pmap
, va
, VM_PROT_ALL
, VM_PROT_WRITE
,
3470 VM_PAGE_WIRED(m
), FALSE
, FALSE
, FALSE
, 0, NULL
,
3473 vm_object_unlock(cpm_obj
);
3478 * Verify ordering in address space.
3480 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
3481 vm_object_lock(cpm_obj
);
3482 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
3483 vm_object_unlock(cpm_obj
);
3484 if (m
== VM_PAGE_NULL
)
3485 panic("vm_allocate_cpm: obj %p off 0x%llx no page",
3486 cpm_obj
, (uint64_t)offset
);
3490 assert(!m
->fictitious
);
3491 assert(!m
->private);
3494 assert(!m
->cleaning
);
3495 assert(!m
->laundry
);
3496 assert(!m
->precious
);
3497 assert(!m
->clustered
);
3499 if (m
->phys_page
!= prev_addr
+ 1) {
3500 printf("start 0x%llx end 0x%llx va 0x%llx\n",
3501 (uint64_t)start
, (uint64_t)end
, (uint64_t)va
);
3502 printf("obj %p off 0x%llx\n", cpm_obj
, (uint64_t)offset
);
3503 printf("m %p prev_address 0x%llx\n", m
, (uint64_t)prev_addr
);
3504 panic("vm_allocate_cpm: pages not contig!");
3507 prev_addr
= m
->phys_page
;
3509 #endif /* MACH_ASSERT */
3511 vm_object_deallocate(cpm_obj
); /* kill extra ref */
3520 * Interface is defined in all cases, but unless the kernel
3521 * is built explicitly for this option, the interface does
3527 __unused vm_map_t map
,
3528 __unused vm_map_offset_t
*addr
,
3529 __unused vm_map_size_t size
,
3532 return KERN_FAILURE
;
3536 /* Not used without nested pmaps */
3537 #ifndef NO_NESTED_PMAP
3539 * Clip and unnest a portion of a nested submap mapping.
3546 vm_map_entry_t entry
,
3547 vm_map_offset_t start_unnest
,
3548 vm_map_offset_t end_unnest
)
3550 vm_map_offset_t old_start_unnest
= start_unnest
;
3551 vm_map_offset_t old_end_unnest
= end_unnest
;
3553 assert(entry
->is_sub_map
);
3554 assert(entry
->object
.sub_map
!= NULL
);
3555 assert(entry
->use_pmap
);
3558 * Query the platform for the optimal unnest range.
3559 * DRK: There's some duplication of effort here, since
3560 * callers may have adjusted the range to some extent. This
3561 * routine was introduced to support 1GiB subtree nesting
3562 * for x86 platforms, which can also nest on 2MiB boundaries
3563 * depending on size/alignment.
3565 if (pmap_adjust_unnest_parameters(map
->pmap
, &start_unnest
, &end_unnest
)) {
3566 log_unnest_badness(map
, old_start_unnest
, old_end_unnest
);
3569 if (entry
->vme_start
> start_unnest
||
3570 entry
->vme_end
< end_unnest
) {
3571 panic("vm_map_clip_unnest(0x%llx,0x%llx): "
3572 "bad nested entry: start=0x%llx end=0x%llx\n",
3573 (long long)start_unnest
, (long long)end_unnest
,
3574 (long long)entry
->vme_start
, (long long)entry
->vme_end
);
3577 if (start_unnest
> entry
->vme_start
) {
3578 _vm_map_clip_start(&map
->hdr
,
3581 vm_map_store_update_first_free(map
, map
->first_free
);
3583 if (entry
->vme_end
> end_unnest
) {
3584 _vm_map_clip_end(&map
->hdr
,
3587 vm_map_store_update_first_free(map
, map
->first_free
);
3590 pmap_unnest(map
->pmap
,
3592 entry
->vme_end
- entry
->vme_start
);
3593 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
3594 /* clean up parent map/maps */
3595 vm_map_submap_pmap_clean(
3596 map
, entry
->vme_start
,
3598 entry
->object
.sub_map
,
3601 entry
->use_pmap
= FALSE
;
3602 if (entry
->alias
== VM_MEMORY_SHARED_PMAP
) {
3603 entry
->alias
= VM_MEMORY_UNSHARED_PMAP
;
3606 #endif /* NO_NESTED_PMAP */
3609 * vm_map_clip_start: [ internal use only ]
3611 * Asserts that the given entry begins at or after
3612 * the specified address; if necessary,
3613 * it splits the entry into two.
3618 vm_map_entry_t entry
,
3619 vm_map_offset_t startaddr
)
3621 #ifndef NO_NESTED_PMAP
3622 if (entry
->is_sub_map
&&
3624 startaddr
>= entry
->vme_start
) {
3625 vm_map_offset_t start_unnest
, end_unnest
;
3628 * Make sure "startaddr" is no longer in a nested range
3629 * before we clip. Unnest only the minimum range the platform
3631 * vm_map_clip_unnest may perform additional adjustments to
3634 start_unnest
= startaddr
& ~(pmap_nesting_size_min
- 1);
3635 end_unnest
= start_unnest
+ pmap_nesting_size_min
;
3636 vm_map_clip_unnest(map
, entry
, start_unnest
, end_unnest
);
3638 #endif /* NO_NESTED_PMAP */
3639 if (startaddr
> entry
->vme_start
) {
3640 if (entry
->object
.vm_object
&&
3641 !entry
->is_sub_map
&&
3642 entry
->object
.vm_object
->phys_contiguous
) {
3643 pmap_remove(map
->pmap
,
3644 (addr64_t
)(entry
->vme_start
),
3645 (addr64_t
)(entry
->vme_end
));
3647 _vm_map_clip_start(&map
->hdr
, entry
, startaddr
);
3648 vm_map_store_update_first_free(map
, map
->first_free
);
3653 #define vm_map_copy_clip_start(copy, entry, startaddr) \
3655 if ((startaddr) > (entry)->vme_start) \
3656 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
3660 * This routine is called only when it is known that
3661 * the entry must be split.
3665 register struct vm_map_header
*map_header
,
3666 register vm_map_entry_t entry
,
3667 register vm_map_offset_t start
)
3669 register vm_map_entry_t new_entry
;
3672 * Split off the front portion --
3673 * note that we must insert the new
3674 * entry BEFORE this one, so that
3675 * this entry has the specified starting
3679 if (entry
->map_aligned
) {
3680 assert(VM_MAP_PAGE_ALIGNED(start
,
3681 VM_MAP_HDR_PAGE_MASK(map_header
)));
3684 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
3685 vm_map_entry_copy_full(new_entry
, entry
);
3687 new_entry
->vme_end
= start
;
3688 assert(new_entry
->vme_start
< new_entry
->vme_end
);
3689 entry
->offset
+= (start
- entry
->vme_start
);
3690 assert(start
< entry
->vme_end
);
3691 entry
->vme_start
= start
;
3693 _vm_map_store_entry_link(map_header
, entry
->vme_prev
, new_entry
);
3695 if (entry
->is_sub_map
)
3696 vm_map_reference(new_entry
->object
.sub_map
);
3698 vm_object_reference(new_entry
->object
.vm_object
);
3703 * vm_map_clip_end: [ internal use only ]
3705 * Asserts that the given entry ends at or before
3706 * the specified address; if necessary,
3707 * it splits the entry into two.
3712 vm_map_entry_t entry
,
3713 vm_map_offset_t endaddr
)
3715 if (endaddr
> entry
->vme_end
) {
3717 * Within the scope of this clipping, limit "endaddr" to
3718 * the end of this map entry...
3720 endaddr
= entry
->vme_end
;
3722 #ifndef NO_NESTED_PMAP
3723 if (entry
->is_sub_map
&& entry
->use_pmap
) {
3724 vm_map_offset_t start_unnest
, end_unnest
;
3727 * Make sure the range between the start of this entry and
3728 * the new "endaddr" is no longer nested before we clip.
3729 * Unnest only the minimum range the platform can handle.
3730 * vm_map_clip_unnest may perform additional adjustments to
3733 start_unnest
= entry
->vme_start
;
3735 (endaddr
+ pmap_nesting_size_min
- 1) &
3736 ~(pmap_nesting_size_min
- 1);
3737 vm_map_clip_unnest(map
, entry
, start_unnest
, end_unnest
);
3739 #endif /* NO_NESTED_PMAP */
3740 if (endaddr
< entry
->vme_end
) {
3741 if (entry
->object
.vm_object
&&
3742 !entry
->is_sub_map
&&
3743 entry
->object
.vm_object
->phys_contiguous
) {
3744 pmap_remove(map
->pmap
,
3745 (addr64_t
)(entry
->vme_start
),
3746 (addr64_t
)(entry
->vme_end
));
3748 _vm_map_clip_end(&map
->hdr
, entry
, endaddr
);
3749 vm_map_store_update_first_free(map
, map
->first_free
);
3754 #define vm_map_copy_clip_end(copy, entry, endaddr) \
3756 if ((endaddr) < (entry)->vme_end) \
3757 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
3761 * This routine is called only when it is known that
3762 * the entry must be split.
3766 register struct vm_map_header
*map_header
,
3767 register vm_map_entry_t entry
,
3768 register vm_map_offset_t end
)
3770 register vm_map_entry_t new_entry
;
3773 * Create a new entry and insert it
3774 * AFTER the specified entry
3777 if (entry
->map_aligned
) {
3778 assert(VM_MAP_PAGE_ALIGNED(end
,
3779 VM_MAP_HDR_PAGE_MASK(map_header
)));
3782 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
3783 vm_map_entry_copy_full(new_entry
, entry
);
3785 assert(entry
->vme_start
< end
);
3786 new_entry
->vme_start
= entry
->vme_end
= end
;
3787 new_entry
->offset
+= (end
- entry
->vme_start
);
3788 assert(new_entry
->vme_start
< new_entry
->vme_end
);
3790 _vm_map_store_entry_link(map_header
, entry
, new_entry
);
3792 if (entry
->is_sub_map
)
3793 vm_map_reference(new_entry
->object
.sub_map
);
3795 vm_object_reference(new_entry
->object
.vm_object
);
3800 * VM_MAP_RANGE_CHECK: [ internal use only ]
3802 * Asserts that the starting and ending region
3803 * addresses fall within the valid range of the map.
3805 #define VM_MAP_RANGE_CHECK(map, start, end) \
3807 if (start < vm_map_min(map)) \
3808 start = vm_map_min(map); \
3809 if (end > vm_map_max(map)) \
3810 end = vm_map_max(map); \
3816 * vm_map_range_check: [ internal use only ]
3818 * Check that the region defined by the specified start and
3819 * end addresses are wholly contained within a single map
3820 * entry or set of adjacent map entries of the spacified map,
3821 * i.e. the specified region contains no unmapped space.
3822 * If any or all of the region is unmapped, FALSE is returned.
3823 * Otherwise, TRUE is returned and if the output argument 'entry'
3824 * is not NULL it points to the map entry containing the start
3827 * The map is locked for reading on entry and is left locked.
3831 register vm_map_t map
,
3832 register vm_map_offset_t start
,
3833 register vm_map_offset_t end
,
3834 vm_map_entry_t
*entry
)
3837 register vm_map_offset_t prev
;
3840 * Basic sanity checks first
3842 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
3846 * Check first if the region starts within a valid
3847 * mapping for the map.
3849 if (!vm_map_lookup_entry(map
, start
, &cur
))
3853 * Optimize for the case that the region is contained
3854 * in a single map entry.
3856 if (entry
!= (vm_map_entry_t
*) NULL
)
3858 if (end
<= cur
->vme_end
)
3862 * If the region is not wholly contained within a
3863 * single entry, walk the entries looking for holes.
3865 prev
= cur
->vme_end
;
3866 cur
= cur
->vme_next
;
3867 while ((cur
!= vm_map_to_entry(map
)) && (prev
== cur
->vme_start
)) {
3868 if (end
<= cur
->vme_end
)
3870 prev
= cur
->vme_end
;
3871 cur
= cur
->vme_next
;
3877 * vm_map_submap: [ kernel use only ]
3879 * Mark the given range as handled by a subordinate map.
3881 * This range must have been created with vm_map_find using
3882 * the vm_submap_object, and no other operations may have been
3883 * performed on this range prior to calling vm_map_submap.
3885 * Only a limited number of operations can be performed
3886 * within this rage after calling vm_map_submap:
3888 * [Don't try vm_map_copyin!]
3890 * To remove a submapping, one must first remove the
3891 * range from the superior map, and then destroy the
3892 * submap (if desired). [Better yet, don't try it.]
3897 vm_map_offset_t start
,
3898 vm_map_offset_t end
,
3900 vm_map_offset_t offset
,
3901 #ifdef NO_NESTED_PMAP
3903 #endif /* NO_NESTED_PMAP */
3906 vm_map_entry_t entry
;
3907 register kern_return_t result
= KERN_INVALID_ARGUMENT
;
3908 register vm_object_t object
;
3912 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
3913 entry
= entry
->vme_next
;
3916 if (entry
== vm_map_to_entry(map
) ||
3917 entry
->is_sub_map
) {
3919 return KERN_INVALID_ARGUMENT
;
3922 vm_map_clip_start(map
, entry
, start
);
3923 vm_map_clip_end(map
, entry
, end
);
3925 if ((entry
->vme_start
== start
) && (entry
->vme_end
== end
) &&
3926 (!entry
->is_sub_map
) &&
3927 ((object
= entry
->object
.vm_object
) == vm_submap_object
) &&
3928 (object
->resident_page_count
== 0) &&
3929 (object
->copy
== VM_OBJECT_NULL
) &&
3930 (object
->shadow
== VM_OBJECT_NULL
) &&
3931 (!object
->pager_created
)) {
3932 entry
->offset
= (vm_object_offset_t
)offset
;
3933 entry
->object
.vm_object
= VM_OBJECT_NULL
;
3934 vm_object_deallocate(object
);
3935 entry
->is_sub_map
= TRUE
;
3936 entry
->use_pmap
= FALSE
;
3937 entry
->object
.sub_map
= submap
;
3938 vm_map_reference(submap
);
3939 if (submap
->mapped_in_other_pmaps
== FALSE
&&
3940 vm_map_pmap(submap
) != PMAP_NULL
&&
3941 vm_map_pmap(submap
) != vm_map_pmap(map
)) {
3943 * This submap is being mapped in a map
3944 * that uses a different pmap.
3945 * Set its "mapped_in_other_pmaps" flag
3946 * to indicate that we now need to
3947 * remove mappings from all pmaps rather
3948 * than just the submap's pmap.
3950 submap
->mapped_in_other_pmaps
= TRUE
;
3953 #ifndef NO_NESTED_PMAP
3955 /* nest if platform code will allow */
3956 if(submap
->pmap
== NULL
) {
3957 ledger_t ledger
= map
->pmap
->ledger
;
3958 submap
->pmap
= pmap_create(ledger
,
3959 (vm_map_size_t
) 0, FALSE
);
3960 if(submap
->pmap
== PMAP_NULL
) {
3962 return(KERN_NO_SPACE
);
3965 result
= pmap_nest(map
->pmap
,
3966 (entry
->object
.sub_map
)->pmap
,
3969 (uint64_t)(end
- start
));
3971 panic("vm_map_submap: pmap_nest failed, rc = %08X\n", result
);
3972 entry
->use_pmap
= TRUE
;
3974 #else /* NO_NESTED_PMAP */
3975 pmap_remove(map
->pmap
, (addr64_t
)start
, (addr64_t
)end
);
3976 #endif /* NO_NESTED_PMAP */
3977 result
= KERN_SUCCESS
;
3987 * Sets the protection of the specified address
3988 * region in the target map. If "set_max" is
3989 * specified, the maximum protection is to be set;
3990 * otherwise, only the current protection is affected.
3994 register vm_map_t map
,
3995 register vm_map_offset_t start
,
3996 register vm_map_offset_t end
,
3997 register vm_prot_t new_prot
,
3998 register boolean_t set_max
)
4000 register vm_map_entry_t current
;
4001 register vm_map_offset_t prev
;
4002 vm_map_entry_t entry
;
4006 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
4007 map
, start
, end
, new_prot
, set_max
);
4011 /* LP64todo - remove this check when vm_map_commpage64()
4012 * no longer has to stuff in a map_entry for the commpage
4013 * above the map's max_offset.
4015 if (start
>= map
->max_offset
) {
4017 return(KERN_INVALID_ADDRESS
);
4022 * Lookup the entry. If it doesn't start in a valid
4023 * entry, return an error.
4025 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
4027 return(KERN_INVALID_ADDRESS
);
4030 if (entry
->superpage_size
&& (start
& (SUPERPAGE_SIZE
-1))) { /* extend request to whole entry */
4031 start
= SUPERPAGE_ROUND_DOWN(start
);
4036 if (entry
->superpage_size
)
4037 end
= SUPERPAGE_ROUND_UP(end
);
4040 * Make a first pass to check for protection and address
4045 prev
= current
->vme_start
;
4046 while ((current
!= vm_map_to_entry(map
)) &&
4047 (current
->vme_start
< end
)) {
4050 * If there is a hole, return an error.
4052 if (current
->vme_start
!= prev
) {
4054 return(KERN_INVALID_ADDRESS
);
4057 new_max
= current
->max_protection
;
4058 if(new_prot
& VM_PROT_COPY
) {
4059 new_max
|= VM_PROT_WRITE
;
4060 if ((new_prot
& (new_max
| VM_PROT_COPY
)) != new_prot
) {
4062 return(KERN_PROTECTION_FAILURE
);
4065 if ((new_prot
& new_max
) != new_prot
) {
4067 return(KERN_PROTECTION_FAILURE
);
4072 prev
= current
->vme_end
;
4073 current
= current
->vme_next
;
4077 return(KERN_INVALID_ADDRESS
);
4081 * Go back and fix up protections.
4082 * Clip to start here if the range starts within
4087 if (current
!= vm_map_to_entry(map
)) {
4088 /* clip and unnest if necessary */
4089 vm_map_clip_start(map
, current
, start
);
4092 while ((current
!= vm_map_to_entry(map
)) &&
4093 (current
->vme_start
< end
)) {
4097 vm_map_clip_end(map
, current
, end
);
4099 if (current
->is_sub_map
) {
4100 /* clipping did unnest if needed */
4101 assert(!current
->use_pmap
);
4104 old_prot
= current
->protection
;
4106 if(new_prot
& VM_PROT_COPY
) {
4107 /* caller is asking specifically to copy the */
4108 /* mapped data, this implies that max protection */
4109 /* will include write. Caller must be prepared */
4110 /* for loss of shared memory communication in the */
4111 /* target area after taking this step */
4113 if (current
->is_sub_map
== FALSE
&& current
->object
.vm_object
== VM_OBJECT_NULL
){
4114 current
->object
.vm_object
= vm_object_allocate((vm_map_size_t
)(current
->vme_end
- current
->vme_start
));
4115 current
->offset
= 0;
4116 assert(current
->use_pmap
);
4118 current
->needs_copy
= TRUE
;
4119 current
->max_protection
|= VM_PROT_WRITE
;
4123 current
->protection
=
4124 (current
->max_protection
=
4125 new_prot
& ~VM_PROT_COPY
) &
4128 current
->protection
= new_prot
& ~VM_PROT_COPY
;
4131 * Update physical map if necessary.
4132 * If the request is to turn off write protection,
4133 * we won't do it for real (in pmap). This is because
4134 * it would cause copy-on-write to fail. We've already
4135 * set, the new protection in the map, so if a
4136 * write-protect fault occurred, it will be fixed up
4137 * properly, COW or not.
4139 if (current
->protection
!= old_prot
) {
4140 /* Look one level in we support nested pmaps */
4141 /* from mapped submaps which are direct entries */
4146 prot
= current
->protection
& ~VM_PROT_WRITE
;
4148 if (override_nx(map
, current
->alias
) && prot
)
4149 prot
|= VM_PROT_EXECUTE
;
4151 if (current
->is_sub_map
&& current
->use_pmap
) {
4152 pmap_protect(current
->object
.sub_map
->pmap
,
4157 pmap_protect(map
->pmap
,
4163 current
= current
->vme_next
;
4167 while ((current
!= vm_map_to_entry(map
)) &&
4168 (current
->vme_start
<= end
)) {
4169 vm_map_simplify_entry(map
, current
);
4170 current
= current
->vme_next
;
4174 return(KERN_SUCCESS
);
4180 * Sets the inheritance of the specified address
4181 * range in the target map. Inheritance
4182 * affects how the map will be shared with
4183 * child maps at the time of vm_map_fork.
4187 register vm_map_t map
,
4188 register vm_map_offset_t start
,
4189 register vm_map_offset_t end
,
4190 register vm_inherit_t new_inheritance
)
4192 register vm_map_entry_t entry
;
4193 vm_map_entry_t temp_entry
;
4197 VM_MAP_RANGE_CHECK(map
, start
, end
);
4199 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
4203 temp_entry
= temp_entry
->vme_next
;
4207 /* first check entire range for submaps which can't support the */
4208 /* given inheritance. */
4209 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
4210 if(entry
->is_sub_map
) {
4211 if(new_inheritance
== VM_INHERIT_COPY
) {
4213 return(KERN_INVALID_ARGUMENT
);
4217 entry
= entry
->vme_next
;
4221 if (entry
!= vm_map_to_entry(map
)) {
4222 /* clip and unnest if necessary */
4223 vm_map_clip_start(map
, entry
, start
);
4226 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
4227 vm_map_clip_end(map
, entry
, end
);
4228 if (entry
->is_sub_map
) {
4229 /* clip did unnest if needed */
4230 assert(!entry
->use_pmap
);
4233 entry
->inheritance
= new_inheritance
;
4235 entry
= entry
->vme_next
;
4239 return(KERN_SUCCESS
);
4243 * Update the accounting for the amount of wired memory in this map. If the user has
4244 * exceeded the defined limits, then we fail. Wiring on behalf of the kernel never fails.
4247 static kern_return_t
4250 vm_map_entry_t entry
,
4251 boolean_t user_wire
)
4256 unsigned int total_wire_count
= vm_page_wire_count
+ vm_lopage_free_count
;
4259 * We're wiring memory at the request of the user. Check if this is the first time the user is wiring
4263 if (entry
->user_wired_count
== 0) {
4264 size
= entry
->vme_end
- entry
->vme_start
;
4267 * Since this is the first time the user is wiring this map entry, check to see if we're
4268 * exceeding the user wire limits. There is a per map limit which is the smaller of either
4269 * the process's rlimit or the global vm_user_wire_limit which caps this value. There is also
4270 * a system-wide limit on the amount of memory all users can wire. If the user is over either
4271 * limit, then we fail.
4274 if(size
+ map
->user_wire_size
> MIN(map
->user_wire_limit
, vm_user_wire_limit
) ||
4275 size
+ ptoa_64(total_wire_count
) > vm_global_user_wire_limit
||
4276 size
+ ptoa_64(total_wire_count
) > max_mem
- vm_global_no_user_wire_amount
)
4277 return KERN_RESOURCE_SHORTAGE
;
4280 * The first time the user wires an entry, we also increment the wired_count and add this to
4281 * the total that has been wired in the map.
4284 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
4285 return KERN_FAILURE
;
4287 entry
->wired_count
++;
4288 map
->user_wire_size
+= size
;
4291 if (entry
->user_wired_count
>= MAX_WIRE_COUNT
)
4292 return KERN_FAILURE
;
4294 entry
->user_wired_count
++;
4299 * The kernel's wiring the memory. Just bump the count and continue.
4302 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
4303 panic("vm_map_wire: too many wirings");
4305 entry
->wired_count
++;
4308 return KERN_SUCCESS
;
4312 * Update the memory wiring accounting now that the given map entry is being unwired.
4316 subtract_wire_counts(
4318 vm_map_entry_t entry
,
4319 boolean_t user_wire
)
4325 * We're unwiring memory at the request of the user. See if we're removing the last user wire reference.
4328 if (entry
->user_wired_count
== 1) {
4331 * We're removing the last user wire reference. Decrement the wired_count and the total
4332 * user wired memory for this map.
4335 assert(entry
->wired_count
>= 1);
4336 entry
->wired_count
--;
4337 map
->user_wire_size
-= entry
->vme_end
- entry
->vme_start
;
4340 assert(entry
->user_wired_count
>= 1);
4341 entry
->user_wired_count
--;
4346 * The kernel is unwiring the memory. Just update the count.
4349 assert(entry
->wired_count
>= 1);
4350 entry
->wired_count
--;
4357 * Sets the pageability of the specified address range in the
4358 * target map as wired. Regions specified as not pageable require
4359 * locked-down physical memory and physical page maps. The
4360 * access_type variable indicates types of accesses that must not
4361 * generate page faults. This is checked against protection of
4362 * memory being locked-down.
4364 * The map must not be locked, but a reference must remain to the
4365 * map throughout the call.
4367 static kern_return_t
4369 register vm_map_t map
,
4370 register vm_map_offset_t start
,
4371 register vm_map_offset_t end
,
4372 register vm_prot_t access_type
,
4373 boolean_t user_wire
,
4375 vm_map_offset_t pmap_addr
,
4376 ppnum_t
*physpage_p
)
4378 register vm_map_entry_t entry
;
4379 struct vm_map_entry
*first_entry
, tmp_entry
;
4381 register vm_map_offset_t s
,e
;
4383 boolean_t need_wakeup
;
4384 boolean_t main_map
= FALSE
;
4385 wait_interrupt_t interruptible_state
;
4386 thread_t cur_thread
;
4387 unsigned int last_timestamp
;
4389 boolean_t wire_and_extract
;
4391 wire_and_extract
= FALSE
;
4392 if (physpage_p
!= NULL
) {
4394 * The caller wants the physical page number of the
4395 * wired page. We return only one physical page number
4396 * so this works for only one page at a time.
4398 if ((end
- start
) != PAGE_SIZE
) {
4399 return KERN_INVALID_ARGUMENT
;
4401 wire_and_extract
= TRUE
;
4406 if(map_pmap
== NULL
)
4408 last_timestamp
= map
->timestamp
;
4410 VM_MAP_RANGE_CHECK(map
, start
, end
);
4411 assert(page_aligned(start
));
4412 assert(page_aligned(end
));
4413 assert(VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)));
4414 assert(VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)));
4416 /* We wired what the caller asked for, zero pages */
4418 return KERN_SUCCESS
;
4421 need_wakeup
= FALSE
;
4422 cur_thread
= current_thread();
4427 if (vm_map_lookup_entry(map
, s
, &first_entry
)) {
4428 entry
= first_entry
;
4430 * vm_map_clip_start will be done later.
4431 * We don't want to unnest any nested submaps here !
4434 /* Start address is not in map */
4435 rc
= KERN_INVALID_ADDRESS
;
4439 while ((entry
!= vm_map_to_entry(map
)) && (s
< end
)) {
4441 * At this point, we have wired from "start" to "s".
4442 * We still need to wire from "s" to "end".
4444 * "entry" hasn't been clipped, so it could start before "s"
4445 * and/or end after "end".
4448 /* "e" is how far we want to wire in this entry */
4454 * If another thread is wiring/unwiring this entry then
4455 * block after informing other thread to wake us up.
4457 if (entry
->in_transition
) {
4458 wait_result_t wait_result
;
4461 * We have not clipped the entry. Make sure that
4462 * the start address is in range so that the lookup
4463 * below will succeed.
4464 * "s" is the current starting point: we've already
4465 * wired from "start" to "s" and we still have
4466 * to wire from "s" to "end".
4469 entry
->needs_wakeup
= TRUE
;
4472 * wake up anybody waiting on entries that we have
4476 vm_map_entry_wakeup(map
);
4477 need_wakeup
= FALSE
;
4480 * User wiring is interruptible
4482 wait_result
= vm_map_entry_wait(map
,
4483 (user_wire
) ? THREAD_ABORTSAFE
:
4485 if (user_wire
&& wait_result
== THREAD_INTERRUPTED
) {
4487 * undo the wirings we have done so far
4488 * We do not clear the needs_wakeup flag,
4489 * because we cannot tell if we were the
4497 * Cannot avoid a lookup here. reset timestamp.
4499 last_timestamp
= map
->timestamp
;
4502 * The entry could have been clipped, look it up again.
4503 * Worse that can happen is, it may not exist anymore.
4505 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
4507 * User: undo everything upto the previous
4508 * entry. let vm_map_unwire worry about
4509 * checking the validity of the range.
4514 entry
= first_entry
;
4518 if (entry
->is_sub_map
) {
4519 vm_map_offset_t sub_start
;
4520 vm_map_offset_t sub_end
;
4521 vm_map_offset_t local_start
;
4522 vm_map_offset_t local_end
;
4525 if (wire_and_extract
) {
4527 * Wiring would result in copy-on-write
4528 * which would not be compatible with
4529 * the sharing we have with the original
4530 * provider of this memory.
4532 rc
= KERN_INVALID_ARGUMENT
;
4536 vm_map_clip_start(map
, entry
, s
);
4537 vm_map_clip_end(map
, entry
, end
);
4539 sub_start
= entry
->offset
;
4540 sub_end
= entry
->vme_end
;
4541 sub_end
+= entry
->offset
- entry
->vme_start
;
4543 local_end
= entry
->vme_end
;
4544 if(map_pmap
== NULL
) {
4546 vm_object_offset_t offset
;
4549 vm_map_entry_t local_entry
;
4550 vm_map_version_t version
;
4551 vm_map_t lookup_map
;
4553 if(entry
->use_pmap
) {
4554 pmap
= entry
->object
.sub_map
->pmap
;
4555 /* ppc implementation requires that */
4556 /* submaps pmap address ranges line */
4557 /* up with parent map */
4559 pmap_addr
= sub_start
;
4567 if (entry
->wired_count
) {
4568 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
4572 * The map was not unlocked:
4573 * no need to goto re-lookup.
4574 * Just go directly to next entry.
4576 entry
= entry
->vme_next
;
4577 s
= entry
->vme_start
;
4582 /* call vm_map_lookup_locked to */
4583 /* cause any needs copy to be */
4585 local_start
= entry
->vme_start
;
4587 vm_map_lock_write_to_read(map
);
4588 if(vm_map_lookup_locked(
4589 &lookup_map
, local_start
,
4591 OBJECT_LOCK_EXCLUSIVE
,
4593 &offset
, &prot
, &wired
,
4597 vm_map_unlock_read(lookup_map
);
4598 vm_map_unwire(map
, start
,
4600 return(KERN_FAILURE
);
4602 vm_object_unlock(object
);
4603 if(real_map
!= lookup_map
)
4604 vm_map_unlock(real_map
);
4605 vm_map_unlock_read(lookup_map
);
4608 /* we unlocked, so must re-lookup */
4609 if (!vm_map_lookup_entry(map
,
4617 * entry could have been "simplified",
4620 entry
= local_entry
;
4621 assert(s
== local_start
);
4622 vm_map_clip_start(map
, entry
, s
);
4623 vm_map_clip_end(map
, entry
, end
);
4624 /* re-compute "e" */
4629 /* did we have a change of type? */
4630 if (!entry
->is_sub_map
) {
4631 last_timestamp
= map
->timestamp
;
4635 local_start
= entry
->vme_start
;
4639 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
4642 entry
->in_transition
= TRUE
;
4645 rc
= vm_map_wire_nested(entry
->object
.sub_map
,
4648 user_wire
, pmap
, pmap_addr
,
4653 * Find the entry again. It could have been clipped
4654 * after we unlocked the map.
4656 if (!vm_map_lookup_entry(map
, local_start
,
4658 panic("vm_map_wire: re-lookup failed");
4659 entry
= first_entry
;
4661 assert(local_start
== s
);
4662 /* re-compute "e" */
4667 last_timestamp
= map
->timestamp
;
4668 while ((entry
!= vm_map_to_entry(map
)) &&
4669 (entry
->vme_start
< e
)) {
4670 assert(entry
->in_transition
);
4671 entry
->in_transition
= FALSE
;
4672 if (entry
->needs_wakeup
) {
4673 entry
->needs_wakeup
= FALSE
;
4676 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
4677 subtract_wire_counts(map
, entry
, user_wire
);
4679 entry
= entry
->vme_next
;
4681 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
4685 /* no need to relookup again */
4686 s
= entry
->vme_start
;
4691 * If this entry is already wired then increment
4692 * the appropriate wire reference count.
4694 if (entry
->wired_count
) {
4696 if ((entry
->protection
& access_type
) != access_type
) {
4697 /* found a protection problem */
4701 * We should always return an error
4702 * in this case but since we didn't
4703 * enforce it before, let's do
4704 * it only for the new "wire_and_extract"
4705 * code path for now...
4707 if (wire_and_extract
) {
4708 rc
= KERN_PROTECTION_FAILURE
;
4714 * entry is already wired down, get our reference
4715 * after clipping to our range.
4717 vm_map_clip_start(map
, entry
, s
);
4718 vm_map_clip_end(map
, entry
, end
);
4720 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
4723 if (wire_and_extract
) {
4725 vm_object_offset_t offset
;
4729 * We don't have to "wire" the page again
4730 * bit we still have to "extract" its
4731 * physical page number, after some sanity
4734 assert((entry
->vme_end
- entry
->vme_start
)
4736 assert(!entry
->needs_copy
);
4737 assert(!entry
->is_sub_map
);
4738 assert(entry
->object
.vm_object
);
4739 if (((entry
->vme_end
- entry
->vme_start
)
4741 entry
->needs_copy
||
4742 entry
->is_sub_map
||
4743 entry
->object
.vm_object
== VM_OBJECT_NULL
) {
4744 rc
= KERN_INVALID_ARGUMENT
;
4748 object
= entry
->object
.vm_object
;
4749 offset
= entry
->offset
;
4750 /* need exclusive lock to update m->dirty */
4751 if (entry
->protection
& VM_PROT_WRITE
) {
4752 vm_object_lock(object
);
4754 vm_object_lock_shared(object
);
4756 m
= vm_page_lookup(object
, offset
);
4757 assert(m
!= VM_PAGE_NULL
);
4758 assert(m
->wire_count
);
4759 if (m
!= VM_PAGE_NULL
&& m
->wire_count
) {
4760 *physpage_p
= m
->phys_page
;
4761 if (entry
->protection
& VM_PROT_WRITE
) {
4762 vm_object_lock_assert_exclusive(
4767 /* not already wired !? */
4770 vm_object_unlock(object
);
4773 /* map was not unlocked: no need to relookup */
4774 entry
= entry
->vme_next
;
4775 s
= entry
->vme_start
;
4780 * Unwired entry or wire request transmitted via submap
4785 * Perform actions of vm_map_lookup that need the write
4786 * lock on the map: create a shadow object for a
4787 * copy-on-write region, or an object for a zero-fill
4790 size
= entry
->vme_end
- entry
->vme_start
;
4792 * If wiring a copy-on-write page, we need to copy it now
4793 * even if we're only (currently) requesting read access.
4794 * This is aggressive, but once it's wired we can't move it.
4796 if (entry
->needs_copy
) {
4797 if (wire_and_extract
) {
4799 * We're supposed to share with the original
4800 * provider so should not be "needs_copy"
4802 rc
= KERN_INVALID_ARGUMENT
;
4806 vm_object_shadow(&entry
->object
.vm_object
,
4807 &entry
->offset
, size
);
4808 entry
->needs_copy
= FALSE
;
4809 } else if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
4810 if (wire_and_extract
) {
4812 * We're supposed to share with the original
4813 * provider so should already have an object.
4815 rc
= KERN_INVALID_ARGUMENT
;
4818 entry
->object
.vm_object
= vm_object_allocate(size
);
4819 entry
->offset
= (vm_object_offset_t
)0;
4820 assert(entry
->use_pmap
);
4823 vm_map_clip_start(map
, entry
, s
);
4824 vm_map_clip_end(map
, entry
, end
);
4826 /* re-compute "e" */
4832 * Check for holes and protection mismatch.
4833 * Holes: Next entry should be contiguous unless this
4834 * is the end of the region.
4835 * Protection: Access requested must be allowed, unless
4836 * wiring is by protection class
4838 if ((entry
->vme_end
< end
) &&
4839 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
4840 (entry
->vme_next
->vme_start
> entry
->vme_end
))) {
4842 rc
= KERN_INVALID_ADDRESS
;
4845 if ((entry
->protection
& access_type
) != access_type
) {
4846 /* found a protection problem */
4847 rc
= KERN_PROTECTION_FAILURE
;
4851 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
4853 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
4856 entry
->in_transition
= TRUE
;
4859 * This entry might get split once we unlock the map.
4860 * In vm_fault_wire(), we need the current range as
4861 * defined by this entry. In order for this to work
4862 * along with a simultaneous clip operation, we make a
4863 * temporary copy of this entry and use that for the
4864 * wiring. Note that the underlying objects do not
4865 * change during a clip.
4870 * The in_transition state guarentees that the entry
4871 * (or entries for this range, if split occured) will be
4872 * there when the map lock is acquired for the second time.
4876 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
4877 interruptible_state
= thread_interrupt_level(THREAD_UNINT
);
4879 interruptible_state
= THREAD_UNINT
;
4882 rc
= vm_fault_wire(map
,
4883 &tmp_entry
, map_pmap
, pmap_addr
,
4886 rc
= vm_fault_wire(map
,
4887 &tmp_entry
, map
->pmap
,
4888 tmp_entry
.vme_start
,
4891 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
4892 thread_interrupt_level(interruptible_state
);
4896 if (last_timestamp
+1 != map
->timestamp
) {
4898 * Find the entry again. It could have been clipped
4899 * after we unlocked the map.
4901 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
4903 panic("vm_map_wire: re-lookup failed");
4905 entry
= first_entry
;
4908 last_timestamp
= map
->timestamp
;
4910 while ((entry
!= vm_map_to_entry(map
)) &&
4911 (entry
->vme_start
< tmp_entry
.vme_end
)) {
4912 assert(entry
->in_transition
);
4913 entry
->in_transition
= FALSE
;
4914 if (entry
->needs_wakeup
) {
4915 entry
->needs_wakeup
= FALSE
;
4918 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
4919 subtract_wire_counts(map
, entry
, user_wire
);
4921 entry
= entry
->vme_next
;
4924 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
4928 s
= entry
->vme_start
;
4929 } /* end while loop through map entries */
4932 if (rc
== KERN_SUCCESS
) {
4933 /* repair any damage we may have made to the VM map */
4934 vm_map_simplify_range(map
, start
, end
);
4940 * wake up anybody waiting on entries we wired.
4943 vm_map_entry_wakeup(map
);
4945 if (rc
!= KERN_SUCCESS
) {
4946 /* undo what has been wired so far */
4947 vm_map_unwire(map
, start
, s
, user_wire
);
4959 register vm_map_t map
,
4960 register vm_map_offset_t start
,
4961 register vm_map_offset_t end
,
4962 register vm_prot_t access_type
,
4963 boolean_t user_wire
)
4968 kret
= vm_map_wire_nested(map
, start
, end
, access_type
,
4969 user_wire
, (pmap_t
)NULL
, 0, NULL
);
4974 vm_map_wire_and_extract(
4976 vm_map_offset_t start
,
4977 vm_prot_t access_type
,
4978 boolean_t user_wire
,
4979 ppnum_t
*physpage_p
)
4984 kret
= vm_map_wire_nested(map
,
4986 start
+VM_MAP_PAGE_SIZE(map
),
4992 if (kret
!= KERN_SUCCESS
&&
4993 physpage_p
!= NULL
) {
5002 * Sets the pageability of the specified address range in the target
5003 * as pageable. Regions specified must have been wired previously.
5005 * The map must not be locked, but a reference must remain to the map
5006 * throughout the call.
5008 * Kernel will panic on failures. User unwire ignores holes and
5009 * unwired and intransition entries to avoid losing memory by leaving
5012 static kern_return_t
5013 vm_map_unwire_nested(
5014 register vm_map_t map
,
5015 register vm_map_offset_t start
,
5016 register vm_map_offset_t end
,
5017 boolean_t user_wire
,
5019 vm_map_offset_t pmap_addr
)
5021 register vm_map_entry_t entry
;
5022 struct vm_map_entry
*first_entry
, tmp_entry
;
5023 boolean_t need_wakeup
;
5024 boolean_t main_map
= FALSE
;
5025 unsigned int last_timestamp
;
5028 if(map_pmap
== NULL
)
5030 last_timestamp
= map
->timestamp
;
5032 VM_MAP_RANGE_CHECK(map
, start
, end
);
5033 assert(page_aligned(start
));
5034 assert(page_aligned(end
));
5035 assert(VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)));
5036 assert(VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)));
5039 /* We unwired what the caller asked for: zero pages */
5041 return KERN_SUCCESS
;
5044 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
5045 entry
= first_entry
;
5047 * vm_map_clip_start will be done later.
5048 * We don't want to unnest any nested sub maps here !
5053 panic("vm_map_unwire: start not found");
5055 /* Start address is not in map. */
5057 return(KERN_INVALID_ADDRESS
);
5060 if (entry
->superpage_size
) {
5061 /* superpages are always wired */
5063 return KERN_INVALID_ADDRESS
;
5066 need_wakeup
= FALSE
;
5067 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
5068 if (entry
->in_transition
) {
5071 * Another thread is wiring down this entry. Note
5072 * that if it is not for the other thread we would
5073 * be unwiring an unwired entry. This is not
5074 * permitted. If we wait, we will be unwiring memory
5078 * Another thread is unwiring this entry. We did not
5079 * have a reference to it, because if we did, this
5080 * entry will not be getting unwired now.
5085 * This could happen: there could be some
5086 * overlapping vslock/vsunlock operations
5088 * We should probably just wait and retry,
5089 * but then we have to be careful that this
5090 * entry could get "simplified" after
5091 * "in_transition" gets unset and before
5092 * we re-lookup the entry, so we would
5093 * have to re-clip the entry to avoid
5094 * re-unwiring what we have already unwired...
5095 * See vm_map_wire_nested().
5097 * Or we could just ignore "in_transition"
5098 * here and proceed to decement the wired
5099 * count(s) on this entry. That should be fine
5100 * as long as "wired_count" doesn't drop all
5101 * the way to 0 (and we should panic if THAT
5104 panic("vm_map_unwire: in_transition entry");
5107 entry
= entry
->vme_next
;
5111 if (entry
->is_sub_map
) {
5112 vm_map_offset_t sub_start
;
5113 vm_map_offset_t sub_end
;
5114 vm_map_offset_t local_end
;
5117 vm_map_clip_start(map
, entry
, start
);
5118 vm_map_clip_end(map
, entry
, end
);
5120 sub_start
= entry
->offset
;
5121 sub_end
= entry
->vme_end
- entry
->vme_start
;
5122 sub_end
+= entry
->offset
;
5123 local_end
= entry
->vme_end
;
5124 if(map_pmap
== NULL
) {
5125 if(entry
->use_pmap
) {
5126 pmap
= entry
->object
.sub_map
->pmap
;
5127 pmap_addr
= sub_start
;
5132 if (entry
->wired_count
== 0 ||
5133 (user_wire
&& entry
->user_wired_count
== 0)) {
5135 panic("vm_map_unwire: entry is unwired");
5136 entry
= entry
->vme_next
;
5142 * Holes: Next entry should be contiguous unless
5143 * this is the end of the region.
5145 if (((entry
->vme_end
< end
) &&
5146 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
5147 (entry
->vme_next
->vme_start
5148 > entry
->vme_end
)))) {
5150 panic("vm_map_unwire: non-contiguous region");
5152 entry = entry->vme_next;
5157 subtract_wire_counts(map
, entry
, user_wire
);
5159 if (entry
->wired_count
!= 0) {
5160 entry
= entry
->vme_next
;
5164 entry
->in_transition
= TRUE
;
5165 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
5168 * We can unlock the map now. The in_transition state
5169 * guarantees existance of the entry.
5172 vm_map_unwire_nested(entry
->object
.sub_map
,
5173 sub_start
, sub_end
, user_wire
, pmap
, pmap_addr
);
5176 if (last_timestamp
+1 != map
->timestamp
) {
5178 * Find the entry again. It could have been
5179 * clipped or deleted after we unlocked the map.
5181 if (!vm_map_lookup_entry(map
,
5182 tmp_entry
.vme_start
,
5185 panic("vm_map_unwire: re-lookup failed");
5186 entry
= first_entry
->vme_next
;
5188 entry
= first_entry
;
5190 last_timestamp
= map
->timestamp
;
5193 * clear transition bit for all constituent entries
5194 * that were in the original entry (saved in
5195 * tmp_entry). Also check for waiters.
5197 while ((entry
!= vm_map_to_entry(map
)) &&
5198 (entry
->vme_start
< tmp_entry
.vme_end
)) {
5199 assert(entry
->in_transition
);
5200 entry
->in_transition
= FALSE
;
5201 if (entry
->needs_wakeup
) {
5202 entry
->needs_wakeup
= FALSE
;
5205 entry
= entry
->vme_next
;
5210 vm_map_unwire_nested(entry
->object
.sub_map
,
5211 sub_start
, sub_end
, user_wire
, map_pmap
,
5215 if (last_timestamp
+1 != map
->timestamp
) {
5217 * Find the entry again. It could have been
5218 * clipped or deleted after we unlocked the map.
5220 if (!vm_map_lookup_entry(map
,
5221 tmp_entry
.vme_start
,
5224 panic("vm_map_unwire: re-lookup failed");
5225 entry
= first_entry
->vme_next
;
5227 entry
= first_entry
;
5229 last_timestamp
= map
->timestamp
;
5234 if ((entry
->wired_count
== 0) ||
5235 (user_wire
&& entry
->user_wired_count
== 0)) {
5237 panic("vm_map_unwire: entry is unwired");
5239 entry
= entry
->vme_next
;
5243 assert(entry
->wired_count
> 0 &&
5244 (!user_wire
|| entry
->user_wired_count
> 0));
5246 vm_map_clip_start(map
, entry
, start
);
5247 vm_map_clip_end(map
, entry
, end
);
5251 * Holes: Next entry should be contiguous unless
5252 * this is the end of the region.
5254 if (((entry
->vme_end
< end
) &&
5255 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
5256 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
5259 panic("vm_map_unwire: non-contiguous region");
5260 entry
= entry
->vme_next
;
5264 subtract_wire_counts(map
, entry
, user_wire
);
5266 if (entry
->wired_count
!= 0) {
5267 entry
= entry
->vme_next
;
5271 if(entry
->zero_wired_pages
) {
5272 entry
->zero_wired_pages
= FALSE
;
5275 entry
->in_transition
= TRUE
;
5276 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
5279 * We can unlock the map now. The in_transition state
5280 * guarantees existance of the entry.
5284 vm_fault_unwire(map
,
5285 &tmp_entry
, FALSE
, map_pmap
, pmap_addr
);
5287 vm_fault_unwire(map
,
5288 &tmp_entry
, FALSE
, map
->pmap
,
5289 tmp_entry
.vme_start
);
5293 if (last_timestamp
+1 != map
->timestamp
) {
5295 * Find the entry again. It could have been clipped
5296 * or deleted after we unlocked the map.
5298 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
5301 panic("vm_map_unwire: re-lookup failed");
5302 entry
= first_entry
->vme_next
;
5304 entry
= first_entry
;
5306 last_timestamp
= map
->timestamp
;
5309 * clear transition bit for all constituent entries that
5310 * were in the original entry (saved in tmp_entry). Also
5311 * check for waiters.
5313 while ((entry
!= vm_map_to_entry(map
)) &&
5314 (entry
->vme_start
< tmp_entry
.vme_end
)) {
5315 assert(entry
->in_transition
);
5316 entry
->in_transition
= FALSE
;
5317 if (entry
->needs_wakeup
) {
5318 entry
->needs_wakeup
= FALSE
;
5321 entry
= entry
->vme_next
;
5326 * We might have fragmented the address space when we wired this
5327 * range of addresses. Attempt to re-coalesce these VM map entries
5328 * with their neighbors now that they're no longer wired.
5329 * Under some circumstances, address space fragmentation can
5330 * prevent VM object shadow chain collapsing, which can cause
5333 vm_map_simplify_range(map
, start
, end
);
5337 * wake up anybody waiting on entries that we have unwired.
5340 vm_map_entry_wakeup(map
);
5341 return(KERN_SUCCESS
);
5347 register vm_map_t map
,
5348 register vm_map_offset_t start
,
5349 register vm_map_offset_t end
,
5350 boolean_t user_wire
)
5352 return vm_map_unwire_nested(map
, start
, end
,
5353 user_wire
, (pmap_t
)NULL
, 0);
5358 * vm_map_entry_delete: [ internal use only ]
5360 * Deallocate the given entry from the target map.
5363 vm_map_entry_delete(
5364 register vm_map_t map
,
5365 register vm_map_entry_t entry
)
5367 register vm_map_offset_t s
, e
;
5368 register vm_object_t object
;
5369 register vm_map_t submap
;
5371 s
= entry
->vme_start
;
5373 assert(page_aligned(s
));
5374 assert(page_aligned(e
));
5375 if (entry
->map_aligned
== TRUE
) {
5376 assert(VM_MAP_PAGE_ALIGNED(s
, VM_MAP_PAGE_MASK(map
)));
5377 assert(VM_MAP_PAGE_ALIGNED(e
, VM_MAP_PAGE_MASK(map
)));
5379 assert(entry
->wired_count
== 0);
5380 assert(entry
->user_wired_count
== 0);
5381 assert(!entry
->permanent
);
5383 if (entry
->is_sub_map
) {
5385 submap
= entry
->object
.sub_map
;
5388 object
= entry
->object
.vm_object
;
5391 vm_map_store_entry_unlink(map
, entry
);
5394 vm_map_entry_dispose(map
, entry
);
5398 * Deallocate the object only after removing all
5399 * pmap entries pointing to its pages.
5402 vm_map_deallocate(submap
);
5404 vm_object_deallocate(object
);
5409 vm_map_submap_pmap_clean(
5411 vm_map_offset_t start
,
5412 vm_map_offset_t end
,
5414 vm_map_offset_t offset
)
5416 vm_map_offset_t submap_start
;
5417 vm_map_offset_t submap_end
;
5418 vm_map_size_t remove_size
;
5419 vm_map_entry_t entry
;
5421 submap_end
= offset
+ (end
- start
);
5422 submap_start
= offset
;
5424 vm_map_lock_read(sub_map
);
5425 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
5427 remove_size
= (entry
->vme_end
- entry
->vme_start
);
5428 if(offset
> entry
->vme_start
)
5429 remove_size
-= offset
- entry
->vme_start
;
5432 if(submap_end
< entry
->vme_end
) {
5434 entry
->vme_end
- submap_end
;
5436 if(entry
->is_sub_map
) {
5437 vm_map_submap_pmap_clean(
5440 start
+ remove_size
,
5441 entry
->object
.sub_map
,
5445 if((map
->mapped_in_other_pmaps
) && (map
->ref_count
)
5446 && (entry
->object
.vm_object
!= NULL
)) {
5447 vm_object_pmap_protect(
5448 entry
->object
.vm_object
,
5449 entry
->offset
+(offset
-entry
->vme_start
),
5455 pmap_remove(map
->pmap
,
5457 (addr64_t
)(start
+ remove_size
));
5462 entry
= entry
->vme_next
;
5464 while((entry
!= vm_map_to_entry(sub_map
))
5465 && (entry
->vme_start
< submap_end
)) {
5466 remove_size
= (entry
->vme_end
- entry
->vme_start
);
5467 if(submap_end
< entry
->vme_end
) {
5468 remove_size
-= entry
->vme_end
- submap_end
;
5470 if(entry
->is_sub_map
) {
5471 vm_map_submap_pmap_clean(
5473 (start
+ entry
->vme_start
) - offset
,
5474 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
5475 entry
->object
.sub_map
,
5478 if((map
->mapped_in_other_pmaps
) && (map
->ref_count
)
5479 && (entry
->object
.vm_object
!= NULL
)) {
5480 vm_object_pmap_protect(
5481 entry
->object
.vm_object
,
5488 pmap_remove(map
->pmap
,
5489 (addr64_t
)((start
+ entry
->vme_start
)
5491 (addr64_t
)(((start
+ entry
->vme_start
)
5492 - offset
) + remove_size
));
5495 entry
= entry
->vme_next
;
5497 vm_map_unlock_read(sub_map
);
5502 * vm_map_delete: [ internal use only ]
5504 * Deallocates the given address range from the target map.
5505 * Removes all user wirings. Unwires one kernel wiring if
5506 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
5507 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
5508 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
5510 * This routine is called with map locked and leaves map locked.
5512 static kern_return_t
5515 vm_map_offset_t start
,
5516 vm_map_offset_t end
,
5520 vm_map_entry_t entry
, next
;
5521 struct vm_map_entry
*first_entry
, tmp_entry
;
5522 register vm_map_offset_t s
;
5523 register vm_object_t object
;
5524 boolean_t need_wakeup
;
5525 unsigned int last_timestamp
= ~0; /* unlikely value */
5528 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
5529 THREAD_ABORTSAFE
: THREAD_UNINT
;
5532 * All our DMA I/O operations in IOKit are currently done by
5533 * wiring through the map entries of the task requesting the I/O.
5534 * Because of this, we must always wait for kernel wirings
5535 * to go away on the entries before deleting them.
5537 * Any caller who wants to actually remove a kernel wiring
5538 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
5539 * properly remove one wiring instead of blasting through
5542 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
5546 * Find the start of the region, and clip it
5548 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
5549 entry
= first_entry
;
5550 if (map
== kalloc_map
&&
5551 (entry
->vme_start
!= start
||
5552 entry
->vme_end
!= end
)) {
5553 panic("vm_map_delete(%p,0x%llx,0x%llx): "
5554 "mismatched entry %p [0x%llx:0x%llx]\n",
5559 (uint64_t)entry
->vme_start
,
5560 (uint64_t)entry
->vme_end
);
5562 if (entry
->superpage_size
&& (start
& ~SUPERPAGE_MASK
)) { /* extend request to whole entry */ start
= SUPERPAGE_ROUND_DOWN(start
);
5563 start
= SUPERPAGE_ROUND_DOWN(start
);
5566 if (start
== entry
->vme_start
) {
5568 * No need to clip. We don't want to cause
5569 * any unnecessary unnesting in this case...
5572 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
5573 entry
->map_aligned
&&
5574 !VM_MAP_PAGE_ALIGNED(
5576 VM_MAP_PAGE_MASK(map
))) {
5578 * The entry will no longer be
5579 * map-aligned after clipping
5580 * and the caller said it's OK.
5582 entry
->map_aligned
= FALSE
;
5584 if (map
== kalloc_map
) {
5585 panic("vm_map_delete(%p,0x%llx,0x%llx):"
5586 " clipping %p at 0x%llx\n",
5593 vm_map_clip_start(map
, entry
, start
);
5597 * Fix the lookup hint now, rather than each
5598 * time through the loop.
5600 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
5602 if (map
->pmap
== kernel_pmap
&&
5603 map
->ref_count
!= 0) {
5604 panic("vm_map_delete(%p,0x%llx,0x%llx): "
5605 "no map entry at 0x%llx\n",
5611 entry
= first_entry
->vme_next
;
5615 if (entry
->superpage_size
)
5616 end
= SUPERPAGE_ROUND_UP(end
);
5618 need_wakeup
= FALSE
;
5620 * Step through all entries in this region
5622 s
= entry
->vme_start
;
5623 while ((entry
!= vm_map_to_entry(map
)) && (s
< end
)) {
5625 * At this point, we have deleted all the memory entries
5626 * between "start" and "s". We still need to delete
5627 * all memory entries between "s" and "end".
5628 * While we were blocked and the map was unlocked, some
5629 * new memory entries could have been re-allocated between
5630 * "start" and "s" and we don't want to mess with those.
5631 * Some of those entries could even have been re-assembled
5632 * with an entry after "s" (in vm_map_simplify_entry()), so
5633 * we may have to vm_map_clip_start() again.
5636 if (entry
->vme_start
>= s
) {
5638 * This entry starts on or after "s"
5639 * so no need to clip its start.
5643 * This entry has been re-assembled by a
5644 * vm_map_simplify_entry(). We need to
5645 * re-clip its start.
5647 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
5648 entry
->map_aligned
&&
5649 !VM_MAP_PAGE_ALIGNED(s
,
5650 VM_MAP_PAGE_MASK(map
))) {
5652 * The entry will no longer be map-aligned
5653 * after clipping and the caller said it's OK.
5655 entry
->map_aligned
= FALSE
;
5657 if (map
== kalloc_map
) {
5658 panic("vm_map_delete(%p,0x%llx,0x%llx): "
5659 "clipping %p at 0x%llx\n",
5666 vm_map_clip_start(map
, entry
, s
);
5668 if (entry
->vme_end
<= end
) {
5670 * This entry is going away completely, so no need
5671 * to clip and possibly cause an unnecessary unnesting.
5674 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
5675 entry
->map_aligned
&&
5676 !VM_MAP_PAGE_ALIGNED(end
,
5677 VM_MAP_PAGE_MASK(map
))) {
5679 * The entry will no longer be map-aligned
5680 * after clipping and the caller said it's OK.
5682 entry
->map_aligned
= FALSE
;
5684 if (map
== kalloc_map
) {
5685 panic("vm_map_delete(%p,0x%llx,0x%llx): "
5686 "clipping %p at 0x%llx\n",
5693 vm_map_clip_end(map
, entry
, end
);
5696 if (entry
->permanent
) {
5697 panic("attempt to remove permanent VM map entry "
5698 "%p [0x%llx:0x%llx]\n",
5699 entry
, (uint64_t) s
, (uint64_t) end
);
5703 if (entry
->in_transition
) {
5704 wait_result_t wait_result
;
5707 * Another thread is wiring/unwiring this entry.
5708 * Let the other thread know we are waiting.
5710 assert(s
== entry
->vme_start
);
5711 entry
->needs_wakeup
= TRUE
;
5714 * wake up anybody waiting on entries that we have
5715 * already unwired/deleted.
5718 vm_map_entry_wakeup(map
);
5719 need_wakeup
= FALSE
;
5722 wait_result
= vm_map_entry_wait(map
, interruptible
);
5724 if (interruptible
&&
5725 wait_result
== THREAD_INTERRUPTED
) {
5727 * We do not clear the needs_wakeup flag,
5728 * since we cannot tell if we were the only one.
5730 return KERN_ABORTED
;
5734 * The entry could have been clipped or it
5735 * may not exist anymore. Look it up again.
5737 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
5738 assert((map
!= kernel_map
) &&
5739 (!entry
->is_sub_map
));
5741 * User: use the next entry
5743 entry
= first_entry
->vme_next
;
5744 s
= entry
->vme_start
;
5746 entry
= first_entry
;
5747 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
5749 last_timestamp
= map
->timestamp
;
5751 } /* end in_transition */
5753 if (entry
->wired_count
) {
5754 boolean_t user_wire
;
5756 user_wire
= entry
->user_wired_count
> 0;
5759 * Remove a kernel wiring if requested
5761 if (flags
& VM_MAP_REMOVE_KUNWIRE
) {
5762 entry
->wired_count
--;
5766 * Remove all user wirings for proper accounting
5768 if (entry
->user_wired_count
> 0) {
5769 while (entry
->user_wired_count
)
5770 subtract_wire_counts(map
, entry
, user_wire
);
5773 if (entry
->wired_count
!= 0) {
5774 assert(map
!= kernel_map
);
5776 * Cannot continue. Typical case is when
5777 * a user thread has physical io pending on
5778 * on this page. Either wait for the
5779 * kernel wiring to go away or return an
5782 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
5783 wait_result_t wait_result
;
5785 assert(s
== entry
->vme_start
);
5786 entry
->needs_wakeup
= TRUE
;
5787 wait_result
= vm_map_entry_wait(map
,
5790 if (interruptible
&&
5791 wait_result
== THREAD_INTERRUPTED
) {
5793 * We do not clear the
5794 * needs_wakeup flag, since we
5795 * cannot tell if we were the
5798 return KERN_ABORTED
;
5802 * The entry could have been clipped or
5803 * it may not exist anymore. Look it
5806 if (!vm_map_lookup_entry(map
, s
,
5808 assert(map
!= kernel_map
);
5810 * User: use the next entry
5812 entry
= first_entry
->vme_next
;
5813 s
= entry
->vme_start
;
5815 entry
= first_entry
;
5816 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
5818 last_timestamp
= map
->timestamp
;
5822 return KERN_FAILURE
;
5826 entry
->in_transition
= TRUE
;
5828 * copy current entry. see comment in vm_map_wire()
5831 assert(s
== entry
->vme_start
);
5834 * We can unlock the map now. The in_transition
5835 * state guarentees existance of the entry.
5839 if (tmp_entry
.is_sub_map
) {
5841 vm_map_offset_t sub_start
, sub_end
;
5843 vm_map_offset_t pmap_addr
;
5846 sub_map
= tmp_entry
.object
.sub_map
;
5847 sub_start
= tmp_entry
.offset
;
5848 sub_end
= sub_start
+ (tmp_entry
.vme_end
-
5849 tmp_entry
.vme_start
);
5850 if (tmp_entry
.use_pmap
) {
5851 pmap
= sub_map
->pmap
;
5852 pmap_addr
= tmp_entry
.vme_start
;
5855 pmap_addr
= tmp_entry
.vme_start
;
5857 (void) vm_map_unwire_nested(sub_map
,
5863 if (tmp_entry
.object
.vm_object
== kernel_object
) {
5864 pmap_protect_options(
5866 tmp_entry
.vme_start
,
5869 PMAP_OPTIONS_REMOVE
,
5872 vm_fault_unwire(map
, &tmp_entry
,
5873 tmp_entry
.object
.vm_object
== kernel_object
,
5874 map
->pmap
, tmp_entry
.vme_start
);
5879 if (last_timestamp
+1 != map
->timestamp
) {
5881 * Find the entry again. It could have
5882 * been clipped after we unlocked the map.
5884 if (!vm_map_lookup_entry(map
, s
, &first_entry
)){
5885 assert((map
!= kernel_map
) &&
5886 (!entry
->is_sub_map
));
5887 first_entry
= first_entry
->vme_next
;
5888 s
= first_entry
->vme_start
;
5890 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
5893 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
5894 first_entry
= entry
;
5897 last_timestamp
= map
->timestamp
;
5899 entry
= first_entry
;
5900 while ((entry
!= vm_map_to_entry(map
)) &&
5901 (entry
->vme_start
< tmp_entry
.vme_end
)) {
5902 assert(entry
->in_transition
);
5903 entry
->in_transition
= FALSE
;
5904 if (entry
->needs_wakeup
) {
5905 entry
->needs_wakeup
= FALSE
;
5908 entry
= entry
->vme_next
;
5911 * We have unwired the entry(s). Go back and
5914 entry
= first_entry
;
5918 /* entry is unwired */
5919 assert(entry
->wired_count
== 0);
5920 assert(entry
->user_wired_count
== 0);
5922 assert(s
== entry
->vme_start
);
5924 if (flags
& VM_MAP_REMOVE_NO_PMAP_CLEANUP
) {
5926 * XXX with the VM_MAP_REMOVE_SAVE_ENTRIES flag to
5927 * vm_map_delete(), some map entries might have been
5928 * transferred to a "zap_map", which doesn't have a
5929 * pmap. The original pmap has already been flushed
5930 * in the vm_map_delete() call targeting the original
5931 * map, but when we get to destroying the "zap_map",
5932 * we don't have any pmap to flush, so let's just skip
5935 } else if (entry
->is_sub_map
) {
5936 if (entry
->use_pmap
) {
5937 #ifndef NO_NESTED_PMAP
5938 pmap_unnest(map
->pmap
,
5939 (addr64_t
)entry
->vme_start
,
5940 entry
->vme_end
- entry
->vme_start
);
5941 #endif /* NO_NESTED_PMAP */
5942 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
5943 /* clean up parent map/maps */
5944 vm_map_submap_pmap_clean(
5945 map
, entry
->vme_start
,
5947 entry
->object
.sub_map
,
5951 vm_map_submap_pmap_clean(
5952 map
, entry
->vme_start
, entry
->vme_end
,
5953 entry
->object
.sub_map
,
5956 } else if (entry
->object
.vm_object
!= kernel_object
&&
5957 entry
->object
.vm_object
!= compressor_object
) {
5958 object
= entry
->object
.vm_object
;
5959 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
5960 vm_object_pmap_protect_options(
5961 object
, entry
->offset
,
5962 entry
->vme_end
- entry
->vme_start
,
5966 PMAP_OPTIONS_REMOVE
);
5967 } else if ((entry
->object
.vm_object
!=
5969 (map
->pmap
== kernel_pmap
)) {
5970 /* Remove translations associated
5971 * with this range unless the entry
5972 * does not have an object, or
5973 * it's the kernel map or a descendant
5974 * since the platform could potentially
5975 * create "backdoor" mappings invisible
5976 * to the VM. It is expected that
5977 * objectless, non-kernel ranges
5978 * do not have such VM invisible
5981 pmap_remove_options(map
->pmap
,
5982 (addr64_t
)entry
->vme_start
,
5983 (addr64_t
)entry
->vme_end
,
5984 PMAP_OPTIONS_REMOVE
);
5988 if (entry
->iokit_acct
) {
5989 /* alternate accounting */
5990 vm_map_iokit_unmapped_region(map
,
5993 entry
->iokit_acct
= FALSE
;
5997 * All pmap mappings for this map entry must have been
6001 assert(vm_map_pmap_is_empty(map
,
6006 next
= entry
->vme_next
;
6008 if (map
->pmap
== kernel_pmap
&&
6009 map
->ref_count
!= 0 &&
6010 entry
->vme_end
< end
&&
6011 (next
== vm_map_to_entry(map
) ||
6012 next
->vme_start
!= entry
->vme_end
)) {
6013 panic("vm_map_delete(%p,0x%llx,0x%llx): "
6014 "hole after %p at 0x%llx\n",
6019 (uint64_t)entry
->vme_end
);
6022 s
= next
->vme_start
;
6023 last_timestamp
= map
->timestamp
;
6025 if ((flags
& VM_MAP_REMOVE_SAVE_ENTRIES
) &&
6026 zap_map
!= VM_MAP_NULL
) {
6027 vm_map_size_t entry_size
;
6029 * The caller wants to save the affected VM map entries
6030 * into the "zap_map". The caller will take care of
6033 /* unlink the entry from "map" ... */
6034 vm_map_store_entry_unlink(map
, entry
);
6035 /* ... and add it to the end of the "zap_map" */
6036 vm_map_store_entry_link(zap_map
,
6037 vm_map_last_entry(zap_map
),
6039 entry_size
= entry
->vme_end
- entry
->vme_start
;
6040 map
->size
-= entry_size
;
6041 zap_map
->size
+= entry_size
;
6042 /* we didn't unlock the map, so no timestamp increase */
6045 vm_map_entry_delete(map
, entry
);
6046 /* vm_map_entry_delete unlocks the map */
6052 if(entry
== vm_map_to_entry(map
)) {
6055 if (last_timestamp
+1 != map
->timestamp
) {
6057 * we are responsible for deleting everything
6058 * from the give space, if someone has interfered
6059 * we pick up where we left off, back fills should
6060 * be all right for anyone except map_delete and
6061 * we have to assume that the task has been fully
6062 * disabled before we get here
6064 if (!vm_map_lookup_entry(map
, s
, &entry
)){
6065 entry
= entry
->vme_next
;
6066 s
= entry
->vme_start
;
6068 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
6071 * others can not only allocate behind us, we can
6072 * also see coalesce while we don't have the map lock
6074 if(entry
== vm_map_to_entry(map
)) {
6078 last_timestamp
= map
->timestamp
;
6081 if (map
->wait_for_space
)
6082 thread_wakeup((event_t
) map
);
6084 * wake up anybody waiting on entries that we have already deleted.
6087 vm_map_entry_wakeup(map
);
6089 return KERN_SUCCESS
;
6095 * Remove the given address range from the target map.
6096 * This is the exported form of vm_map_delete.
6100 register vm_map_t map
,
6101 register vm_map_offset_t start
,
6102 register vm_map_offset_t end
,
6103 register boolean_t flags
)
6105 register kern_return_t result
;
6108 VM_MAP_RANGE_CHECK(map
, start
, end
);
6110 * For the zone_map, the kernel controls the allocation/freeing of memory.
6111 * Any free to the zone_map should be within the bounds of the map and
6112 * should free up memory. If the VM_MAP_RANGE_CHECK() silently converts a
6113 * free to the zone_map into a no-op, there is a problem and we should
6116 if ((map
== zone_map
) && (start
== end
))
6117 panic("Nothing being freed to the zone_map. start = end = %p\n", (void *)start
);
6118 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
6126 * Routine: vm_map_copy_discard
6129 * Dispose of a map copy object (returned by
6133 vm_map_copy_discard(
6136 if (copy
== VM_MAP_COPY_NULL
)
6139 switch (copy
->type
) {
6140 case VM_MAP_COPY_ENTRY_LIST
:
6141 while (vm_map_copy_first_entry(copy
) !=
6142 vm_map_copy_to_entry(copy
)) {
6143 vm_map_entry_t entry
= vm_map_copy_first_entry(copy
);
6145 vm_map_copy_entry_unlink(copy
, entry
);
6146 if (entry
->is_sub_map
) {
6147 vm_map_deallocate(entry
->object
.sub_map
);
6149 vm_object_deallocate(entry
->object
.vm_object
);
6151 vm_map_copy_entry_dispose(copy
, entry
);
6154 case VM_MAP_COPY_OBJECT
:
6155 vm_object_deallocate(copy
->cpy_object
);
6157 case VM_MAP_COPY_KERNEL_BUFFER
:
6160 * The vm_map_copy_t and possibly the data buffer were
6161 * allocated by a single call to kalloc(), i.e. the
6162 * vm_map_copy_t was not allocated out of the zone.
6164 kfree(copy
, copy
->cpy_kalloc_size
);
6167 zfree(vm_map_copy_zone
, copy
);
6171 * Routine: vm_map_copy_copy
6174 * Move the information in a map copy object to
6175 * a new map copy object, leaving the old one
6178 * This is used by kernel routines that need
6179 * to look at out-of-line data (in copyin form)
6180 * before deciding whether to return SUCCESS.
6181 * If the routine returns FAILURE, the original
6182 * copy object will be deallocated; therefore,
6183 * these routines must make a copy of the copy
6184 * object and leave the original empty so that
6185 * deallocation will not fail.
6191 vm_map_copy_t new_copy
;
6193 if (copy
== VM_MAP_COPY_NULL
)
6194 return VM_MAP_COPY_NULL
;
6197 * Allocate a new copy object, and copy the information
6198 * from the old one into it.
6201 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6204 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
6206 * The links in the entry chain must be
6207 * changed to point to the new copy object.
6209 vm_map_copy_first_entry(copy
)->vme_prev
6210 = vm_map_copy_to_entry(new_copy
);
6211 vm_map_copy_last_entry(copy
)->vme_next
6212 = vm_map_copy_to_entry(new_copy
);
6216 * Change the old copy object into one that contains
6217 * nothing to be deallocated.
6219 copy
->type
= VM_MAP_COPY_OBJECT
;
6220 copy
->cpy_object
= VM_OBJECT_NULL
;
6223 * Return the new object.
6228 static kern_return_t
6229 vm_map_overwrite_submap_recurse(
6231 vm_map_offset_t dst_addr
,
6232 vm_map_size_t dst_size
)
6234 vm_map_offset_t dst_end
;
6235 vm_map_entry_t tmp_entry
;
6236 vm_map_entry_t entry
;
6237 kern_return_t result
;
6238 boolean_t encountered_sub_map
= FALSE
;
6243 * Verify that the destination is all writeable
6244 * initially. We have to trunc the destination
6245 * address and round the copy size or we'll end up
6246 * splitting entries in strange ways.
6249 dst_end
= vm_map_round_page(dst_addr
+ dst_size
,
6250 VM_MAP_PAGE_MASK(dst_map
));
6251 vm_map_lock(dst_map
);
6254 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
6255 vm_map_unlock(dst_map
);
6256 return(KERN_INVALID_ADDRESS
);
6259 vm_map_clip_start(dst_map
,
6261 vm_map_trunc_page(dst_addr
,
6262 VM_MAP_PAGE_MASK(dst_map
)));
6263 if (tmp_entry
->is_sub_map
) {
6264 /* clipping did unnest if needed */
6265 assert(!tmp_entry
->use_pmap
);
6268 for (entry
= tmp_entry
;;) {
6269 vm_map_entry_t next
;
6271 next
= entry
->vme_next
;
6272 while(entry
->is_sub_map
) {
6273 vm_map_offset_t sub_start
;
6274 vm_map_offset_t sub_end
;
6275 vm_map_offset_t local_end
;
6277 if (entry
->in_transition
) {
6279 * Say that we are waiting, and wait for entry.
6281 entry
->needs_wakeup
= TRUE
;
6282 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
6287 encountered_sub_map
= TRUE
;
6288 sub_start
= entry
->offset
;
6290 if(entry
->vme_end
< dst_end
)
6291 sub_end
= entry
->vme_end
;
6294 sub_end
-= entry
->vme_start
;
6295 sub_end
+= entry
->offset
;
6296 local_end
= entry
->vme_end
;
6297 vm_map_unlock(dst_map
);
6299 result
= vm_map_overwrite_submap_recurse(
6300 entry
->object
.sub_map
,
6302 sub_end
- sub_start
);
6304 if(result
!= KERN_SUCCESS
)
6306 if (dst_end
<= entry
->vme_end
)
6307 return KERN_SUCCESS
;
6308 vm_map_lock(dst_map
);
6309 if(!vm_map_lookup_entry(dst_map
, local_end
,
6311 vm_map_unlock(dst_map
);
6312 return(KERN_INVALID_ADDRESS
);
6315 next
= entry
->vme_next
;
6318 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
6319 vm_map_unlock(dst_map
);
6320 return(KERN_PROTECTION_FAILURE
);
6324 * If the entry is in transition, we must wait
6325 * for it to exit that state. Anything could happen
6326 * when we unlock the map, so start over.
6328 if (entry
->in_transition
) {
6331 * Say that we are waiting, and wait for entry.
6333 entry
->needs_wakeup
= TRUE
;
6334 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
6340 * our range is contained completely within this map entry
6342 if (dst_end
<= entry
->vme_end
) {
6343 vm_map_unlock(dst_map
);
6344 return KERN_SUCCESS
;
6347 * check that range specified is contiguous region
6349 if ((next
== vm_map_to_entry(dst_map
)) ||
6350 (next
->vme_start
!= entry
->vme_end
)) {
6351 vm_map_unlock(dst_map
);
6352 return(KERN_INVALID_ADDRESS
);
6356 * Check for permanent objects in the destination.
6358 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
6359 ((!entry
->object
.vm_object
->internal
) ||
6360 (entry
->object
.vm_object
->true_share
))) {
6361 if(encountered_sub_map
) {
6362 vm_map_unlock(dst_map
);
6363 return(KERN_FAILURE
);
6370 vm_map_unlock(dst_map
);
6371 return(KERN_SUCCESS
);
6375 * Routine: vm_map_copy_overwrite
6378 * Copy the memory described by the map copy
6379 * object (copy; returned by vm_map_copyin) onto
6380 * the specified destination region (dst_map, dst_addr).
6381 * The destination must be writeable.
6383 * Unlike vm_map_copyout, this routine actually
6384 * writes over previously-mapped memory. If the
6385 * previous mapping was to a permanent (user-supplied)
6386 * memory object, it is preserved.
6388 * The attributes (protection and inheritance) of the
6389 * destination region are preserved.
6391 * If successful, consumes the copy object.
6392 * Otherwise, the caller is responsible for it.
6394 * Implementation notes:
6395 * To overwrite aligned temporary virtual memory, it is
6396 * sufficient to remove the previous mapping and insert
6397 * the new copy. This replacement is done either on
6398 * the whole region (if no permanent virtual memory
6399 * objects are embedded in the destination region) or
6400 * in individual map entries.
6402 * To overwrite permanent virtual memory , it is necessary
6403 * to copy each page, as the external memory management
6404 * interface currently does not provide any optimizations.
6406 * Unaligned memory also has to be copied. It is possible
6407 * to use 'vm_trickery' to copy the aligned data. This is
6408 * not done but not hard to implement.
6410 * Once a page of permanent memory has been overwritten,
6411 * it is impossible to interrupt this function; otherwise,
6412 * the call would be neither atomic nor location-independent.
6413 * The kernel-state portion of a user thread must be
6416 * It may be expensive to forward all requests that might
6417 * overwrite permanent memory (vm_write, vm_copy) to
6418 * uninterruptible kernel threads. This routine may be
6419 * called by interruptible threads; however, success is
6420 * not guaranteed -- if the request cannot be performed
6421 * atomically and interruptibly, an error indication is
6425 static kern_return_t
6426 vm_map_copy_overwrite_nested(
6428 vm_map_address_t dst_addr
,
6430 boolean_t interruptible
,
6432 boolean_t discard_on_success
)
6434 vm_map_offset_t dst_end
;
6435 vm_map_entry_t tmp_entry
;
6436 vm_map_entry_t entry
;
6438 boolean_t aligned
= TRUE
;
6439 boolean_t contains_permanent_objects
= FALSE
;
6440 boolean_t encountered_sub_map
= FALSE
;
6441 vm_map_offset_t base_addr
;
6442 vm_map_size_t copy_size
;
6443 vm_map_size_t total_size
;
6447 * Check for null copy object.
6450 if (copy
== VM_MAP_COPY_NULL
)
6451 return(KERN_SUCCESS
);
6454 * Check for special kernel buffer allocated
6455 * by new_ipc_kmsg_copyin.
6458 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
6459 return(vm_map_copyout_kernel_buffer(
6461 copy
, TRUE
, discard_on_success
));
6465 * Only works for entry lists at the moment. Will
6466 * support page lists later.
6469 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
6471 if (copy
->size
== 0) {
6472 if (discard_on_success
)
6473 vm_map_copy_discard(copy
);
6474 return(KERN_SUCCESS
);
6478 * Verify that the destination is all writeable
6479 * initially. We have to trunc the destination
6480 * address and round the copy size or we'll end up
6481 * splitting entries in strange ways.
6484 if (!VM_MAP_PAGE_ALIGNED(copy
->size
,
6485 VM_MAP_PAGE_MASK(dst_map
)) ||
6486 !VM_MAP_PAGE_ALIGNED(copy
->offset
,
6487 VM_MAP_PAGE_MASK(dst_map
)) ||
6488 !VM_MAP_PAGE_ALIGNED(dst_addr
,
6489 VM_MAP_PAGE_MASK(dst_map
)))
6492 dst_end
= vm_map_round_page(dst_addr
+ copy
->size
,
6493 VM_MAP_PAGE_MASK(dst_map
));
6495 dst_end
= dst_addr
+ copy
->size
;
6498 vm_map_lock(dst_map
);
6500 /* LP64todo - remove this check when vm_map_commpage64()
6501 * no longer has to stuff in a map_entry for the commpage
6502 * above the map's max_offset.
6504 if (dst_addr
>= dst_map
->max_offset
) {
6505 vm_map_unlock(dst_map
);
6506 return(KERN_INVALID_ADDRESS
);
6510 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
6511 vm_map_unlock(dst_map
);
6512 return(KERN_INVALID_ADDRESS
);
6514 vm_map_clip_start(dst_map
,
6516 vm_map_trunc_page(dst_addr
,
6517 VM_MAP_PAGE_MASK(dst_map
)));
6518 for (entry
= tmp_entry
;;) {
6519 vm_map_entry_t next
= entry
->vme_next
;
6521 while(entry
->is_sub_map
) {
6522 vm_map_offset_t sub_start
;
6523 vm_map_offset_t sub_end
;
6524 vm_map_offset_t local_end
;
6526 if (entry
->in_transition
) {
6529 * Say that we are waiting, and wait for entry.
6531 entry
->needs_wakeup
= TRUE
;
6532 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
6537 local_end
= entry
->vme_end
;
6538 if (!(entry
->needs_copy
)) {
6539 /* if needs_copy we are a COW submap */
6540 /* in such a case we just replace so */
6541 /* there is no need for the follow- */
6543 encountered_sub_map
= TRUE
;
6544 sub_start
= entry
->offset
;
6546 if(entry
->vme_end
< dst_end
)
6547 sub_end
= entry
->vme_end
;
6550 sub_end
-= entry
->vme_start
;
6551 sub_end
+= entry
->offset
;
6552 vm_map_unlock(dst_map
);
6554 kr
= vm_map_overwrite_submap_recurse(
6555 entry
->object
.sub_map
,
6557 sub_end
- sub_start
);
6558 if(kr
!= KERN_SUCCESS
)
6560 vm_map_lock(dst_map
);
6563 if (dst_end
<= entry
->vme_end
)
6564 goto start_overwrite
;
6565 if(!vm_map_lookup_entry(dst_map
, local_end
,
6567 vm_map_unlock(dst_map
);
6568 return(KERN_INVALID_ADDRESS
);
6570 next
= entry
->vme_next
;
6573 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
6574 vm_map_unlock(dst_map
);
6575 return(KERN_PROTECTION_FAILURE
);
6579 * If the entry is in transition, we must wait
6580 * for it to exit that state. Anything could happen
6581 * when we unlock the map, so start over.
6583 if (entry
->in_transition
) {
6586 * Say that we are waiting, and wait for entry.
6588 entry
->needs_wakeup
= TRUE
;
6589 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
6595 * our range is contained completely within this map entry
6597 if (dst_end
<= entry
->vme_end
)
6600 * check that range specified is contiguous region
6602 if ((next
== vm_map_to_entry(dst_map
)) ||
6603 (next
->vme_start
!= entry
->vme_end
)) {
6604 vm_map_unlock(dst_map
);
6605 return(KERN_INVALID_ADDRESS
);
6610 * Check for permanent objects in the destination.
6612 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
6613 ((!entry
->object
.vm_object
->internal
) ||
6614 (entry
->object
.vm_object
->true_share
))) {
6615 contains_permanent_objects
= TRUE
;
6623 * If there are permanent objects in the destination, then
6624 * the copy cannot be interrupted.
6627 if (interruptible
&& contains_permanent_objects
) {
6628 vm_map_unlock(dst_map
);
6629 return(KERN_FAILURE
); /* XXX */
6634 * Make a second pass, overwriting the data
6635 * At the beginning of each loop iteration,
6636 * the next entry to be overwritten is "tmp_entry"
6637 * (initially, the value returned from the lookup above),
6638 * and the starting address expected in that entry
6642 total_size
= copy
->size
;
6643 if(encountered_sub_map
) {
6645 /* re-calculate tmp_entry since we've had the map */
6647 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
6648 vm_map_unlock(dst_map
);
6649 return(KERN_INVALID_ADDRESS
);
6652 copy_size
= copy
->size
;
6655 base_addr
= dst_addr
;
6657 /* deconstruct the copy object and do in parts */
6658 /* only in sub_map, interruptable case */
6659 vm_map_entry_t copy_entry
;
6660 vm_map_entry_t previous_prev
= VM_MAP_ENTRY_NULL
;
6661 vm_map_entry_t next_copy
= VM_MAP_ENTRY_NULL
;
6663 int remaining_entries
= 0;
6664 vm_map_offset_t new_offset
= 0;
6666 for (entry
= tmp_entry
; copy_size
== 0;) {
6667 vm_map_entry_t next
;
6669 next
= entry
->vme_next
;
6671 /* tmp_entry and base address are moved along */
6672 /* each time we encounter a sub-map. Otherwise */
6673 /* entry can outpase tmp_entry, and the copy_size */
6674 /* may reflect the distance between them */
6675 /* if the current entry is found to be in transition */
6676 /* we will start over at the beginning or the last */
6677 /* encounter of a submap as dictated by base_addr */
6678 /* we will zero copy_size accordingly. */
6679 if (entry
->in_transition
) {
6681 * Say that we are waiting, and wait for entry.
6683 entry
->needs_wakeup
= TRUE
;
6684 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
6686 if(!vm_map_lookup_entry(dst_map
, base_addr
,
6688 vm_map_unlock(dst_map
);
6689 return(KERN_INVALID_ADDRESS
);
6695 if(entry
->is_sub_map
) {
6696 vm_map_offset_t sub_start
;
6697 vm_map_offset_t sub_end
;
6698 vm_map_offset_t local_end
;
6700 if (entry
->needs_copy
) {
6701 /* if this is a COW submap */
6702 /* just back the range with a */
6703 /* anonymous entry */
6704 if(entry
->vme_end
< dst_end
)
6705 sub_end
= entry
->vme_end
;
6708 if(entry
->vme_start
< base_addr
)
6709 sub_start
= base_addr
;
6711 sub_start
= entry
->vme_start
;
6713 dst_map
, entry
, sub_end
);
6715 dst_map
, entry
, sub_start
);
6716 assert(!entry
->use_pmap
);
6717 entry
->is_sub_map
= FALSE
;
6719 entry
->object
.sub_map
);
6720 entry
->object
.sub_map
= NULL
;
6721 entry
->is_shared
= FALSE
;
6722 entry
->needs_copy
= FALSE
;
6726 * We should propagate the protections
6727 * of the submap entry here instead
6728 * of forcing them to VM_PROT_ALL...
6729 * Or better yet, we should inherit
6730 * the protection of the copy_entry.
6732 entry
->protection
= VM_PROT_ALL
;
6733 entry
->max_protection
= VM_PROT_ALL
;
6734 entry
->wired_count
= 0;
6735 entry
->user_wired_count
= 0;
6736 if(entry
->inheritance
6737 == VM_INHERIT_SHARE
)
6738 entry
->inheritance
= VM_INHERIT_COPY
;
6741 /* first take care of any non-sub_map */
6742 /* entries to send */
6743 if(base_addr
< entry
->vme_start
) {
6746 entry
->vme_start
- base_addr
;
6749 sub_start
= entry
->offset
;
6751 if(entry
->vme_end
< dst_end
)
6752 sub_end
= entry
->vme_end
;
6755 sub_end
-= entry
->vme_start
;
6756 sub_end
+= entry
->offset
;
6757 local_end
= entry
->vme_end
;
6758 vm_map_unlock(dst_map
);
6759 copy_size
= sub_end
- sub_start
;
6761 /* adjust the copy object */
6762 if (total_size
> copy_size
) {
6763 vm_map_size_t local_size
= 0;
6764 vm_map_size_t entry_size
;
6767 new_offset
= copy
->offset
;
6768 copy_entry
= vm_map_copy_first_entry(copy
);
6770 vm_map_copy_to_entry(copy
)){
6771 entry_size
= copy_entry
->vme_end
-
6772 copy_entry
->vme_start
;
6773 if((local_size
< copy_size
) &&
6774 ((local_size
+ entry_size
)
6776 vm_map_copy_clip_end(copy
,
6778 copy_entry
->vme_start
+
6779 (copy_size
- local_size
));
6780 entry_size
= copy_entry
->vme_end
-
6781 copy_entry
->vme_start
;
6782 local_size
+= entry_size
;
6783 new_offset
+= entry_size
;
6785 if(local_size
>= copy_size
) {
6786 next_copy
= copy_entry
->vme_next
;
6787 copy_entry
->vme_next
=
6788 vm_map_copy_to_entry(copy
);
6790 copy
->cpy_hdr
.links
.prev
;
6791 copy
->cpy_hdr
.links
.prev
= copy_entry
;
6792 copy
->size
= copy_size
;
6794 copy
->cpy_hdr
.nentries
;
6795 remaining_entries
-= nentries
;
6796 copy
->cpy_hdr
.nentries
= nentries
;
6799 local_size
+= entry_size
;
6800 new_offset
+= entry_size
;
6803 copy_entry
= copy_entry
->vme_next
;
6807 if((entry
->use_pmap
) && (pmap
== NULL
)) {
6808 kr
= vm_map_copy_overwrite_nested(
6809 entry
->object
.sub_map
,
6813 entry
->object
.sub_map
->pmap
,
6815 } else if (pmap
!= NULL
) {
6816 kr
= vm_map_copy_overwrite_nested(
6817 entry
->object
.sub_map
,
6820 interruptible
, pmap
,
6823 kr
= vm_map_copy_overwrite_nested(
6824 entry
->object
.sub_map
,
6831 if(kr
!= KERN_SUCCESS
) {
6832 if(next_copy
!= NULL
) {
6833 copy
->cpy_hdr
.nentries
+=
6835 copy
->cpy_hdr
.links
.prev
->vme_next
=
6837 copy
->cpy_hdr
.links
.prev
6839 copy
->size
= total_size
;
6843 if (dst_end
<= local_end
) {
6844 return(KERN_SUCCESS
);
6846 /* otherwise copy no longer exists, it was */
6847 /* destroyed after successful copy_overwrite */
6848 copy
= (vm_map_copy_t
)
6849 zalloc(vm_map_copy_zone
);
6850 vm_map_copy_first_entry(copy
) =
6851 vm_map_copy_last_entry(copy
) =
6852 vm_map_copy_to_entry(copy
);
6853 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
6854 copy
->offset
= new_offset
;
6858 * this does not seem to deal with
6859 * the VM map store (R&B tree)
6862 total_size
-= copy_size
;
6864 /* put back remainder of copy in container */
6865 if(next_copy
!= NULL
) {
6866 copy
->cpy_hdr
.nentries
= remaining_entries
;
6867 copy
->cpy_hdr
.links
.next
= next_copy
;
6868 copy
->cpy_hdr
.links
.prev
= previous_prev
;
6869 copy
->size
= total_size
;
6870 next_copy
->vme_prev
=
6871 vm_map_copy_to_entry(copy
);
6874 base_addr
= local_end
;
6875 vm_map_lock(dst_map
);
6876 if(!vm_map_lookup_entry(dst_map
,
6877 local_end
, &tmp_entry
)) {
6878 vm_map_unlock(dst_map
);
6879 return(KERN_INVALID_ADDRESS
);
6884 if (dst_end
<= entry
->vme_end
) {
6885 copy_size
= dst_end
- base_addr
;
6889 if ((next
== vm_map_to_entry(dst_map
)) ||
6890 (next
->vme_start
!= entry
->vme_end
)) {
6891 vm_map_unlock(dst_map
);
6892 return(KERN_INVALID_ADDRESS
);
6901 /* adjust the copy object */
6902 if (total_size
> copy_size
) {
6903 vm_map_size_t local_size
= 0;
6904 vm_map_size_t entry_size
;
6906 new_offset
= copy
->offset
;
6907 copy_entry
= vm_map_copy_first_entry(copy
);
6908 while(copy_entry
!= vm_map_copy_to_entry(copy
)) {
6909 entry_size
= copy_entry
->vme_end
-
6910 copy_entry
->vme_start
;
6911 if((local_size
< copy_size
) &&
6912 ((local_size
+ entry_size
)
6914 vm_map_copy_clip_end(copy
, copy_entry
,
6915 copy_entry
->vme_start
+
6916 (copy_size
- local_size
));
6917 entry_size
= copy_entry
->vme_end
-
6918 copy_entry
->vme_start
;
6919 local_size
+= entry_size
;
6920 new_offset
+= entry_size
;
6922 if(local_size
>= copy_size
) {
6923 next_copy
= copy_entry
->vme_next
;
6924 copy_entry
->vme_next
=
6925 vm_map_copy_to_entry(copy
);
6927 copy
->cpy_hdr
.links
.prev
;
6928 copy
->cpy_hdr
.links
.prev
= copy_entry
;
6929 copy
->size
= copy_size
;
6931 copy
->cpy_hdr
.nentries
;
6932 remaining_entries
-= nentries
;
6933 copy
->cpy_hdr
.nentries
= nentries
;
6936 local_size
+= entry_size
;
6937 new_offset
+= entry_size
;
6940 copy_entry
= copy_entry
->vme_next
;
6950 local_pmap
= dst_map
->pmap
;
6952 if ((kr
= vm_map_copy_overwrite_aligned(
6953 dst_map
, tmp_entry
, copy
,
6954 base_addr
, local_pmap
)) != KERN_SUCCESS
) {
6955 if(next_copy
!= NULL
) {
6956 copy
->cpy_hdr
.nentries
+=
6958 copy
->cpy_hdr
.links
.prev
->vme_next
=
6960 copy
->cpy_hdr
.links
.prev
=
6962 copy
->size
+= copy_size
;
6966 vm_map_unlock(dst_map
);
6971 * if the copy and dst address are misaligned but the same
6972 * offset within the page we can copy_not_aligned the
6973 * misaligned parts and copy aligned the rest. If they are
6974 * aligned but len is unaligned we simply need to copy
6975 * the end bit unaligned. We'll need to split the misaligned
6976 * bits of the region in this case !
6978 /* ALWAYS UNLOCKS THE dst_map MAP */
6979 kr
= vm_map_copy_overwrite_unaligned(
6984 discard_on_success
);
6985 if (kr
!= KERN_SUCCESS
) {
6986 if(next_copy
!= NULL
) {
6987 copy
->cpy_hdr
.nentries
+=
6989 copy
->cpy_hdr
.links
.prev
->vme_next
=
6991 copy
->cpy_hdr
.links
.prev
=
6993 copy
->size
+= copy_size
;
6998 total_size
-= copy_size
;
7001 base_addr
+= copy_size
;
7003 copy
->offset
= new_offset
;
7004 if(next_copy
!= NULL
) {
7005 copy
->cpy_hdr
.nentries
= remaining_entries
;
7006 copy
->cpy_hdr
.links
.next
= next_copy
;
7007 copy
->cpy_hdr
.links
.prev
= previous_prev
;
7008 next_copy
->vme_prev
= vm_map_copy_to_entry(copy
);
7009 copy
->size
= total_size
;
7011 vm_map_lock(dst_map
);
7013 if (!vm_map_lookup_entry(dst_map
,
7014 base_addr
, &tmp_entry
)) {
7015 vm_map_unlock(dst_map
);
7016 return(KERN_INVALID_ADDRESS
);
7018 if (tmp_entry
->in_transition
) {
7019 entry
->needs_wakeup
= TRUE
;
7020 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
7025 vm_map_clip_start(dst_map
,
7027 vm_map_trunc_page(base_addr
,
7028 VM_MAP_PAGE_MASK(dst_map
)));
7034 * Throw away the vm_map_copy object
7036 if (discard_on_success
)
7037 vm_map_copy_discard(copy
);
7039 return(KERN_SUCCESS
);
7040 }/* vm_map_copy_overwrite */
7043 vm_map_copy_overwrite(
7045 vm_map_offset_t dst_addr
,
7047 boolean_t interruptible
)
7049 vm_map_size_t head_size
, tail_size
;
7050 vm_map_copy_t head_copy
, tail_copy
;
7051 vm_map_offset_t head_addr
, tail_addr
;
7052 vm_map_entry_t entry
;
7062 if (interruptible
||
7063 copy
== VM_MAP_COPY_NULL
||
7064 copy
->type
!= VM_MAP_COPY_ENTRY_LIST
) {
7066 * We can't split the "copy" map if we're interruptible
7067 * or if we don't have a "copy" map...
7070 return vm_map_copy_overwrite_nested(dst_map
,
7078 if (copy
->size
< 3 * PAGE_SIZE
) {
7080 * Too small to bother with optimizing...
7085 if ((dst_addr
& VM_MAP_PAGE_MASK(dst_map
)) !=
7086 (copy
->offset
& VM_MAP_PAGE_MASK(dst_map
))) {
7088 * Incompatible mis-alignment of source and destination...
7094 * Proper alignment or identical mis-alignment at the beginning.
7095 * Let's try and do a small unaligned copy first (if needed)
7096 * and then an aligned copy for the rest.
7098 if (!page_aligned(dst_addr
)) {
7099 head_addr
= dst_addr
;
7100 head_size
= (VM_MAP_PAGE_SIZE(dst_map
) -
7101 (copy
->offset
& VM_MAP_PAGE_MASK(dst_map
)));
7103 if (!page_aligned(copy
->offset
+ copy
->size
)) {
7105 * Mis-alignment at the end.
7106 * Do an aligned copy up to the last page and
7107 * then an unaligned copy for the remaining bytes.
7109 tail_size
= ((copy
->offset
+ copy
->size
) &
7110 VM_MAP_PAGE_MASK(dst_map
));
7111 tail_addr
= dst_addr
+ copy
->size
- tail_size
;
7114 if (head_size
+ tail_size
== copy
->size
) {
7116 * It's all unaligned, no optimization possible...
7122 * Can't optimize if there are any submaps in the
7123 * destination due to the way we free the "copy" map
7124 * progressively in vm_map_copy_overwrite_nested()
7127 vm_map_lock_read(dst_map
);
7128 if (! vm_map_lookup_entry(dst_map
, dst_addr
, &entry
)) {
7129 vm_map_unlock_read(dst_map
);
7133 (entry
!= vm_map_copy_to_entry(copy
) &&
7134 entry
->vme_start
< dst_addr
+ copy
->size
);
7135 entry
= entry
->vme_next
) {
7136 if (entry
->is_sub_map
) {
7137 vm_map_unlock_read(dst_map
);
7141 vm_map_unlock_read(dst_map
);
7145 * Unaligned copy of the first "head_size" bytes, to reach
7150 * Extract "head_copy" out of "copy".
7152 head_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
7153 vm_map_copy_first_entry(head_copy
) =
7154 vm_map_copy_to_entry(head_copy
);
7155 vm_map_copy_last_entry(head_copy
) =
7156 vm_map_copy_to_entry(head_copy
);
7157 head_copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
7158 head_copy
->cpy_hdr
.nentries
= 0;
7159 head_copy
->cpy_hdr
.entries_pageable
=
7160 copy
->cpy_hdr
.entries_pageable
;
7161 vm_map_store_init(&head_copy
->cpy_hdr
);
7163 head_copy
->offset
= copy
->offset
;
7164 head_copy
->size
= head_size
;
7166 copy
->offset
+= head_size
;
7167 copy
->size
-= head_size
;
7169 entry
= vm_map_copy_first_entry(copy
);
7170 vm_map_copy_clip_end(copy
, entry
, copy
->offset
);
7171 vm_map_copy_entry_unlink(copy
, entry
);
7172 vm_map_copy_entry_link(head_copy
,
7173 vm_map_copy_to_entry(head_copy
),
7177 * Do the unaligned copy.
7179 kr
= vm_map_copy_overwrite_nested(dst_map
,
7185 if (kr
!= KERN_SUCCESS
)
7191 * Extract "tail_copy" out of "copy".
7193 tail_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
7194 vm_map_copy_first_entry(tail_copy
) =
7195 vm_map_copy_to_entry(tail_copy
);
7196 vm_map_copy_last_entry(tail_copy
) =
7197 vm_map_copy_to_entry(tail_copy
);
7198 tail_copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
7199 tail_copy
->cpy_hdr
.nentries
= 0;
7200 tail_copy
->cpy_hdr
.entries_pageable
=
7201 copy
->cpy_hdr
.entries_pageable
;
7202 vm_map_store_init(&tail_copy
->cpy_hdr
);
7204 tail_copy
->offset
= copy
->offset
+ copy
->size
- tail_size
;
7205 tail_copy
->size
= tail_size
;
7207 copy
->size
-= tail_size
;
7209 entry
= vm_map_copy_last_entry(copy
);
7210 vm_map_copy_clip_start(copy
, entry
, tail_copy
->offset
);
7211 entry
= vm_map_copy_last_entry(copy
);
7212 vm_map_copy_entry_unlink(copy
, entry
);
7213 vm_map_copy_entry_link(tail_copy
,
7214 vm_map_copy_last_entry(tail_copy
),
7219 * Copy most (or possibly all) of the data.
7221 kr
= vm_map_copy_overwrite_nested(dst_map
,
7222 dst_addr
+ head_size
,
7227 if (kr
!= KERN_SUCCESS
) {
7232 kr
= vm_map_copy_overwrite_nested(dst_map
,
7241 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
7242 if (kr
== KERN_SUCCESS
) {
7244 * Discard all the copy maps.
7247 vm_map_copy_discard(head_copy
);
7250 vm_map_copy_discard(copy
);
7252 vm_map_copy_discard(tail_copy
);
7257 * Re-assemble the original copy map.
7260 entry
= vm_map_copy_first_entry(head_copy
);
7261 vm_map_copy_entry_unlink(head_copy
, entry
);
7262 vm_map_copy_entry_link(copy
,
7263 vm_map_copy_to_entry(copy
),
7265 copy
->offset
-= head_size
;
7266 copy
->size
+= head_size
;
7267 vm_map_copy_discard(head_copy
);
7271 entry
= vm_map_copy_last_entry(tail_copy
);
7272 vm_map_copy_entry_unlink(tail_copy
, entry
);
7273 vm_map_copy_entry_link(copy
,
7274 vm_map_copy_last_entry(copy
),
7276 copy
->size
+= tail_size
;
7277 vm_map_copy_discard(tail_copy
);
7286 * Routine: vm_map_copy_overwrite_unaligned [internal use only]
7289 * Physically copy unaligned data
7292 * Unaligned parts of pages have to be physically copied. We use
7293 * a modified form of vm_fault_copy (which understands none-aligned
7294 * page offsets and sizes) to do the copy. We attempt to copy as
7295 * much memory in one go as possibly, however vm_fault_copy copies
7296 * within 1 memory object so we have to find the smaller of "amount left"
7297 * "source object data size" and "target object data size". With
7298 * unaligned data we don't need to split regions, therefore the source
7299 * (copy) object should be one map entry, the target range may be split
7300 * over multiple map entries however. In any event we are pessimistic
7301 * about these assumptions.
7304 * dst_map is locked on entry and is return locked on success,
7305 * unlocked on error.
7308 static kern_return_t
7309 vm_map_copy_overwrite_unaligned(
7311 vm_map_entry_t entry
,
7313 vm_map_offset_t start
,
7314 boolean_t discard_on_success
)
7316 vm_map_entry_t copy_entry
;
7317 vm_map_entry_t copy_entry_next
;
7318 vm_map_version_t version
;
7319 vm_object_t dst_object
;
7320 vm_object_offset_t dst_offset
;
7321 vm_object_offset_t src_offset
;
7322 vm_object_offset_t entry_offset
;
7323 vm_map_offset_t entry_end
;
7324 vm_map_size_t src_size
,
7328 kern_return_t kr
= KERN_SUCCESS
;
7331 copy_entry
= vm_map_copy_first_entry(copy
);
7333 vm_map_lock_write_to_read(dst_map
);
7335 src_offset
= copy
->offset
- vm_object_trunc_page(copy
->offset
);
7336 amount_left
= copy
->size
;
7338 * unaligned so we never clipped this entry, we need the offset into
7339 * the vm_object not just the data.
7341 while (amount_left
> 0) {
7343 if (entry
== vm_map_to_entry(dst_map
)) {
7344 vm_map_unlock_read(dst_map
);
7345 return KERN_INVALID_ADDRESS
;
7348 /* "start" must be within the current map entry */
7349 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
7351 dst_offset
= start
- entry
->vme_start
;
7353 dst_size
= entry
->vme_end
- start
;
7355 src_size
= copy_entry
->vme_end
-
7356 (copy_entry
->vme_start
+ src_offset
);
7358 if (dst_size
< src_size
) {
7360 * we can only copy dst_size bytes before
7361 * we have to get the next destination entry
7363 copy_size
= dst_size
;
7366 * we can only copy src_size bytes before
7367 * we have to get the next source copy entry
7369 copy_size
= src_size
;
7372 if (copy_size
> amount_left
) {
7373 copy_size
= amount_left
;
7376 * Entry needs copy, create a shadow shadow object for
7377 * Copy on write region.
7379 if (entry
->needs_copy
&&
7380 ((entry
->protection
& VM_PROT_WRITE
) != 0))
7382 if (vm_map_lock_read_to_write(dst_map
)) {
7383 vm_map_lock_read(dst_map
);
7386 vm_object_shadow(&entry
->object
.vm_object
,
7388 (vm_map_size_t
)(entry
->vme_end
7389 - entry
->vme_start
));
7390 entry
->needs_copy
= FALSE
;
7391 vm_map_lock_write_to_read(dst_map
);
7393 dst_object
= entry
->object
.vm_object
;
7395 * unlike with the virtual (aligned) copy we're going
7396 * to fault on it therefore we need a target object.
7398 if (dst_object
== VM_OBJECT_NULL
) {
7399 if (vm_map_lock_read_to_write(dst_map
)) {
7400 vm_map_lock_read(dst_map
);
7403 dst_object
= vm_object_allocate((vm_map_size_t
)
7404 entry
->vme_end
- entry
->vme_start
);
7405 entry
->object
.vm_object
= dst_object
;
7407 assert(entry
->use_pmap
);
7408 vm_map_lock_write_to_read(dst_map
);
7411 * Take an object reference and unlock map. The "entry" may
7412 * disappear or change when the map is unlocked.
7414 vm_object_reference(dst_object
);
7415 version
.main_timestamp
= dst_map
->timestamp
;
7416 entry_offset
= entry
->offset
;
7417 entry_end
= entry
->vme_end
;
7418 vm_map_unlock_read(dst_map
);
7420 * Copy as much as possible in one pass
7423 copy_entry
->object
.vm_object
,
7424 copy_entry
->offset
+ src_offset
,
7427 entry_offset
+ dst_offset
,
7433 src_offset
+= copy_size
;
7434 amount_left
-= copy_size
;
7436 * Release the object reference
7438 vm_object_deallocate(dst_object
);
7440 * If a hard error occurred, return it now
7442 if (kr
!= KERN_SUCCESS
)
7445 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
7446 || amount_left
== 0)
7449 * all done with this copy entry, dispose.
7451 copy_entry_next
= copy_entry
->vme_next
;
7453 if (discard_on_success
) {
7454 vm_map_copy_entry_unlink(copy
, copy_entry
);
7455 assert(!copy_entry
->is_sub_map
);
7456 vm_object_deallocate(
7457 copy_entry
->object
.vm_object
);
7458 vm_map_copy_entry_dispose(copy
, copy_entry
);
7461 if (copy_entry_next
== vm_map_copy_to_entry(copy
) &&
7464 * not finished copying but run out of source
7466 return KERN_INVALID_ADDRESS
;
7469 copy_entry
= copy_entry_next
;
7474 if (amount_left
== 0)
7475 return KERN_SUCCESS
;
7477 vm_map_lock_read(dst_map
);
7478 if (version
.main_timestamp
== dst_map
->timestamp
) {
7479 if (start
== entry_end
) {
7481 * destination region is split. Use the version
7482 * information to avoid a lookup in the normal
7485 entry
= entry
->vme_next
;
7487 * should be contiguous. Fail if we encounter
7488 * a hole in the destination.
7490 if (start
!= entry
->vme_start
) {
7491 vm_map_unlock_read(dst_map
);
7492 return KERN_INVALID_ADDRESS
;
7497 * Map version check failed.
7498 * we must lookup the entry because somebody
7499 * might have changed the map behind our backs.
7502 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
7504 vm_map_unlock_read(dst_map
);
7505 return KERN_INVALID_ADDRESS
;
7510 return KERN_SUCCESS
;
7511 }/* vm_map_copy_overwrite_unaligned */
7514 * Routine: vm_map_copy_overwrite_aligned [internal use only]
7517 * Does all the vm_trickery possible for whole pages.
7521 * If there are no permanent objects in the destination,
7522 * and the source and destination map entry zones match,
7523 * and the destination map entry is not shared,
7524 * then the map entries can be deleted and replaced
7525 * with those from the copy. The following code is the
7526 * basic idea of what to do, but there are lots of annoying
7527 * little details about getting protection and inheritance
7528 * right. Should add protection, inheritance, and sharing checks
7529 * to the above pass and make sure that no wiring is involved.
7532 int vm_map_copy_overwrite_aligned_src_not_internal
= 0;
7533 int vm_map_copy_overwrite_aligned_src_not_symmetric
= 0;
7534 int vm_map_copy_overwrite_aligned_src_large
= 0;
7536 static kern_return_t
7537 vm_map_copy_overwrite_aligned(
7539 vm_map_entry_t tmp_entry
,
7541 vm_map_offset_t start
,
7542 __unused pmap_t pmap
)
7545 vm_map_entry_t copy_entry
;
7546 vm_map_size_t copy_size
;
7548 vm_map_entry_t entry
;
7550 while ((copy_entry
= vm_map_copy_first_entry(copy
))
7551 != vm_map_copy_to_entry(copy
))
7553 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
7556 if (entry
->is_sub_map
) {
7557 /* unnested when clipped earlier */
7558 assert(!entry
->use_pmap
);
7560 if (entry
== vm_map_to_entry(dst_map
)) {
7561 vm_map_unlock(dst_map
);
7562 return KERN_INVALID_ADDRESS
;
7564 size
= (entry
->vme_end
- entry
->vme_start
);
7566 * Make sure that no holes popped up in the
7567 * address map, and that the protection is
7568 * still valid, in case the map was unlocked
7572 if ((entry
->vme_start
!= start
) || ((entry
->is_sub_map
)
7573 && !entry
->needs_copy
)) {
7574 vm_map_unlock(dst_map
);
7575 return(KERN_INVALID_ADDRESS
);
7577 assert(entry
!= vm_map_to_entry(dst_map
));
7580 * Check protection again
7583 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
7584 vm_map_unlock(dst_map
);
7585 return(KERN_PROTECTION_FAILURE
);
7589 * Adjust to source size first
7592 if (copy_size
< size
) {
7593 if (entry
->map_aligned
&&
7594 !VM_MAP_PAGE_ALIGNED(entry
->vme_start
+ copy_size
,
7595 VM_MAP_PAGE_MASK(dst_map
))) {
7596 /* no longer map-aligned */
7597 entry
->map_aligned
= FALSE
;
7599 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
7604 * Adjust to destination size
7607 if (size
< copy_size
) {
7608 vm_map_copy_clip_end(copy
, copy_entry
,
7609 copy_entry
->vme_start
+ size
);
7613 assert((entry
->vme_end
- entry
->vme_start
) == size
);
7614 assert((tmp_entry
->vme_end
- tmp_entry
->vme_start
) == size
);
7615 assert((copy_entry
->vme_end
- copy_entry
->vme_start
) == size
);
7618 * If the destination contains temporary unshared memory,
7619 * we can perform the copy by throwing it away and
7620 * installing the source data.
7623 object
= entry
->object
.vm_object
;
7624 if ((!entry
->is_shared
&&
7625 ((object
== VM_OBJECT_NULL
) ||
7626 (object
->internal
&& !object
->true_share
))) ||
7627 entry
->needs_copy
) {
7628 vm_object_t old_object
= entry
->object
.vm_object
;
7629 vm_object_offset_t old_offset
= entry
->offset
;
7630 vm_object_offset_t offset
;
7633 * Ensure that the source and destination aren't
7636 if (old_object
== copy_entry
->object
.vm_object
&&
7637 old_offset
== copy_entry
->offset
) {
7638 vm_map_copy_entry_unlink(copy
, copy_entry
);
7639 vm_map_copy_entry_dispose(copy
, copy_entry
);
7641 if (old_object
!= VM_OBJECT_NULL
)
7642 vm_object_deallocate(old_object
);
7644 start
= tmp_entry
->vme_end
;
7645 tmp_entry
= tmp_entry
->vme_next
;
7649 #define __TRADEOFF1_OBJ_SIZE (64 * 1024 * 1024) /* 64 MB */
7650 #define __TRADEOFF1_COPY_SIZE (128 * 1024) /* 128 KB */
7651 if (copy_entry
->object
.vm_object
!= VM_OBJECT_NULL
&&
7652 copy_entry
->object
.vm_object
->vo_size
>= __TRADEOFF1_OBJ_SIZE
&&
7653 copy_size
<= __TRADEOFF1_COPY_SIZE
) {
7655 * Virtual vs. Physical copy tradeoff #1.
7657 * Copying only a few pages out of a large
7658 * object: do a physical copy instead of
7659 * a virtual copy, to avoid possibly keeping
7660 * the entire large object alive because of
7661 * those few copy-on-write pages.
7663 vm_map_copy_overwrite_aligned_src_large
++;
7667 if (entry
->alias
>= VM_MEMORY_MALLOC
&&
7668 entry
->alias
<= VM_MEMORY_MALLOC_LARGE_REUSED
) {
7669 vm_object_t new_object
, new_shadow
;
7672 * We're about to map something over a mapping
7673 * established by malloc()...
7675 new_object
= copy_entry
->object
.vm_object
;
7676 if (new_object
!= VM_OBJECT_NULL
) {
7677 vm_object_lock_shared(new_object
);
7679 while (new_object
!= VM_OBJECT_NULL
&&
7680 !new_object
->true_share
&&
7681 new_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
7682 new_object
->internal
) {
7683 new_shadow
= new_object
->shadow
;
7684 if (new_shadow
== VM_OBJECT_NULL
) {
7687 vm_object_lock_shared(new_shadow
);
7688 vm_object_unlock(new_object
);
7689 new_object
= new_shadow
;
7691 if (new_object
!= VM_OBJECT_NULL
) {
7692 if (!new_object
->internal
) {
7694 * The new mapping is backed
7695 * by an external object. We
7696 * don't want malloc'ed memory
7697 * to be replaced with such a
7698 * non-anonymous mapping, so
7699 * let's go off the optimized
7702 vm_map_copy_overwrite_aligned_src_not_internal
++;
7703 vm_object_unlock(new_object
);
7706 if (new_object
->true_share
||
7707 new_object
->copy_strategy
!= MEMORY_OBJECT_COPY_SYMMETRIC
) {
7709 * Same if there's a "true_share"
7710 * object in the shadow chain, or
7711 * an object with a non-default
7712 * (SYMMETRIC) copy strategy.
7714 vm_map_copy_overwrite_aligned_src_not_symmetric
++;
7715 vm_object_unlock(new_object
);
7718 vm_object_unlock(new_object
);
7721 * The new mapping is still backed by
7722 * anonymous (internal) memory, so it's
7723 * OK to substitute it for the original
7728 if (old_object
!= VM_OBJECT_NULL
) {
7729 if(entry
->is_sub_map
) {
7730 if(entry
->use_pmap
) {
7731 #ifndef NO_NESTED_PMAP
7732 pmap_unnest(dst_map
->pmap
,
7733 (addr64_t
)entry
->vme_start
,
7734 entry
->vme_end
- entry
->vme_start
);
7735 #endif /* NO_NESTED_PMAP */
7736 if(dst_map
->mapped_in_other_pmaps
) {
7737 /* clean up parent */
7739 vm_map_submap_pmap_clean(
7740 dst_map
, entry
->vme_start
,
7742 entry
->object
.sub_map
,
7746 vm_map_submap_pmap_clean(
7747 dst_map
, entry
->vme_start
,
7749 entry
->object
.sub_map
,
7753 entry
->object
.sub_map
);
7755 if(dst_map
->mapped_in_other_pmaps
) {
7756 vm_object_pmap_protect_options(
7757 entry
->object
.vm_object
,
7764 PMAP_OPTIONS_REMOVE
);
7766 pmap_remove_options(
7768 (addr64_t
)(entry
->vme_start
),
7769 (addr64_t
)(entry
->vme_end
),
7770 PMAP_OPTIONS_REMOVE
);
7772 vm_object_deallocate(old_object
);
7776 entry
->is_sub_map
= FALSE
;
7777 entry
->object
= copy_entry
->object
;
7778 object
= entry
->object
.vm_object
;
7779 entry
->needs_copy
= copy_entry
->needs_copy
;
7780 entry
->wired_count
= 0;
7781 entry
->user_wired_count
= 0;
7782 offset
= entry
->offset
= copy_entry
->offset
;
7784 vm_map_copy_entry_unlink(copy
, copy_entry
);
7785 vm_map_copy_entry_dispose(copy
, copy_entry
);
7788 * we could try to push pages into the pmap at this point, BUT
7789 * this optimization only saved on average 2 us per page if ALL
7790 * the pages in the source were currently mapped
7791 * and ALL the pages in the dest were touched, if there were fewer
7792 * than 2/3 of the pages touched, this optimization actually cost more cycles
7793 * it also puts a lot of pressure on the pmap layer w/r to mapping structures
7797 * Set up for the next iteration. The map
7798 * has not been unlocked, so the next
7799 * address should be at the end of this
7800 * entry, and the next map entry should be
7801 * the one following it.
7804 start
= tmp_entry
->vme_end
;
7805 tmp_entry
= tmp_entry
->vme_next
;
7807 vm_map_version_t version
;
7808 vm_object_t dst_object
;
7809 vm_object_offset_t dst_offset
;
7813 if (entry
->needs_copy
) {
7814 vm_object_shadow(&entry
->object
.vm_object
,
7818 entry
->needs_copy
= FALSE
;
7821 dst_object
= entry
->object
.vm_object
;
7822 dst_offset
= entry
->offset
;
7825 * Take an object reference, and record
7826 * the map version information so that the
7827 * map can be safely unlocked.
7830 if (dst_object
== VM_OBJECT_NULL
) {
7832 * We would usually have just taken the
7833 * optimized path above if the destination
7834 * object has not been allocated yet. But we
7835 * now disable that optimization if the copy
7836 * entry's object is not backed by anonymous
7837 * memory to avoid replacing malloc'ed
7838 * (i.e. re-usable) anonymous memory with a
7839 * not-so-anonymous mapping.
7840 * So we have to handle this case here and
7841 * allocate a new VM object for this map entry.
7843 dst_object
= vm_object_allocate(
7844 entry
->vme_end
- entry
->vme_start
);
7846 entry
->object
.vm_object
= dst_object
;
7847 entry
->offset
= dst_offset
;
7848 assert(entry
->use_pmap
);
7852 vm_object_reference(dst_object
);
7854 /* account for unlock bumping up timestamp */
7855 version
.main_timestamp
= dst_map
->timestamp
+ 1;
7857 vm_map_unlock(dst_map
);
7860 * Copy as much as possible in one pass
7865 copy_entry
->object
.vm_object
,
7875 * Release the object reference
7878 vm_object_deallocate(dst_object
);
7881 * If a hard error occurred, return it now
7884 if (r
!= KERN_SUCCESS
)
7887 if (copy_size
!= 0) {
7889 * Dispose of the copied region
7892 vm_map_copy_clip_end(copy
, copy_entry
,
7893 copy_entry
->vme_start
+ copy_size
);
7894 vm_map_copy_entry_unlink(copy
, copy_entry
);
7895 vm_object_deallocate(copy_entry
->object
.vm_object
);
7896 vm_map_copy_entry_dispose(copy
, copy_entry
);
7900 * Pick up in the destination map where we left off.
7902 * Use the version information to avoid a lookup
7903 * in the normal case.
7907 vm_map_lock(dst_map
);
7908 if (version
.main_timestamp
== dst_map
->timestamp
&&
7910 /* We can safely use saved tmp_entry value */
7912 if (tmp_entry
->map_aligned
&&
7913 !VM_MAP_PAGE_ALIGNED(
7915 VM_MAP_PAGE_MASK(dst_map
))) {
7916 /* no longer map-aligned */
7917 tmp_entry
->map_aligned
= FALSE
;
7919 vm_map_clip_end(dst_map
, tmp_entry
, start
);
7920 tmp_entry
= tmp_entry
->vme_next
;
7922 /* Must do lookup of tmp_entry */
7924 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
7925 vm_map_unlock(dst_map
);
7926 return(KERN_INVALID_ADDRESS
);
7928 if (tmp_entry
->map_aligned
&&
7929 !VM_MAP_PAGE_ALIGNED(
7931 VM_MAP_PAGE_MASK(dst_map
))) {
7932 /* no longer map-aligned */
7933 tmp_entry
->map_aligned
= FALSE
;
7935 vm_map_clip_start(dst_map
, tmp_entry
, start
);
7940 return(KERN_SUCCESS
);
7941 }/* vm_map_copy_overwrite_aligned */
7944 * Routine: vm_map_copyin_kernel_buffer [internal use only]
7947 * Copy in data to a kernel buffer from space in the
7948 * source map. The original space may be optionally
7951 * If successful, returns a new copy object.
7953 static kern_return_t
7954 vm_map_copyin_kernel_buffer(
7956 vm_map_offset_t src_addr
,
7958 boolean_t src_destroy
,
7959 vm_map_copy_t
*copy_result
)
7963 vm_size_t kalloc_size
;
7965 if ((vm_size_t
) len
!= len
) {
7966 /* "len" is too big and doesn't fit in a "vm_size_t" */
7967 return KERN_RESOURCE_SHORTAGE
;
7969 kalloc_size
= (vm_size_t
) (sizeof(struct vm_map_copy
) + len
);
7970 assert((vm_map_size_t
) kalloc_size
== sizeof (struct vm_map_copy
) + len
);
7972 copy
= (vm_map_copy_t
) kalloc(kalloc_size
);
7973 if (copy
== VM_MAP_COPY_NULL
) {
7974 return KERN_RESOURCE_SHORTAGE
;
7976 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
7979 copy
->cpy_kdata
= (void *) (copy
+ 1);
7980 copy
->cpy_kalloc_size
= kalloc_size
;
7982 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, (vm_size_t
) len
);
7983 if (kr
!= KERN_SUCCESS
) {
7984 kfree(copy
, kalloc_size
);
7988 (void) vm_map_remove(
7990 vm_map_trunc_page(src_addr
,
7991 VM_MAP_PAGE_MASK(src_map
)),
7992 vm_map_round_page(src_addr
+ len
,
7993 VM_MAP_PAGE_MASK(src_map
)),
7994 (VM_MAP_REMOVE_INTERRUPTIBLE
|
7995 VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
7996 (src_map
== kernel_map
) ? VM_MAP_REMOVE_KUNWIRE
: 0));
7998 *copy_result
= copy
;
7999 return KERN_SUCCESS
;
8003 * Routine: vm_map_copyout_kernel_buffer [internal use only]
8006 * Copy out data from a kernel buffer into space in the
8007 * destination map. The space may be otpionally dynamically
8010 * If successful, consumes the copy object.
8011 * Otherwise, the caller is responsible for it.
8013 static int vm_map_copyout_kernel_buffer_failures
= 0;
8014 static kern_return_t
8015 vm_map_copyout_kernel_buffer(
8017 vm_map_address_t
*addr
, /* IN/OUT */
8019 boolean_t overwrite
,
8020 boolean_t consume_on_success
)
8022 kern_return_t kr
= KERN_SUCCESS
;
8023 thread_t thread
= current_thread();
8028 * Allocate space in the target map for the data
8031 kr
= vm_map_enter(map
,
8033 vm_map_round_page(copy
->size
,
8034 VM_MAP_PAGE_MASK(map
)),
8035 (vm_map_offset_t
) 0,
8038 (vm_object_offset_t
) 0,
8042 VM_INHERIT_DEFAULT
);
8043 if (kr
!= KERN_SUCCESS
)
8048 * Copyout the data from the kernel buffer to the target map.
8050 if (thread
->map
== map
) {
8053 * If the target map is the current map, just do
8056 assert((vm_size_t
) copy
->size
== copy
->size
);
8057 if (copyout(copy
->cpy_kdata
, *addr
, (vm_size_t
) copy
->size
)) {
8058 kr
= KERN_INVALID_ADDRESS
;
8065 * If the target map is another map, assume the
8066 * target's address space identity for the duration
8069 vm_map_reference(map
);
8070 oldmap
= vm_map_switch(map
);
8072 assert((vm_size_t
) copy
->size
== copy
->size
);
8073 if (copyout(copy
->cpy_kdata
, *addr
, (vm_size_t
) copy
->size
)) {
8074 vm_map_copyout_kernel_buffer_failures
++;
8075 kr
= KERN_INVALID_ADDRESS
;
8078 (void) vm_map_switch(oldmap
);
8079 vm_map_deallocate(map
);
8082 if (kr
!= KERN_SUCCESS
) {
8083 /* the copy failed, clean up */
8086 * Deallocate the space we allocated in the target map.
8088 (void) vm_map_remove(
8090 vm_map_trunc_page(*addr
,
8091 VM_MAP_PAGE_MASK(map
)),
8092 vm_map_round_page((*addr
+
8093 vm_map_round_page(copy
->size
,
8094 VM_MAP_PAGE_MASK(map
))),
8095 VM_MAP_PAGE_MASK(map
)),
8100 /* copy was successful, dicard the copy structure */
8101 if (consume_on_success
) {
8102 kfree(copy
, copy
->cpy_kalloc_size
);
8110 * Macro: vm_map_copy_insert
8113 * Link a copy chain ("copy") into a map at the
8114 * specified location (after "where").
8116 * The copy chain is destroyed.
8118 * The arguments are evaluated multiple times.
8120 #define vm_map_copy_insert(map, where, copy) \
8122 vm_map_store_copy_insert(map, where, copy); \
8123 zfree(vm_map_copy_zone, copy); \
8129 vm_map_entry_t where
,
8131 vm_map_offset_t adjustment
,
8134 vm_inherit_t inheritance
)
8136 vm_map_entry_t copy_entry
, new_entry
;
8138 for (copy_entry
= vm_map_copy_first_entry(copy
);
8139 copy_entry
!= vm_map_copy_to_entry(copy
);
8140 copy_entry
= copy_entry
->vme_next
) {
8141 /* get a new VM map entry for the map */
8142 new_entry
= vm_map_entry_create(map
,
8143 !map
->hdr
.entries_pageable
);
8144 /* copy the "copy entry" to the new entry */
8145 vm_map_entry_copy(new_entry
, copy_entry
);
8146 /* adjust "start" and "end" */
8147 new_entry
->vme_start
+= adjustment
;
8148 new_entry
->vme_end
+= adjustment
;
8149 /* clear some attributes */
8150 new_entry
->inheritance
= inheritance
;
8151 new_entry
->protection
= cur_prot
;
8152 new_entry
->max_protection
= max_prot
;
8153 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
8154 /* take an extra reference on the entry's "object" */
8155 if (new_entry
->is_sub_map
) {
8156 assert(!new_entry
->use_pmap
); /* not nested */
8157 vm_map_lock(new_entry
->object
.sub_map
);
8158 vm_map_reference(new_entry
->object
.sub_map
);
8159 vm_map_unlock(new_entry
->object
.sub_map
);
8161 vm_object_reference(new_entry
->object
.vm_object
);
8163 /* insert the new entry in the map */
8164 vm_map_store_entry_link(map
, where
, new_entry
);
8165 /* continue inserting the "copy entries" after the new entry */
8171 * Routine: vm_map_copyout
8174 * Copy out a copy chain ("copy") into newly-allocated
8175 * space in the destination map.
8177 * If successful, consumes the copy object.
8178 * Otherwise, the caller is responsible for it.
8184 vm_map_address_t
*dst_addr
, /* OUT */
8187 return vm_map_copyout_internal(dst_map
, dst_addr
, copy
,
8188 TRUE
, /* consume_on_success */
8191 VM_INHERIT_DEFAULT
);
8195 vm_map_copyout_internal(
8197 vm_map_address_t
*dst_addr
, /* OUT */
8199 boolean_t consume_on_success
,
8200 vm_prot_t cur_protection
,
8201 vm_prot_t max_protection
,
8202 vm_inherit_t inheritance
)
8205 vm_map_size_t adjustment
;
8206 vm_map_offset_t start
;
8207 vm_object_offset_t vm_copy_start
;
8208 vm_map_entry_t last
;
8209 vm_map_entry_t entry
;
8212 * Check for null copy object.
8215 if (copy
== VM_MAP_COPY_NULL
) {
8217 return(KERN_SUCCESS
);
8221 * Check for special copy object, created
8222 * by vm_map_copyin_object.
8225 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
8226 vm_object_t object
= copy
->cpy_object
;
8228 vm_object_offset_t offset
;
8230 offset
= vm_object_trunc_page(copy
->offset
);
8231 size
= vm_map_round_page((copy
->size
+
8232 (vm_map_size_t
)(copy
->offset
-
8234 VM_MAP_PAGE_MASK(dst_map
));
8236 kr
= vm_map_enter(dst_map
, dst_addr
, size
,
8237 (vm_map_offset_t
) 0, VM_FLAGS_ANYWHERE
,
8238 object
, offset
, FALSE
,
8239 VM_PROT_DEFAULT
, VM_PROT_ALL
,
8240 VM_INHERIT_DEFAULT
);
8241 if (kr
!= KERN_SUCCESS
)
8243 /* Account for non-pagealigned copy object */
8244 *dst_addr
+= (vm_map_offset_t
)(copy
->offset
- offset
);
8245 if (consume_on_success
)
8246 zfree(vm_map_copy_zone
, copy
);
8247 return(KERN_SUCCESS
);
8251 * Check for special kernel buffer allocated
8252 * by new_ipc_kmsg_copyin.
8255 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
8256 return vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
8258 consume_on_success
);
8263 * Find space for the data
8266 vm_copy_start
= vm_map_trunc_page((vm_map_size_t
)copy
->offset
,
8267 VM_MAP_COPY_PAGE_MASK(copy
));
8268 size
= vm_map_round_page((vm_map_size_t
)copy
->offset
+ copy
->size
,
8269 VM_MAP_COPY_PAGE_MASK(copy
))
8275 vm_map_lock(dst_map
);
8276 if( dst_map
->disable_vmentry_reuse
== TRUE
) {
8277 VM_MAP_HIGHEST_ENTRY(dst_map
, entry
, start
);
8280 assert(first_free_is_valid(dst_map
));
8281 start
= ((last
= dst_map
->first_free
) == vm_map_to_entry(dst_map
)) ?
8282 vm_map_min(dst_map
) : last
->vme_end
;
8283 start
= vm_map_round_page(start
,
8284 VM_MAP_PAGE_MASK(dst_map
));
8288 vm_map_entry_t next
= last
->vme_next
;
8289 vm_map_offset_t end
= start
+ size
;
8291 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
8292 if (dst_map
->wait_for_space
) {
8293 if (size
<= (dst_map
->max_offset
- dst_map
->min_offset
)) {
8294 assert_wait((event_t
) dst_map
,
8295 THREAD_INTERRUPTIBLE
);
8296 vm_map_unlock(dst_map
);
8297 thread_block(THREAD_CONTINUE_NULL
);
8301 vm_map_unlock(dst_map
);
8302 return(KERN_NO_SPACE
);
8305 if ((next
== vm_map_to_entry(dst_map
)) ||
8306 (next
->vme_start
>= end
))
8310 start
= last
->vme_end
;
8311 start
= vm_map_round_page(start
,
8312 VM_MAP_PAGE_MASK(dst_map
));
8315 adjustment
= start
- vm_copy_start
;
8316 if (! consume_on_success
) {
8318 * We're not allowed to consume "copy", so we'll have to
8319 * copy its map entries into the destination map below.
8320 * No need to re-allocate map entries from the correct
8321 * (pageable or not) zone, since we'll get new map entries
8322 * during the transfer.
8323 * We'll also adjust the map entries's "start" and "end"
8324 * during the transfer, to keep "copy"'s entries consistent
8325 * with its "offset".
8327 goto after_adjustments
;
8331 * Since we're going to just drop the map
8332 * entries from the copy into the destination
8333 * map, they must come from the same pool.
8336 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
8338 * Mismatches occur when dealing with the default
8342 vm_map_entry_t next
, new;
8345 * Find the zone that the copies were allocated from
8348 entry
= vm_map_copy_first_entry(copy
);
8351 * Reinitialize the copy so that vm_map_copy_entry_link
8354 vm_map_store_copy_reset(copy
, entry
);
8355 copy
->cpy_hdr
.entries_pageable
= dst_map
->hdr
.entries_pageable
;
8360 while (entry
!= vm_map_copy_to_entry(copy
)) {
8361 new = vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
8362 vm_map_entry_copy_full(new, entry
);
8363 assert(!new->iokit_acct
);
8364 if (new->is_sub_map
) {
8365 /* clr address space specifics */
8366 new->use_pmap
= FALSE
;
8368 vm_map_copy_entry_link(copy
,
8369 vm_map_copy_last_entry(copy
),
8371 next
= entry
->vme_next
;
8372 old_zone
= entry
->from_reserved_zone
? vm_map_entry_reserved_zone
: vm_map_entry_zone
;
8373 zfree(old_zone
, entry
);
8379 * Adjust the addresses in the copy chain, and
8380 * reset the region attributes.
8383 for (entry
= vm_map_copy_first_entry(copy
);
8384 entry
!= vm_map_copy_to_entry(copy
);
8385 entry
= entry
->vme_next
) {
8386 if (VM_MAP_PAGE_SHIFT(dst_map
) == PAGE_SHIFT
) {
8388 * We're injecting this copy entry into a map that
8389 * has the standard page alignment, so clear
8390 * "map_aligned" (which might have been inherited
8391 * from the original map entry).
8393 entry
->map_aligned
= FALSE
;
8396 entry
->vme_start
+= adjustment
;
8397 entry
->vme_end
+= adjustment
;
8399 if (entry
->map_aligned
) {
8400 assert(VM_MAP_PAGE_ALIGNED(entry
->vme_start
,
8401 VM_MAP_PAGE_MASK(dst_map
)));
8402 assert(VM_MAP_PAGE_ALIGNED(entry
->vme_end
,
8403 VM_MAP_PAGE_MASK(dst_map
)));
8406 entry
->inheritance
= VM_INHERIT_DEFAULT
;
8407 entry
->protection
= VM_PROT_DEFAULT
;
8408 entry
->max_protection
= VM_PROT_ALL
;
8409 entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
8412 * If the entry is now wired,
8413 * map the pages into the destination map.
8415 if (entry
->wired_count
!= 0) {
8416 register vm_map_offset_t va
;
8417 vm_object_offset_t offset
;
8418 register vm_object_t object
;
8422 object
= entry
->object
.vm_object
;
8423 offset
= entry
->offset
;
8424 va
= entry
->vme_start
;
8426 pmap_pageable(dst_map
->pmap
,
8431 while (va
< entry
->vme_end
) {
8432 register vm_page_t m
;
8435 * Look up the page in the object.
8436 * Assert that the page will be found in the
8439 * the object was newly created by
8440 * vm_object_copy_slowly, and has
8441 * copies of all of the pages from
8444 * the object was moved from the old
8445 * map entry; because the old map
8446 * entry was wired, all of the pages
8447 * were in the top-level object.
8448 * (XXX not true if we wire pages for
8451 vm_object_lock(object
);
8453 m
= vm_page_lookup(object
, offset
);
8454 if (m
== VM_PAGE_NULL
|| !VM_PAGE_WIRED(m
) ||
8456 panic("vm_map_copyout: wiring %p", m
);
8460 * The page is assumed to be wired here, so it
8461 * shouldn't be encrypted. Otherwise, we
8462 * couldn't enter it in the page table, since
8463 * we don't want the user to see the encrypted
8466 ASSERT_PAGE_DECRYPTED(m
);
8468 prot
= entry
->protection
;
8470 if (override_nx(dst_map
, entry
->alias
) && prot
)
8471 prot
|= VM_PROT_EXECUTE
;
8473 type_of_fault
= DBG_CACHE_HIT_FAULT
;
8475 vm_fault_enter(m
, dst_map
->pmap
, va
, prot
, prot
,
8476 VM_PAGE_WIRED(m
), FALSE
, FALSE
,
8477 FALSE
, entry
->alias
,
8478 ((entry
->iokit_acct
||
8479 (!entry
->is_sub_map
&&
8481 ? PMAP_OPTIONS_ALT_ACCT
8483 NULL
, &type_of_fault
);
8485 vm_object_unlock(object
);
8487 offset
+= PAGE_SIZE_64
;
8496 * Correct the page alignment for the result
8499 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
8502 * Update the hints and the map size
8505 if (consume_on_success
) {
8506 SAVE_HINT_MAP_WRITE(dst_map
, vm_map_copy_last_entry(copy
));
8508 SAVE_HINT_MAP_WRITE(dst_map
, last
);
8511 dst_map
->size
+= size
;
8517 if (consume_on_success
) {
8518 vm_map_copy_insert(dst_map
, last
, copy
);
8520 vm_map_copy_remap(dst_map
, last
, copy
, adjustment
,
8521 cur_protection
, max_protection
,
8525 vm_map_unlock(dst_map
);
8528 * XXX If wiring_required, call vm_map_pageable
8531 return(KERN_SUCCESS
);
8535 * Routine: vm_map_copyin
8538 * see vm_map_copyin_common. Exported via Unsupported.exports.
8542 #undef vm_map_copyin
8547 vm_map_address_t src_addr
,
8549 boolean_t src_destroy
,
8550 vm_map_copy_t
*copy_result
) /* OUT */
8552 return(vm_map_copyin_common(src_map
, src_addr
, len
, src_destroy
,
8553 FALSE
, copy_result
, FALSE
));
8557 * Routine: vm_map_copyin_common
8560 * Copy the specified region (src_addr, len) from the
8561 * source address space (src_map), possibly removing
8562 * the region from the source address space (src_destroy).
8565 * A vm_map_copy_t object (copy_result), suitable for
8566 * insertion into another address space (using vm_map_copyout),
8567 * copying over another address space region (using
8568 * vm_map_copy_overwrite). If the copy is unused, it
8569 * should be destroyed (using vm_map_copy_discard).
8571 * In/out conditions:
8572 * The source map should not be locked on entry.
8575 typedef struct submap_map
{
8576 vm_map_t parent_map
;
8577 vm_map_offset_t base_start
;
8578 vm_map_offset_t base_end
;
8579 vm_map_size_t base_len
;
8580 struct submap_map
*next
;
8584 vm_map_copyin_common(
8586 vm_map_address_t src_addr
,
8588 boolean_t src_destroy
,
8589 __unused boolean_t src_volatile
,
8590 vm_map_copy_t
*copy_result
, /* OUT */
8591 boolean_t use_maxprot
)
8593 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
8594 * in multi-level lookup, this
8595 * entry contains the actual
8599 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
8601 vm_map_offset_t src_start
; /* Start of current entry --
8602 * where copy is taking place now
8604 vm_map_offset_t src_end
; /* End of entire region to be
8606 vm_map_offset_t src_base
;
8607 vm_map_t base_map
= src_map
;
8608 boolean_t map_share
=FALSE
;
8609 submap_map_t
*parent_maps
= NULL
;
8612 vm_map_copy_t copy
; /* Resulting copy */
8613 vm_map_address_t copy_addr
;
8614 vm_map_size_t copy_size
;
8617 * Check for copies of zero bytes.
8621 *copy_result
= VM_MAP_COPY_NULL
;
8622 return(KERN_SUCCESS
);
8626 * Check that the end address doesn't overflow
8628 src_end
= src_addr
+ len
;
8629 if (src_end
< src_addr
)
8630 return KERN_INVALID_ADDRESS
;
8633 * If the copy is sufficiently small, use a kernel buffer instead
8634 * of making a virtual copy. The theory being that the cost of
8635 * setting up VM (and taking C-O-W faults) dominates the copy costs
8636 * for small regions.
8638 if ((len
< msg_ool_size_small
) && !use_maxprot
)
8639 return vm_map_copyin_kernel_buffer(src_map
, src_addr
, len
,
8640 src_destroy
, copy_result
);
8643 * Compute (page aligned) start and end of region
8645 src_start
= vm_map_trunc_page(src_addr
,
8646 VM_MAP_PAGE_MASK(src_map
));
8647 src_end
= vm_map_round_page(src_end
,
8648 VM_MAP_PAGE_MASK(src_map
));
8650 XPR(XPR_VM_MAP
, "vm_map_copyin_common map 0x%x addr 0x%x len 0x%x dest %d\n", src_map
, src_addr
, len
, src_destroy
, 0);
8653 * Allocate a header element for the list.
8655 * Use the start and end in the header to
8656 * remember the endpoints prior to rounding.
8659 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
8660 vm_map_copy_first_entry(copy
) =
8661 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
8662 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
8663 copy
->cpy_hdr
.nentries
= 0;
8664 copy
->cpy_hdr
.entries_pageable
= TRUE
;
8666 copy
->cpy_hdr
.page_shift
= src_map
->hdr
.page_shift
;
8669 * The copy entries can be broken down for a variety of reasons,
8670 * so we can't guarantee that they will remain map-aligned...
8671 * Will need to adjust the first copy_entry's "vme_start" and
8672 * the last copy_entry's "vme_end" to be rounded to PAGE_MASK
8673 * rather than the original map's alignment.
8675 copy
->cpy_hdr
.page_shift
= PAGE_SHIFT
;
8678 vm_map_store_init( &(copy
->cpy_hdr
) );
8680 copy
->offset
= src_addr
;
8683 new_entry
= vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
8687 vm_map_unlock(src_map); \
8688 if(src_map != base_map) \
8689 vm_map_deallocate(src_map); \
8690 if (new_entry != VM_MAP_ENTRY_NULL) \
8691 vm_map_copy_entry_dispose(copy,new_entry); \
8692 vm_map_copy_discard(copy); \
8694 submap_map_t *_ptr; \
8696 for(_ptr = parent_maps; _ptr != NULL; _ptr = parent_maps) { \
8697 parent_maps=parent_maps->next; \
8698 if (_ptr->parent_map != base_map) \
8699 vm_map_deallocate(_ptr->parent_map); \
8700 kfree(_ptr, sizeof(submap_map_t)); \
8707 * Find the beginning of the region.
8710 vm_map_lock(src_map
);
8713 * Lookup the original "src_addr" rather than the truncated
8714 * "src_start", in case "src_start" falls in a non-map-aligned
8715 * map entry *before* the map entry that contains "src_addr"...
8717 if (!vm_map_lookup_entry(src_map
, src_addr
, &tmp_entry
))
8718 RETURN(KERN_INVALID_ADDRESS
);
8719 if(!tmp_entry
->is_sub_map
) {
8721 * ... but clip to the map-rounded "src_start" rather than
8722 * "src_addr" to preserve map-alignment. We'll adjust the
8723 * first copy entry at the end, if needed.
8725 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
8727 if (src_start
< tmp_entry
->vme_start
) {
8729 * Move "src_start" up to the start of the
8730 * first map entry to copy.
8732 src_start
= tmp_entry
->vme_start
;
8734 /* set for later submap fix-up */
8735 copy_addr
= src_start
;
8738 * Go through entries until we get to the end.
8743 vm_map_entry_t src_entry
= tmp_entry
; /* Top-level entry */
8744 vm_map_size_t src_size
; /* Size of source
8745 * map entry (in both
8750 vm_object_t src_object
; /* Object to copy */
8751 vm_object_offset_t src_offset
;
8753 boolean_t src_needs_copy
; /* Should source map
8755 * for copy-on-write?
8758 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
8760 boolean_t was_wired
; /* Was source wired? */
8761 vm_map_version_t version
; /* Version before locks
8762 * dropped to make copy
8764 kern_return_t result
; /* Return value from
8765 * copy_strategically.
8767 while(tmp_entry
->is_sub_map
) {
8768 vm_map_size_t submap_len
;
8771 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
8772 ptr
->next
= parent_maps
;
8774 ptr
->parent_map
= src_map
;
8775 ptr
->base_start
= src_start
;
8776 ptr
->base_end
= src_end
;
8777 submap_len
= tmp_entry
->vme_end
- src_start
;
8778 if(submap_len
> (src_end
-src_start
))
8779 submap_len
= src_end
-src_start
;
8780 ptr
->base_len
= submap_len
;
8782 src_start
-= tmp_entry
->vme_start
;
8783 src_start
+= tmp_entry
->offset
;
8784 src_end
= src_start
+ submap_len
;
8785 src_map
= tmp_entry
->object
.sub_map
;
8786 vm_map_lock(src_map
);
8787 /* keep an outstanding reference for all maps in */
8788 /* the parents tree except the base map */
8789 vm_map_reference(src_map
);
8790 vm_map_unlock(ptr
->parent_map
);
8791 if (!vm_map_lookup_entry(
8792 src_map
, src_start
, &tmp_entry
))
8793 RETURN(KERN_INVALID_ADDRESS
);
8795 if(!tmp_entry
->is_sub_map
)
8796 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
8797 src_entry
= tmp_entry
;
8799 /* we are now in the lowest level submap... */
8801 if ((tmp_entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
8802 (tmp_entry
->object
.vm_object
->phys_contiguous
)) {
8803 /* This is not, supported for now.In future */
8804 /* we will need to detect the phys_contig */
8805 /* condition and then upgrade copy_slowly */
8806 /* to do physical copy from the device mem */
8807 /* based object. We can piggy-back off of */
8808 /* the was wired boolean to set-up the */
8809 /* proper handling */
8810 RETURN(KERN_PROTECTION_FAILURE
);
8813 * Create a new address map entry to hold the result.
8814 * Fill in the fields from the appropriate source entries.
8815 * We must unlock the source map to do this if we need
8816 * to allocate a map entry.
8818 if (new_entry
== VM_MAP_ENTRY_NULL
) {
8819 version
.main_timestamp
= src_map
->timestamp
;
8820 vm_map_unlock(src_map
);
8822 new_entry
= vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
8824 vm_map_lock(src_map
);
8825 if ((version
.main_timestamp
+ 1) != src_map
->timestamp
) {
8826 if (!vm_map_lookup_entry(src_map
, src_start
,
8828 RETURN(KERN_INVALID_ADDRESS
);
8830 if (!tmp_entry
->is_sub_map
)
8831 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
8832 continue; /* restart w/ new tmp_entry */
8837 * Verify that the region can be read.
8839 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
8841 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
8842 RETURN(KERN_PROTECTION_FAILURE
);
8845 * Clip against the endpoints of the entire region.
8848 vm_map_clip_end(src_map
, src_entry
, src_end
);
8850 src_size
= src_entry
->vme_end
- src_start
;
8851 src_object
= src_entry
->object
.vm_object
;
8852 src_offset
= src_entry
->offset
;
8853 was_wired
= (src_entry
->wired_count
!= 0);
8855 vm_map_entry_copy(new_entry
, src_entry
);
8856 if (new_entry
->is_sub_map
) {
8857 /* clr address space specifics */
8858 new_entry
->use_pmap
= FALSE
;
8862 * Attempt non-blocking copy-on-write optimizations.
8866 (src_object
== VM_OBJECT_NULL
||
8867 (src_object
->internal
&& !src_object
->true_share
8870 * If we are destroying the source, and the object
8871 * is internal, we can move the object reference
8872 * from the source to the copy. The copy is
8873 * copy-on-write only if the source is.
8874 * We make another reference to the object, because
8875 * destroying the source entry will deallocate it.
8877 vm_object_reference(src_object
);
8880 * Copy is always unwired. vm_map_copy_entry
8881 * set its wired count to zero.
8884 goto CopySuccessful
;
8889 XPR(XPR_VM_MAP
, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
8890 src_object
, new_entry
, new_entry
->object
.vm_object
,
8892 if ((src_object
== VM_OBJECT_NULL
||
8893 (!was_wired
&& !map_share
&& !tmp_entry
->is_shared
)) &&
8894 vm_object_copy_quickly(
8895 &new_entry
->object
.vm_object
,
8899 &new_entry_needs_copy
)) {
8901 new_entry
->needs_copy
= new_entry_needs_copy
;
8904 * Handle copy-on-write obligations
8907 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
8910 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
8912 if (override_nx(src_map
, src_entry
->alias
) && prot
)
8913 prot
|= VM_PROT_EXECUTE
;
8915 vm_object_pmap_protect(
8919 (src_entry
->is_shared
?
8922 src_entry
->vme_start
,
8925 tmp_entry
->needs_copy
= TRUE
;
8929 * The map has never been unlocked, so it's safe
8930 * to move to the next entry rather than doing
8934 goto CopySuccessful
;
8938 * Take an object reference, so that we may
8939 * release the map lock(s).
8942 assert(src_object
!= VM_OBJECT_NULL
);
8943 vm_object_reference(src_object
);
8946 * Record the timestamp for later verification.
8950 version
.main_timestamp
= src_map
->timestamp
;
8951 vm_map_unlock(src_map
); /* Increments timestamp once! */
8959 vm_object_lock(src_object
);
8960 result
= vm_object_copy_slowly(
8965 &new_entry
->object
.vm_object
);
8966 new_entry
->offset
= 0;
8967 new_entry
->needs_copy
= FALSE
;
8970 else if (src_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
8971 (tmp_entry
->is_shared
|| map_share
)) {
8972 vm_object_t new_object
;
8974 vm_object_lock_shared(src_object
);
8975 new_object
= vm_object_copy_delayed(
8980 if (new_object
== VM_OBJECT_NULL
)
8983 new_entry
->object
.vm_object
= new_object
;
8984 new_entry
->needs_copy
= TRUE
;
8985 assert(!new_entry
->iokit_acct
);
8986 assert(new_object
->purgable
== VM_PURGABLE_DENY
);
8987 new_entry
->use_pmap
= TRUE
;
8988 result
= KERN_SUCCESS
;
8991 result
= vm_object_copy_strategically(src_object
,
8994 &new_entry
->object
.vm_object
,
8996 &new_entry_needs_copy
);
8998 new_entry
->needs_copy
= new_entry_needs_copy
;
9001 if (result
!= KERN_SUCCESS
&&
9002 result
!= KERN_MEMORY_RESTART_COPY
) {
9003 vm_map_lock(src_map
);
9008 * Throw away the extra reference
9011 vm_object_deallocate(src_object
);
9014 * Verify that the map has not substantially
9015 * changed while the copy was being made.
9018 vm_map_lock(src_map
);
9020 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
)
9021 goto VerificationSuccessful
;
9024 * Simple version comparison failed.
9026 * Retry the lookup and verify that the
9027 * same object/offset are still present.
9029 * [Note: a memory manager that colludes with
9030 * the calling task can detect that we have
9031 * cheated. While the map was unlocked, the
9032 * mapping could have been changed and restored.]
9035 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
9036 if (result
!= KERN_MEMORY_RESTART_COPY
) {
9037 vm_object_deallocate(new_entry
->object
.vm_object
);
9038 new_entry
->object
.vm_object
= VM_OBJECT_NULL
;
9039 assert(!new_entry
->iokit_acct
);
9040 new_entry
->use_pmap
= TRUE
;
9042 RETURN(KERN_INVALID_ADDRESS
);
9045 src_entry
= tmp_entry
;
9046 vm_map_clip_start(src_map
, src_entry
, src_start
);
9048 if ((((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
) &&
9050 ((src_entry
->max_protection
& VM_PROT_READ
) == 0))
9051 goto VerificationFailed
;
9053 if (src_entry
->vme_end
< new_entry
->vme_end
) {
9054 assert(VM_MAP_PAGE_ALIGNED(src_entry
->vme_end
,
9055 VM_MAP_COPY_PAGE_MASK(copy
)));
9056 new_entry
->vme_end
= src_entry
->vme_end
;
9057 src_size
= new_entry
->vme_end
- src_start
;
9060 if ((src_entry
->object
.vm_object
!= src_object
) ||
9061 (src_entry
->offset
!= src_offset
) ) {
9064 * Verification failed.
9066 * Start over with this top-level entry.
9069 VerificationFailed
: ;
9071 vm_object_deallocate(new_entry
->object
.vm_object
);
9072 tmp_entry
= src_entry
;
9077 * Verification succeeded.
9080 VerificationSuccessful
: ;
9082 if (result
== KERN_MEMORY_RESTART_COPY
)
9092 * Link in the new copy entry.
9095 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
9099 * Determine whether the entire region
9102 src_base
= src_start
;
9103 src_start
= new_entry
->vme_end
;
9104 new_entry
= VM_MAP_ENTRY_NULL
;
9105 while ((src_start
>= src_end
) && (src_end
!= 0)) {
9108 if (src_map
== base_map
) {
9109 /* back to the top */
9114 assert(ptr
!= NULL
);
9115 parent_maps
= parent_maps
->next
;
9117 /* fix up the damage we did in that submap */
9118 vm_map_simplify_range(src_map
,
9122 vm_map_unlock(src_map
);
9123 vm_map_deallocate(src_map
);
9124 vm_map_lock(ptr
->parent_map
);
9125 src_map
= ptr
->parent_map
;
9126 src_base
= ptr
->base_start
;
9127 src_start
= ptr
->base_start
+ ptr
->base_len
;
9128 src_end
= ptr
->base_end
;
9129 if (!vm_map_lookup_entry(src_map
,
9132 (src_end
> src_start
)) {
9133 RETURN(KERN_INVALID_ADDRESS
);
9135 kfree(ptr
, sizeof(submap_map_t
));
9136 if (parent_maps
== NULL
)
9138 src_entry
= tmp_entry
->vme_prev
;
9141 if ((VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
) &&
9142 (src_start
>= src_addr
+ len
) &&
9143 (src_addr
+ len
!= 0)) {
9145 * Stop copying now, even though we haven't reached
9146 * "src_end". We'll adjust the end of the last copy
9147 * entry at the end, if needed.
9149 * If src_map's aligment is different from the
9150 * system's page-alignment, there could be
9151 * extra non-map-aligned map entries between
9152 * the original (non-rounded) "src_addr + len"
9153 * and the rounded "src_end".
9154 * We do not want to copy those map entries since
9155 * they're not part of the copied range.
9160 if ((src_start
>= src_end
) && (src_end
!= 0))
9164 * Verify that there are no gaps in the region
9167 tmp_entry
= src_entry
->vme_next
;
9168 if ((tmp_entry
->vme_start
!= src_start
) ||
9169 (tmp_entry
== vm_map_to_entry(src_map
))) {
9170 RETURN(KERN_INVALID_ADDRESS
);
9175 * If the source should be destroyed, do it now, since the
9176 * copy was successful.
9179 (void) vm_map_delete(
9181 vm_map_trunc_page(src_addr
,
9182 VM_MAP_PAGE_MASK(src_map
)),
9184 ((src_map
== kernel_map
) ?
9185 VM_MAP_REMOVE_KUNWIRE
:
9189 /* fix up the damage we did in the base map */
9190 vm_map_simplify_range(
9192 vm_map_trunc_page(src_addr
,
9193 VM_MAP_PAGE_MASK(src_map
)),
9194 vm_map_round_page(src_end
,
9195 VM_MAP_PAGE_MASK(src_map
)));
9198 vm_map_unlock(src_map
);
9200 if (VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
) {
9201 vm_map_offset_t original_start
, original_offset
, original_end
;
9203 assert(VM_MAP_COPY_PAGE_MASK(copy
) == PAGE_MASK
);
9205 /* adjust alignment of first copy_entry's "vme_start" */
9206 tmp_entry
= vm_map_copy_first_entry(copy
);
9207 if (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
9208 vm_map_offset_t adjustment
;
9210 original_start
= tmp_entry
->vme_start
;
9211 original_offset
= tmp_entry
->offset
;
9213 /* map-align the start of the first copy entry... */
9214 adjustment
= (tmp_entry
->vme_start
-
9216 tmp_entry
->vme_start
,
9217 VM_MAP_PAGE_MASK(src_map
)));
9218 tmp_entry
->vme_start
-= adjustment
;
9219 tmp_entry
->offset
-= adjustment
;
9220 copy_addr
-= adjustment
;
9221 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
9222 /* ... adjust for mis-aligned start of copy range */
9224 (vm_map_trunc_page(copy
->offset
,
9226 vm_map_trunc_page(copy
->offset
,
9227 VM_MAP_PAGE_MASK(src_map
)));
9229 assert(page_aligned(adjustment
));
9230 assert(adjustment
< VM_MAP_PAGE_SIZE(src_map
));
9231 tmp_entry
->vme_start
+= adjustment
;
9232 tmp_entry
->offset
+= adjustment
;
9233 copy_addr
+= adjustment
;
9234 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
9238 * Assert that the adjustments haven't exposed
9239 * more than was originally copied...
9241 assert(tmp_entry
->vme_start
>= original_start
);
9242 assert(tmp_entry
->offset
>= original_offset
);
9244 * ... and that it did not adjust outside of a
9245 * a single 16K page.
9247 assert(vm_map_trunc_page(tmp_entry
->vme_start
,
9248 VM_MAP_PAGE_MASK(src_map
)) ==
9249 vm_map_trunc_page(original_start
,
9250 VM_MAP_PAGE_MASK(src_map
)));
9253 /* adjust alignment of last copy_entry's "vme_end" */
9254 tmp_entry
= vm_map_copy_last_entry(copy
);
9255 if (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
9256 vm_map_offset_t adjustment
;
9258 original_end
= tmp_entry
->vme_end
;
9260 /* map-align the end of the last copy entry... */
9261 tmp_entry
->vme_end
=
9262 vm_map_round_page(tmp_entry
->vme_end
,
9263 VM_MAP_PAGE_MASK(src_map
));
9264 /* ... adjust for mis-aligned end of copy range */
9266 (vm_map_round_page((copy
->offset
+
9268 VM_MAP_PAGE_MASK(src_map
)) -
9269 vm_map_round_page((copy
->offset
+
9273 assert(page_aligned(adjustment
));
9274 assert(adjustment
< VM_MAP_PAGE_SIZE(src_map
));
9275 tmp_entry
->vme_end
-= adjustment
;
9276 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
9280 * Assert that the adjustments haven't exposed
9281 * more than was originally copied...
9283 assert(tmp_entry
->vme_end
<= original_end
);
9285 * ... and that it did not adjust outside of a
9286 * a single 16K page.
9288 assert(vm_map_round_page(tmp_entry
->vme_end
,
9289 VM_MAP_PAGE_MASK(src_map
)) ==
9290 vm_map_round_page(original_end
,
9291 VM_MAP_PAGE_MASK(src_map
)));
9295 /* Fix-up start and end points in copy. This is necessary */
9296 /* when the various entries in the copy object were picked */
9297 /* up from different sub-maps */
9299 tmp_entry
= vm_map_copy_first_entry(copy
);
9300 copy_size
= 0; /* compute actual size */
9301 while (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
9302 assert(VM_MAP_PAGE_ALIGNED(
9303 copy_addr
+ (tmp_entry
->vme_end
-
9304 tmp_entry
->vme_start
),
9305 VM_MAP_COPY_PAGE_MASK(copy
)));
9306 assert(VM_MAP_PAGE_ALIGNED(
9308 VM_MAP_COPY_PAGE_MASK(copy
)));
9311 * The copy_entries will be injected directly into the
9312 * destination map and might not be "map aligned" there...
9314 tmp_entry
->map_aligned
= FALSE
;
9316 tmp_entry
->vme_end
= copy_addr
+
9317 (tmp_entry
->vme_end
- tmp_entry
->vme_start
);
9318 tmp_entry
->vme_start
= copy_addr
;
9319 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
9320 copy_addr
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
9321 copy_size
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
9322 tmp_entry
= (struct vm_map_entry
*)tmp_entry
->vme_next
;
9325 if (VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
&&
9326 copy_size
< copy
->size
) {
9328 * The actual size of the VM map copy is smaller than what
9329 * was requested by the caller. This must be because some
9330 * PAGE_SIZE-sized pages are missing at the end of the last
9331 * VM_MAP_PAGE_SIZE(src_map)-sized chunk of the range.
9332 * The caller might not have been aware of those missing
9333 * pages and might not want to be aware of it, which is
9334 * fine as long as they don't try to access (and crash on)
9335 * those missing pages.
9336 * Let's adjust the size of the "copy", to avoid failing
9337 * in vm_map_copyout() or vm_map_copy_overwrite().
9339 assert(vm_map_round_page(copy_size
,
9340 VM_MAP_PAGE_MASK(src_map
)) ==
9341 vm_map_round_page(copy
->size
,
9342 VM_MAP_PAGE_MASK(src_map
)));
9343 copy
->size
= copy_size
;
9346 *copy_result
= copy
;
9347 return(KERN_SUCCESS
);
9353 vm_map_copy_extract(
9355 vm_map_address_t src_addr
,
9357 vm_map_copy_t
*copy_result
, /* OUT */
9358 vm_prot_t
*cur_prot
, /* OUT */
9359 vm_prot_t
*max_prot
)
9361 vm_map_offset_t src_start
, src_end
;
9366 * Check for copies of zero bytes.
9370 *copy_result
= VM_MAP_COPY_NULL
;
9371 return(KERN_SUCCESS
);
9375 * Check that the end address doesn't overflow
9377 src_end
= src_addr
+ len
;
9378 if (src_end
< src_addr
)
9379 return KERN_INVALID_ADDRESS
;
9382 * Compute (page aligned) start and end of region
9384 src_start
= vm_map_trunc_page(src_addr
, PAGE_MASK
);
9385 src_end
= vm_map_round_page(src_end
, PAGE_MASK
);
9388 * Allocate a header element for the list.
9390 * Use the start and end in the header to
9391 * remember the endpoints prior to rounding.
9394 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
9395 vm_map_copy_first_entry(copy
) =
9396 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
9397 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
9398 copy
->cpy_hdr
.nentries
= 0;
9399 copy
->cpy_hdr
.entries_pageable
= TRUE
;
9401 vm_map_store_init(©
->cpy_hdr
);
9406 kr
= vm_map_remap_extract(src_map
,
9414 TRUE
); /* pageable */
9415 if (kr
!= KERN_SUCCESS
) {
9416 vm_map_copy_discard(copy
);
9420 *copy_result
= copy
;
9421 return KERN_SUCCESS
;
9425 * vm_map_copyin_object:
9427 * Create a copy object from an object.
9428 * Our caller donates an object reference.
9432 vm_map_copyin_object(
9434 vm_object_offset_t offset
, /* offset of region in object */
9435 vm_object_size_t size
, /* size of region in object */
9436 vm_map_copy_t
*copy_result
) /* OUT */
9438 vm_map_copy_t copy
; /* Resulting copy */
9441 * We drop the object into a special copy object
9442 * that contains the object directly.
9445 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
9446 copy
->type
= VM_MAP_COPY_OBJECT
;
9447 copy
->cpy_object
= object
;
9448 copy
->offset
= offset
;
9451 *copy_result
= copy
;
9452 return(KERN_SUCCESS
);
9458 vm_map_entry_t old_entry
,
9462 vm_map_entry_t new_entry
;
9465 * New sharing code. New map entry
9466 * references original object. Internal
9467 * objects use asynchronous copy algorithm for
9468 * future copies. First make sure we have
9469 * the right object. If we need a shadow,
9470 * or someone else already has one, then
9471 * make a new shadow and share it.
9474 object
= old_entry
->object
.vm_object
;
9475 if (old_entry
->is_sub_map
) {
9476 assert(old_entry
->wired_count
== 0);
9477 #ifndef NO_NESTED_PMAP
9478 if(old_entry
->use_pmap
) {
9479 kern_return_t result
;
9481 result
= pmap_nest(new_map
->pmap
,
9482 (old_entry
->object
.sub_map
)->pmap
,
9483 (addr64_t
)old_entry
->vme_start
,
9484 (addr64_t
)old_entry
->vme_start
,
9485 (uint64_t)(old_entry
->vme_end
- old_entry
->vme_start
));
9487 panic("vm_map_fork_share: pmap_nest failed!");
9489 #endif /* NO_NESTED_PMAP */
9490 } else if (object
== VM_OBJECT_NULL
) {
9491 object
= vm_object_allocate((vm_map_size_t
)(old_entry
->vme_end
-
9492 old_entry
->vme_start
));
9493 old_entry
->offset
= 0;
9494 old_entry
->object
.vm_object
= object
;
9495 old_entry
->use_pmap
= TRUE
;
9496 assert(!old_entry
->needs_copy
);
9497 } else if (object
->copy_strategy
!=
9498 MEMORY_OBJECT_COPY_SYMMETRIC
) {
9501 * We are already using an asymmetric
9502 * copy, and therefore we already have
9506 assert(! old_entry
->needs_copy
);
9508 else if (old_entry
->needs_copy
|| /* case 1 */
9509 object
->shadowed
|| /* case 2 */
9510 (!object
->true_share
&& /* case 3 */
9511 !old_entry
->is_shared
&&
9513 (vm_map_size_t
)(old_entry
->vme_end
-
9514 old_entry
->vme_start
)))) {
9517 * We need to create a shadow.
9518 * There are three cases here.
9519 * In the first case, we need to
9520 * complete a deferred symmetrical
9521 * copy that we participated in.
9522 * In the second and third cases,
9523 * we need to create the shadow so
9524 * that changes that we make to the
9525 * object do not interfere with
9526 * any symmetrical copies which
9527 * have occured (case 2) or which
9528 * might occur (case 3).
9530 * The first case is when we had
9531 * deferred shadow object creation
9532 * via the entry->needs_copy mechanism.
9533 * This mechanism only works when
9534 * only one entry points to the source
9535 * object, and we are about to create
9536 * a second entry pointing to the
9537 * same object. The problem is that
9538 * there is no way of mapping from
9539 * an object to the entries pointing
9540 * to it. (Deferred shadow creation
9541 * works with one entry because occurs
9542 * at fault time, and we walk from the
9543 * entry to the object when handling
9546 * The second case is when the object
9547 * to be shared has already been copied
9548 * with a symmetric copy, but we point
9549 * directly to the object without
9550 * needs_copy set in our entry. (This
9551 * can happen because different ranges
9552 * of an object can be pointed to by
9553 * different entries. In particular,
9554 * a single entry pointing to an object
9555 * can be split by a call to vm_inherit,
9556 * which, combined with task_create, can
9557 * result in the different entries
9558 * having different needs_copy values.)
9559 * The shadowed flag in the object allows
9560 * us to detect this case. The problem
9561 * with this case is that if this object
9562 * has or will have shadows, then we
9563 * must not perform an asymmetric copy
9564 * of this object, since such a copy
9565 * allows the object to be changed, which
9566 * will break the previous symmetrical
9567 * copies (which rely upon the object
9568 * not changing). In a sense, the shadowed
9569 * flag says "don't change this object".
9570 * We fix this by creating a shadow
9571 * object for this object, and sharing
9572 * that. This works because we are free
9573 * to change the shadow object (and thus
9574 * to use an asymmetric copy strategy);
9575 * this is also semantically correct,
9576 * since this object is temporary, and
9577 * therefore a copy of the object is
9578 * as good as the object itself. (This
9579 * is not true for permanent objects,
9580 * since the pager needs to see changes,
9581 * which won't happen if the changes
9582 * are made to a copy.)
9584 * The third case is when the object
9585 * to be shared has parts sticking
9586 * outside of the entry we're working
9587 * with, and thus may in the future
9588 * be subject to a symmetrical copy.
9589 * (This is a preemptive version of
9592 vm_object_shadow(&old_entry
->object
.vm_object
,
9594 (vm_map_size_t
) (old_entry
->vme_end
-
9595 old_entry
->vme_start
));
9598 * If we're making a shadow for other than
9599 * copy on write reasons, then we have
9600 * to remove write permission.
9603 if (!old_entry
->needs_copy
&&
9604 (old_entry
->protection
& VM_PROT_WRITE
)) {
9607 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
9609 if (override_nx(old_map
, old_entry
->alias
) && prot
)
9610 prot
|= VM_PROT_EXECUTE
;
9612 if (old_map
->mapped_in_other_pmaps
) {
9613 vm_object_pmap_protect(
9614 old_entry
->object
.vm_object
,
9616 (old_entry
->vme_end
-
9617 old_entry
->vme_start
),
9619 old_entry
->vme_start
,
9622 pmap_protect(old_map
->pmap
,
9623 old_entry
->vme_start
,
9629 old_entry
->needs_copy
= FALSE
;
9630 object
= old_entry
->object
.vm_object
;
9635 * If object was using a symmetric copy strategy,
9636 * change its copy strategy to the default
9637 * asymmetric copy strategy, which is copy_delay
9638 * in the non-norma case and copy_call in the
9639 * norma case. Bump the reference count for the
9643 if(old_entry
->is_sub_map
) {
9644 vm_map_lock(old_entry
->object
.sub_map
);
9645 vm_map_reference(old_entry
->object
.sub_map
);
9646 vm_map_unlock(old_entry
->object
.sub_map
);
9648 vm_object_lock(object
);
9649 vm_object_reference_locked(object
);
9650 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
9651 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
9653 vm_object_unlock(object
);
9657 * Clone the entry, using object ref from above.
9658 * Mark both entries as shared.
9661 new_entry
= vm_map_entry_create(new_map
, FALSE
); /* Never the kernel
9662 * map or descendants */
9663 vm_map_entry_copy(new_entry
, old_entry
);
9664 old_entry
->is_shared
= TRUE
;
9665 new_entry
->is_shared
= TRUE
;
9668 * Insert the entry into the new map -- we
9669 * know we're inserting at the end of the new
9673 vm_map_store_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
9676 * Update the physical map
9679 if (old_entry
->is_sub_map
) {
9680 /* Bill Angell pmap support goes here */
9682 pmap_copy(new_map
->pmap
, old_map
->pmap
, new_entry
->vme_start
,
9683 old_entry
->vme_end
- old_entry
->vme_start
,
9684 old_entry
->vme_start
);
9691 vm_map_entry_t
*old_entry_p
,
9694 vm_map_entry_t old_entry
= *old_entry_p
;
9695 vm_map_size_t entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
9696 vm_map_offset_t start
= old_entry
->vme_start
;
9698 vm_map_entry_t last
= vm_map_last_entry(new_map
);
9700 vm_map_unlock(old_map
);
9702 * Use maxprot version of copyin because we
9703 * care about whether this memory can ever
9704 * be accessed, not just whether it's accessible
9707 if (vm_map_copyin_maxprot(old_map
, start
, entry_size
, FALSE
, ©
)
9710 * The map might have changed while it
9711 * was unlocked, check it again. Skip
9712 * any blank space or permanently
9713 * unreadable region.
9715 vm_map_lock(old_map
);
9716 if (!vm_map_lookup_entry(old_map
, start
, &last
) ||
9717 (last
->max_protection
& VM_PROT_READ
) == VM_PROT_NONE
) {
9718 last
= last
->vme_next
;
9720 *old_entry_p
= last
;
9723 * XXX For some error returns, want to
9724 * XXX skip to the next element. Note
9725 * that INVALID_ADDRESS and
9726 * PROTECTION_FAILURE are handled above.
9733 * Insert the copy into the new map
9736 vm_map_copy_insert(new_map
, last
, copy
);
9739 * Pick up the traversal at the end of
9740 * the copied region.
9743 vm_map_lock(old_map
);
9744 start
+= entry_size
;
9745 if (! vm_map_lookup_entry(old_map
, start
, &last
)) {
9746 last
= last
->vme_next
;
9748 if (last
->vme_start
== start
) {
9750 * No need to clip here and we don't
9751 * want to cause any unnecessary
9755 vm_map_clip_start(old_map
, last
, start
);
9758 *old_entry_p
= last
;
9766 * Create and return a new map based on the old
9767 * map, according to the inheritance values on the
9768 * regions in that map.
9770 * The source map must not be locked.
9779 vm_map_entry_t old_entry
;
9780 vm_map_size_t new_size
= 0, entry_size
;
9781 vm_map_entry_t new_entry
;
9782 boolean_t src_needs_copy
;
9783 boolean_t new_entry_needs_copy
;
9785 new_pmap
= pmap_create(ledger
, (vm_map_size_t
) 0,
9786 #if defined(__i386__) || defined(__x86_64__)
9787 old_map
->pmap
->pm_task_map
!= TASK_MAP_32BIT
9789 #error Unknown architecture.
9793 vm_map_reference_swap(old_map
);
9794 vm_map_lock(old_map
);
9796 new_map
= vm_map_create(new_pmap
,
9797 old_map
->min_offset
,
9798 old_map
->max_offset
,
9799 old_map
->hdr
.entries_pageable
);
9800 /* inherit the parent map's page size */
9801 vm_map_set_page_shift(new_map
, VM_MAP_PAGE_SHIFT(old_map
));
9803 old_entry
= vm_map_first_entry(old_map
);
9804 old_entry
!= vm_map_to_entry(old_map
);
9807 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
9809 switch (old_entry
->inheritance
) {
9810 case VM_INHERIT_NONE
:
9813 case VM_INHERIT_SHARE
:
9814 vm_map_fork_share(old_map
, old_entry
, new_map
);
9815 new_size
+= entry_size
;
9818 case VM_INHERIT_COPY
:
9821 * Inline the copy_quickly case;
9822 * upon failure, fall back on call
9823 * to vm_map_fork_copy.
9826 if(old_entry
->is_sub_map
)
9828 if ((old_entry
->wired_count
!= 0) ||
9829 ((old_entry
->object
.vm_object
!= NULL
) &&
9830 (old_entry
->object
.vm_object
->true_share
))) {
9831 goto slow_vm_map_fork_copy
;
9834 new_entry
= vm_map_entry_create(new_map
, FALSE
); /* never the kernel map or descendants */
9835 vm_map_entry_copy(new_entry
, old_entry
);
9836 if (new_entry
->is_sub_map
) {
9837 /* clear address space specifics */
9838 new_entry
->use_pmap
= FALSE
;
9841 if (! vm_object_copy_quickly(
9842 &new_entry
->object
.vm_object
,
9844 (old_entry
->vme_end
-
9845 old_entry
->vme_start
),
9847 &new_entry_needs_copy
)) {
9848 vm_map_entry_dispose(new_map
, new_entry
);
9849 goto slow_vm_map_fork_copy
;
9853 * Handle copy-on-write obligations
9856 if (src_needs_copy
&& !old_entry
->needs_copy
) {
9859 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
9861 if (override_nx(old_map
, old_entry
->alias
) && prot
)
9862 prot
|= VM_PROT_EXECUTE
;
9864 vm_object_pmap_protect(
9865 old_entry
->object
.vm_object
,
9867 (old_entry
->vme_end
-
9868 old_entry
->vme_start
),
9869 ((old_entry
->is_shared
9870 || old_map
->mapped_in_other_pmaps
)
9873 old_entry
->vme_start
,
9876 old_entry
->needs_copy
= TRUE
;
9878 new_entry
->needs_copy
= new_entry_needs_copy
;
9881 * Insert the entry at the end
9885 vm_map_store_entry_link(new_map
, vm_map_last_entry(new_map
),
9887 new_size
+= entry_size
;
9890 slow_vm_map_fork_copy
:
9891 if (vm_map_fork_copy(old_map
, &old_entry
, new_map
)) {
9892 new_size
+= entry_size
;
9896 old_entry
= old_entry
->vme_next
;
9900 new_map
->size
= new_size
;
9901 vm_map_unlock(old_map
);
9902 vm_map_deallocate(old_map
);
9910 * Setup the "new_map" with the proper execution environment according
9911 * to the type of executable (platform, 64bit, chroot environment).
9912 * Map the comm page and shared region, etc...
9921 SHARED_REGION_TRACE_DEBUG(
9922 ("shared_region: task %p: vm_map_exec(%p,%p,%p,0x%x): ->\n",
9923 (void *)VM_KERNEL_ADDRPERM(current_task()),
9924 (void *)VM_KERNEL_ADDRPERM(new_map
),
9925 (void *)VM_KERNEL_ADDRPERM(task
),
9926 (void *)VM_KERNEL_ADDRPERM(fsroot
),
9928 (void) vm_commpage_enter(new_map
, task
);
9929 (void) vm_shared_region_enter(new_map
, task
, fsroot
, cpu
);
9930 SHARED_REGION_TRACE_DEBUG(
9931 ("shared_region: task %p: vm_map_exec(%p,%p,%p,0x%x): <-\n",
9932 (void *)VM_KERNEL_ADDRPERM(current_task()),
9933 (void *)VM_KERNEL_ADDRPERM(new_map
),
9934 (void *)VM_KERNEL_ADDRPERM(task
),
9935 (void *)VM_KERNEL_ADDRPERM(fsroot
),
9937 return KERN_SUCCESS
;
9941 * vm_map_lookup_locked:
9943 * Finds the VM object, offset, and
9944 * protection for a given virtual address in the
9945 * specified map, assuming a page fault of the
9948 * Returns the (object, offset, protection) for
9949 * this address, whether it is wired down, and whether
9950 * this map has the only reference to the data in question.
9951 * In order to later verify this lookup, a "version"
9954 * The map MUST be locked by the caller and WILL be
9955 * locked on exit. In order to guarantee the
9956 * existence of the returned object, it is returned
9959 * If a lookup is requested with "write protection"
9960 * specified, the map may be changed to perform virtual
9961 * copying operations, although the data referenced will
9965 vm_map_lookup_locked(
9966 vm_map_t
*var_map
, /* IN/OUT */
9967 vm_map_offset_t vaddr
,
9968 vm_prot_t fault_type
,
9969 int object_lock_type
,
9970 vm_map_version_t
*out_version
, /* OUT */
9971 vm_object_t
*object
, /* OUT */
9972 vm_object_offset_t
*offset
, /* OUT */
9973 vm_prot_t
*out_prot
, /* OUT */
9974 boolean_t
*wired
, /* OUT */
9975 vm_object_fault_info_t fault_info
, /* OUT */
9978 vm_map_entry_t entry
;
9979 register vm_map_t map
= *var_map
;
9980 vm_map_t old_map
= *var_map
;
9981 vm_map_t cow_sub_map_parent
= VM_MAP_NULL
;
9982 vm_map_offset_t cow_parent_vaddr
= 0;
9983 vm_map_offset_t old_start
= 0;
9984 vm_map_offset_t old_end
= 0;
9985 register vm_prot_t prot
;
9986 boolean_t mask_protections
;
9987 boolean_t force_copy
;
9988 vm_prot_t original_fault_type
;
9991 * VM_PROT_MASK means that the caller wants us to use "fault_type"
9992 * as a mask against the mapping's actual protections, not as an
9995 mask_protections
= (fault_type
& VM_PROT_IS_MASK
) ? TRUE
: FALSE
;
9996 force_copy
= (fault_type
& VM_PROT_COPY
) ? TRUE
: FALSE
;
9997 fault_type
&= VM_PROT_ALL
;
9998 original_fault_type
= fault_type
;
10003 fault_type
= original_fault_type
;
10006 * If the map has an interesting hint, try it before calling
10007 * full blown lookup routine.
10011 if ((entry
== vm_map_to_entry(map
)) ||
10012 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
10013 vm_map_entry_t tmp_entry
;
10016 * Entry was either not a valid hint, or the vaddr
10017 * was not contained in the entry, so do a full lookup.
10019 if (!vm_map_lookup_entry(map
, vaddr
, &tmp_entry
)) {
10020 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
))
10021 vm_map_unlock(cow_sub_map_parent
);
10022 if((*real_map
!= map
)
10023 && (*real_map
!= cow_sub_map_parent
))
10024 vm_map_unlock(*real_map
);
10025 return KERN_INVALID_ADDRESS
;
10030 if(map
== old_map
) {
10031 old_start
= entry
->vme_start
;
10032 old_end
= entry
->vme_end
;
10036 * Handle submaps. Drop lock on upper map, submap is
10041 if (entry
->is_sub_map
) {
10042 vm_map_offset_t local_vaddr
;
10043 vm_map_offset_t end_delta
;
10044 vm_map_offset_t start_delta
;
10045 vm_map_entry_t submap_entry
;
10046 boolean_t mapped_needs_copy
=FALSE
;
10048 local_vaddr
= vaddr
;
10050 if ((entry
->use_pmap
&& !(fault_type
& VM_PROT_WRITE
))) {
10051 /* if real_map equals map we unlock below */
10052 if ((*real_map
!= map
) &&
10053 (*real_map
!= cow_sub_map_parent
))
10054 vm_map_unlock(*real_map
);
10055 *real_map
= entry
->object
.sub_map
;
10058 if(entry
->needs_copy
&& (fault_type
& VM_PROT_WRITE
)) {
10059 if (!mapped_needs_copy
) {
10060 if (vm_map_lock_read_to_write(map
)) {
10061 vm_map_lock_read(map
);
10065 vm_map_lock_read(entry
->object
.sub_map
);
10066 *var_map
= entry
->object
.sub_map
;
10067 cow_sub_map_parent
= map
;
10068 /* reset base to map before cow object */
10069 /* this is the map which will accept */
10070 /* the new cow object */
10071 old_start
= entry
->vme_start
;
10072 old_end
= entry
->vme_end
;
10073 cow_parent_vaddr
= vaddr
;
10074 mapped_needs_copy
= TRUE
;
10076 vm_map_lock_read(entry
->object
.sub_map
);
10077 *var_map
= entry
->object
.sub_map
;
10078 if((cow_sub_map_parent
!= map
) &&
10079 (*real_map
!= map
))
10080 vm_map_unlock(map
);
10083 vm_map_lock_read(entry
->object
.sub_map
);
10084 *var_map
= entry
->object
.sub_map
;
10085 /* leave map locked if it is a target */
10086 /* cow sub_map above otherwise, just */
10087 /* follow the maps down to the object */
10088 /* here we unlock knowing we are not */
10089 /* revisiting the map. */
10090 if((*real_map
!= map
) && (map
!= cow_sub_map_parent
))
10091 vm_map_unlock_read(map
);
10096 /* calculate the offset in the submap for vaddr */
10097 local_vaddr
= (local_vaddr
- entry
->vme_start
) + entry
->offset
;
10100 if(!vm_map_lookup_entry(map
, local_vaddr
, &submap_entry
)) {
10101 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
)){
10102 vm_map_unlock(cow_sub_map_parent
);
10104 if((*real_map
!= map
)
10105 && (*real_map
!= cow_sub_map_parent
)) {
10106 vm_map_unlock(*real_map
);
10109 return KERN_INVALID_ADDRESS
;
10112 /* find the attenuated shadow of the underlying object */
10113 /* on our target map */
10115 /* in english the submap object may extend beyond the */
10116 /* region mapped by the entry or, may only fill a portion */
10117 /* of it. For our purposes, we only care if the object */
10118 /* doesn't fill. In this case the area which will */
10119 /* ultimately be clipped in the top map will only need */
10120 /* to be as big as the portion of the underlying entry */
10121 /* which is mapped */
10122 start_delta
= submap_entry
->vme_start
> entry
->offset
?
10123 submap_entry
->vme_start
- entry
->offset
: 0;
10126 (entry
->offset
+ start_delta
+ (old_end
- old_start
)) <=
10127 submap_entry
->vme_end
?
10128 0 : (entry
->offset
+
10129 (old_end
- old_start
))
10130 - submap_entry
->vme_end
;
10132 old_start
+= start_delta
;
10133 old_end
-= end_delta
;
10135 if(submap_entry
->is_sub_map
) {
10136 entry
= submap_entry
;
10137 vaddr
= local_vaddr
;
10138 goto submap_recurse
;
10141 if(((fault_type
& VM_PROT_WRITE
) && cow_sub_map_parent
)) {
10143 vm_object_t sub_object
, copy_object
;
10144 vm_object_offset_t copy_offset
;
10145 vm_map_offset_t local_start
;
10146 vm_map_offset_t local_end
;
10147 boolean_t copied_slowly
= FALSE
;
10149 if (vm_map_lock_read_to_write(map
)) {
10150 vm_map_lock_read(map
);
10151 old_start
-= start_delta
;
10152 old_end
+= end_delta
;
10157 sub_object
= submap_entry
->object
.vm_object
;
10158 if (sub_object
== VM_OBJECT_NULL
) {
10160 vm_object_allocate(
10162 (submap_entry
->vme_end
-
10163 submap_entry
->vme_start
));
10164 submap_entry
->object
.vm_object
= sub_object
;
10165 submap_entry
->offset
= 0;
10167 local_start
= local_vaddr
-
10168 (cow_parent_vaddr
- old_start
);
10169 local_end
= local_vaddr
+
10170 (old_end
- cow_parent_vaddr
);
10171 vm_map_clip_start(map
, submap_entry
, local_start
);
10172 vm_map_clip_end(map
, submap_entry
, local_end
);
10173 if (submap_entry
->is_sub_map
) {
10174 /* unnesting was done when clipping */
10175 assert(!submap_entry
->use_pmap
);
10178 /* This is the COW case, lets connect */
10179 /* an entry in our space to the underlying */
10180 /* object in the submap, bypassing the */
10184 if(submap_entry
->wired_count
!= 0 ||
10185 (sub_object
->copy_strategy
==
10186 MEMORY_OBJECT_COPY_NONE
)) {
10187 vm_object_lock(sub_object
);
10188 vm_object_copy_slowly(sub_object
,
10189 submap_entry
->offset
,
10190 (submap_entry
->vme_end
-
10191 submap_entry
->vme_start
),
10194 copied_slowly
= TRUE
;
10197 /* set up shadow object */
10198 copy_object
= sub_object
;
10199 vm_object_reference(copy_object
);
10200 sub_object
->shadowed
= TRUE
;
10201 submap_entry
->needs_copy
= TRUE
;
10203 prot
= submap_entry
->protection
& ~VM_PROT_WRITE
;
10205 if (override_nx(old_map
, submap_entry
->alias
) && prot
)
10206 prot
|= VM_PROT_EXECUTE
;
10208 vm_object_pmap_protect(
10210 submap_entry
->offset
,
10211 submap_entry
->vme_end
-
10212 submap_entry
->vme_start
,
10213 (submap_entry
->is_shared
10214 || map
->mapped_in_other_pmaps
) ?
10215 PMAP_NULL
: map
->pmap
,
10216 submap_entry
->vme_start
,
10221 * Adjust the fault offset to the submap entry.
10223 copy_offset
= (local_vaddr
-
10224 submap_entry
->vme_start
+
10225 submap_entry
->offset
);
10227 /* This works diffently than the */
10228 /* normal submap case. We go back */
10229 /* to the parent of the cow map and*/
10230 /* clip out the target portion of */
10231 /* the sub_map, substituting the */
10232 /* new copy object, */
10234 vm_map_unlock(map
);
10235 local_start
= old_start
;
10236 local_end
= old_end
;
10237 map
= cow_sub_map_parent
;
10238 *var_map
= cow_sub_map_parent
;
10239 vaddr
= cow_parent_vaddr
;
10240 cow_sub_map_parent
= NULL
;
10242 if(!vm_map_lookup_entry(map
,
10244 vm_object_deallocate(
10246 vm_map_lock_write_to_read(map
);
10247 return KERN_INVALID_ADDRESS
;
10250 /* clip out the portion of space */
10251 /* mapped by the sub map which */
10252 /* corresponds to the underlying */
10256 * Clip (and unnest) the smallest nested chunk
10257 * possible around the faulting address...
10259 local_start
= vaddr
& ~(pmap_nesting_size_min
- 1);
10260 local_end
= local_start
+ pmap_nesting_size_min
;
10262 * ... but don't go beyond the "old_start" to "old_end"
10263 * range, to avoid spanning over another VM region
10264 * with a possibly different VM object and/or offset.
10266 if (local_start
< old_start
) {
10267 local_start
= old_start
;
10269 if (local_end
> old_end
) {
10270 local_end
= old_end
;
10273 * Adjust copy_offset to the start of the range.
10275 copy_offset
-= (vaddr
- local_start
);
10277 vm_map_clip_start(map
, entry
, local_start
);
10278 vm_map_clip_end(map
, entry
, local_end
);
10279 if (entry
->is_sub_map
) {
10280 /* unnesting was done when clipping */
10281 assert(!entry
->use_pmap
);
10284 /* substitute copy object for */
10285 /* shared map entry */
10286 vm_map_deallocate(entry
->object
.sub_map
);
10287 assert(!entry
->iokit_acct
);
10288 entry
->is_sub_map
= FALSE
;
10289 entry
->use_pmap
= TRUE
;
10290 entry
->object
.vm_object
= copy_object
;
10292 /* propagate the submap entry's protections */
10293 entry
->protection
|= submap_entry
->protection
;
10294 entry
->max_protection
|= submap_entry
->max_protection
;
10296 if(copied_slowly
) {
10297 entry
->offset
= local_start
- old_start
;
10298 entry
->needs_copy
= FALSE
;
10299 entry
->is_shared
= FALSE
;
10301 entry
->offset
= copy_offset
;
10302 entry
->needs_copy
= TRUE
;
10303 if(entry
->inheritance
== VM_INHERIT_SHARE
)
10304 entry
->inheritance
= VM_INHERIT_COPY
;
10305 if (map
!= old_map
)
10306 entry
->is_shared
= TRUE
;
10308 if(entry
->inheritance
== VM_INHERIT_SHARE
)
10309 entry
->inheritance
= VM_INHERIT_COPY
;
10311 vm_map_lock_write_to_read(map
);
10313 if((cow_sub_map_parent
)
10314 && (cow_sub_map_parent
!= *real_map
)
10315 && (cow_sub_map_parent
!= map
)) {
10316 vm_map_unlock(cow_sub_map_parent
);
10318 entry
= submap_entry
;
10319 vaddr
= local_vaddr
;
10324 * Check whether this task is allowed to have
10328 prot
= entry
->protection
;
10330 if (override_nx(old_map
, entry
->alias
) && prot
) {
10332 * HACK -- if not a stack, then allow execution
10334 prot
|= VM_PROT_EXECUTE
;
10337 if (mask_protections
) {
10338 fault_type
&= prot
;
10339 if (fault_type
== VM_PROT_NONE
) {
10340 goto protection_failure
;
10343 if ((fault_type
& (prot
)) != fault_type
) {
10344 protection_failure
:
10345 if (*real_map
!= map
) {
10346 vm_map_unlock(*real_map
);
10350 if ((fault_type
& VM_PROT_EXECUTE
) && prot
)
10351 log_stack_execution_failure((addr64_t
)vaddr
, prot
);
10353 DTRACE_VM2(prot_fault
, int, 1, (uint64_t *), NULL
);
10354 return KERN_PROTECTION_FAILURE
;
10358 * If this page is not pageable, we have to get
10359 * it for all possible accesses.
10362 *wired
= (entry
->wired_count
!= 0);
10367 * If the entry was copy-on-write, we either ...
10370 if (entry
->needs_copy
) {
10372 * If we want to write the page, we may as well
10373 * handle that now since we've got the map locked.
10375 * If we don't need to write the page, we just
10376 * demote the permissions allowed.
10379 if ((fault_type
& VM_PROT_WRITE
) || *wired
|| force_copy
) {
10381 * Make a new object, and place it in the
10382 * object chain. Note that no new references
10383 * have appeared -- one just moved from the
10384 * map to the new object.
10387 if (vm_map_lock_read_to_write(map
)) {
10388 vm_map_lock_read(map
);
10391 vm_object_shadow(&entry
->object
.vm_object
,
10393 (vm_map_size_t
) (entry
->vme_end
-
10394 entry
->vme_start
));
10396 entry
->object
.vm_object
->shadowed
= TRUE
;
10397 entry
->needs_copy
= FALSE
;
10398 vm_map_lock_write_to_read(map
);
10402 * We're attempting to read a copy-on-write
10403 * page -- don't allow writes.
10406 prot
&= (~VM_PROT_WRITE
);
10411 * Create an object if necessary.
10413 if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
10415 if (vm_map_lock_read_to_write(map
)) {
10416 vm_map_lock_read(map
);
10420 entry
->object
.vm_object
= vm_object_allocate(
10421 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
10423 vm_map_lock_write_to_read(map
);
10427 * Return the object/offset from this entry. If the entry
10428 * was copy-on-write or empty, it has been fixed up. Also
10429 * return the protection.
10432 *offset
= (vaddr
- entry
->vme_start
) + entry
->offset
;
10433 *object
= entry
->object
.vm_object
;
10437 fault_info
->interruptible
= THREAD_UNINT
; /* for now... */
10438 /* ... the caller will change "interruptible" if needed */
10439 fault_info
->cluster_size
= 0;
10440 fault_info
->user_tag
= entry
->alias
;
10441 fault_info
->pmap_options
= 0;
10442 if (entry
->iokit_acct
||
10443 (!entry
->is_sub_map
&& !entry
->use_pmap
)) {
10444 fault_info
->pmap_options
|= PMAP_OPTIONS_ALT_ACCT
;
10446 fault_info
->behavior
= entry
->behavior
;
10447 fault_info
->lo_offset
= entry
->offset
;
10448 fault_info
->hi_offset
= (entry
->vme_end
- entry
->vme_start
) + entry
->offset
;
10449 fault_info
->no_cache
= entry
->no_cache
;
10450 fault_info
->stealth
= FALSE
;
10451 fault_info
->io_sync
= FALSE
;
10452 fault_info
->cs_bypass
= (entry
->used_for_jit
)? TRUE
: FALSE
;
10453 fault_info
->mark_zf_absent
= FALSE
;
10454 fault_info
->batch_pmap_op
= FALSE
;
10458 * Lock the object to prevent it from disappearing
10460 if (object_lock_type
== OBJECT_LOCK_EXCLUSIVE
)
10461 vm_object_lock(*object
);
10463 vm_object_lock_shared(*object
);
10466 * Save the version number
10469 out_version
->main_timestamp
= map
->timestamp
;
10471 return KERN_SUCCESS
;
10478 * Verifies that the map in question has not changed
10479 * since the given version. If successful, the map
10480 * will not change until vm_map_verify_done() is called.
10484 register vm_map_t map
,
10485 register vm_map_version_t
*version
) /* REF */
10489 vm_map_lock_read(map
);
10490 result
= (map
->timestamp
== version
->main_timestamp
);
10493 vm_map_unlock_read(map
);
10499 * vm_map_verify_done:
10501 * Releases locks acquired by a vm_map_verify.
10503 * This is now a macro in vm/vm_map.h. It does a
10504 * vm_map_unlock_read on the map.
10509 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
10510 * Goes away after regular vm_region_recurse function migrates to
10512 * vm_region_recurse: A form of vm_region which follows the
10513 * submaps in a target map
10518 vm_map_region_recurse_64(
10520 vm_map_offset_t
*address
, /* IN/OUT */
10521 vm_map_size_t
*size
, /* OUT */
10522 natural_t
*nesting_depth
, /* IN/OUT */
10523 vm_region_submap_info_64_t submap_info
, /* IN/OUT */
10524 mach_msg_type_number_t
*count
) /* IN/OUT */
10526 mach_msg_type_number_t original_count
;
10527 vm_region_extended_info_data_t extended
;
10528 vm_map_entry_t tmp_entry
;
10529 vm_map_offset_t user_address
;
10530 unsigned int user_max_depth
;
10533 * "curr_entry" is the VM map entry preceding or including the
10534 * address we're looking for.
10535 * "curr_map" is the map or sub-map containing "curr_entry".
10536 * "curr_address" is the equivalent of the top map's "user_address"
10537 * in the current map.
10538 * "curr_offset" is the cumulated offset of "curr_map" in the
10539 * target task's address space.
10540 * "curr_depth" is the depth of "curr_map" in the chain of
10543 * "curr_max_below" and "curr_max_above" limit the range (around
10544 * "curr_address") we should take into account in the current (sub)map.
10545 * They limit the range to what's visible through the map entries
10546 * we've traversed from the top map to the current map.
10549 vm_map_entry_t curr_entry
;
10550 vm_map_address_t curr_address
;
10551 vm_map_offset_t curr_offset
;
10553 unsigned int curr_depth
;
10554 vm_map_offset_t curr_max_below
, curr_max_above
;
10555 vm_map_offset_t curr_skip
;
10558 * "next_" is the same as "curr_" but for the VM region immediately
10559 * after the address we're looking for. We need to keep track of this
10560 * too because we want to return info about that region if the
10561 * address we're looking for is not mapped.
10563 vm_map_entry_t next_entry
;
10564 vm_map_offset_t next_offset
;
10565 vm_map_offset_t next_address
;
10567 unsigned int next_depth
;
10568 vm_map_offset_t next_max_below
, next_max_above
;
10569 vm_map_offset_t next_skip
;
10571 boolean_t look_for_pages
;
10572 vm_region_submap_short_info_64_t short_info
;
10574 if (map
== VM_MAP_NULL
) {
10575 /* no address space to work on */
10576 return KERN_INVALID_ARGUMENT
;
10580 if (*count
< VM_REGION_SUBMAP_SHORT_INFO_COUNT_64
) {
10582 * "info" structure is not big enough and
10585 return KERN_INVALID_ARGUMENT
;
10588 original_count
= *count
;
10590 if (original_count
< VM_REGION_SUBMAP_INFO_V0_COUNT_64
) {
10591 *count
= VM_REGION_SUBMAP_SHORT_INFO_COUNT_64
;
10592 look_for_pages
= FALSE
;
10593 short_info
= (vm_region_submap_short_info_64_t
) submap_info
;
10594 submap_info
= NULL
;
10596 look_for_pages
= TRUE
;
10597 *count
= VM_REGION_SUBMAP_INFO_V0_COUNT_64
;
10600 if (original_count
>= VM_REGION_SUBMAP_INFO_V1_COUNT_64
) {
10601 *count
= VM_REGION_SUBMAP_INFO_V1_COUNT_64
;
10605 user_address
= *address
;
10606 user_max_depth
= *nesting_depth
;
10610 curr_address
= user_address
;
10614 curr_max_above
= ((vm_map_offset_t
) -1) - curr_address
;
10615 curr_max_below
= curr_address
;
10623 next_max_above
= (vm_map_offset_t
) -1;
10624 next_max_below
= (vm_map_offset_t
) -1;
10627 vm_map_lock_read(curr_map
);
10631 if (vm_map_lookup_entry(curr_map
,
10634 /* tmp_entry contains the address we're looking for */
10635 curr_entry
= tmp_entry
;
10637 vm_map_offset_t skip
;
10639 * The address is not mapped. "tmp_entry" is the
10640 * map entry preceding the address. We want the next
10641 * one, if it exists.
10643 curr_entry
= tmp_entry
->vme_next
;
10645 if (curr_entry
== vm_map_to_entry(curr_map
) ||
10646 (curr_entry
->vme_start
>=
10647 curr_address
+ curr_max_above
)) {
10648 /* no next entry at this level: stop looking */
10650 vm_map_unlock_read(curr_map
);
10656 curr_max_above
= 0;
10657 curr_max_below
= 0;
10661 /* adjust current address and offset */
10662 skip
= curr_entry
->vme_start
- curr_address
;
10663 curr_address
= curr_entry
->vme_start
;
10665 curr_offset
+= skip
;
10666 curr_max_above
-= skip
;
10667 curr_max_below
= 0;
10671 * Is the next entry at this level closer to the address (or
10672 * deeper in the submap chain) than the one we had
10675 tmp_entry
= curr_entry
->vme_next
;
10676 if (tmp_entry
== vm_map_to_entry(curr_map
)) {
10677 /* no next entry at this level */
10678 } else if (tmp_entry
->vme_start
>=
10679 curr_address
+ curr_max_above
) {
10681 * tmp_entry is beyond the scope of what we mapped of
10682 * this submap in the upper level: ignore it.
10684 } else if ((next_entry
== NULL
) ||
10685 (tmp_entry
->vme_start
+ curr_offset
<=
10686 next_entry
->vme_start
+ next_offset
)) {
10688 * We didn't have a "next_entry" or this one is
10689 * closer to the address we're looking for:
10690 * use this "tmp_entry" as the new "next_entry".
10692 if (next_entry
!= NULL
) {
10693 /* unlock the last "next_map" */
10694 if (next_map
!= curr_map
&& not_in_kdp
) {
10695 vm_map_unlock_read(next_map
);
10698 next_entry
= tmp_entry
;
10699 next_map
= curr_map
;
10700 next_depth
= curr_depth
;
10701 next_address
= next_entry
->vme_start
;
10702 next_skip
= curr_skip
;
10703 next_offset
= curr_offset
;
10704 next_offset
+= (next_address
- curr_address
);
10705 next_max_above
= MIN(next_max_above
, curr_max_above
);
10706 next_max_above
= MIN(next_max_above
,
10707 next_entry
->vme_end
- next_address
);
10708 next_max_below
= MIN(next_max_below
, curr_max_below
);
10709 next_max_below
= MIN(next_max_below
,
10710 next_address
- next_entry
->vme_start
);
10714 * "curr_max_{above,below}" allow us to keep track of the
10715 * portion of the submap that is actually mapped at this level:
10716 * the rest of that submap is irrelevant to us, since it's not
10718 * The relevant portion of the map starts at
10719 * "curr_entry->offset" up to the size of "curr_entry".
10721 curr_max_above
= MIN(curr_max_above
,
10722 curr_entry
->vme_end
- curr_address
);
10723 curr_max_below
= MIN(curr_max_below
,
10724 curr_address
- curr_entry
->vme_start
);
10726 if (!curr_entry
->is_sub_map
||
10727 curr_depth
>= user_max_depth
) {
10729 * We hit a leaf map or we reached the maximum depth
10730 * we could, so stop looking. Keep the current map
10737 * Get down to the next submap level.
10741 * Lock the next level and unlock the current level,
10742 * unless we need to keep it locked to access the "next_entry"
10746 vm_map_lock_read(curr_entry
->object
.sub_map
);
10748 if (curr_map
== next_map
) {
10749 /* keep "next_map" locked in case we need it */
10751 /* release this map */
10753 vm_map_unlock_read(curr_map
);
10757 * Adjust the offset. "curr_entry" maps the submap
10758 * at relative address "curr_entry->vme_start" in the
10759 * curr_map but skips the first "curr_entry->offset"
10760 * bytes of the submap.
10761 * "curr_offset" always represents the offset of a virtual
10762 * address in the curr_map relative to the absolute address
10763 * space (i.e. the top-level VM map).
10766 (curr_entry
->offset
- curr_entry
->vme_start
);
10767 curr_address
= user_address
+ curr_offset
;
10768 /* switch to the submap */
10769 curr_map
= curr_entry
->object
.sub_map
;
10774 if (curr_entry
== NULL
) {
10775 /* no VM region contains the address... */
10776 if (next_entry
== NULL
) {
10777 /* ... and no VM region follows it either */
10778 return KERN_INVALID_ADDRESS
;
10780 /* ... gather info about the next VM region */
10781 curr_entry
= next_entry
;
10782 curr_map
= next_map
; /* still locked ... */
10783 curr_address
= next_address
;
10784 curr_skip
= next_skip
;
10785 curr_offset
= next_offset
;
10786 curr_depth
= next_depth
;
10787 curr_max_above
= next_max_above
;
10788 curr_max_below
= next_max_below
;
10789 if (curr_map
== map
) {
10790 user_address
= curr_address
;
10793 /* we won't need "next_entry" after all */
10794 if (next_entry
!= NULL
) {
10795 /* release "next_map" */
10796 if (next_map
!= curr_map
&& not_in_kdp
) {
10797 vm_map_unlock_read(next_map
);
10806 next_max_below
= -1;
10807 next_max_above
= -1;
10809 *nesting_depth
= curr_depth
;
10810 *size
= curr_max_above
+ curr_max_below
;
10811 *address
= user_address
+ curr_skip
- curr_max_below
;
10813 // LP64todo: all the current tools are 32bit, obviously never worked for 64b
10814 // so probably should be a real 32b ID vs. ptr.
10815 // Current users just check for equality
10816 #define INFO_MAKE_OBJECT_ID(p) ((uint32_t)(uintptr_t)VM_KERNEL_ADDRPERM(p))
10818 if (look_for_pages
) {
10819 submap_info
->user_tag
= curr_entry
->alias
;
10820 submap_info
->offset
= curr_entry
->offset
;
10821 submap_info
->protection
= curr_entry
->protection
;
10822 submap_info
->inheritance
= curr_entry
->inheritance
;
10823 submap_info
->max_protection
= curr_entry
->max_protection
;
10824 submap_info
->behavior
= curr_entry
->behavior
;
10825 submap_info
->user_wired_count
= curr_entry
->user_wired_count
;
10826 submap_info
->is_submap
= curr_entry
->is_sub_map
;
10827 submap_info
->object_id
= INFO_MAKE_OBJECT_ID(curr_entry
->object
.vm_object
);
10829 short_info
->user_tag
= curr_entry
->alias
;
10830 short_info
->offset
= curr_entry
->offset
;
10831 short_info
->protection
= curr_entry
->protection
;
10832 short_info
->inheritance
= curr_entry
->inheritance
;
10833 short_info
->max_protection
= curr_entry
->max_protection
;
10834 short_info
->behavior
= curr_entry
->behavior
;
10835 short_info
->user_wired_count
= curr_entry
->user_wired_count
;
10836 short_info
->is_submap
= curr_entry
->is_sub_map
;
10837 short_info
->object_id
= INFO_MAKE_OBJECT_ID(curr_entry
->object
.vm_object
);
10840 extended
.pages_resident
= 0;
10841 extended
.pages_swapped_out
= 0;
10842 extended
.pages_shared_now_private
= 0;
10843 extended
.pages_dirtied
= 0;
10844 extended
.pages_reusable
= 0;
10845 extended
.external_pager
= 0;
10846 extended
.shadow_depth
= 0;
10849 if (!curr_entry
->is_sub_map
) {
10850 vm_map_offset_t range_start
, range_end
;
10851 range_start
= MAX((curr_address
- curr_max_below
),
10852 curr_entry
->vme_start
);
10853 range_end
= MIN((curr_address
+ curr_max_above
),
10854 curr_entry
->vme_end
);
10855 vm_map_region_walk(curr_map
,
10858 (curr_entry
->offset
+
10860 curr_entry
->vme_start
)),
10861 range_end
- range_start
,
10863 look_for_pages
, VM_REGION_EXTENDED_INFO_COUNT
);
10864 if (extended
.external_pager
&&
10865 extended
.ref_count
== 2 &&
10866 extended
.share_mode
== SM_SHARED
) {
10867 extended
.share_mode
= SM_PRIVATE
;
10870 if (curr_entry
->use_pmap
) {
10871 extended
.share_mode
= SM_TRUESHARED
;
10873 extended
.share_mode
= SM_PRIVATE
;
10875 extended
.ref_count
=
10876 curr_entry
->object
.sub_map
->ref_count
;
10880 if (look_for_pages
) {
10881 submap_info
->pages_resident
= extended
.pages_resident
;
10882 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
10883 submap_info
->pages_shared_now_private
=
10884 extended
.pages_shared_now_private
;
10885 submap_info
->pages_dirtied
= extended
.pages_dirtied
;
10886 submap_info
->external_pager
= extended
.external_pager
;
10887 submap_info
->shadow_depth
= extended
.shadow_depth
;
10888 submap_info
->share_mode
= extended
.share_mode
;
10889 submap_info
->ref_count
= extended
.ref_count
;
10891 if (original_count
>= VM_REGION_SUBMAP_INFO_V1_COUNT_64
) {
10892 submap_info
->pages_reusable
= extended
.pages_reusable
;
10895 short_info
->external_pager
= extended
.external_pager
;
10896 short_info
->shadow_depth
= extended
.shadow_depth
;
10897 short_info
->share_mode
= extended
.share_mode
;
10898 short_info
->ref_count
= extended
.ref_count
;
10902 vm_map_unlock_read(curr_map
);
10905 return KERN_SUCCESS
;
10911 * User call to obtain information about a region in
10912 * a task's address map. Currently, only one flavor is
10915 * XXX The reserved and behavior fields cannot be filled
10916 * in until the vm merge from the IK is completed, and
10917 * vm_reserve is implemented.
10923 vm_map_offset_t
*address
, /* IN/OUT */
10924 vm_map_size_t
*size
, /* OUT */
10925 vm_region_flavor_t flavor
, /* IN */
10926 vm_region_info_t info
, /* OUT */
10927 mach_msg_type_number_t
*count
, /* IN/OUT */
10928 mach_port_t
*object_name
) /* OUT */
10930 vm_map_entry_t tmp_entry
;
10931 vm_map_entry_t entry
;
10932 vm_map_offset_t start
;
10934 if (map
== VM_MAP_NULL
)
10935 return(KERN_INVALID_ARGUMENT
);
10939 case VM_REGION_BASIC_INFO
:
10940 /* legacy for old 32-bit objects info */
10942 vm_region_basic_info_t basic
;
10944 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
10945 return(KERN_INVALID_ARGUMENT
);
10947 basic
= (vm_region_basic_info_t
) info
;
10948 *count
= VM_REGION_BASIC_INFO_COUNT
;
10950 vm_map_lock_read(map
);
10953 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
10954 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
10955 vm_map_unlock_read(map
);
10956 return(KERN_INVALID_ADDRESS
);
10962 start
= entry
->vme_start
;
10964 basic
->offset
= (uint32_t)entry
->offset
;
10965 basic
->protection
= entry
->protection
;
10966 basic
->inheritance
= entry
->inheritance
;
10967 basic
->max_protection
= entry
->max_protection
;
10968 basic
->behavior
= entry
->behavior
;
10969 basic
->user_wired_count
= entry
->user_wired_count
;
10970 basic
->reserved
= entry
->is_sub_map
;
10972 *size
= (entry
->vme_end
- start
);
10974 if (object_name
) *object_name
= IP_NULL
;
10975 if (entry
->is_sub_map
) {
10976 basic
->shared
= FALSE
;
10978 basic
->shared
= entry
->is_shared
;
10981 vm_map_unlock_read(map
);
10982 return(KERN_SUCCESS
);
10985 case VM_REGION_BASIC_INFO_64
:
10987 vm_region_basic_info_64_t basic
;
10989 if (*count
< VM_REGION_BASIC_INFO_COUNT_64
)
10990 return(KERN_INVALID_ARGUMENT
);
10992 basic
= (vm_region_basic_info_64_t
) info
;
10993 *count
= VM_REGION_BASIC_INFO_COUNT_64
;
10995 vm_map_lock_read(map
);
10998 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
10999 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
11000 vm_map_unlock_read(map
);
11001 return(KERN_INVALID_ADDRESS
);
11007 start
= entry
->vme_start
;
11009 basic
->offset
= entry
->offset
;
11010 basic
->protection
= entry
->protection
;
11011 basic
->inheritance
= entry
->inheritance
;
11012 basic
->max_protection
= entry
->max_protection
;
11013 basic
->behavior
= entry
->behavior
;
11014 basic
->user_wired_count
= entry
->user_wired_count
;
11015 basic
->reserved
= entry
->is_sub_map
;
11017 *size
= (entry
->vme_end
- start
);
11019 if (object_name
) *object_name
= IP_NULL
;
11020 if (entry
->is_sub_map
) {
11021 basic
->shared
= FALSE
;
11023 basic
->shared
= entry
->is_shared
;
11026 vm_map_unlock_read(map
);
11027 return(KERN_SUCCESS
);
11029 case VM_REGION_EXTENDED_INFO
:
11030 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
11031 return(KERN_INVALID_ARGUMENT
);
11033 case VM_REGION_EXTENDED_INFO__legacy
:
11034 if (*count
< VM_REGION_EXTENDED_INFO_COUNT__legacy
)
11035 return KERN_INVALID_ARGUMENT
;
11038 vm_region_extended_info_t extended
;
11039 mach_msg_type_number_t original_count
;
11041 extended
= (vm_region_extended_info_t
) info
;
11043 vm_map_lock_read(map
);
11046 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
11047 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
11048 vm_map_unlock_read(map
);
11049 return(KERN_INVALID_ADDRESS
);
11054 start
= entry
->vme_start
;
11056 extended
->protection
= entry
->protection
;
11057 extended
->user_tag
= entry
->alias
;
11058 extended
->pages_resident
= 0;
11059 extended
->pages_swapped_out
= 0;
11060 extended
->pages_shared_now_private
= 0;
11061 extended
->pages_dirtied
= 0;
11062 extended
->external_pager
= 0;
11063 extended
->shadow_depth
= 0;
11065 original_count
= *count
;
11066 if (flavor
== VM_REGION_EXTENDED_INFO__legacy
) {
11067 *count
= VM_REGION_EXTENDED_INFO_COUNT__legacy
;
11069 extended
->pages_reusable
= 0;
11070 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
11073 vm_map_region_walk(map
, start
, entry
, entry
->offset
, entry
->vme_end
- start
, extended
, TRUE
, *count
);
11075 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
11076 extended
->share_mode
= SM_PRIVATE
;
11079 *object_name
= IP_NULL
;
11081 *size
= (entry
->vme_end
- start
);
11083 vm_map_unlock_read(map
);
11084 return(KERN_SUCCESS
);
11086 case VM_REGION_TOP_INFO
:
11088 vm_region_top_info_t top
;
11090 if (*count
< VM_REGION_TOP_INFO_COUNT
)
11091 return(KERN_INVALID_ARGUMENT
);
11093 top
= (vm_region_top_info_t
) info
;
11094 *count
= VM_REGION_TOP_INFO_COUNT
;
11096 vm_map_lock_read(map
);
11099 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
11100 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
11101 vm_map_unlock_read(map
);
11102 return(KERN_INVALID_ADDRESS
);
11108 start
= entry
->vme_start
;
11110 top
->private_pages_resident
= 0;
11111 top
->shared_pages_resident
= 0;
11113 vm_map_region_top_walk(entry
, top
);
11116 *object_name
= IP_NULL
;
11118 *size
= (entry
->vme_end
- start
);
11120 vm_map_unlock_read(map
);
11121 return(KERN_SUCCESS
);
11124 return(KERN_INVALID_ARGUMENT
);
11128 #define OBJ_RESIDENT_COUNT(obj, entry_size) \
11129 MIN((entry_size), \
11130 ((obj)->all_reusable ? \
11131 (obj)->wired_page_count : \
11132 (obj)->resident_page_count - (obj)->reusable_page_count))
11135 vm_map_region_top_walk(
11136 vm_map_entry_t entry
,
11137 vm_region_top_info_t top
)
11140 if (entry
->object
.vm_object
== 0 || entry
->is_sub_map
) {
11141 top
->share_mode
= SM_EMPTY
;
11142 top
->ref_count
= 0;
11148 struct vm_object
*obj
, *tmp_obj
;
11150 uint32_t entry_size
;
11152 entry_size
= (uint32_t) ((entry
->vme_end
- entry
->vme_start
) / PAGE_SIZE_64
);
11154 obj
= entry
->object
.vm_object
;
11156 vm_object_lock(obj
);
11158 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
11161 assert(obj
->reusable_page_count
<= obj
->resident_page_count
);
11163 if (ref_count
== 1)
11164 top
->private_pages_resident
=
11165 OBJ_RESIDENT_COUNT(obj
, entry_size
);
11167 top
->shared_pages_resident
=
11168 OBJ_RESIDENT_COUNT(obj
, entry_size
);
11169 top
->ref_count
= ref_count
;
11170 top
->share_mode
= SM_COW
;
11172 while ((tmp_obj
= obj
->shadow
)) {
11173 vm_object_lock(tmp_obj
);
11174 vm_object_unlock(obj
);
11177 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
11180 assert(obj
->reusable_page_count
<= obj
->resident_page_count
);
11181 top
->shared_pages_resident
+=
11182 OBJ_RESIDENT_COUNT(obj
, entry_size
);
11183 top
->ref_count
+= ref_count
- 1;
11186 if (entry
->superpage_size
) {
11187 top
->share_mode
= SM_LARGE_PAGE
;
11188 top
->shared_pages_resident
= 0;
11189 top
->private_pages_resident
= entry_size
;
11190 } else if (entry
->needs_copy
) {
11191 top
->share_mode
= SM_COW
;
11192 top
->shared_pages_resident
=
11193 OBJ_RESIDENT_COUNT(obj
, entry_size
);
11195 if (ref_count
== 1 ||
11196 (ref_count
== 2 && !(obj
->pager_trusted
) && !(obj
->internal
))) {
11197 top
->share_mode
= SM_PRIVATE
;
11198 top
->private_pages_resident
=
11199 OBJ_RESIDENT_COUNT(obj
,
11202 top
->share_mode
= SM_SHARED
;
11203 top
->shared_pages_resident
=
11204 OBJ_RESIDENT_COUNT(obj
,
11208 top
->ref_count
= ref_count
;
11210 /* XXX K64: obj_id will be truncated */
11211 top
->obj_id
= (unsigned int) (uintptr_t)VM_KERNEL_ADDRPERM(obj
);
11213 vm_object_unlock(obj
);
11218 vm_map_region_walk(
11220 vm_map_offset_t va
,
11221 vm_map_entry_t entry
,
11222 vm_object_offset_t offset
,
11223 vm_object_size_t range
,
11224 vm_region_extended_info_t extended
,
11225 boolean_t look_for_pages
,
11226 mach_msg_type_number_t count
)
11228 register struct vm_object
*obj
, *tmp_obj
;
11229 register vm_map_offset_t last_offset
;
11231 register int ref_count
;
11232 struct vm_object
*shadow_object
;
11235 if ((entry
->object
.vm_object
== 0) ||
11236 (entry
->is_sub_map
) ||
11237 (entry
->object
.vm_object
->phys_contiguous
&&
11238 !entry
->superpage_size
)) {
11239 extended
->share_mode
= SM_EMPTY
;
11240 extended
->ref_count
= 0;
11244 if (entry
->superpage_size
) {
11245 extended
->shadow_depth
= 0;
11246 extended
->share_mode
= SM_LARGE_PAGE
;
11247 extended
->ref_count
= 1;
11248 extended
->external_pager
= 0;
11249 extended
->pages_resident
= (unsigned int)(range
>> PAGE_SHIFT
);
11250 extended
->shadow_depth
= 0;
11255 obj
= entry
->object
.vm_object
;
11257 vm_object_lock(obj
);
11259 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
11262 if (look_for_pages
) {
11263 for (last_offset
= offset
+ range
;
11264 offset
< last_offset
;
11265 offset
+= PAGE_SIZE_64
, va
+= PAGE_SIZE
) {
11266 vm_map_region_look_for_page(map
, va
, obj
,
11268 0, extended
, count
);
11271 shadow_object
= obj
->shadow
;
11274 if ( !(obj
->pager_trusted
) && !(obj
->internal
))
11275 extended
->external_pager
= 1;
11277 if (shadow_object
!= VM_OBJECT_NULL
) {
11278 vm_object_lock(shadow_object
);
11280 shadow_object
!= VM_OBJECT_NULL
;
11282 vm_object_t next_shadow
;
11284 if ( !(shadow_object
->pager_trusted
) &&
11285 !(shadow_object
->internal
))
11286 extended
->external_pager
= 1;
11288 next_shadow
= shadow_object
->shadow
;
11290 vm_object_lock(next_shadow
);
11292 vm_object_unlock(shadow_object
);
11293 shadow_object
= next_shadow
;
11296 extended
->shadow_depth
= shadow_depth
;
11299 if (extended
->shadow_depth
|| entry
->needs_copy
)
11300 extended
->share_mode
= SM_COW
;
11302 if (ref_count
== 1)
11303 extended
->share_mode
= SM_PRIVATE
;
11305 if (obj
->true_share
)
11306 extended
->share_mode
= SM_TRUESHARED
;
11308 extended
->share_mode
= SM_SHARED
;
11311 extended
->ref_count
= ref_count
- extended
->shadow_depth
;
11313 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
11314 if ((tmp_obj
= obj
->shadow
) == 0)
11316 vm_object_lock(tmp_obj
);
11317 vm_object_unlock(obj
);
11319 if ((ref_count
= tmp_obj
->ref_count
) > 1 && tmp_obj
->paging_in_progress
)
11322 extended
->ref_count
+= ref_count
;
11325 vm_object_unlock(obj
);
11327 if (extended
->share_mode
== SM_SHARED
) {
11328 register vm_map_entry_t cur
;
11329 register vm_map_entry_t last
;
11332 obj
= entry
->object
.vm_object
;
11333 last
= vm_map_to_entry(map
);
11336 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
11338 for (cur
= vm_map_first_entry(map
); cur
!= last
; cur
= cur
->vme_next
)
11339 my_refs
+= vm_map_region_count_obj_refs(cur
, obj
);
11341 if (my_refs
== ref_count
)
11342 extended
->share_mode
= SM_PRIVATE_ALIASED
;
11343 else if (my_refs
> 1)
11344 extended
->share_mode
= SM_SHARED_ALIASED
;
11350 /* object is locked on entry and locked on return */
11354 vm_map_region_look_for_page(
11355 __unused vm_map_t map
,
11356 __unused vm_map_offset_t va
,
11357 vm_object_t object
,
11358 vm_object_offset_t offset
,
11361 vm_region_extended_info_t extended
,
11362 mach_msg_type_number_t count
)
11364 register vm_page_t p
;
11365 register vm_object_t shadow
;
11366 register int ref_count
;
11367 vm_object_t caller_object
;
11369 shadow
= object
->shadow
;
11370 caller_object
= object
;
11375 if ( !(object
->pager_trusted
) && !(object
->internal
))
11376 extended
->external_pager
= 1;
11378 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
11379 if (shadow
&& (max_refcnt
== 1))
11380 extended
->pages_shared_now_private
++;
11382 if (!p
->fictitious
&&
11383 (p
->dirty
|| pmap_is_modified(p
->phys_page
)))
11384 extended
->pages_dirtied
++;
11385 else if (count
>= VM_REGION_EXTENDED_INFO_COUNT
) {
11386 if (p
->reusable
|| p
->object
->all_reusable
) {
11387 extended
->pages_reusable
++;
11391 extended
->pages_resident
++;
11393 if(object
!= caller_object
)
11394 vm_object_unlock(object
);
11399 if (object
->existence_map
) {
11400 if (vm_external_state_get(object
->existence_map
, offset
) == VM_EXTERNAL_STATE_EXISTS
) {
11402 extended
->pages_swapped_out
++;
11404 if(object
!= caller_object
)
11405 vm_object_unlock(object
);
11410 #endif /* MACH_PAGEMAP */
11411 if (object
->internal
&&
11413 !object
->terminating
&&
11414 object
->pager_ready
) {
11416 if (COMPRESSED_PAGER_IS_ACTIVE
|| DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE
) {
11417 if (VM_COMPRESSOR_PAGER_STATE_GET(object
,
11419 == VM_EXTERNAL_STATE_EXISTS
) {
11420 /* the pager has that page */
11421 extended
->pages_swapped_out
++;
11422 if (object
!= caller_object
)
11423 vm_object_unlock(object
);
11427 memory_object_t pager
;
11429 vm_object_paging_begin(object
);
11430 pager
= object
->pager
;
11431 vm_object_unlock(object
);
11433 kr
= memory_object_data_request(
11435 offset
+ object
->paging_offset
,
11436 0, /* just poke the pager */
11440 vm_object_lock(object
);
11441 vm_object_paging_end(object
);
11443 if (kr
== KERN_SUCCESS
) {
11444 /* the pager has that page */
11445 extended
->pages_swapped_out
++;
11446 if (object
!= caller_object
)
11447 vm_object_unlock(object
);
11454 vm_object_lock(shadow
);
11456 if ((ref_count
= shadow
->ref_count
) > 1 && shadow
->paging_in_progress
)
11459 if (++depth
> extended
->shadow_depth
)
11460 extended
->shadow_depth
= depth
;
11462 if (ref_count
> max_refcnt
)
11463 max_refcnt
= ref_count
;
11465 if(object
!= caller_object
)
11466 vm_object_unlock(object
);
11468 offset
= offset
+ object
->vo_shadow_offset
;
11470 shadow
= object
->shadow
;
11473 if(object
!= caller_object
)
11474 vm_object_unlock(object
);
11480 vm_map_region_count_obj_refs(
11481 vm_map_entry_t entry
,
11482 vm_object_t object
)
11484 register int ref_count
;
11485 register vm_object_t chk_obj
;
11486 register vm_object_t tmp_obj
;
11488 if (entry
->object
.vm_object
== 0)
11491 if (entry
->is_sub_map
)
11496 chk_obj
= entry
->object
.vm_object
;
11497 vm_object_lock(chk_obj
);
11500 if (chk_obj
== object
)
11502 tmp_obj
= chk_obj
->shadow
;
11504 vm_object_lock(tmp_obj
);
11505 vm_object_unlock(chk_obj
);
11515 * Routine: vm_map_simplify
11518 * Attempt to simplify the map representation in
11519 * the vicinity of the given starting address.
11521 * This routine is intended primarily to keep the
11522 * kernel maps more compact -- they generally don't
11523 * benefit from the "expand a map entry" technology
11524 * at allocation time because the adjacent entry
11525 * is often wired down.
11528 vm_map_simplify_entry(
11530 vm_map_entry_t this_entry
)
11532 vm_map_entry_t prev_entry
;
11534 counter(c_vm_map_simplify_entry_called
++);
11536 prev_entry
= this_entry
->vme_prev
;
11538 if ((this_entry
!= vm_map_to_entry(map
)) &&
11539 (prev_entry
!= vm_map_to_entry(map
)) &&
11541 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
11543 (prev_entry
->is_sub_map
== this_entry
->is_sub_map
) &&
11544 (prev_entry
->object
.vm_object
== this_entry
->object
.vm_object
) &&
11545 ((prev_entry
->offset
+ (prev_entry
->vme_end
-
11546 prev_entry
->vme_start
))
11547 == this_entry
->offset
) &&
11549 (prev_entry
->behavior
== this_entry
->behavior
) &&
11550 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
11551 (prev_entry
->protection
== this_entry
->protection
) &&
11552 (prev_entry
->max_protection
== this_entry
->max_protection
) &&
11553 (prev_entry
->inheritance
== this_entry
->inheritance
) &&
11554 (prev_entry
->use_pmap
== this_entry
->use_pmap
) &&
11555 (prev_entry
->alias
== this_entry
->alias
) &&
11556 (prev_entry
->no_cache
== this_entry
->no_cache
) &&
11557 (prev_entry
->permanent
== this_entry
->permanent
) &&
11558 (prev_entry
->map_aligned
== this_entry
->map_aligned
) &&
11559 (prev_entry
->zero_wired_pages
== this_entry
->zero_wired_pages
) &&
11560 (prev_entry
->used_for_jit
== this_entry
->used_for_jit
) &&
11561 /* from_reserved_zone: OK if that field doesn't match */
11562 (prev_entry
->iokit_acct
== this_entry
->iokit_acct
) &&
11564 (prev_entry
->wired_count
== this_entry
->wired_count
) &&
11565 (prev_entry
->user_wired_count
== this_entry
->user_wired_count
) &&
11567 (prev_entry
->in_transition
== FALSE
) &&
11568 (this_entry
->in_transition
== FALSE
) &&
11569 (prev_entry
->needs_wakeup
== FALSE
) &&
11570 (this_entry
->needs_wakeup
== FALSE
) &&
11571 (prev_entry
->is_shared
== FALSE
) &&
11572 (this_entry
->is_shared
== FALSE
) &&
11573 (prev_entry
->superpage_size
== FALSE
) &&
11574 (this_entry
->superpage_size
== FALSE
)
11576 vm_map_store_entry_unlink(map
, prev_entry
);
11577 assert(prev_entry
->vme_start
< this_entry
->vme_end
);
11578 if (prev_entry
->map_aligned
)
11579 assert(VM_MAP_PAGE_ALIGNED(prev_entry
->vme_start
,
11580 VM_MAP_PAGE_MASK(map
)));
11581 this_entry
->vme_start
= prev_entry
->vme_start
;
11582 this_entry
->offset
= prev_entry
->offset
;
11583 if (prev_entry
->is_sub_map
) {
11584 vm_map_deallocate(prev_entry
->object
.sub_map
);
11586 vm_object_deallocate(prev_entry
->object
.vm_object
);
11588 vm_map_entry_dispose(map
, prev_entry
);
11589 SAVE_HINT_MAP_WRITE(map
, this_entry
);
11590 counter(c_vm_map_simplified
++);
11597 vm_map_offset_t start
)
11599 vm_map_entry_t this_entry
;
11602 if (vm_map_lookup_entry(map
, start
, &this_entry
)) {
11603 vm_map_simplify_entry(map
, this_entry
);
11604 vm_map_simplify_entry(map
, this_entry
->vme_next
);
11606 counter(c_vm_map_simplify_called
++);
11607 vm_map_unlock(map
);
11611 vm_map_simplify_range(
11613 vm_map_offset_t start
,
11614 vm_map_offset_t end
)
11616 vm_map_entry_t entry
;
11619 * The map should be locked (for "write") by the caller.
11622 if (start
>= end
) {
11623 /* invalid address range */
11627 start
= vm_map_trunc_page(start
,
11628 VM_MAP_PAGE_MASK(map
));
11629 end
= vm_map_round_page(end
,
11630 VM_MAP_PAGE_MASK(map
));
11632 if (!vm_map_lookup_entry(map
, start
, &entry
)) {
11633 /* "start" is not mapped and "entry" ends before "start" */
11634 if (entry
== vm_map_to_entry(map
)) {
11635 /* start with first entry in the map */
11636 entry
= vm_map_first_entry(map
);
11638 /* start with next entry */
11639 entry
= entry
->vme_next
;
11643 while (entry
!= vm_map_to_entry(map
) &&
11644 entry
->vme_start
<= end
) {
11645 /* try and coalesce "entry" with its previous entry */
11646 vm_map_simplify_entry(map
, entry
);
11647 entry
= entry
->vme_next
;
11653 * Routine: vm_map_machine_attribute
11655 * Provide machine-specific attributes to mappings,
11656 * such as cachability etc. for machines that provide
11657 * them. NUMA architectures and machines with big/strange
11658 * caches will use this.
11660 * Responsibilities for locking and checking are handled here,
11661 * everything else in the pmap module. If any non-volatile
11662 * information must be kept, the pmap module should handle
11663 * it itself. [This assumes that attributes do not
11664 * need to be inherited, which seems ok to me]
11667 vm_map_machine_attribute(
11669 vm_map_offset_t start
,
11670 vm_map_offset_t end
,
11671 vm_machine_attribute_t attribute
,
11672 vm_machine_attribute_val_t
* value
) /* IN/OUT */
11675 vm_map_size_t sync_size
;
11676 vm_map_entry_t entry
;
11678 if (start
< vm_map_min(map
) || end
> vm_map_max(map
))
11679 return KERN_INVALID_ADDRESS
;
11681 /* Figure how much memory we need to flush (in page increments) */
11682 sync_size
= end
- start
;
11686 if (attribute
!= MATTR_CACHE
) {
11687 /* If we don't have to find physical addresses, we */
11688 /* don't have to do an explicit traversal here. */
11689 ret
= pmap_attribute(map
->pmap
, start
, end
-start
,
11691 vm_map_unlock(map
);
11695 ret
= KERN_SUCCESS
; /* Assume it all worked */
11698 if (vm_map_lookup_entry(map
, start
, &entry
)) {
11699 vm_map_size_t sub_size
;
11700 if((entry
->vme_end
- start
) > sync_size
) {
11701 sub_size
= sync_size
;
11704 sub_size
= entry
->vme_end
- start
;
11705 sync_size
-= sub_size
;
11707 if(entry
->is_sub_map
) {
11708 vm_map_offset_t sub_start
;
11709 vm_map_offset_t sub_end
;
11711 sub_start
= (start
- entry
->vme_start
)
11713 sub_end
= sub_start
+ sub_size
;
11714 vm_map_machine_attribute(
11715 entry
->object
.sub_map
,
11720 if(entry
->object
.vm_object
) {
11722 vm_object_t object
;
11723 vm_object_t base_object
;
11724 vm_object_t last_object
;
11725 vm_object_offset_t offset
;
11726 vm_object_offset_t base_offset
;
11727 vm_map_size_t range
;
11729 offset
= (start
- entry
->vme_start
)
11731 base_offset
= offset
;
11732 object
= entry
->object
.vm_object
;
11733 base_object
= object
;
11734 last_object
= NULL
;
11736 vm_object_lock(object
);
11739 m
= vm_page_lookup(
11742 if (m
&& !m
->fictitious
) {
11744 pmap_attribute_cache_sync(
11749 } else if (object
->shadow
) {
11750 offset
= offset
+ object
->vo_shadow_offset
;
11751 last_object
= object
;
11752 object
= object
->shadow
;
11753 vm_object_lock(last_object
->shadow
);
11754 vm_object_unlock(last_object
);
11757 range
-= PAGE_SIZE
;
11759 if (base_object
!= object
) {
11760 vm_object_unlock(object
);
11761 vm_object_lock(base_object
);
11762 object
= base_object
;
11764 /* Bump to the next page */
11765 base_offset
+= PAGE_SIZE
;
11766 offset
= base_offset
;
11768 vm_object_unlock(object
);
11773 vm_map_unlock(map
);
11774 return KERN_FAILURE
;
11779 vm_map_unlock(map
);
11785 * vm_map_behavior_set:
11787 * Sets the paging reference behavior of the specified address
11788 * range in the target map. Paging reference behavior affects
11789 * how pagein operations resulting from faults on the map will be
11793 vm_map_behavior_set(
11795 vm_map_offset_t start
,
11796 vm_map_offset_t end
,
11797 vm_behavior_t new_behavior
)
11799 register vm_map_entry_t entry
;
11800 vm_map_entry_t temp_entry
;
11803 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
11804 map
, start
, end
, new_behavior
, 0);
11807 start
< vm_map_min(map
) ||
11808 end
> vm_map_max(map
)) {
11809 return KERN_NO_SPACE
;
11812 switch (new_behavior
) {
11815 * This first block of behaviors all set a persistent state on the specified
11816 * memory range. All we have to do here is to record the desired behavior
11817 * in the vm_map_entry_t's.
11820 case VM_BEHAVIOR_DEFAULT
:
11821 case VM_BEHAVIOR_RANDOM
:
11822 case VM_BEHAVIOR_SEQUENTIAL
:
11823 case VM_BEHAVIOR_RSEQNTL
:
11824 case VM_BEHAVIOR_ZERO_WIRED_PAGES
:
11828 * The entire address range must be valid for the map.
11829 * Note that vm_map_range_check() does a
11830 * vm_map_lookup_entry() internally and returns the
11831 * entry containing the start of the address range if
11832 * the entire range is valid.
11834 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
11835 entry
= temp_entry
;
11836 vm_map_clip_start(map
, entry
, start
);
11839 vm_map_unlock(map
);
11840 return(KERN_INVALID_ADDRESS
);
11843 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
11844 vm_map_clip_end(map
, entry
, end
);
11845 if (entry
->is_sub_map
) {
11846 assert(!entry
->use_pmap
);
11849 if( new_behavior
== VM_BEHAVIOR_ZERO_WIRED_PAGES
) {
11850 entry
->zero_wired_pages
= TRUE
;
11852 entry
->behavior
= new_behavior
;
11854 entry
= entry
->vme_next
;
11857 vm_map_unlock(map
);
11861 * The rest of these are different from the above in that they cause
11862 * an immediate action to take place as opposed to setting a behavior that
11863 * affects future actions.
11866 case VM_BEHAVIOR_WILLNEED
:
11867 return vm_map_willneed(map
, start
, end
);
11869 case VM_BEHAVIOR_DONTNEED
:
11870 return vm_map_msync(map
, start
, end
- start
, VM_SYNC_DEACTIVATE
| VM_SYNC_CONTIGUOUS
);
11872 case VM_BEHAVIOR_FREE
:
11873 return vm_map_msync(map
, start
, end
- start
, VM_SYNC_KILLPAGES
| VM_SYNC_CONTIGUOUS
);
11875 case VM_BEHAVIOR_REUSABLE
:
11876 return vm_map_reusable_pages(map
, start
, end
);
11878 case VM_BEHAVIOR_REUSE
:
11879 return vm_map_reuse_pages(map
, start
, end
);
11881 case VM_BEHAVIOR_CAN_REUSE
:
11882 return vm_map_can_reuse(map
, start
, end
);
11885 return(KERN_INVALID_ARGUMENT
);
11888 return(KERN_SUCCESS
);
11893 * Internals for madvise(MADV_WILLNEED) system call.
11895 * The present implementation is to do a read-ahead if the mapping corresponds
11896 * to a mapped regular file. If it's an anonymous mapping, then we do nothing
11897 * and basically ignore the "advice" (which we are always free to do).
11901 static kern_return_t
11904 vm_map_offset_t start
,
11905 vm_map_offset_t end
11908 vm_map_entry_t entry
;
11909 vm_object_t object
;
11910 memory_object_t pager
;
11911 struct vm_object_fault_info fault_info
;
11913 vm_object_size_t len
;
11914 vm_object_offset_t offset
;
11917 * Fill in static values in fault_info. Several fields get ignored by the code
11918 * we call, but we'll fill them in anyway since uninitialized fields are bad
11919 * when it comes to future backwards compatibility.
11922 fault_info
.interruptible
= THREAD_UNINT
; /* ignored value */
11923 fault_info
.behavior
= VM_BEHAVIOR_SEQUENTIAL
;
11924 fault_info
.no_cache
= FALSE
; /* ignored value */
11925 fault_info
.stealth
= TRUE
;
11926 fault_info
.io_sync
= FALSE
;
11927 fault_info
.cs_bypass
= FALSE
;
11928 fault_info
.mark_zf_absent
= FALSE
;
11929 fault_info
.batch_pmap_op
= FALSE
;
11932 * The MADV_WILLNEED operation doesn't require any changes to the
11933 * vm_map_entry_t's, so the read lock is sufficient.
11936 vm_map_lock_read(map
);
11939 * The madvise semantics require that the address range be fully
11940 * allocated with no holes. Otherwise, we're required to return
11944 if (! vm_map_range_check(map
, start
, end
, &entry
)) {
11945 vm_map_unlock_read(map
);
11946 return KERN_INVALID_ADDRESS
;
11950 * Examine each vm_map_entry_t in the range.
11952 for (; entry
!= vm_map_to_entry(map
) && start
< end
; ) {
11955 * The first time through, the start address could be anywhere
11956 * within the vm_map_entry we found. So adjust the offset to
11957 * correspond. After that, the offset will always be zero to
11958 * correspond to the beginning of the current vm_map_entry.
11960 offset
= (start
- entry
->vme_start
) + entry
->offset
;
11963 * Set the length so we don't go beyond the end of the
11964 * map_entry or beyond the end of the range we were given.
11965 * This range could span also multiple map entries all of which
11966 * map different files, so make sure we only do the right amount
11967 * of I/O for each object. Note that it's possible for there
11968 * to be multiple map entries all referring to the same object
11969 * but with different page permissions, but it's not worth
11970 * trying to optimize that case.
11972 len
= MIN(entry
->vme_end
- start
, end
- start
);
11974 if ((vm_size_t
) len
!= len
) {
11975 /* 32-bit overflow */
11976 len
= (vm_size_t
) (0 - PAGE_SIZE
);
11978 fault_info
.cluster_size
= (vm_size_t
) len
;
11979 fault_info
.lo_offset
= offset
;
11980 fault_info
.hi_offset
= offset
+ len
;
11981 fault_info
.user_tag
= entry
->alias
;
11982 fault_info
.pmap_options
= 0;
11983 if (entry
->iokit_acct
||
11984 (!entry
->is_sub_map
&& !entry
->use_pmap
)) {
11985 fault_info
.pmap_options
|= PMAP_OPTIONS_ALT_ACCT
;
11989 * If there's no read permission to this mapping, then just
11992 if ((entry
->protection
& VM_PROT_READ
) == 0) {
11993 entry
= entry
->vme_next
;
11994 start
= entry
->vme_start
;
11999 * Find the file object backing this map entry. If there is
12000 * none, then we simply ignore the "will need" advice for this
12001 * entry and go on to the next one.
12003 if ((object
= find_vnode_object(entry
)) == VM_OBJECT_NULL
) {
12004 entry
= entry
->vme_next
;
12005 start
= entry
->vme_start
;
12010 * The data_request() could take a long time, so let's
12011 * release the map lock to avoid blocking other threads.
12013 vm_map_unlock_read(map
);
12015 vm_object_paging_begin(object
);
12016 pager
= object
->pager
;
12017 vm_object_unlock(object
);
12020 * Get the data from the object asynchronously.
12022 * Note that memory_object_data_request() places limits on the
12023 * amount of I/O it will do. Regardless of the len we
12024 * specified, it won't do more than MAX_UPL_TRANSFER_BYTES and it
12025 * silently truncates the len to that size. This isn't
12026 * necessarily bad since madvise shouldn't really be used to
12027 * page in unlimited amounts of data. Other Unix variants
12028 * limit the willneed case as well. If this turns out to be an
12029 * issue for developers, then we can always adjust the policy
12030 * here and still be backwards compatible since this is all
12033 kr
= memory_object_data_request(
12035 offset
+ object
->paging_offset
,
12038 (memory_object_fault_info_t
)&fault_info
);
12040 vm_object_lock(object
);
12041 vm_object_paging_end(object
);
12042 vm_object_unlock(object
);
12045 * If we couldn't do the I/O for some reason, just give up on
12046 * the madvise. We still return success to the user since
12047 * madvise isn't supposed to fail when the advice can't be
12050 if (kr
!= KERN_SUCCESS
) {
12051 return KERN_SUCCESS
;
12055 if (start
>= end
) {
12057 return KERN_SUCCESS
;
12060 /* look up next entry */
12061 vm_map_lock_read(map
);
12062 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
12064 * There's a new hole in the address range.
12066 vm_map_unlock_read(map
);
12067 return KERN_INVALID_ADDRESS
;
12071 vm_map_unlock_read(map
);
12072 return KERN_SUCCESS
;
12076 vm_map_entry_is_reusable(
12077 vm_map_entry_t entry
)
12079 vm_object_t object
;
12081 switch (entry
->alias
) {
12082 case VM_MEMORY_MALLOC
:
12083 case VM_MEMORY_MALLOC_SMALL
:
12084 case VM_MEMORY_MALLOC_LARGE
:
12085 case VM_MEMORY_REALLOC
:
12086 case VM_MEMORY_MALLOC_TINY
:
12087 case VM_MEMORY_MALLOC_LARGE_REUSABLE
:
12088 case VM_MEMORY_MALLOC_LARGE_REUSED
:
12090 * This is a malloc() memory region: check if it's still
12091 * in its original state and can be re-used for more
12092 * malloc() allocations.
12097 * Not a malloc() memory region: let the caller decide if
12103 if (entry
->is_shared
||
12104 entry
->is_sub_map
||
12105 entry
->in_transition
||
12106 entry
->protection
!= VM_PROT_DEFAULT
||
12107 entry
->max_protection
!= VM_PROT_ALL
||
12108 entry
->inheritance
!= VM_INHERIT_DEFAULT
||
12110 entry
->permanent
||
12111 entry
->superpage_size
!= FALSE
||
12112 entry
->zero_wired_pages
||
12113 entry
->wired_count
!= 0 ||
12114 entry
->user_wired_count
!= 0) {
12118 object
= entry
->object
.vm_object
;
12119 if (object
== VM_OBJECT_NULL
) {
12125 * Let's proceed even if the VM object is potentially
12127 * We check for this later when processing the actual
12128 * VM pages, so the contents will be safe if shared.
12130 * But we can still mark this memory region as "reusable" to
12131 * acknowledge that the caller did let us know that the memory
12132 * could be re-used and should not be penalized for holding
12133 * on to it. This allows its "resident size" to not include
12134 * the reusable range.
12136 object
->ref_count
== 1 &&
12138 object
->wired_page_count
== 0 &&
12139 object
->copy
== VM_OBJECT_NULL
&&
12140 object
->shadow
== VM_OBJECT_NULL
&&
12141 object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
12142 object
->internal
&&
12143 !object
->true_share
&&
12144 object
->wimg_bits
== VM_WIMG_USE_DEFAULT
&&
12145 !object
->code_signed
) {
12153 static kern_return_t
12154 vm_map_reuse_pages(
12156 vm_map_offset_t start
,
12157 vm_map_offset_t end
)
12159 vm_map_entry_t entry
;
12160 vm_object_t object
;
12161 vm_object_offset_t start_offset
, end_offset
;
12164 * The MADV_REUSE operation doesn't require any changes to the
12165 * vm_map_entry_t's, so the read lock is sufficient.
12168 vm_map_lock_read(map
);
12171 * The madvise semantics require that the address range be fully
12172 * allocated with no holes. Otherwise, we're required to return
12176 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
12177 vm_map_unlock_read(map
);
12178 vm_page_stats_reusable
.reuse_pages_failure
++;
12179 return KERN_INVALID_ADDRESS
;
12183 * Examine each vm_map_entry_t in the range.
12185 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
12186 entry
= entry
->vme_next
) {
12188 * Sanity check on the VM map entry.
12190 if (! vm_map_entry_is_reusable(entry
)) {
12191 vm_map_unlock_read(map
);
12192 vm_page_stats_reusable
.reuse_pages_failure
++;
12193 return KERN_INVALID_ADDRESS
;
12197 * The first time through, the start address could be anywhere
12198 * within the vm_map_entry we found. So adjust the offset to
12201 if (entry
->vme_start
< start
) {
12202 start_offset
= start
- entry
->vme_start
;
12206 end_offset
= MIN(end
, entry
->vme_end
) - entry
->vme_start
;
12207 start_offset
+= entry
->offset
;
12208 end_offset
+= entry
->offset
;
12210 object
= entry
->object
.vm_object
;
12211 if (object
!= VM_OBJECT_NULL
) {
12212 vm_object_lock(object
);
12213 vm_object_reuse_pages(object
, start_offset
, end_offset
,
12215 vm_object_unlock(object
);
12218 if (entry
->alias
== VM_MEMORY_MALLOC_LARGE_REUSABLE
) {
12221 * We do not hold the VM map exclusively here.
12222 * The "alias" field is not that critical, so it's
12223 * safe to update it here, as long as it is the only
12224 * one that can be modified while holding the VM map
12227 entry
->alias
= VM_MEMORY_MALLOC_LARGE_REUSED
;
12231 vm_map_unlock_read(map
);
12232 vm_page_stats_reusable
.reuse_pages_success
++;
12233 return KERN_SUCCESS
;
12237 static kern_return_t
12238 vm_map_reusable_pages(
12240 vm_map_offset_t start
,
12241 vm_map_offset_t end
)
12243 vm_map_entry_t entry
;
12244 vm_object_t object
;
12245 vm_object_offset_t start_offset
, end_offset
;
12248 * The MADV_REUSABLE operation doesn't require any changes to the
12249 * vm_map_entry_t's, so the read lock is sufficient.
12252 vm_map_lock_read(map
);
12255 * The madvise semantics require that the address range be fully
12256 * allocated with no holes. Otherwise, we're required to return
12260 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
12261 vm_map_unlock_read(map
);
12262 vm_page_stats_reusable
.reusable_pages_failure
++;
12263 return KERN_INVALID_ADDRESS
;
12267 * Examine each vm_map_entry_t in the range.
12269 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
12270 entry
= entry
->vme_next
) {
12271 int kill_pages
= 0;
12274 * Sanity check on the VM map entry.
12276 if (! vm_map_entry_is_reusable(entry
)) {
12277 vm_map_unlock_read(map
);
12278 vm_page_stats_reusable
.reusable_pages_failure
++;
12279 return KERN_INVALID_ADDRESS
;
12283 * The first time through, the start address could be anywhere
12284 * within the vm_map_entry we found. So adjust the offset to
12287 if (entry
->vme_start
< start
) {
12288 start_offset
= start
- entry
->vme_start
;
12292 end_offset
= MIN(end
, entry
->vme_end
) - entry
->vme_start
;
12293 start_offset
+= entry
->offset
;
12294 end_offset
+= entry
->offset
;
12296 object
= entry
->object
.vm_object
;
12297 if (object
== VM_OBJECT_NULL
)
12301 vm_object_lock(object
);
12302 if (object
->ref_count
== 1 &&
12305 * "iokit_acct" entries are billed for their virtual size
12306 * (rather than for their resident pages only), so they
12307 * wouldn't benefit from making pages reusable, and it
12308 * would be hard to keep track of pages that are both
12309 * "iokit_acct" and "reusable" in the pmap stats and ledgers.
12311 !(entry
->iokit_acct
||
12312 (!entry
->is_sub_map
&& !entry
->use_pmap
)))
12316 if (kill_pages
!= -1) {
12317 vm_object_deactivate_pages(object
,
12319 end_offset
- start_offset
,
12321 TRUE
/*reusable_pages*/);
12323 vm_page_stats_reusable
.reusable_pages_shared
++;
12325 vm_object_unlock(object
);
12327 if (entry
->alias
== VM_MEMORY_MALLOC_LARGE
||
12328 entry
->alias
== VM_MEMORY_MALLOC_LARGE_REUSED
) {
12331 * We do not hold the VM map exclusively here.
12332 * The "alias" field is not that critical, so it's
12333 * safe to update it here, as long as it is the only
12334 * one that can be modified while holding the VM map
12337 entry
->alias
= VM_MEMORY_MALLOC_LARGE_REUSABLE
;
12341 vm_map_unlock_read(map
);
12342 vm_page_stats_reusable
.reusable_pages_success
++;
12343 return KERN_SUCCESS
;
12347 static kern_return_t
12350 vm_map_offset_t start
,
12351 vm_map_offset_t end
)
12353 vm_map_entry_t entry
;
12356 * The MADV_REUSABLE operation doesn't require any changes to the
12357 * vm_map_entry_t's, so the read lock is sufficient.
12360 vm_map_lock_read(map
);
12363 * The madvise semantics require that the address range be fully
12364 * allocated with no holes. Otherwise, we're required to return
12368 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
12369 vm_map_unlock_read(map
);
12370 vm_page_stats_reusable
.can_reuse_failure
++;
12371 return KERN_INVALID_ADDRESS
;
12375 * Examine each vm_map_entry_t in the range.
12377 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
12378 entry
= entry
->vme_next
) {
12380 * Sanity check on the VM map entry.
12382 if (! vm_map_entry_is_reusable(entry
)) {
12383 vm_map_unlock_read(map
);
12384 vm_page_stats_reusable
.can_reuse_failure
++;
12385 return KERN_INVALID_ADDRESS
;
12389 vm_map_unlock_read(map
);
12390 vm_page_stats_reusable
.can_reuse_success
++;
12391 return KERN_SUCCESS
;
12396 * Routine: vm_map_entry_insert
12398 * Descritpion: This routine inserts a new vm_entry in a locked map.
12401 vm_map_entry_insert(
12403 vm_map_entry_t insp_entry
,
12404 vm_map_offset_t start
,
12405 vm_map_offset_t end
,
12406 vm_object_t object
,
12407 vm_object_offset_t offset
,
12408 boolean_t needs_copy
,
12409 boolean_t is_shared
,
12410 boolean_t in_transition
,
12411 vm_prot_t cur_protection
,
12412 vm_prot_t max_protection
,
12413 vm_behavior_t behavior
,
12414 vm_inherit_t inheritance
,
12415 unsigned wired_count
,
12416 boolean_t no_cache
,
12417 boolean_t permanent
,
12418 unsigned int superpage_size
,
12419 boolean_t clear_map_aligned
,
12420 boolean_t is_submap
)
12422 vm_map_entry_t new_entry
;
12424 assert(insp_entry
!= (vm_map_entry_t
)0);
12426 new_entry
= vm_map_entry_create(map
, !map
->hdr
.entries_pageable
);
12428 if (VM_MAP_PAGE_SHIFT(map
) != PAGE_SHIFT
) {
12429 new_entry
->map_aligned
= TRUE
;
12431 new_entry
->map_aligned
= FALSE
;
12433 if (clear_map_aligned
&&
12434 (! VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)) ||
12435 ! VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)))) {
12436 new_entry
->map_aligned
= FALSE
;
12439 new_entry
->vme_start
= start
;
12440 new_entry
->vme_end
= end
;
12441 assert(page_aligned(new_entry
->vme_start
));
12442 assert(page_aligned(new_entry
->vme_end
));
12443 if (new_entry
->map_aligned
) {
12444 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_start
,
12445 VM_MAP_PAGE_MASK(map
)));
12446 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_end
,
12447 VM_MAP_PAGE_MASK(map
)));
12449 assert(new_entry
->vme_start
< new_entry
->vme_end
);
12451 new_entry
->object
.vm_object
= object
;
12452 new_entry
->offset
= offset
;
12453 new_entry
->is_shared
= is_shared
;
12454 new_entry
->is_sub_map
= is_submap
;
12455 new_entry
->needs_copy
= needs_copy
;
12456 new_entry
->in_transition
= in_transition
;
12457 new_entry
->needs_wakeup
= FALSE
;
12458 new_entry
->inheritance
= inheritance
;
12459 new_entry
->protection
= cur_protection
;
12460 new_entry
->max_protection
= max_protection
;
12461 new_entry
->behavior
= behavior
;
12462 new_entry
->wired_count
= wired_count
;
12463 new_entry
->user_wired_count
= 0;
12466 * submap: "use_pmap" means "nested".
12469 new_entry
->use_pmap
= FALSE
;
12472 * object: "use_pmap" means "use pmap accounting" for footprint.
12475 new_entry
->use_pmap
= TRUE
;
12477 new_entry
->alias
= 0;
12478 new_entry
->zero_wired_pages
= FALSE
;
12479 new_entry
->no_cache
= no_cache
;
12480 new_entry
->permanent
= permanent
;
12481 if (superpage_size
)
12482 new_entry
->superpage_size
= TRUE
;
12484 new_entry
->superpage_size
= FALSE
;
12485 new_entry
->used_for_jit
= FALSE
;
12486 new_entry
->iokit_acct
= FALSE
;
12489 * Insert the new entry into the list.
12492 vm_map_store_entry_link(map
, insp_entry
, new_entry
);
12493 map
->size
+= end
- start
;
12496 * Update the free space hint and the lookup hint.
12499 SAVE_HINT_MAP_WRITE(map
, new_entry
);
12504 * Routine: vm_map_remap_extract
12506 * Descritpion: This routine returns a vm_entry list from a map.
12508 static kern_return_t
12509 vm_map_remap_extract(
12511 vm_map_offset_t addr
,
12512 vm_map_size_t size
,
12514 struct vm_map_header
*map_header
,
12515 vm_prot_t
*cur_protection
,
12516 vm_prot_t
*max_protection
,
12517 /* What, no behavior? */
12518 vm_inherit_t inheritance
,
12519 boolean_t pageable
)
12521 kern_return_t result
;
12522 vm_map_size_t mapped_size
;
12523 vm_map_size_t tmp_size
;
12524 vm_map_entry_t src_entry
; /* result of last map lookup */
12525 vm_map_entry_t new_entry
;
12526 vm_object_offset_t offset
;
12527 vm_map_offset_t map_address
;
12528 vm_map_offset_t src_start
; /* start of entry to map */
12529 vm_map_offset_t src_end
; /* end of region to be mapped */
12530 vm_object_t object
;
12531 vm_map_version_t version
;
12532 boolean_t src_needs_copy
;
12533 boolean_t new_entry_needs_copy
;
12535 assert(map
!= VM_MAP_NULL
);
12537 assert(size
== vm_map_round_page(size
, PAGE_MASK
));
12538 assert(inheritance
== VM_INHERIT_NONE
||
12539 inheritance
== VM_INHERIT_COPY
||
12540 inheritance
== VM_INHERIT_SHARE
);
12543 * Compute start and end of region.
12545 src_start
= vm_map_trunc_page(addr
, PAGE_MASK
);
12546 src_end
= vm_map_round_page(src_start
+ size
, PAGE_MASK
);
12550 * Initialize map_header.
12552 map_header
->links
.next
= (struct vm_map_entry
*)&map_header
->links
;
12553 map_header
->links
.prev
= (struct vm_map_entry
*)&map_header
->links
;
12554 map_header
->nentries
= 0;
12555 map_header
->entries_pageable
= pageable
;
12556 map_header
->page_shift
= PAGE_SHIFT
;
12558 vm_map_store_init( map_header
);
12560 *cur_protection
= VM_PROT_ALL
;
12561 *max_protection
= VM_PROT_ALL
;
12565 result
= KERN_SUCCESS
;
12568 * The specified source virtual space might correspond to
12569 * multiple map entries, need to loop on them.
12572 while (mapped_size
!= size
) {
12573 vm_map_size_t entry_size
;
12576 * Find the beginning of the region.
12578 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
12579 result
= KERN_INVALID_ADDRESS
;
12583 if (src_start
< src_entry
->vme_start
||
12584 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
12585 result
= KERN_INVALID_ADDRESS
;
12589 tmp_size
= size
- mapped_size
;
12590 if (src_end
> src_entry
->vme_end
)
12591 tmp_size
-= (src_end
- src_entry
->vme_end
);
12593 entry_size
= (vm_map_size_t
)(src_entry
->vme_end
-
12594 src_entry
->vme_start
);
12596 if(src_entry
->is_sub_map
) {
12597 vm_map_reference(src_entry
->object
.sub_map
);
12598 object
= VM_OBJECT_NULL
;
12600 object
= src_entry
->object
.vm_object
;
12601 if (src_entry
->iokit_acct
) {
12603 * This entry uses "IOKit accounting".
12605 } else if (object
!= VM_OBJECT_NULL
&&
12606 object
->purgable
!= VM_PURGABLE_DENY
) {
12608 * Purgeable objects have their own accounting:
12609 * no pmap accounting for them.
12611 assert(!src_entry
->use_pmap
);
12614 * Not IOKit or purgeable:
12615 * must be accounted by pmap stats.
12617 assert(src_entry
->use_pmap
);
12620 if (object
== VM_OBJECT_NULL
) {
12621 object
= vm_object_allocate(entry_size
);
12622 src_entry
->offset
= 0;
12623 src_entry
->object
.vm_object
= object
;
12624 } else if (object
->copy_strategy
!=
12625 MEMORY_OBJECT_COPY_SYMMETRIC
) {
12627 * We are already using an asymmetric
12628 * copy, and therefore we already have
12629 * the right object.
12631 assert(!src_entry
->needs_copy
);
12632 } else if (src_entry
->needs_copy
|| object
->shadowed
||
12633 (object
->internal
&& !object
->true_share
&&
12634 !src_entry
->is_shared
&&
12635 object
->vo_size
> entry_size
)) {
12637 vm_object_shadow(&src_entry
->object
.vm_object
,
12638 &src_entry
->offset
,
12641 if (!src_entry
->needs_copy
&&
12642 (src_entry
->protection
& VM_PROT_WRITE
)) {
12645 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
12647 if (override_nx(map
, src_entry
->alias
) && prot
)
12648 prot
|= VM_PROT_EXECUTE
;
12650 if(map
->mapped_in_other_pmaps
) {
12651 vm_object_pmap_protect(
12652 src_entry
->object
.vm_object
,
12656 src_entry
->vme_start
,
12659 pmap_protect(vm_map_pmap(map
),
12660 src_entry
->vme_start
,
12661 src_entry
->vme_end
,
12666 object
= src_entry
->object
.vm_object
;
12667 src_entry
->needs_copy
= FALSE
;
12671 vm_object_lock(object
);
12672 vm_object_reference_locked(object
); /* object ref. for new entry */
12673 if (object
->copy_strategy
==
12674 MEMORY_OBJECT_COPY_SYMMETRIC
) {
12675 object
->copy_strategy
=
12676 MEMORY_OBJECT_COPY_DELAY
;
12678 vm_object_unlock(object
);
12681 offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
12683 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
12684 vm_map_entry_copy(new_entry
, src_entry
);
12685 if (new_entry
->is_sub_map
) {
12686 /* clr address space specifics */
12687 new_entry
->use_pmap
= FALSE
;
12690 new_entry
->map_aligned
= FALSE
;
12692 new_entry
->vme_start
= map_address
;
12693 new_entry
->vme_end
= map_address
+ tmp_size
;
12694 assert(new_entry
->vme_start
< new_entry
->vme_end
);
12695 new_entry
->inheritance
= inheritance
;
12696 new_entry
->offset
= offset
;
12699 * The new region has to be copied now if required.
12704 * Cannot allow an entry describing a JIT
12705 * region to be shared across address spaces.
12707 if (src_entry
->used_for_jit
== TRUE
) {
12708 result
= KERN_INVALID_ARGUMENT
;
12711 src_entry
->is_shared
= TRUE
;
12712 new_entry
->is_shared
= TRUE
;
12713 if (!(new_entry
->is_sub_map
))
12714 new_entry
->needs_copy
= FALSE
;
12716 } else if (src_entry
->is_sub_map
) {
12717 /* make this a COW sub_map if not already */
12718 new_entry
->needs_copy
= TRUE
;
12719 object
= VM_OBJECT_NULL
;
12720 } else if (src_entry
->wired_count
== 0 &&
12721 vm_object_copy_quickly(&new_entry
->object
.vm_object
,
12723 (new_entry
->vme_end
-
12724 new_entry
->vme_start
),
12726 &new_entry_needs_copy
)) {
12728 new_entry
->needs_copy
= new_entry_needs_copy
;
12729 new_entry
->is_shared
= FALSE
;
12732 * Handle copy_on_write semantics.
12734 if (src_needs_copy
&& !src_entry
->needs_copy
) {
12737 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
12739 if (override_nx(map
, src_entry
->alias
) && prot
)
12740 prot
|= VM_PROT_EXECUTE
;
12742 vm_object_pmap_protect(object
,
12745 ((src_entry
->is_shared
12746 || map
->mapped_in_other_pmaps
) ?
12747 PMAP_NULL
: map
->pmap
),
12748 src_entry
->vme_start
,
12751 src_entry
->needs_copy
= TRUE
;
12754 * Throw away the old object reference of the new entry.
12756 vm_object_deallocate(object
);
12759 new_entry
->is_shared
= FALSE
;
12762 * The map can be safely unlocked since we
12763 * already hold a reference on the object.
12765 * Record the timestamp of the map for later
12766 * verification, and unlock the map.
12768 version
.main_timestamp
= map
->timestamp
;
12769 vm_map_unlock(map
); /* Increments timestamp once! */
12772 * Perform the copy.
12774 if (src_entry
->wired_count
> 0) {
12775 vm_object_lock(object
);
12776 result
= vm_object_copy_slowly(
12781 &new_entry
->object
.vm_object
);
12783 new_entry
->offset
= 0;
12784 new_entry
->needs_copy
= FALSE
;
12786 result
= vm_object_copy_strategically(
12790 &new_entry
->object
.vm_object
,
12791 &new_entry
->offset
,
12792 &new_entry_needs_copy
);
12794 new_entry
->needs_copy
= new_entry_needs_copy
;
12798 * Throw away the old object reference of the new entry.
12800 vm_object_deallocate(object
);
12802 if (result
!= KERN_SUCCESS
&&
12803 result
!= KERN_MEMORY_RESTART_COPY
) {
12804 _vm_map_entry_dispose(map_header
, new_entry
);
12809 * Verify that the map has not substantially
12810 * changed while the copy was being made.
12814 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
12816 * Simple version comparison failed.
12818 * Retry the lookup and verify that the
12819 * same object/offset are still present.
12821 vm_object_deallocate(new_entry
->
12823 _vm_map_entry_dispose(map_header
, new_entry
);
12824 if (result
== KERN_MEMORY_RESTART_COPY
)
12825 result
= KERN_SUCCESS
;
12829 if (result
== KERN_MEMORY_RESTART_COPY
) {
12830 vm_object_reference(object
);
12835 _vm_map_store_entry_link(map_header
,
12836 map_header
->links
.prev
, new_entry
);
12838 /*Protections for submap mapping are irrelevant here*/
12839 if( !src_entry
->is_sub_map
) {
12840 *cur_protection
&= src_entry
->protection
;
12841 *max_protection
&= src_entry
->max_protection
;
12843 map_address
+= tmp_size
;
12844 mapped_size
+= tmp_size
;
12845 src_start
+= tmp_size
;
12849 vm_map_unlock(map
);
12850 if (result
!= KERN_SUCCESS
) {
12852 * Free all allocated elements.
12854 for (src_entry
= map_header
->links
.next
;
12855 src_entry
!= (struct vm_map_entry
*)&map_header
->links
;
12856 src_entry
= new_entry
) {
12857 new_entry
= src_entry
->vme_next
;
12858 _vm_map_store_entry_unlink(map_header
, src_entry
);
12859 if (src_entry
->is_sub_map
) {
12860 vm_map_deallocate(src_entry
->object
.sub_map
);
12862 vm_object_deallocate(src_entry
->object
.vm_object
);
12864 _vm_map_entry_dispose(map_header
, src_entry
);
12871 * Routine: vm_remap
12873 * Map portion of a task's address space.
12874 * Mapped region must not overlap more than
12875 * one vm memory object. Protections and
12876 * inheritance attributes remain the same
12877 * as in the original task and are out parameters.
12878 * Source and Target task can be identical
12879 * Other attributes are identical as for vm_map()
12883 vm_map_t target_map
,
12884 vm_map_address_t
*address
,
12885 vm_map_size_t size
,
12886 vm_map_offset_t mask
,
12889 vm_map_offset_t memory_address
,
12891 vm_prot_t
*cur_protection
,
12892 vm_prot_t
*max_protection
,
12893 vm_inherit_t inheritance
)
12895 kern_return_t result
;
12896 vm_map_entry_t entry
;
12897 vm_map_entry_t insp_entry
= VM_MAP_ENTRY_NULL
;
12898 vm_map_entry_t new_entry
;
12899 struct vm_map_header map_header
;
12900 vm_map_offset_t offset_in_mapping
;
12902 if (target_map
== VM_MAP_NULL
)
12903 return KERN_INVALID_ARGUMENT
;
12905 switch (inheritance
) {
12906 case VM_INHERIT_NONE
:
12907 case VM_INHERIT_COPY
:
12908 case VM_INHERIT_SHARE
:
12909 if (size
!= 0 && src_map
!= VM_MAP_NULL
)
12913 return KERN_INVALID_ARGUMENT
;
12917 * If the user is requesting that we return the address of the
12918 * first byte of the data (rather than the base of the page),
12919 * then we use different rounding semantics: specifically,
12920 * we assume that (memory_address, size) describes a region
12921 * all of whose pages we must cover, rather than a base to be truncated
12922 * down and a size to be added to that base. So we figure out
12923 * the highest page that the requested region includes and make
12924 * sure that the size will cover it.
12926 * The key example we're worried about it is of the form:
12928 * memory_address = 0x1ff0, size = 0x20
12930 * With the old semantics, we round down the memory_address to 0x1000
12931 * and round up the size to 0x1000, resulting in our covering *only*
12932 * page 0x1000. With the new semantics, we'd realize that the region covers
12933 * 0x1ff0-0x2010, and compute a size of 0x2000. Thus, we cover both page
12934 * 0x1000 and page 0x2000 in the region we remap.
12936 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
12937 offset_in_mapping
= memory_address
- vm_map_trunc_page(memory_address
, PAGE_MASK
);
12938 size
= vm_map_round_page(memory_address
+ size
- vm_map_trunc_page(memory_address
, PAGE_MASK
), PAGE_MASK
);
12940 size
= vm_map_round_page(size
, PAGE_MASK
);
12943 result
= vm_map_remap_extract(src_map
, memory_address
,
12944 size
, copy
, &map_header
,
12948 target_map
->hdr
.entries_pageable
);
12950 if (result
!= KERN_SUCCESS
) {
12955 * Allocate/check a range of free virtual address
12956 * space for the target
12958 *address
= vm_map_trunc_page(*address
,
12959 VM_MAP_PAGE_MASK(target_map
));
12960 vm_map_lock(target_map
);
12961 result
= vm_map_remap_range_allocate(target_map
, address
, size
,
12962 mask
, flags
, &insp_entry
);
12964 for (entry
= map_header
.links
.next
;
12965 entry
!= (struct vm_map_entry
*)&map_header
.links
;
12966 entry
= new_entry
) {
12967 new_entry
= entry
->vme_next
;
12968 _vm_map_store_entry_unlink(&map_header
, entry
);
12969 if (result
== KERN_SUCCESS
) {
12970 entry
->vme_start
+= *address
;
12971 entry
->vme_end
+= *address
;
12972 assert(!entry
->map_aligned
);
12973 vm_map_store_entry_link(target_map
, insp_entry
, entry
);
12974 insp_entry
= entry
;
12976 if (!entry
->is_sub_map
) {
12977 vm_object_deallocate(entry
->object
.vm_object
);
12979 vm_map_deallocate(entry
->object
.sub_map
);
12981 _vm_map_entry_dispose(&map_header
, entry
);
12985 if( target_map
->disable_vmentry_reuse
== TRUE
) {
12986 if( target_map
->highest_entry_end
< insp_entry
->vme_end
){
12987 target_map
->highest_entry_end
= insp_entry
->vme_end
;
12991 if (result
== KERN_SUCCESS
) {
12992 target_map
->size
+= size
;
12993 SAVE_HINT_MAP_WRITE(target_map
, insp_entry
);
12995 vm_map_unlock(target_map
);
12997 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
12998 result
= vm_map_wire(target_map
, *address
,
12999 *address
+ size
, *cur_protection
, TRUE
);
13002 * If requested, return the address of the data pointed to by the
13003 * request, rather than the base of the resulting page.
13005 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
13006 *address
+= offset_in_mapping
;
13013 * Routine: vm_map_remap_range_allocate
13016 * Allocate a range in the specified virtual address map.
13017 * returns the address and the map entry just before the allocated
13020 * Map must be locked.
13023 static kern_return_t
13024 vm_map_remap_range_allocate(
13026 vm_map_address_t
*address
, /* IN/OUT */
13027 vm_map_size_t size
,
13028 vm_map_offset_t mask
,
13030 vm_map_entry_t
*map_entry
) /* OUT */
13032 vm_map_entry_t entry
;
13033 vm_map_offset_t start
;
13034 vm_map_offset_t end
;
13041 if (flags
& VM_FLAGS_ANYWHERE
)
13044 * Calculate the first possible address.
13047 if (start
< map
->min_offset
)
13048 start
= map
->min_offset
;
13049 if (start
> map
->max_offset
)
13050 return(KERN_NO_SPACE
);
13053 * Look for the first possible address;
13054 * if there's already something at this
13055 * address, we have to start after it.
13058 if( map
->disable_vmentry_reuse
== TRUE
) {
13059 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
13061 assert(first_free_is_valid(map
));
13062 if (start
== map
->min_offset
) {
13063 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
13064 start
= entry
->vme_end
;
13066 vm_map_entry_t tmp_entry
;
13067 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
13068 start
= tmp_entry
->vme_end
;
13071 start
= vm_map_round_page(start
,
13072 VM_MAP_PAGE_MASK(map
));
13076 * In any case, the "entry" always precedes
13077 * the proposed new region throughout the
13082 register vm_map_entry_t next
;
13085 * Find the end of the proposed new region.
13086 * Be sure we didn't go beyond the end, or
13087 * wrap around the address.
13090 end
= ((start
+ mask
) & ~mask
);
13091 end
= vm_map_round_page(end
,
13092 VM_MAP_PAGE_MASK(map
));
13094 return(KERN_NO_SPACE
);
13098 if ((end
> map
->max_offset
) || (end
< start
)) {
13099 if (map
->wait_for_space
) {
13100 if (size
<= (map
->max_offset
-
13101 map
->min_offset
)) {
13102 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
13103 vm_map_unlock(map
);
13104 thread_block(THREAD_CONTINUE_NULL
);
13110 return(KERN_NO_SPACE
);
13114 * If there are no more entries, we must win.
13117 next
= entry
->vme_next
;
13118 if (next
== vm_map_to_entry(map
))
13122 * If there is another entry, it must be
13123 * after the end of the potential new region.
13126 if (next
->vme_start
>= end
)
13130 * Didn't fit -- move to the next entry.
13134 start
= entry
->vme_end
;
13138 vm_map_entry_t temp_entry
;
13142 * the address doesn't itself violate
13143 * the mask requirement.
13146 if ((start
& mask
) != 0)
13147 return(KERN_NO_SPACE
);
13151 * ... the address is within bounds
13154 end
= start
+ size
;
13156 if ((start
< map
->min_offset
) ||
13157 (end
> map
->max_offset
) ||
13159 return(KERN_INVALID_ADDRESS
);
13163 * If we're asked to overwrite whatever was mapped in that
13164 * range, first deallocate that range.
13166 if (flags
& VM_FLAGS_OVERWRITE
) {
13170 * We use a "zap_map" to avoid having to unlock
13171 * the "map" in vm_map_delete(), which would compromise
13172 * the atomicity of the "deallocate" and then "remap"
13175 zap_map
= vm_map_create(PMAP_NULL
,
13178 map
->hdr
.entries_pageable
);
13179 if (zap_map
== VM_MAP_NULL
) {
13180 return KERN_RESOURCE_SHORTAGE
;
13182 vm_map_set_page_shift(zap_map
, VM_MAP_PAGE_SHIFT(map
));
13184 kr
= vm_map_delete(map
, start
, end
,
13185 (VM_MAP_REMOVE_SAVE_ENTRIES
|
13186 VM_MAP_REMOVE_NO_MAP_ALIGN
),
13188 if (kr
== KERN_SUCCESS
) {
13189 vm_map_destroy(zap_map
,
13190 VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
13191 zap_map
= VM_MAP_NULL
;
13196 * ... the starting address isn't allocated
13199 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
13200 return(KERN_NO_SPACE
);
13202 entry
= temp_entry
;
13205 * ... the next region doesn't overlap the
13209 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
13210 (entry
->vme_next
->vme_start
< end
))
13211 return(KERN_NO_SPACE
);
13213 *map_entry
= entry
;
13214 return(KERN_SUCCESS
);
13220 * Set the address map for the current thread to the specified map
13228 thread_t thread
= current_thread();
13229 vm_map_t oldmap
= thread
->map
;
13231 mp_disable_preemption();
13232 mycpu
= cpu_number();
13235 * Deactivate the current map and activate the requested map
13237 PMAP_SWITCH_USER(thread
, map
, mycpu
);
13239 mp_enable_preemption();
13245 * Routine: vm_map_write_user
13248 * Copy out data from a kernel space into space in the
13249 * destination map. The space must already exist in the
13251 * NOTE: This routine should only be called by threads
13252 * which can block on a page fault. i.e. kernel mode user
13260 vm_map_address_t dst_addr
,
13263 kern_return_t kr
= KERN_SUCCESS
;
13265 if(current_map() == map
) {
13266 if (copyout(src_p
, dst_addr
, size
)) {
13267 kr
= KERN_INVALID_ADDRESS
;
13272 /* take on the identity of the target map while doing */
13275 vm_map_reference(map
);
13276 oldmap
= vm_map_switch(map
);
13277 if (copyout(src_p
, dst_addr
, size
)) {
13278 kr
= KERN_INVALID_ADDRESS
;
13280 vm_map_switch(oldmap
);
13281 vm_map_deallocate(map
);
13287 * Routine: vm_map_read_user
13290 * Copy in data from a user space source map into the
13291 * kernel map. The space must already exist in the
13293 * NOTE: This routine should only be called by threads
13294 * which can block on a page fault. i.e. kernel mode user
13301 vm_map_address_t src_addr
,
13305 kern_return_t kr
= KERN_SUCCESS
;
13307 if(current_map() == map
) {
13308 if (copyin(src_addr
, dst_p
, size
)) {
13309 kr
= KERN_INVALID_ADDRESS
;
13314 /* take on the identity of the target map while doing */
13317 vm_map_reference(map
);
13318 oldmap
= vm_map_switch(map
);
13319 if (copyin(src_addr
, dst_p
, size
)) {
13320 kr
= KERN_INVALID_ADDRESS
;
13322 vm_map_switch(oldmap
);
13323 vm_map_deallocate(map
);
13330 * vm_map_check_protection:
13332 * Assert that the target map allows the specified
13333 * privilege on the entire address region given.
13334 * The entire region must be allocated.
13337 vm_map_check_protection(vm_map_t map
, vm_map_offset_t start
,
13338 vm_map_offset_t end
, vm_prot_t protection
)
13340 vm_map_entry_t entry
;
13341 vm_map_entry_t tmp_entry
;
13345 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
13347 vm_map_unlock(map
);
13351 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
13352 vm_map_unlock(map
);
13358 while (start
< end
) {
13359 if (entry
== vm_map_to_entry(map
)) {
13360 vm_map_unlock(map
);
13365 * No holes allowed!
13368 if (start
< entry
->vme_start
) {
13369 vm_map_unlock(map
);
13374 * Check protection associated with entry.
13377 if ((entry
->protection
& protection
) != protection
) {
13378 vm_map_unlock(map
);
13382 /* go to next entry */
13384 start
= entry
->vme_end
;
13385 entry
= entry
->vme_next
;
13387 vm_map_unlock(map
);
13392 vm_map_purgable_control(
13394 vm_map_offset_t address
,
13395 vm_purgable_t control
,
13398 vm_map_entry_t entry
;
13399 vm_object_t object
;
13401 boolean_t was_nonvolatile
;
13404 * Vet all the input parameters and current type and state of the
13405 * underlaying object. Return with an error if anything is amiss.
13407 if (map
== VM_MAP_NULL
)
13408 return(KERN_INVALID_ARGUMENT
);
13410 if (control
!= VM_PURGABLE_SET_STATE
&&
13411 control
!= VM_PURGABLE_GET_STATE
&&
13412 control
!= VM_PURGABLE_PURGE_ALL
)
13413 return(KERN_INVALID_ARGUMENT
);
13415 if (control
== VM_PURGABLE_PURGE_ALL
) {
13416 vm_purgeable_object_purge_all();
13417 return KERN_SUCCESS
;
13420 if (control
== VM_PURGABLE_SET_STATE
&&
13421 (((*state
& ~(VM_PURGABLE_ALL_MASKS
)) != 0) ||
13422 ((*state
& VM_PURGABLE_STATE_MASK
) > VM_PURGABLE_STATE_MASK
)))
13423 return(KERN_INVALID_ARGUMENT
);
13425 vm_map_lock_read(map
);
13427 if (!vm_map_lookup_entry(map
, address
, &entry
) || entry
->is_sub_map
) {
13430 * Must pass a valid non-submap address.
13432 vm_map_unlock_read(map
);
13433 return(KERN_INVALID_ADDRESS
);
13436 if ((entry
->protection
& VM_PROT_WRITE
) == 0) {
13438 * Can't apply purgable controls to something you can't write.
13440 vm_map_unlock_read(map
);
13441 return(KERN_PROTECTION_FAILURE
);
13444 object
= entry
->object
.vm_object
;
13445 if (object
== VM_OBJECT_NULL
||
13446 object
->purgable
== VM_PURGABLE_DENY
) {
13448 * Object must already be present and be purgeable.
13450 vm_map_unlock_read(map
);
13451 return KERN_INVALID_ARGUMENT
;
13454 vm_object_lock(object
);
13457 if (entry
->offset
!= 0 ||
13458 entry
->vme_end
- entry
->vme_start
!= object
->vo_size
) {
13460 * Can only apply purgable controls to the whole (existing)
13463 vm_map_unlock_read(map
);
13464 vm_object_unlock(object
);
13465 return KERN_INVALID_ARGUMENT
;
13469 assert(!entry
->is_sub_map
);
13470 assert(!entry
->use_pmap
); /* purgeable has its own accounting */
13472 vm_map_unlock_read(map
);
13474 was_nonvolatile
= (object
->purgable
== VM_PURGABLE_NONVOLATILE
);
13476 kr
= vm_object_purgable_control(object
, control
, state
);
13478 if (was_nonvolatile
&&
13479 object
->purgable
!= VM_PURGABLE_NONVOLATILE
&&
13480 map
->pmap
== kernel_pmap
) {
13482 object
->vo_purgeable_volatilizer
= kernel_task
;
13486 vm_object_unlock(object
);
13492 vm_map_page_query_internal(
13493 vm_map_t target_map
,
13494 vm_map_offset_t offset
,
13499 vm_page_info_basic_data_t info
;
13500 mach_msg_type_number_t count
;
13502 count
= VM_PAGE_INFO_BASIC_COUNT
;
13503 kr
= vm_map_page_info(target_map
,
13505 VM_PAGE_INFO_BASIC
,
13506 (vm_page_info_t
) &info
,
13508 if (kr
== KERN_SUCCESS
) {
13509 *disposition
= info
.disposition
;
13510 *ref_count
= info
.ref_count
;
13522 vm_map_offset_t offset
,
13523 vm_page_info_flavor_t flavor
,
13524 vm_page_info_t info
,
13525 mach_msg_type_number_t
*count
)
13527 vm_map_entry_t map_entry
;
13528 vm_object_t object
;
13531 kern_return_t retval
= KERN_SUCCESS
;
13532 boolean_t top_object
;
13535 vm_page_info_basic_t basic_info
;
13537 vm_map_offset_t offset_in_page
;
13540 case VM_PAGE_INFO_BASIC
:
13541 if (*count
!= VM_PAGE_INFO_BASIC_COUNT
) {
13543 * The "vm_page_info_basic_data" structure was not
13544 * properly padded, so allow the size to be off by
13545 * one to maintain backwards binary compatibility...
13547 if (*count
!= VM_PAGE_INFO_BASIC_COUNT
- 1)
13548 return KERN_INVALID_ARGUMENT
;
13552 return KERN_INVALID_ARGUMENT
;
13560 retval
= KERN_SUCCESS
;
13561 offset_in_page
= offset
& PAGE_MASK
;
13562 offset
= vm_map_trunc_page(offset
, PAGE_MASK
);
13564 vm_map_lock_read(map
);
13567 * First, find the map entry covering "offset", going down
13568 * submaps if necessary.
13571 if (!vm_map_lookup_entry(map
, offset
, &map_entry
)) {
13572 vm_map_unlock_read(map
);
13573 return KERN_INVALID_ADDRESS
;
13575 /* compute offset from this map entry's start */
13576 offset
-= map_entry
->vme_start
;
13577 /* compute offset into this map entry's object (or submap) */
13578 offset
+= map_entry
->offset
;
13580 if (map_entry
->is_sub_map
) {
13583 sub_map
= map_entry
->object
.sub_map
;
13584 vm_map_lock_read(sub_map
);
13585 vm_map_unlock_read(map
);
13589 ref_count
= MAX(ref_count
, map
->ref_count
);
13595 object
= map_entry
->object
.vm_object
;
13596 if (object
== VM_OBJECT_NULL
) {
13597 /* no object -> no page */
13598 vm_map_unlock_read(map
);
13602 vm_object_lock(object
);
13603 vm_map_unlock_read(map
);
13606 * Go down the VM object shadow chain until we find the page
13607 * we're looking for.
13610 ref_count
= MAX(ref_count
, object
->ref_count
);
13612 m
= vm_page_lookup(object
, offset
);
13614 if (m
!= VM_PAGE_NULL
) {
13615 disposition
|= VM_PAGE_QUERY_PAGE_PRESENT
;
13619 if (object
->existence_map
) {
13620 if (vm_external_state_get(object
->existence_map
,
13622 VM_EXTERNAL_STATE_EXISTS
) {
13624 * this page has been paged out
13626 disposition
|= VM_PAGE_QUERY_PAGE_PAGED_OUT
;
13631 if (object
->internal
&&
13633 !object
->terminating
&&
13634 object
->pager_ready
) {
13636 if (COMPRESSED_PAGER_IS_ACTIVE
|| DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE
) {
13637 if (VM_COMPRESSOR_PAGER_STATE_GET(
13640 == VM_EXTERNAL_STATE_EXISTS
) {
13641 /* the pager has that page */
13642 disposition
|= VM_PAGE_QUERY_PAGE_PAGED_OUT
;
13646 memory_object_t pager
;
13648 vm_object_paging_begin(object
);
13649 pager
= object
->pager
;
13650 vm_object_unlock(object
);
13653 * Ask the default pager if
13654 * it has this page.
13656 kr
= memory_object_data_request(
13658 offset
+ object
->paging_offset
,
13659 0, /* just poke the pager */
13663 vm_object_lock(object
);
13664 vm_object_paging_end(object
);
13666 if (kr
== KERN_SUCCESS
) {
13667 /* the default pager has it */
13668 disposition
|= VM_PAGE_QUERY_PAGE_PAGED_OUT
;
13674 if (object
->shadow
!= VM_OBJECT_NULL
) {
13675 vm_object_t shadow
;
13677 offset
+= object
->vo_shadow_offset
;
13678 shadow
= object
->shadow
;
13680 vm_object_lock(shadow
);
13681 vm_object_unlock(object
);
13684 top_object
= FALSE
;
13687 // if (!object->internal)
13689 // retval = KERN_FAILURE;
13690 // goto done_with_object;
13695 /* The ref_count is not strictly accurate, it measures the number */
13696 /* of entities holding a ref on the object, they may not be mapping */
13697 /* the object or may not be mapping the section holding the */
13698 /* target page but its still a ball park number and though an over- */
13699 /* count, it picks up the copy-on-write cases */
13701 /* We could also get a picture of page sharing from pmap_attributes */
13702 /* but this would under count as only faulted-in mappings would */
13705 if (top_object
== TRUE
&& object
->shadow
)
13706 disposition
|= VM_PAGE_QUERY_PAGE_COPIED
;
13708 if (! object
->internal
)
13709 disposition
|= VM_PAGE_QUERY_PAGE_EXTERNAL
;
13711 if (m
== VM_PAGE_NULL
)
13712 goto done_with_object
;
13714 if (m
->fictitious
) {
13715 disposition
|= VM_PAGE_QUERY_PAGE_FICTITIOUS
;
13716 goto done_with_object
;
13718 if (m
->dirty
|| pmap_is_modified(m
->phys_page
))
13719 disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
13721 if (m
->reference
|| pmap_is_referenced(m
->phys_page
))
13722 disposition
|= VM_PAGE_QUERY_PAGE_REF
;
13724 if (m
->speculative
)
13725 disposition
|= VM_PAGE_QUERY_PAGE_SPECULATIVE
;
13727 if (m
->cs_validated
)
13728 disposition
|= VM_PAGE_QUERY_PAGE_CS_VALIDATED
;
13730 disposition
|= VM_PAGE_QUERY_PAGE_CS_TAINTED
;
13733 vm_object_unlock(object
);
13737 case VM_PAGE_INFO_BASIC
:
13738 basic_info
= (vm_page_info_basic_t
) info
;
13739 basic_info
->disposition
= disposition
;
13740 basic_info
->ref_count
= ref_count
;
13741 basic_info
->object_id
= (vm_object_id_t
) (uintptr_t)
13742 VM_KERNEL_ADDRPERM(object
);
13743 basic_info
->offset
=
13744 (memory_object_offset_t
) offset
+ offset_in_page
;
13745 basic_info
->depth
= depth
;
13755 * Synchronises the memory range specified with its backing store
13756 * image by either flushing or cleaning the contents to the appropriate
13757 * memory manager engaging in a memory object synchronize dialog with
13758 * the manager. The client doesn't return until the manager issues
13759 * m_o_s_completed message. MIG Magically converts user task parameter
13760 * to the task's address map.
13762 * interpretation of sync_flags
13763 * VM_SYNC_INVALIDATE - discard pages, only return precious
13764 * pages to manager.
13766 * VM_SYNC_INVALIDATE & (VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS)
13767 * - discard pages, write dirty or precious
13768 * pages back to memory manager.
13770 * VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS
13771 * - write dirty or precious pages back to
13772 * the memory manager.
13774 * VM_SYNC_CONTIGUOUS - does everything normally, but if there
13775 * is a hole in the region, and we would
13776 * have returned KERN_SUCCESS, return
13777 * KERN_INVALID_ADDRESS instead.
13780 * The memory object attributes have not yet been implemented, this
13781 * function will have to deal with the invalidate attribute
13784 * KERN_INVALID_TASK Bad task parameter
13785 * KERN_INVALID_ARGUMENT both sync and async were specified.
13786 * KERN_SUCCESS The usual.
13787 * KERN_INVALID_ADDRESS There was a hole in the region.
13793 vm_map_address_t address
,
13794 vm_map_size_t size
,
13795 vm_sync_t sync_flags
)
13798 msync_req_t new_msr
;
13799 queue_chain_t req_q
; /* queue of requests for this msync */
13800 vm_map_entry_t entry
;
13801 vm_map_size_t amount_left
;
13802 vm_object_offset_t offset
;
13803 boolean_t do_sync_req
;
13804 boolean_t had_hole
= FALSE
;
13805 memory_object_t pager
;
13807 if ((sync_flags
& VM_SYNC_ASYNCHRONOUS
) &&
13808 (sync_flags
& VM_SYNC_SYNCHRONOUS
))
13809 return(KERN_INVALID_ARGUMENT
);
13812 * align address and size on page boundaries
13814 size
= (vm_map_round_page(address
+ size
,
13815 VM_MAP_PAGE_MASK(map
)) -
13816 vm_map_trunc_page(address
,
13817 VM_MAP_PAGE_MASK(map
)));
13818 address
= vm_map_trunc_page(address
,
13819 VM_MAP_PAGE_MASK(map
));
13821 if (map
== VM_MAP_NULL
)
13822 return(KERN_INVALID_TASK
);
13825 return(KERN_SUCCESS
);
13827 queue_init(&req_q
);
13828 amount_left
= size
;
13830 while (amount_left
> 0) {
13831 vm_object_size_t flush_size
;
13832 vm_object_t object
;
13835 if (!vm_map_lookup_entry(map
,
13838 VM_MAP_PAGE_MASK(map
)),
13841 vm_map_size_t skip
;
13844 * hole in the address map.
13849 * Check for empty map.
13851 if (entry
== vm_map_to_entry(map
) &&
13852 entry
->vme_next
== entry
) {
13853 vm_map_unlock(map
);
13857 * Check that we don't wrap and that
13858 * we have at least one real map entry.
13860 if ((map
->hdr
.nentries
== 0) ||
13861 (entry
->vme_next
->vme_start
< address
)) {
13862 vm_map_unlock(map
);
13866 * Move up to the next entry if needed
13868 skip
= (entry
->vme_next
->vme_start
- address
);
13869 if (skip
>= amount_left
)
13872 amount_left
-= skip
;
13873 address
= entry
->vme_next
->vme_start
;
13874 vm_map_unlock(map
);
13878 offset
= address
- entry
->vme_start
;
13881 * do we have more to flush than is contained in this
13884 if (amount_left
+ entry
->vme_start
+ offset
> entry
->vme_end
) {
13885 flush_size
= entry
->vme_end
-
13886 (entry
->vme_start
+ offset
);
13888 flush_size
= amount_left
;
13890 amount_left
-= flush_size
;
13891 address
+= flush_size
;
13893 if (entry
->is_sub_map
== TRUE
) {
13894 vm_map_t local_map
;
13895 vm_map_offset_t local_offset
;
13897 local_map
= entry
->object
.sub_map
;
13898 local_offset
= entry
->offset
;
13899 vm_map_unlock(map
);
13904 sync_flags
) == KERN_INVALID_ADDRESS
) {
13909 object
= entry
->object
.vm_object
;
13912 * We can't sync this object if the object has not been
13915 if (object
== VM_OBJECT_NULL
) {
13916 vm_map_unlock(map
);
13919 offset
+= entry
->offset
;
13921 vm_object_lock(object
);
13923 if (sync_flags
& (VM_SYNC_KILLPAGES
| VM_SYNC_DEACTIVATE
)) {
13924 int kill_pages
= 0;
13925 boolean_t reusable_pages
= FALSE
;
13927 if (sync_flags
& VM_SYNC_KILLPAGES
) {
13928 if (object
->ref_count
== 1 && !object
->shadow
)
13933 if (kill_pages
!= -1)
13934 vm_object_deactivate_pages(object
, offset
,
13935 (vm_object_size_t
)flush_size
, kill_pages
, reusable_pages
);
13936 vm_object_unlock(object
);
13937 vm_map_unlock(map
);
13941 * We can't sync this object if there isn't a pager.
13942 * Don't bother to sync internal objects, since there can't
13943 * be any "permanent" storage for these objects anyway.
13945 if ((object
->pager
== MEMORY_OBJECT_NULL
) ||
13946 (object
->internal
) || (object
->private)) {
13947 vm_object_unlock(object
);
13948 vm_map_unlock(map
);
13952 * keep reference on the object until syncing is done
13954 vm_object_reference_locked(object
);
13955 vm_object_unlock(object
);
13957 vm_map_unlock(map
);
13959 do_sync_req
= vm_object_sync(object
,
13962 sync_flags
& VM_SYNC_INVALIDATE
,
13963 ((sync_flags
& VM_SYNC_SYNCHRONOUS
) ||
13964 (sync_flags
& VM_SYNC_ASYNCHRONOUS
)),
13965 sync_flags
& VM_SYNC_SYNCHRONOUS
);
13967 * only send a m_o_s if we returned pages or if the entry
13968 * is writable (ie dirty pages may have already been sent back)
13970 if (!do_sync_req
) {
13971 if ((sync_flags
& VM_SYNC_INVALIDATE
) && object
->resident_page_count
== 0) {
13973 * clear out the clustering and read-ahead hints
13975 vm_object_lock(object
);
13977 object
->pages_created
= 0;
13978 object
->pages_used
= 0;
13979 object
->sequential
= 0;
13980 object
->last_alloc
= 0;
13982 vm_object_unlock(object
);
13984 vm_object_deallocate(object
);
13987 msync_req_alloc(new_msr
);
13989 vm_object_lock(object
);
13990 offset
+= object
->paging_offset
;
13992 new_msr
->offset
= offset
;
13993 new_msr
->length
= flush_size
;
13994 new_msr
->object
= object
;
13995 new_msr
->flag
= VM_MSYNC_SYNCHRONIZING
;
13999 * We can't sync this object if there isn't a pager. The
14000 * pager can disappear anytime we're not holding the object
14001 * lock. So this has to be checked anytime we goto re_iterate.
14004 pager
= object
->pager
;
14006 if (pager
== MEMORY_OBJECT_NULL
) {
14007 vm_object_unlock(object
);
14008 vm_object_deallocate(object
);
14009 msync_req_free(new_msr
);
14014 queue_iterate(&object
->msr_q
, msr
, msync_req_t
, msr_q
) {
14016 * need to check for overlapping entry, if found, wait
14017 * on overlapping msr to be done, then reiterate
14020 if (msr
->flag
== VM_MSYNC_SYNCHRONIZING
&&
14021 ((offset
>= msr
->offset
&&
14022 offset
< (msr
->offset
+ msr
->length
)) ||
14023 (msr
->offset
>= offset
&&
14024 msr
->offset
< (offset
+ flush_size
))))
14026 assert_wait((event_t
) msr
,THREAD_INTERRUPTIBLE
);
14028 vm_object_unlock(object
);
14029 thread_block(THREAD_CONTINUE_NULL
);
14030 vm_object_lock(object
);
14034 }/* queue_iterate */
14036 queue_enter(&object
->msr_q
, new_msr
, msync_req_t
, msr_q
);
14038 vm_object_paging_begin(object
);
14039 vm_object_unlock(object
);
14041 queue_enter(&req_q
, new_msr
, msync_req_t
, req_q
);
14043 (void) memory_object_synchronize(
14047 sync_flags
& ~VM_SYNC_CONTIGUOUS
);
14049 vm_object_lock(object
);
14050 vm_object_paging_end(object
);
14051 vm_object_unlock(object
);
14055 * wait for memory_object_sychronize_completed messages from pager(s)
14058 while (!queue_empty(&req_q
)) {
14059 msr
= (msync_req_t
)queue_first(&req_q
);
14061 while(msr
->flag
!= VM_MSYNC_DONE
) {
14062 assert_wait((event_t
) msr
, THREAD_INTERRUPTIBLE
);
14064 thread_block(THREAD_CONTINUE_NULL
);
14067 queue_remove(&req_q
, msr
, msync_req_t
, req_q
);
14069 vm_object_deallocate(msr
->object
);
14070 msync_req_free(msr
);
14071 }/* queue_iterate */
14073 /* for proper msync() behaviour */
14074 if (had_hole
== TRUE
&& (sync_flags
& VM_SYNC_CONTIGUOUS
))
14075 return(KERN_INVALID_ADDRESS
);
14077 return(KERN_SUCCESS
);
14081 * Routine: convert_port_entry_to_map
14083 * Convert from a port specifying an entry or a task
14084 * to a map. Doesn't consume the port ref; produces a map ref,
14085 * which may be null. Unlike convert_port_to_map, the
14086 * port may be task or a named entry backed.
14093 convert_port_entry_to_map(
14097 vm_named_entry_t named_entry
;
14098 uint32_t try_failed_count
= 0;
14100 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
14103 if(ip_active(port
) && (ip_kotype(port
)
14104 == IKOT_NAMED_ENTRY
)) {
14106 (vm_named_entry_t
)port
->ip_kobject
;
14107 if (!(lck_mtx_try_lock(&(named_entry
)->Lock
))) {
14110 try_failed_count
++;
14111 mutex_pause(try_failed_count
);
14114 named_entry
->ref_count
++;
14115 lck_mtx_unlock(&(named_entry
)->Lock
);
14117 if ((named_entry
->is_sub_map
) &&
14118 (named_entry
->protection
14119 & VM_PROT_WRITE
)) {
14120 map
= named_entry
->backing
.map
;
14122 mach_destroy_memory_entry(port
);
14123 return VM_MAP_NULL
;
14125 vm_map_reference_swap(map
);
14126 mach_destroy_memory_entry(port
);
14130 return VM_MAP_NULL
;
14134 map
= convert_port_to_map(port
);
14140 * Routine: convert_port_entry_to_object
14142 * Convert from a port specifying a named entry to an
14143 * object. Doesn't consume the port ref; produces a map ref,
14144 * which may be null.
14151 convert_port_entry_to_object(
14154 vm_object_t object
= VM_OBJECT_NULL
;
14155 vm_named_entry_t named_entry
;
14156 uint32_t try_failed_count
= 0;
14158 if (IP_VALID(port
) &&
14159 (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
14162 if (ip_active(port
) &&
14163 (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
14164 named_entry
= (vm_named_entry_t
)port
->ip_kobject
;
14165 if (!(lck_mtx_try_lock(&(named_entry
)->Lock
))) {
14167 try_failed_count
++;
14168 mutex_pause(try_failed_count
);
14171 named_entry
->ref_count
++;
14172 lck_mtx_unlock(&(named_entry
)->Lock
);
14174 if (!(named_entry
->is_sub_map
) &&
14175 !(named_entry
->is_pager
) &&
14176 !(named_entry
->is_copy
) &&
14177 (named_entry
->protection
& VM_PROT_WRITE
)) {
14178 object
= named_entry
->backing
.object
;
14179 vm_object_reference(object
);
14181 mach_destroy_memory_entry(port
);
14189 * Export routines to other components for the things we access locally through
14196 return (current_map_fast());
14200 * vm_map_reference:
14202 * Most code internal to the osfmk will go through a
14203 * macro defining this. This is always here for the
14204 * use of other kernel components.
14206 #undef vm_map_reference
14209 register vm_map_t map
)
14211 if (map
== VM_MAP_NULL
)
14214 lck_mtx_lock(&map
->s_lock
);
14216 assert(map
->res_count
> 0);
14217 assert(map
->ref_count
>= map
->res_count
);
14221 lck_mtx_unlock(&map
->s_lock
);
14225 * vm_map_deallocate:
14227 * Removes a reference from the specified map,
14228 * destroying it if no references remain.
14229 * The map should not be locked.
14233 register vm_map_t map
)
14237 if (map
== VM_MAP_NULL
)
14240 lck_mtx_lock(&map
->s_lock
);
14241 ref
= --map
->ref_count
;
14243 vm_map_res_deallocate(map
);
14244 lck_mtx_unlock(&map
->s_lock
);
14247 assert(map
->ref_count
== 0);
14248 lck_mtx_unlock(&map
->s_lock
);
14252 * The map residence count isn't decremented here because
14253 * the vm_map_delete below will traverse the entire map,
14254 * deleting entries, and the residence counts on objects
14255 * and sharing maps will go away then.
14259 vm_map_destroy(map
, VM_MAP_NO_FLAGS
);
14264 vm_map_disable_NX(vm_map_t map
)
14268 if (map
->pmap
== NULL
)
14271 pmap_disable_NX(map
->pmap
);
14275 vm_map_disallow_data_exec(vm_map_t map
)
14280 map
->map_disallow_data_exec
= TRUE
;
14283 /* XXX Consider making these constants (VM_MAX_ADDRESS and MACH_VM_MAX_ADDRESS)
14284 * more descriptive.
14287 vm_map_set_32bit(vm_map_t map
)
14289 map
->max_offset
= (vm_map_offset_t
)VM_MAX_ADDRESS
;
14294 vm_map_set_64bit(vm_map_t map
)
14296 map
->max_offset
= (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
;
14300 vm_compute_max_offset(unsigned is64
)
14302 return (is64
? (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
: (vm_map_offset_t
)VM_MAX_ADDRESS
);
14306 vm_map_get_max_aslr_slide_pages(vm_map_t map
)
14308 return (1 << (vm_map_is_64bit(map
) ? 16 : 8));
14315 return map
->max_offset
> ((vm_map_offset_t
)VM_MAX_ADDRESS
);
14319 vm_map_has_hard_pagezero(
14321 vm_map_offset_t pagezero_size
)
14325 * We should lock the VM map (for read) here but we can get away
14326 * with it for now because there can't really be any race condition:
14327 * the VM map's min_offset is changed only when the VM map is created
14328 * and when the zero page is established (when the binary gets loaded),
14329 * and this routine gets called only when the task terminates and the
14330 * VM map is being torn down, and when a new map is created via
14331 * load_machfile()/execve().
14333 return (map
->min_offset
>= pagezero_size
);
14337 * Raise a VM map's maximun offset.
14340 vm_map_raise_max_offset(
14342 vm_map_offset_t new_max_offset
)
14347 ret
= KERN_INVALID_ADDRESS
;
14349 if (new_max_offset
>= map
->max_offset
) {
14350 if (!vm_map_is_64bit(map
)) {
14351 if (new_max_offset
<= (vm_map_offset_t
)VM_MAX_ADDRESS
) {
14352 map
->max_offset
= new_max_offset
;
14353 ret
= KERN_SUCCESS
;
14356 if (new_max_offset
<= (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
) {
14357 map
->max_offset
= new_max_offset
;
14358 ret
= KERN_SUCCESS
;
14363 vm_map_unlock(map
);
14369 * Raise a VM map's minimum offset.
14370 * To strictly enforce "page zero" reservation.
14373 vm_map_raise_min_offset(
14375 vm_map_offset_t new_min_offset
)
14377 vm_map_entry_t first_entry
;
14379 new_min_offset
= vm_map_round_page(new_min_offset
,
14380 VM_MAP_PAGE_MASK(map
));
14384 if (new_min_offset
< map
->min_offset
) {
14386 * Can't move min_offset backwards, as that would expose
14387 * a part of the address space that was previously, and for
14388 * possibly good reasons, inaccessible.
14390 vm_map_unlock(map
);
14391 return KERN_INVALID_ADDRESS
;
14394 first_entry
= vm_map_first_entry(map
);
14395 if (first_entry
!= vm_map_to_entry(map
) &&
14396 first_entry
->vme_start
< new_min_offset
) {
14398 * Some memory was already allocated below the new
14399 * minimun offset. It's too late to change it now...
14401 vm_map_unlock(map
);
14402 return KERN_NO_SPACE
;
14405 map
->min_offset
= new_min_offset
;
14407 vm_map_unlock(map
);
14409 return KERN_SUCCESS
;
14413 * Set the limit on the maximum amount of user wired memory allowed for this map.
14414 * This is basically a copy of the MEMLOCK rlimit value maintained by the BSD side of
14415 * the kernel. The limits are checked in the mach VM side, so we keep a copy so we
14416 * don't have to reach over to the BSD data structures.
14420 vm_map_set_user_wire_limit(vm_map_t map
,
14423 map
->user_wire_limit
= limit
;
14427 void vm_map_switch_protect(vm_map_t map
,
14431 map
->switch_protect
=val
;
14432 vm_map_unlock(map
);
14436 * IOKit has mapped a region into this map; adjust the pmap's ledgers appropriately.
14437 * phys_footprint is a composite limit consisting of iokit + physmem, so we need to
14438 * bump both counters.
14441 vm_map_iokit_mapped_region(vm_map_t map
, vm_size_t bytes
)
14443 pmap_t pmap
= vm_map_pmap(map
);
14445 ledger_credit(pmap
->ledger
, task_ledgers
.iokit_mapped
, bytes
);
14446 ledger_credit(pmap
->ledger
, task_ledgers
.phys_footprint
, bytes
);
14450 vm_map_iokit_unmapped_region(vm_map_t map
, vm_size_t bytes
)
14452 pmap_t pmap
= vm_map_pmap(map
);
14454 ledger_debit(pmap
->ledger
, task_ledgers
.iokit_mapped
, bytes
);
14455 ledger_debit(pmap
->ledger
, task_ledgers
.phys_footprint
, bytes
);
14458 /* Add (generate) code signature for memory range */
14459 #if CONFIG_DYNAMIC_CODE_SIGNING
14460 kern_return_t
vm_map_sign(vm_map_t map
,
14461 vm_map_offset_t start
,
14462 vm_map_offset_t end
)
14464 vm_map_entry_t entry
;
14466 vm_object_t object
;
14469 * Vet all the input parameters and current type and state of the
14470 * underlaying object. Return with an error if anything is amiss.
14472 if (map
== VM_MAP_NULL
)
14473 return(KERN_INVALID_ARGUMENT
);
14475 vm_map_lock_read(map
);
14477 if (!vm_map_lookup_entry(map
, start
, &entry
) || entry
->is_sub_map
) {
14479 * Must pass a valid non-submap address.
14481 vm_map_unlock_read(map
);
14482 return(KERN_INVALID_ADDRESS
);
14485 if((entry
->vme_start
> start
) || (entry
->vme_end
< end
)) {
14487 * Map entry doesn't cover the requested range. Not handling
14488 * this situation currently.
14490 vm_map_unlock_read(map
);
14491 return(KERN_INVALID_ARGUMENT
);
14494 object
= entry
->object
.vm_object
;
14495 if (object
== VM_OBJECT_NULL
) {
14497 * Object must already be present or we can't sign.
14499 vm_map_unlock_read(map
);
14500 return KERN_INVALID_ARGUMENT
;
14503 vm_object_lock(object
);
14504 vm_map_unlock_read(map
);
14506 while(start
< end
) {
14509 m
= vm_page_lookup(object
, start
- entry
->vme_start
+ entry
->offset
);
14510 if (m
==VM_PAGE_NULL
) {
14511 /* shoud we try to fault a page here? we can probably
14512 * demand it exists and is locked for this request */
14513 vm_object_unlock(object
);
14514 return KERN_FAILURE
;
14516 /* deal with special page status */
14518 (m
->unusual
&& (m
->error
|| m
->restart
|| m
->private || m
->absent
))) {
14519 vm_object_unlock(object
);
14520 return KERN_FAILURE
;
14523 /* Page is OK... now "validate" it */
14524 /* This is the place where we'll call out to create a code
14525 * directory, later */
14526 m
->cs_validated
= TRUE
;
14528 /* The page is now "clean" for codesigning purposes. That means
14529 * we don't consider it as modified (wpmapped) anymore. But
14530 * we'll disconnect the page so we note any future modification
14532 m
->wpmapped
= FALSE
;
14533 refmod
= pmap_disconnect(m
->phys_page
);
14535 /* Pull the dirty status from the pmap, since we cleared the
14537 if ((refmod
& VM_MEM_MODIFIED
) && !m
->dirty
) {
14538 SET_PAGE_DIRTY(m
, FALSE
);
14541 /* On to the next page */
14542 start
+= PAGE_SIZE
;
14544 vm_object_unlock(object
);
14546 return KERN_SUCCESS
;
14550 kern_return_t
vm_map_partial_reap(vm_map_t map
, unsigned int *reclaimed_resident
, unsigned int *reclaimed_compressed
)
14552 vm_map_entry_t entry
= VM_MAP_ENTRY_NULL
;
14553 vm_map_entry_t next_entry
;
14554 kern_return_t kr
= KERN_SUCCESS
;
14560 * We use a "zap_map" to avoid having to unlock
14561 * the "map" in vm_map_delete().
14563 zap_map
= vm_map_create(PMAP_NULL
,
14566 map
->hdr
.entries_pageable
);
14568 if (zap_map
== VM_MAP_NULL
) {
14569 return KERN_RESOURCE_SHORTAGE
;
14572 vm_map_set_page_shift(zap_map
,
14573 VM_MAP_PAGE_SHIFT(map
));
14575 for (entry
= vm_map_first_entry(map
);
14576 entry
!= vm_map_to_entry(map
);
14577 entry
= next_entry
) {
14578 next_entry
= entry
->vme_next
;
14580 if (entry
->object
.vm_object
&& !entry
->is_sub_map
&& (entry
->object
.vm_object
->internal
== TRUE
)
14581 && (entry
->object
.vm_object
->ref_count
== 1)) {
14583 *reclaimed_resident
+= entry
->object
.vm_object
->resident_page_count
;
14584 *reclaimed_compressed
+= vm_compressor_pager_get_count(entry
->object
.vm_object
->pager
);
14586 (void)vm_map_delete(map
,
14589 VM_MAP_REMOVE_SAVE_ENTRIES
,
14594 vm_map_unlock(map
);
14597 * Get rid of the "zap_maps" and all the map entries that
14598 * they may still contain.
14600 if (zap_map
!= VM_MAP_NULL
) {
14601 vm_map_destroy(zap_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
14602 zap_map
= VM_MAP_NULL
;
14610 kern_return_t
vm_map_freeze_walk(
14612 unsigned int *purgeable_count
,
14613 unsigned int *wired_count
,
14614 unsigned int *clean_count
,
14615 unsigned int *dirty_count
,
14616 unsigned int dirty_budget
,
14617 boolean_t
*has_shared
)
14619 vm_map_entry_t entry
;
14621 vm_map_lock_read(map
);
14623 *purgeable_count
= *wired_count
= *clean_count
= *dirty_count
= 0;
14624 *has_shared
= FALSE
;
14626 for (entry
= vm_map_first_entry(map
);
14627 entry
!= vm_map_to_entry(map
);
14628 entry
= entry
->vme_next
) {
14629 unsigned int purgeable
, clean
, dirty
, wired
;
14632 if ((entry
->object
.vm_object
== 0) ||
14633 (entry
->is_sub_map
) ||
14634 (entry
->object
.vm_object
->phys_contiguous
)) {
14638 default_freezer_pack(&purgeable
, &wired
, &clean
, &dirty
, dirty_budget
, &shared
, entry
->object
.vm_object
, NULL
);
14640 *purgeable_count
+= purgeable
;
14641 *wired_count
+= wired
;
14642 *clean_count
+= clean
;
14643 *dirty_count
+= dirty
;
14646 *has_shared
= TRUE
;
14649 /* Adjust pageout budget and finish up if reached */
14650 if (dirty_budget
) {
14651 dirty_budget
-= dirty
;
14652 if (dirty_budget
== 0) {
14658 vm_map_unlock_read(map
);
14660 return KERN_SUCCESS
;
14663 kern_return_t
vm_map_freeze(
14665 unsigned int *purgeable_count
,
14666 unsigned int *wired_count
,
14667 unsigned int *clean_count
,
14668 unsigned int *dirty_count
,
14669 unsigned int dirty_budget
,
14670 boolean_t
*has_shared
)
14672 vm_map_entry_t entry2
= VM_MAP_ENTRY_NULL
;
14673 kern_return_t kr
= KERN_SUCCESS
;
14674 boolean_t default_freezer_active
= TRUE
;
14676 *purgeable_count
= *wired_count
= *clean_count
= *dirty_count
= 0;
14677 *has_shared
= FALSE
;
14680 * We need the exclusive lock here so that we can
14681 * block any page faults or lookups while we are
14682 * in the middle of freezing this vm map.
14686 if (COMPRESSED_PAGER_IS_ACTIVE
|| DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE
) {
14687 default_freezer_active
= FALSE
;
14690 if (default_freezer_active
) {
14691 if (map
->default_freezer_handle
== NULL
) {
14692 map
->default_freezer_handle
= default_freezer_handle_allocate();
14695 if ((kr
= default_freezer_handle_init(map
->default_freezer_handle
)) != KERN_SUCCESS
) {
14697 * Can happen if default_freezer_handle passed in is NULL
14698 * Or, a table has already been allocated and associated
14699 * with this handle, i.e. the map is already frozen.
14705 for (entry2
= vm_map_first_entry(map
);
14706 entry2
!= vm_map_to_entry(map
);
14707 entry2
= entry2
->vme_next
) {
14709 vm_object_t src_object
= entry2
->object
.vm_object
;
14711 if (entry2
->object
.vm_object
&& !entry2
->is_sub_map
&& !entry2
->object
.vm_object
->phys_contiguous
) {
14712 /* If eligible, scan the entry, moving eligible pages over to our parent object */
14713 if (default_freezer_active
) {
14714 unsigned int purgeable
, clean
, dirty
, wired
;
14717 default_freezer_pack(&purgeable
, &wired
, &clean
, &dirty
, dirty_budget
, &shared
,
14718 src_object
, map
->default_freezer_handle
);
14720 *purgeable_count
+= purgeable
;
14721 *wired_count
+= wired
;
14722 *clean_count
+= clean
;
14723 *dirty_count
+= dirty
;
14725 /* Adjust pageout budget and finish up if reached */
14726 if (dirty_budget
) {
14727 dirty_budget
-= dirty
;
14728 if (dirty_budget
== 0) {
14734 *has_shared
= TRUE
;
14738 * To the compressor.
14740 if (entry2
->object
.vm_object
->internal
== TRUE
) {
14741 vm_object_pageout(entry2
->object
.vm_object
);
14747 if (default_freezer_active
) {
14748 /* Finally, throw out the pages to swap */
14749 default_freezer_pageout(map
->default_freezer_handle
);
14753 vm_map_unlock(map
);
14762 kern_return_t kr
= KERN_SUCCESS
;
14764 if (COMPRESSED_PAGER_IS_ACTIVE
|| DEFAULT_FREEZER_COMPRESSED_PAGER_IS_ACTIVE
) {
14766 * We will on-demand thaw in the presence of the compressed pager.
14773 if (map
->default_freezer_handle
== NULL
) {
14775 * This map is not in a frozen state.
14781 kr
= default_freezer_unpack(map
->default_freezer_handle
);
14783 vm_map_unlock(map
);
14790 * vm_map_entry_should_cow_for_true_share:
14792 * Determines if the map entry should be clipped and setup for copy-on-write
14793 * to avoid applying "true_share" to a large VM object when only a subset is
14796 * For now, we target only the map entries created for the Objective C
14797 * Garbage Collector, which initially have the following properties:
14798 * - alias == VM_MEMORY_MALLOC
14799 * - wired_count == 0
14801 * and a VM object with:
14803 * - copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC
14805 * - vo_size == ANON_CHUNK_SIZE
14808 vm_map_entry_should_cow_for_true_share(
14809 vm_map_entry_t entry
)
14811 vm_object_t object
;
14813 if (entry
->is_sub_map
) {
14814 /* entry does not point at a VM object */
14818 if (entry
->needs_copy
) {
14819 /* already set for copy_on_write: done! */
14823 if (entry
->alias
!= VM_MEMORY_MALLOC
&&
14824 entry
->alias
!= VM_MEMORY_MALLOC_SMALL
) {
14825 /* not a malloc heap or Obj-C Garbage Collector heap */
14829 if (entry
->wired_count
) {
14830 /* wired: can't change the map entry... */
14831 vm_counters
.should_cow_but_wired
++;
14835 object
= entry
->object
.vm_object
;
14837 if (object
== VM_OBJECT_NULL
) {
14838 /* no object yet... */
14842 if (!object
->internal
) {
14843 /* not an internal object */
14847 if (object
->copy_strategy
!= MEMORY_OBJECT_COPY_SYMMETRIC
) {
14848 /* not the default copy strategy */
14852 if (object
->true_share
) {
14853 /* already true_share: too late to avoid it */
14857 if (entry
->alias
== VM_MEMORY_MALLOC
&&
14858 object
->vo_size
!= ANON_CHUNK_SIZE
) {
14859 /* ... not an object created for the ObjC Garbage Collector */
14863 if (entry
->alias
== VM_MEMORY_MALLOC_SMALL
&&
14864 object
->vo_size
!= 2048 * 4096) {
14865 /* ... not a "MALLOC_SMALL" heap */
14870 * All the criteria match: we have a large object being targeted for "true_share".
14871 * To limit the adverse side-effects linked with "true_share", tell the caller to
14872 * try and avoid setting up the entire object for "true_share" by clipping the
14873 * targeted range and setting it up for copy-on-write.
14879 vm_map_round_page_mask(
14880 vm_map_offset_t offset
,
14881 vm_map_offset_t mask
)
14883 return VM_MAP_ROUND_PAGE(offset
, mask
);
14887 vm_map_trunc_page_mask(
14888 vm_map_offset_t offset
,
14889 vm_map_offset_t mask
)
14891 return VM_MAP_TRUNC_PAGE(offset
, mask
);
14898 return VM_MAP_PAGE_SHIFT(map
);
14905 return VM_MAP_PAGE_SIZE(map
);
14912 return VM_MAP_PAGE_MASK(map
);
14916 vm_map_set_page_shift(
14920 if (map
->hdr
.nentries
!= 0) {
14921 /* too late to change page size */
14922 return KERN_FAILURE
;
14925 map
->hdr
.page_shift
= pageshift
;
14927 return KERN_SUCCESS
;
14934 int num_object_purged
;
14935 vm_map_entry_t entry
;
14936 vm_map_offset_t next_address
;
14937 vm_object_t object
;
14941 num_object_purged
= 0;
14943 vm_map_lock_read(map
);
14944 entry
= vm_map_first_entry(map
);
14945 while (entry
!= vm_map_to_entry(map
)) {
14946 if (entry
->is_sub_map
) {
14949 if (! (entry
->protection
& VM_PROT_WRITE
)) {
14952 object
= entry
->object
.vm_object
;
14953 if (object
== VM_OBJECT_NULL
) {
14956 if (object
->purgable
!= VM_PURGABLE_VOLATILE
) {
14960 vm_object_lock(object
);
14962 if (entry
->offset
!= 0 ||
14963 (entry
->vme_end
- entry
->vme_start
) != object
->vo_size
) {
14964 vm_object_unlock(object
);
14968 next_address
= entry
->vme_end
;
14969 vm_map_unlock_read(map
);
14970 state
= VM_PURGABLE_EMPTY
;
14971 kr
= vm_object_purgable_control(object
,
14972 VM_PURGABLE_SET_STATE
,
14974 if (kr
== KERN_SUCCESS
) {
14975 num_object_purged
++;
14977 vm_object_unlock(object
);
14979 vm_map_lock_read(map
);
14980 if (vm_map_lookup_entry(map
, next_address
, &entry
)) {
14984 entry
= entry
->vme_next
;
14986 vm_map_unlock_read(map
);
14988 return num_object_purged
;
14992 vm_map_query_volatile(
14994 mach_vm_size_t
*volatile_virtual_size_p
,
14995 mach_vm_size_t
*volatile_resident_size_p
,
14996 mach_vm_size_t
*volatile_pmap_size_p
)
14998 mach_vm_size_t volatile_virtual_size
;
14999 mach_vm_size_t volatile_resident_count
;
15000 mach_vm_size_t volatile_pmap_count
;
15001 mach_vm_size_t resident_count
;
15002 vm_map_entry_t entry
;
15003 vm_object_t object
;
15005 /* map should be locked by caller */
15007 volatile_virtual_size
= 0;
15008 volatile_resident_count
= 0;
15009 volatile_pmap_count
= 0;
15011 for (entry
= vm_map_first_entry(map
);
15012 entry
!= vm_map_to_entry(map
);
15013 entry
= entry
->vme_next
) {
15014 if (entry
->is_sub_map
) {
15017 if (! (entry
->protection
& VM_PROT_WRITE
)) {
15020 object
= entry
->object
.vm_object
;
15021 if (object
== VM_OBJECT_NULL
) {
15024 if (object
->purgable
!= VM_PURGABLE_VOLATILE
) {
15027 if (entry
->offset
!= 0) {
15029 * If the map entry has been split and the object now
15030 * appears several times in the VM map, we don't want
15031 * to count the object's resident_page_count more than
15032 * once. We count it only for the first one, starting
15033 * at offset 0 and ignore the other VM map entries.
15037 resident_count
= object
->resident_page_count
;
15038 if ((entry
->offset
/ PAGE_SIZE
) >= resident_count
) {
15039 resident_count
= 0;
15041 resident_count
-= (entry
->offset
/ PAGE_SIZE
);
15044 volatile_virtual_size
+= entry
->vme_end
- entry
->vme_start
;
15045 volatile_resident_count
+= resident_count
;
15046 volatile_pmap_count
+= pmap_query_resident(map
->pmap
,
15051 /* map is still locked on return */
15053 *volatile_virtual_size_p
= volatile_virtual_size
;
15054 *volatile_resident_size_p
= volatile_resident_count
* PAGE_SIZE
;
15055 *volatile_pmap_size_p
= volatile_pmap_count
* PAGE_SIZE
;
15057 return KERN_SUCCESS
;
15060 #if VM_SCAN_FOR_SHADOW_CHAIN
15061 int vm_map_shadow_max(vm_map_t map
);
15062 int vm_map_shadow_max(
15065 int shadows
, shadows_max
;
15066 vm_map_entry_t entry
;
15067 vm_object_t object
, next_object
;
15074 vm_map_lock_read(map
);
15076 for (entry
= vm_map_first_entry(map
);
15077 entry
!= vm_map_to_entry(map
);
15078 entry
= entry
->vme_next
) {
15079 if (entry
->is_sub_map
) {
15082 object
= entry
->object
.vm_object
;
15083 if (object
== NULL
) {
15086 vm_object_lock_shared(object
);
15088 object
->shadow
!= NULL
;
15089 shadows
++, object
= next_object
) {
15090 next_object
= object
->shadow
;
15091 vm_object_lock_shared(next_object
);
15092 vm_object_unlock(object
);
15094 vm_object_unlock(object
);
15095 if (shadows
> shadows_max
) {
15096 shadows_max
= shadows
;
15100 vm_map_unlock_read(map
);
15102 return shadows_max
;
15104 #endif /* VM_SCAN_FOR_SHADOW_CHAIN */