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/backtrace.h>
86 #include <kern/counters.h>
87 #include <kern/kalloc.h>
88 #include <kern/zalloc.h>
91 #include <vm/vm_compressor_pager.h>
92 #include <vm/vm_init.h>
93 #include <vm/vm_fault.h>
94 #include <vm/vm_map.h>
95 #include <vm/vm_object.h>
96 #include <vm/vm_page.h>
97 #include <vm/vm_pageout.h>
98 #include <vm/vm_kern.h>
99 #include <ipc/ipc_port.h>
100 #include <kern/sched_prim.h>
101 #include <kern/misc_protos.h>
102 #include <kern/xpr.h>
104 #include <mach/vm_map_server.h>
105 #include <mach/mach_host_server.h>
106 #include <vm/vm_protos.h>
107 #include <vm/vm_purgeable_internal.h>
109 #include <vm/vm_protos.h>
110 #include <vm/vm_shared_region.h>
111 #include <vm/vm_map_store.h>
113 #include <san/kasan.h>
116 extern int fourk_binary_compatibility_unsafe
;
117 extern int fourk_binary_compatibility_allow_wx
;
118 #endif /* __arm64__ */
119 extern int proc_selfpid(void);
120 extern char *proc_name_address(void *p
);
122 #if VM_MAP_DEBUG_APPLE_PROTECT
123 int vm_map_debug_apple_protect
= 0;
124 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
125 #if VM_MAP_DEBUG_FOURK
126 int vm_map_debug_fourk
= 0;
127 #endif /* VM_MAP_DEBUG_FOURK */
129 int vm_map_executable_immutable
= 0;
130 int vm_map_executable_immutable_no_log
= 0;
132 extern u_int32_t
random(void); /* from <libkern/libkern.h> */
133 /* Internal prototypes
136 static void vm_map_simplify_range(
138 vm_map_offset_t start
,
139 vm_map_offset_t end
); /* forward */
141 static boolean_t
vm_map_range_check(
143 vm_map_offset_t start
,
145 vm_map_entry_t
*entry
);
147 static vm_map_entry_t
_vm_map_entry_create(
148 struct vm_map_header
*map_header
, boolean_t map_locked
);
150 static void _vm_map_entry_dispose(
151 struct vm_map_header
*map_header
,
152 vm_map_entry_t entry
);
154 static void vm_map_pmap_enter(
156 vm_map_offset_t addr
,
157 vm_map_offset_t end_addr
,
159 vm_object_offset_t offset
,
160 vm_prot_t protection
);
162 static void _vm_map_clip_end(
163 struct vm_map_header
*map_header
,
164 vm_map_entry_t entry
,
165 vm_map_offset_t end
);
167 static void _vm_map_clip_start(
168 struct vm_map_header
*map_header
,
169 vm_map_entry_t entry
,
170 vm_map_offset_t start
);
172 static void vm_map_entry_delete(
174 vm_map_entry_t entry
);
176 static kern_return_t
vm_map_delete(
178 vm_map_offset_t start
,
183 static kern_return_t
vm_map_copy_overwrite_unaligned(
185 vm_map_entry_t entry
,
187 vm_map_address_t start
,
188 boolean_t discard_on_success
);
190 static kern_return_t
vm_map_copy_overwrite_aligned(
192 vm_map_entry_t tmp_entry
,
194 vm_map_offset_t start
,
197 static kern_return_t
vm_map_copyin_kernel_buffer(
199 vm_map_address_t src_addr
,
201 boolean_t src_destroy
,
202 vm_map_copy_t
*copy_result
); /* OUT */
204 static kern_return_t
vm_map_copyout_kernel_buffer(
206 vm_map_address_t
*addr
, /* IN/OUT */
208 vm_map_size_t copy_size
,
210 boolean_t consume_on_success
);
212 static void vm_map_fork_share(
214 vm_map_entry_t old_entry
,
217 static boolean_t
vm_map_fork_copy(
219 vm_map_entry_t
*old_entry_p
,
221 int vm_map_copyin_flags
);
223 void vm_map_region_top_walk(
224 vm_map_entry_t entry
,
225 vm_region_top_info_t top
);
227 void vm_map_region_walk(
230 vm_map_entry_t entry
,
231 vm_object_offset_t offset
,
232 vm_object_size_t range
,
233 vm_region_extended_info_t extended
,
234 boolean_t look_for_pages
,
235 mach_msg_type_number_t count
);
237 static kern_return_t
vm_map_wire_nested(
239 vm_map_offset_t start
,
241 vm_prot_t caller_prot
,
245 vm_map_offset_t pmap_addr
,
246 ppnum_t
*physpage_p
);
248 static kern_return_t
vm_map_unwire_nested(
250 vm_map_offset_t start
,
254 vm_map_offset_t pmap_addr
);
256 static kern_return_t
vm_map_overwrite_submap_recurse(
258 vm_map_offset_t dst_addr
,
259 vm_map_size_t dst_size
);
261 static kern_return_t
vm_map_copy_overwrite_nested(
263 vm_map_offset_t dst_addr
,
265 boolean_t interruptible
,
267 boolean_t discard_on_success
);
269 static kern_return_t
vm_map_remap_extract(
271 vm_map_offset_t addr
,
274 struct vm_map_header
*map_header
,
275 vm_prot_t
*cur_protection
,
276 vm_prot_t
*max_protection
,
277 vm_inherit_t inheritance
,
280 vm_map_kernel_flags_t vmk_flags
);
282 static kern_return_t
vm_map_remap_range_allocate(
284 vm_map_address_t
*address
,
286 vm_map_offset_t mask
,
288 vm_map_kernel_flags_t vmk_flags
,
290 vm_map_entry_t
*map_entry
);
292 static void vm_map_region_look_for_page(
296 vm_object_offset_t offset
,
299 vm_region_extended_info_t extended
,
300 mach_msg_type_number_t count
);
302 static int vm_map_region_count_obj_refs(
303 vm_map_entry_t entry
,
307 static kern_return_t
vm_map_willneed(
309 vm_map_offset_t start
,
310 vm_map_offset_t end
);
312 static kern_return_t
vm_map_reuse_pages(
314 vm_map_offset_t start
,
315 vm_map_offset_t end
);
317 static kern_return_t
vm_map_reusable_pages(
319 vm_map_offset_t start
,
320 vm_map_offset_t end
);
322 static kern_return_t
vm_map_can_reuse(
324 vm_map_offset_t start
,
325 vm_map_offset_t end
);
328 static kern_return_t
vm_map_pageout(
330 vm_map_offset_t start
,
331 vm_map_offset_t end
);
332 #endif /* MACH_ASSERT */
334 pid_t
find_largest_process_vm_map_entries(void);
337 * Macros to copy a vm_map_entry. We must be careful to correctly
338 * manage the wired page count. vm_map_entry_copy() creates a new
339 * map entry to the same memory - the wired count in the new entry
340 * must be set to zero. vm_map_entry_copy_full() creates a new
341 * entry that is identical to the old entry. This preserves the
342 * wire count; it's used for map splitting and zone changing in
346 #define vm_map_entry_copy(NEW,OLD) \
348 boolean_t _vmec_reserved = (NEW)->from_reserved_zone; \
350 (NEW)->is_shared = FALSE; \
351 (NEW)->needs_wakeup = FALSE; \
352 (NEW)->in_transition = FALSE; \
353 (NEW)->wired_count = 0; \
354 (NEW)->user_wired_count = 0; \
355 (NEW)->permanent = FALSE; \
356 (NEW)->used_for_jit = FALSE; \
357 (NEW)->from_reserved_zone = _vmec_reserved; \
358 if ((NEW)->iokit_acct) { \
359 assertf(!(NEW)->use_pmap, "old %p new %p\n", (OLD), (NEW)); \
360 (NEW)->iokit_acct = FALSE; \
361 (NEW)->use_pmap = TRUE; \
363 (NEW)->vme_resilient_codesign = FALSE; \
364 (NEW)->vme_resilient_media = FALSE; \
365 (NEW)->vme_atomic = FALSE; \
368 #define vm_map_entry_copy_full(NEW,OLD) \
370 boolean_t _vmecf_reserved = (NEW)->from_reserved_zone; \
372 (NEW)->from_reserved_zone = _vmecf_reserved; \
376 * Decide if we want to allow processes to execute from their data or stack areas.
377 * override_nx() returns true if we do. Data/stack execution can be enabled independently
378 * for 32 and 64 bit processes. Set the VM_ABI_32 or VM_ABI_64 flags in allow_data_exec
379 * or allow_stack_exec to enable data execution for that type of data area for that particular
380 * ABI (or both by or'ing the flags together). These are initialized in the architecture
381 * specific pmap files since the default behavior varies according to architecture. The
382 * main reason it varies is because of the need to provide binary compatibility with old
383 * applications that were written before these restrictions came into being. In the old
384 * days, an app could execute anything it could read, but this has slowly been tightened
385 * up over time. The default behavior is:
387 * 32-bit PPC apps may execute from both stack and data areas
388 * 32-bit Intel apps may exeucte from data areas but not stack
389 * 64-bit PPC/Intel apps may not execute from either data or stack
391 * An application on any architecture may override these defaults by explicitly
392 * adding PROT_EXEC permission to the page in question with the mprotect(2)
393 * system call. This code here just determines what happens when an app tries to
394 * execute from a page that lacks execute permission.
396 * Note that allow_data_exec or allow_stack_exec may also be modified by sysctl to change the
397 * default behavior for both 32 and 64 bit apps on a system-wide basis. Furthermore,
398 * a Mach-O header flag bit (MH_NO_HEAP_EXECUTION) can be used to forcibly disallow
399 * execution from data areas for a particular binary even if the arch normally permits it. As
400 * a final wrinkle, a posix_spawn attribute flag can be used to negate this opt-in header bit
401 * to support some complicated use cases, notably browsers with out-of-process plugins that
402 * are not all NX-safe.
405 extern int allow_data_exec
, allow_stack_exec
;
408 override_nx(vm_map_t map
, uint32_t user_tag
) /* map unused on arm */
412 if (map
->pmap
== kernel_pmap
) return FALSE
;
415 * Determine if the app is running in 32 or 64 bit mode.
418 if (vm_map_is_64bit(map
))
419 current_abi
= VM_ABI_64
;
421 current_abi
= VM_ABI_32
;
424 * Determine if we should allow the execution based on whether it's a
425 * stack or data area and the current architecture.
428 if (user_tag
== VM_MEMORY_STACK
)
429 return allow_stack_exec
& current_abi
;
431 return (allow_data_exec
& current_abi
) && (map
->map_disallow_data_exec
== FALSE
);
436 * Virtual memory maps provide for the mapping, protection,
437 * and sharing of virtual memory objects. In addition,
438 * this module provides for an efficient virtual copy of
439 * memory from one map to another.
441 * Synchronization is required prior to most operations.
443 * Maps consist of an ordered doubly-linked list of simple
444 * entries; a single hint is used to speed up lookups.
446 * Sharing maps have been deleted from this version of Mach.
447 * All shared objects are now mapped directly into the respective
448 * maps. This requires a change in the copy on write strategy;
449 * the asymmetric (delayed) strategy is used for shared temporary
450 * objects instead of the symmetric (shadow) strategy. All maps
451 * are now "top level" maps (either task map, kernel map or submap
452 * of the kernel map).
454 * Since portions of maps are specified by start/end addreses,
455 * which may not align with existing map entries, all
456 * routines merely "clip" entries to these start/end values.
457 * [That is, an entry is split into two, bordering at a
458 * start or end value.] Note that these clippings may not
459 * always be necessary (as the two resulting entries are then
460 * not changed); however, the clipping is done for convenience.
461 * No attempt is currently made to "glue back together" two
464 * The symmetric (shadow) copy strategy implements virtual copy
465 * by copying VM object references from one map to
466 * another, and then marking both regions as copy-on-write.
467 * It is important to note that only one writeable reference
468 * to a VM object region exists in any map when this strategy
469 * is used -- this means that shadow object creation can be
470 * delayed until a write operation occurs. The symmetric (delayed)
471 * strategy allows multiple maps to have writeable references to
472 * the same region of a vm object, and hence cannot delay creating
473 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
474 * Copying of permanent objects is completely different; see
475 * vm_object_copy_strategically() in vm_object.c.
478 static zone_t vm_map_zone
; /* zone for vm_map structures */
479 zone_t vm_map_entry_zone
; /* zone for vm_map_entry structures */
480 static zone_t vm_map_entry_reserved_zone
; /* zone with reserve for non-blocking allocations */
481 static zone_t vm_map_copy_zone
; /* zone for vm_map_copy structures */
482 zone_t vm_map_holes_zone
; /* zone for vm map holes (vm_map_links) structures */
486 * Placeholder object for submap operations. This object is dropped
487 * into the range by a call to vm_map_find, and removed when
488 * vm_map_submap creates the submap.
491 vm_object_t vm_submap_object
;
493 static void *map_data
;
494 static vm_size_t map_data_size
;
495 static void *kentry_data
;
496 static vm_size_t kentry_data_size
;
497 static void *map_holes_data
;
498 static vm_size_t map_holes_data_size
;
501 #define NO_COALESCE_LIMIT 0
503 #define NO_COALESCE_LIMIT ((1024 * 128) - 1)
506 /* Skip acquiring locks if we're in the midst of a kernel core dump */
507 unsigned int not_in_kdp
= 1;
509 unsigned int vm_map_set_cache_attr_count
= 0;
512 vm_map_set_cache_attr(
516 vm_map_entry_t map_entry
;
518 kern_return_t kr
= KERN_SUCCESS
;
520 vm_map_lock_read(map
);
522 if (!vm_map_lookup_entry(map
, va
, &map_entry
) ||
523 map_entry
->is_sub_map
) {
525 * that memory is not properly mapped
527 kr
= KERN_INVALID_ARGUMENT
;
530 object
= VME_OBJECT(map_entry
);
532 if (object
== VM_OBJECT_NULL
) {
534 * there should be a VM object here at this point
536 kr
= KERN_INVALID_ARGUMENT
;
539 vm_object_lock(object
);
540 object
->set_cache_attr
= TRUE
;
541 vm_object_unlock(object
);
543 vm_map_set_cache_attr_count
++;
545 vm_map_unlock_read(map
);
551 #if CONFIG_CODE_DECRYPTION
553 * vm_map_apple_protected:
554 * This remaps the requested part of the object with an object backed by
555 * the decrypting pager.
556 * crypt_info contains entry points and session data for the crypt module.
557 * The crypt_info block will be copied by vm_map_apple_protected. The data structures
558 * referenced in crypt_info must remain valid until crypt_info->crypt_end() is called.
561 vm_map_apple_protected(
563 vm_map_offset_t start
,
565 vm_object_offset_t crypto_backing_offset
,
566 struct pager_crypt_info
*crypt_info
)
568 boolean_t map_locked
;
570 vm_map_entry_t map_entry
;
571 struct vm_map_entry tmp_entry
;
572 memory_object_t unprotected_mem_obj
;
573 vm_object_t protected_object
;
574 vm_map_offset_t map_addr
;
575 vm_map_offset_t start_aligned
, end_aligned
;
576 vm_object_offset_t crypto_start
, crypto_end
;
578 vm_map_kernel_flags_t vmk_flags
;
581 vmk_flags
= VM_MAP_KERNEL_FLAGS_NONE
;
584 unprotected_mem_obj
= MEMORY_OBJECT_NULL
;
586 start_aligned
= vm_map_trunc_page(start
, PAGE_MASK_64
);
587 end_aligned
= vm_map_round_page(end
, PAGE_MASK_64
);
588 start_aligned
= vm_map_trunc_page(start_aligned
, VM_MAP_PAGE_MASK(map
));
589 end_aligned
= vm_map_round_page(end_aligned
, VM_MAP_PAGE_MASK(map
));
593 * "start" and "end" might be 4K-aligned but not 16K-aligned,
594 * so we might have to loop and establish up to 3 mappings:
596 * + the first 16K-page, which might overlap with the previous
597 * 4K-aligned mapping,
599 * + the last 16K-page, which might overlap with the next
600 * 4K-aligned mapping.
601 * Each of these mapping might be backed by a vnode pager (if
602 * properly page-aligned) or a "fourk_pager", itself backed by a
603 * vnode pager (if 4K-aligned but not page-aligned).
605 #else /* __arm64__ */
606 assert(start_aligned
== start
);
607 assert(end_aligned
== end
);
608 #endif /* __arm64__ */
610 map_addr
= start_aligned
;
611 for (map_addr
= start_aligned
;
613 map_addr
= tmp_entry
.vme_end
) {
617 /* lookup the protected VM object */
618 if (!vm_map_lookup_entry(map
,
621 map_entry
->is_sub_map
||
622 VME_OBJECT(map_entry
) == VM_OBJECT_NULL
||
623 !(map_entry
->protection
& VM_PROT_EXECUTE
)) {
624 /* that memory is not properly mapped */
625 kr
= KERN_INVALID_ARGUMENT
;
629 /* get the protected object to be decrypted */
630 protected_object
= VME_OBJECT(map_entry
);
631 if (protected_object
== VM_OBJECT_NULL
) {
632 /* there should be a VM object here at this point */
633 kr
= KERN_INVALID_ARGUMENT
;
636 /* ensure protected object stays alive while map is unlocked */
637 vm_object_reference(protected_object
);
639 /* limit the map entry to the area we want to cover */
640 vm_map_clip_start(map
, map_entry
, start_aligned
);
641 vm_map_clip_end(map
, map_entry
, end_aligned
);
643 tmp_entry
= *map_entry
;
644 map_entry
= VM_MAP_ENTRY_NULL
; /* not valid after unlocking map */
649 * This map entry might be only partially encrypted
650 * (if not fully "page-aligned").
653 crypto_end
= tmp_entry
.vme_end
- tmp_entry
.vme_start
;
654 if (tmp_entry
.vme_start
< start
) {
655 if (tmp_entry
.vme_start
!= start_aligned
) {
656 kr
= KERN_INVALID_ADDRESS
;
658 crypto_start
+= (start
- tmp_entry
.vme_start
);
660 if (tmp_entry
.vme_end
> end
) {
661 if (tmp_entry
.vme_end
!= end_aligned
) {
662 kr
= KERN_INVALID_ADDRESS
;
664 crypto_end
-= (tmp_entry
.vme_end
- end
);
668 * This "extra backing offset" is needed to get the decryption
669 * routine to use the right key. It adjusts for the possibly
670 * relative offset of an interposed "4K" pager...
672 if (crypto_backing_offset
== (vm_object_offset_t
) -1) {
673 crypto_backing_offset
= VME_OFFSET(&tmp_entry
);
677 * Lookup (and create if necessary) the protected memory object
678 * matching that VM object.
679 * If successful, this also grabs a reference on the memory object,
680 * to guarantee that it doesn't go away before we get a chance to map
683 unprotected_mem_obj
= apple_protect_pager_setup(
685 VME_OFFSET(&tmp_entry
),
686 crypto_backing_offset
,
691 /* release extra ref on protected object */
692 vm_object_deallocate(protected_object
);
694 if (unprotected_mem_obj
== NULL
) {
699 vm_flags
= VM_FLAGS_FIXED
| VM_FLAGS_OVERWRITE
;
700 /* can overwrite an immutable mapping */
701 vmk_flags
.vmkf_overwrite_immutable
= TRUE
;
703 if (tmp_entry
.used_for_jit
&&
704 (VM_MAP_PAGE_SHIFT(map
) != FOURK_PAGE_SHIFT
||
705 PAGE_SHIFT
!= FOURK_PAGE_SHIFT
) &&
706 fourk_binary_compatibility_unsafe
&&
707 fourk_binary_compatibility_allow_wx
) {
708 printf("** FOURK_COMPAT [%d]: "
709 "allowing write+execute at 0x%llx\n",
710 proc_selfpid(), tmp_entry
.vme_start
);
711 vmk_flags
.vmkf_map_jit
= TRUE
;
713 #endif /* __arm64__ */
715 /* map this memory object in place of the current one */
716 map_addr
= tmp_entry
.vme_start
;
717 kr
= vm_map_enter_mem_object(map
,
720 tmp_entry
.vme_start
),
721 (mach_vm_offset_t
) 0,
725 (ipc_port_t
) unprotected_mem_obj
,
728 tmp_entry
.protection
,
729 tmp_entry
.max_protection
,
730 tmp_entry
.inheritance
);
731 assertf(kr
== KERN_SUCCESS
,
733 assertf(map_addr
== tmp_entry
.vme_start
,
734 "map_addr=0x%llx vme_start=0x%llx tmp_entry=%p\n",
736 (uint64_t) tmp_entry
.vme_start
,
739 #if VM_MAP_DEBUG_APPLE_PROTECT
740 if (vm_map_debug_apple_protect
) {
741 printf("APPLE_PROTECT: map %p [0x%llx:0x%llx] pager %p:"
742 " backing:[object:%p,offset:0x%llx,"
743 "crypto_backing_offset:0x%llx,"
744 "crypto_start:0x%llx,crypto_end:0x%llx]\n",
747 (uint64_t) (map_addr
+ (tmp_entry
.vme_end
-
748 tmp_entry
.vme_start
)),
751 VME_OFFSET(&tmp_entry
),
752 crypto_backing_offset
,
756 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
759 * Release the reference obtained by
760 * apple_protect_pager_setup().
761 * The mapping (if it succeeded) is now holding a reference on
764 memory_object_deallocate(unprotected_mem_obj
);
765 unprotected_mem_obj
= MEMORY_OBJECT_NULL
;
767 /* continue with next map entry */
768 crypto_backing_offset
+= (tmp_entry
.vme_end
-
769 tmp_entry
.vme_start
);
770 crypto_backing_offset
-= crypto_start
;
780 #endif /* CONFIG_CODE_DECRYPTION */
783 lck_grp_t vm_map_lck_grp
;
784 lck_grp_attr_t vm_map_lck_grp_attr
;
785 lck_attr_t vm_map_lck_attr
;
786 lck_attr_t vm_map_lck_rw_attr
;
792 * Initialize the vm_map module. Must be called before
793 * any other vm_map routines.
795 * Map and entry structures are allocated from zones -- we must
796 * initialize those zones.
798 * There are three zones of interest:
800 * vm_map_zone: used to allocate maps.
801 * vm_map_entry_zone: used to allocate map entries.
802 * vm_map_entry_reserved_zone: fallback zone for kernel map entries
804 * The kernel allocates map entries from a special zone that is initially
805 * "crammed" with memory. It would be difficult (perhaps impossible) for
806 * the kernel to allocate more memory to a entry zone when it became
807 * empty since the very act of allocating memory implies the creation
814 vm_size_t entry_zone_alloc_size
;
815 const char *mez_name
= "VM map entries";
817 vm_map_zone
= zinit((vm_map_size_t
) sizeof(struct _vm_map
), 40*1024,
819 zone_change(vm_map_zone
, Z_NOENCRYPT
, TRUE
);
820 #if defined(__LP64__)
821 entry_zone_alloc_size
= PAGE_SIZE
* 5;
823 entry_zone_alloc_size
= PAGE_SIZE
* 6;
825 vm_map_entry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
826 1024*1024, entry_zone_alloc_size
,
828 zone_change(vm_map_entry_zone
, Z_NOENCRYPT
, TRUE
);
829 zone_change(vm_map_entry_zone
, Z_NOCALLOUT
, TRUE
);
830 zone_change(vm_map_entry_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
832 vm_map_entry_reserved_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
833 kentry_data_size
* 64, kentry_data_size
,
834 "Reserved VM map entries");
835 zone_change(vm_map_entry_reserved_zone
, Z_NOENCRYPT
, TRUE
);
836 /* Don't quarantine because we always need elements available */
837 zone_change(vm_map_entry_reserved_zone
, Z_KASAN_QUARANTINE
, FALSE
);
839 vm_map_copy_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_copy
),
840 16*1024, PAGE_SIZE
, "VM map copies");
841 zone_change(vm_map_copy_zone
, Z_NOENCRYPT
, TRUE
);
843 vm_map_holes_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_links
),
844 16*1024, PAGE_SIZE
, "VM map holes");
845 zone_change(vm_map_holes_zone
, Z_NOENCRYPT
, TRUE
);
848 * Cram the map and kentry zones with initial data.
849 * Set reserved_zone non-collectible to aid zone_gc().
851 zone_change(vm_map_zone
, Z_COLLECT
, FALSE
);
852 zone_change(vm_map_zone
, Z_FOREIGN
, TRUE
);
853 zone_change(vm_map_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
855 zone_change(vm_map_entry_reserved_zone
, Z_COLLECT
, FALSE
);
856 zone_change(vm_map_entry_reserved_zone
, Z_EXPAND
, FALSE
);
857 zone_change(vm_map_entry_reserved_zone
, Z_FOREIGN
, TRUE
);
858 zone_change(vm_map_entry_reserved_zone
, Z_NOCALLOUT
, TRUE
);
859 zone_change(vm_map_entry_reserved_zone
, Z_CALLERACCT
, FALSE
); /* don't charge caller */
860 zone_change(vm_map_copy_zone
, Z_CALLERACCT
, FALSE
); /* don't charge caller */
861 zone_change(vm_map_entry_reserved_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
863 zone_change(vm_map_holes_zone
, Z_COLLECT
, TRUE
);
864 zone_change(vm_map_holes_zone
, Z_EXPAND
, TRUE
);
865 zone_change(vm_map_holes_zone
, Z_FOREIGN
, TRUE
);
866 zone_change(vm_map_holes_zone
, Z_NOCALLOUT
, TRUE
);
867 zone_change(vm_map_holes_zone
, Z_CALLERACCT
, TRUE
);
868 zone_change(vm_map_holes_zone
, Z_GZALLOC_EXEMPT
, TRUE
);
871 * Add the stolen memory to zones, adjust zone size and stolen counts.
872 * zcram only up to the maximum number of pages for each zone chunk.
874 zcram(vm_map_zone
, (vm_offset_t
)map_data
, map_data_size
);
876 const vm_size_t stride
= ZONE_CHUNK_MAXPAGES
* PAGE_SIZE
;
877 for (vm_offset_t off
= 0; off
< kentry_data_size
; off
+= stride
) {
878 zcram(vm_map_entry_reserved_zone
,
879 (vm_offset_t
)kentry_data
+ off
,
880 MIN(kentry_data_size
- off
, stride
));
882 for (vm_offset_t off
= 0; off
< map_holes_data_size
; off
+= stride
) {
883 zcram(vm_map_holes_zone
,
884 (vm_offset_t
)map_holes_data
+ off
,
885 MIN(map_holes_data_size
- off
, stride
));
888 VM_PAGE_MOVE_STOLEN(atop_64(map_data_size
) + atop_64(kentry_data_size
) + atop_64(map_holes_data_size
));
890 lck_grp_attr_setdefault(&vm_map_lck_grp_attr
);
891 lck_grp_init(&vm_map_lck_grp
, "vm_map", &vm_map_lck_grp_attr
);
892 lck_attr_setdefault(&vm_map_lck_attr
);
894 lck_attr_setdefault(&vm_map_lck_rw_attr
);
895 lck_attr_cleardebug(&vm_map_lck_rw_attr
);
897 #if VM_MAP_DEBUG_APPLE_PROTECT
898 PE_parse_boot_argn("vm_map_debug_apple_protect",
899 &vm_map_debug_apple_protect
,
900 sizeof(vm_map_debug_apple_protect
));
901 #endif /* VM_MAP_DEBUG_APPLE_PROTECT */
902 #if VM_MAP_DEBUG_APPLE_FOURK
903 PE_parse_boot_argn("vm_map_debug_fourk",
905 sizeof(vm_map_debug_fourk
));
906 #endif /* VM_MAP_DEBUG_FOURK */
907 PE_parse_boot_argn("vm_map_executable_immutable",
908 &vm_map_executable_immutable
,
909 sizeof(vm_map_executable_immutable
));
910 PE_parse_boot_argn("vm_map_executable_immutable_no_log",
911 &vm_map_executable_immutable_no_log
,
912 sizeof(vm_map_executable_immutable_no_log
));
919 uint32_t kentry_initial_pages
;
921 map_data_size
= round_page(10 * sizeof(struct _vm_map
));
922 map_data
= pmap_steal_memory(map_data_size
);
925 * kentry_initial_pages corresponds to the number of kernel map entries
926 * required during bootstrap until the asynchronous replenishment
927 * scheme is activated and/or entries are available from the general
930 #if defined(__LP64__)
931 kentry_initial_pages
= 10;
933 kentry_initial_pages
= 6;
937 /* If using the guard allocator, reserve more memory for the kernel
938 * reserved map entry pool.
940 if (gzalloc_enabled())
941 kentry_initial_pages
*= 1024;
944 kentry_data_size
= kentry_initial_pages
* PAGE_SIZE
;
945 kentry_data
= pmap_steal_memory(kentry_data_size
);
947 map_holes_data_size
= kentry_data_size
;
948 map_holes_data
= pmap_steal_memory(map_holes_data_size
);
951 boolean_t vm_map_supports_hole_optimization
= FALSE
;
954 vm_kernel_reserved_entry_init(void) {
955 zone_prio_refill_configure(vm_map_entry_reserved_zone
, (6*PAGE_SIZE
)/sizeof(struct vm_map_entry
));
958 * Once we have our replenish thread set up, we can start using the vm_map_holes zone.
960 zone_prio_refill_configure(vm_map_holes_zone
, (6*PAGE_SIZE
)/sizeof(struct vm_map_links
));
961 vm_map_supports_hole_optimization
= TRUE
;
965 vm_map_disable_hole_optimization(vm_map_t map
)
967 vm_map_entry_t head_entry
, hole_entry
, next_hole_entry
;
969 if (map
->holelistenabled
) {
971 head_entry
= hole_entry
= (vm_map_entry_t
) map
->holes_list
;
973 while (hole_entry
!= NULL
) {
975 next_hole_entry
= hole_entry
->vme_next
;
977 hole_entry
->vme_next
= NULL
;
978 hole_entry
->vme_prev
= NULL
;
979 zfree(vm_map_holes_zone
, hole_entry
);
981 if (next_hole_entry
== head_entry
) {
984 hole_entry
= next_hole_entry
;
988 map
->holes_list
= NULL
;
989 map
->holelistenabled
= FALSE
;
991 map
->first_free
= vm_map_first_entry(map
);
992 SAVE_HINT_HOLE_WRITE(map
, NULL
);
997 vm_kernel_map_is_kernel(vm_map_t map
) {
998 return (map
->pmap
== kernel_pmap
);
1004 * Creates and returns a new empty VM map with
1005 * the given physical map structure, and having
1006 * the given lower and upper address bounds.
1012 vm_map_offset_t min
,
1013 vm_map_offset_t max
,
1016 static int color_seed
= 0;
1018 struct vm_map_links
*hole_entry
= NULL
;
1020 result
= (vm_map_t
) zalloc(vm_map_zone
);
1021 if (result
== VM_MAP_NULL
)
1022 panic("vm_map_create");
1024 vm_map_first_entry(result
) = vm_map_to_entry(result
);
1025 vm_map_last_entry(result
) = vm_map_to_entry(result
);
1026 result
->hdr
.nentries
= 0;
1027 result
->hdr
.entries_pageable
= pageable
;
1029 vm_map_store_init( &(result
->hdr
) );
1031 result
->hdr
.page_shift
= PAGE_SHIFT
;
1034 result
->user_wire_limit
= MACH_VM_MAX_ADDRESS
; /* default limit is unlimited */
1035 result
->user_wire_size
= 0;
1037 result
->vmmap_high_start
= 0;
1038 #endif /* __x86_64__ */
1039 result
->ref_count
= 1;
1041 result
->res_count
= 1;
1042 result
->sw_state
= MAP_SW_IN
;
1043 #endif /* TASK_SWAPPER */
1044 result
->pmap
= pmap
;
1045 result
->min_offset
= min
;
1046 result
->max_offset
= max
;
1047 result
->wiring_required
= FALSE
;
1048 result
->no_zero_fill
= FALSE
;
1049 result
->mapped_in_other_pmaps
= FALSE
;
1050 result
->wait_for_space
= FALSE
;
1051 result
->switch_protect
= FALSE
;
1052 result
->disable_vmentry_reuse
= FALSE
;
1053 result
->map_disallow_data_exec
= FALSE
;
1054 result
->is_nested_map
= FALSE
;
1055 result
->highest_entry_end
= 0;
1056 result
->first_free
= vm_map_to_entry(result
);
1057 result
->hint
= vm_map_to_entry(result
);
1058 result
->color_rr
= (color_seed
++) & vm_color_mask
;
1059 result
->jit_entry_exists
= FALSE
;
1061 if (vm_map_supports_hole_optimization
) {
1062 hole_entry
= zalloc(vm_map_holes_zone
);
1064 hole_entry
->start
= min
;
1065 #if defined(__arm__) || defined(__arm64__)
1066 hole_entry
->end
= result
->max_offset
;
1068 hole_entry
->end
= (max
> (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
) ? max
: (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
;
1070 result
->holes_list
= result
->hole_hint
= hole_entry
;
1071 hole_entry
->prev
= hole_entry
->next
= (vm_map_entry_t
) hole_entry
;
1072 result
->holelistenabled
= TRUE
;
1076 result
->holelistenabled
= FALSE
;
1079 vm_map_lock_init(result
);
1080 lck_mtx_init_ext(&result
->s_lock
, &result
->s_lock_ext
, &vm_map_lck_grp
, &vm_map_lck_attr
);
1086 * vm_map_entry_create: [ internal use only ]
1088 * Allocates a VM map entry for insertion in the
1089 * given map (or map copy). No fields are filled.
1091 #define vm_map_entry_create(map, map_locked) _vm_map_entry_create(&(map)->hdr, map_locked)
1093 #define vm_map_copy_entry_create(copy, map_locked) \
1094 _vm_map_entry_create(&(copy)->cpy_hdr, map_locked)
1095 unsigned reserved_zalloc_count
, nonreserved_zalloc_count
;
1097 static vm_map_entry_t
1098 _vm_map_entry_create(
1099 struct vm_map_header
*map_header
, boolean_t __unused map_locked
)
1102 vm_map_entry_t entry
;
1104 zone
= vm_map_entry_zone
;
1106 assert(map_header
->entries_pageable
? !map_locked
: TRUE
);
1108 if (map_header
->entries_pageable
) {
1109 entry
= (vm_map_entry_t
) zalloc(zone
);
1112 entry
= (vm_map_entry_t
) zalloc_canblock(zone
, FALSE
);
1114 if (entry
== VM_MAP_ENTRY_NULL
) {
1115 zone
= vm_map_entry_reserved_zone
;
1116 entry
= (vm_map_entry_t
) zalloc(zone
);
1117 OSAddAtomic(1, &reserved_zalloc_count
);
1119 OSAddAtomic(1, &nonreserved_zalloc_count
);
1122 if (entry
== VM_MAP_ENTRY_NULL
)
1123 panic("vm_map_entry_create");
1124 entry
->from_reserved_zone
= (zone
== vm_map_entry_reserved_zone
);
1126 vm_map_store_update( (vm_map_t
) NULL
, entry
, VM_MAP_ENTRY_CREATE
);
1127 #if MAP_ENTRY_CREATION_DEBUG
1128 entry
->vme_creation_maphdr
= map_header
;
1129 backtrace(&entry
->vme_creation_bt
[0],
1130 (sizeof(entry
->vme_creation_bt
)/sizeof(uintptr_t)));
1136 * vm_map_entry_dispose: [ internal use only ]
1138 * Inverse of vm_map_entry_create.
1140 * write map lock held so no need to
1141 * do anything special to insure correctness
1144 #define vm_map_entry_dispose(map, entry) \
1145 _vm_map_entry_dispose(&(map)->hdr, (entry))
1147 #define vm_map_copy_entry_dispose(map, entry) \
1148 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
1151 _vm_map_entry_dispose(
1152 struct vm_map_header
*map_header
,
1153 vm_map_entry_t entry
)
1157 if (map_header
->entries_pageable
|| !(entry
->from_reserved_zone
))
1158 zone
= vm_map_entry_zone
;
1160 zone
= vm_map_entry_reserved_zone
;
1162 if (!map_header
->entries_pageable
) {
1163 if (zone
== vm_map_entry_zone
)
1164 OSAddAtomic(-1, &nonreserved_zalloc_count
);
1166 OSAddAtomic(-1, &reserved_zalloc_count
);
1173 static boolean_t first_free_check
= FALSE
;
1175 first_free_is_valid(
1178 if (!first_free_check
)
1181 return( first_free_is_valid_store( map
));
1183 #endif /* MACH_ASSERT */
1186 #define vm_map_copy_entry_link(copy, after_where, entry) \
1187 _vm_map_store_entry_link(&(copy)->cpy_hdr, after_where, (entry))
1189 #define vm_map_copy_entry_unlink(copy, entry) \
1190 _vm_map_store_entry_unlink(&(copy)->cpy_hdr, (entry))
1192 #if MACH_ASSERT && TASK_SWAPPER
1194 * vm_map_res_reference:
1196 * Adds another valid residence count to the given map.
1198 * Map is locked so this function can be called from
1202 void vm_map_res_reference(vm_map_t map
)
1204 /* assert map is locked */
1205 assert(map
->res_count
>= 0);
1206 assert(map
->ref_count
>= map
->res_count
);
1207 if (map
->res_count
== 0) {
1208 lck_mtx_unlock(&map
->s_lock
);
1211 lck_mtx_lock(&map
->s_lock
);
1219 * vm_map_reference_swap:
1221 * Adds valid reference and residence counts to the given map.
1223 * The map may not be in memory (i.e. zero residence count).
1226 void vm_map_reference_swap(vm_map_t map
)
1228 assert(map
!= VM_MAP_NULL
);
1229 lck_mtx_lock(&map
->s_lock
);
1230 assert(map
->res_count
>= 0);
1231 assert(map
->ref_count
>= map
->res_count
);
1233 vm_map_res_reference(map
);
1234 lck_mtx_unlock(&map
->s_lock
);
1238 * vm_map_res_deallocate:
1240 * Decrement residence count on a map; possibly causing swapout.
1242 * The map must be in memory (i.e. non-zero residence count).
1244 * The map is locked, so this function is callable from vm_map_deallocate.
1247 void vm_map_res_deallocate(vm_map_t map
)
1249 assert(map
->res_count
> 0);
1250 if (--map
->res_count
== 0) {
1251 lck_mtx_unlock(&map
->s_lock
);
1253 vm_map_swapout(map
);
1255 lck_mtx_lock(&map
->s_lock
);
1257 assert(map
->ref_count
>= map
->res_count
);
1259 #endif /* MACH_ASSERT && TASK_SWAPPER */
1264 * Actually destroy a map.
1273 /* final cleanup: no need to unnest shared region */
1274 flags
|= VM_MAP_REMOVE_NO_UNNESTING
;
1275 /* final cleanup: ok to remove immutable mappings */
1276 flags
|= VM_MAP_REMOVE_IMMUTABLE
;
1278 /* clean up regular map entries */
1279 (void) vm_map_delete(map
, map
->min_offset
, map
->max_offset
,
1280 flags
, VM_MAP_NULL
);
1281 /* clean up leftover special mappings (commpage, etc...) */
1282 #if !defined(__arm__) && !defined(__arm64__)
1283 (void) vm_map_delete(map
, 0x0, 0xFFFFFFFFFFFFF000ULL
,
1284 flags
, VM_MAP_NULL
);
1285 #endif /* !__arm__ && !__arm64__ */
1287 vm_map_disable_hole_optimization(map
);
1290 assert(map
->hdr
.nentries
== 0);
1293 pmap_destroy(map
->pmap
);
1295 if (vm_map_lck_attr
.lck_attr_val
& LCK_ATTR_DEBUG
) {
1297 * If lock debugging is enabled the mutexes get tagged as LCK_MTX_TAG_INDIRECT.
1298 * And this is regardless of whether the lck_mtx_ext_t is embedded in the
1299 * structure or kalloc'ed via lck_mtx_init.
1300 * An example is s_lock_ext within struct _vm_map.
1302 * A lck_mtx_destroy on such a mutex will attempt a kfree and panic. We
1303 * can add another tag to detect embedded vs alloc'ed indirect external
1304 * mutexes but that'll be additional checks in the lock path and require
1305 * updating dependencies for the old vs new tag.
1307 * Since the kfree() is for LCK_MTX_TAG_INDIRECT mutexes and that tag is applied
1308 * just when lock debugging is ON, we choose to forego explicitly destroying
1309 * the vm_map mutex and rw lock and, as a consequence, will overflow the reference
1310 * count on vm_map_lck_grp, which has no serious side-effect.
1313 lck_rw_destroy(&(map
)->lock
, &vm_map_lck_grp
);
1314 lck_mtx_destroy(&(map
)->s_lock
, &vm_map_lck_grp
);
1317 zfree(vm_map_zone
, map
);
1321 * Returns pid of the task with the largest number of VM map entries.
1322 * Used in the zone-map-exhaustion jetsam path.
1325 find_largest_process_vm_map_entries(void)
1327 pid_t victim_pid
= -1;
1328 int max_vm_map_entries
= 0;
1329 task_t task
= TASK_NULL
;
1330 queue_head_t
*task_list
= &tasks
;
1332 lck_mtx_lock(&tasks_threads_lock
);
1333 queue_iterate(task_list
, task
, task_t
, tasks
) {
1334 if (task
== kernel_task
|| !task
->active
)
1337 vm_map_t task_map
= task
->map
;
1338 if (task_map
!= VM_MAP_NULL
) {
1339 int task_vm_map_entries
= task_map
->hdr
.nentries
;
1340 if (task_vm_map_entries
> max_vm_map_entries
) {
1341 max_vm_map_entries
= task_vm_map_entries
;
1342 victim_pid
= pid_from_task(task
);
1346 lck_mtx_unlock(&tasks_threads_lock
);
1348 printf("zone_map_exhaustion: victim pid %d, vm region count: %d\n", victim_pid
, max_vm_map_entries
);
1354 * vm_map_swapin/vm_map_swapout
1356 * Swap a map in and out, either referencing or releasing its resources.
1357 * These functions are internal use only; however, they must be exported
1358 * because they may be called from macros, which are exported.
1360 * In the case of swapout, there could be races on the residence count,
1361 * so if the residence count is up, we return, assuming that a
1362 * vm_map_deallocate() call in the near future will bring us back.
1365 * -- We use the map write lock for synchronization among races.
1366 * -- The map write lock, and not the simple s_lock, protects the
1367 * swap state of the map.
1368 * -- If a map entry is a share map, then we hold both locks, in
1369 * hierarchical order.
1371 * Synchronization Notes:
1372 * 1) If a vm_map_swapin() call happens while swapout in progress, it
1373 * will block on the map lock and proceed when swapout is through.
1374 * 2) A vm_map_reference() call at this time is illegal, and will
1375 * cause a panic. vm_map_reference() is only allowed on resident
1376 * maps, since it refuses to block.
1377 * 3) A vm_map_swapin() call during a swapin will block, and
1378 * proceeed when the first swapin is done, turning into a nop.
1379 * This is the reason the res_count is not incremented until
1380 * after the swapin is complete.
1381 * 4) There is a timing hole after the checks of the res_count, before
1382 * the map lock is taken, during which a swapin may get the lock
1383 * before a swapout about to happen. If this happens, the swapin
1384 * will detect the state and increment the reference count, causing
1385 * the swapout to be a nop, thereby delaying it until a later
1386 * vm_map_deallocate. If the swapout gets the lock first, then
1387 * the swapin will simply block until the swapout is done, and
1390 * Because vm_map_swapin() is potentially an expensive operation, it
1391 * should be used with caution.
1394 * 1) A map with a residence count of zero is either swapped, or
1396 * 2) A map with a non-zero residence count is either resident,
1397 * or being swapped in.
1400 int vm_map_swap_enable
= 1;
1402 void vm_map_swapin (vm_map_t map
)
1404 vm_map_entry_t entry
;
1406 if (!vm_map_swap_enable
) /* debug */
1411 * First deal with various races.
1413 if (map
->sw_state
== MAP_SW_IN
)
1415 * we raced with swapout and won. Returning will incr.
1416 * the res_count, turning the swapout into a nop.
1421 * The residence count must be zero. If we raced with another
1422 * swapin, the state would have been IN; if we raced with a
1423 * swapout (after another competing swapin), we must have lost
1424 * the race to get here (see above comment), in which case
1425 * res_count is still 0.
1427 assert(map
->res_count
== 0);
1430 * There are no intermediate states of a map going out or
1431 * coming in, since the map is locked during the transition.
1433 assert(map
->sw_state
== MAP_SW_OUT
);
1436 * We now operate upon each map entry. If the entry is a sub-
1437 * or share-map, we call vm_map_res_reference upon it.
1438 * If the entry is an object, we call vm_object_res_reference
1439 * (this may iterate through the shadow chain).
1440 * Note that we hold the map locked the entire time,
1441 * even if we get back here via a recursive call in
1442 * vm_map_res_reference.
1444 entry
= vm_map_first_entry(map
);
1446 while (entry
!= vm_map_to_entry(map
)) {
1447 if (VME_OBJECT(entry
) != VM_OBJECT_NULL
) {
1448 if (entry
->is_sub_map
) {
1449 vm_map_t lmap
= VME_SUBMAP(entry
);
1450 lck_mtx_lock(&lmap
->s_lock
);
1451 vm_map_res_reference(lmap
);
1452 lck_mtx_unlock(&lmap
->s_lock
);
1454 vm_object_t object
= VME_OBEJCT(entry
);
1455 vm_object_lock(object
);
1457 * This call may iterate through the
1460 vm_object_res_reference(object
);
1461 vm_object_unlock(object
);
1464 entry
= entry
->vme_next
;
1466 assert(map
->sw_state
== MAP_SW_OUT
);
1467 map
->sw_state
= MAP_SW_IN
;
1470 void vm_map_swapout(vm_map_t map
)
1472 vm_map_entry_t entry
;
1476 * First deal with various races.
1477 * If we raced with a swapin and lost, the residence count
1478 * will have been incremented to 1, and we simply return.
1480 lck_mtx_lock(&map
->s_lock
);
1481 if (map
->res_count
!= 0) {
1482 lck_mtx_unlock(&map
->s_lock
);
1485 lck_mtx_unlock(&map
->s_lock
);
1488 * There are no intermediate states of a map going out or
1489 * coming in, since the map is locked during the transition.
1491 assert(map
->sw_state
== MAP_SW_IN
);
1493 if (!vm_map_swap_enable
)
1497 * We now operate upon each map entry. If the entry is a sub-
1498 * or share-map, we call vm_map_res_deallocate upon it.
1499 * If the entry is an object, we call vm_object_res_deallocate
1500 * (this may iterate through the shadow chain).
1501 * Note that we hold the map locked the entire time,
1502 * even if we get back here via a recursive call in
1503 * vm_map_res_deallocate.
1505 entry
= vm_map_first_entry(map
);
1507 while (entry
!= vm_map_to_entry(map
)) {
1508 if (VME_OBJECT(entry
) != VM_OBJECT_NULL
) {
1509 if (entry
->is_sub_map
) {
1510 vm_map_t lmap
= VME_SUBMAP(entry
);
1511 lck_mtx_lock(&lmap
->s_lock
);
1512 vm_map_res_deallocate(lmap
);
1513 lck_mtx_unlock(&lmap
->s_lock
);
1515 vm_object_t object
= VME_OBJECT(entry
);
1516 vm_object_lock(object
);
1518 * This call may take a long time,
1519 * since it could actively push
1520 * out pages (if we implement it
1523 vm_object_res_deallocate(object
);
1524 vm_object_unlock(object
);
1527 entry
= entry
->vme_next
;
1529 assert(map
->sw_state
== MAP_SW_IN
);
1530 map
->sw_state
= MAP_SW_OUT
;
1533 #endif /* TASK_SWAPPER */
1536 * vm_map_lookup_entry: [ internal use only ]
1538 * Calls into the vm map store layer to find the map
1539 * entry containing (or immediately preceding) the
1540 * specified address in the given map; the entry is returned
1541 * in the "entry" parameter. The boolean
1542 * result indicates whether the address is
1543 * actually contained in the map.
1546 vm_map_lookup_entry(
1548 vm_map_offset_t address
,
1549 vm_map_entry_t
*entry
) /* OUT */
1551 return ( vm_map_store_lookup_entry( map
, address
, entry
));
1555 * Routine: vm_map_find_space
1557 * Allocate a range in the specified virtual address map,
1558 * returning the entry allocated for that range.
1559 * Used by kmem_alloc, etc.
1561 * The map must be NOT be locked. It will be returned locked
1562 * on KERN_SUCCESS, unlocked on failure.
1564 * If an entry is allocated, the object/offset fields
1565 * are initialized to zero.
1570 vm_map_offset_t
*address
, /* OUT */
1572 vm_map_offset_t mask
,
1574 vm_map_kernel_flags_t vmk_flags
,
1576 vm_map_entry_t
*o_entry
) /* OUT */
1578 vm_map_entry_t entry
, new_entry
;
1579 vm_map_offset_t start
;
1580 vm_map_offset_t end
;
1581 vm_map_entry_t hole_entry
;
1585 return KERN_INVALID_ARGUMENT
;
1588 if (vmk_flags
.vmkf_guard_after
) {
1589 /* account for the back guard page in the size */
1590 size
+= VM_MAP_PAGE_SIZE(map
);
1593 new_entry
= vm_map_entry_create(map
, FALSE
);
1596 * Look for the first possible address; if there's already
1597 * something at this address, we have to start after it.
1602 if( map
->disable_vmentry_reuse
== TRUE
) {
1603 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
1605 if (map
->holelistenabled
) {
1606 hole_entry
= (vm_map_entry_t
)map
->holes_list
;
1608 if (hole_entry
== NULL
) {
1610 * No more space in the map?
1612 vm_map_entry_dispose(map
, new_entry
);
1614 return(KERN_NO_SPACE
);
1618 start
= entry
->vme_start
;
1620 assert(first_free_is_valid(map
));
1621 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1622 start
= map
->min_offset
;
1624 start
= entry
->vme_end
;
1629 * In any case, the "entry" always precedes
1630 * the proposed new region throughout the loop:
1634 vm_map_entry_t next
;
1637 * Find the end of the proposed new region.
1638 * Be sure we didn't go beyond the end, or
1639 * wrap around the address.
1642 if (vmk_flags
.vmkf_guard_before
) {
1643 /* reserve space for the front guard page */
1644 start
+= VM_MAP_PAGE_SIZE(map
);
1646 end
= ((start
+ mask
) & ~mask
);
1649 vm_map_entry_dispose(map
, new_entry
);
1651 return(KERN_NO_SPACE
);
1656 if ((end
> map
->max_offset
) || (end
< start
)) {
1657 vm_map_entry_dispose(map
, new_entry
);
1659 return(KERN_NO_SPACE
);
1662 next
= entry
->vme_next
;
1664 if (map
->holelistenabled
) {
1665 if (entry
->vme_end
>= end
)
1669 * If there are no more entries, we must win.
1673 * If there is another entry, it must be
1674 * after the end of the potential new region.
1677 if (next
== vm_map_to_entry(map
))
1680 if (next
->vme_start
>= end
)
1685 * Didn't fit -- move to the next entry.
1690 if (map
->holelistenabled
) {
1691 if (entry
== (vm_map_entry_t
) map
->holes_list
) {
1695 vm_map_entry_dispose(map
, new_entry
);
1697 return(KERN_NO_SPACE
);
1699 start
= entry
->vme_start
;
1701 start
= entry
->vme_end
;
1705 if (map
->holelistenabled
) {
1706 if (vm_map_lookup_entry(map
, entry
->vme_start
, &entry
)) {
1707 panic("Found an existing entry (%p) instead of potential hole at address: 0x%llx.\n", entry
, (unsigned long long)entry
->vme_start
);
1713 * "start" and "end" should define the endpoints of the
1714 * available new range, and
1715 * "entry" should refer to the region before the new
1718 * the map should be locked.
1721 if (vmk_flags
.vmkf_guard_before
) {
1722 /* go back for the front guard page */
1723 start
-= VM_MAP_PAGE_SIZE(map
);
1727 assert(start
< end
);
1728 new_entry
->vme_start
= start
;
1729 new_entry
->vme_end
= end
;
1730 assert(page_aligned(new_entry
->vme_start
));
1731 assert(page_aligned(new_entry
->vme_end
));
1732 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_start
,
1733 VM_MAP_PAGE_MASK(map
)));
1734 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_end
,
1735 VM_MAP_PAGE_MASK(map
)));
1737 new_entry
->is_shared
= FALSE
;
1738 new_entry
->is_sub_map
= FALSE
;
1739 new_entry
->use_pmap
= TRUE
;
1740 VME_OBJECT_SET(new_entry
, VM_OBJECT_NULL
);
1741 VME_OFFSET_SET(new_entry
, (vm_object_offset_t
) 0);
1743 new_entry
->needs_copy
= FALSE
;
1745 new_entry
->inheritance
= VM_INHERIT_DEFAULT
;
1746 new_entry
->protection
= VM_PROT_DEFAULT
;
1747 new_entry
->max_protection
= VM_PROT_ALL
;
1748 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
1749 new_entry
->wired_count
= 0;
1750 new_entry
->user_wired_count
= 0;
1752 new_entry
->in_transition
= FALSE
;
1753 new_entry
->needs_wakeup
= FALSE
;
1754 new_entry
->no_cache
= FALSE
;
1755 new_entry
->permanent
= FALSE
;
1756 new_entry
->superpage_size
= FALSE
;
1757 if (VM_MAP_PAGE_SHIFT(map
) != PAGE_SHIFT
) {
1758 new_entry
->map_aligned
= TRUE
;
1760 new_entry
->map_aligned
= FALSE
;
1763 new_entry
->used_for_jit
= FALSE
;
1764 new_entry
->zero_wired_pages
= FALSE
;
1765 new_entry
->iokit_acct
= FALSE
;
1766 new_entry
->vme_resilient_codesign
= FALSE
;
1767 new_entry
->vme_resilient_media
= FALSE
;
1768 if (vmk_flags
.vmkf_atomic_entry
)
1769 new_entry
->vme_atomic
= TRUE
;
1771 new_entry
->vme_atomic
= FALSE
;
1773 VME_ALIAS_SET(new_entry
, tag
);
1776 * Insert the new entry into the list
1779 vm_map_store_entry_link(map
, entry
, new_entry
);
1784 * Update the lookup hint
1786 SAVE_HINT_MAP_WRITE(map
, new_entry
);
1788 *o_entry
= new_entry
;
1789 return(KERN_SUCCESS
);
1792 int vm_map_pmap_enter_print
= FALSE
;
1793 int vm_map_pmap_enter_enable
= FALSE
;
1796 * Routine: vm_map_pmap_enter [internal only]
1799 * Force pages from the specified object to be entered into
1800 * the pmap at the specified address if they are present.
1801 * As soon as a page not found in the object the scan ends.
1806 * In/out conditions:
1807 * The source map should not be locked on entry.
1809 __unused
static void
1812 vm_map_offset_t addr
,
1813 vm_map_offset_t end_addr
,
1815 vm_object_offset_t offset
,
1816 vm_prot_t protection
)
1824 while (addr
< end_addr
) {
1830 * From vm_map_enter(), we come into this function without the map
1831 * lock held or the object lock held.
1832 * We haven't taken a reference on the object either.
1833 * We should do a proper lookup on the map to make sure
1834 * that things are sane before we go locking objects that
1835 * could have been deallocated from under us.
1838 vm_object_lock(object
);
1840 m
= vm_page_lookup(object
, offset
);
1842 if (m
== VM_PAGE_NULL
|| m
->busy
|| m
->fictitious
||
1843 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
))) {
1844 vm_object_unlock(object
);
1848 if (vm_map_pmap_enter_print
) {
1849 printf("vm_map_pmap_enter:");
1850 printf("map: %p, addr: %llx, object: %p, offset: %llx\n",
1851 map
, (unsigned long long)addr
, object
, (unsigned long long)offset
);
1853 type_of_fault
= DBG_CACHE_HIT_FAULT
;
1854 kr
= vm_fault_enter(m
, map
->pmap
, addr
, protection
, protection
,
1856 FALSE
, /* change_wiring */
1857 VM_KERN_MEMORY_NONE
, /* tag - not wiring */
1858 FALSE
, /* no_cache */
1859 FALSE
, /* cs_bypass */
1860 0, /* XXX need user tag / alias? */
1861 0, /* pmap_options */
1862 NULL
, /* need_retry */
1865 vm_object_unlock(object
);
1867 offset
+= PAGE_SIZE_64
;
1872 boolean_t
vm_map_pmap_is_empty(
1874 vm_map_offset_t start
,
1875 vm_map_offset_t end
);
1876 boolean_t
vm_map_pmap_is_empty(
1878 vm_map_offset_t start
,
1879 vm_map_offset_t end
)
1881 #ifdef MACHINE_PMAP_IS_EMPTY
1882 return pmap_is_empty(map
->pmap
, start
, end
);
1883 #else /* MACHINE_PMAP_IS_EMPTY */
1884 vm_map_offset_t offset
;
1887 if (map
->pmap
== NULL
) {
1891 for (offset
= start
;
1893 offset
+= PAGE_SIZE
) {
1894 phys_page
= pmap_find_phys(map
->pmap
, offset
);
1896 kprintf("vm_map_pmap_is_empty(%p,0x%llx,0x%llx): "
1897 "page %d at 0x%llx\n",
1898 map
, (long long)start
, (long long)end
,
1899 phys_page
, (long long)offset
);
1904 #endif /* MACHINE_PMAP_IS_EMPTY */
1907 #define MAX_TRIES_TO_GET_RANDOM_ADDRESS 1000
1909 vm_map_random_address_for_size(
1911 vm_map_offset_t
*address
,
1914 kern_return_t kr
= KERN_SUCCESS
;
1916 vm_map_offset_t random_addr
= 0;
1917 vm_map_offset_t hole_end
;
1919 vm_map_entry_t next_entry
= VM_MAP_ENTRY_NULL
;
1920 vm_map_entry_t prev_entry
= VM_MAP_ENTRY_NULL
;
1921 vm_map_size_t vm_hole_size
= 0;
1922 vm_map_size_t addr_space_size
;
1924 addr_space_size
= vm_map_max(map
) - vm_map_min(map
);
1926 assert(page_aligned(size
));
1928 while (tries
< MAX_TRIES_TO_GET_RANDOM_ADDRESS
) {
1929 random_addr
= ((vm_map_offset_t
)random()) << PAGE_SHIFT
;
1930 random_addr
= vm_map_trunc_page(
1931 vm_map_min(map
) +(random_addr
% addr_space_size
),
1932 VM_MAP_PAGE_MASK(map
));
1934 if (vm_map_lookup_entry(map
, random_addr
, &prev_entry
) == FALSE
) {
1935 if (prev_entry
== vm_map_to_entry(map
)) {
1936 next_entry
= vm_map_first_entry(map
);
1938 next_entry
= prev_entry
->vme_next
;
1940 if (next_entry
== vm_map_to_entry(map
)) {
1941 hole_end
= vm_map_max(map
);
1943 hole_end
= next_entry
->vme_start
;
1945 vm_hole_size
= hole_end
- random_addr
;
1946 if (vm_hole_size
>= size
) {
1947 *address
= random_addr
;
1954 if (tries
== MAX_TRIES_TO_GET_RANDOM_ADDRESS
) {
1961 * Routine: vm_map_enter
1964 * Allocate a range in the specified virtual address map.
1965 * The resulting range will refer to memory defined by
1966 * the given memory object and offset into that object.
1968 * Arguments are as defined in the vm_map call.
1970 int _map_enter_debug
= 0;
1971 static unsigned int vm_map_enter_restore_successes
= 0;
1972 static unsigned int vm_map_enter_restore_failures
= 0;
1976 vm_map_offset_t
*address
, /* IN/OUT */
1978 vm_map_offset_t mask
,
1980 vm_map_kernel_flags_t vmk_flags
,
1983 vm_object_offset_t offset
,
1984 boolean_t needs_copy
,
1985 vm_prot_t cur_protection
,
1986 vm_prot_t max_protection
,
1987 vm_inherit_t inheritance
)
1989 vm_map_entry_t entry
, new_entry
;
1990 vm_map_offset_t start
, tmp_start
, tmp_offset
;
1991 vm_map_offset_t end
, tmp_end
;
1992 vm_map_offset_t tmp2_start
, tmp2_end
;
1993 vm_map_offset_t step
;
1994 kern_return_t result
= KERN_SUCCESS
;
1995 vm_map_t zap_old_map
= VM_MAP_NULL
;
1996 vm_map_t zap_new_map
= VM_MAP_NULL
;
1997 boolean_t map_locked
= FALSE
;
1998 boolean_t pmap_empty
= TRUE
;
1999 boolean_t new_mapping_established
= FALSE
;
2000 boolean_t keep_map_locked
= vmk_flags
.vmkf_keep_map_locked
;
2001 boolean_t anywhere
= ((flags
& VM_FLAGS_ANYWHERE
) != 0);
2002 boolean_t purgable
= ((flags
& VM_FLAGS_PURGABLE
) != 0);
2003 boolean_t overwrite
= ((flags
& VM_FLAGS_OVERWRITE
) != 0);
2004 boolean_t no_cache
= ((flags
& VM_FLAGS_NO_CACHE
) != 0);
2005 boolean_t is_submap
= vmk_flags
.vmkf_submap
;
2006 boolean_t permanent
= vmk_flags
.vmkf_permanent
;
2007 boolean_t entry_for_jit
= vmk_flags
.vmkf_map_jit
;
2008 boolean_t iokit_acct
= vmk_flags
.vmkf_iokit_acct
;
2009 boolean_t resilient_codesign
= ((flags
& VM_FLAGS_RESILIENT_CODESIGN
) != 0);
2010 boolean_t resilient_media
= ((flags
& VM_FLAGS_RESILIENT_MEDIA
) != 0);
2011 boolean_t random_address
= ((flags
& VM_FLAGS_RANDOM_ADDR
) != 0);
2012 unsigned int superpage_size
= ((flags
& VM_FLAGS_SUPERPAGE_MASK
) >> VM_FLAGS_SUPERPAGE_SHIFT
);
2013 vm_tag_t user_alias
;
2014 vm_map_offset_t effective_min_offset
, effective_max_offset
;
2016 boolean_t clear_map_aligned
= FALSE
;
2017 vm_map_entry_t hole_entry
;
2019 assertf(vmk_flags
.__vmkf_unused
== 0, "vmk_flags unused=0x%x\n", vmk_flags
.__vmkf_unused
);
2021 if (superpage_size
) {
2022 switch (superpage_size
) {
2024 * Note that the current implementation only supports
2025 * a single size for superpages, SUPERPAGE_SIZE, per
2026 * architecture. As soon as more sizes are supposed
2027 * to be supported, SUPERPAGE_SIZE has to be replaced
2028 * with a lookup of the size depending on superpage_size.
2031 case SUPERPAGE_SIZE_ANY
:
2032 /* handle it like 2 MB and round up to page size */
2033 size
= (size
+ 2*1024*1024 - 1) & ~(2*1024*1024 - 1);
2034 case SUPERPAGE_SIZE_2MB
:
2038 return KERN_INVALID_ARGUMENT
;
2040 mask
= SUPERPAGE_SIZE
-1;
2041 if (size
& (SUPERPAGE_SIZE
-1))
2042 return KERN_INVALID_ARGUMENT
;
2043 inheritance
= VM_INHERIT_NONE
; /* fork() children won't inherit superpages */
2048 if (cur_protection
& VM_PROT_WRITE
){
2049 if ((cur_protection
& VM_PROT_EXECUTE
) && !entry_for_jit
){
2050 printf("EMBEDDED: %s: curprot cannot be write+execute. "
2051 "turning off execute\n",
2053 cur_protection
&= ~VM_PROT_EXECUTE
;
2056 #endif /* CONFIG_EMBEDDED */
2058 if (resilient_codesign
|| resilient_media
) {
2059 if ((cur_protection
& (VM_PROT_WRITE
| VM_PROT_EXECUTE
)) ||
2060 (max_protection
& (VM_PROT_WRITE
| VM_PROT_EXECUTE
))) {
2061 return KERN_PROTECTION_FAILURE
;
2067 /* submaps can not be purgeable */
2068 return KERN_INVALID_ARGUMENT
;
2070 if (object
== VM_OBJECT_NULL
) {
2071 /* submaps can not be created lazily */
2072 return KERN_INVALID_ARGUMENT
;
2075 if (vmk_flags
.vmkf_already
) {
2077 * VM_FLAGS_ALREADY says that it's OK if the same mapping
2078 * is already present. For it to be meaningul, the requested
2079 * mapping has to be at a fixed address (!VM_FLAGS_ANYWHERE) and
2080 * we shouldn't try and remove what was mapped there first
2081 * (!VM_FLAGS_OVERWRITE).
2083 if ((flags
& VM_FLAGS_ANYWHERE
) ||
2084 (flags
& VM_FLAGS_OVERWRITE
)) {
2085 return KERN_INVALID_ARGUMENT
;
2089 effective_min_offset
= map
->min_offset
;
2091 if (vmk_flags
.vmkf_beyond_max
) {
2093 * Allow an insertion beyond the map's max offset.
2095 #if !defined(__arm__) && !defined(__arm64__)
2096 if (vm_map_is_64bit(map
))
2097 effective_max_offset
= 0xFFFFFFFFFFFFF000ULL
;
2099 #endif /* __arm__ */
2100 effective_max_offset
= 0x00000000FFFFF000ULL
;
2102 effective_max_offset
= map
->max_offset
;
2106 (offset
& PAGE_MASK_64
) != 0) {
2108 return KERN_INVALID_ARGUMENT
;
2111 if (map
->pmap
== kernel_pmap
) {
2112 user_alias
= VM_KERN_MEMORY_NONE
;
2117 #define RETURN(value) { result = value; goto BailOut; }
2119 assert(page_aligned(*address
));
2120 assert(page_aligned(size
));
2122 if (!VM_MAP_PAGE_ALIGNED(size
, VM_MAP_PAGE_MASK(map
))) {
2124 * In most cases, the caller rounds the size up to the
2126 * If we get a size that is explicitly not map-aligned here,
2127 * we'll have to respect the caller's wish and mark the
2128 * mapping as "not map-aligned" to avoid tripping the
2129 * map alignment checks later.
2131 clear_map_aligned
= TRUE
;
2134 !VM_MAP_PAGE_ALIGNED(*address
, VM_MAP_PAGE_MASK(map
))) {
2136 * We've been asked to map at a fixed address and that
2137 * address is not aligned to the map's specific alignment.
2138 * The caller should know what it's doing (i.e. most likely
2139 * mapping some fragmented copy map, transferring memory from
2140 * a VM map with a different alignment), so clear map_aligned
2141 * for this new VM map entry and proceed.
2143 clear_map_aligned
= TRUE
;
2147 * Only zero-fill objects are allowed to be purgable.
2148 * LP64todo - limit purgable objects to 32-bits for now
2152 (object
!= VM_OBJECT_NULL
&&
2153 (object
->vo_size
!= size
||
2154 object
->purgable
== VM_PURGABLE_DENY
))
2155 || size
> ANON_MAX_SIZE
)) /* LP64todo: remove when dp capable */
2156 return KERN_INVALID_ARGUMENT
;
2158 if (!anywhere
&& overwrite
) {
2160 * Create a temporary VM map to hold the old mappings in the
2161 * affected area while we create the new one.
2162 * This avoids releasing the VM map lock in
2163 * vm_map_entry_delete() and allows atomicity
2164 * when we want to replace some mappings with a new one.
2165 * It also allows us to restore the old VM mappings if the
2166 * new mapping fails.
2168 zap_old_map
= vm_map_create(PMAP_NULL
,
2171 map
->hdr
.entries_pageable
);
2172 vm_map_set_page_shift(zap_old_map
, VM_MAP_PAGE_SHIFT(map
));
2173 vm_map_disable_hole_optimization(zap_old_map
);
2184 if (entry_for_jit
) {
2185 if (map
->jit_entry_exists
) {
2186 result
= KERN_INVALID_ARGUMENT
;
2189 random_address
= TRUE
;
2192 if (random_address
) {
2194 * Get a random start address.
2196 result
= vm_map_random_address_for_size(map
, address
, size
);
2197 if (result
!= KERN_SUCCESS
) {
2203 else if ((start
== 0 || start
== vm_map_min(map
)) &&
2204 !map
->disable_vmentry_reuse
&&
2205 map
->vmmap_high_start
!= 0) {
2206 start
= map
->vmmap_high_start
;
2208 #endif /* __x86_64__ */
2212 * Calculate the first possible address.
2215 if (start
< effective_min_offset
)
2216 start
= effective_min_offset
;
2217 if (start
> effective_max_offset
)
2218 RETURN(KERN_NO_SPACE
);
2221 * Look for the first possible address;
2222 * if there's already something at this
2223 * address, we have to start after it.
2226 if( map
->disable_vmentry_reuse
== TRUE
) {
2227 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
2230 if (map
->holelistenabled
) {
2231 hole_entry
= (vm_map_entry_t
)map
->holes_list
;
2233 if (hole_entry
== NULL
) {
2235 * No more space in the map?
2237 result
= KERN_NO_SPACE
;
2241 boolean_t found_hole
= FALSE
;
2244 if (hole_entry
->vme_start
>= start
) {
2245 start
= hole_entry
->vme_start
;
2250 if (hole_entry
->vme_end
> start
) {
2254 hole_entry
= hole_entry
->vme_next
;
2256 } while (hole_entry
!= (vm_map_entry_t
) map
->holes_list
);
2258 if (found_hole
== FALSE
) {
2259 result
= KERN_NO_SPACE
;
2266 start
+= PAGE_SIZE_64
;
2269 assert(first_free_is_valid(map
));
2271 entry
= map
->first_free
;
2273 if (entry
== vm_map_to_entry(map
)) {
2276 if (entry
->vme_next
== vm_map_to_entry(map
)){
2278 * Hole at the end of the map.
2282 if (start
< (entry
->vme_next
)->vme_start
) {
2283 start
= entry
->vme_end
;
2284 start
= vm_map_round_page(start
,
2285 VM_MAP_PAGE_MASK(map
));
2288 * Need to do a lookup.
2295 if (entry
== NULL
) {
2296 vm_map_entry_t tmp_entry
;
2297 if (vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
2298 assert(!entry_for_jit
);
2299 start
= tmp_entry
->vme_end
;
2300 start
= vm_map_round_page(start
,
2301 VM_MAP_PAGE_MASK(map
));
2309 * In any case, the "entry" always precedes
2310 * the proposed new region throughout the
2315 vm_map_entry_t next
;
2318 * Find the end of the proposed new region.
2319 * Be sure we didn't go beyond the end, or
2320 * wrap around the address.
2323 end
= ((start
+ mask
) & ~mask
);
2324 end
= vm_map_round_page(end
,
2325 VM_MAP_PAGE_MASK(map
));
2327 RETURN(KERN_NO_SPACE
);
2329 assert(VM_MAP_PAGE_ALIGNED(start
,
2330 VM_MAP_PAGE_MASK(map
)));
2333 if ((end
> effective_max_offset
) || (end
< start
)) {
2334 if (map
->wait_for_space
) {
2335 assert(!keep_map_locked
);
2336 if (size
<= (effective_max_offset
-
2337 effective_min_offset
)) {
2338 assert_wait((event_t
)map
,
2342 thread_block(THREAD_CONTINUE_NULL
);
2346 RETURN(KERN_NO_SPACE
);
2349 next
= entry
->vme_next
;
2351 if (map
->holelistenabled
) {
2352 if (entry
->vme_end
>= end
)
2356 * If there are no more entries, we must win.
2360 * If there is another entry, it must be
2361 * after the end of the potential new region.
2364 if (next
== vm_map_to_entry(map
))
2367 if (next
->vme_start
>= end
)
2372 * Didn't fit -- move to the next entry.
2377 if (map
->holelistenabled
) {
2378 if (entry
== (vm_map_entry_t
) map
->holes_list
) {
2382 result
= KERN_NO_SPACE
;
2385 start
= entry
->vme_start
;
2387 start
= entry
->vme_end
;
2390 start
= vm_map_round_page(start
,
2391 VM_MAP_PAGE_MASK(map
));
2394 if (map
->holelistenabled
) {
2395 if (vm_map_lookup_entry(map
, entry
->vme_start
, &entry
)) {
2396 panic("Found an existing entry (%p) instead of potential hole at address: 0x%llx.\n", entry
, (unsigned long long)entry
->vme_start
);
2401 assert(VM_MAP_PAGE_ALIGNED(*address
,
2402 VM_MAP_PAGE_MASK(map
)));
2406 * the address doesn't itself violate
2407 * the mask requirement.
2412 if ((start
& mask
) != 0)
2413 RETURN(KERN_NO_SPACE
);
2416 * ... the address is within bounds
2421 if ((start
< effective_min_offset
) ||
2422 (end
> effective_max_offset
) ||
2424 RETURN(KERN_INVALID_ADDRESS
);
2427 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
2430 * Fixed mapping and "overwrite" flag: attempt to
2431 * remove all existing mappings in the specified
2432 * address range, saving them in our "zap_old_map".
2434 remove_flags
= VM_MAP_REMOVE_SAVE_ENTRIES
;
2435 remove_flags
|= VM_MAP_REMOVE_NO_MAP_ALIGN
;
2436 if (vmk_flags
.vmkf_overwrite_immutable
) {
2437 /* we can overwrite immutable mappings */
2438 remove_flags
|= VM_MAP_REMOVE_IMMUTABLE
;
2440 (void) vm_map_delete(map
, start
, end
,
2446 * ... the starting address isn't allocated
2449 if (vm_map_lookup_entry(map
, start
, &entry
)) {
2450 if (! (vmk_flags
.vmkf_already
)) {
2451 RETURN(KERN_NO_SPACE
);
2454 * Check if what's already there is what we want.
2457 tmp_offset
= offset
;
2458 if (entry
->vme_start
< start
) {
2459 tmp_start
-= start
- entry
->vme_start
;
2460 tmp_offset
-= start
- entry
->vme_start
;
2463 for (; entry
->vme_start
< end
;
2464 entry
= entry
->vme_next
) {
2466 * Check if the mapping's attributes
2467 * match the existing map entry.
2469 if (entry
== vm_map_to_entry(map
) ||
2470 entry
->vme_start
!= tmp_start
||
2471 entry
->is_sub_map
!= is_submap
||
2472 VME_OFFSET(entry
) != tmp_offset
||
2473 entry
->needs_copy
!= needs_copy
||
2474 entry
->protection
!= cur_protection
||
2475 entry
->max_protection
!= max_protection
||
2476 entry
->inheritance
!= inheritance
||
2477 entry
->iokit_acct
!= iokit_acct
||
2478 VME_ALIAS(entry
) != alias
) {
2479 /* not the same mapping ! */
2480 RETURN(KERN_NO_SPACE
);
2483 * Check if the same object is being mapped.
2486 if (VME_SUBMAP(entry
) !=
2487 (vm_map_t
) object
) {
2488 /* not the same submap */
2489 RETURN(KERN_NO_SPACE
);
2492 if (VME_OBJECT(entry
) != object
) {
2493 /* not the same VM object... */
2496 obj2
= VME_OBJECT(entry
);
2497 if ((obj2
== VM_OBJECT_NULL
||
2499 (object
== VM_OBJECT_NULL
||
2500 object
->internal
)) {
2507 RETURN(KERN_NO_SPACE
);
2512 tmp_offset
+= entry
->vme_end
- entry
->vme_start
;
2513 tmp_start
+= entry
->vme_end
- entry
->vme_start
;
2514 if (entry
->vme_end
>= end
) {
2515 /* reached the end of our mapping */
2519 /* it all matches: let's use what's already there ! */
2520 RETURN(KERN_MEMORY_PRESENT
);
2524 * ... the next region doesn't overlap the
2528 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
2529 (entry
->vme_next
->vme_start
< end
))
2530 RETURN(KERN_NO_SPACE
);
2535 * "start" and "end" should define the endpoints of the
2536 * available new range, and
2537 * "entry" should refer to the region before the new
2540 * the map should be locked.
2544 * See whether we can avoid creating a new entry (and object) by
2545 * extending one of our neighbors. [So far, we only attempt to
2546 * extend from below.] Note that we can never extend/join
2547 * purgable objects because they need to remain distinct
2548 * entities in order to implement their "volatile object"
2552 if (purgable
|| entry_for_jit
) {
2553 if (object
== VM_OBJECT_NULL
) {
2555 object
= vm_object_allocate(size
);
2556 object
->copy_strategy
= MEMORY_OBJECT_COPY_NONE
;
2557 object
->true_share
= TRUE
;
2560 object
->purgable
= VM_PURGABLE_NONVOLATILE
;
2561 if (map
->pmap
== kernel_pmap
) {
2563 * Purgeable mappings made in a kernel
2564 * map are "owned" by the kernel itself
2565 * rather than the current user task
2566 * because they're likely to be used by
2567 * more than this user task (see
2568 * execargs_purgeable_allocate(), for
2571 owner
= kernel_task
;
2573 owner
= current_task();
2575 assert(object
->vo_purgeable_owner
== NULL
);
2576 assert(object
->resident_page_count
== 0);
2577 assert(object
->wired_page_count
== 0);
2578 vm_object_lock(object
);
2579 vm_purgeable_nonvolatile_enqueue(object
, owner
);
2580 vm_object_unlock(object
);
2582 offset
= (vm_object_offset_t
)0;
2584 } else if ((is_submap
== FALSE
) &&
2585 (object
== VM_OBJECT_NULL
) &&
2586 (entry
!= vm_map_to_entry(map
)) &&
2587 (entry
->vme_end
== start
) &&
2588 (!entry
->is_shared
) &&
2589 (!entry
->is_sub_map
) &&
2590 (!entry
->in_transition
) &&
2591 (!entry
->needs_wakeup
) &&
2592 (entry
->behavior
== VM_BEHAVIOR_DEFAULT
) &&
2593 (entry
->protection
== cur_protection
) &&
2594 (entry
->max_protection
== max_protection
) &&
2595 (entry
->inheritance
== inheritance
) &&
2596 ((user_alias
== VM_MEMORY_REALLOC
) ||
2597 (VME_ALIAS(entry
) == alias
)) &&
2598 (entry
->no_cache
== no_cache
) &&
2599 (entry
->permanent
== permanent
) &&
2600 /* no coalescing for immutable executable mappings */
2601 !((entry
->protection
& VM_PROT_EXECUTE
) &&
2602 entry
->permanent
) &&
2603 (!entry
->superpage_size
&& !superpage_size
) &&
2605 * No coalescing if not map-aligned, to avoid propagating
2606 * that condition any further than needed:
2608 (!entry
->map_aligned
|| !clear_map_aligned
) &&
2609 (!entry
->zero_wired_pages
) &&
2610 (!entry
->used_for_jit
&& !entry_for_jit
) &&
2611 (entry
->iokit_acct
== iokit_acct
) &&
2612 (!entry
->vme_resilient_codesign
) &&
2613 (!entry
->vme_resilient_media
) &&
2614 (!entry
->vme_atomic
) &&
2616 ((entry
->vme_end
- entry
->vme_start
) + size
<=
2617 (user_alias
== VM_MEMORY_REALLOC
?
2619 NO_COALESCE_LIMIT
)) &&
2621 (entry
->wired_count
== 0)) { /* implies user_wired_count == 0 */
2622 if (vm_object_coalesce(VME_OBJECT(entry
),
2625 (vm_object_offset_t
) 0,
2626 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
),
2627 (vm_map_size_t
)(end
- entry
->vme_end
))) {
2630 * Coalesced the two objects - can extend
2631 * the previous map entry to include the
2634 map
->size
+= (end
- entry
->vme_end
);
2635 assert(entry
->vme_start
< end
);
2636 assert(VM_MAP_PAGE_ALIGNED(end
,
2637 VM_MAP_PAGE_MASK(map
)));
2638 if (__improbable(vm_debug_events
))
2639 DTRACE_VM5(map_entry_extend
, vm_map_t
, map
, vm_map_entry_t
, entry
, vm_address_t
, entry
->vme_start
, vm_address_t
, entry
->vme_end
, vm_address_t
, end
);
2640 entry
->vme_end
= end
;
2641 if (map
->holelistenabled
) {
2642 vm_map_store_update_first_free(map
, entry
, TRUE
);
2644 vm_map_store_update_first_free(map
, map
->first_free
, TRUE
);
2646 new_mapping_established
= TRUE
;
2647 RETURN(KERN_SUCCESS
);
2651 step
= superpage_size
? SUPERPAGE_SIZE
: (end
- start
);
2654 for (tmp2_start
= start
; tmp2_start
<end
; tmp2_start
+= step
) {
2655 tmp2_end
= tmp2_start
+ step
;
2657 * Create a new entry
2658 * LP64todo - for now, we can only allocate 4GB internal objects
2659 * because the default pager can't page bigger ones. Remove this
2663 * The reserved "page zero" in each process's address space can
2664 * be arbitrarily large. Splitting it into separate 4GB objects and
2665 * therefore different VM map entries serves no purpose and just
2666 * slows down operations on the VM map, so let's not split the
2667 * allocation into 4GB chunks if the max protection is NONE. That
2668 * memory should never be accessible, so it will never get to the
2671 tmp_start
= tmp2_start
;
2672 if (object
== VM_OBJECT_NULL
&&
2673 size
> (vm_map_size_t
)ANON_CHUNK_SIZE
&&
2674 max_protection
!= VM_PROT_NONE
&&
2675 superpage_size
== 0)
2676 tmp_end
= tmp_start
+ (vm_map_size_t
)ANON_CHUNK_SIZE
;
2680 new_entry
= vm_map_entry_insert(
2681 map
, entry
, tmp_start
, tmp_end
,
2682 object
, offset
, needs_copy
,
2684 cur_protection
, max_protection
,
2685 VM_BEHAVIOR_DEFAULT
,
2686 (entry_for_jit
)? VM_INHERIT_NONE
: inheritance
,
2696 assert((object
!= kernel_object
) || (VM_KERN_MEMORY_NONE
!= alias
));
2698 if (resilient_codesign
&&
2699 ! ((cur_protection
| max_protection
) &
2700 (VM_PROT_WRITE
| VM_PROT_EXECUTE
))) {
2701 new_entry
->vme_resilient_codesign
= TRUE
;
2704 if (resilient_media
&&
2705 ! ((cur_protection
| max_protection
) &
2706 (VM_PROT_WRITE
| VM_PROT_EXECUTE
))) {
2707 new_entry
->vme_resilient_media
= TRUE
;
2710 assert(!new_entry
->iokit_acct
);
2712 object
!= VM_OBJECT_NULL
&&
2713 object
->purgable
!= VM_PURGABLE_DENY
) {
2714 assert(new_entry
->use_pmap
);
2715 assert(!new_entry
->iokit_acct
);
2717 * Turn off pmap accounting since
2718 * purgeable objects have their
2721 new_entry
->use_pmap
= FALSE
;
2722 } else if (!is_submap
&&
2724 object
!= VM_OBJECT_NULL
&&
2726 /* alternate accounting */
2727 assert(!new_entry
->iokit_acct
);
2728 assert(new_entry
->use_pmap
);
2729 new_entry
->iokit_acct
= TRUE
;
2730 new_entry
->use_pmap
= FALSE
;
2732 vm_map_iokit_mapped_region
,
2734 vm_map_offset_t
, new_entry
->vme_start
,
2735 vm_map_offset_t
, new_entry
->vme_end
,
2736 int, VME_ALIAS(new_entry
));
2737 vm_map_iokit_mapped_region(
2739 (new_entry
->vme_end
-
2740 new_entry
->vme_start
));
2741 } else if (!is_submap
) {
2742 assert(!new_entry
->iokit_acct
);
2743 assert(new_entry
->use_pmap
);
2748 boolean_t submap_is_64bit
;
2751 assert(new_entry
->is_sub_map
);
2752 assert(!new_entry
->use_pmap
);
2753 assert(!new_entry
->iokit_acct
);
2754 submap
= (vm_map_t
) object
;
2755 submap_is_64bit
= vm_map_is_64bit(submap
);
2756 use_pmap
= (user_alias
== VM_MEMORY_SHARED_PMAP
);
2757 #ifndef NO_NESTED_PMAP
2758 if (use_pmap
&& submap
->pmap
== NULL
) {
2759 ledger_t ledger
= map
->pmap
->ledger
;
2760 /* we need a sub pmap to nest... */
2761 submap
->pmap
= pmap_create(ledger
, 0,
2763 if (submap
->pmap
== NULL
) {
2764 /* let's proceed without nesting... */
2766 #if defined(__arm__) || defined(__arm64__)
2768 pmap_set_nested(submap
->pmap
);
2772 if (use_pmap
&& submap
->pmap
!= NULL
) {
2773 kr
= pmap_nest(map
->pmap
,
2777 tmp_end
- tmp_start
);
2778 if (kr
!= KERN_SUCCESS
) {
2779 printf("vm_map_enter: "
2780 "pmap_nest(0x%llx,0x%llx) "
2782 (long long)tmp_start
,
2786 /* we're now nested ! */
2787 new_entry
->use_pmap
= TRUE
;
2791 #endif /* NO_NESTED_PMAP */
2795 if (superpage_size
) {
2797 vm_object_t sp_object
;
2798 vm_object_offset_t sp_offset
;
2800 VME_OFFSET_SET(entry
, 0);
2802 /* allocate one superpage */
2803 kr
= cpm_allocate(SUPERPAGE_SIZE
, &pages
, 0, SUPERPAGE_NBASEPAGES
-1, TRUE
, 0);
2804 if (kr
!= KERN_SUCCESS
) {
2805 /* deallocate whole range... */
2806 new_mapping_established
= TRUE
;
2807 /* ... but only up to "tmp_end" */
2808 size
-= end
- tmp_end
;
2812 /* create one vm_object per superpage */
2813 sp_object
= vm_object_allocate((vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
2814 sp_object
->phys_contiguous
= TRUE
;
2815 sp_object
->vo_shadow_offset
= (vm_object_offset_t
)VM_PAGE_GET_PHYS_PAGE(pages
)*PAGE_SIZE
;
2816 VME_OBJECT_SET(entry
, sp_object
);
2817 assert(entry
->use_pmap
);
2819 /* enter the base pages into the object */
2820 vm_object_lock(sp_object
);
2822 sp_offset
< SUPERPAGE_SIZE
;
2823 sp_offset
+= PAGE_SIZE
) {
2825 pmap_zero_page(VM_PAGE_GET_PHYS_PAGE(m
));
2826 pages
= NEXT_PAGE(m
);
2827 *(NEXT_PAGE_PTR(m
)) = VM_PAGE_NULL
;
2828 vm_page_insert_wired(m
, sp_object
, sp_offset
, VM_KERN_MEMORY_OSFMK
);
2830 vm_object_unlock(sp_object
);
2832 } while (tmp_end
!= tmp2_end
&&
2833 (tmp_start
= tmp_end
) &&
2834 (tmp_end
= (tmp2_end
- tmp_end
> (vm_map_size_t
)ANON_CHUNK_SIZE
) ?
2835 tmp_end
+ (vm_map_size_t
)ANON_CHUNK_SIZE
: tmp2_end
));
2838 new_mapping_established
= TRUE
;
2841 assert(map_locked
== TRUE
);
2843 if (result
== KERN_SUCCESS
) {
2844 vm_prot_t pager_prot
;
2845 memory_object_t pager
;
2849 !(vmk_flags
.vmkf_no_pmap_check
)) {
2850 assert(vm_map_pmap_is_empty(map
,
2857 * For "named" VM objects, let the pager know that the
2858 * memory object is being mapped. Some pagers need to keep
2859 * track of this, to know when they can reclaim the memory
2860 * object, for example.
2861 * VM calls memory_object_map() for each mapping (specifying
2862 * the protection of each mapping) and calls
2863 * memory_object_last_unmap() when all the mappings are gone.
2865 pager_prot
= max_protection
;
2868 * Copy-On-Write mapping: won't modify
2869 * the memory object.
2871 pager_prot
&= ~VM_PROT_WRITE
;
2874 object
!= VM_OBJECT_NULL
&&
2876 object
->pager
!= MEMORY_OBJECT_NULL
) {
2877 vm_object_lock(object
);
2878 pager
= object
->pager
;
2879 if (object
->named
&&
2880 pager
!= MEMORY_OBJECT_NULL
) {
2881 assert(object
->pager_ready
);
2882 vm_object_mapping_wait(object
, THREAD_UNINT
);
2883 vm_object_mapping_begin(object
);
2884 vm_object_unlock(object
);
2886 kr
= memory_object_map(pager
, pager_prot
);
2887 assert(kr
== KERN_SUCCESS
);
2889 vm_object_lock(object
);
2890 vm_object_mapping_end(object
);
2892 vm_object_unlock(object
);
2896 assert(map_locked
== TRUE
);
2898 if (!keep_map_locked
) {
2904 * We can't hold the map lock if we enter this block.
2907 if (result
== KERN_SUCCESS
) {
2909 /* Wire down the new entry if the user
2910 * requested all new map entries be wired.
2912 if ((map
->wiring_required
)||(superpage_size
)) {
2913 assert(!keep_map_locked
);
2914 pmap_empty
= FALSE
; /* pmap won't be empty */
2915 kr
= vm_map_wire_kernel(map
, start
, end
,
2916 new_entry
->protection
, VM_KERN_MEMORY_MLOCK
,
2923 if (result
!= KERN_SUCCESS
) {
2924 if (new_mapping_established
) {
2926 * We have to get rid of the new mappings since we
2927 * won't make them available to the user.
2928 * Try and do that atomically, to minimize the risk
2929 * that someone else create new mappings that range.
2931 zap_new_map
= vm_map_create(PMAP_NULL
,
2934 map
->hdr
.entries_pageable
);
2935 vm_map_set_page_shift(zap_new_map
,
2936 VM_MAP_PAGE_SHIFT(map
));
2937 vm_map_disable_hole_optimization(zap_new_map
);
2943 (void) vm_map_delete(map
, *address
, *address
+size
,
2944 (VM_MAP_REMOVE_SAVE_ENTRIES
|
2945 VM_MAP_REMOVE_NO_MAP_ALIGN
),
2948 if (zap_old_map
!= VM_MAP_NULL
&&
2949 zap_old_map
->hdr
.nentries
!= 0) {
2950 vm_map_entry_t entry1
, entry2
;
2953 * The new mapping failed. Attempt to restore
2954 * the old mappings, saved in the "zap_old_map".
2961 /* first check if the coast is still clear */
2962 start
= vm_map_first_entry(zap_old_map
)->vme_start
;
2963 end
= vm_map_last_entry(zap_old_map
)->vme_end
;
2964 if (vm_map_lookup_entry(map
, start
, &entry1
) ||
2965 vm_map_lookup_entry(map
, end
, &entry2
) ||
2968 * Part of that range has already been
2969 * re-mapped: we can't restore the old
2972 vm_map_enter_restore_failures
++;
2975 * Transfer the saved map entries from
2976 * "zap_old_map" to the original "map",
2977 * inserting them all after "entry1".
2979 for (entry2
= vm_map_first_entry(zap_old_map
);
2980 entry2
!= vm_map_to_entry(zap_old_map
);
2981 entry2
= vm_map_first_entry(zap_old_map
)) {
2982 vm_map_size_t entry_size
;
2984 entry_size
= (entry2
->vme_end
-
2986 vm_map_store_entry_unlink(zap_old_map
,
2988 zap_old_map
->size
-= entry_size
;
2989 vm_map_store_entry_link(map
, entry1
, entry2
);
2990 map
->size
+= entry_size
;
2993 if (map
->wiring_required
) {
2995 * XXX TODO: we should rewire the
2999 vm_map_enter_restore_successes
++;
3005 * The caller is responsible for releasing the lock if it requested to
3006 * keep the map locked.
3008 if (map_locked
&& !keep_map_locked
) {
3013 * Get rid of the "zap_maps" and all the map entries that
3014 * they may still contain.
3016 if (zap_old_map
!= VM_MAP_NULL
) {
3017 vm_map_destroy(zap_old_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
3018 zap_old_map
= VM_MAP_NULL
;
3020 if (zap_new_map
!= VM_MAP_NULL
) {
3021 vm_map_destroy(zap_new_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
3022 zap_new_map
= VM_MAP_NULL
;
3031 extern const struct memory_object_pager_ops fourk_pager_ops
;
3035 vm_map_offset_t
*address
, /* IN/OUT */
3037 vm_map_offset_t mask
,
3039 vm_map_kernel_flags_t vmk_flags
,
3042 vm_object_offset_t offset
,
3043 boolean_t needs_copy
,
3044 vm_prot_t cur_protection
,
3045 vm_prot_t max_protection
,
3046 vm_inherit_t inheritance
)
3048 vm_map_entry_t entry
, new_entry
;
3049 vm_map_offset_t start
, fourk_start
;
3050 vm_map_offset_t end
, fourk_end
;
3051 vm_map_size_t fourk_size
;
3052 kern_return_t result
= KERN_SUCCESS
;
3053 vm_map_t zap_old_map
= VM_MAP_NULL
;
3054 vm_map_t zap_new_map
= VM_MAP_NULL
;
3055 boolean_t map_locked
= FALSE
;
3056 boolean_t pmap_empty
= TRUE
;
3057 boolean_t new_mapping_established
= FALSE
;
3058 boolean_t keep_map_locked
= vmk_flags
.vmkf_keep_map_locked
;
3059 boolean_t anywhere
= ((flags
& VM_FLAGS_ANYWHERE
) != 0);
3060 boolean_t purgable
= ((flags
& VM_FLAGS_PURGABLE
) != 0);
3061 boolean_t overwrite
= ((flags
& VM_FLAGS_OVERWRITE
) != 0);
3062 boolean_t no_cache
= ((flags
& VM_FLAGS_NO_CACHE
) != 0);
3063 boolean_t is_submap
= vmk_flags
.vmkf_submap
;
3064 boolean_t permanent
= vmk_flags
.vmkf_permanent
;
3065 boolean_t entry_for_jit
= vmk_flags
.vmkf_map_jit
;
3066 // boolean_t iokit_acct = vmk_flags.vmkf_iokit_acct;
3067 unsigned int superpage_size
= ((flags
& VM_FLAGS_SUPERPAGE_MASK
) >> VM_FLAGS_SUPERPAGE_SHIFT
);
3068 vm_map_offset_t effective_min_offset
, effective_max_offset
;
3070 boolean_t clear_map_aligned
= FALSE
;
3071 memory_object_t fourk_mem_obj
;
3072 vm_object_t fourk_object
;
3073 vm_map_offset_t fourk_pager_offset
;
3074 int fourk_pager_index_start
, fourk_pager_index_num
;
3076 boolean_t fourk_copy
;
3077 vm_object_t copy_object
;
3078 vm_object_offset_t copy_offset
;
3080 fourk_mem_obj
= MEMORY_OBJECT_NULL
;
3081 fourk_object
= VM_OBJECT_NULL
;
3083 if (superpage_size
) {
3084 return KERN_NOT_SUPPORTED
;
3088 if (cur_protection
& VM_PROT_WRITE
) {
3089 if ((cur_protection
& VM_PROT_EXECUTE
) &&
3091 printf("EMBEDDED: %s: curprot cannot be write+execute. "
3092 "turning off execute\n",
3094 cur_protection
&= ~VM_PROT_EXECUTE
;
3097 #endif /* CONFIG_EMBEDDED */
3100 return KERN_NOT_SUPPORTED
;
3102 if (vmk_flags
.vmkf_already
) {
3103 return KERN_NOT_SUPPORTED
;
3105 if (purgable
|| entry_for_jit
) {
3106 return KERN_NOT_SUPPORTED
;
3109 effective_min_offset
= map
->min_offset
;
3111 if (vmk_flags
.vmkf_beyond_max
) {
3112 return KERN_NOT_SUPPORTED
;
3114 effective_max_offset
= map
->max_offset
;
3118 (offset
& FOURK_PAGE_MASK
) != 0) {
3120 return KERN_INVALID_ARGUMENT
;
3123 #define RETURN(value) { result = value; goto BailOut; }
3125 assert(VM_MAP_PAGE_ALIGNED(*address
, FOURK_PAGE_MASK
));
3126 assert(VM_MAP_PAGE_ALIGNED(size
, FOURK_PAGE_MASK
));
3128 if (!anywhere
&& overwrite
) {
3129 return KERN_NOT_SUPPORTED
;
3131 if (!anywhere
&& overwrite
) {
3133 * Create a temporary VM map to hold the old mappings in the
3134 * affected area while we create the new one.
3135 * This avoids releasing the VM map lock in
3136 * vm_map_entry_delete() and allows atomicity
3137 * when we want to replace some mappings with a new one.
3138 * It also allows us to restore the old VM mappings if the
3139 * new mapping fails.
3141 zap_old_map
= vm_map_create(PMAP_NULL
,
3144 map
->hdr
.entries_pageable
);
3145 vm_map_set_page_shift(zap_old_map
, VM_MAP_PAGE_SHIFT(map
));
3146 vm_map_disable_hole_optimization(zap_old_map
);
3149 fourk_start
= *address
;
3151 fourk_end
= fourk_start
+ fourk_size
;
3153 start
= vm_map_trunc_page(*address
, VM_MAP_PAGE_MASK(map
));
3154 end
= vm_map_round_page(fourk_end
, VM_MAP_PAGE_MASK(map
));
3158 return KERN_NOT_SUPPORTED
;
3162 * the address doesn't itself violate
3163 * the mask requirement.
3168 if ((start
& mask
) != 0) {
3169 RETURN(KERN_NO_SPACE
);
3173 * ... the address is within bounds
3178 if ((start
< effective_min_offset
) ||
3179 (end
> effective_max_offset
) ||
3181 RETURN(KERN_INVALID_ADDRESS
);
3184 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
3186 * Fixed mapping and "overwrite" flag: attempt to
3187 * remove all existing mappings in the specified
3188 * address range, saving them in our "zap_old_map".
3190 (void) vm_map_delete(map
, start
, end
,
3191 (VM_MAP_REMOVE_SAVE_ENTRIES
|
3192 VM_MAP_REMOVE_NO_MAP_ALIGN
),
3197 * ... the starting address isn't allocated
3199 if (vm_map_lookup_entry(map
, start
, &entry
)) {
3200 vm_object_t cur_object
, shadow_object
;
3203 * We might already some 4K mappings
3204 * in a 16K page here.
3207 if (entry
->vme_end
- entry
->vme_start
3208 != SIXTEENK_PAGE_SIZE
) {
3209 RETURN(KERN_NO_SPACE
);
3211 if (entry
->is_sub_map
) {
3212 RETURN(KERN_NO_SPACE
);
3214 if (VME_OBJECT(entry
) == VM_OBJECT_NULL
) {
3215 RETURN(KERN_NO_SPACE
);
3218 /* go all the way down the shadow chain */
3219 cur_object
= VME_OBJECT(entry
);
3220 vm_object_lock(cur_object
);
3221 while (cur_object
->shadow
!= VM_OBJECT_NULL
) {
3222 shadow_object
= cur_object
->shadow
;
3223 vm_object_lock(shadow_object
);
3224 vm_object_unlock(cur_object
);
3225 cur_object
= shadow_object
;
3226 shadow_object
= VM_OBJECT_NULL
;
3228 if (cur_object
->internal
||
3229 cur_object
->pager
== NULL
) {
3230 vm_object_unlock(cur_object
);
3231 RETURN(KERN_NO_SPACE
);
3233 if (cur_object
->pager
->mo_pager_ops
3234 != &fourk_pager_ops
) {
3235 vm_object_unlock(cur_object
);
3236 RETURN(KERN_NO_SPACE
);
3238 fourk_object
= cur_object
;
3239 fourk_mem_obj
= fourk_object
->pager
;
3241 /* keep the "4K" object alive */
3242 vm_object_reference_locked(fourk_object
);
3243 vm_object_unlock(fourk_object
);
3245 /* merge permissions */
3246 entry
->protection
|= cur_protection
;
3247 entry
->max_protection
|= max_protection
;
3248 if ((entry
->protection
& (VM_PROT_WRITE
|
3249 VM_PROT_EXECUTE
)) ==
3250 (VM_PROT_WRITE
| VM_PROT_EXECUTE
) &&
3251 fourk_binary_compatibility_unsafe
&&
3252 fourk_binary_compatibility_allow_wx
) {
3253 /* write+execute: need to be "jit" */
3254 entry
->used_for_jit
= TRUE
;
3257 goto map_in_fourk_pager
;
3261 * ... the next region doesn't overlap the
3265 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
3266 (entry
->vme_next
->vme_start
< end
)) {
3267 RETURN(KERN_NO_SPACE
);
3273 * "start" and "end" should define the endpoints of the
3274 * available new range, and
3275 * "entry" should refer to the region before the new
3278 * the map should be locked.
3281 /* create a new "4K" pager */
3282 fourk_mem_obj
= fourk_pager_create();
3283 fourk_object
= fourk_pager_to_vm_object(fourk_mem_obj
);
3284 assert(fourk_object
);
3286 /* keep the "4" object alive */
3287 vm_object_reference(fourk_object
);
3289 /* create a "copy" object, to map the "4K" object copy-on-write */
3291 result
= vm_object_copy_strategically(fourk_object
,
3297 assert(result
== KERN_SUCCESS
);
3298 assert(copy_object
!= VM_OBJECT_NULL
);
3299 assert(copy_offset
== 0);
3301 /* take a reference on the copy object, for this mapping */
3302 vm_object_reference(copy_object
);
3304 /* map the "4K" pager's copy object */
3306 vm_map_entry_insert(map
, entry
,
3307 vm_map_trunc_page(start
,
3308 VM_MAP_PAGE_MASK(map
)),
3309 vm_map_round_page(end
,
3310 VM_MAP_PAGE_MASK(map
)),
3313 FALSE
, /* needs_copy */
3315 cur_protection
, max_protection
,
3316 VM_BEHAVIOR_DEFAULT
,
3330 #if VM_MAP_DEBUG_FOURK
3331 if (vm_map_debug_fourk
) {
3332 printf("FOURK_PAGER: map %p [0x%llx:0x%llx] new pager %p\n",
3334 (uint64_t) entry
->vme_start
,
3335 (uint64_t) entry
->vme_end
,
3338 #endif /* VM_MAP_DEBUG_FOURK */
3340 new_mapping_established
= TRUE
;
3343 /* "map" the original "object" where it belongs in the "4K" pager */
3344 fourk_pager_offset
= (fourk_start
& SIXTEENK_PAGE_MASK
);
3345 fourk_pager_index_start
= (int) (fourk_pager_offset
/ FOURK_PAGE_SIZE
);
3346 if (fourk_size
> SIXTEENK_PAGE_SIZE
) {
3347 fourk_pager_index_num
= 4;
3349 fourk_pager_index_num
= (int) (fourk_size
/ FOURK_PAGE_SIZE
);
3351 if (fourk_pager_index_start
+ fourk_pager_index_num
> 4) {
3352 fourk_pager_index_num
= 4 - fourk_pager_index_start
;
3355 cur_idx
< fourk_pager_index_num
;
3357 vm_object_t old_object
;
3358 vm_object_offset_t old_offset
;
3360 kr
= fourk_pager_populate(fourk_mem_obj
,
3361 TRUE
, /* overwrite */
3362 fourk_pager_index_start
+ cur_idx
,
3366 (cur_idx
* FOURK_PAGE_SIZE
))
3370 #if VM_MAP_DEBUG_FOURK
3371 if (vm_map_debug_fourk
) {
3372 if (old_object
== (vm_object_t
) -1 &&
3373 old_offset
== (vm_object_offset_t
) -1) {
3374 printf("FOURK_PAGER: map %p [0x%llx:0x%llx] "
3375 "pager [%p:0x%llx] "
3377 "[object:%p,offset:0x%llx]\n",
3379 (uint64_t) entry
->vme_start
,
3380 (uint64_t) entry
->vme_end
,
3383 fourk_pager_index_start
+ cur_idx
,
3386 ? (offset
+ (cur_idx
* FOURK_PAGE_SIZE
))
3389 printf("FOURK_PAGER: map %p [0x%llx:0x%llx] "
3390 "pager [%p:0x%llx] "
3391 "populate[%d] [object:%p,offset:0x%llx] "
3392 "old [%p:0x%llx]\n",
3394 (uint64_t) entry
->vme_start
,
3395 (uint64_t) entry
->vme_end
,
3398 fourk_pager_index_start
+ cur_idx
,
3401 ? (offset
+ (cur_idx
* FOURK_PAGE_SIZE
))
3407 #endif /* VM_MAP_DEBUG_FOURK */
3409 assert(kr
== KERN_SUCCESS
);
3410 if (object
!= old_object
&&
3411 object
!= VM_OBJECT_NULL
&&
3412 object
!= (vm_object_t
) -1) {
3413 vm_object_reference(object
);
3415 if (object
!= old_object
&&
3416 old_object
!= VM_OBJECT_NULL
&&
3417 old_object
!= (vm_object_t
) -1) {
3418 vm_object_deallocate(old_object
);
3423 assert(map_locked
== TRUE
);
3425 if (fourk_object
!= VM_OBJECT_NULL
) {
3426 vm_object_deallocate(fourk_object
);
3427 fourk_object
= VM_OBJECT_NULL
;
3428 fourk_mem_obj
= MEMORY_OBJECT_NULL
;
3431 if (result
== KERN_SUCCESS
) {
3432 vm_prot_t pager_prot
;
3433 memory_object_t pager
;
3437 !(vmk_flags
.vmkf_no_pmap_check
)) {
3438 assert(vm_map_pmap_is_empty(map
,
3445 * For "named" VM objects, let the pager know that the
3446 * memory object is being mapped. Some pagers need to keep
3447 * track of this, to know when they can reclaim the memory
3448 * object, for example.
3449 * VM calls memory_object_map() for each mapping (specifying
3450 * the protection of each mapping) and calls
3451 * memory_object_last_unmap() when all the mappings are gone.
3453 pager_prot
= max_protection
;
3456 * Copy-On-Write mapping: won't modify
3457 * the memory object.
3459 pager_prot
&= ~VM_PROT_WRITE
;
3462 object
!= VM_OBJECT_NULL
&&
3464 object
->pager
!= MEMORY_OBJECT_NULL
) {
3465 vm_object_lock(object
);
3466 pager
= object
->pager
;
3467 if (object
->named
&&
3468 pager
!= MEMORY_OBJECT_NULL
) {
3469 assert(object
->pager_ready
);
3470 vm_object_mapping_wait(object
, THREAD_UNINT
);
3471 vm_object_mapping_begin(object
);
3472 vm_object_unlock(object
);
3474 kr
= memory_object_map(pager
, pager_prot
);
3475 assert(kr
== KERN_SUCCESS
);
3477 vm_object_lock(object
);
3478 vm_object_mapping_end(object
);
3480 vm_object_unlock(object
);
3483 fourk_object
!= VM_OBJECT_NULL
&&
3484 fourk_object
->named
&&
3485 fourk_object
->pager
!= MEMORY_OBJECT_NULL
) {
3486 vm_object_lock(fourk_object
);
3487 pager
= fourk_object
->pager
;
3488 if (fourk_object
->named
&&
3489 pager
!= MEMORY_OBJECT_NULL
) {
3490 assert(fourk_object
->pager_ready
);
3491 vm_object_mapping_wait(fourk_object
,
3493 vm_object_mapping_begin(fourk_object
);
3494 vm_object_unlock(fourk_object
);
3496 kr
= memory_object_map(pager
, VM_PROT_READ
);
3497 assert(kr
== KERN_SUCCESS
);
3499 vm_object_lock(fourk_object
);
3500 vm_object_mapping_end(fourk_object
);
3502 vm_object_unlock(fourk_object
);
3506 assert(map_locked
== TRUE
);
3508 if (!keep_map_locked
) {
3514 * We can't hold the map lock if we enter this block.
3517 if (result
== KERN_SUCCESS
) {
3519 /* Wire down the new entry if the user
3520 * requested all new map entries be wired.
3522 if ((map
->wiring_required
)||(superpage_size
)) {
3523 assert(!keep_map_locked
);
3524 pmap_empty
= FALSE
; /* pmap won't be empty */
3525 kr
= vm_map_wire_kernel(map
, start
, end
,
3526 new_entry
->protection
, VM_KERN_MEMORY_MLOCK
,
3533 if (result
!= KERN_SUCCESS
) {
3534 if (new_mapping_established
) {
3536 * We have to get rid of the new mappings since we
3537 * won't make them available to the user.
3538 * Try and do that atomically, to minimize the risk
3539 * that someone else create new mappings that range.
3541 zap_new_map
= vm_map_create(PMAP_NULL
,
3544 map
->hdr
.entries_pageable
);
3545 vm_map_set_page_shift(zap_new_map
,
3546 VM_MAP_PAGE_SHIFT(map
));
3547 vm_map_disable_hole_optimization(zap_new_map
);
3553 (void) vm_map_delete(map
, *address
, *address
+size
,
3554 (VM_MAP_REMOVE_SAVE_ENTRIES
|
3555 VM_MAP_REMOVE_NO_MAP_ALIGN
),
3558 if (zap_old_map
!= VM_MAP_NULL
&&
3559 zap_old_map
->hdr
.nentries
!= 0) {
3560 vm_map_entry_t entry1
, entry2
;
3563 * The new mapping failed. Attempt to restore
3564 * the old mappings, saved in the "zap_old_map".
3571 /* first check if the coast is still clear */
3572 start
= vm_map_first_entry(zap_old_map
)->vme_start
;
3573 end
= vm_map_last_entry(zap_old_map
)->vme_end
;
3574 if (vm_map_lookup_entry(map
, start
, &entry1
) ||
3575 vm_map_lookup_entry(map
, end
, &entry2
) ||
3578 * Part of that range has already been
3579 * re-mapped: we can't restore the old
3582 vm_map_enter_restore_failures
++;
3585 * Transfer the saved map entries from
3586 * "zap_old_map" to the original "map",
3587 * inserting them all after "entry1".
3589 for (entry2
= vm_map_first_entry(zap_old_map
);
3590 entry2
!= vm_map_to_entry(zap_old_map
);
3591 entry2
= vm_map_first_entry(zap_old_map
)) {
3592 vm_map_size_t entry_size
;
3594 entry_size
= (entry2
->vme_end
-
3596 vm_map_store_entry_unlink(zap_old_map
,
3598 zap_old_map
->size
-= entry_size
;
3599 vm_map_store_entry_link(map
, entry1
, entry2
);
3600 map
->size
+= entry_size
;
3603 if (map
->wiring_required
) {
3605 * XXX TODO: we should rewire the
3609 vm_map_enter_restore_successes
++;
3615 * The caller is responsible for releasing the lock if it requested to
3616 * keep the map locked.
3618 if (map_locked
&& !keep_map_locked
) {
3623 * Get rid of the "zap_maps" and all the map entries that
3624 * they may still contain.
3626 if (zap_old_map
!= VM_MAP_NULL
) {
3627 vm_map_destroy(zap_old_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
3628 zap_old_map
= VM_MAP_NULL
;
3630 if (zap_new_map
!= VM_MAP_NULL
) {
3631 vm_map_destroy(zap_new_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
3632 zap_new_map
= VM_MAP_NULL
;
3639 #endif /* __arm64__ */
3642 * Counters for the prefault optimization.
3644 int64_t vm_prefault_nb_pages
= 0;
3645 int64_t vm_prefault_nb_bailout
= 0;
3647 static kern_return_t
3648 vm_map_enter_mem_object_helper(
3649 vm_map_t target_map
,
3650 vm_map_offset_t
*address
,
3651 vm_map_size_t initial_size
,
3652 vm_map_offset_t mask
,
3654 vm_map_kernel_flags_t vmk_flags
,
3657 vm_object_offset_t offset
,
3659 vm_prot_t cur_protection
,
3660 vm_prot_t max_protection
,
3661 vm_inherit_t inheritance
,
3662 upl_page_list_ptr_t page_list
,
3663 unsigned int page_list_count
)
3665 vm_map_address_t map_addr
;
3666 vm_map_size_t map_size
;
3668 vm_object_size_t size
;
3669 kern_return_t result
;
3670 boolean_t mask_cur_protection
, mask_max_protection
;
3671 boolean_t kernel_prefault
, try_prefault
= (page_list_count
!= 0);
3672 vm_map_offset_t offset_in_mapping
= 0;
3674 boolean_t fourk
= vmk_flags
.vmkf_fourk
;
3675 #endif /* __arm64__ */
3677 assertf(vmk_flags
.__vmkf_unused
== 0, "vmk_flags unused=0x%x\n", vmk_flags
.__vmkf_unused
);
3679 mask_cur_protection
= cur_protection
& VM_PROT_IS_MASK
;
3680 mask_max_protection
= max_protection
& VM_PROT_IS_MASK
;
3681 cur_protection
&= ~VM_PROT_IS_MASK
;
3682 max_protection
&= ~VM_PROT_IS_MASK
;
3685 * Check arguments for validity
3687 if ((target_map
== VM_MAP_NULL
) ||
3688 (cur_protection
& ~VM_PROT_ALL
) ||
3689 (max_protection
& ~VM_PROT_ALL
) ||
3690 (inheritance
> VM_INHERIT_LAST_VALID
) ||
3691 (try_prefault
&& (copy
|| !page_list
)) ||
3692 initial_size
== 0) {
3693 return KERN_INVALID_ARGUMENT
;
3698 map_addr
= vm_map_trunc_page(*address
, FOURK_PAGE_MASK
);
3699 map_size
= vm_map_round_page(initial_size
, FOURK_PAGE_MASK
);
3701 #endif /* __arm64__ */
3703 map_addr
= vm_map_trunc_page(*address
,
3704 VM_MAP_PAGE_MASK(target_map
));
3705 map_size
= vm_map_round_page(initial_size
,
3706 VM_MAP_PAGE_MASK(target_map
));
3708 size
= vm_object_round_page(initial_size
);
3711 * Find the vm object (if any) corresponding to this port.
3713 if (!IP_VALID(port
)) {
3714 object
= VM_OBJECT_NULL
;
3717 } else if (ip_kotype(port
) == IKOT_NAMED_ENTRY
) {
3718 vm_named_entry_t named_entry
;
3720 named_entry
= (vm_named_entry_t
) port
->ip_kobject
;
3722 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
3723 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
3724 offset
+= named_entry
->data_offset
;
3727 /* a few checks to make sure user is obeying rules */
3729 if (offset
>= named_entry
->size
)
3730 return KERN_INVALID_RIGHT
;
3731 size
= named_entry
->size
- offset
;
3733 if (mask_max_protection
) {
3734 max_protection
&= named_entry
->protection
;
3736 if (mask_cur_protection
) {
3737 cur_protection
&= named_entry
->protection
;
3739 if ((named_entry
->protection
& max_protection
) !=
3741 return KERN_INVALID_RIGHT
;
3742 if ((named_entry
->protection
& cur_protection
) !=
3744 return KERN_INVALID_RIGHT
;
3745 if (offset
+ size
< offset
) {
3747 return KERN_INVALID_ARGUMENT
;
3749 if (named_entry
->size
< (offset
+ initial_size
)) {
3750 return KERN_INVALID_ARGUMENT
;
3753 if (named_entry
->is_copy
) {
3754 /* for a vm_map_copy, we can only map it whole */
3755 if ((size
!= named_entry
->size
) &&
3756 (vm_map_round_page(size
,
3757 VM_MAP_PAGE_MASK(target_map
)) ==
3758 named_entry
->size
)) {
3759 /* XXX FBDP use the rounded size... */
3760 size
= vm_map_round_page(
3762 VM_MAP_PAGE_MASK(target_map
));
3765 if (!(flags
& VM_FLAGS_ANYWHERE
) &&
3767 size
!= named_entry
->size
)) {
3769 * XXX for a mapping at a "fixed" address,
3770 * we can't trim after mapping the whole
3771 * memory entry, so reject a request for a
3774 return KERN_INVALID_ARGUMENT
;
3778 /* the callers parameter offset is defined to be the */
3779 /* offset from beginning of named entry offset in object */
3780 offset
= offset
+ named_entry
->offset
;
3782 if (! VM_MAP_PAGE_ALIGNED(size
,
3783 VM_MAP_PAGE_MASK(target_map
))) {
3785 * Let's not map more than requested;
3786 * vm_map_enter() will handle this "not map-aligned"
3792 named_entry_lock(named_entry
);
3793 if (named_entry
->is_sub_map
) {
3796 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
3797 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
3798 panic("VM_FLAGS_RETURN_DATA_ADDR not expected for submap.");
3801 submap
= named_entry
->backing
.map
;
3802 vm_map_lock(submap
);
3803 vm_map_reference(submap
);
3804 vm_map_unlock(submap
);
3805 named_entry_unlock(named_entry
);
3807 vmk_flags
.vmkf_submap
= TRUE
;
3809 result
= vm_map_enter(target_map
,
3816 (vm_object_t
) submap
,
3822 if (result
!= KERN_SUCCESS
) {
3823 vm_map_deallocate(submap
);
3826 * No need to lock "submap" just to check its
3827 * "mapped" flag: that flag is never reset
3828 * once it's been set and if we race, we'll
3829 * just end up setting it twice, which is OK.
3831 if (submap
->mapped_in_other_pmaps
== FALSE
&&
3832 vm_map_pmap(submap
) != PMAP_NULL
&&
3833 vm_map_pmap(submap
) !=
3834 vm_map_pmap(target_map
)) {
3836 * This submap is being mapped in a map
3837 * that uses a different pmap.
3838 * Set its "mapped_in_other_pmaps" flag
3839 * to indicate that we now need to
3840 * remove mappings from all pmaps rather
3841 * than just the submap's pmap.
3843 vm_map_lock(submap
);
3844 submap
->mapped_in_other_pmaps
= TRUE
;
3845 vm_map_unlock(submap
);
3847 *address
= map_addr
;
3851 } else if (named_entry
->is_copy
) {
3853 vm_map_copy_t copy_map
;
3854 vm_map_entry_t copy_entry
;
3855 vm_map_offset_t copy_addr
;
3857 if (flags
& ~(VM_FLAGS_FIXED
|
3859 VM_FLAGS_OVERWRITE
|
3860 VM_FLAGS_RETURN_4K_DATA_ADDR
|
3861 VM_FLAGS_RETURN_DATA_ADDR
|
3862 VM_FLAGS_ALIAS_MASK
)) {
3863 named_entry_unlock(named_entry
);
3864 return KERN_INVALID_ARGUMENT
;
3867 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
3868 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
3869 offset_in_mapping
= offset
- vm_object_trunc_page(offset
);
3870 if (flags
& VM_FLAGS_RETURN_4K_DATA_ADDR
)
3871 offset_in_mapping
&= ~((signed)(0xFFF));
3872 offset
= vm_object_trunc_page(offset
);
3873 map_size
= vm_object_round_page(offset
+ offset_in_mapping
+ initial_size
) - offset
;
3876 copy_map
= named_entry
->backing
.copy
;
3877 assert(copy_map
->type
== VM_MAP_COPY_ENTRY_LIST
);
3878 if (copy_map
->type
!= VM_MAP_COPY_ENTRY_LIST
) {
3879 /* unsupported type; should not happen */
3880 printf("vm_map_enter_mem_object: "
3881 "memory_entry->backing.copy "
3882 "unsupported type 0x%x\n",
3884 named_entry_unlock(named_entry
);
3885 return KERN_INVALID_ARGUMENT
;
3888 /* reserve a contiguous range */
3889 kr
= vm_map_enter(target_map
,
3891 /* map whole mem entry, trim later: */
3894 flags
& (VM_FLAGS_ANYWHERE
|
3895 VM_FLAGS_OVERWRITE
|
3896 VM_FLAGS_RETURN_4K_DATA_ADDR
|
3897 VM_FLAGS_RETURN_DATA_ADDR
),
3906 if (kr
!= KERN_SUCCESS
) {
3907 named_entry_unlock(named_entry
);
3911 copy_addr
= map_addr
;
3913 for (copy_entry
= vm_map_copy_first_entry(copy_map
);
3914 copy_entry
!= vm_map_copy_to_entry(copy_map
);
3915 copy_entry
= copy_entry
->vme_next
) {
3917 vm_map_kernel_flags_t vmk_remap_flags
;
3918 vm_map_t copy_submap
;
3919 vm_object_t copy_object
;
3920 vm_map_size_t copy_size
;
3921 vm_object_offset_t copy_offset
;
3925 vmk_remap_flags
= VM_MAP_KERNEL_FLAGS_NONE
;
3927 copy_object
= VME_OBJECT(copy_entry
);
3928 copy_offset
= VME_OFFSET(copy_entry
);
3929 copy_size
= (copy_entry
->vme_end
-
3930 copy_entry
->vme_start
);
3931 VM_GET_FLAGS_ALIAS(flags
, copy_vm_alias
);
3932 if (copy_vm_alias
== 0) {
3934 * Caller does not want a specific
3935 * alias for this new mapping: use
3936 * the alias of the original mapping.
3938 copy_vm_alias
= VME_ALIAS(copy_entry
);
3942 if ((copy_addr
+ copy_size
) >
3944 named_entry
->size
/* XXX full size */ )) {
3945 /* over-mapping too much !? */
3946 kr
= KERN_INVALID_ARGUMENT
;
3951 /* take a reference on the object */
3952 if (copy_entry
->is_sub_map
) {
3953 vmk_remap_flags
.vmkf_submap
= TRUE
;
3954 copy_submap
= VME_SUBMAP(copy_entry
);
3955 vm_map_lock(copy_submap
);
3956 vm_map_reference(copy_submap
);
3957 vm_map_unlock(copy_submap
);
3958 copy_object
= (vm_object_t
) copy_submap
;
3960 copy_object
!= VM_OBJECT_NULL
&&
3961 (copy_entry
->needs_copy
||
3962 copy_object
->shadowed
||
3963 (!copy_object
->true_share
&&
3964 !copy_entry
->is_shared
&&
3965 copy_object
->vo_size
> copy_size
))) {
3967 * We need to resolve our side of this
3968 * "symmetric" copy-on-write now; we
3969 * need a new object to map and share,
3970 * instead of the current one which
3971 * might still be shared with the
3974 * Note: A "vm_map_copy_t" does not
3975 * have a lock but we're protected by
3976 * the named entry's lock here.
3978 // assert(copy_object->copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC);
3979 VME_OBJECT_SHADOW(copy_entry
, copy_size
);
3980 if (!copy_entry
->needs_copy
&&
3981 copy_entry
->protection
& VM_PROT_WRITE
) {
3984 prot
= copy_entry
->protection
& ~VM_PROT_WRITE
;
3985 vm_object_pmap_protect(copy_object
,
3993 copy_entry
->needs_copy
= FALSE
;
3994 copy_entry
->is_shared
= TRUE
;
3995 copy_object
= VME_OBJECT(copy_entry
);
3996 copy_offset
= VME_OFFSET(copy_entry
);
3997 vm_object_lock(copy_object
);
3998 vm_object_reference_locked(copy_object
);
3999 if (copy_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
4000 /* we're about to make a shared mapping of this object */
4001 copy_object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
4002 copy_object
->true_share
= TRUE
;
4004 vm_object_unlock(copy_object
);
4007 * We already have the right object
4010 copy_object
= VME_OBJECT(copy_entry
);
4011 vm_object_reference(copy_object
);
4014 /* over-map the object into destination */
4015 remap_flags
|= flags
;
4016 remap_flags
|= VM_FLAGS_FIXED
;
4017 remap_flags
|= VM_FLAGS_OVERWRITE
;
4018 remap_flags
&= ~VM_FLAGS_ANYWHERE
;
4019 if (!copy
&& !copy_entry
->is_sub_map
) {
4021 * copy-on-write should have been
4022 * resolved at this point, or we would
4023 * end up sharing instead of copying.
4025 assert(!copy_entry
->needs_copy
);
4027 kr
= vm_map_enter(target_map
,
4030 (vm_map_offset_t
) 0,
4040 if (kr
!= KERN_SUCCESS
) {
4041 if (copy_entry
->is_sub_map
) {
4042 vm_map_deallocate(copy_submap
);
4044 vm_object_deallocate(copy_object
);
4051 copy_addr
+= copy_size
;
4054 if (kr
== KERN_SUCCESS
) {
4055 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
4056 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
4057 *address
= map_addr
+ offset_in_mapping
;
4059 *address
= map_addr
;
4064 * Trim in front, from 0 to "offset".
4066 vm_map_remove(target_map
,
4072 if (offset
+ map_size
< named_entry
->size
) {
4074 * Trim in back, from
4075 * "offset + map_size" to
4076 * "named_entry->size".
4078 vm_map_remove(target_map
,
4086 named_entry_unlock(named_entry
);
4088 if (kr
!= KERN_SUCCESS
) {
4089 if (! (flags
& VM_FLAGS_OVERWRITE
)) {
4090 /* deallocate the contiguous range */
4091 (void) vm_deallocate(target_map
,
4100 unsigned int access
;
4101 vm_prot_t protections
;
4102 unsigned int wimg_mode
;
4104 /* we are mapping a VM object */
4106 protections
= named_entry
->protection
& VM_PROT_ALL
;
4107 access
= GET_MAP_MEM(named_entry
->protection
);
4109 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
4110 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
4111 offset_in_mapping
= offset
- vm_object_trunc_page(offset
);
4112 if (flags
& VM_FLAGS_RETURN_4K_DATA_ADDR
)
4113 offset_in_mapping
&= ~((signed)(0xFFF));
4114 offset
= vm_object_trunc_page(offset
);
4115 map_size
= vm_object_round_page(offset
+ offset_in_mapping
+ initial_size
) - offset
;
4118 object
= named_entry
->backing
.object
;
4119 assert(object
!= VM_OBJECT_NULL
);
4120 vm_object_lock(object
);
4121 named_entry_unlock(named_entry
);
4123 vm_object_reference_locked(object
);
4125 wimg_mode
= object
->wimg_bits
;
4126 vm_prot_to_wimg(access
, &wimg_mode
);
4127 if (object
->wimg_bits
!= wimg_mode
)
4128 vm_object_change_wimg_mode(object
, wimg_mode
);
4130 vm_object_unlock(object
);
4132 } else if (ip_kotype(port
) == IKOT_MEMORY_OBJECT
) {
4134 * JMM - This is temporary until we unify named entries
4135 * and raw memory objects.
4137 * Detected fake ip_kotype for a memory object. In
4138 * this case, the port isn't really a port at all, but
4139 * instead is just a raw memory object.
4141 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
4142 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
4143 panic("VM_FLAGS_RETURN_DATA_ADDR not expected for raw memory object.");
4146 object
= memory_object_to_vm_object((memory_object_t
)port
);
4147 if (object
== VM_OBJECT_NULL
)
4148 return KERN_INVALID_OBJECT
;
4149 vm_object_reference(object
);
4151 /* wait for object (if any) to be ready */
4152 if (object
!= VM_OBJECT_NULL
) {
4153 if (object
== kernel_object
) {
4154 printf("Warning: Attempt to map kernel object"
4155 " by a non-private kernel entity\n");
4156 return KERN_INVALID_OBJECT
;
4158 if (!object
->pager_ready
) {
4159 vm_object_lock(object
);
4161 while (!object
->pager_ready
) {
4162 vm_object_wait(object
,
4163 VM_OBJECT_EVENT_PAGER_READY
,
4165 vm_object_lock(object
);
4167 vm_object_unlock(object
);
4171 return KERN_INVALID_OBJECT
;
4174 if (object
!= VM_OBJECT_NULL
&&
4176 object
->pager
!= MEMORY_OBJECT_NULL
&&
4177 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
4178 memory_object_t pager
;
4179 vm_prot_t pager_prot
;
4183 * For "named" VM objects, let the pager know that the
4184 * memory object is being mapped. Some pagers need to keep
4185 * track of this, to know when they can reclaim the memory
4186 * object, for example.
4187 * VM calls memory_object_map() for each mapping (specifying
4188 * the protection of each mapping) and calls
4189 * memory_object_last_unmap() when all the mappings are gone.
4191 pager_prot
= max_protection
;
4194 * Copy-On-Write mapping: won't modify the
4197 pager_prot
&= ~VM_PROT_WRITE
;
4199 vm_object_lock(object
);
4200 pager
= object
->pager
;
4201 if (object
->named
&&
4202 pager
!= MEMORY_OBJECT_NULL
&&
4203 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
4204 assert(object
->pager_ready
);
4205 vm_object_mapping_wait(object
, THREAD_UNINT
);
4206 vm_object_mapping_begin(object
);
4207 vm_object_unlock(object
);
4209 kr
= memory_object_map(pager
, pager_prot
);
4210 assert(kr
== KERN_SUCCESS
);
4212 vm_object_lock(object
);
4213 vm_object_mapping_end(object
);
4215 vm_object_unlock(object
);
4219 * Perform the copy if requested
4223 vm_object_t new_object
;
4224 vm_object_offset_t new_offset
;
4226 result
= vm_object_copy_strategically(object
, offset
,
4228 &new_object
, &new_offset
,
4232 if (result
== KERN_MEMORY_RESTART_COPY
) {
4234 boolean_t src_needs_copy
;
4238 * We currently ignore src_needs_copy.
4239 * This really is the issue of how to make
4240 * MEMORY_OBJECT_COPY_SYMMETRIC safe for
4241 * non-kernel users to use. Solution forthcoming.
4242 * In the meantime, since we don't allow non-kernel
4243 * memory managers to specify symmetric copy,
4244 * we won't run into problems here.
4246 new_object
= object
;
4247 new_offset
= offset
;
4248 success
= vm_object_copy_quickly(&new_object
,
4254 result
= KERN_SUCCESS
;
4257 * Throw away the reference to the
4258 * original object, as it won't be mapped.
4261 vm_object_deallocate(object
);
4263 if (result
!= KERN_SUCCESS
) {
4267 object
= new_object
;
4268 offset
= new_offset
;
4272 * If non-kernel users want to try to prefault pages, the mapping and prefault
4273 * needs to be atomic.
4275 kernel_prefault
= (try_prefault
&& vm_kernel_map_is_kernel(target_map
));
4276 vmk_flags
.vmkf_keep_map_locked
= (try_prefault
&& !kernel_prefault
);
4280 /* map this object in a "4K" pager */
4281 result
= vm_map_enter_fourk(target_map
,
4284 (vm_map_offset_t
) mask
,
4295 #endif /* __arm64__ */
4297 result
= vm_map_enter(target_map
,
4298 &map_addr
, map_size
,
4299 (vm_map_offset_t
)mask
,
4305 cur_protection
, max_protection
,
4308 if (result
!= KERN_SUCCESS
)
4309 vm_object_deallocate(object
);
4312 * Try to prefault, and do not forget to release the vm map lock.
4314 if (result
== KERN_SUCCESS
&& try_prefault
) {
4315 mach_vm_address_t va
= map_addr
;
4316 kern_return_t kr
= KERN_SUCCESS
;
4320 pmap_options
= kernel_prefault
? 0 : PMAP_OPTIONS_NOWAIT
;
4321 if (object
->internal
) {
4322 pmap_options
|= PMAP_OPTIONS_INTERNAL
;
4325 for (i
= 0; i
< page_list_count
; ++i
) {
4326 if (!UPL_VALID_PAGE(page_list
, i
)) {
4327 if (kernel_prefault
) {
4328 assertf(FALSE
, "kernel_prefault && !UPL_VALID_PAGE");
4329 result
= KERN_MEMORY_ERROR
;
4334 * If this function call failed, we should stop
4335 * trying to optimize, other calls are likely
4336 * going to fail too.
4338 * We are not gonna report an error for such
4339 * failure though. That's an optimization, not
4340 * something critical.
4342 kr
= pmap_enter_options(target_map
->pmap
,
4343 va
, UPL_PHYS_PAGE(page_list
, i
),
4344 cur_protection
, VM_PROT_NONE
,
4345 0, TRUE
, pmap_options
, NULL
);
4346 if (kr
!= KERN_SUCCESS
) {
4347 OSIncrementAtomic64(&vm_prefault_nb_bailout
);
4348 if (kernel_prefault
) {
4353 OSIncrementAtomic64(&vm_prefault_nb_pages
);
4356 /* Next virtual address */
4359 if (vmk_flags
.vmkf_keep_map_locked
) {
4360 vm_map_unlock(target_map
);
4364 if (flags
& (VM_FLAGS_RETURN_DATA_ADDR
|
4365 VM_FLAGS_RETURN_4K_DATA_ADDR
)) {
4366 *address
= map_addr
+ offset_in_mapping
;
4368 *address
= map_addr
;
4374 vm_map_enter_mem_object(
4375 vm_map_t target_map
,
4376 vm_map_offset_t
*address
,
4377 vm_map_size_t initial_size
,
4378 vm_map_offset_t mask
,
4380 vm_map_kernel_flags_t vmk_flags
,
4383 vm_object_offset_t offset
,
4385 vm_prot_t cur_protection
,
4386 vm_prot_t max_protection
,
4387 vm_inherit_t inheritance
)
4391 ret
= vm_map_enter_mem_object_helper(target_map
,
4408 if (ret
== KERN_SUCCESS
&& address
&& target_map
->pmap
== kernel_pmap
) {
4409 kasan_notify_address(*address
, initial_size
);
4417 vm_map_enter_mem_object_prefault(
4418 vm_map_t target_map
,
4419 vm_map_offset_t
*address
,
4420 vm_map_size_t initial_size
,
4421 vm_map_offset_t mask
,
4423 vm_map_kernel_flags_t vmk_flags
,
4426 vm_object_offset_t offset
,
4427 vm_prot_t cur_protection
,
4428 vm_prot_t max_protection
,
4429 upl_page_list_ptr_t page_list
,
4430 unsigned int page_list_count
)
4434 ret
= vm_map_enter_mem_object_helper(target_map
,
4451 if (ret
== KERN_SUCCESS
&& address
&& target_map
->pmap
== kernel_pmap
) {
4452 kasan_notify_address(*address
, initial_size
);
4461 vm_map_enter_mem_object_control(
4462 vm_map_t target_map
,
4463 vm_map_offset_t
*address
,
4464 vm_map_size_t initial_size
,
4465 vm_map_offset_t mask
,
4467 vm_map_kernel_flags_t vmk_flags
,
4469 memory_object_control_t control
,
4470 vm_object_offset_t offset
,
4472 vm_prot_t cur_protection
,
4473 vm_prot_t max_protection
,
4474 vm_inherit_t inheritance
)
4476 vm_map_address_t map_addr
;
4477 vm_map_size_t map_size
;
4479 vm_object_size_t size
;
4480 kern_return_t result
;
4481 memory_object_t pager
;
4482 vm_prot_t pager_prot
;
4485 boolean_t fourk
= vmk_flags
.vmkf_fourk
;
4486 #endif /* __arm64__ */
4489 * Check arguments for validity
4491 if ((target_map
== VM_MAP_NULL
) ||
4492 (cur_protection
& ~VM_PROT_ALL
) ||
4493 (max_protection
& ~VM_PROT_ALL
) ||
4494 (inheritance
> VM_INHERIT_LAST_VALID
) ||
4495 initial_size
== 0) {
4496 return KERN_INVALID_ARGUMENT
;
4501 map_addr
= vm_map_trunc_page(*address
,
4503 map_size
= vm_map_round_page(initial_size
,
4506 #endif /* __arm64__ */
4508 map_addr
= vm_map_trunc_page(*address
,
4509 VM_MAP_PAGE_MASK(target_map
));
4510 map_size
= vm_map_round_page(initial_size
,
4511 VM_MAP_PAGE_MASK(target_map
));
4513 size
= vm_object_round_page(initial_size
);
4515 object
= memory_object_control_to_vm_object(control
);
4517 if (object
== VM_OBJECT_NULL
)
4518 return KERN_INVALID_OBJECT
;
4520 if (object
== kernel_object
) {
4521 printf("Warning: Attempt to map kernel object"
4522 " by a non-private kernel entity\n");
4523 return KERN_INVALID_OBJECT
;
4526 vm_object_lock(object
);
4527 object
->ref_count
++;
4528 vm_object_res_reference(object
);
4531 * For "named" VM objects, let the pager know that the
4532 * memory object is being mapped. Some pagers need to keep
4533 * track of this, to know when they can reclaim the memory
4534 * object, for example.
4535 * VM calls memory_object_map() for each mapping (specifying
4536 * the protection of each mapping) and calls
4537 * memory_object_last_unmap() when all the mappings are gone.
4539 pager_prot
= max_protection
;
4541 pager_prot
&= ~VM_PROT_WRITE
;
4543 pager
= object
->pager
;
4544 if (object
->named
&&
4545 pager
!= MEMORY_OBJECT_NULL
&&
4546 object
->copy_strategy
!= MEMORY_OBJECT_COPY_NONE
) {
4547 assert(object
->pager_ready
);
4548 vm_object_mapping_wait(object
, THREAD_UNINT
);
4549 vm_object_mapping_begin(object
);
4550 vm_object_unlock(object
);
4552 kr
= memory_object_map(pager
, pager_prot
);
4553 assert(kr
== KERN_SUCCESS
);
4555 vm_object_lock(object
);
4556 vm_object_mapping_end(object
);
4558 vm_object_unlock(object
);
4561 * Perform the copy if requested
4565 vm_object_t new_object
;
4566 vm_object_offset_t new_offset
;
4568 result
= vm_object_copy_strategically(object
, offset
, size
,
4569 &new_object
, &new_offset
,
4573 if (result
== KERN_MEMORY_RESTART_COPY
) {
4575 boolean_t src_needs_copy
;
4579 * We currently ignore src_needs_copy.
4580 * This really is the issue of how to make
4581 * MEMORY_OBJECT_COPY_SYMMETRIC safe for
4582 * non-kernel users to use. Solution forthcoming.
4583 * In the meantime, since we don't allow non-kernel
4584 * memory managers to specify symmetric copy,
4585 * we won't run into problems here.
4587 new_object
= object
;
4588 new_offset
= offset
;
4589 success
= vm_object_copy_quickly(&new_object
,
4594 result
= KERN_SUCCESS
;
4597 * Throw away the reference to the
4598 * original object, as it won't be mapped.
4601 vm_object_deallocate(object
);
4603 if (result
!= KERN_SUCCESS
) {
4607 object
= new_object
;
4608 offset
= new_offset
;
4613 result
= vm_map_enter_fourk(target_map
,
4616 (vm_map_offset_t
)mask
,
4622 cur_protection
, max_protection
,
4625 #endif /* __arm64__ */
4627 result
= vm_map_enter(target_map
,
4628 &map_addr
, map_size
,
4629 (vm_map_offset_t
)mask
,
4635 cur_protection
, max_protection
,
4638 if (result
!= KERN_SUCCESS
)
4639 vm_object_deallocate(object
);
4640 *address
= map_addr
;
4649 extern pmap_paddr_t avail_start
, avail_end
;
4653 * Allocate memory in the specified map, with the caveat that
4654 * the memory is physically contiguous. This call may fail
4655 * if the system can't find sufficient contiguous memory.
4656 * This call may cause or lead to heart-stopping amounts of
4659 * Memory obtained from this call should be freed in the
4660 * normal way, viz., via vm_deallocate.
4665 vm_map_offset_t
*addr
,
4669 vm_object_t cpm_obj
;
4673 vm_map_offset_t va
, start
, end
, offset
;
4675 vm_map_offset_t prev_addr
= 0;
4676 #endif /* MACH_ASSERT */
4678 boolean_t anywhere
= ((VM_FLAGS_ANYWHERE
& flags
) != 0);
4681 VM_GET_FLAGS_ALIAS(flags
, tag
);
4685 return KERN_SUCCESS
;
4688 *addr
= vm_map_min(map
);
4690 *addr
= vm_map_trunc_page(*addr
,
4691 VM_MAP_PAGE_MASK(map
));
4692 size
= vm_map_round_page(size
,
4693 VM_MAP_PAGE_MASK(map
));
4696 * LP64todo - cpm_allocate should probably allow
4697 * allocations of >4GB, but not with the current
4698 * algorithm, so just cast down the size for now.
4700 if (size
> VM_MAX_ADDRESS
)
4701 return KERN_RESOURCE_SHORTAGE
;
4702 if ((kr
= cpm_allocate(CAST_DOWN(vm_size_t
, size
),
4703 &pages
, 0, 0, TRUE
, flags
)) != KERN_SUCCESS
)
4706 cpm_obj
= vm_object_allocate((vm_object_size_t
)size
);
4707 assert(cpm_obj
!= VM_OBJECT_NULL
);
4708 assert(cpm_obj
->internal
);
4709 assert(cpm_obj
->vo_size
== (vm_object_size_t
)size
);
4710 assert(cpm_obj
->can_persist
== FALSE
);
4711 assert(cpm_obj
->pager_created
== FALSE
);
4712 assert(cpm_obj
->pageout
== FALSE
);
4713 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
4716 * Insert pages into object.
4719 vm_object_lock(cpm_obj
);
4720 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
4722 pages
= NEXT_PAGE(m
);
4723 *(NEXT_PAGE_PTR(m
)) = VM_PAGE_NULL
;
4725 assert(!m
->gobbled
);
4727 assert(!m
->pageout
);
4729 assert(VM_PAGE_WIRED(m
));
4731 assert(VM_PAGE_GET_PHYS_PAGE(m
)>=(avail_start
>>PAGE_SHIFT
) && VM_PAGE_GET_PHYS_PAGE(m
)<=(avail_end
>>PAGE_SHIFT
));
4734 vm_page_insert(m
, cpm_obj
, offset
);
4736 assert(cpm_obj
->resident_page_count
== size
/ PAGE_SIZE
);
4737 vm_object_unlock(cpm_obj
);
4740 * Hang onto a reference on the object in case a
4741 * multi-threaded application for some reason decides
4742 * to deallocate the portion of the address space into
4743 * which we will insert this object.
4745 * Unfortunately, we must insert the object now before
4746 * we can talk to the pmap module about which addresses
4747 * must be wired down. Hence, the race with a multi-
4750 vm_object_reference(cpm_obj
);
4753 * Insert object into map.
4762 VM_MAP_KERNEL_FLAGS_NONE
,
4764 (vm_object_offset_t
)0,
4768 VM_INHERIT_DEFAULT
);
4770 if (kr
!= KERN_SUCCESS
) {
4772 * A CPM object doesn't have can_persist set,
4773 * so all we have to do is deallocate it to
4774 * free up these pages.
4776 assert(cpm_obj
->pager_created
== FALSE
);
4777 assert(cpm_obj
->can_persist
== FALSE
);
4778 assert(cpm_obj
->pageout
== FALSE
);
4779 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
4780 vm_object_deallocate(cpm_obj
); /* kill acquired ref */
4781 vm_object_deallocate(cpm_obj
); /* kill creation ref */
4785 * Inform the physical mapping system that the
4786 * range of addresses may not fault, so that
4787 * page tables and such can be locked down as well.
4791 pmap
= vm_map_pmap(map
);
4792 pmap_pageable(pmap
, start
, end
, FALSE
);
4795 * Enter each page into the pmap, to avoid faults.
4796 * Note that this loop could be coded more efficiently,
4797 * if the need arose, rather than looking up each page
4800 for (offset
= 0, va
= start
; offset
< size
;
4801 va
+= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
4804 vm_object_lock(cpm_obj
);
4805 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
4806 assert(m
!= VM_PAGE_NULL
);
4808 vm_page_zero_fill(m
);
4810 type_of_fault
= DBG_ZERO_FILL_FAULT
;
4812 vm_fault_enter(m
, pmap
, va
, VM_PROT_ALL
, VM_PROT_WRITE
,
4814 FALSE
, /* change_wiring */
4815 VM_KERN_MEMORY_NONE
, /* tag - not wiring */
4816 FALSE
, /* no_cache */
4817 FALSE
, /* cs_bypass */
4819 0, /* pmap_options */
4820 NULL
, /* need_retry */
4823 vm_object_unlock(cpm_obj
);
4828 * Verify ordering in address space.
4830 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
4831 vm_object_lock(cpm_obj
);
4832 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
4833 vm_object_unlock(cpm_obj
);
4834 if (m
== VM_PAGE_NULL
)
4835 panic("vm_allocate_cpm: obj %p off 0x%llx no page",
4836 cpm_obj
, (uint64_t)offset
);
4840 assert(!m
->fictitious
);
4841 assert(!m
->private);
4844 assert(!m
->cleaning
);
4845 assert(!m
->laundry
);
4846 assert(!m
->precious
);
4847 assert(!m
->clustered
);
4849 if (VM_PAGE_GET_PHYS_PAGE(m
) != prev_addr
+ 1) {
4850 printf("start 0x%llx end 0x%llx va 0x%llx\n",
4851 (uint64_t)start
, (uint64_t)end
, (uint64_t)va
);
4852 printf("obj %p off 0x%llx\n", cpm_obj
, (uint64_t)offset
);
4853 printf("m %p prev_address 0x%llx\n", m
, (uint64_t)prev_addr
);
4854 panic("vm_allocate_cpm: pages not contig!");
4857 prev_addr
= VM_PAGE_GET_PHYS_PAGE(m
);
4859 #endif /* MACH_ASSERT */
4861 vm_object_deallocate(cpm_obj
); /* kill extra ref */
4870 * Interface is defined in all cases, but unless the kernel
4871 * is built explicitly for this option, the interface does
4877 __unused vm_map_t map
,
4878 __unused vm_map_offset_t
*addr
,
4879 __unused vm_map_size_t size
,
4882 return KERN_FAILURE
;
4886 /* Not used without nested pmaps */
4887 #ifndef NO_NESTED_PMAP
4889 * Clip and unnest a portion of a nested submap mapping.
4896 vm_map_entry_t entry
,
4897 vm_map_offset_t start_unnest
,
4898 vm_map_offset_t end_unnest
)
4900 vm_map_offset_t old_start_unnest
= start_unnest
;
4901 vm_map_offset_t old_end_unnest
= end_unnest
;
4903 assert(entry
->is_sub_map
);
4904 assert(VME_SUBMAP(entry
) != NULL
);
4905 assert(entry
->use_pmap
);
4908 * Query the platform for the optimal unnest range.
4909 * DRK: There's some duplication of effort here, since
4910 * callers may have adjusted the range to some extent. This
4911 * routine was introduced to support 1GiB subtree nesting
4912 * for x86 platforms, which can also nest on 2MiB boundaries
4913 * depending on size/alignment.
4915 if (pmap_adjust_unnest_parameters(map
->pmap
, &start_unnest
, &end_unnest
)) {
4916 assert(VME_SUBMAP(entry
)->is_nested_map
);
4917 assert(!VME_SUBMAP(entry
)->disable_vmentry_reuse
);
4918 log_unnest_badness(map
,
4921 VME_SUBMAP(entry
)->is_nested_map
,
4923 VME_SUBMAP(entry
)->lowest_unnestable_start
-
4924 VME_OFFSET(entry
)));
4927 if (entry
->vme_start
> start_unnest
||
4928 entry
->vme_end
< end_unnest
) {
4929 panic("vm_map_clip_unnest(0x%llx,0x%llx): "
4930 "bad nested entry: start=0x%llx end=0x%llx\n",
4931 (long long)start_unnest
, (long long)end_unnest
,
4932 (long long)entry
->vme_start
, (long long)entry
->vme_end
);
4935 if (start_unnest
> entry
->vme_start
) {
4936 _vm_map_clip_start(&map
->hdr
,
4939 if (map
->holelistenabled
) {
4940 vm_map_store_update_first_free(map
, NULL
, FALSE
);
4942 vm_map_store_update_first_free(map
, map
->first_free
, FALSE
);
4945 if (entry
->vme_end
> end_unnest
) {
4946 _vm_map_clip_end(&map
->hdr
,
4949 if (map
->holelistenabled
) {
4950 vm_map_store_update_first_free(map
, NULL
, FALSE
);
4952 vm_map_store_update_first_free(map
, map
->first_free
, FALSE
);
4956 pmap_unnest(map
->pmap
,
4958 entry
->vme_end
- entry
->vme_start
);
4959 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
4960 /* clean up parent map/maps */
4961 vm_map_submap_pmap_clean(
4962 map
, entry
->vme_start
,
4967 entry
->use_pmap
= FALSE
;
4968 if ((map
->pmap
!= kernel_pmap
) &&
4969 (VME_ALIAS(entry
) == VM_MEMORY_SHARED_PMAP
)) {
4970 VME_ALIAS_SET(entry
, VM_MEMORY_UNSHARED_PMAP
);
4973 #endif /* NO_NESTED_PMAP */
4976 * vm_map_clip_start: [ internal use only ]
4978 * Asserts that the given entry begins at or after
4979 * the specified address; if necessary,
4980 * it splits the entry into two.
4985 vm_map_entry_t entry
,
4986 vm_map_offset_t startaddr
)
4988 #ifndef NO_NESTED_PMAP
4989 if (entry
->is_sub_map
&&
4991 startaddr
>= entry
->vme_start
) {
4992 vm_map_offset_t start_unnest
, end_unnest
;
4995 * Make sure "startaddr" is no longer in a nested range
4996 * before we clip. Unnest only the minimum range the platform
4998 * vm_map_clip_unnest may perform additional adjustments to
5001 start_unnest
= startaddr
& ~(pmap_nesting_size_min
- 1);
5002 end_unnest
= start_unnest
+ pmap_nesting_size_min
;
5003 vm_map_clip_unnest(map
, entry
, start_unnest
, end_unnest
);
5005 #endif /* NO_NESTED_PMAP */
5006 if (startaddr
> entry
->vme_start
) {
5007 if (VME_OBJECT(entry
) &&
5008 !entry
->is_sub_map
&&
5009 VME_OBJECT(entry
)->phys_contiguous
) {
5010 pmap_remove(map
->pmap
,
5011 (addr64_t
)(entry
->vme_start
),
5012 (addr64_t
)(entry
->vme_end
));
5014 if (entry
->vme_atomic
) {
5015 panic("Attempting to clip an atomic VM entry! (map: %p, entry: %p)\n", map
, entry
);
5017 _vm_map_clip_start(&map
->hdr
, entry
, startaddr
);
5018 if (map
->holelistenabled
) {
5019 vm_map_store_update_first_free(map
, NULL
, FALSE
);
5021 vm_map_store_update_first_free(map
, map
->first_free
, FALSE
);
5027 #define vm_map_copy_clip_start(copy, entry, startaddr) \
5029 if ((startaddr) > (entry)->vme_start) \
5030 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
5034 * This routine is called only when it is known that
5035 * the entry must be split.
5039 struct vm_map_header
*map_header
,
5040 vm_map_entry_t entry
,
5041 vm_map_offset_t start
)
5043 vm_map_entry_t new_entry
;
5046 * Split off the front portion --
5047 * note that we must insert the new
5048 * entry BEFORE this one, so that
5049 * this entry has the specified starting
5053 if (entry
->map_aligned
) {
5054 assert(VM_MAP_PAGE_ALIGNED(start
,
5055 VM_MAP_HDR_PAGE_MASK(map_header
)));
5058 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
5059 vm_map_entry_copy_full(new_entry
, entry
);
5061 new_entry
->vme_end
= start
;
5062 assert(new_entry
->vme_start
< new_entry
->vme_end
);
5063 VME_OFFSET_SET(entry
, VME_OFFSET(entry
) + (start
- entry
->vme_start
));
5064 assert(start
< entry
->vme_end
);
5065 entry
->vme_start
= start
;
5067 _vm_map_store_entry_link(map_header
, entry
->vme_prev
, new_entry
);
5069 if (entry
->is_sub_map
)
5070 vm_map_reference(VME_SUBMAP(new_entry
));
5072 vm_object_reference(VME_OBJECT(new_entry
));
5077 * vm_map_clip_end: [ internal use only ]
5079 * Asserts that the given entry ends at or before
5080 * the specified address; if necessary,
5081 * it splits the entry into two.
5086 vm_map_entry_t entry
,
5087 vm_map_offset_t endaddr
)
5089 if (endaddr
> entry
->vme_end
) {
5091 * Within the scope of this clipping, limit "endaddr" to
5092 * the end of this map entry...
5094 endaddr
= entry
->vme_end
;
5096 #ifndef NO_NESTED_PMAP
5097 if (entry
->is_sub_map
&& entry
->use_pmap
) {
5098 vm_map_offset_t start_unnest
, end_unnest
;
5101 * Make sure the range between the start of this entry and
5102 * the new "endaddr" is no longer nested before we clip.
5103 * Unnest only the minimum range the platform can handle.
5104 * vm_map_clip_unnest may perform additional adjustments to
5107 start_unnest
= entry
->vme_start
;
5109 (endaddr
+ pmap_nesting_size_min
- 1) &
5110 ~(pmap_nesting_size_min
- 1);
5111 vm_map_clip_unnest(map
, entry
, start_unnest
, end_unnest
);
5113 #endif /* NO_NESTED_PMAP */
5114 if (endaddr
< entry
->vme_end
) {
5115 if (VME_OBJECT(entry
) &&
5116 !entry
->is_sub_map
&&
5117 VME_OBJECT(entry
)->phys_contiguous
) {
5118 pmap_remove(map
->pmap
,
5119 (addr64_t
)(entry
->vme_start
),
5120 (addr64_t
)(entry
->vme_end
));
5122 if (entry
->vme_atomic
) {
5123 panic("Attempting to clip an atomic VM entry! (map: %p, entry: %p)\n", map
, entry
);
5125 _vm_map_clip_end(&map
->hdr
, entry
, endaddr
);
5126 if (map
->holelistenabled
) {
5127 vm_map_store_update_first_free(map
, NULL
, FALSE
);
5129 vm_map_store_update_first_free(map
, map
->first_free
, FALSE
);
5135 #define vm_map_copy_clip_end(copy, entry, endaddr) \
5137 if ((endaddr) < (entry)->vme_end) \
5138 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
5142 * This routine is called only when it is known that
5143 * the entry must be split.
5147 struct vm_map_header
*map_header
,
5148 vm_map_entry_t entry
,
5149 vm_map_offset_t end
)
5151 vm_map_entry_t new_entry
;
5154 * Create a new entry and insert it
5155 * AFTER the specified entry
5158 if (entry
->map_aligned
) {
5159 assert(VM_MAP_PAGE_ALIGNED(end
,
5160 VM_MAP_HDR_PAGE_MASK(map_header
)));
5163 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
5164 vm_map_entry_copy_full(new_entry
, entry
);
5166 assert(entry
->vme_start
< end
);
5167 new_entry
->vme_start
= entry
->vme_end
= end
;
5168 VME_OFFSET_SET(new_entry
,
5169 VME_OFFSET(new_entry
) + (end
- entry
->vme_start
));
5170 assert(new_entry
->vme_start
< new_entry
->vme_end
);
5172 _vm_map_store_entry_link(map_header
, entry
, new_entry
);
5174 if (entry
->is_sub_map
)
5175 vm_map_reference(VME_SUBMAP(new_entry
));
5177 vm_object_reference(VME_OBJECT(new_entry
));
5182 * VM_MAP_RANGE_CHECK: [ internal use only ]
5184 * Asserts that the starting and ending region
5185 * addresses fall within the valid range of the map.
5187 #define VM_MAP_RANGE_CHECK(map, start, end) \
5189 if (start < vm_map_min(map)) \
5190 start = vm_map_min(map); \
5191 if (end > vm_map_max(map)) \
5192 end = vm_map_max(map); \
5198 * vm_map_range_check: [ internal use only ]
5200 * Check that the region defined by the specified start and
5201 * end addresses are wholly contained within a single map
5202 * entry or set of adjacent map entries of the spacified map,
5203 * i.e. the specified region contains no unmapped space.
5204 * If any or all of the region is unmapped, FALSE is returned.
5205 * Otherwise, TRUE is returned and if the output argument 'entry'
5206 * is not NULL it points to the map entry containing the start
5209 * The map is locked for reading on entry and is left locked.
5214 vm_map_offset_t start
,
5215 vm_map_offset_t end
,
5216 vm_map_entry_t
*entry
)
5219 vm_map_offset_t prev
;
5222 * Basic sanity checks first
5224 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
5228 * Check first if the region starts within a valid
5229 * mapping for the map.
5231 if (!vm_map_lookup_entry(map
, start
, &cur
))
5235 * Optimize for the case that the region is contained
5236 * in a single map entry.
5238 if (entry
!= (vm_map_entry_t
*) NULL
)
5240 if (end
<= cur
->vme_end
)
5244 * If the region is not wholly contained within a
5245 * single entry, walk the entries looking for holes.
5247 prev
= cur
->vme_end
;
5248 cur
= cur
->vme_next
;
5249 while ((cur
!= vm_map_to_entry(map
)) && (prev
== cur
->vme_start
)) {
5250 if (end
<= cur
->vme_end
)
5252 prev
= cur
->vme_end
;
5253 cur
= cur
->vme_next
;
5259 * vm_map_submap: [ kernel use only ]
5261 * Mark the given range as handled by a subordinate map.
5263 * This range must have been created with vm_map_find using
5264 * the vm_submap_object, and no other operations may have been
5265 * performed on this range prior to calling vm_map_submap.
5267 * Only a limited number of operations can be performed
5268 * within this rage after calling vm_map_submap:
5270 * [Don't try vm_map_copyin!]
5272 * To remove a submapping, one must first remove the
5273 * range from the superior map, and then destroy the
5274 * submap (if desired). [Better yet, don't try it.]
5279 vm_map_offset_t start
,
5280 vm_map_offset_t end
,
5282 vm_map_offset_t offset
,
5283 #ifdef NO_NESTED_PMAP
5285 #endif /* NO_NESTED_PMAP */
5288 vm_map_entry_t entry
;
5289 kern_return_t result
= KERN_INVALID_ARGUMENT
;
5294 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
5295 entry
= entry
->vme_next
;
5298 if (entry
== vm_map_to_entry(map
) ||
5299 entry
->is_sub_map
) {
5301 return KERN_INVALID_ARGUMENT
;
5304 vm_map_clip_start(map
, entry
, start
);
5305 vm_map_clip_end(map
, entry
, end
);
5307 if ((entry
->vme_start
== start
) && (entry
->vme_end
== end
) &&
5308 (!entry
->is_sub_map
) &&
5309 ((object
= VME_OBJECT(entry
)) == vm_submap_object
) &&
5310 (object
->resident_page_count
== 0) &&
5311 (object
->copy
== VM_OBJECT_NULL
) &&
5312 (object
->shadow
== VM_OBJECT_NULL
) &&
5313 (!object
->pager_created
)) {
5314 VME_OFFSET_SET(entry
, (vm_object_offset_t
)offset
);
5315 VME_OBJECT_SET(entry
, VM_OBJECT_NULL
);
5316 vm_object_deallocate(object
);
5317 entry
->is_sub_map
= TRUE
;
5318 entry
->use_pmap
= FALSE
;
5319 VME_SUBMAP_SET(entry
, submap
);
5320 vm_map_reference(submap
);
5321 if (submap
->mapped_in_other_pmaps
== FALSE
&&
5322 vm_map_pmap(submap
) != PMAP_NULL
&&
5323 vm_map_pmap(submap
) != vm_map_pmap(map
)) {
5325 * This submap is being mapped in a map
5326 * that uses a different pmap.
5327 * Set its "mapped_in_other_pmaps" flag
5328 * to indicate that we now need to
5329 * remove mappings from all pmaps rather
5330 * than just the submap's pmap.
5332 submap
->mapped_in_other_pmaps
= TRUE
;
5335 #ifndef NO_NESTED_PMAP
5337 /* nest if platform code will allow */
5338 if(submap
->pmap
== NULL
) {
5339 ledger_t ledger
= map
->pmap
->ledger
;
5340 submap
->pmap
= pmap_create(ledger
,
5341 (vm_map_size_t
) 0, FALSE
);
5342 if(submap
->pmap
== PMAP_NULL
) {
5344 return(KERN_NO_SPACE
);
5346 #if defined(__arm__) || defined(__arm64__)
5347 pmap_set_nested(submap
->pmap
);
5350 result
= pmap_nest(map
->pmap
,
5351 (VME_SUBMAP(entry
))->pmap
,
5354 (uint64_t)(end
- start
));
5356 panic("vm_map_submap: pmap_nest failed, rc = %08X\n", result
);
5357 entry
->use_pmap
= TRUE
;
5359 #else /* NO_NESTED_PMAP */
5360 pmap_remove(map
->pmap
, (addr64_t
)start
, (addr64_t
)end
);
5361 #endif /* NO_NESTED_PMAP */
5362 result
= KERN_SUCCESS
;
5369 #if CONFIG_EMBEDDED && (DEVELOPMENT || DEBUG)
5370 #include <sys/codesign.h>
5371 extern int proc_selfcsflags(void);
5372 extern int panic_on_unsigned_execute
;
5373 #endif /* CONFIG_EMBEDDED && (DEVELOPMENT || DEBUG) */
5378 * Sets the protection of the specified address
5379 * region in the target map. If "set_max" is
5380 * specified, the maximum protection is to be set;
5381 * otherwise, only the current protection is affected.
5386 vm_map_offset_t start
,
5387 vm_map_offset_t end
,
5391 vm_map_entry_t current
;
5392 vm_map_offset_t prev
;
5393 vm_map_entry_t entry
;
5395 int pmap_options
= 0;
5399 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
5400 map
, start
, end
, new_prot
, set_max
);
5402 if (new_prot
& VM_PROT_COPY
) {
5403 vm_map_offset_t new_start
;
5404 vm_prot_t cur_prot
, max_prot
;
5405 vm_map_kernel_flags_t kflags
;
5407 /* LP64todo - see below */
5408 if (start
>= map
->max_offset
) {
5409 return KERN_INVALID_ADDRESS
;
5412 kflags
= VM_MAP_KERNEL_FLAGS_NONE
;
5413 kflags
.vmkf_remap_prot_copy
= TRUE
;
5415 kr
= vm_map_remap(map
,
5419 VM_FLAGS_FIXED
| VM_FLAGS_OVERWRITE
,
5424 TRUE
, /* copy-on-write remapping! */
5427 VM_INHERIT_DEFAULT
);
5428 if (kr
!= KERN_SUCCESS
) {
5431 new_prot
&= ~VM_PROT_COPY
;
5436 /* LP64todo - remove this check when vm_map_commpage64()
5437 * no longer has to stuff in a map_entry for the commpage
5438 * above the map's max_offset.
5440 if (start
>= map
->max_offset
) {
5442 return(KERN_INVALID_ADDRESS
);
5447 * Lookup the entry. If it doesn't start in a valid
5448 * entry, return an error.
5450 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
5452 return(KERN_INVALID_ADDRESS
);
5455 if (entry
->superpage_size
&& (start
& (SUPERPAGE_SIZE
-1))) { /* extend request to whole entry */
5456 start
= SUPERPAGE_ROUND_DOWN(start
);
5461 if (entry
->superpage_size
)
5462 end
= SUPERPAGE_ROUND_UP(end
);
5465 * Make a first pass to check for protection and address
5470 prev
= current
->vme_start
;
5471 while ((current
!= vm_map_to_entry(map
)) &&
5472 (current
->vme_start
< end
)) {
5475 * If there is a hole, return an error.
5477 if (current
->vme_start
!= prev
) {
5479 return(KERN_INVALID_ADDRESS
);
5482 new_max
= current
->max_protection
;
5483 if ((new_prot
& new_max
) != new_prot
) {
5485 return(KERN_PROTECTION_FAILURE
);
5489 if (new_prot
& VM_PROT_WRITE
) {
5490 if ((new_prot
& VM_PROT_EXECUTE
) && !(current
->used_for_jit
)) {
5491 printf("EMBEDDED: %s can't have both write and exec at the same time\n", __FUNCTION__
);
5492 new_prot
&= ~VM_PROT_EXECUTE
;
5497 prev
= current
->vme_end
;
5498 current
= current
->vme_next
;
5503 end
== vm_map_round_page(prev
, VM_MAP_PAGE_MASK(map
))) {
5504 vm_map_entry_t prev_entry
;
5506 prev_entry
= current
->vme_prev
;
5507 if (prev_entry
!= vm_map_to_entry(map
) &&
5508 !prev_entry
->map_aligned
&&
5509 (vm_map_round_page(prev_entry
->vme_end
,
5510 VM_MAP_PAGE_MASK(map
))
5513 * The last entry in our range is not "map-aligned"
5514 * but it would have reached all the way to "end"
5515 * if it had been map-aligned, so this is not really
5516 * a hole in the range and we can proceed.
5521 #endif /* __arm64__ */
5525 return(KERN_INVALID_ADDRESS
);
5529 * Go back and fix up protections.
5530 * Clip to start here if the range starts within
5535 if (current
!= vm_map_to_entry(map
)) {
5536 /* clip and unnest if necessary */
5537 vm_map_clip_start(map
, current
, start
);
5540 while ((current
!= vm_map_to_entry(map
)) &&
5541 (current
->vme_start
< end
)) {
5545 vm_map_clip_end(map
, current
, end
);
5547 if (current
->is_sub_map
) {
5548 /* clipping did unnest if needed */
5549 assert(!current
->use_pmap
);
5552 old_prot
= current
->protection
;
5555 current
->max_protection
= new_prot
;
5556 current
->protection
= new_prot
& old_prot
;
5558 current
->protection
= new_prot
;
5562 * Update physical map if necessary.
5563 * If the request is to turn off write protection,
5564 * we won't do it for real (in pmap). This is because
5565 * it would cause copy-on-write to fail. We've already
5566 * set, the new protection in the map, so if a
5567 * write-protect fault occurred, it will be fixed up
5568 * properly, COW or not.
5570 if (current
->protection
!= old_prot
) {
5571 /* Look one level in we support nested pmaps */
5572 /* from mapped submaps which are direct entries */
5577 prot
= current
->protection
;
5578 if (current
->is_sub_map
|| (VME_OBJECT(current
) == NULL
) || (VME_OBJECT(current
) != compressor_object
)) {
5579 prot
&= ~VM_PROT_WRITE
;
5581 assert(!VME_OBJECT(current
)->code_signed
);
5582 assert(VME_OBJECT(current
)->copy_strategy
== MEMORY_OBJECT_COPY_NONE
);
5585 if (override_nx(map
, VME_ALIAS(current
)) && prot
)
5586 prot
|= VM_PROT_EXECUTE
;
5588 #if CONFIG_EMBEDDED && (DEVELOPMENT || DEBUG)
5589 if (!(old_prot
& VM_PROT_EXECUTE
) &&
5590 (prot
& VM_PROT_EXECUTE
) &&
5591 (proc_selfcsflags() & CS_KILL
) &&
5592 panic_on_unsigned_execute
) {
5593 panic("vm_map_protect(%p,0x%llx,0x%llx) old=0x%x new=0x%x - <rdar://23770418> code-signing bypass?\n", map
, (uint64_t)current
->vme_start
, (uint64_t)current
->vme_end
, old_prot
, prot
);
5595 #endif /* CONFIG_EMBEDDED && (DEVELOPMENT || DEBUG) */
5597 if (pmap_has_prot_policy(prot
)) {
5598 if (current
->wired_count
) {
5599 panic("vm_map_protect(%p,0x%llx,0x%llx) new=0x%x wired=%x\n",
5600 map
, (uint64_t)current
->vme_start
, (uint64_t)current
->vme_end
, prot
, current
->wired_count
);
5603 /* If the pmap layer cares about this
5604 * protection type, force a fault for
5605 * each page so that vm_fault will
5606 * repopulate the page with the full
5607 * set of protections.
5610 * TODO: We don't seem to need this,
5611 * but this is due to an internal
5612 * implementation detail of
5613 * pmap_protect. Do we want to rely
5616 prot
= VM_PROT_NONE
;
5619 if (current
->is_sub_map
&& current
->use_pmap
) {
5620 pmap_protect(VME_SUBMAP(current
)->pmap
,
5625 if (prot
& VM_PROT_WRITE
) {
5626 if (VME_OBJECT(current
) == compressor_object
) {
5628 * For write requests on the
5629 * compressor, we wil ask the
5630 * pmap layer to prevent us from
5631 * taking a write fault when we
5632 * attempt to access the mapping
5635 pmap_options
|= PMAP_OPTIONS_PROTECT_IMMEDIATE
;
5639 pmap_protect_options(map
->pmap
,
5647 current
= current
->vme_next
;
5651 while ((current
!= vm_map_to_entry(map
)) &&
5652 (current
->vme_start
<= end
)) {
5653 vm_map_simplify_entry(map
, current
);
5654 current
= current
->vme_next
;
5658 return(KERN_SUCCESS
);
5664 * Sets the inheritance of the specified address
5665 * range in the target map. Inheritance
5666 * affects how the map will be shared with
5667 * child maps at the time of vm_map_fork.
5672 vm_map_offset_t start
,
5673 vm_map_offset_t end
,
5674 vm_inherit_t new_inheritance
)
5676 vm_map_entry_t entry
;
5677 vm_map_entry_t temp_entry
;
5681 VM_MAP_RANGE_CHECK(map
, start
, end
);
5683 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
5687 temp_entry
= temp_entry
->vme_next
;
5691 /* first check entire range for submaps which can't support the */
5692 /* given inheritance. */
5693 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
5694 if(entry
->is_sub_map
) {
5695 if(new_inheritance
== VM_INHERIT_COPY
) {
5697 return(KERN_INVALID_ARGUMENT
);
5701 entry
= entry
->vme_next
;
5705 if (entry
!= vm_map_to_entry(map
)) {
5706 /* clip and unnest if necessary */
5707 vm_map_clip_start(map
, entry
, start
);
5710 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
5711 vm_map_clip_end(map
, entry
, end
);
5712 if (entry
->is_sub_map
) {
5713 /* clip did unnest if needed */
5714 assert(!entry
->use_pmap
);
5717 entry
->inheritance
= new_inheritance
;
5719 entry
= entry
->vme_next
;
5723 return(KERN_SUCCESS
);
5727 * Update the accounting for the amount of wired memory in this map. If the user has
5728 * exceeded the defined limits, then we fail. Wiring on behalf of the kernel never fails.
5731 static kern_return_t
5734 vm_map_entry_t entry
,
5735 boolean_t user_wire
)
5740 unsigned int total_wire_count
= vm_page_wire_count
+ vm_lopage_free_count
;
5743 * We're wiring memory at the request of the user. Check if this is the first time the user is wiring
5747 if (entry
->user_wired_count
== 0) {
5748 size
= entry
->vme_end
- entry
->vme_start
;
5751 * Since this is the first time the user is wiring this map entry, check to see if we're
5752 * exceeding the user wire limits. There is a per map limit which is the smaller of either
5753 * the process's rlimit or the global vm_user_wire_limit which caps this value. There is also
5754 * a system-wide limit on the amount of memory all users can wire. If the user is over either
5755 * limit, then we fail.
5758 if(size
+ map
->user_wire_size
> MIN(map
->user_wire_limit
, vm_user_wire_limit
) ||
5759 size
+ ptoa_64(total_wire_count
) > vm_global_user_wire_limit
||
5760 size
+ ptoa_64(total_wire_count
) > max_mem
- vm_global_no_user_wire_amount
)
5761 return KERN_RESOURCE_SHORTAGE
;
5764 * The first time the user wires an entry, we also increment the wired_count and add this to
5765 * the total that has been wired in the map.
5768 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
5769 return KERN_FAILURE
;
5771 entry
->wired_count
++;
5772 map
->user_wire_size
+= size
;
5775 if (entry
->user_wired_count
>= MAX_WIRE_COUNT
)
5776 return KERN_FAILURE
;
5778 entry
->user_wired_count
++;
5783 * The kernel's wiring the memory. Just bump the count and continue.
5786 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
5787 panic("vm_map_wire: too many wirings");
5789 entry
->wired_count
++;
5792 return KERN_SUCCESS
;
5796 * Update the memory wiring accounting now that the given map entry is being unwired.
5800 subtract_wire_counts(
5802 vm_map_entry_t entry
,
5803 boolean_t user_wire
)
5809 * We're unwiring memory at the request of the user. See if we're removing the last user wire reference.
5812 if (entry
->user_wired_count
== 1) {
5815 * We're removing the last user wire reference. Decrement the wired_count and the total
5816 * user wired memory for this map.
5819 assert(entry
->wired_count
>= 1);
5820 entry
->wired_count
--;
5821 map
->user_wire_size
-= entry
->vme_end
- entry
->vme_start
;
5824 assert(entry
->user_wired_count
>= 1);
5825 entry
->user_wired_count
--;
5830 * The kernel is unwiring the memory. Just update the count.
5833 assert(entry
->wired_count
>= 1);
5834 entry
->wired_count
--;
5839 int cs_executable_wire
= 0;
5840 #endif /* CONFIG_EMBEDDED */
5845 * Sets the pageability of the specified address range in the
5846 * target map as wired. Regions specified as not pageable require
5847 * locked-down physical memory and physical page maps. The
5848 * access_type variable indicates types of accesses that must not
5849 * generate page faults. This is checked against protection of
5850 * memory being locked-down.
5852 * The map must not be locked, but a reference must remain to the
5853 * map throughout the call.
5855 static kern_return_t
5858 vm_map_offset_t start
,
5859 vm_map_offset_t end
,
5860 vm_prot_t caller_prot
,
5862 boolean_t user_wire
,
5864 vm_map_offset_t pmap_addr
,
5865 ppnum_t
*physpage_p
)
5867 vm_map_entry_t entry
;
5868 vm_prot_t access_type
;
5869 struct vm_map_entry
*first_entry
, tmp_entry
;
5871 vm_map_offset_t s
,e
;
5873 boolean_t need_wakeup
;
5874 boolean_t main_map
= FALSE
;
5875 wait_interrupt_t interruptible_state
;
5876 thread_t cur_thread
;
5877 unsigned int last_timestamp
;
5879 boolean_t wire_and_extract
;
5881 access_type
= (caller_prot
& VM_PROT_ALL
);
5883 wire_and_extract
= FALSE
;
5884 if (physpage_p
!= NULL
) {
5886 * The caller wants the physical page number of the
5887 * wired page. We return only one physical page number
5888 * so this works for only one page at a time.
5890 if ((end
- start
) != PAGE_SIZE
) {
5891 return KERN_INVALID_ARGUMENT
;
5893 wire_and_extract
= TRUE
;
5898 if(map_pmap
== NULL
)
5900 last_timestamp
= map
->timestamp
;
5902 VM_MAP_RANGE_CHECK(map
, start
, end
);
5903 assert(page_aligned(start
));
5904 assert(page_aligned(end
));
5905 assert(VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)));
5906 assert(VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)));
5908 /* We wired what the caller asked for, zero pages */
5910 return KERN_SUCCESS
;
5913 need_wakeup
= FALSE
;
5914 cur_thread
= current_thread();
5919 if (vm_map_lookup_entry(map
, s
, &first_entry
)) {
5920 entry
= first_entry
;
5922 * vm_map_clip_start will be done later.
5923 * We don't want to unnest any nested submaps here !
5926 /* Start address is not in map */
5927 rc
= KERN_INVALID_ADDRESS
;
5931 while ((entry
!= vm_map_to_entry(map
)) && (s
< end
)) {
5933 * At this point, we have wired from "start" to "s".
5934 * We still need to wire from "s" to "end".
5936 * "entry" hasn't been clipped, so it could start before "s"
5937 * and/or end after "end".
5940 /* "e" is how far we want to wire in this entry */
5946 * If another thread is wiring/unwiring this entry then
5947 * block after informing other thread to wake us up.
5949 if (entry
->in_transition
) {
5950 wait_result_t wait_result
;
5953 * We have not clipped the entry. Make sure that
5954 * the start address is in range so that the lookup
5955 * below will succeed.
5956 * "s" is the current starting point: we've already
5957 * wired from "start" to "s" and we still have
5958 * to wire from "s" to "end".
5961 entry
->needs_wakeup
= TRUE
;
5964 * wake up anybody waiting on entries that we have
5968 vm_map_entry_wakeup(map
);
5969 need_wakeup
= FALSE
;
5972 * User wiring is interruptible
5974 wait_result
= vm_map_entry_wait(map
,
5975 (user_wire
) ? THREAD_ABORTSAFE
:
5977 if (user_wire
&& wait_result
== THREAD_INTERRUPTED
) {
5979 * undo the wirings we have done so far
5980 * We do not clear the needs_wakeup flag,
5981 * because we cannot tell if we were the
5989 * Cannot avoid a lookup here. reset timestamp.
5991 last_timestamp
= map
->timestamp
;
5994 * The entry could have been clipped, look it up again.
5995 * Worse that can happen is, it may not exist anymore.
5997 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
5999 * User: undo everything upto the previous
6000 * entry. let vm_map_unwire worry about
6001 * checking the validity of the range.
6006 entry
= first_entry
;
6010 if (entry
->is_sub_map
) {
6011 vm_map_offset_t sub_start
;
6012 vm_map_offset_t sub_end
;
6013 vm_map_offset_t local_start
;
6014 vm_map_offset_t local_end
;
6017 if (wire_and_extract
) {
6019 * Wiring would result in copy-on-write
6020 * which would not be compatible with
6021 * the sharing we have with the original
6022 * provider of this memory.
6024 rc
= KERN_INVALID_ARGUMENT
;
6028 vm_map_clip_start(map
, entry
, s
);
6029 vm_map_clip_end(map
, entry
, end
);
6031 sub_start
= VME_OFFSET(entry
);
6032 sub_end
= entry
->vme_end
;
6033 sub_end
+= VME_OFFSET(entry
) - entry
->vme_start
;
6035 local_end
= entry
->vme_end
;
6036 if(map_pmap
== NULL
) {
6038 vm_object_offset_t offset
;
6041 vm_map_entry_t local_entry
;
6042 vm_map_version_t version
;
6043 vm_map_t lookup_map
;
6045 if(entry
->use_pmap
) {
6046 pmap
= VME_SUBMAP(entry
)->pmap
;
6047 /* ppc implementation requires that */
6048 /* submaps pmap address ranges line */
6049 /* up with parent map */
6051 pmap_addr
= sub_start
;
6059 if (entry
->wired_count
) {
6060 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
6064 * The map was not unlocked:
6065 * no need to goto re-lookup.
6066 * Just go directly to next entry.
6068 entry
= entry
->vme_next
;
6069 s
= entry
->vme_start
;
6074 /* call vm_map_lookup_locked to */
6075 /* cause any needs copy to be */
6077 local_start
= entry
->vme_start
;
6079 vm_map_lock_write_to_read(map
);
6080 if(vm_map_lookup_locked(
6081 &lookup_map
, local_start
,
6082 access_type
| VM_PROT_COPY
,
6083 OBJECT_LOCK_EXCLUSIVE
,
6085 &offset
, &prot
, &wired
,
6089 vm_map_unlock_read(lookup_map
);
6090 assert(map_pmap
== NULL
);
6091 vm_map_unwire(map
, start
,
6093 return(KERN_FAILURE
);
6095 vm_object_unlock(object
);
6096 if(real_map
!= lookup_map
)
6097 vm_map_unlock(real_map
);
6098 vm_map_unlock_read(lookup_map
);
6101 /* we unlocked, so must re-lookup */
6102 if (!vm_map_lookup_entry(map
,
6110 * entry could have been "simplified",
6113 entry
= local_entry
;
6114 assert(s
== local_start
);
6115 vm_map_clip_start(map
, entry
, s
);
6116 vm_map_clip_end(map
, entry
, end
);
6117 /* re-compute "e" */
6122 /* did we have a change of type? */
6123 if (!entry
->is_sub_map
) {
6124 last_timestamp
= map
->timestamp
;
6128 local_start
= entry
->vme_start
;
6132 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
6135 entry
->in_transition
= TRUE
;
6138 rc
= vm_map_wire_nested(VME_SUBMAP(entry
),
6141 user_wire
, pmap
, pmap_addr
,
6146 * Find the entry again. It could have been clipped
6147 * after we unlocked the map.
6149 if (!vm_map_lookup_entry(map
, local_start
,
6151 panic("vm_map_wire: re-lookup failed");
6152 entry
= first_entry
;
6154 assert(local_start
== s
);
6155 /* re-compute "e" */
6160 last_timestamp
= map
->timestamp
;
6161 while ((entry
!= vm_map_to_entry(map
)) &&
6162 (entry
->vme_start
< e
)) {
6163 assert(entry
->in_transition
);
6164 entry
->in_transition
= FALSE
;
6165 if (entry
->needs_wakeup
) {
6166 entry
->needs_wakeup
= FALSE
;
6169 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
6170 subtract_wire_counts(map
, entry
, user_wire
);
6172 entry
= entry
->vme_next
;
6174 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
6178 /* no need to relookup again */
6179 s
= entry
->vme_start
;
6184 * If this entry is already wired then increment
6185 * the appropriate wire reference count.
6187 if (entry
->wired_count
) {
6189 if ((entry
->protection
& access_type
) != access_type
) {
6190 /* found a protection problem */
6194 * We should always return an error
6195 * in this case but since we didn't
6196 * enforce it before, let's do
6197 * it only for the new "wire_and_extract"
6198 * code path for now...
6200 if (wire_and_extract
) {
6201 rc
= KERN_PROTECTION_FAILURE
;
6207 * entry is already wired down, get our reference
6208 * after clipping to our range.
6210 vm_map_clip_start(map
, entry
, s
);
6211 vm_map_clip_end(map
, entry
, end
);
6213 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
6216 if (wire_and_extract
) {
6218 vm_object_offset_t offset
;
6222 * We don't have to "wire" the page again
6223 * bit we still have to "extract" its
6224 * physical page number, after some sanity
6227 assert((entry
->vme_end
- entry
->vme_start
)
6229 assert(!entry
->needs_copy
);
6230 assert(!entry
->is_sub_map
);
6231 assert(VME_OBJECT(entry
));
6232 if (((entry
->vme_end
- entry
->vme_start
)
6234 entry
->needs_copy
||
6235 entry
->is_sub_map
||
6236 VME_OBJECT(entry
) == VM_OBJECT_NULL
) {
6237 rc
= KERN_INVALID_ARGUMENT
;
6241 object
= VME_OBJECT(entry
);
6242 offset
= VME_OFFSET(entry
);
6243 /* need exclusive lock to update m->dirty */
6244 if (entry
->protection
& VM_PROT_WRITE
) {
6245 vm_object_lock(object
);
6247 vm_object_lock_shared(object
);
6249 m
= vm_page_lookup(object
, offset
);
6250 assert(m
!= VM_PAGE_NULL
);
6251 assert(VM_PAGE_WIRED(m
));
6252 if (m
!= VM_PAGE_NULL
&& VM_PAGE_WIRED(m
)) {
6253 *physpage_p
= VM_PAGE_GET_PHYS_PAGE(m
);
6254 if (entry
->protection
& VM_PROT_WRITE
) {
6255 vm_object_lock_assert_exclusive(
6260 /* not already wired !? */
6263 vm_object_unlock(object
);
6266 /* map was not unlocked: no need to relookup */
6267 entry
= entry
->vme_next
;
6268 s
= entry
->vme_start
;
6273 * Unwired entry or wire request transmitted via submap
6278 * Wiring would copy the pages to the shadow object.
6279 * The shadow object would not be code-signed so
6280 * attempting to execute code from these copied pages
6281 * would trigger a code-signing violation.
6283 if (entry
->protection
& VM_PROT_EXECUTE
) {
6285 printf("pid %d[%s] wiring executable range from "
6286 "0x%llx to 0x%llx: rejected to preserve "
6289 (current_task()->bsd_info
6290 ? proc_name_address(current_task()->bsd_info
)
6292 (uint64_t) entry
->vme_start
,
6293 (uint64_t) entry
->vme_end
);
6294 #endif /* MACH_ASSERT */
6295 DTRACE_VM2(cs_executable_wire
,
6296 uint64_t, (uint64_t)entry
->vme_start
,
6297 uint64_t, (uint64_t)entry
->vme_end
);
6298 cs_executable_wire
++;
6299 rc
= KERN_PROTECTION_FAILURE
;
6302 #endif /* CONFIG_EMBEDDED */
6306 * Perform actions of vm_map_lookup that need the write
6307 * lock on the map: create a shadow object for a
6308 * copy-on-write region, or an object for a zero-fill
6311 size
= entry
->vme_end
- entry
->vme_start
;
6313 * If wiring a copy-on-write page, we need to copy it now
6314 * even if we're only (currently) requesting read access.
6315 * This is aggressive, but once it's wired we can't move it.
6317 if (entry
->needs_copy
) {
6318 if (wire_and_extract
) {
6320 * We're supposed to share with the original
6321 * provider so should not be "needs_copy"
6323 rc
= KERN_INVALID_ARGUMENT
;
6327 VME_OBJECT_SHADOW(entry
, size
);
6328 entry
->needs_copy
= FALSE
;
6329 } else if (VME_OBJECT(entry
) == VM_OBJECT_NULL
) {
6330 if (wire_and_extract
) {
6332 * We're supposed to share with the original
6333 * provider so should already have an object.
6335 rc
= KERN_INVALID_ARGUMENT
;
6338 VME_OBJECT_SET(entry
, vm_object_allocate(size
));
6339 VME_OFFSET_SET(entry
, (vm_object_offset_t
)0);
6340 assert(entry
->use_pmap
);
6343 vm_map_clip_start(map
, entry
, s
);
6344 vm_map_clip_end(map
, entry
, end
);
6346 /* re-compute "e" */
6352 * Check for holes and protection mismatch.
6353 * Holes: Next entry should be contiguous unless this
6354 * is the end of the region.
6355 * Protection: Access requested must be allowed, unless
6356 * wiring is by protection class
6358 if ((entry
->vme_end
< end
) &&
6359 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
6360 (entry
->vme_next
->vme_start
> entry
->vme_end
))) {
6362 rc
= KERN_INVALID_ADDRESS
;
6365 if ((entry
->protection
& access_type
) != access_type
) {
6366 /* found a protection problem */
6367 rc
= KERN_PROTECTION_FAILURE
;
6371 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
6373 if ((rc
= add_wire_counts(map
, entry
, user_wire
)) != KERN_SUCCESS
)
6376 entry
->in_transition
= TRUE
;
6379 * This entry might get split once we unlock the map.
6380 * In vm_fault_wire(), we need the current range as
6381 * defined by this entry. In order for this to work
6382 * along with a simultaneous clip operation, we make a
6383 * temporary copy of this entry and use that for the
6384 * wiring. Note that the underlying objects do not
6385 * change during a clip.
6390 * The in_transition state guarentees that the entry
6391 * (or entries for this range, if split occured) will be
6392 * there when the map lock is acquired for the second time.
6396 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
6397 interruptible_state
= thread_interrupt_level(THREAD_UNINT
);
6399 interruptible_state
= THREAD_UNINT
;
6402 rc
= vm_fault_wire(map
,
6403 &tmp_entry
, caller_prot
, tag
, map_pmap
, pmap_addr
,
6406 rc
= vm_fault_wire(map
,
6407 &tmp_entry
, caller_prot
, tag
, map
->pmap
,
6408 tmp_entry
.vme_start
,
6411 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
6412 thread_interrupt_level(interruptible_state
);
6416 if (last_timestamp
+1 != map
->timestamp
) {
6418 * Find the entry again. It could have been clipped
6419 * after we unlocked the map.
6421 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
6423 panic("vm_map_wire: re-lookup failed");
6425 entry
= first_entry
;
6428 last_timestamp
= map
->timestamp
;
6430 while ((entry
!= vm_map_to_entry(map
)) &&
6431 (entry
->vme_start
< tmp_entry
.vme_end
)) {
6432 assert(entry
->in_transition
);
6433 entry
->in_transition
= FALSE
;
6434 if (entry
->needs_wakeup
) {
6435 entry
->needs_wakeup
= FALSE
;
6438 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
6439 subtract_wire_counts(map
, entry
, user_wire
);
6441 entry
= entry
->vme_next
;
6444 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
6448 if ((entry
!= vm_map_to_entry(map
)) && /* we still have entries in the map */
6449 (tmp_entry
.vme_end
!= end
) && /* AND, we are not at the end of the requested range */
6450 (entry
->vme_start
!= tmp_entry
.vme_end
)) { /* AND, the next entry is not contiguous. */
6451 /* found a "new" hole */
6452 s
= tmp_entry
.vme_end
;
6453 rc
= KERN_INVALID_ADDRESS
;
6457 s
= entry
->vme_start
;
6459 } /* end while loop through map entries */
6462 if (rc
== KERN_SUCCESS
) {
6463 /* repair any damage we may have made to the VM map */
6464 vm_map_simplify_range(map
, start
, end
);
6470 * wake up anybody waiting on entries we wired.
6473 vm_map_entry_wakeup(map
);
6475 if (rc
!= KERN_SUCCESS
) {
6476 /* undo what has been wired so far */
6477 vm_map_unwire_nested(map
, start
, s
, user_wire
,
6478 map_pmap
, pmap_addr
);
6489 vm_map_wire_external(
6491 vm_map_offset_t start
,
6492 vm_map_offset_t end
,
6493 vm_prot_t caller_prot
,
6494 boolean_t user_wire
)
6498 kret
= vm_map_wire_nested(map
, start
, end
, caller_prot
, vm_tag_bt(),
6499 user_wire
, (pmap_t
)NULL
, 0, NULL
);
6506 vm_map_offset_t start
,
6507 vm_map_offset_t end
,
6508 vm_prot_t caller_prot
,
6510 boolean_t user_wire
)
6514 kret
= vm_map_wire_nested(map
, start
, end
, caller_prot
, tag
,
6515 user_wire
, (pmap_t
)NULL
, 0, NULL
);
6520 vm_map_wire_and_extract_external(
6522 vm_map_offset_t start
,
6523 vm_prot_t caller_prot
,
6524 boolean_t user_wire
,
6525 ppnum_t
*physpage_p
)
6529 kret
= vm_map_wire_nested(map
,
6531 start
+VM_MAP_PAGE_SIZE(map
),
6538 if (kret
!= KERN_SUCCESS
&&
6539 physpage_p
!= NULL
) {
6546 vm_map_wire_and_extract_kernel(
6548 vm_map_offset_t start
,
6549 vm_prot_t caller_prot
,
6551 boolean_t user_wire
,
6552 ppnum_t
*physpage_p
)
6556 kret
= vm_map_wire_nested(map
,
6558 start
+VM_MAP_PAGE_SIZE(map
),
6565 if (kret
!= KERN_SUCCESS
&&
6566 physpage_p
!= NULL
) {
6575 * Sets the pageability of the specified address range in the target
6576 * as pageable. Regions specified must have been wired previously.
6578 * The map must not be locked, but a reference must remain to the map
6579 * throughout the call.
6581 * Kernel will panic on failures. User unwire ignores holes and
6582 * unwired and intransition entries to avoid losing memory by leaving
6585 static kern_return_t
6586 vm_map_unwire_nested(
6588 vm_map_offset_t start
,
6589 vm_map_offset_t end
,
6590 boolean_t user_wire
,
6592 vm_map_offset_t pmap_addr
)
6594 vm_map_entry_t entry
;
6595 struct vm_map_entry
*first_entry
, tmp_entry
;
6596 boolean_t need_wakeup
;
6597 boolean_t main_map
= FALSE
;
6598 unsigned int last_timestamp
;
6601 if(map_pmap
== NULL
)
6603 last_timestamp
= map
->timestamp
;
6605 VM_MAP_RANGE_CHECK(map
, start
, end
);
6606 assert(page_aligned(start
));
6607 assert(page_aligned(end
));
6608 assert(VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)));
6609 assert(VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)));
6612 /* We unwired what the caller asked for: zero pages */
6614 return KERN_SUCCESS
;
6617 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
6618 entry
= first_entry
;
6620 * vm_map_clip_start will be done later.
6621 * We don't want to unnest any nested sub maps here !
6626 panic("vm_map_unwire: start not found");
6628 /* Start address is not in map. */
6630 return(KERN_INVALID_ADDRESS
);
6633 if (entry
->superpage_size
) {
6634 /* superpages are always wired */
6636 return KERN_INVALID_ADDRESS
;
6639 need_wakeup
= FALSE
;
6640 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
6641 if (entry
->in_transition
) {
6644 * Another thread is wiring down this entry. Note
6645 * that if it is not for the other thread we would
6646 * be unwiring an unwired entry. This is not
6647 * permitted. If we wait, we will be unwiring memory
6651 * Another thread is unwiring this entry. We did not
6652 * have a reference to it, because if we did, this
6653 * entry will not be getting unwired now.
6658 * This could happen: there could be some
6659 * overlapping vslock/vsunlock operations
6661 * We should probably just wait and retry,
6662 * but then we have to be careful that this
6663 * entry could get "simplified" after
6664 * "in_transition" gets unset and before
6665 * we re-lookup the entry, so we would
6666 * have to re-clip the entry to avoid
6667 * re-unwiring what we have already unwired...
6668 * See vm_map_wire_nested().
6670 * Or we could just ignore "in_transition"
6671 * here and proceed to decement the wired
6672 * count(s) on this entry. That should be fine
6673 * as long as "wired_count" doesn't drop all
6674 * the way to 0 (and we should panic if THAT
6677 panic("vm_map_unwire: in_transition entry");
6680 entry
= entry
->vme_next
;
6684 if (entry
->is_sub_map
) {
6685 vm_map_offset_t sub_start
;
6686 vm_map_offset_t sub_end
;
6687 vm_map_offset_t local_end
;
6690 vm_map_clip_start(map
, entry
, start
);
6691 vm_map_clip_end(map
, entry
, end
);
6693 sub_start
= VME_OFFSET(entry
);
6694 sub_end
= entry
->vme_end
- entry
->vme_start
;
6695 sub_end
+= VME_OFFSET(entry
);
6696 local_end
= entry
->vme_end
;
6697 if(map_pmap
== NULL
) {
6698 if(entry
->use_pmap
) {
6699 pmap
= VME_SUBMAP(entry
)->pmap
;
6700 pmap_addr
= sub_start
;
6705 if (entry
->wired_count
== 0 ||
6706 (user_wire
&& entry
->user_wired_count
== 0)) {
6708 panic("vm_map_unwire: entry is unwired");
6709 entry
= entry
->vme_next
;
6715 * Holes: Next entry should be contiguous unless
6716 * this is the end of the region.
6718 if (((entry
->vme_end
< end
) &&
6719 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
6720 (entry
->vme_next
->vme_start
6721 > entry
->vme_end
)))) {
6723 panic("vm_map_unwire: non-contiguous region");
6725 entry = entry->vme_next;
6730 subtract_wire_counts(map
, entry
, user_wire
);
6732 if (entry
->wired_count
!= 0) {
6733 entry
= entry
->vme_next
;
6737 entry
->in_transition
= TRUE
;
6738 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
6741 * We can unlock the map now. The in_transition state
6742 * guarantees existance of the entry.
6745 vm_map_unwire_nested(VME_SUBMAP(entry
),
6746 sub_start
, sub_end
, user_wire
, pmap
, pmap_addr
);
6749 if (last_timestamp
+1 != map
->timestamp
) {
6751 * Find the entry again. It could have been
6752 * clipped or deleted after we unlocked the map.
6754 if (!vm_map_lookup_entry(map
,
6755 tmp_entry
.vme_start
,
6758 panic("vm_map_unwire: re-lookup failed");
6759 entry
= first_entry
->vme_next
;
6761 entry
= first_entry
;
6763 last_timestamp
= map
->timestamp
;
6766 * clear transition bit for all constituent entries
6767 * that were in the original entry (saved in
6768 * tmp_entry). Also check for waiters.
6770 while ((entry
!= vm_map_to_entry(map
)) &&
6771 (entry
->vme_start
< tmp_entry
.vme_end
)) {
6772 assert(entry
->in_transition
);
6773 entry
->in_transition
= FALSE
;
6774 if (entry
->needs_wakeup
) {
6775 entry
->needs_wakeup
= FALSE
;
6778 entry
= entry
->vme_next
;
6783 vm_map_unwire_nested(VME_SUBMAP(entry
),
6784 sub_start
, sub_end
, user_wire
, map_pmap
,
6788 if (last_timestamp
+1 != map
->timestamp
) {
6790 * Find the entry again. It could have been
6791 * clipped or deleted after we unlocked the map.
6793 if (!vm_map_lookup_entry(map
,
6794 tmp_entry
.vme_start
,
6797 panic("vm_map_unwire: re-lookup failed");
6798 entry
= first_entry
->vme_next
;
6800 entry
= first_entry
;
6802 last_timestamp
= map
->timestamp
;
6807 if ((entry
->wired_count
== 0) ||
6808 (user_wire
&& entry
->user_wired_count
== 0)) {
6810 panic("vm_map_unwire: entry is unwired");
6812 entry
= entry
->vme_next
;
6816 assert(entry
->wired_count
> 0 &&
6817 (!user_wire
|| entry
->user_wired_count
> 0));
6819 vm_map_clip_start(map
, entry
, start
);
6820 vm_map_clip_end(map
, entry
, end
);
6824 * Holes: Next entry should be contiguous unless
6825 * this is the end of the region.
6827 if (((entry
->vme_end
< end
) &&
6828 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
6829 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
6832 panic("vm_map_unwire: non-contiguous region");
6833 entry
= entry
->vme_next
;
6837 subtract_wire_counts(map
, entry
, user_wire
);
6839 if (entry
->wired_count
!= 0) {
6840 entry
= entry
->vme_next
;
6844 if(entry
->zero_wired_pages
) {
6845 entry
->zero_wired_pages
= FALSE
;
6848 entry
->in_transition
= TRUE
;
6849 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
6852 * We can unlock the map now. The in_transition state
6853 * guarantees existance of the entry.
6857 vm_fault_unwire(map
,
6858 &tmp_entry
, FALSE
, map_pmap
, pmap_addr
);
6860 vm_fault_unwire(map
,
6861 &tmp_entry
, FALSE
, map
->pmap
,
6862 tmp_entry
.vme_start
);
6866 if (last_timestamp
+1 != map
->timestamp
) {
6868 * Find the entry again. It could have been clipped
6869 * or deleted after we unlocked the map.
6871 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
6874 panic("vm_map_unwire: re-lookup failed");
6875 entry
= first_entry
->vme_next
;
6877 entry
= first_entry
;
6879 last_timestamp
= map
->timestamp
;
6882 * clear transition bit for all constituent entries that
6883 * were in the original entry (saved in tmp_entry). Also
6884 * check for waiters.
6886 while ((entry
!= vm_map_to_entry(map
)) &&
6887 (entry
->vme_start
< tmp_entry
.vme_end
)) {
6888 assert(entry
->in_transition
);
6889 entry
->in_transition
= FALSE
;
6890 if (entry
->needs_wakeup
) {
6891 entry
->needs_wakeup
= FALSE
;
6894 entry
= entry
->vme_next
;
6899 * We might have fragmented the address space when we wired this
6900 * range of addresses. Attempt to re-coalesce these VM map entries
6901 * with their neighbors now that they're no longer wired.
6902 * Under some circumstances, address space fragmentation can
6903 * prevent VM object shadow chain collapsing, which can cause
6906 vm_map_simplify_range(map
, start
, end
);
6910 * wake up anybody waiting on entries that we have unwired.
6913 vm_map_entry_wakeup(map
);
6914 return(KERN_SUCCESS
);
6921 vm_map_offset_t start
,
6922 vm_map_offset_t end
,
6923 boolean_t user_wire
)
6925 return vm_map_unwire_nested(map
, start
, end
,
6926 user_wire
, (pmap_t
)NULL
, 0);
6931 * vm_map_entry_delete: [ internal use only ]
6933 * Deallocate the given entry from the target map.
6936 vm_map_entry_delete(
6938 vm_map_entry_t entry
)
6940 vm_map_offset_t s
, e
;
6944 s
= entry
->vme_start
;
6946 assert(page_aligned(s
));
6947 assert(page_aligned(e
));
6948 if (entry
->map_aligned
== TRUE
) {
6949 assert(VM_MAP_PAGE_ALIGNED(s
, VM_MAP_PAGE_MASK(map
)));
6950 assert(VM_MAP_PAGE_ALIGNED(e
, VM_MAP_PAGE_MASK(map
)));
6952 assert(entry
->wired_count
== 0);
6953 assert(entry
->user_wired_count
== 0);
6954 assert(!entry
->permanent
);
6956 if (entry
->is_sub_map
) {
6958 submap
= VME_SUBMAP(entry
);
6961 object
= VME_OBJECT(entry
);
6964 vm_map_store_entry_unlink(map
, entry
);
6967 vm_map_entry_dispose(map
, entry
);
6971 * Deallocate the object only after removing all
6972 * pmap entries pointing to its pages.
6975 vm_map_deallocate(submap
);
6977 vm_object_deallocate(object
);
6982 vm_map_submap_pmap_clean(
6984 vm_map_offset_t start
,
6985 vm_map_offset_t end
,
6987 vm_map_offset_t offset
)
6989 vm_map_offset_t submap_start
;
6990 vm_map_offset_t submap_end
;
6991 vm_map_size_t remove_size
;
6992 vm_map_entry_t entry
;
6994 submap_end
= offset
+ (end
- start
);
6995 submap_start
= offset
;
6997 vm_map_lock_read(sub_map
);
6998 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
7000 remove_size
= (entry
->vme_end
- entry
->vme_start
);
7001 if(offset
> entry
->vme_start
)
7002 remove_size
-= offset
- entry
->vme_start
;
7005 if(submap_end
< entry
->vme_end
) {
7007 entry
->vme_end
- submap_end
;
7009 if(entry
->is_sub_map
) {
7010 vm_map_submap_pmap_clean(
7013 start
+ remove_size
,
7018 if((map
->mapped_in_other_pmaps
) && (map
->ref_count
)
7019 && (VME_OBJECT(entry
) != NULL
)) {
7020 vm_object_pmap_protect_options(
7022 (VME_OFFSET(entry
) +
7029 PMAP_OPTIONS_REMOVE
);
7031 pmap_remove(map
->pmap
,
7033 (addr64_t
)(start
+ remove_size
));
7038 entry
= entry
->vme_next
;
7040 while((entry
!= vm_map_to_entry(sub_map
))
7041 && (entry
->vme_start
< submap_end
)) {
7042 remove_size
= (entry
->vme_end
- entry
->vme_start
);
7043 if(submap_end
< entry
->vme_end
) {
7044 remove_size
-= entry
->vme_end
- submap_end
;
7046 if(entry
->is_sub_map
) {
7047 vm_map_submap_pmap_clean(
7049 (start
+ entry
->vme_start
) - offset
,
7050 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
7054 if((map
->mapped_in_other_pmaps
) && (map
->ref_count
)
7055 && (VME_OBJECT(entry
) != NULL
)) {
7056 vm_object_pmap_protect_options(
7063 PMAP_OPTIONS_REMOVE
);
7065 pmap_remove(map
->pmap
,
7066 (addr64_t
)((start
+ entry
->vme_start
)
7068 (addr64_t
)(((start
+ entry
->vme_start
)
7069 - offset
) + remove_size
));
7072 entry
= entry
->vme_next
;
7074 vm_map_unlock_read(sub_map
);
7079 * vm_map_delete: [ internal use only ]
7081 * Deallocates the given address range from the target map.
7082 * Removes all user wirings. Unwires one kernel wiring if
7083 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
7084 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
7085 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
7087 * This routine is called with map locked and leaves map locked.
7089 static kern_return_t
7092 vm_map_offset_t start
,
7093 vm_map_offset_t end
,
7097 vm_map_entry_t entry
, next
;
7098 struct vm_map_entry
*first_entry
, tmp_entry
;
7101 boolean_t need_wakeup
;
7102 unsigned int last_timestamp
= ~0; /* unlikely value */
7105 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
7106 THREAD_ABORTSAFE
: THREAD_UNINT
;
7109 * All our DMA I/O operations in IOKit are currently done by
7110 * wiring through the map entries of the task requesting the I/O.
7111 * Because of this, we must always wait for kernel wirings
7112 * to go away on the entries before deleting them.
7114 * Any caller who wants to actually remove a kernel wiring
7115 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
7116 * properly remove one wiring instead of blasting through
7119 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
7123 * Find the start of the region, and clip it
7125 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
7126 entry
= first_entry
;
7127 if (map
== kalloc_map
&&
7128 (entry
->vme_start
!= start
||
7129 entry
->vme_end
!= end
)) {
7130 panic("vm_map_delete(%p,0x%llx,0x%llx): "
7131 "mismatched entry %p [0x%llx:0x%llx]\n",
7136 (uint64_t)entry
->vme_start
,
7137 (uint64_t)entry
->vme_end
);
7139 if (entry
->superpage_size
&& (start
& ~SUPERPAGE_MASK
)) { /* extend request to whole entry */ start
= SUPERPAGE_ROUND_DOWN(start
);
7140 start
= SUPERPAGE_ROUND_DOWN(start
);
7143 if (start
== entry
->vme_start
) {
7145 * No need to clip. We don't want to cause
7146 * any unnecessary unnesting in this case...
7149 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
7150 entry
->map_aligned
&&
7151 !VM_MAP_PAGE_ALIGNED(
7153 VM_MAP_PAGE_MASK(map
))) {
7155 * The entry will no longer be
7156 * map-aligned after clipping
7157 * and the caller said it's OK.
7159 entry
->map_aligned
= FALSE
;
7161 if (map
== kalloc_map
) {
7162 panic("vm_map_delete(%p,0x%llx,0x%llx):"
7163 " clipping %p at 0x%llx\n",
7170 vm_map_clip_start(map
, entry
, start
);
7174 * Fix the lookup hint now, rather than each
7175 * time through the loop.
7177 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7179 if (map
->pmap
== kernel_pmap
&&
7180 map
->ref_count
!= 0) {
7181 panic("vm_map_delete(%p,0x%llx,0x%llx): "
7182 "no map entry at 0x%llx\n",
7188 entry
= first_entry
->vme_next
;
7192 if (entry
->superpage_size
)
7193 end
= SUPERPAGE_ROUND_UP(end
);
7195 need_wakeup
= FALSE
;
7197 * Step through all entries in this region
7199 s
= entry
->vme_start
;
7200 while ((entry
!= vm_map_to_entry(map
)) && (s
< end
)) {
7202 * At this point, we have deleted all the memory entries
7203 * between "start" and "s". We still need to delete
7204 * all memory entries between "s" and "end".
7205 * While we were blocked and the map was unlocked, some
7206 * new memory entries could have been re-allocated between
7207 * "start" and "s" and we don't want to mess with those.
7208 * Some of those entries could even have been re-assembled
7209 * with an entry after "s" (in vm_map_simplify_entry()), so
7210 * we may have to vm_map_clip_start() again.
7213 if (entry
->vme_start
>= s
) {
7215 * This entry starts on or after "s"
7216 * so no need to clip its start.
7220 * This entry has been re-assembled by a
7221 * vm_map_simplify_entry(). We need to
7222 * re-clip its start.
7224 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
7225 entry
->map_aligned
&&
7226 !VM_MAP_PAGE_ALIGNED(s
,
7227 VM_MAP_PAGE_MASK(map
))) {
7229 * The entry will no longer be map-aligned
7230 * after clipping and the caller said it's OK.
7232 entry
->map_aligned
= FALSE
;
7234 if (map
== kalloc_map
) {
7235 panic("vm_map_delete(%p,0x%llx,0x%llx): "
7236 "clipping %p at 0x%llx\n",
7243 vm_map_clip_start(map
, entry
, s
);
7245 if (entry
->vme_end
<= end
) {
7247 * This entry is going away completely, so no need
7248 * to clip and possibly cause an unnecessary unnesting.
7251 if ((flags
& VM_MAP_REMOVE_NO_MAP_ALIGN
) &&
7252 entry
->map_aligned
&&
7253 !VM_MAP_PAGE_ALIGNED(end
,
7254 VM_MAP_PAGE_MASK(map
))) {
7256 * The entry will no longer be map-aligned
7257 * after clipping and the caller said it's OK.
7259 entry
->map_aligned
= FALSE
;
7261 if (map
== kalloc_map
) {
7262 panic("vm_map_delete(%p,0x%llx,0x%llx): "
7263 "clipping %p at 0x%llx\n",
7270 vm_map_clip_end(map
, entry
, end
);
7273 if (entry
->permanent
) {
7274 if (map
->pmap
== kernel_pmap
) {
7275 panic("%s(%p,0x%llx,0x%llx): "
7276 "attempt to remove permanent "
7278 "%p [0x%llx:0x%llx]\n",
7284 (uint64_t) entry
->vme_start
,
7285 (uint64_t) entry
->vme_end
);
7286 } else if (flags
& VM_MAP_REMOVE_IMMUTABLE
) {
7287 // printf("FBDP %d[%s] removing permanent entry %p [0x%llx:0x%llx] prot 0x%x/0x%x\n", proc_selfpid(), (current_task()->bsd_info ? proc_name_address(current_task()->bsd_info) : "?"), entry, (uint64_t)entry->vme_start, (uint64_t)entry->vme_end, entry->protection, entry->max_protection);
7288 entry
->permanent
= FALSE
;
7290 if (!vm_map_executable_immutable_no_log
) {
7291 printf("%d[%s] %s(0x%llx,0x%llx): "
7292 "permanent entry [0x%llx:0x%llx] "
7295 (current_task()->bsd_info
7296 ? proc_name_address(current_task()->bsd_info
)
7301 (uint64_t)entry
->vme_start
,
7302 (uint64_t)entry
->vme_end
,
7304 entry
->max_protection
);
7307 * dtrace -n 'vm_map_delete_permanent { print("start=0x%llx end=0x%llx prot=0x%x/0x%x\n", arg0, arg1, arg2, arg3); stack(); ustack(); }'
7309 DTRACE_VM5(vm_map_delete_permanent
,
7310 vm_map_offset_t
, entry
->vme_start
,
7311 vm_map_offset_t
, entry
->vme_end
,
7312 vm_prot_t
, entry
->protection
,
7313 vm_prot_t
, entry
->max_protection
,
7314 int, VME_ALIAS(entry
));
7319 if (entry
->in_transition
) {
7320 wait_result_t wait_result
;
7323 * Another thread is wiring/unwiring this entry.
7324 * Let the other thread know we are waiting.
7326 assert(s
== entry
->vme_start
);
7327 entry
->needs_wakeup
= TRUE
;
7330 * wake up anybody waiting on entries that we have
7331 * already unwired/deleted.
7334 vm_map_entry_wakeup(map
);
7335 need_wakeup
= FALSE
;
7338 wait_result
= vm_map_entry_wait(map
, interruptible
);
7340 if (interruptible
&&
7341 wait_result
== THREAD_INTERRUPTED
) {
7343 * We do not clear the needs_wakeup flag,
7344 * since we cannot tell if we were the only one.
7346 return KERN_ABORTED
;
7350 * The entry could have been clipped or it
7351 * may not exist anymore. Look it up again.
7353 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
7355 * User: use the next entry
7357 entry
= first_entry
->vme_next
;
7358 s
= entry
->vme_start
;
7360 entry
= first_entry
;
7361 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7363 last_timestamp
= map
->timestamp
;
7365 } /* end in_transition */
7367 if (entry
->wired_count
) {
7368 boolean_t user_wire
;
7370 user_wire
= entry
->user_wired_count
> 0;
7373 * Remove a kernel wiring if requested
7375 if (flags
& VM_MAP_REMOVE_KUNWIRE
) {
7376 entry
->wired_count
--;
7380 * Remove all user wirings for proper accounting
7382 if (entry
->user_wired_count
> 0) {
7383 while (entry
->user_wired_count
)
7384 subtract_wire_counts(map
, entry
, user_wire
);
7387 if (entry
->wired_count
!= 0) {
7388 assert(map
!= kernel_map
);
7390 * Cannot continue. Typical case is when
7391 * a user thread has physical io pending on
7392 * on this page. Either wait for the
7393 * kernel wiring to go away or return an
7396 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
7397 wait_result_t wait_result
;
7399 assert(s
== entry
->vme_start
);
7400 entry
->needs_wakeup
= TRUE
;
7401 wait_result
= vm_map_entry_wait(map
,
7404 if (interruptible
&&
7405 wait_result
== THREAD_INTERRUPTED
) {
7407 * We do not clear the
7408 * needs_wakeup flag, since we
7409 * cannot tell if we were the
7412 return KERN_ABORTED
;
7416 * The entry could have been clipped or
7417 * it may not exist anymore. Look it
7420 if (!vm_map_lookup_entry(map
, s
,
7422 assert(map
!= kernel_map
);
7424 * User: use the next entry
7426 entry
= first_entry
->vme_next
;
7427 s
= entry
->vme_start
;
7429 entry
= first_entry
;
7430 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7432 last_timestamp
= map
->timestamp
;
7436 return KERN_FAILURE
;
7440 entry
->in_transition
= TRUE
;
7442 * copy current entry. see comment in vm_map_wire()
7445 assert(s
== entry
->vme_start
);
7448 * We can unlock the map now. The in_transition
7449 * state guarentees existance of the entry.
7453 if (tmp_entry
.is_sub_map
) {
7455 vm_map_offset_t sub_start
, sub_end
;
7457 vm_map_offset_t pmap_addr
;
7460 sub_map
= VME_SUBMAP(&tmp_entry
);
7461 sub_start
= VME_OFFSET(&tmp_entry
);
7462 sub_end
= sub_start
+ (tmp_entry
.vme_end
-
7463 tmp_entry
.vme_start
);
7464 if (tmp_entry
.use_pmap
) {
7465 pmap
= sub_map
->pmap
;
7466 pmap_addr
= tmp_entry
.vme_start
;
7469 pmap_addr
= tmp_entry
.vme_start
;
7471 (void) vm_map_unwire_nested(sub_map
,
7477 if (VME_OBJECT(&tmp_entry
) == kernel_object
) {
7478 pmap_protect_options(
7480 tmp_entry
.vme_start
,
7483 PMAP_OPTIONS_REMOVE
,
7486 vm_fault_unwire(map
, &tmp_entry
,
7487 VME_OBJECT(&tmp_entry
) == kernel_object
,
7488 map
->pmap
, tmp_entry
.vme_start
);
7493 if (last_timestamp
+1 != map
->timestamp
) {
7495 * Find the entry again. It could have
7496 * been clipped after we unlocked the map.
7498 if (!vm_map_lookup_entry(map
, s
, &first_entry
)){
7499 assert((map
!= kernel_map
) &&
7500 (!entry
->is_sub_map
));
7501 first_entry
= first_entry
->vme_next
;
7502 s
= first_entry
->vme_start
;
7504 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7507 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7508 first_entry
= entry
;
7511 last_timestamp
= map
->timestamp
;
7513 entry
= first_entry
;
7514 while ((entry
!= vm_map_to_entry(map
)) &&
7515 (entry
->vme_start
< tmp_entry
.vme_end
)) {
7516 assert(entry
->in_transition
);
7517 entry
->in_transition
= FALSE
;
7518 if (entry
->needs_wakeup
) {
7519 entry
->needs_wakeup
= FALSE
;
7522 entry
= entry
->vme_next
;
7525 * We have unwired the entry(s). Go back and
7528 entry
= first_entry
;
7532 /* entry is unwired */
7533 assert(entry
->wired_count
== 0);
7534 assert(entry
->user_wired_count
== 0);
7536 assert(s
== entry
->vme_start
);
7538 if (flags
& VM_MAP_REMOVE_NO_PMAP_CLEANUP
) {
7540 * XXX with the VM_MAP_REMOVE_SAVE_ENTRIES flag to
7541 * vm_map_delete(), some map entries might have been
7542 * transferred to a "zap_map", which doesn't have a
7543 * pmap. The original pmap has already been flushed
7544 * in the vm_map_delete() call targeting the original
7545 * map, but when we get to destroying the "zap_map",
7546 * we don't have any pmap to flush, so let's just skip
7549 } else if (entry
->is_sub_map
) {
7550 if (entry
->use_pmap
) {
7551 #ifndef NO_NESTED_PMAP
7554 if (flags
& VM_MAP_REMOVE_NO_UNNESTING
) {
7556 * This is the final cleanup of the
7557 * address space being terminated.
7558 * No new mappings are expected and
7559 * we don't really need to unnest the
7560 * shared region (and lose the "global"
7561 * pmap mappings, if applicable).
7563 * Tell the pmap layer that we're
7564 * "clean" wrt nesting.
7566 pmap_flags
= PMAP_UNNEST_CLEAN
;
7569 * We're unmapping part of the nested
7570 * shared region, so we can't keep the
7575 pmap_unnest_options(
7577 (addr64_t
)entry
->vme_start
,
7578 entry
->vme_end
- entry
->vme_start
,
7580 #endif /* NO_NESTED_PMAP */
7581 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
7582 /* clean up parent map/maps */
7583 vm_map_submap_pmap_clean(
7584 map
, entry
->vme_start
,
7590 vm_map_submap_pmap_clean(
7591 map
, entry
->vme_start
, entry
->vme_end
,
7595 } else if (VME_OBJECT(entry
) != kernel_object
&&
7596 VME_OBJECT(entry
) != compressor_object
) {
7597 object
= VME_OBJECT(entry
);
7598 if ((map
->mapped_in_other_pmaps
) && (map
->ref_count
)) {
7599 vm_object_pmap_protect_options(
7600 object
, VME_OFFSET(entry
),
7601 entry
->vme_end
- entry
->vme_start
,
7605 PMAP_OPTIONS_REMOVE
);
7606 } else if ((VME_OBJECT(entry
) != VM_OBJECT_NULL
) ||
7607 (map
->pmap
== kernel_pmap
)) {
7608 /* Remove translations associated
7609 * with this range unless the entry
7610 * does not have an object, or
7611 * it's the kernel map or a descendant
7612 * since the platform could potentially
7613 * create "backdoor" mappings invisible
7614 * to the VM. It is expected that
7615 * objectless, non-kernel ranges
7616 * do not have such VM invisible
7619 pmap_remove_options(map
->pmap
,
7620 (addr64_t
)entry
->vme_start
,
7621 (addr64_t
)entry
->vme_end
,
7622 PMAP_OPTIONS_REMOVE
);
7626 if (entry
->iokit_acct
) {
7627 /* alternate accounting */
7628 DTRACE_VM4(vm_map_iokit_unmapped_region
,
7630 vm_map_offset_t
, entry
->vme_start
,
7631 vm_map_offset_t
, entry
->vme_end
,
7632 int, VME_ALIAS(entry
));
7633 vm_map_iokit_unmapped_region(map
,
7636 entry
->iokit_acct
= FALSE
;
7640 * All pmap mappings for this map entry must have been
7644 assert(vm_map_pmap_is_empty(map
,
7649 next
= entry
->vme_next
;
7651 if (map
->pmap
== kernel_pmap
&&
7652 map
->ref_count
!= 0 &&
7653 entry
->vme_end
< end
&&
7654 (next
== vm_map_to_entry(map
) ||
7655 next
->vme_start
!= entry
->vme_end
)) {
7656 panic("vm_map_delete(%p,0x%llx,0x%llx): "
7657 "hole after %p at 0x%llx\n",
7662 (uint64_t)entry
->vme_end
);
7665 s
= next
->vme_start
;
7666 last_timestamp
= map
->timestamp
;
7668 if (entry
->permanent
) {
7670 * A permanent entry can not be removed, so leave it
7671 * in place but remove all access permissions.
7673 entry
->protection
= VM_PROT_NONE
;
7674 entry
->max_protection
= VM_PROT_NONE
;
7675 } else if ((flags
& VM_MAP_REMOVE_SAVE_ENTRIES
) &&
7676 zap_map
!= VM_MAP_NULL
) {
7677 vm_map_size_t entry_size
;
7679 * The caller wants to save the affected VM map entries
7680 * into the "zap_map". The caller will take care of
7683 /* unlink the entry from "map" ... */
7684 vm_map_store_entry_unlink(map
, entry
);
7685 /* ... and add it to the end of the "zap_map" */
7686 vm_map_store_entry_link(zap_map
,
7687 vm_map_last_entry(zap_map
),
7689 entry_size
= entry
->vme_end
- entry
->vme_start
;
7690 map
->size
-= entry_size
;
7691 zap_map
->size
+= entry_size
;
7692 /* we didn't unlock the map, so no timestamp increase */
7695 vm_map_entry_delete(map
, entry
);
7696 /* vm_map_entry_delete unlocks the map */
7702 if(entry
== vm_map_to_entry(map
)) {
7705 if (last_timestamp
+1 != map
->timestamp
) {
7707 * we are responsible for deleting everything
7708 * from the give space, if someone has interfered
7709 * we pick up where we left off, back fills should
7710 * be all right for anyone except map_delete and
7711 * we have to assume that the task has been fully
7712 * disabled before we get here
7714 if (!vm_map_lookup_entry(map
, s
, &entry
)){
7715 entry
= entry
->vme_next
;
7716 s
= entry
->vme_start
;
7718 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
7721 * others can not only allocate behind us, we can
7722 * also see coalesce while we don't have the map lock
7724 if(entry
== vm_map_to_entry(map
)) {
7728 last_timestamp
= map
->timestamp
;
7731 if (map
->wait_for_space
)
7732 thread_wakeup((event_t
) map
);
7734 * wake up anybody waiting on entries that we have already deleted.
7737 vm_map_entry_wakeup(map
);
7739 return KERN_SUCCESS
;
7745 * Remove the given address range from the target map.
7746 * This is the exported form of vm_map_delete.
7751 vm_map_offset_t start
,
7752 vm_map_offset_t end
,
7755 kern_return_t result
;
7758 VM_MAP_RANGE_CHECK(map
, start
, end
);
7760 * For the zone_map, the kernel controls the allocation/freeing of memory.
7761 * Any free to the zone_map should be within the bounds of the map and
7762 * should free up memory. If the VM_MAP_RANGE_CHECK() silently converts a
7763 * free to the zone_map into a no-op, there is a problem and we should
7766 if ((map
== zone_map
) && (start
== end
))
7767 panic("Nothing being freed to the zone_map. start = end = %p\n", (void *)start
);
7768 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
7775 * vm_map_remove_locked:
7777 * Remove the given address range from the target locked map.
7778 * This is the exported form of vm_map_delete.
7781 vm_map_remove_locked(
7783 vm_map_offset_t start
,
7784 vm_map_offset_t end
,
7787 kern_return_t result
;
7789 VM_MAP_RANGE_CHECK(map
, start
, end
);
7790 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
7796 * Routine: vm_map_copy_discard
7799 * Dispose of a map copy object (returned by
7803 vm_map_copy_discard(
7806 if (copy
== VM_MAP_COPY_NULL
)
7809 switch (copy
->type
) {
7810 case VM_MAP_COPY_ENTRY_LIST
:
7811 while (vm_map_copy_first_entry(copy
) !=
7812 vm_map_copy_to_entry(copy
)) {
7813 vm_map_entry_t entry
= vm_map_copy_first_entry(copy
);
7815 vm_map_copy_entry_unlink(copy
, entry
);
7816 if (entry
->is_sub_map
) {
7817 vm_map_deallocate(VME_SUBMAP(entry
));
7819 vm_object_deallocate(VME_OBJECT(entry
));
7821 vm_map_copy_entry_dispose(copy
, entry
);
7824 case VM_MAP_COPY_OBJECT
:
7825 vm_object_deallocate(copy
->cpy_object
);
7827 case VM_MAP_COPY_KERNEL_BUFFER
:
7830 * The vm_map_copy_t and possibly the data buffer were
7831 * allocated by a single call to kalloc(), i.e. the
7832 * vm_map_copy_t was not allocated out of the zone.
7834 if (copy
->size
> msg_ool_size_small
|| copy
->offset
)
7835 panic("Invalid vm_map_copy_t sz:%lld, ofst:%lld",
7836 (long long)copy
->size
, (long long)copy
->offset
);
7837 kfree(copy
, copy
->size
+ cpy_kdata_hdr_sz
);
7840 zfree(vm_map_copy_zone
, copy
);
7844 * Routine: vm_map_copy_copy
7847 * Move the information in a map copy object to
7848 * a new map copy object, leaving the old one
7851 * This is used by kernel routines that need
7852 * to look at out-of-line data (in copyin form)
7853 * before deciding whether to return SUCCESS.
7854 * If the routine returns FAILURE, the original
7855 * copy object will be deallocated; therefore,
7856 * these routines must make a copy of the copy
7857 * object and leave the original empty so that
7858 * deallocation will not fail.
7864 vm_map_copy_t new_copy
;
7866 if (copy
== VM_MAP_COPY_NULL
)
7867 return VM_MAP_COPY_NULL
;
7870 * Allocate a new copy object, and copy the information
7871 * from the old one into it.
7874 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
7875 new_copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
7878 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
7880 * The links in the entry chain must be
7881 * changed to point to the new copy object.
7883 vm_map_copy_first_entry(copy
)->vme_prev
7884 = vm_map_copy_to_entry(new_copy
);
7885 vm_map_copy_last_entry(copy
)->vme_next
7886 = vm_map_copy_to_entry(new_copy
);
7890 * Change the old copy object into one that contains
7891 * nothing to be deallocated.
7893 copy
->type
= VM_MAP_COPY_OBJECT
;
7894 copy
->cpy_object
= VM_OBJECT_NULL
;
7897 * Return the new object.
7902 static kern_return_t
7903 vm_map_overwrite_submap_recurse(
7905 vm_map_offset_t dst_addr
,
7906 vm_map_size_t dst_size
)
7908 vm_map_offset_t dst_end
;
7909 vm_map_entry_t tmp_entry
;
7910 vm_map_entry_t entry
;
7911 kern_return_t result
;
7912 boolean_t encountered_sub_map
= FALSE
;
7917 * Verify that the destination is all writeable
7918 * initially. We have to trunc the destination
7919 * address and round the copy size or we'll end up
7920 * splitting entries in strange ways.
7923 dst_end
= vm_map_round_page(dst_addr
+ dst_size
,
7924 VM_MAP_PAGE_MASK(dst_map
));
7925 vm_map_lock(dst_map
);
7928 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
7929 vm_map_unlock(dst_map
);
7930 return(KERN_INVALID_ADDRESS
);
7933 vm_map_clip_start(dst_map
,
7935 vm_map_trunc_page(dst_addr
,
7936 VM_MAP_PAGE_MASK(dst_map
)));
7937 if (tmp_entry
->is_sub_map
) {
7938 /* clipping did unnest if needed */
7939 assert(!tmp_entry
->use_pmap
);
7942 for (entry
= tmp_entry
;;) {
7943 vm_map_entry_t next
;
7945 next
= entry
->vme_next
;
7946 while(entry
->is_sub_map
) {
7947 vm_map_offset_t sub_start
;
7948 vm_map_offset_t sub_end
;
7949 vm_map_offset_t local_end
;
7951 if (entry
->in_transition
) {
7953 * Say that we are waiting, and wait for entry.
7955 entry
->needs_wakeup
= TRUE
;
7956 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
7961 encountered_sub_map
= TRUE
;
7962 sub_start
= VME_OFFSET(entry
);
7964 if(entry
->vme_end
< dst_end
)
7965 sub_end
= entry
->vme_end
;
7968 sub_end
-= entry
->vme_start
;
7969 sub_end
+= VME_OFFSET(entry
);
7970 local_end
= entry
->vme_end
;
7971 vm_map_unlock(dst_map
);
7973 result
= vm_map_overwrite_submap_recurse(
7976 sub_end
- sub_start
);
7978 if(result
!= KERN_SUCCESS
)
7980 if (dst_end
<= entry
->vme_end
)
7981 return KERN_SUCCESS
;
7982 vm_map_lock(dst_map
);
7983 if(!vm_map_lookup_entry(dst_map
, local_end
,
7985 vm_map_unlock(dst_map
);
7986 return(KERN_INVALID_ADDRESS
);
7989 next
= entry
->vme_next
;
7992 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
7993 vm_map_unlock(dst_map
);
7994 return(KERN_PROTECTION_FAILURE
);
7998 * If the entry is in transition, we must wait
7999 * for it to exit that state. Anything could happen
8000 * when we unlock the map, so start over.
8002 if (entry
->in_transition
) {
8005 * Say that we are waiting, and wait for entry.
8007 entry
->needs_wakeup
= TRUE
;
8008 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
8014 * our range is contained completely within this map entry
8016 if (dst_end
<= entry
->vme_end
) {
8017 vm_map_unlock(dst_map
);
8018 return KERN_SUCCESS
;
8021 * check that range specified is contiguous region
8023 if ((next
== vm_map_to_entry(dst_map
)) ||
8024 (next
->vme_start
!= entry
->vme_end
)) {
8025 vm_map_unlock(dst_map
);
8026 return(KERN_INVALID_ADDRESS
);
8030 * Check for permanent objects in the destination.
8032 if ((VME_OBJECT(entry
) != VM_OBJECT_NULL
) &&
8033 ((!VME_OBJECT(entry
)->internal
) ||
8034 (VME_OBJECT(entry
)->true_share
))) {
8035 if(encountered_sub_map
) {
8036 vm_map_unlock(dst_map
);
8037 return(KERN_FAILURE
);
8044 vm_map_unlock(dst_map
);
8045 return(KERN_SUCCESS
);
8049 * Routine: vm_map_copy_overwrite
8052 * Copy the memory described by the map copy
8053 * object (copy; returned by vm_map_copyin) onto
8054 * the specified destination region (dst_map, dst_addr).
8055 * The destination must be writeable.
8057 * Unlike vm_map_copyout, this routine actually
8058 * writes over previously-mapped memory. If the
8059 * previous mapping was to a permanent (user-supplied)
8060 * memory object, it is preserved.
8062 * The attributes (protection and inheritance) of the
8063 * destination region are preserved.
8065 * If successful, consumes the copy object.
8066 * Otherwise, the caller is responsible for it.
8068 * Implementation notes:
8069 * To overwrite aligned temporary virtual memory, it is
8070 * sufficient to remove the previous mapping and insert
8071 * the new copy. This replacement is done either on
8072 * the whole region (if no permanent virtual memory
8073 * objects are embedded in the destination region) or
8074 * in individual map entries.
8076 * To overwrite permanent virtual memory , it is necessary
8077 * to copy each page, as the external memory management
8078 * interface currently does not provide any optimizations.
8080 * Unaligned memory also has to be copied. It is possible
8081 * to use 'vm_trickery' to copy the aligned data. This is
8082 * not done but not hard to implement.
8084 * Once a page of permanent memory has been overwritten,
8085 * it is impossible to interrupt this function; otherwise,
8086 * the call would be neither atomic nor location-independent.
8087 * The kernel-state portion of a user thread must be
8090 * It may be expensive to forward all requests that might
8091 * overwrite permanent memory (vm_write, vm_copy) to
8092 * uninterruptible kernel threads. This routine may be
8093 * called by interruptible threads; however, success is
8094 * not guaranteed -- if the request cannot be performed
8095 * atomically and interruptibly, an error indication is
8099 static kern_return_t
8100 vm_map_copy_overwrite_nested(
8102 vm_map_address_t dst_addr
,
8104 boolean_t interruptible
,
8106 boolean_t discard_on_success
)
8108 vm_map_offset_t dst_end
;
8109 vm_map_entry_t tmp_entry
;
8110 vm_map_entry_t entry
;
8112 boolean_t aligned
= TRUE
;
8113 boolean_t contains_permanent_objects
= FALSE
;
8114 boolean_t encountered_sub_map
= FALSE
;
8115 vm_map_offset_t base_addr
;
8116 vm_map_size_t copy_size
;
8117 vm_map_size_t total_size
;
8121 * Check for null copy object.
8124 if (copy
== VM_MAP_COPY_NULL
)
8125 return(KERN_SUCCESS
);
8128 * Check for special kernel buffer allocated
8129 * by new_ipc_kmsg_copyin.
8132 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
8133 return(vm_map_copyout_kernel_buffer(
8135 copy
, copy
->size
, TRUE
, discard_on_success
));
8139 * Only works for entry lists at the moment. Will
8140 * support page lists later.
8143 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
8145 if (copy
->size
== 0) {
8146 if (discard_on_success
)
8147 vm_map_copy_discard(copy
);
8148 return(KERN_SUCCESS
);
8152 * Verify that the destination is all writeable
8153 * initially. We have to trunc the destination
8154 * address and round the copy size or we'll end up
8155 * splitting entries in strange ways.
8158 if (!VM_MAP_PAGE_ALIGNED(copy
->size
,
8159 VM_MAP_PAGE_MASK(dst_map
)) ||
8160 !VM_MAP_PAGE_ALIGNED(copy
->offset
,
8161 VM_MAP_PAGE_MASK(dst_map
)) ||
8162 !VM_MAP_PAGE_ALIGNED(dst_addr
,
8163 VM_MAP_PAGE_MASK(dst_map
)))
8166 dst_end
= vm_map_round_page(dst_addr
+ copy
->size
,
8167 VM_MAP_PAGE_MASK(dst_map
));
8169 dst_end
= dst_addr
+ copy
->size
;
8172 vm_map_lock(dst_map
);
8174 /* LP64todo - remove this check when vm_map_commpage64()
8175 * no longer has to stuff in a map_entry for the commpage
8176 * above the map's max_offset.
8178 if (dst_addr
>= dst_map
->max_offset
) {
8179 vm_map_unlock(dst_map
);
8180 return(KERN_INVALID_ADDRESS
);
8184 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
8185 vm_map_unlock(dst_map
);
8186 return(KERN_INVALID_ADDRESS
);
8188 vm_map_clip_start(dst_map
,
8190 vm_map_trunc_page(dst_addr
,
8191 VM_MAP_PAGE_MASK(dst_map
)));
8192 for (entry
= tmp_entry
;;) {
8193 vm_map_entry_t next
= entry
->vme_next
;
8195 while(entry
->is_sub_map
) {
8196 vm_map_offset_t sub_start
;
8197 vm_map_offset_t sub_end
;
8198 vm_map_offset_t local_end
;
8200 if (entry
->in_transition
) {
8203 * Say that we are waiting, and wait for entry.
8205 entry
->needs_wakeup
= TRUE
;
8206 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
8211 local_end
= entry
->vme_end
;
8212 if (!(entry
->needs_copy
)) {
8213 /* if needs_copy we are a COW submap */
8214 /* in such a case we just replace so */
8215 /* there is no need for the follow- */
8217 encountered_sub_map
= TRUE
;
8218 sub_start
= VME_OFFSET(entry
);
8220 if(entry
->vme_end
< dst_end
)
8221 sub_end
= entry
->vme_end
;
8224 sub_end
-= entry
->vme_start
;
8225 sub_end
+= VME_OFFSET(entry
);
8226 vm_map_unlock(dst_map
);
8228 kr
= vm_map_overwrite_submap_recurse(
8231 sub_end
- sub_start
);
8232 if(kr
!= KERN_SUCCESS
)
8234 vm_map_lock(dst_map
);
8237 if (dst_end
<= entry
->vme_end
)
8238 goto start_overwrite
;
8239 if(!vm_map_lookup_entry(dst_map
, local_end
,
8241 vm_map_unlock(dst_map
);
8242 return(KERN_INVALID_ADDRESS
);
8244 next
= entry
->vme_next
;
8247 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
8248 vm_map_unlock(dst_map
);
8249 return(KERN_PROTECTION_FAILURE
);
8253 * If the entry is in transition, we must wait
8254 * for it to exit that state. Anything could happen
8255 * when we unlock the map, so start over.
8257 if (entry
->in_transition
) {
8260 * Say that we are waiting, and wait for entry.
8262 entry
->needs_wakeup
= TRUE
;
8263 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
8269 * our range is contained completely within this map entry
8271 if (dst_end
<= entry
->vme_end
)
8274 * check that range specified is contiguous region
8276 if ((next
== vm_map_to_entry(dst_map
)) ||
8277 (next
->vme_start
!= entry
->vme_end
)) {
8278 vm_map_unlock(dst_map
);
8279 return(KERN_INVALID_ADDRESS
);
8284 * Check for permanent objects in the destination.
8286 if ((VME_OBJECT(entry
) != VM_OBJECT_NULL
) &&
8287 ((!VME_OBJECT(entry
)->internal
) ||
8288 (VME_OBJECT(entry
)->true_share
))) {
8289 contains_permanent_objects
= TRUE
;
8297 * If there are permanent objects in the destination, then
8298 * the copy cannot be interrupted.
8301 if (interruptible
&& contains_permanent_objects
) {
8302 vm_map_unlock(dst_map
);
8303 return(KERN_FAILURE
); /* XXX */
8308 * Make a second pass, overwriting the data
8309 * At the beginning of each loop iteration,
8310 * the next entry to be overwritten is "tmp_entry"
8311 * (initially, the value returned from the lookup above),
8312 * and the starting address expected in that entry
8316 total_size
= copy
->size
;
8317 if(encountered_sub_map
) {
8319 /* re-calculate tmp_entry since we've had the map */
8321 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
8322 vm_map_unlock(dst_map
);
8323 return(KERN_INVALID_ADDRESS
);
8326 copy_size
= copy
->size
;
8329 base_addr
= dst_addr
;
8331 /* deconstruct the copy object and do in parts */
8332 /* only in sub_map, interruptable case */
8333 vm_map_entry_t copy_entry
;
8334 vm_map_entry_t previous_prev
= VM_MAP_ENTRY_NULL
;
8335 vm_map_entry_t next_copy
= VM_MAP_ENTRY_NULL
;
8337 int remaining_entries
= 0;
8338 vm_map_offset_t new_offset
= 0;
8340 for (entry
= tmp_entry
; copy_size
== 0;) {
8341 vm_map_entry_t next
;
8343 next
= entry
->vme_next
;
8345 /* tmp_entry and base address are moved along */
8346 /* each time we encounter a sub-map. Otherwise */
8347 /* entry can outpase tmp_entry, and the copy_size */
8348 /* may reflect the distance between them */
8349 /* if the current entry is found to be in transition */
8350 /* we will start over at the beginning or the last */
8351 /* encounter of a submap as dictated by base_addr */
8352 /* we will zero copy_size accordingly. */
8353 if (entry
->in_transition
) {
8355 * Say that we are waiting, and wait for entry.
8357 entry
->needs_wakeup
= TRUE
;
8358 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
8360 if(!vm_map_lookup_entry(dst_map
, base_addr
,
8362 vm_map_unlock(dst_map
);
8363 return(KERN_INVALID_ADDRESS
);
8369 if (entry
->is_sub_map
) {
8370 vm_map_offset_t sub_start
;
8371 vm_map_offset_t sub_end
;
8372 vm_map_offset_t local_end
;
8374 if (entry
->needs_copy
) {
8375 /* if this is a COW submap */
8376 /* just back the range with a */
8377 /* anonymous entry */
8378 if(entry
->vme_end
< dst_end
)
8379 sub_end
= entry
->vme_end
;
8382 if(entry
->vme_start
< base_addr
)
8383 sub_start
= base_addr
;
8385 sub_start
= entry
->vme_start
;
8387 dst_map
, entry
, sub_end
);
8389 dst_map
, entry
, sub_start
);
8390 assert(!entry
->use_pmap
);
8391 entry
->is_sub_map
= FALSE
;
8394 VME_OBJECT_SET(entry
, NULL
);
8395 VME_OFFSET_SET(entry
, 0);
8396 entry
->is_shared
= FALSE
;
8397 entry
->needs_copy
= FALSE
;
8398 entry
->protection
= VM_PROT_DEFAULT
;
8399 entry
->max_protection
= VM_PROT_ALL
;
8400 entry
->wired_count
= 0;
8401 entry
->user_wired_count
= 0;
8402 if(entry
->inheritance
8403 == VM_INHERIT_SHARE
)
8404 entry
->inheritance
= VM_INHERIT_COPY
;
8407 /* first take care of any non-sub_map */
8408 /* entries to send */
8409 if(base_addr
< entry
->vme_start
) {
8412 entry
->vme_start
- base_addr
;
8415 sub_start
= VME_OFFSET(entry
);
8417 if(entry
->vme_end
< dst_end
)
8418 sub_end
= entry
->vme_end
;
8421 sub_end
-= entry
->vme_start
;
8422 sub_end
+= VME_OFFSET(entry
);
8423 local_end
= entry
->vme_end
;
8424 vm_map_unlock(dst_map
);
8425 copy_size
= sub_end
- sub_start
;
8427 /* adjust the copy object */
8428 if (total_size
> copy_size
) {
8429 vm_map_size_t local_size
= 0;
8430 vm_map_size_t entry_size
;
8433 new_offset
= copy
->offset
;
8434 copy_entry
= vm_map_copy_first_entry(copy
);
8436 vm_map_copy_to_entry(copy
)){
8437 entry_size
= copy_entry
->vme_end
-
8438 copy_entry
->vme_start
;
8439 if((local_size
< copy_size
) &&
8440 ((local_size
+ entry_size
)
8442 vm_map_copy_clip_end(copy
,
8444 copy_entry
->vme_start
+
8445 (copy_size
- local_size
));
8446 entry_size
= copy_entry
->vme_end
-
8447 copy_entry
->vme_start
;
8448 local_size
+= entry_size
;
8449 new_offset
+= entry_size
;
8451 if(local_size
>= copy_size
) {
8452 next_copy
= copy_entry
->vme_next
;
8453 copy_entry
->vme_next
=
8454 vm_map_copy_to_entry(copy
);
8456 copy
->cpy_hdr
.links
.prev
;
8457 copy
->cpy_hdr
.links
.prev
= copy_entry
;
8458 copy
->size
= copy_size
;
8460 copy
->cpy_hdr
.nentries
;
8461 remaining_entries
-= nentries
;
8462 copy
->cpy_hdr
.nentries
= nentries
;
8465 local_size
+= entry_size
;
8466 new_offset
+= entry_size
;
8469 copy_entry
= copy_entry
->vme_next
;
8473 if((entry
->use_pmap
) && (pmap
== NULL
)) {
8474 kr
= vm_map_copy_overwrite_nested(
8479 VME_SUBMAP(entry
)->pmap
,
8481 } else if (pmap
!= NULL
) {
8482 kr
= vm_map_copy_overwrite_nested(
8486 interruptible
, pmap
,
8489 kr
= vm_map_copy_overwrite_nested(
8497 if(kr
!= KERN_SUCCESS
) {
8498 if(next_copy
!= NULL
) {
8499 copy
->cpy_hdr
.nentries
+=
8501 copy
->cpy_hdr
.links
.prev
->vme_next
=
8503 copy
->cpy_hdr
.links
.prev
8505 copy
->size
= total_size
;
8509 if (dst_end
<= local_end
) {
8510 return(KERN_SUCCESS
);
8512 /* otherwise copy no longer exists, it was */
8513 /* destroyed after successful copy_overwrite */
8514 copy
= (vm_map_copy_t
)
8515 zalloc(vm_map_copy_zone
);
8516 copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
8517 vm_map_copy_first_entry(copy
) =
8518 vm_map_copy_last_entry(copy
) =
8519 vm_map_copy_to_entry(copy
);
8520 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
8521 copy
->offset
= new_offset
;
8525 * this does not seem to deal with
8526 * the VM map store (R&B tree)
8529 total_size
-= copy_size
;
8531 /* put back remainder of copy in container */
8532 if(next_copy
!= NULL
) {
8533 copy
->cpy_hdr
.nentries
= remaining_entries
;
8534 copy
->cpy_hdr
.links
.next
= next_copy
;
8535 copy
->cpy_hdr
.links
.prev
= previous_prev
;
8536 copy
->size
= total_size
;
8537 next_copy
->vme_prev
=
8538 vm_map_copy_to_entry(copy
);
8541 base_addr
= local_end
;
8542 vm_map_lock(dst_map
);
8543 if(!vm_map_lookup_entry(dst_map
,
8544 local_end
, &tmp_entry
)) {
8545 vm_map_unlock(dst_map
);
8546 return(KERN_INVALID_ADDRESS
);
8551 if (dst_end
<= entry
->vme_end
) {
8552 copy_size
= dst_end
- base_addr
;
8556 if ((next
== vm_map_to_entry(dst_map
)) ||
8557 (next
->vme_start
!= entry
->vme_end
)) {
8558 vm_map_unlock(dst_map
);
8559 return(KERN_INVALID_ADDRESS
);
8568 /* adjust the copy object */
8569 if (total_size
> copy_size
) {
8570 vm_map_size_t local_size
= 0;
8571 vm_map_size_t entry_size
;
8573 new_offset
= copy
->offset
;
8574 copy_entry
= vm_map_copy_first_entry(copy
);
8575 while(copy_entry
!= vm_map_copy_to_entry(copy
)) {
8576 entry_size
= copy_entry
->vme_end
-
8577 copy_entry
->vme_start
;
8578 if((local_size
< copy_size
) &&
8579 ((local_size
+ entry_size
)
8581 vm_map_copy_clip_end(copy
, copy_entry
,
8582 copy_entry
->vme_start
+
8583 (copy_size
- local_size
));
8584 entry_size
= copy_entry
->vme_end
-
8585 copy_entry
->vme_start
;
8586 local_size
+= entry_size
;
8587 new_offset
+= entry_size
;
8589 if(local_size
>= copy_size
) {
8590 next_copy
= copy_entry
->vme_next
;
8591 copy_entry
->vme_next
=
8592 vm_map_copy_to_entry(copy
);
8594 copy
->cpy_hdr
.links
.prev
;
8595 copy
->cpy_hdr
.links
.prev
= copy_entry
;
8596 copy
->size
= copy_size
;
8598 copy
->cpy_hdr
.nentries
;
8599 remaining_entries
-= nentries
;
8600 copy
->cpy_hdr
.nentries
= nentries
;
8603 local_size
+= entry_size
;
8604 new_offset
+= entry_size
;
8607 copy_entry
= copy_entry
->vme_next
;
8617 local_pmap
= dst_map
->pmap
;
8619 if ((kr
= vm_map_copy_overwrite_aligned(
8620 dst_map
, tmp_entry
, copy
,
8621 base_addr
, local_pmap
)) != KERN_SUCCESS
) {
8622 if(next_copy
!= NULL
) {
8623 copy
->cpy_hdr
.nentries
+=
8625 copy
->cpy_hdr
.links
.prev
->vme_next
=
8627 copy
->cpy_hdr
.links
.prev
=
8629 copy
->size
+= copy_size
;
8633 vm_map_unlock(dst_map
);
8638 * if the copy and dst address are misaligned but the same
8639 * offset within the page we can copy_not_aligned the
8640 * misaligned parts and copy aligned the rest. If they are
8641 * aligned but len is unaligned we simply need to copy
8642 * the end bit unaligned. We'll need to split the misaligned
8643 * bits of the region in this case !
8645 /* ALWAYS UNLOCKS THE dst_map MAP */
8646 kr
= vm_map_copy_overwrite_unaligned(
8651 discard_on_success
);
8652 if (kr
!= KERN_SUCCESS
) {
8653 if(next_copy
!= NULL
) {
8654 copy
->cpy_hdr
.nentries
+=
8656 copy
->cpy_hdr
.links
.prev
->vme_next
=
8658 copy
->cpy_hdr
.links
.prev
=
8660 copy
->size
+= copy_size
;
8665 total_size
-= copy_size
;
8668 base_addr
+= copy_size
;
8670 copy
->offset
= new_offset
;
8671 if(next_copy
!= NULL
) {
8672 copy
->cpy_hdr
.nentries
= remaining_entries
;
8673 copy
->cpy_hdr
.links
.next
= next_copy
;
8674 copy
->cpy_hdr
.links
.prev
= previous_prev
;
8675 next_copy
->vme_prev
= vm_map_copy_to_entry(copy
);
8676 copy
->size
= total_size
;
8678 vm_map_lock(dst_map
);
8680 if (!vm_map_lookup_entry(dst_map
,
8681 base_addr
, &tmp_entry
)) {
8682 vm_map_unlock(dst_map
);
8683 return(KERN_INVALID_ADDRESS
);
8685 if (tmp_entry
->in_transition
) {
8686 entry
->needs_wakeup
= TRUE
;
8687 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
8692 vm_map_clip_start(dst_map
,
8694 vm_map_trunc_page(base_addr
,
8695 VM_MAP_PAGE_MASK(dst_map
)));
8701 * Throw away the vm_map_copy object
8703 if (discard_on_success
)
8704 vm_map_copy_discard(copy
);
8706 return(KERN_SUCCESS
);
8707 }/* vm_map_copy_overwrite */
8710 vm_map_copy_overwrite(
8712 vm_map_offset_t dst_addr
,
8714 boolean_t interruptible
)
8716 vm_map_size_t head_size
, tail_size
;
8717 vm_map_copy_t head_copy
, tail_copy
;
8718 vm_map_offset_t head_addr
, tail_addr
;
8719 vm_map_entry_t entry
;
8721 vm_map_offset_t effective_page_mask
, effective_page_size
;
8730 if (interruptible
||
8731 copy
== VM_MAP_COPY_NULL
||
8732 copy
->type
!= VM_MAP_COPY_ENTRY_LIST
) {
8734 * We can't split the "copy" map if we're interruptible
8735 * or if we don't have a "copy" map...
8738 return vm_map_copy_overwrite_nested(dst_map
,
8746 effective_page_mask
= MAX(VM_MAP_PAGE_MASK(dst_map
), PAGE_MASK
);
8747 effective_page_mask
= MAX(VM_MAP_COPY_PAGE_MASK(copy
),
8748 effective_page_mask
);
8749 effective_page_size
= effective_page_mask
+ 1;
8751 if (copy
->size
< 3 * effective_page_size
) {
8753 * Too small to bother with optimizing...
8758 if ((dst_addr
& effective_page_mask
) !=
8759 (copy
->offset
& effective_page_mask
)) {
8761 * Incompatible mis-alignment of source and destination...
8767 * Proper alignment or identical mis-alignment at the beginning.
8768 * Let's try and do a small unaligned copy first (if needed)
8769 * and then an aligned copy for the rest.
8771 if (!vm_map_page_aligned(dst_addr
, effective_page_mask
)) {
8772 head_addr
= dst_addr
;
8773 head_size
= (effective_page_size
-
8774 (copy
->offset
& effective_page_mask
));
8775 head_size
= MIN(head_size
, copy
->size
);
8777 if (!vm_map_page_aligned(copy
->offset
+ copy
->size
,
8778 effective_page_mask
)) {
8780 * Mis-alignment at the end.
8781 * Do an aligned copy up to the last page and
8782 * then an unaligned copy for the remaining bytes.
8784 tail_size
= ((copy
->offset
+ copy
->size
) &
8785 effective_page_mask
);
8786 tail_size
= MIN(tail_size
, copy
->size
);
8787 tail_addr
= dst_addr
+ copy
->size
- tail_size
;
8788 assert(tail_addr
>= head_addr
+ head_size
);
8790 assert(head_size
+ tail_size
<= copy
->size
);
8792 if (head_size
+ tail_size
== copy
->size
) {
8794 * It's all unaligned, no optimization possible...
8800 * Can't optimize if there are any submaps in the
8801 * destination due to the way we free the "copy" map
8802 * progressively in vm_map_copy_overwrite_nested()
8805 vm_map_lock_read(dst_map
);
8806 if (! vm_map_lookup_entry(dst_map
, dst_addr
, &entry
)) {
8807 vm_map_unlock_read(dst_map
);
8811 (entry
!= vm_map_copy_to_entry(copy
) &&
8812 entry
->vme_start
< dst_addr
+ copy
->size
);
8813 entry
= entry
->vme_next
) {
8814 if (entry
->is_sub_map
) {
8815 vm_map_unlock_read(dst_map
);
8819 vm_map_unlock_read(dst_map
);
8823 * Unaligned copy of the first "head_size" bytes, to reach
8828 * Extract "head_copy" out of "copy".
8830 head_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
8831 head_copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
8832 vm_map_copy_first_entry(head_copy
) =
8833 vm_map_copy_to_entry(head_copy
);
8834 vm_map_copy_last_entry(head_copy
) =
8835 vm_map_copy_to_entry(head_copy
);
8836 head_copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
8837 head_copy
->cpy_hdr
.nentries
= 0;
8838 head_copy
->cpy_hdr
.entries_pageable
=
8839 copy
->cpy_hdr
.entries_pageable
;
8840 vm_map_store_init(&head_copy
->cpy_hdr
);
8842 entry
= vm_map_copy_first_entry(copy
);
8843 if (entry
->vme_end
< copy
->offset
+ head_size
) {
8844 head_size
= entry
->vme_end
- copy
->offset
;
8847 head_copy
->offset
= copy
->offset
;
8848 head_copy
->size
= head_size
;
8849 copy
->offset
+= head_size
;
8850 copy
->size
-= head_size
;
8852 vm_map_copy_clip_end(copy
, entry
, copy
->offset
);
8853 vm_map_copy_entry_unlink(copy
, entry
);
8854 vm_map_copy_entry_link(head_copy
,
8855 vm_map_copy_to_entry(head_copy
),
8859 * Do the unaligned copy.
8861 kr
= vm_map_copy_overwrite_nested(dst_map
,
8867 if (kr
!= KERN_SUCCESS
)
8873 * Extract "tail_copy" out of "copy".
8875 tail_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
8876 tail_copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
8877 vm_map_copy_first_entry(tail_copy
) =
8878 vm_map_copy_to_entry(tail_copy
);
8879 vm_map_copy_last_entry(tail_copy
) =
8880 vm_map_copy_to_entry(tail_copy
);
8881 tail_copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
8882 tail_copy
->cpy_hdr
.nentries
= 0;
8883 tail_copy
->cpy_hdr
.entries_pageable
=
8884 copy
->cpy_hdr
.entries_pageable
;
8885 vm_map_store_init(&tail_copy
->cpy_hdr
);
8887 tail_copy
->offset
= copy
->offset
+ copy
->size
- tail_size
;
8888 tail_copy
->size
= tail_size
;
8890 copy
->size
-= tail_size
;
8892 entry
= vm_map_copy_last_entry(copy
);
8893 vm_map_copy_clip_start(copy
, entry
, tail_copy
->offset
);
8894 entry
= vm_map_copy_last_entry(copy
);
8895 vm_map_copy_entry_unlink(copy
, entry
);
8896 vm_map_copy_entry_link(tail_copy
,
8897 vm_map_copy_last_entry(tail_copy
),
8902 * Copy most (or possibly all) of the data.
8904 kr
= vm_map_copy_overwrite_nested(dst_map
,
8905 dst_addr
+ head_size
,
8910 if (kr
!= KERN_SUCCESS
) {
8915 kr
= vm_map_copy_overwrite_nested(dst_map
,
8924 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
8925 if (kr
== KERN_SUCCESS
) {
8927 * Discard all the copy maps.
8930 vm_map_copy_discard(head_copy
);
8933 vm_map_copy_discard(copy
);
8935 vm_map_copy_discard(tail_copy
);
8940 * Re-assemble the original copy map.
8943 entry
= vm_map_copy_first_entry(head_copy
);
8944 vm_map_copy_entry_unlink(head_copy
, entry
);
8945 vm_map_copy_entry_link(copy
,
8946 vm_map_copy_to_entry(copy
),
8948 copy
->offset
-= head_size
;
8949 copy
->size
+= head_size
;
8950 vm_map_copy_discard(head_copy
);
8954 entry
= vm_map_copy_last_entry(tail_copy
);
8955 vm_map_copy_entry_unlink(tail_copy
, entry
);
8956 vm_map_copy_entry_link(copy
,
8957 vm_map_copy_last_entry(copy
),
8959 copy
->size
+= tail_size
;
8960 vm_map_copy_discard(tail_copy
);
8969 * Routine: vm_map_copy_overwrite_unaligned [internal use only]
8972 * Physically copy unaligned data
8975 * Unaligned parts of pages have to be physically copied. We use
8976 * a modified form of vm_fault_copy (which understands none-aligned
8977 * page offsets and sizes) to do the copy. We attempt to copy as
8978 * much memory in one go as possibly, however vm_fault_copy copies
8979 * within 1 memory object so we have to find the smaller of "amount left"
8980 * "source object data size" and "target object data size". With
8981 * unaligned data we don't need to split regions, therefore the source
8982 * (copy) object should be one map entry, the target range may be split
8983 * over multiple map entries however. In any event we are pessimistic
8984 * about these assumptions.
8987 * dst_map is locked on entry and is return locked on success,
8988 * unlocked on error.
8991 static kern_return_t
8992 vm_map_copy_overwrite_unaligned(
8994 vm_map_entry_t entry
,
8996 vm_map_offset_t start
,
8997 boolean_t discard_on_success
)
8999 vm_map_entry_t copy_entry
;
9000 vm_map_entry_t copy_entry_next
;
9001 vm_map_version_t version
;
9002 vm_object_t dst_object
;
9003 vm_object_offset_t dst_offset
;
9004 vm_object_offset_t src_offset
;
9005 vm_object_offset_t entry_offset
;
9006 vm_map_offset_t entry_end
;
9007 vm_map_size_t src_size
,
9011 kern_return_t kr
= KERN_SUCCESS
;
9014 copy_entry
= vm_map_copy_first_entry(copy
);
9016 vm_map_lock_write_to_read(dst_map
);
9018 src_offset
= copy
->offset
- vm_object_trunc_page(copy
->offset
);
9019 amount_left
= copy
->size
;
9021 * unaligned so we never clipped this entry, we need the offset into
9022 * the vm_object not just the data.
9024 while (amount_left
> 0) {
9026 if (entry
== vm_map_to_entry(dst_map
)) {
9027 vm_map_unlock_read(dst_map
);
9028 return KERN_INVALID_ADDRESS
;
9031 /* "start" must be within the current map entry */
9032 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
9034 dst_offset
= start
- entry
->vme_start
;
9036 dst_size
= entry
->vme_end
- start
;
9038 src_size
= copy_entry
->vme_end
-
9039 (copy_entry
->vme_start
+ src_offset
);
9041 if (dst_size
< src_size
) {
9043 * we can only copy dst_size bytes before
9044 * we have to get the next destination entry
9046 copy_size
= dst_size
;
9049 * we can only copy src_size bytes before
9050 * we have to get the next source copy entry
9052 copy_size
= src_size
;
9055 if (copy_size
> amount_left
) {
9056 copy_size
= amount_left
;
9059 * Entry needs copy, create a shadow shadow object for
9060 * Copy on write region.
9062 if (entry
->needs_copy
&&
9063 ((entry
->protection
& VM_PROT_WRITE
) != 0))
9065 if (vm_map_lock_read_to_write(dst_map
)) {
9066 vm_map_lock_read(dst_map
);
9069 VME_OBJECT_SHADOW(entry
,
9070 (vm_map_size_t
)(entry
->vme_end
9071 - entry
->vme_start
));
9072 entry
->needs_copy
= FALSE
;
9073 vm_map_lock_write_to_read(dst_map
);
9075 dst_object
= VME_OBJECT(entry
);
9077 * unlike with the virtual (aligned) copy we're going
9078 * to fault on it therefore we need a target object.
9080 if (dst_object
== VM_OBJECT_NULL
) {
9081 if (vm_map_lock_read_to_write(dst_map
)) {
9082 vm_map_lock_read(dst_map
);
9085 dst_object
= vm_object_allocate((vm_map_size_t
)
9086 entry
->vme_end
- entry
->vme_start
);
9087 VME_OBJECT(entry
) = dst_object
;
9088 VME_OFFSET_SET(entry
, 0);
9089 assert(entry
->use_pmap
);
9090 vm_map_lock_write_to_read(dst_map
);
9093 * Take an object reference and unlock map. The "entry" may
9094 * disappear or change when the map is unlocked.
9096 vm_object_reference(dst_object
);
9097 version
.main_timestamp
= dst_map
->timestamp
;
9098 entry_offset
= VME_OFFSET(entry
);
9099 entry_end
= entry
->vme_end
;
9100 vm_map_unlock_read(dst_map
);
9102 * Copy as much as possible in one pass
9105 VME_OBJECT(copy_entry
),
9106 VME_OFFSET(copy_entry
) + src_offset
,
9109 entry_offset
+ dst_offset
,
9115 src_offset
+= copy_size
;
9116 amount_left
-= copy_size
;
9118 * Release the object reference
9120 vm_object_deallocate(dst_object
);
9122 * If a hard error occurred, return it now
9124 if (kr
!= KERN_SUCCESS
)
9127 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
9128 || amount_left
== 0)
9131 * all done with this copy entry, dispose.
9133 copy_entry_next
= copy_entry
->vme_next
;
9135 if (discard_on_success
) {
9136 vm_map_copy_entry_unlink(copy
, copy_entry
);
9137 assert(!copy_entry
->is_sub_map
);
9138 vm_object_deallocate(VME_OBJECT(copy_entry
));
9139 vm_map_copy_entry_dispose(copy
, copy_entry
);
9142 if (copy_entry_next
== vm_map_copy_to_entry(copy
) &&
9145 * not finished copying but run out of source
9147 return KERN_INVALID_ADDRESS
;
9150 copy_entry
= copy_entry_next
;
9155 if (amount_left
== 0)
9156 return KERN_SUCCESS
;
9158 vm_map_lock_read(dst_map
);
9159 if (version
.main_timestamp
== dst_map
->timestamp
) {
9160 if (start
== entry_end
) {
9162 * destination region is split. Use the version
9163 * information to avoid a lookup in the normal
9166 entry
= entry
->vme_next
;
9168 * should be contiguous. Fail if we encounter
9169 * a hole in the destination.
9171 if (start
!= entry
->vme_start
) {
9172 vm_map_unlock_read(dst_map
);
9173 return KERN_INVALID_ADDRESS
;
9178 * Map version check failed.
9179 * we must lookup the entry because somebody
9180 * might have changed the map behind our backs.
9183 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
9185 vm_map_unlock_read(dst_map
);
9186 return KERN_INVALID_ADDRESS
;
9191 return KERN_SUCCESS
;
9192 }/* vm_map_copy_overwrite_unaligned */
9195 * Routine: vm_map_copy_overwrite_aligned [internal use only]
9198 * Does all the vm_trickery possible for whole pages.
9202 * If there are no permanent objects in the destination,
9203 * and the source and destination map entry zones match,
9204 * and the destination map entry is not shared,
9205 * then the map entries can be deleted and replaced
9206 * with those from the copy. The following code is the
9207 * basic idea of what to do, but there are lots of annoying
9208 * little details about getting protection and inheritance
9209 * right. Should add protection, inheritance, and sharing checks
9210 * to the above pass and make sure that no wiring is involved.
9213 int vm_map_copy_overwrite_aligned_src_not_internal
= 0;
9214 int vm_map_copy_overwrite_aligned_src_not_symmetric
= 0;
9215 int vm_map_copy_overwrite_aligned_src_large
= 0;
9217 static kern_return_t
9218 vm_map_copy_overwrite_aligned(
9220 vm_map_entry_t tmp_entry
,
9222 vm_map_offset_t start
,
9223 __unused pmap_t pmap
)
9226 vm_map_entry_t copy_entry
;
9227 vm_map_size_t copy_size
;
9229 vm_map_entry_t entry
;
9231 while ((copy_entry
= vm_map_copy_first_entry(copy
))
9232 != vm_map_copy_to_entry(copy
))
9234 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
9237 if (entry
->is_sub_map
) {
9238 /* unnested when clipped earlier */
9239 assert(!entry
->use_pmap
);
9241 if (entry
== vm_map_to_entry(dst_map
)) {
9242 vm_map_unlock(dst_map
);
9243 return KERN_INVALID_ADDRESS
;
9245 size
= (entry
->vme_end
- entry
->vme_start
);
9247 * Make sure that no holes popped up in the
9248 * address map, and that the protection is
9249 * still valid, in case the map was unlocked
9253 if ((entry
->vme_start
!= start
) || ((entry
->is_sub_map
)
9254 && !entry
->needs_copy
)) {
9255 vm_map_unlock(dst_map
);
9256 return(KERN_INVALID_ADDRESS
);
9258 assert(entry
!= vm_map_to_entry(dst_map
));
9261 * Check protection again
9264 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
9265 vm_map_unlock(dst_map
);
9266 return(KERN_PROTECTION_FAILURE
);
9270 * Adjust to source size first
9273 if (copy_size
< size
) {
9274 if (entry
->map_aligned
&&
9275 !VM_MAP_PAGE_ALIGNED(entry
->vme_start
+ copy_size
,
9276 VM_MAP_PAGE_MASK(dst_map
))) {
9277 /* no longer map-aligned */
9278 entry
->map_aligned
= FALSE
;
9280 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
9285 * Adjust to destination size
9288 if (size
< copy_size
) {
9289 vm_map_copy_clip_end(copy
, copy_entry
,
9290 copy_entry
->vme_start
+ size
);
9294 assert((entry
->vme_end
- entry
->vme_start
) == size
);
9295 assert((tmp_entry
->vme_end
- tmp_entry
->vme_start
) == size
);
9296 assert((copy_entry
->vme_end
- copy_entry
->vme_start
) == size
);
9299 * If the destination contains temporary unshared memory,
9300 * we can perform the copy by throwing it away and
9301 * installing the source data.
9304 object
= VME_OBJECT(entry
);
9305 if ((!entry
->is_shared
&&
9306 ((object
== VM_OBJECT_NULL
) ||
9307 (object
->internal
&& !object
->true_share
))) ||
9308 entry
->needs_copy
) {
9309 vm_object_t old_object
= VME_OBJECT(entry
);
9310 vm_object_offset_t old_offset
= VME_OFFSET(entry
);
9311 vm_object_offset_t offset
;
9314 * Ensure that the source and destination aren't
9317 if (old_object
== VME_OBJECT(copy_entry
) &&
9318 old_offset
== VME_OFFSET(copy_entry
)) {
9319 vm_map_copy_entry_unlink(copy
, copy_entry
);
9320 vm_map_copy_entry_dispose(copy
, copy_entry
);
9322 if (old_object
!= VM_OBJECT_NULL
)
9323 vm_object_deallocate(old_object
);
9325 start
= tmp_entry
->vme_end
;
9326 tmp_entry
= tmp_entry
->vme_next
;
9330 #if !CONFIG_EMBEDDED
9331 #define __TRADEOFF1_OBJ_SIZE (64 * 1024 * 1024) /* 64 MB */
9332 #define __TRADEOFF1_COPY_SIZE (128 * 1024) /* 128 KB */
9333 if (VME_OBJECT(copy_entry
) != VM_OBJECT_NULL
&&
9334 VME_OBJECT(copy_entry
)->vo_size
>= __TRADEOFF1_OBJ_SIZE
&&
9335 copy_size
<= __TRADEOFF1_COPY_SIZE
) {
9337 * Virtual vs. Physical copy tradeoff #1.
9339 * Copying only a few pages out of a large
9340 * object: do a physical copy instead of
9341 * a virtual copy, to avoid possibly keeping
9342 * the entire large object alive because of
9343 * those few copy-on-write pages.
9345 vm_map_copy_overwrite_aligned_src_large
++;
9348 #endif /* !CONFIG_EMBEDDED */
9350 if ((dst_map
->pmap
!= kernel_pmap
) &&
9351 (VME_ALIAS(entry
) >= VM_MEMORY_MALLOC
) &&
9352 (VME_ALIAS(entry
) <= VM_MEMORY_MALLOC_LARGE_REUSED
)) {
9353 vm_object_t new_object
, new_shadow
;
9356 * We're about to map something over a mapping
9357 * established by malloc()...
9359 new_object
= VME_OBJECT(copy_entry
);
9360 if (new_object
!= VM_OBJECT_NULL
) {
9361 vm_object_lock_shared(new_object
);
9363 while (new_object
!= VM_OBJECT_NULL
&&
9364 #if !CONFIG_EMBEDDED
9365 !new_object
->true_share
&&
9366 new_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
9367 #endif /* !CONFIG_EMBEDDED */
9368 new_object
->internal
) {
9369 new_shadow
= new_object
->shadow
;
9370 if (new_shadow
== VM_OBJECT_NULL
) {
9373 vm_object_lock_shared(new_shadow
);
9374 vm_object_unlock(new_object
);
9375 new_object
= new_shadow
;
9377 if (new_object
!= VM_OBJECT_NULL
) {
9378 if (!new_object
->internal
) {
9380 * The new mapping is backed
9381 * by an external object. We
9382 * don't want malloc'ed memory
9383 * to be replaced with such a
9384 * non-anonymous mapping, so
9385 * let's go off the optimized
9388 vm_map_copy_overwrite_aligned_src_not_internal
++;
9389 vm_object_unlock(new_object
);
9392 #if !CONFIG_EMBEDDED
9393 if (new_object
->true_share
||
9394 new_object
->copy_strategy
!= MEMORY_OBJECT_COPY_SYMMETRIC
) {
9396 * Same if there's a "true_share"
9397 * object in the shadow chain, or
9398 * an object with a non-default
9399 * (SYMMETRIC) copy strategy.
9401 vm_map_copy_overwrite_aligned_src_not_symmetric
++;
9402 vm_object_unlock(new_object
);
9405 #endif /* !CONFIG_EMBEDDED */
9406 vm_object_unlock(new_object
);
9409 * The new mapping is still backed by
9410 * anonymous (internal) memory, so it's
9411 * OK to substitute it for the original
9416 if (old_object
!= VM_OBJECT_NULL
) {
9417 if(entry
->is_sub_map
) {
9418 if(entry
->use_pmap
) {
9419 #ifndef NO_NESTED_PMAP
9420 pmap_unnest(dst_map
->pmap
,
9421 (addr64_t
)entry
->vme_start
,
9422 entry
->vme_end
- entry
->vme_start
);
9423 #endif /* NO_NESTED_PMAP */
9424 if(dst_map
->mapped_in_other_pmaps
) {
9425 /* clean up parent */
9427 vm_map_submap_pmap_clean(
9428 dst_map
, entry
->vme_start
,
9434 vm_map_submap_pmap_clean(
9435 dst_map
, entry
->vme_start
,
9440 vm_map_deallocate(VME_SUBMAP(entry
));
9442 if(dst_map
->mapped_in_other_pmaps
) {
9443 vm_object_pmap_protect_options(
9451 PMAP_OPTIONS_REMOVE
);
9453 pmap_remove_options(
9455 (addr64_t
)(entry
->vme_start
),
9456 (addr64_t
)(entry
->vme_end
),
9457 PMAP_OPTIONS_REMOVE
);
9459 vm_object_deallocate(old_object
);
9463 entry
->is_sub_map
= FALSE
;
9464 VME_OBJECT_SET(entry
, VME_OBJECT(copy_entry
));
9465 object
= VME_OBJECT(entry
);
9466 entry
->needs_copy
= copy_entry
->needs_copy
;
9467 entry
->wired_count
= 0;
9468 entry
->user_wired_count
= 0;
9469 offset
= VME_OFFSET(copy_entry
);
9470 VME_OFFSET_SET(entry
, offset
);
9472 vm_map_copy_entry_unlink(copy
, copy_entry
);
9473 vm_map_copy_entry_dispose(copy
, copy_entry
);
9476 * we could try to push pages into the pmap at this point, BUT
9477 * this optimization only saved on average 2 us per page if ALL
9478 * the pages in the source were currently mapped
9479 * and ALL the pages in the dest were touched, if there were fewer
9480 * than 2/3 of the pages touched, this optimization actually cost more cycles
9481 * it also puts a lot of pressure on the pmap layer w/r to mapping structures
9485 * Set up for the next iteration. The map
9486 * has not been unlocked, so the next
9487 * address should be at the end of this
9488 * entry, and the next map entry should be
9489 * the one following it.
9492 start
= tmp_entry
->vme_end
;
9493 tmp_entry
= tmp_entry
->vme_next
;
9495 vm_map_version_t version
;
9496 vm_object_t dst_object
;
9497 vm_object_offset_t dst_offset
;
9501 if (entry
->needs_copy
) {
9502 VME_OBJECT_SHADOW(entry
,
9505 entry
->needs_copy
= FALSE
;
9508 dst_object
= VME_OBJECT(entry
);
9509 dst_offset
= VME_OFFSET(entry
);
9512 * Take an object reference, and record
9513 * the map version information so that the
9514 * map can be safely unlocked.
9517 if (dst_object
== VM_OBJECT_NULL
) {
9519 * We would usually have just taken the
9520 * optimized path above if the destination
9521 * object has not been allocated yet. But we
9522 * now disable that optimization if the copy
9523 * entry's object is not backed by anonymous
9524 * memory to avoid replacing malloc'ed
9525 * (i.e. re-usable) anonymous memory with a
9526 * not-so-anonymous mapping.
9527 * So we have to handle this case here and
9528 * allocate a new VM object for this map entry.
9530 dst_object
= vm_object_allocate(
9531 entry
->vme_end
- entry
->vme_start
);
9533 VME_OBJECT_SET(entry
, dst_object
);
9534 VME_OFFSET_SET(entry
, dst_offset
);
9535 assert(entry
->use_pmap
);
9539 vm_object_reference(dst_object
);
9541 /* account for unlock bumping up timestamp */
9542 version
.main_timestamp
= dst_map
->timestamp
+ 1;
9544 vm_map_unlock(dst_map
);
9547 * Copy as much as possible in one pass
9552 VME_OBJECT(copy_entry
),
9553 VME_OFFSET(copy_entry
),
9562 * Release the object reference
9565 vm_object_deallocate(dst_object
);
9568 * If a hard error occurred, return it now
9571 if (r
!= KERN_SUCCESS
)
9574 if (copy_size
!= 0) {
9576 * Dispose of the copied region
9579 vm_map_copy_clip_end(copy
, copy_entry
,
9580 copy_entry
->vme_start
+ copy_size
);
9581 vm_map_copy_entry_unlink(copy
, copy_entry
);
9582 vm_object_deallocate(VME_OBJECT(copy_entry
));
9583 vm_map_copy_entry_dispose(copy
, copy_entry
);
9587 * Pick up in the destination map where we left off.
9589 * Use the version information to avoid a lookup
9590 * in the normal case.
9594 vm_map_lock(dst_map
);
9595 if (version
.main_timestamp
== dst_map
->timestamp
&&
9597 /* We can safely use saved tmp_entry value */
9599 if (tmp_entry
->map_aligned
&&
9600 !VM_MAP_PAGE_ALIGNED(
9602 VM_MAP_PAGE_MASK(dst_map
))) {
9603 /* no longer map-aligned */
9604 tmp_entry
->map_aligned
= FALSE
;
9606 vm_map_clip_end(dst_map
, tmp_entry
, start
);
9607 tmp_entry
= tmp_entry
->vme_next
;
9609 /* Must do lookup of tmp_entry */
9611 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
9612 vm_map_unlock(dst_map
);
9613 return(KERN_INVALID_ADDRESS
);
9615 if (tmp_entry
->map_aligned
&&
9616 !VM_MAP_PAGE_ALIGNED(
9618 VM_MAP_PAGE_MASK(dst_map
))) {
9619 /* no longer map-aligned */
9620 tmp_entry
->map_aligned
= FALSE
;
9622 vm_map_clip_start(dst_map
, tmp_entry
, start
);
9627 return(KERN_SUCCESS
);
9628 }/* vm_map_copy_overwrite_aligned */
9631 * Routine: vm_map_copyin_kernel_buffer [internal use only]
9634 * Copy in data to a kernel buffer from space in the
9635 * source map. The original space may be optionally
9638 * If successful, returns a new copy object.
9640 static kern_return_t
9641 vm_map_copyin_kernel_buffer(
9643 vm_map_offset_t src_addr
,
9645 boolean_t src_destroy
,
9646 vm_map_copy_t
*copy_result
)
9650 vm_size_t kalloc_size
;
9652 if (len
> msg_ool_size_small
)
9653 return KERN_INVALID_ARGUMENT
;
9655 kalloc_size
= (vm_size_t
)(cpy_kdata_hdr_sz
+ len
);
9657 copy
= (vm_map_copy_t
)kalloc(kalloc_size
);
9658 if (copy
== VM_MAP_COPY_NULL
)
9659 return KERN_RESOURCE_SHORTAGE
;
9660 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
9664 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, (vm_size_t
)len
);
9665 if (kr
!= KERN_SUCCESS
) {
9666 kfree(copy
, kalloc_size
);
9670 (void) vm_map_remove(
9672 vm_map_trunc_page(src_addr
,
9673 VM_MAP_PAGE_MASK(src_map
)),
9674 vm_map_round_page(src_addr
+ len
,
9675 VM_MAP_PAGE_MASK(src_map
)),
9676 (VM_MAP_REMOVE_INTERRUPTIBLE
|
9677 VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
9678 ((src_map
== kernel_map
) ? VM_MAP_REMOVE_KUNWIRE
: 0)));
9680 *copy_result
= copy
;
9681 return KERN_SUCCESS
;
9685 * Routine: vm_map_copyout_kernel_buffer [internal use only]
9688 * Copy out data from a kernel buffer into space in the
9689 * destination map. The space may be otpionally dynamically
9692 * If successful, consumes the copy object.
9693 * Otherwise, the caller is responsible for it.
9695 static int vm_map_copyout_kernel_buffer_failures
= 0;
9696 static kern_return_t
9697 vm_map_copyout_kernel_buffer(
9699 vm_map_address_t
*addr
, /* IN/OUT */
9701 vm_map_size_t copy_size
,
9702 boolean_t overwrite
,
9703 boolean_t consume_on_success
)
9705 kern_return_t kr
= KERN_SUCCESS
;
9706 thread_t thread
= current_thread();
9708 assert(copy
->size
== copy_size
);
9711 * check for corrupted vm_map_copy structure
9713 if (copy_size
> msg_ool_size_small
|| copy
->offset
)
9714 panic("Invalid vm_map_copy_t sz:%lld, ofst:%lld",
9715 (long long)copy
->size
, (long long)copy
->offset
);
9720 * Allocate space in the target map for the data
9723 kr
= vm_map_enter(map
,
9725 vm_map_round_page(copy_size
,
9726 VM_MAP_PAGE_MASK(map
)),
9727 (vm_map_offset_t
) 0,
9729 VM_MAP_KERNEL_FLAGS_NONE
,
9730 VM_KERN_MEMORY_NONE
,
9732 (vm_object_offset_t
) 0,
9736 VM_INHERIT_DEFAULT
);
9737 if (kr
!= KERN_SUCCESS
)
9740 if (map
->pmap
== kernel_pmap
) {
9741 kasan_notify_address(*addr
, copy
->size
);
9747 * Copyout the data from the kernel buffer to the target map.
9749 if (thread
->map
== map
) {
9752 * If the target map is the current map, just do
9755 assert((vm_size_t
)copy_size
== copy_size
);
9756 if (copyout(copy
->cpy_kdata
, *addr
, (vm_size_t
)copy_size
)) {
9757 kr
= KERN_INVALID_ADDRESS
;
9764 * If the target map is another map, assume the
9765 * target's address space identity for the duration
9768 vm_map_reference(map
);
9769 oldmap
= vm_map_switch(map
);
9771 assert((vm_size_t
)copy_size
== copy_size
);
9772 if (copyout(copy
->cpy_kdata
, *addr
, (vm_size_t
)copy_size
)) {
9773 vm_map_copyout_kernel_buffer_failures
++;
9774 kr
= KERN_INVALID_ADDRESS
;
9777 (void) vm_map_switch(oldmap
);
9778 vm_map_deallocate(map
);
9781 if (kr
!= KERN_SUCCESS
) {
9782 /* the copy failed, clean up */
9785 * Deallocate the space we allocated in the target map.
9787 (void) vm_map_remove(
9789 vm_map_trunc_page(*addr
,
9790 VM_MAP_PAGE_MASK(map
)),
9791 vm_map_round_page((*addr
+
9792 vm_map_round_page(copy_size
,
9793 VM_MAP_PAGE_MASK(map
))),
9794 VM_MAP_PAGE_MASK(map
)),
9799 /* copy was successful, dicard the copy structure */
9800 if (consume_on_success
) {
9801 kfree(copy
, copy_size
+ cpy_kdata_hdr_sz
);
9809 * Macro: vm_map_copy_insert
9812 * Link a copy chain ("copy") into a map at the
9813 * specified location (after "where").
9815 * The copy chain is destroyed.
9817 * The arguments are evaluated multiple times.
9819 #define vm_map_copy_insert(map, where, copy) \
9821 vm_map_store_copy_insert(map, where, copy); \
9822 zfree(vm_map_copy_zone, copy); \
9828 vm_map_entry_t where
,
9830 vm_map_offset_t adjustment
,
9833 vm_inherit_t inheritance
)
9835 vm_map_entry_t copy_entry
, new_entry
;
9837 for (copy_entry
= vm_map_copy_first_entry(copy
);
9838 copy_entry
!= vm_map_copy_to_entry(copy
);
9839 copy_entry
= copy_entry
->vme_next
) {
9840 /* get a new VM map entry for the map */
9841 new_entry
= vm_map_entry_create(map
,
9842 !map
->hdr
.entries_pageable
);
9843 /* copy the "copy entry" to the new entry */
9844 vm_map_entry_copy(new_entry
, copy_entry
);
9845 /* adjust "start" and "end" */
9846 new_entry
->vme_start
+= adjustment
;
9847 new_entry
->vme_end
+= adjustment
;
9848 /* clear some attributes */
9849 new_entry
->inheritance
= inheritance
;
9850 new_entry
->protection
= cur_prot
;
9851 new_entry
->max_protection
= max_prot
;
9852 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
9853 /* take an extra reference on the entry's "object" */
9854 if (new_entry
->is_sub_map
) {
9855 assert(!new_entry
->use_pmap
); /* not nested */
9856 vm_map_lock(VME_SUBMAP(new_entry
));
9857 vm_map_reference(VME_SUBMAP(new_entry
));
9858 vm_map_unlock(VME_SUBMAP(new_entry
));
9860 vm_object_reference(VME_OBJECT(new_entry
));
9862 /* insert the new entry in the map */
9863 vm_map_store_entry_link(map
, where
, new_entry
);
9864 /* continue inserting the "copy entries" after the new entry */
9871 * Returns true if *size matches (or is in the range of) copy->size.
9872 * Upon returning true, the *size field is updated with the actual size of the
9873 * copy object (may be different for VM_MAP_COPY_ENTRY_LIST types)
9876 vm_map_copy_validate_size(
9879 vm_map_size_t
*size
)
9881 if (copy
== VM_MAP_COPY_NULL
)
9883 vm_map_size_t copy_sz
= copy
->size
;
9884 vm_map_size_t sz
= *size
;
9885 switch (copy
->type
) {
9886 case VM_MAP_COPY_OBJECT
:
9887 case VM_MAP_COPY_KERNEL_BUFFER
:
9891 case VM_MAP_COPY_ENTRY_LIST
:
9893 * potential page-size rounding prevents us from exactly
9894 * validating this flavor of vm_map_copy, but we can at least
9895 * assert that it's within a range.
9897 if (copy_sz
>= sz
&&
9898 copy_sz
<= vm_map_round_page(sz
, VM_MAP_PAGE_MASK(dst_map
))) {
9910 * Routine: vm_map_copyout_size
9913 * Copy out a copy chain ("copy") into newly-allocated
9914 * space in the destination map. Uses a prevalidated
9915 * size for the copy object (vm_map_copy_validate_size).
9917 * If successful, consumes the copy object.
9918 * Otherwise, the caller is responsible for it.
9921 vm_map_copyout_size(
9923 vm_map_address_t
*dst_addr
, /* OUT */
9925 vm_map_size_t copy_size
)
9927 return vm_map_copyout_internal(dst_map
, dst_addr
, copy
, copy_size
,
9928 TRUE
, /* consume_on_success */
9931 VM_INHERIT_DEFAULT
);
9935 * Routine: vm_map_copyout
9938 * Copy out a copy chain ("copy") into newly-allocated
9939 * space in the destination map.
9941 * If successful, consumes the copy object.
9942 * Otherwise, the caller is responsible for it.
9947 vm_map_address_t
*dst_addr
, /* OUT */
9950 return vm_map_copyout_internal(dst_map
, dst_addr
, copy
, copy
? copy
->size
: 0,
9951 TRUE
, /* consume_on_success */
9954 VM_INHERIT_DEFAULT
);
9958 vm_map_copyout_internal(
9960 vm_map_address_t
*dst_addr
, /* OUT */
9962 vm_map_size_t copy_size
,
9963 boolean_t consume_on_success
,
9964 vm_prot_t cur_protection
,
9965 vm_prot_t max_protection
,
9966 vm_inherit_t inheritance
)
9969 vm_map_size_t adjustment
;
9970 vm_map_offset_t start
;
9971 vm_object_offset_t vm_copy_start
;
9972 vm_map_entry_t last
;
9973 vm_map_entry_t entry
;
9974 vm_map_entry_t hole_entry
;
9977 * Check for null copy object.
9980 if (copy
== VM_MAP_COPY_NULL
) {
9982 return(KERN_SUCCESS
);
9985 if (copy
->size
!= copy_size
) {
9987 return KERN_FAILURE
;
9991 * Check for special copy object, created
9992 * by vm_map_copyin_object.
9995 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
9996 vm_object_t object
= copy
->cpy_object
;
9998 vm_object_offset_t offset
;
10000 offset
= vm_object_trunc_page(copy
->offset
);
10001 size
= vm_map_round_page((copy_size
+
10002 (vm_map_size_t
)(copy
->offset
-
10004 VM_MAP_PAGE_MASK(dst_map
));
10006 kr
= vm_map_enter(dst_map
, dst_addr
, size
,
10007 (vm_map_offset_t
) 0, VM_FLAGS_ANYWHERE
,
10008 VM_MAP_KERNEL_FLAGS_NONE
,
10009 VM_KERN_MEMORY_NONE
,
10010 object
, offset
, FALSE
,
10011 VM_PROT_DEFAULT
, VM_PROT_ALL
,
10012 VM_INHERIT_DEFAULT
);
10013 if (kr
!= KERN_SUCCESS
)
10015 /* Account for non-pagealigned copy object */
10016 *dst_addr
+= (vm_map_offset_t
)(copy
->offset
- offset
);
10017 if (consume_on_success
)
10018 zfree(vm_map_copy_zone
, copy
);
10019 return(KERN_SUCCESS
);
10023 * Check for special kernel buffer allocated
10024 * by new_ipc_kmsg_copyin.
10027 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
10028 return vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
10029 copy
, copy_size
, FALSE
,
10030 consume_on_success
);
10035 * Find space for the data
10038 vm_copy_start
= vm_map_trunc_page((vm_map_size_t
)copy
->offset
,
10039 VM_MAP_COPY_PAGE_MASK(copy
));
10040 size
= vm_map_round_page((vm_map_size_t
)copy
->offset
+ copy_size
,
10041 VM_MAP_COPY_PAGE_MASK(copy
))
10047 vm_map_lock(dst_map
);
10048 if( dst_map
->disable_vmentry_reuse
== TRUE
) {
10049 VM_MAP_HIGHEST_ENTRY(dst_map
, entry
, start
);
10052 if (dst_map
->holelistenabled
) {
10053 hole_entry
= (vm_map_entry_t
)dst_map
->holes_list
;
10055 if (hole_entry
== NULL
) {
10057 * No more space in the map?
10059 vm_map_unlock(dst_map
);
10060 return(KERN_NO_SPACE
);
10064 start
= last
->vme_start
;
10066 assert(first_free_is_valid(dst_map
));
10067 start
= ((last
= dst_map
->first_free
) == vm_map_to_entry(dst_map
)) ?
10068 vm_map_min(dst_map
) : last
->vme_end
;
10070 start
= vm_map_round_page(start
,
10071 VM_MAP_PAGE_MASK(dst_map
));
10075 vm_map_entry_t next
= last
->vme_next
;
10076 vm_map_offset_t end
= start
+ size
;
10078 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
10079 if (dst_map
->wait_for_space
) {
10080 if (size
<= (dst_map
->max_offset
- dst_map
->min_offset
)) {
10081 assert_wait((event_t
) dst_map
,
10082 THREAD_INTERRUPTIBLE
);
10083 vm_map_unlock(dst_map
);
10084 thread_block(THREAD_CONTINUE_NULL
);
10088 vm_map_unlock(dst_map
);
10089 return(KERN_NO_SPACE
);
10092 if (dst_map
->holelistenabled
) {
10093 if (last
->vme_end
>= end
)
10097 * If there are no more entries, we must win.
10101 * If there is another entry, it must be
10102 * after the end of the potential new region.
10105 if (next
== vm_map_to_entry(dst_map
))
10108 if (next
->vme_start
>= end
)
10114 if (dst_map
->holelistenabled
) {
10115 if (last
== (vm_map_entry_t
) dst_map
->holes_list
) {
10119 vm_map_unlock(dst_map
);
10120 return(KERN_NO_SPACE
);
10122 start
= last
->vme_start
;
10124 start
= last
->vme_end
;
10126 start
= vm_map_round_page(start
,
10127 VM_MAP_PAGE_MASK(dst_map
));
10130 if (dst_map
->holelistenabled
) {
10131 if (vm_map_lookup_entry(dst_map
, last
->vme_start
, &last
)) {
10132 panic("Found an existing entry (%p) instead of potential hole at address: 0x%llx.\n", last
, (unsigned long long)last
->vme_start
);
10137 adjustment
= start
- vm_copy_start
;
10138 if (! consume_on_success
) {
10140 * We're not allowed to consume "copy", so we'll have to
10141 * copy its map entries into the destination map below.
10142 * No need to re-allocate map entries from the correct
10143 * (pageable or not) zone, since we'll get new map entries
10144 * during the transfer.
10145 * We'll also adjust the map entries's "start" and "end"
10146 * during the transfer, to keep "copy"'s entries consistent
10147 * with its "offset".
10149 goto after_adjustments
;
10153 * Since we're going to just drop the map
10154 * entries from the copy into the destination
10155 * map, they must come from the same pool.
10158 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
10160 * Mismatches occur when dealing with the default
10164 vm_map_entry_t next
, new;
10167 * Find the zone that the copies were allocated from
10170 entry
= vm_map_copy_first_entry(copy
);
10173 * Reinitialize the copy so that vm_map_copy_entry_link
10176 vm_map_store_copy_reset(copy
, entry
);
10177 copy
->cpy_hdr
.entries_pageable
= dst_map
->hdr
.entries_pageable
;
10182 while (entry
!= vm_map_copy_to_entry(copy
)) {
10183 new = vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
10184 vm_map_entry_copy_full(new, entry
);
10185 assert(!new->iokit_acct
);
10186 if (new->is_sub_map
) {
10187 /* clr address space specifics */
10188 new->use_pmap
= FALSE
;
10190 vm_map_copy_entry_link(copy
,
10191 vm_map_copy_last_entry(copy
),
10193 next
= entry
->vme_next
;
10194 old_zone
= entry
->from_reserved_zone
? vm_map_entry_reserved_zone
: vm_map_entry_zone
;
10195 zfree(old_zone
, entry
);
10201 * Adjust the addresses in the copy chain, and
10202 * reset the region attributes.
10205 for (entry
= vm_map_copy_first_entry(copy
);
10206 entry
!= vm_map_copy_to_entry(copy
);
10207 entry
= entry
->vme_next
) {
10208 if (VM_MAP_PAGE_SHIFT(dst_map
) == PAGE_SHIFT
) {
10210 * We're injecting this copy entry into a map that
10211 * has the standard page alignment, so clear
10212 * "map_aligned" (which might have been inherited
10213 * from the original map entry).
10215 entry
->map_aligned
= FALSE
;
10218 entry
->vme_start
+= adjustment
;
10219 entry
->vme_end
+= adjustment
;
10221 if (entry
->map_aligned
) {
10222 assert(VM_MAP_PAGE_ALIGNED(entry
->vme_start
,
10223 VM_MAP_PAGE_MASK(dst_map
)));
10224 assert(VM_MAP_PAGE_ALIGNED(entry
->vme_end
,
10225 VM_MAP_PAGE_MASK(dst_map
)));
10228 entry
->inheritance
= VM_INHERIT_DEFAULT
;
10229 entry
->protection
= VM_PROT_DEFAULT
;
10230 entry
->max_protection
= VM_PROT_ALL
;
10231 entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
10234 * If the entry is now wired,
10235 * map the pages into the destination map.
10237 if (entry
->wired_count
!= 0) {
10238 vm_map_offset_t va
;
10239 vm_object_offset_t offset
;
10240 vm_object_t object
;
10244 object
= VME_OBJECT(entry
);
10245 offset
= VME_OFFSET(entry
);
10246 va
= entry
->vme_start
;
10248 pmap_pageable(dst_map
->pmap
,
10253 while (va
< entry
->vme_end
) {
10257 * Look up the page in the object.
10258 * Assert that the page will be found in the
10261 * the object was newly created by
10262 * vm_object_copy_slowly, and has
10263 * copies of all of the pages from
10264 * the source object
10266 * the object was moved from the old
10267 * map entry; because the old map
10268 * entry was wired, all of the pages
10269 * were in the top-level object.
10270 * (XXX not true if we wire pages for
10273 vm_object_lock(object
);
10275 m
= vm_page_lookup(object
, offset
);
10276 if (m
== VM_PAGE_NULL
|| !VM_PAGE_WIRED(m
) ||
10278 panic("vm_map_copyout: wiring %p", m
);
10280 prot
= entry
->protection
;
10282 if (override_nx(dst_map
, VME_ALIAS(entry
)) &&
10284 prot
|= VM_PROT_EXECUTE
;
10286 type_of_fault
= DBG_CACHE_HIT_FAULT
;
10288 vm_fault_enter(m
, dst_map
->pmap
, va
, prot
, prot
,
10290 FALSE
, /* change_wiring */
10291 VM_KERN_MEMORY_NONE
, /* tag - not wiring */
10292 FALSE
, /* no_cache */
10293 FALSE
, /* cs_bypass */
10295 ((entry
->iokit_acct
||
10296 (!entry
->is_sub_map
&&
10298 ? PMAP_OPTIONS_ALT_ACCT
10299 : 0), /* pmap_options */
10300 NULL
, /* need_retry */
10303 vm_object_unlock(object
);
10305 offset
+= PAGE_SIZE_64
;
10314 * Correct the page alignment for the result
10317 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
10320 kasan_notify_address(*dst_addr
, size
);
10324 * Update the hints and the map size
10327 if (consume_on_success
) {
10328 SAVE_HINT_MAP_WRITE(dst_map
, vm_map_copy_last_entry(copy
));
10330 SAVE_HINT_MAP_WRITE(dst_map
, last
);
10333 dst_map
->size
+= size
;
10339 if (consume_on_success
) {
10340 vm_map_copy_insert(dst_map
, last
, copy
);
10342 vm_map_copy_remap(dst_map
, last
, copy
, adjustment
,
10343 cur_protection
, max_protection
,
10347 vm_map_unlock(dst_map
);
10350 * XXX If wiring_required, call vm_map_pageable
10353 return(KERN_SUCCESS
);
10357 * Routine: vm_map_copyin
10360 * see vm_map_copyin_common. Exported via Unsupported.exports.
10364 #undef vm_map_copyin
10369 vm_map_address_t src_addr
,
10371 boolean_t src_destroy
,
10372 vm_map_copy_t
*copy_result
) /* OUT */
10374 return(vm_map_copyin_common(src_map
, src_addr
, len
, src_destroy
,
10375 FALSE
, copy_result
, FALSE
));
10379 * Routine: vm_map_copyin_common
10382 * Copy the specified region (src_addr, len) from the
10383 * source address space (src_map), possibly removing
10384 * the region from the source address space (src_destroy).
10387 * A vm_map_copy_t object (copy_result), suitable for
10388 * insertion into another address space (using vm_map_copyout),
10389 * copying over another address space region (using
10390 * vm_map_copy_overwrite). If the copy is unused, it
10391 * should be destroyed (using vm_map_copy_discard).
10393 * In/out conditions:
10394 * The source map should not be locked on entry.
10397 typedef struct submap_map
{
10398 vm_map_t parent_map
;
10399 vm_map_offset_t base_start
;
10400 vm_map_offset_t base_end
;
10401 vm_map_size_t base_len
;
10402 struct submap_map
*next
;
10406 vm_map_copyin_common(
10408 vm_map_address_t src_addr
,
10410 boolean_t src_destroy
,
10411 __unused boolean_t src_volatile
,
10412 vm_map_copy_t
*copy_result
, /* OUT */
10413 boolean_t use_maxprot
)
10419 flags
|= VM_MAP_COPYIN_SRC_DESTROY
;
10422 flags
|= VM_MAP_COPYIN_USE_MAXPROT
;
10424 return vm_map_copyin_internal(src_map
,
10431 vm_map_copyin_internal(
10433 vm_map_address_t src_addr
,
10436 vm_map_copy_t
*copy_result
) /* OUT */
10438 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
10439 * in multi-level lookup, this
10440 * entry contains the actual
10441 * vm_object/offset.
10443 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
10445 vm_map_offset_t src_start
; /* Start of current entry --
10446 * where copy is taking place now
10448 vm_map_offset_t src_end
; /* End of entire region to be
10450 vm_map_offset_t src_base
;
10451 vm_map_t base_map
= src_map
;
10452 boolean_t map_share
=FALSE
;
10453 submap_map_t
*parent_maps
= NULL
;
10455 vm_map_copy_t copy
; /* Resulting copy */
10456 vm_map_address_t copy_addr
;
10457 vm_map_size_t copy_size
;
10458 boolean_t src_destroy
;
10459 boolean_t use_maxprot
;
10460 boolean_t preserve_purgeable
;
10461 boolean_t entry_was_shared
;
10462 vm_map_entry_t saved_src_entry
;
10464 if (flags
& ~VM_MAP_COPYIN_ALL_FLAGS
) {
10465 return KERN_INVALID_ARGUMENT
;
10468 src_destroy
= (flags
& VM_MAP_COPYIN_SRC_DESTROY
) ? TRUE
: FALSE
;
10469 use_maxprot
= (flags
& VM_MAP_COPYIN_USE_MAXPROT
) ? TRUE
: FALSE
;
10470 preserve_purgeable
=
10471 (flags
& VM_MAP_COPYIN_PRESERVE_PURGEABLE
) ? TRUE
: FALSE
;
10474 * Check for copies of zero bytes.
10478 *copy_result
= VM_MAP_COPY_NULL
;
10479 return(KERN_SUCCESS
);
10483 * Check that the end address doesn't overflow
10485 src_end
= src_addr
+ len
;
10486 if (src_end
< src_addr
)
10487 return KERN_INVALID_ADDRESS
;
10490 * Compute (page aligned) start and end of region
10492 src_start
= vm_map_trunc_page(src_addr
,
10493 VM_MAP_PAGE_MASK(src_map
));
10494 src_end
= vm_map_round_page(src_end
,
10495 VM_MAP_PAGE_MASK(src_map
));
10498 * If the copy is sufficiently small, use a kernel buffer instead
10499 * of making a virtual copy. The theory being that the cost of
10500 * setting up VM (and taking C-O-W faults) dominates the copy costs
10501 * for small regions.
10503 if ((len
< msg_ool_size_small
) &&
10505 !preserve_purgeable
&&
10506 !(flags
& VM_MAP_COPYIN_ENTRY_LIST
) &&
10508 * Since the "msg_ool_size_small" threshold was increased and
10509 * vm_map_copyin_kernel_buffer() doesn't handle accesses beyond the
10510 * address space limits, we revert to doing a virtual copy if the
10511 * copied range goes beyond those limits. Otherwise, mach_vm_read()
10512 * of the commpage would now fail when it used to work.
10514 (src_start
>= vm_map_min(src_map
) &&
10515 src_start
< vm_map_max(src_map
) &&
10516 src_end
>= vm_map_min(src_map
) &&
10517 src_end
< vm_map_max(src_map
)))
10518 return vm_map_copyin_kernel_buffer(src_map
, src_addr
, len
,
10519 src_destroy
, copy_result
);
10521 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);
10524 * Allocate a header element for the list.
10526 * Use the start and end in the header to
10527 * remember the endpoints prior to rounding.
10530 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
10531 copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
10532 vm_map_copy_first_entry(copy
) =
10533 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
10534 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
10535 copy
->cpy_hdr
.nentries
= 0;
10536 copy
->cpy_hdr
.entries_pageable
= TRUE
;
10538 copy
->cpy_hdr
.page_shift
= src_map
->hdr
.page_shift
;
10541 * The copy entries can be broken down for a variety of reasons,
10542 * so we can't guarantee that they will remain map-aligned...
10543 * Will need to adjust the first copy_entry's "vme_start" and
10544 * the last copy_entry's "vme_end" to be rounded to PAGE_MASK
10545 * rather than the original map's alignment.
10547 copy
->cpy_hdr
.page_shift
= PAGE_SHIFT
;
10550 vm_map_store_init( &(copy
->cpy_hdr
) );
10552 copy
->offset
= src_addr
;
10555 new_entry
= vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
10557 #define RETURN(x) \
10559 vm_map_unlock(src_map); \
10560 if(src_map != base_map) \
10561 vm_map_deallocate(src_map); \
10562 if (new_entry != VM_MAP_ENTRY_NULL) \
10563 vm_map_copy_entry_dispose(copy,new_entry); \
10564 vm_map_copy_discard(copy); \
10566 submap_map_t *_ptr; \
10568 for(_ptr = parent_maps; _ptr != NULL; _ptr = parent_maps) { \
10569 parent_maps=parent_maps->next; \
10570 if (_ptr->parent_map != base_map) \
10571 vm_map_deallocate(_ptr->parent_map); \
10572 kfree(_ptr, sizeof(submap_map_t)); \
10579 * Find the beginning of the region.
10582 vm_map_lock(src_map
);
10585 * Lookup the original "src_addr" rather than the truncated
10586 * "src_start", in case "src_start" falls in a non-map-aligned
10587 * map entry *before* the map entry that contains "src_addr"...
10589 if (!vm_map_lookup_entry(src_map
, src_addr
, &tmp_entry
))
10590 RETURN(KERN_INVALID_ADDRESS
);
10591 if(!tmp_entry
->is_sub_map
) {
10593 * ... but clip to the map-rounded "src_start" rather than
10594 * "src_addr" to preserve map-alignment. We'll adjust the
10595 * first copy entry at the end, if needed.
10597 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
10599 if (src_start
< tmp_entry
->vme_start
) {
10601 * Move "src_start" up to the start of the
10602 * first map entry to copy.
10604 src_start
= tmp_entry
->vme_start
;
10606 /* set for later submap fix-up */
10607 copy_addr
= src_start
;
10610 * Go through entries until we get to the end.
10614 vm_map_entry_t src_entry
= tmp_entry
; /* Top-level entry */
10615 vm_map_size_t src_size
; /* Size of source
10616 * map entry (in both
10620 vm_object_t src_object
; /* Object to copy */
10621 vm_object_offset_t src_offset
;
10623 boolean_t src_needs_copy
; /* Should source map
10624 * be made read-only
10625 * for copy-on-write?
10628 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
10630 boolean_t was_wired
; /* Was source wired? */
10631 vm_map_version_t version
; /* Version before locks
10632 * dropped to make copy
10634 kern_return_t result
; /* Return value from
10635 * copy_strategically.
10637 while(tmp_entry
->is_sub_map
) {
10638 vm_map_size_t submap_len
;
10641 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
10642 ptr
->next
= parent_maps
;
10644 ptr
->parent_map
= src_map
;
10645 ptr
->base_start
= src_start
;
10646 ptr
->base_end
= src_end
;
10647 submap_len
= tmp_entry
->vme_end
- src_start
;
10648 if(submap_len
> (src_end
-src_start
))
10649 submap_len
= src_end
-src_start
;
10650 ptr
->base_len
= submap_len
;
10652 src_start
-= tmp_entry
->vme_start
;
10653 src_start
+= VME_OFFSET(tmp_entry
);
10654 src_end
= src_start
+ submap_len
;
10655 src_map
= VME_SUBMAP(tmp_entry
);
10656 vm_map_lock(src_map
);
10657 /* keep an outstanding reference for all maps in */
10658 /* the parents tree except the base map */
10659 vm_map_reference(src_map
);
10660 vm_map_unlock(ptr
->parent_map
);
10661 if (!vm_map_lookup_entry(
10662 src_map
, src_start
, &tmp_entry
))
10663 RETURN(KERN_INVALID_ADDRESS
);
10665 if(!tmp_entry
->is_sub_map
)
10666 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
10667 src_entry
= tmp_entry
;
10669 /* we are now in the lowest level submap... */
10671 if ((VME_OBJECT(tmp_entry
) != VM_OBJECT_NULL
) &&
10672 (VME_OBJECT(tmp_entry
)->phys_contiguous
)) {
10673 /* This is not, supported for now.In future */
10674 /* we will need to detect the phys_contig */
10675 /* condition and then upgrade copy_slowly */
10676 /* to do physical copy from the device mem */
10677 /* based object. We can piggy-back off of */
10678 /* the was wired boolean to set-up the */
10679 /* proper handling */
10680 RETURN(KERN_PROTECTION_FAILURE
);
10683 * Create a new address map entry to hold the result.
10684 * Fill in the fields from the appropriate source entries.
10685 * We must unlock the source map to do this if we need
10686 * to allocate a map entry.
10688 if (new_entry
== VM_MAP_ENTRY_NULL
) {
10689 version
.main_timestamp
= src_map
->timestamp
;
10690 vm_map_unlock(src_map
);
10692 new_entry
= vm_map_copy_entry_create(copy
, !copy
->cpy_hdr
.entries_pageable
);
10694 vm_map_lock(src_map
);
10695 if ((version
.main_timestamp
+ 1) != src_map
->timestamp
) {
10696 if (!vm_map_lookup_entry(src_map
, src_start
,
10698 RETURN(KERN_INVALID_ADDRESS
);
10700 if (!tmp_entry
->is_sub_map
)
10701 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
10702 continue; /* restart w/ new tmp_entry */
10707 * Verify that the region can be read.
10709 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
10711 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
10712 RETURN(KERN_PROTECTION_FAILURE
);
10715 * Clip against the endpoints of the entire region.
10718 vm_map_clip_end(src_map
, src_entry
, src_end
);
10720 src_size
= src_entry
->vme_end
- src_start
;
10721 src_object
= VME_OBJECT(src_entry
);
10722 src_offset
= VME_OFFSET(src_entry
);
10723 was_wired
= (src_entry
->wired_count
!= 0);
10725 vm_map_entry_copy(new_entry
, src_entry
);
10726 if (new_entry
->is_sub_map
) {
10727 /* clr address space specifics */
10728 new_entry
->use_pmap
= FALSE
;
10732 * Attempt non-blocking copy-on-write optimizations.
10736 (src_object
== VM_OBJECT_NULL
||
10737 (src_object
->internal
&&
10738 src_object
->copy_strategy
!= MEMORY_OBJECT_COPY_DELAY
&&
10739 !src_object
->true_share
&&
10742 * If we are destroying the source, and the object
10743 * is internal, we can move the object reference
10744 * from the source to the copy. The copy is
10745 * copy-on-write only if the source is.
10746 * We make another reference to the object, because
10747 * destroying the source entry will deallocate it.
10749 vm_object_reference(src_object
);
10752 * Copy is always unwired. vm_map_copy_entry
10753 * set its wired count to zero.
10756 goto CopySuccessful
;
10761 XPR(XPR_VM_MAP
, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
10762 src_object
, new_entry
, VME_OBJECT(new_entry
),
10764 if ((src_object
== VM_OBJECT_NULL
||
10765 (!was_wired
&& !map_share
&& !tmp_entry
->is_shared
)) &&
10766 vm_object_copy_quickly(
10767 &VME_OBJECT(new_entry
),
10771 &new_entry_needs_copy
)) {
10773 new_entry
->needs_copy
= new_entry_needs_copy
;
10776 * Handle copy-on-write obligations
10779 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
10782 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
10784 if (override_nx(src_map
, VME_ALIAS(src_entry
))
10786 prot
|= VM_PROT_EXECUTE
;
10788 vm_object_pmap_protect(
10792 (src_entry
->is_shared
?
10795 src_entry
->vme_start
,
10798 assert(tmp_entry
->wired_count
== 0);
10799 tmp_entry
->needs_copy
= TRUE
;
10803 * The map has never been unlocked, so it's safe
10804 * to move to the next entry rather than doing
10808 goto CopySuccessful
;
10811 entry_was_shared
= tmp_entry
->is_shared
;
10814 * Take an object reference, so that we may
10815 * release the map lock(s).
10818 assert(src_object
!= VM_OBJECT_NULL
);
10819 vm_object_reference(src_object
);
10822 * Record the timestamp for later verification.
10826 version
.main_timestamp
= src_map
->timestamp
;
10827 vm_map_unlock(src_map
); /* Increments timestamp once! */
10828 saved_src_entry
= src_entry
;
10829 tmp_entry
= VM_MAP_ENTRY_NULL
;
10830 src_entry
= VM_MAP_ENTRY_NULL
;
10838 vm_object_lock(src_object
);
10839 result
= vm_object_copy_slowly(
10844 &VME_OBJECT(new_entry
));
10845 VME_OFFSET_SET(new_entry
, 0);
10846 new_entry
->needs_copy
= FALSE
;
10849 else if (src_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
10850 (entry_was_shared
|| map_share
)) {
10851 vm_object_t new_object
;
10853 vm_object_lock_shared(src_object
);
10854 new_object
= vm_object_copy_delayed(
10859 if (new_object
== VM_OBJECT_NULL
)
10862 VME_OBJECT_SET(new_entry
, new_object
);
10863 assert(new_entry
->wired_count
== 0);
10864 new_entry
->needs_copy
= TRUE
;
10865 assert(!new_entry
->iokit_acct
);
10866 assert(new_object
->purgable
== VM_PURGABLE_DENY
);
10867 new_entry
->use_pmap
= TRUE
;
10868 result
= KERN_SUCCESS
;
10871 vm_object_offset_t new_offset
;
10872 new_offset
= VME_OFFSET(new_entry
);
10873 result
= vm_object_copy_strategically(src_object
,
10876 &VME_OBJECT(new_entry
),
10878 &new_entry_needs_copy
);
10879 if (new_offset
!= VME_OFFSET(new_entry
)) {
10880 VME_OFFSET_SET(new_entry
, new_offset
);
10883 new_entry
->needs_copy
= new_entry_needs_copy
;
10886 if (result
== KERN_SUCCESS
&&
10887 preserve_purgeable
&&
10888 src_object
->purgable
!= VM_PURGABLE_DENY
) {
10889 vm_object_t new_object
;
10891 new_object
= VME_OBJECT(new_entry
);
10892 assert(new_object
!= src_object
);
10893 vm_object_lock(new_object
);
10894 assert(new_object
->ref_count
== 1);
10895 assert(new_object
->shadow
== VM_OBJECT_NULL
);
10896 assert(new_object
->copy
== VM_OBJECT_NULL
);
10897 assert(new_object
->vo_purgeable_owner
== NULL
);
10899 new_object
->copy_strategy
= MEMORY_OBJECT_COPY_NONE
;
10900 new_object
->true_share
= TRUE
;
10901 /* start as non-volatile with no owner... */
10902 new_object
->purgable
= VM_PURGABLE_NONVOLATILE
;
10903 vm_purgeable_nonvolatile_enqueue(new_object
, NULL
);
10904 /* ... and move to src_object's purgeable state */
10905 if (src_object
->purgable
!= VM_PURGABLE_NONVOLATILE
) {
10907 state
= src_object
->purgable
;
10908 vm_object_purgable_control(
10910 VM_PURGABLE_SET_STATE_FROM_KERNEL
,
10913 vm_object_unlock(new_object
);
10914 new_object
= VM_OBJECT_NULL
;
10917 if (result
!= KERN_SUCCESS
&&
10918 result
!= KERN_MEMORY_RESTART_COPY
) {
10919 vm_map_lock(src_map
);
10924 * Throw away the extra reference
10927 vm_object_deallocate(src_object
);
10930 * Verify that the map has not substantially
10931 * changed while the copy was being made.
10934 vm_map_lock(src_map
);
10936 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
) {
10937 /* src_map hasn't changed: src_entry is still valid */
10938 src_entry
= saved_src_entry
;
10939 goto VerificationSuccessful
;
10943 * Simple version comparison failed.
10945 * Retry the lookup and verify that the
10946 * same object/offset are still present.
10948 * [Note: a memory manager that colludes with
10949 * the calling task can detect that we have
10950 * cheated. While the map was unlocked, the
10951 * mapping could have been changed and restored.]
10954 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
10955 if (result
!= KERN_MEMORY_RESTART_COPY
) {
10956 vm_object_deallocate(VME_OBJECT(new_entry
));
10957 VME_OBJECT_SET(new_entry
, VM_OBJECT_NULL
);
10958 assert(!new_entry
->iokit_acct
);
10959 new_entry
->use_pmap
= TRUE
;
10961 RETURN(KERN_INVALID_ADDRESS
);
10964 src_entry
= tmp_entry
;
10965 vm_map_clip_start(src_map
, src_entry
, src_start
);
10967 if ((((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
) &&
10969 ((src_entry
->max_protection
& VM_PROT_READ
) == 0))
10970 goto VerificationFailed
;
10972 if (src_entry
->vme_end
< new_entry
->vme_end
) {
10974 * This entry might have been shortened
10975 * (vm_map_clip_end) or been replaced with
10976 * an entry that ends closer to "src_start"
10978 * Adjust "new_entry" accordingly; copying
10979 * less memory would be correct but we also
10980 * redo the copy (see below) if the new entry
10981 * no longer points at the same object/offset.
10983 assert(VM_MAP_PAGE_ALIGNED(src_entry
->vme_end
,
10984 VM_MAP_COPY_PAGE_MASK(copy
)));
10985 new_entry
->vme_end
= src_entry
->vme_end
;
10986 src_size
= new_entry
->vme_end
- src_start
;
10987 } else if (src_entry
->vme_end
> new_entry
->vme_end
) {
10989 * This entry might have been extended
10990 * (vm_map_entry_simplify() or coalesce)
10991 * or been replaced with an entry that ends farther
10992 * from "src_start" than before.
10994 * We've called vm_object_copy_*() only on
10995 * the previous <start:end> range, so we can't
10996 * just extend new_entry. We have to re-do
10997 * the copy based on the new entry as if it was
10998 * pointing at a different object/offset (see
10999 * "Verification failed" below).
11003 if ((VME_OBJECT(src_entry
) != src_object
) ||
11004 (VME_OFFSET(src_entry
) != src_offset
) ||
11005 (src_entry
->vme_end
> new_entry
->vme_end
)) {
11008 * Verification failed.
11010 * Start over with this top-level entry.
11013 VerificationFailed
: ;
11015 vm_object_deallocate(VME_OBJECT(new_entry
));
11016 tmp_entry
= src_entry
;
11021 * Verification succeeded.
11024 VerificationSuccessful
: ;
11026 if (result
== KERN_MEMORY_RESTART_COPY
)
11036 * Link in the new copy entry.
11039 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
11043 * Determine whether the entire region
11046 src_base
= src_start
;
11047 src_start
= new_entry
->vme_end
;
11048 new_entry
= VM_MAP_ENTRY_NULL
;
11049 while ((src_start
>= src_end
) && (src_end
!= 0)) {
11052 if (src_map
== base_map
) {
11053 /* back to the top */
11058 assert(ptr
!= NULL
);
11059 parent_maps
= parent_maps
->next
;
11061 /* fix up the damage we did in that submap */
11062 vm_map_simplify_range(src_map
,
11066 vm_map_unlock(src_map
);
11067 vm_map_deallocate(src_map
);
11068 vm_map_lock(ptr
->parent_map
);
11069 src_map
= ptr
->parent_map
;
11070 src_base
= ptr
->base_start
;
11071 src_start
= ptr
->base_start
+ ptr
->base_len
;
11072 src_end
= ptr
->base_end
;
11073 if (!vm_map_lookup_entry(src_map
,
11076 (src_end
> src_start
)) {
11077 RETURN(KERN_INVALID_ADDRESS
);
11079 kfree(ptr
, sizeof(submap_map_t
));
11080 if (parent_maps
== NULL
)
11082 src_entry
= tmp_entry
->vme_prev
;
11085 if ((VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
) &&
11086 (src_start
>= src_addr
+ len
) &&
11087 (src_addr
+ len
!= 0)) {
11089 * Stop copying now, even though we haven't reached
11090 * "src_end". We'll adjust the end of the last copy
11091 * entry at the end, if needed.
11093 * If src_map's aligment is different from the
11094 * system's page-alignment, there could be
11095 * extra non-map-aligned map entries between
11096 * the original (non-rounded) "src_addr + len"
11097 * and the rounded "src_end".
11098 * We do not want to copy those map entries since
11099 * they're not part of the copied range.
11104 if ((src_start
>= src_end
) && (src_end
!= 0))
11108 * Verify that there are no gaps in the region
11111 tmp_entry
= src_entry
->vme_next
;
11112 if ((tmp_entry
->vme_start
!= src_start
) ||
11113 (tmp_entry
== vm_map_to_entry(src_map
))) {
11114 RETURN(KERN_INVALID_ADDRESS
);
11119 * If the source should be destroyed, do it now, since the
11120 * copy was successful.
11123 (void) vm_map_delete(
11125 vm_map_trunc_page(src_addr
,
11126 VM_MAP_PAGE_MASK(src_map
)),
11128 ((src_map
== kernel_map
) ?
11129 VM_MAP_REMOVE_KUNWIRE
:
11133 /* fix up the damage we did in the base map */
11134 vm_map_simplify_range(
11136 vm_map_trunc_page(src_addr
,
11137 VM_MAP_PAGE_MASK(src_map
)),
11138 vm_map_round_page(src_end
,
11139 VM_MAP_PAGE_MASK(src_map
)));
11142 vm_map_unlock(src_map
);
11143 tmp_entry
= VM_MAP_ENTRY_NULL
;
11145 if (VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
) {
11146 vm_map_offset_t original_start
, original_offset
, original_end
;
11148 assert(VM_MAP_COPY_PAGE_MASK(copy
) == PAGE_MASK
);
11150 /* adjust alignment of first copy_entry's "vme_start" */
11151 tmp_entry
= vm_map_copy_first_entry(copy
);
11152 if (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
11153 vm_map_offset_t adjustment
;
11155 original_start
= tmp_entry
->vme_start
;
11156 original_offset
= VME_OFFSET(tmp_entry
);
11158 /* map-align the start of the first copy entry... */
11159 adjustment
= (tmp_entry
->vme_start
-
11161 tmp_entry
->vme_start
,
11162 VM_MAP_PAGE_MASK(src_map
)));
11163 tmp_entry
->vme_start
-= adjustment
;
11164 VME_OFFSET_SET(tmp_entry
,
11165 VME_OFFSET(tmp_entry
) - adjustment
);
11166 copy_addr
-= adjustment
;
11167 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
11168 /* ... adjust for mis-aligned start of copy range */
11170 (vm_map_trunc_page(copy
->offset
,
11172 vm_map_trunc_page(copy
->offset
,
11173 VM_MAP_PAGE_MASK(src_map
)));
11175 assert(page_aligned(adjustment
));
11176 assert(adjustment
< VM_MAP_PAGE_SIZE(src_map
));
11177 tmp_entry
->vme_start
+= adjustment
;
11178 VME_OFFSET_SET(tmp_entry
,
11179 (VME_OFFSET(tmp_entry
) +
11181 copy_addr
+= adjustment
;
11182 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
11186 * Assert that the adjustments haven't exposed
11187 * more than was originally copied...
11189 assert(tmp_entry
->vme_start
>= original_start
);
11190 assert(VME_OFFSET(tmp_entry
) >= original_offset
);
11192 * ... and that it did not adjust outside of a
11193 * a single 16K page.
11195 assert(vm_map_trunc_page(tmp_entry
->vme_start
,
11196 VM_MAP_PAGE_MASK(src_map
)) ==
11197 vm_map_trunc_page(original_start
,
11198 VM_MAP_PAGE_MASK(src_map
)));
11201 /* adjust alignment of last copy_entry's "vme_end" */
11202 tmp_entry
= vm_map_copy_last_entry(copy
);
11203 if (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
11204 vm_map_offset_t adjustment
;
11206 original_end
= tmp_entry
->vme_end
;
11208 /* map-align the end of the last copy entry... */
11209 tmp_entry
->vme_end
=
11210 vm_map_round_page(tmp_entry
->vme_end
,
11211 VM_MAP_PAGE_MASK(src_map
));
11212 /* ... adjust for mis-aligned end of copy range */
11214 (vm_map_round_page((copy
->offset
+
11216 VM_MAP_PAGE_MASK(src_map
)) -
11217 vm_map_round_page((copy
->offset
+
11221 assert(page_aligned(adjustment
));
11222 assert(adjustment
< VM_MAP_PAGE_SIZE(src_map
));
11223 tmp_entry
->vme_end
-= adjustment
;
11224 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
11228 * Assert that the adjustments haven't exposed
11229 * more than was originally copied...
11231 assert(tmp_entry
->vme_end
<= original_end
);
11233 * ... and that it did not adjust outside of a
11234 * a single 16K page.
11236 assert(vm_map_round_page(tmp_entry
->vme_end
,
11237 VM_MAP_PAGE_MASK(src_map
)) ==
11238 vm_map_round_page(original_end
,
11239 VM_MAP_PAGE_MASK(src_map
)));
11243 /* Fix-up start and end points in copy. This is necessary */
11244 /* when the various entries in the copy object were picked */
11245 /* up from different sub-maps */
11247 tmp_entry
= vm_map_copy_first_entry(copy
);
11248 copy_size
= 0; /* compute actual size */
11249 while (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
11250 assert(VM_MAP_PAGE_ALIGNED(
11251 copy_addr
+ (tmp_entry
->vme_end
-
11252 tmp_entry
->vme_start
),
11253 VM_MAP_COPY_PAGE_MASK(copy
)));
11254 assert(VM_MAP_PAGE_ALIGNED(
11256 VM_MAP_COPY_PAGE_MASK(copy
)));
11259 * The copy_entries will be injected directly into the
11260 * destination map and might not be "map aligned" there...
11262 tmp_entry
->map_aligned
= FALSE
;
11264 tmp_entry
->vme_end
= copy_addr
+
11265 (tmp_entry
->vme_end
- tmp_entry
->vme_start
);
11266 tmp_entry
->vme_start
= copy_addr
;
11267 assert(tmp_entry
->vme_start
< tmp_entry
->vme_end
);
11268 copy_addr
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
11269 copy_size
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
11270 tmp_entry
= (struct vm_map_entry
*)tmp_entry
->vme_next
;
11273 if (VM_MAP_PAGE_SHIFT(src_map
) != PAGE_SHIFT
&&
11274 copy_size
< copy
->size
) {
11276 * The actual size of the VM map copy is smaller than what
11277 * was requested by the caller. This must be because some
11278 * PAGE_SIZE-sized pages are missing at the end of the last
11279 * VM_MAP_PAGE_SIZE(src_map)-sized chunk of the range.
11280 * The caller might not have been aware of those missing
11281 * pages and might not want to be aware of it, which is
11282 * fine as long as they don't try to access (and crash on)
11283 * those missing pages.
11284 * Let's adjust the size of the "copy", to avoid failing
11285 * in vm_map_copyout() or vm_map_copy_overwrite().
11287 assert(vm_map_round_page(copy_size
,
11288 VM_MAP_PAGE_MASK(src_map
)) ==
11289 vm_map_round_page(copy
->size
,
11290 VM_MAP_PAGE_MASK(src_map
)));
11291 copy
->size
= copy_size
;
11294 *copy_result
= copy
;
11295 return(KERN_SUCCESS
);
11301 vm_map_copy_extract(
11303 vm_map_address_t src_addr
,
11305 vm_map_copy_t
*copy_result
, /* OUT */
11306 vm_prot_t
*cur_prot
, /* OUT */
11307 vm_prot_t
*max_prot
)
11309 vm_map_offset_t src_start
, src_end
;
11310 vm_map_copy_t copy
;
11314 * Check for copies of zero bytes.
11318 *copy_result
= VM_MAP_COPY_NULL
;
11319 return(KERN_SUCCESS
);
11323 * Check that the end address doesn't overflow
11325 src_end
= src_addr
+ len
;
11326 if (src_end
< src_addr
)
11327 return KERN_INVALID_ADDRESS
;
11330 * Compute (page aligned) start and end of region
11332 src_start
= vm_map_trunc_page(src_addr
, PAGE_MASK
);
11333 src_end
= vm_map_round_page(src_end
, PAGE_MASK
);
11336 * Allocate a header element for the list.
11338 * Use the start and end in the header to
11339 * remember the endpoints prior to rounding.
11342 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
11343 copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
11344 vm_map_copy_first_entry(copy
) =
11345 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
11346 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
11347 copy
->cpy_hdr
.nentries
= 0;
11348 copy
->cpy_hdr
.entries_pageable
= TRUE
;
11350 vm_map_store_init(©
->cpy_hdr
);
11355 kr
= vm_map_remap_extract(src_map
,
11363 TRUE
, /* pageable */
11364 FALSE
, /* same_map */
11365 VM_MAP_KERNEL_FLAGS_NONE
);
11366 if (kr
!= KERN_SUCCESS
) {
11367 vm_map_copy_discard(copy
);
11371 *copy_result
= copy
;
11372 return KERN_SUCCESS
;
11376 * vm_map_copyin_object:
11378 * Create a copy object from an object.
11379 * Our caller donates an object reference.
11383 vm_map_copyin_object(
11384 vm_object_t object
,
11385 vm_object_offset_t offset
, /* offset of region in object */
11386 vm_object_size_t size
, /* size of region in object */
11387 vm_map_copy_t
*copy_result
) /* OUT */
11389 vm_map_copy_t copy
; /* Resulting copy */
11392 * We drop the object into a special copy object
11393 * that contains the object directly.
11396 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
11397 copy
->c_u
.hdr
.rb_head_store
.rbh_root
= (void*)(int)SKIP_RB_TREE
;
11398 copy
->type
= VM_MAP_COPY_OBJECT
;
11399 copy
->cpy_object
= object
;
11400 copy
->offset
= offset
;
11403 *copy_result
= copy
;
11404 return(KERN_SUCCESS
);
11410 vm_map_entry_t old_entry
,
11413 vm_object_t object
;
11414 vm_map_entry_t new_entry
;
11417 * New sharing code. New map entry
11418 * references original object. Internal
11419 * objects use asynchronous copy algorithm for
11420 * future copies. First make sure we have
11421 * the right object. If we need a shadow,
11422 * or someone else already has one, then
11423 * make a new shadow and share it.
11426 object
= VME_OBJECT(old_entry
);
11427 if (old_entry
->is_sub_map
) {
11428 assert(old_entry
->wired_count
== 0);
11429 #ifndef NO_NESTED_PMAP
11430 if(old_entry
->use_pmap
) {
11431 kern_return_t result
;
11433 result
= pmap_nest(new_map
->pmap
,
11434 (VME_SUBMAP(old_entry
))->pmap
,
11435 (addr64_t
)old_entry
->vme_start
,
11436 (addr64_t
)old_entry
->vme_start
,
11437 (uint64_t)(old_entry
->vme_end
- old_entry
->vme_start
));
11439 panic("vm_map_fork_share: pmap_nest failed!");
11441 #endif /* NO_NESTED_PMAP */
11442 } else if (object
== VM_OBJECT_NULL
) {
11443 object
= vm_object_allocate((vm_map_size_t
)(old_entry
->vme_end
-
11444 old_entry
->vme_start
));
11445 VME_OFFSET_SET(old_entry
, 0);
11446 VME_OBJECT_SET(old_entry
, object
);
11447 old_entry
->use_pmap
= TRUE
;
11448 } else if (object
->copy_strategy
!=
11449 MEMORY_OBJECT_COPY_SYMMETRIC
) {
11452 * We are already using an asymmetric
11453 * copy, and therefore we already have
11454 * the right object.
11457 assert(! old_entry
->needs_copy
);
11459 else if (old_entry
->needs_copy
|| /* case 1 */
11460 object
->shadowed
|| /* case 2 */
11461 (!object
->true_share
&& /* case 3 */
11462 !old_entry
->is_shared
&&
11464 (vm_map_size_t
)(old_entry
->vme_end
-
11465 old_entry
->vme_start
)))) {
11468 * We need to create a shadow.
11469 * There are three cases here.
11470 * In the first case, we need to
11471 * complete a deferred symmetrical
11472 * copy that we participated in.
11473 * In the second and third cases,
11474 * we need to create the shadow so
11475 * that changes that we make to the
11476 * object do not interfere with
11477 * any symmetrical copies which
11478 * have occured (case 2) or which
11479 * might occur (case 3).
11481 * The first case is when we had
11482 * deferred shadow object creation
11483 * via the entry->needs_copy mechanism.
11484 * This mechanism only works when
11485 * only one entry points to the source
11486 * object, and we are about to create
11487 * a second entry pointing to the
11488 * same object. The problem is that
11489 * there is no way of mapping from
11490 * an object to the entries pointing
11491 * to it. (Deferred shadow creation
11492 * works with one entry because occurs
11493 * at fault time, and we walk from the
11494 * entry to the object when handling
11497 * The second case is when the object
11498 * to be shared has already been copied
11499 * with a symmetric copy, but we point
11500 * directly to the object without
11501 * needs_copy set in our entry. (This
11502 * can happen because different ranges
11503 * of an object can be pointed to by
11504 * different entries. In particular,
11505 * a single entry pointing to an object
11506 * can be split by a call to vm_inherit,
11507 * which, combined with task_create, can
11508 * result in the different entries
11509 * having different needs_copy values.)
11510 * The shadowed flag in the object allows
11511 * us to detect this case. The problem
11512 * with this case is that if this object
11513 * has or will have shadows, then we
11514 * must not perform an asymmetric copy
11515 * of this object, since such a copy
11516 * allows the object to be changed, which
11517 * will break the previous symmetrical
11518 * copies (which rely upon the object
11519 * not changing). In a sense, the shadowed
11520 * flag says "don't change this object".
11521 * We fix this by creating a shadow
11522 * object for this object, and sharing
11523 * that. This works because we are free
11524 * to change the shadow object (and thus
11525 * to use an asymmetric copy strategy);
11526 * this is also semantically correct,
11527 * since this object is temporary, and
11528 * therefore a copy of the object is
11529 * as good as the object itself. (This
11530 * is not true for permanent objects,
11531 * since the pager needs to see changes,
11532 * which won't happen if the changes
11533 * are made to a copy.)
11535 * The third case is when the object
11536 * to be shared has parts sticking
11537 * outside of the entry we're working
11538 * with, and thus may in the future
11539 * be subject to a symmetrical copy.
11540 * (This is a preemptive version of
11543 VME_OBJECT_SHADOW(old_entry
,
11544 (vm_map_size_t
) (old_entry
->vme_end
-
11545 old_entry
->vme_start
));
11548 * If we're making a shadow for other than
11549 * copy on write reasons, then we have
11550 * to remove write permission.
11553 if (!old_entry
->needs_copy
&&
11554 (old_entry
->protection
& VM_PROT_WRITE
)) {
11557 assert(!pmap_has_prot_policy(old_entry
->protection
));
11559 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
11561 assert(!pmap_has_prot_policy(prot
));
11563 if (override_nx(old_map
, VME_ALIAS(old_entry
)) && prot
)
11564 prot
|= VM_PROT_EXECUTE
;
11567 if (old_map
->mapped_in_other_pmaps
) {
11568 vm_object_pmap_protect(
11569 VME_OBJECT(old_entry
),
11570 VME_OFFSET(old_entry
),
11571 (old_entry
->vme_end
-
11572 old_entry
->vme_start
),
11574 old_entry
->vme_start
,
11577 pmap_protect(old_map
->pmap
,
11578 old_entry
->vme_start
,
11579 old_entry
->vme_end
,
11584 old_entry
->needs_copy
= FALSE
;
11585 object
= VME_OBJECT(old_entry
);
11590 * If object was using a symmetric copy strategy,
11591 * change its copy strategy to the default
11592 * asymmetric copy strategy, which is copy_delay
11593 * in the non-norma case and copy_call in the
11594 * norma case. Bump the reference count for the
11598 if(old_entry
->is_sub_map
) {
11599 vm_map_lock(VME_SUBMAP(old_entry
));
11600 vm_map_reference(VME_SUBMAP(old_entry
));
11601 vm_map_unlock(VME_SUBMAP(old_entry
));
11603 vm_object_lock(object
);
11604 vm_object_reference_locked(object
);
11605 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
11606 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
11608 vm_object_unlock(object
);
11612 * Clone the entry, using object ref from above.
11613 * Mark both entries as shared.
11616 new_entry
= vm_map_entry_create(new_map
, FALSE
); /* Never the kernel
11617 * map or descendants */
11618 vm_map_entry_copy(new_entry
, old_entry
);
11619 old_entry
->is_shared
= TRUE
;
11620 new_entry
->is_shared
= TRUE
;
11623 * If old entry's inheritence is VM_INHERIT_NONE,
11624 * the new entry is for corpse fork, remove the
11625 * write permission from the new entry.
11627 if (old_entry
->inheritance
== VM_INHERIT_NONE
) {
11629 new_entry
->protection
&= ~VM_PROT_WRITE
;
11630 new_entry
->max_protection
&= ~VM_PROT_WRITE
;
11634 * Insert the entry into the new map -- we
11635 * know we're inserting at the end of the new
11639 vm_map_store_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
11642 * Update the physical map
11645 if (old_entry
->is_sub_map
) {
11646 /* Bill Angell pmap support goes here */
11648 pmap_copy(new_map
->pmap
, old_map
->pmap
, new_entry
->vme_start
,
11649 old_entry
->vme_end
- old_entry
->vme_start
,
11650 old_entry
->vme_start
);
11657 vm_map_entry_t
*old_entry_p
,
11659 int vm_map_copyin_flags
)
11661 vm_map_entry_t old_entry
= *old_entry_p
;
11662 vm_map_size_t entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
11663 vm_map_offset_t start
= old_entry
->vme_start
;
11664 vm_map_copy_t copy
;
11665 vm_map_entry_t last
= vm_map_last_entry(new_map
);
11667 vm_map_unlock(old_map
);
11669 * Use maxprot version of copyin because we
11670 * care about whether this memory can ever
11671 * be accessed, not just whether it's accessible
11674 vm_map_copyin_flags
|= VM_MAP_COPYIN_USE_MAXPROT
;
11675 if (vm_map_copyin_internal(old_map
, start
, entry_size
,
11676 vm_map_copyin_flags
, ©
)
11679 * The map might have changed while it
11680 * was unlocked, check it again. Skip
11681 * any blank space or permanently
11682 * unreadable region.
11684 vm_map_lock(old_map
);
11685 if (!vm_map_lookup_entry(old_map
, start
, &last
) ||
11686 (last
->max_protection
& VM_PROT_READ
) == VM_PROT_NONE
) {
11687 last
= last
->vme_next
;
11689 *old_entry_p
= last
;
11692 * XXX For some error returns, want to
11693 * XXX skip to the next element. Note
11694 * that INVALID_ADDRESS and
11695 * PROTECTION_FAILURE are handled above.
11702 * Insert the copy into the new map
11705 vm_map_copy_insert(new_map
, last
, copy
);
11708 * Pick up the traversal at the end of
11709 * the copied region.
11712 vm_map_lock(old_map
);
11713 start
+= entry_size
;
11714 if (! vm_map_lookup_entry(old_map
, start
, &last
)) {
11715 last
= last
->vme_next
;
11717 if (last
->vme_start
== start
) {
11719 * No need to clip here and we don't
11720 * want to cause any unnecessary
11724 vm_map_clip_start(old_map
, last
, start
);
11727 *old_entry_p
= last
;
11735 * Create and return a new map based on the old
11736 * map, according to the inheritance values on the
11737 * regions in that map and the options.
11739 * The source map must not be locked.
11749 vm_map_entry_t old_entry
;
11750 vm_map_size_t new_size
= 0, entry_size
;
11751 vm_map_entry_t new_entry
;
11752 boolean_t src_needs_copy
;
11753 boolean_t new_entry_needs_copy
;
11754 boolean_t pmap_is64bit
;
11755 int vm_map_copyin_flags
;
11757 if (options
& ~(VM_MAP_FORK_SHARE_IF_INHERIT_NONE
|
11758 VM_MAP_FORK_PRESERVE_PURGEABLE
)) {
11759 /* unsupported option */
11760 return VM_MAP_NULL
;
11764 #if defined(__i386__) || defined(__x86_64__)
11765 old_map
->pmap
->pm_task_map
!= TASK_MAP_32BIT
;
11766 #elif defined(__arm64__)
11767 old_map
->pmap
->max
== MACH_VM_MAX_ADDRESS
;
11768 #elif defined(__arm__)
11771 #error Unknown architecture.
11774 new_pmap
= pmap_create(ledger
, (vm_map_size_t
) 0, pmap_is64bit
);
11776 vm_map_reference_swap(old_map
);
11777 vm_map_lock(old_map
);
11779 new_map
= vm_map_create(new_pmap
,
11780 old_map
->min_offset
,
11781 old_map
->max_offset
,
11782 old_map
->hdr
.entries_pageable
);
11783 vm_map_lock(new_map
);
11784 vm_commit_pagezero_status(new_map
);
11785 /* inherit the parent map's page size */
11786 vm_map_set_page_shift(new_map
, VM_MAP_PAGE_SHIFT(old_map
));
11788 old_entry
= vm_map_first_entry(old_map
);
11789 old_entry
!= vm_map_to_entry(old_map
);
11792 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
11794 switch (old_entry
->inheritance
) {
11795 case VM_INHERIT_NONE
:
11797 * Skip making a share entry if VM_MAP_FORK_SHARE_IF_INHERIT_NONE
11798 * is not passed or it is backed by a device pager.
11800 if ((!(options
& VM_MAP_FORK_SHARE_IF_INHERIT_NONE
)) ||
11801 (!old_entry
->is_sub_map
&&
11802 VME_OBJECT(old_entry
) != NULL
&&
11803 VME_OBJECT(old_entry
)->pager
!= NULL
&&
11804 is_device_pager_ops(VME_OBJECT(old_entry
)->pager
->mo_pager_ops
))) {
11809 case VM_INHERIT_SHARE
:
11810 vm_map_fork_share(old_map
, old_entry
, new_map
);
11811 new_size
+= entry_size
;
11814 case VM_INHERIT_COPY
:
11817 * Inline the copy_quickly case;
11818 * upon failure, fall back on call
11819 * to vm_map_fork_copy.
11822 if(old_entry
->is_sub_map
)
11824 if ((old_entry
->wired_count
!= 0) ||
11825 ((VME_OBJECT(old_entry
) != NULL
) &&
11826 (VME_OBJECT(old_entry
)->true_share
))) {
11827 goto slow_vm_map_fork_copy
;
11830 new_entry
= vm_map_entry_create(new_map
, FALSE
); /* never the kernel map or descendants */
11831 vm_map_entry_copy(new_entry
, old_entry
);
11832 if (new_entry
->is_sub_map
) {
11833 /* clear address space specifics */
11834 new_entry
->use_pmap
= FALSE
;
11837 if (! vm_object_copy_quickly(
11838 &VME_OBJECT(new_entry
),
11839 VME_OFFSET(old_entry
),
11840 (old_entry
->vme_end
-
11841 old_entry
->vme_start
),
11843 &new_entry_needs_copy
)) {
11844 vm_map_entry_dispose(new_map
, new_entry
);
11845 goto slow_vm_map_fork_copy
;
11849 * Handle copy-on-write obligations
11852 if (src_needs_copy
&& !old_entry
->needs_copy
) {
11855 assert(!pmap_has_prot_policy(old_entry
->protection
));
11857 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
11859 if (override_nx(old_map
, VME_ALIAS(old_entry
))
11861 prot
|= VM_PROT_EXECUTE
;
11863 assert(!pmap_has_prot_policy(prot
));
11865 vm_object_pmap_protect(
11866 VME_OBJECT(old_entry
),
11867 VME_OFFSET(old_entry
),
11868 (old_entry
->vme_end
-
11869 old_entry
->vme_start
),
11870 ((old_entry
->is_shared
11871 || old_map
->mapped_in_other_pmaps
)
11874 old_entry
->vme_start
,
11877 assert(old_entry
->wired_count
== 0);
11878 old_entry
->needs_copy
= TRUE
;
11880 new_entry
->needs_copy
= new_entry_needs_copy
;
11883 * Insert the entry at the end
11887 vm_map_store_entry_link(new_map
, vm_map_last_entry(new_map
),
11889 new_size
+= entry_size
;
11892 slow_vm_map_fork_copy
:
11893 vm_map_copyin_flags
= 0;
11894 if (options
& VM_MAP_FORK_PRESERVE_PURGEABLE
) {
11895 vm_map_copyin_flags
|=
11896 VM_MAP_COPYIN_PRESERVE_PURGEABLE
;
11898 if (vm_map_fork_copy(old_map
,
11901 vm_map_copyin_flags
)) {
11902 new_size
+= entry_size
;
11906 old_entry
= old_entry
->vme_next
;
11909 #if defined(__arm64__)
11910 pmap_insert_sharedpage(new_map
->pmap
);
11913 new_map
->size
= new_size
;
11914 vm_map_unlock(new_map
);
11915 vm_map_unlock(old_map
);
11916 vm_map_deallocate(old_map
);
11924 * Setup the "new_map" with the proper execution environment according
11925 * to the type of executable (platform, 64bit, chroot environment).
11926 * Map the comm page and shared region, etc...
11936 SHARED_REGION_TRACE_DEBUG(
11937 ("shared_region: task %p: vm_map_exec(%p,%p,%p,0x%x): ->\n",
11938 (void *)VM_KERNEL_ADDRPERM(current_task()),
11939 (void *)VM_KERNEL_ADDRPERM(new_map
),
11940 (void *)VM_KERNEL_ADDRPERM(task
),
11941 (void *)VM_KERNEL_ADDRPERM(fsroot
),
11943 (void) vm_commpage_enter(new_map
, task
, is64bit
);
11944 (void) vm_shared_region_enter(new_map
, task
, is64bit
, fsroot
, cpu
);
11945 SHARED_REGION_TRACE_DEBUG(
11946 ("shared_region: task %p: vm_map_exec(%p,%p,%p,0x%x): <-\n",
11947 (void *)VM_KERNEL_ADDRPERM(current_task()),
11948 (void *)VM_KERNEL_ADDRPERM(new_map
),
11949 (void *)VM_KERNEL_ADDRPERM(task
),
11950 (void *)VM_KERNEL_ADDRPERM(fsroot
),
11952 return KERN_SUCCESS
;
11956 * vm_map_lookup_locked:
11958 * Finds the VM object, offset, and
11959 * protection for a given virtual address in the
11960 * specified map, assuming a page fault of the
11963 * Returns the (object, offset, protection) for
11964 * this address, whether it is wired down, and whether
11965 * this map has the only reference to the data in question.
11966 * In order to later verify this lookup, a "version"
11969 * The map MUST be locked by the caller and WILL be
11970 * locked on exit. In order to guarantee the
11971 * existence of the returned object, it is returned
11974 * If a lookup is requested with "write protection"
11975 * specified, the map may be changed to perform virtual
11976 * copying operations, although the data referenced will
11980 vm_map_lookup_locked(
11981 vm_map_t
*var_map
, /* IN/OUT */
11982 vm_map_offset_t vaddr
,
11983 vm_prot_t fault_type
,
11984 int object_lock_type
,
11985 vm_map_version_t
*out_version
, /* OUT */
11986 vm_object_t
*object
, /* OUT */
11987 vm_object_offset_t
*offset
, /* OUT */
11988 vm_prot_t
*out_prot
, /* OUT */
11989 boolean_t
*wired
, /* OUT */
11990 vm_object_fault_info_t fault_info
, /* OUT */
11991 vm_map_t
*real_map
)
11993 vm_map_entry_t entry
;
11994 vm_map_t map
= *var_map
;
11995 vm_map_t old_map
= *var_map
;
11996 vm_map_t cow_sub_map_parent
= VM_MAP_NULL
;
11997 vm_map_offset_t cow_parent_vaddr
= 0;
11998 vm_map_offset_t old_start
= 0;
11999 vm_map_offset_t old_end
= 0;
12001 boolean_t mask_protections
;
12002 boolean_t force_copy
;
12003 vm_prot_t original_fault_type
;
12006 * VM_PROT_MASK means that the caller wants us to use "fault_type"
12007 * as a mask against the mapping's actual protections, not as an
12010 mask_protections
= (fault_type
& VM_PROT_IS_MASK
) ? TRUE
: FALSE
;
12011 force_copy
= (fault_type
& VM_PROT_COPY
) ? TRUE
: FALSE
;
12012 fault_type
&= VM_PROT_ALL
;
12013 original_fault_type
= fault_type
;
12018 fault_type
= original_fault_type
;
12021 * If the map has an interesting hint, try it before calling
12022 * full blown lookup routine.
12026 if ((entry
== vm_map_to_entry(map
)) ||
12027 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
12028 vm_map_entry_t tmp_entry
;
12031 * Entry was either not a valid hint, or the vaddr
12032 * was not contained in the entry, so do a full lookup.
12034 if (!vm_map_lookup_entry(map
, vaddr
, &tmp_entry
)) {
12035 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
))
12036 vm_map_unlock(cow_sub_map_parent
);
12037 if((*real_map
!= map
)
12038 && (*real_map
!= cow_sub_map_parent
))
12039 vm_map_unlock(*real_map
);
12040 return KERN_INVALID_ADDRESS
;
12045 if(map
== old_map
) {
12046 old_start
= entry
->vme_start
;
12047 old_end
= entry
->vme_end
;
12051 * Handle submaps. Drop lock on upper map, submap is
12056 if (entry
->is_sub_map
) {
12057 vm_map_offset_t local_vaddr
;
12058 vm_map_offset_t end_delta
;
12059 vm_map_offset_t start_delta
;
12060 vm_map_entry_t submap_entry
;
12061 vm_prot_t subentry_protection
;
12062 vm_prot_t subentry_max_protection
;
12063 boolean_t mapped_needs_copy
=FALSE
;
12065 local_vaddr
= vaddr
;
12067 if ((entry
->use_pmap
&&
12068 ! ((fault_type
& VM_PROT_WRITE
) ||
12070 /* if real_map equals map we unlock below */
12071 if ((*real_map
!= map
) &&
12072 (*real_map
!= cow_sub_map_parent
))
12073 vm_map_unlock(*real_map
);
12074 *real_map
= VME_SUBMAP(entry
);
12077 if(entry
->needs_copy
&&
12078 ((fault_type
& VM_PROT_WRITE
) ||
12080 if (!mapped_needs_copy
) {
12081 if (vm_map_lock_read_to_write(map
)) {
12082 vm_map_lock_read(map
);
12086 vm_map_lock_read(VME_SUBMAP(entry
));
12087 *var_map
= VME_SUBMAP(entry
);
12088 cow_sub_map_parent
= map
;
12089 /* reset base to map before cow object */
12090 /* this is the map which will accept */
12091 /* the new cow object */
12092 old_start
= entry
->vme_start
;
12093 old_end
= entry
->vme_end
;
12094 cow_parent_vaddr
= vaddr
;
12095 mapped_needs_copy
= TRUE
;
12097 vm_map_lock_read(VME_SUBMAP(entry
));
12098 *var_map
= VME_SUBMAP(entry
);
12099 if((cow_sub_map_parent
!= map
) &&
12100 (*real_map
!= map
))
12101 vm_map_unlock(map
);
12104 vm_map_lock_read(VME_SUBMAP(entry
));
12105 *var_map
= VME_SUBMAP(entry
);
12106 /* leave map locked if it is a target */
12107 /* cow sub_map above otherwise, just */
12108 /* follow the maps down to the object */
12109 /* here we unlock knowing we are not */
12110 /* revisiting the map. */
12111 if((*real_map
!= map
) && (map
!= cow_sub_map_parent
))
12112 vm_map_unlock_read(map
);
12117 /* calculate the offset in the submap for vaddr */
12118 local_vaddr
= (local_vaddr
- entry
->vme_start
) + VME_OFFSET(entry
);
12121 if(!vm_map_lookup_entry(map
, local_vaddr
, &submap_entry
)) {
12122 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
)){
12123 vm_map_unlock(cow_sub_map_parent
);
12125 if((*real_map
!= map
)
12126 && (*real_map
!= cow_sub_map_parent
)) {
12127 vm_map_unlock(*real_map
);
12130 return KERN_INVALID_ADDRESS
;
12133 /* find the attenuated shadow of the underlying object */
12134 /* on our target map */
12136 /* in english the submap object may extend beyond the */
12137 /* region mapped by the entry or, may only fill a portion */
12138 /* of it. For our purposes, we only care if the object */
12139 /* doesn't fill. In this case the area which will */
12140 /* ultimately be clipped in the top map will only need */
12141 /* to be as big as the portion of the underlying entry */
12142 /* which is mapped */
12143 start_delta
= submap_entry
->vme_start
> VME_OFFSET(entry
) ?
12144 submap_entry
->vme_start
- VME_OFFSET(entry
) : 0;
12147 (VME_OFFSET(entry
) + start_delta
+ (old_end
- old_start
)) <=
12148 submap_entry
->vme_end
?
12149 0 : (VME_OFFSET(entry
) +
12150 (old_end
- old_start
))
12151 - submap_entry
->vme_end
;
12153 old_start
+= start_delta
;
12154 old_end
-= end_delta
;
12156 if(submap_entry
->is_sub_map
) {
12157 entry
= submap_entry
;
12158 vaddr
= local_vaddr
;
12159 goto submap_recurse
;
12162 if (((fault_type
& VM_PROT_WRITE
) ||
12164 && cow_sub_map_parent
) {
12166 vm_object_t sub_object
, copy_object
;
12167 vm_object_offset_t copy_offset
;
12168 vm_map_offset_t local_start
;
12169 vm_map_offset_t local_end
;
12170 boolean_t copied_slowly
= FALSE
;
12172 if (vm_map_lock_read_to_write(map
)) {
12173 vm_map_lock_read(map
);
12174 old_start
-= start_delta
;
12175 old_end
+= end_delta
;
12180 sub_object
= VME_OBJECT(submap_entry
);
12181 if (sub_object
== VM_OBJECT_NULL
) {
12183 vm_object_allocate(
12185 (submap_entry
->vme_end
-
12186 submap_entry
->vme_start
));
12187 VME_OBJECT_SET(submap_entry
, sub_object
);
12188 VME_OFFSET_SET(submap_entry
, 0);
12190 local_start
= local_vaddr
-
12191 (cow_parent_vaddr
- old_start
);
12192 local_end
= local_vaddr
+
12193 (old_end
- cow_parent_vaddr
);
12194 vm_map_clip_start(map
, submap_entry
, local_start
);
12195 vm_map_clip_end(map
, submap_entry
, local_end
);
12196 if (submap_entry
->is_sub_map
) {
12197 /* unnesting was done when clipping */
12198 assert(!submap_entry
->use_pmap
);
12201 /* This is the COW case, lets connect */
12202 /* an entry in our space to the underlying */
12203 /* object in the submap, bypassing the */
12207 if(submap_entry
->wired_count
!= 0 ||
12208 (sub_object
->copy_strategy
==
12209 MEMORY_OBJECT_COPY_NONE
)) {
12210 vm_object_lock(sub_object
);
12211 vm_object_copy_slowly(sub_object
,
12212 VME_OFFSET(submap_entry
),
12213 (submap_entry
->vme_end
-
12214 submap_entry
->vme_start
),
12217 copied_slowly
= TRUE
;
12220 /* set up shadow object */
12221 copy_object
= sub_object
;
12222 vm_object_lock(sub_object
);
12223 vm_object_reference_locked(sub_object
);
12224 sub_object
->shadowed
= TRUE
;
12225 vm_object_unlock(sub_object
);
12227 assert(submap_entry
->wired_count
== 0);
12228 submap_entry
->needs_copy
= TRUE
;
12230 prot
= submap_entry
->protection
;
12231 assert(!pmap_has_prot_policy(prot
));
12232 prot
= prot
& ~VM_PROT_WRITE
;
12233 assert(!pmap_has_prot_policy(prot
));
12235 if (override_nx(old_map
,
12236 VME_ALIAS(submap_entry
))
12238 prot
|= VM_PROT_EXECUTE
;
12240 vm_object_pmap_protect(
12242 VME_OFFSET(submap_entry
),
12243 submap_entry
->vme_end
-
12244 submap_entry
->vme_start
,
12245 (submap_entry
->is_shared
12246 || map
->mapped_in_other_pmaps
) ?
12247 PMAP_NULL
: map
->pmap
,
12248 submap_entry
->vme_start
,
12253 * Adjust the fault offset to the submap entry.
12255 copy_offset
= (local_vaddr
-
12256 submap_entry
->vme_start
+
12257 VME_OFFSET(submap_entry
));
12259 /* This works diffently than the */
12260 /* normal submap case. We go back */
12261 /* to the parent of the cow map and*/
12262 /* clip out the target portion of */
12263 /* the sub_map, substituting the */
12264 /* new copy object, */
12266 subentry_protection
= submap_entry
->protection
;
12267 subentry_max_protection
= submap_entry
->max_protection
;
12268 vm_map_unlock(map
);
12269 submap_entry
= NULL
; /* not valid after map unlock */
12271 local_start
= old_start
;
12272 local_end
= old_end
;
12273 map
= cow_sub_map_parent
;
12274 *var_map
= cow_sub_map_parent
;
12275 vaddr
= cow_parent_vaddr
;
12276 cow_sub_map_parent
= NULL
;
12278 if(!vm_map_lookup_entry(map
,
12280 vm_object_deallocate(
12282 vm_map_lock_write_to_read(map
);
12283 return KERN_INVALID_ADDRESS
;
12286 /* clip out the portion of space */
12287 /* mapped by the sub map which */
12288 /* corresponds to the underlying */
12292 * Clip (and unnest) the smallest nested chunk
12293 * possible around the faulting address...
12295 local_start
= vaddr
& ~(pmap_nesting_size_min
- 1);
12296 local_end
= local_start
+ pmap_nesting_size_min
;
12298 * ... but don't go beyond the "old_start" to "old_end"
12299 * range, to avoid spanning over another VM region
12300 * with a possibly different VM object and/or offset.
12302 if (local_start
< old_start
) {
12303 local_start
= old_start
;
12305 if (local_end
> old_end
) {
12306 local_end
= old_end
;
12309 * Adjust copy_offset to the start of the range.
12311 copy_offset
-= (vaddr
- local_start
);
12313 vm_map_clip_start(map
, entry
, local_start
);
12314 vm_map_clip_end(map
, entry
, local_end
);
12315 if (entry
->is_sub_map
) {
12316 /* unnesting was done when clipping */
12317 assert(!entry
->use_pmap
);
12320 /* substitute copy object for */
12321 /* shared map entry */
12322 vm_map_deallocate(VME_SUBMAP(entry
));
12323 assert(!entry
->iokit_acct
);
12324 entry
->is_sub_map
= FALSE
;
12325 entry
->use_pmap
= TRUE
;
12326 VME_OBJECT_SET(entry
, copy_object
);
12328 /* propagate the submap entry's protections */
12329 entry
->protection
|= subentry_protection
;
12330 entry
->max_protection
|= subentry_max_protection
;
12332 #if CONFIG_EMBEDDED
12333 if (entry
->protection
& VM_PROT_WRITE
) {
12334 if ((entry
->protection
& VM_PROT_EXECUTE
) && !(entry
->used_for_jit
)) {
12335 printf("EMBEDDED: %s can't have both write and exec at the same time\n", __FUNCTION__
);
12336 entry
->protection
&= ~VM_PROT_EXECUTE
;
12341 if(copied_slowly
) {
12342 VME_OFFSET_SET(entry
, local_start
- old_start
);
12343 entry
->needs_copy
= FALSE
;
12344 entry
->is_shared
= FALSE
;
12346 VME_OFFSET_SET(entry
, copy_offset
);
12347 assert(entry
->wired_count
== 0);
12348 entry
->needs_copy
= TRUE
;
12349 if(entry
->inheritance
== VM_INHERIT_SHARE
)
12350 entry
->inheritance
= VM_INHERIT_COPY
;
12351 if (map
!= old_map
)
12352 entry
->is_shared
= TRUE
;
12354 if(entry
->inheritance
== VM_INHERIT_SHARE
)
12355 entry
->inheritance
= VM_INHERIT_COPY
;
12357 vm_map_lock_write_to_read(map
);
12359 if((cow_sub_map_parent
)
12360 && (cow_sub_map_parent
!= *real_map
)
12361 && (cow_sub_map_parent
!= map
)) {
12362 vm_map_unlock(cow_sub_map_parent
);
12364 entry
= submap_entry
;
12365 vaddr
= local_vaddr
;
12370 * Check whether this task is allowed to have
12374 prot
= entry
->protection
;
12376 if (override_nx(old_map
, VME_ALIAS(entry
)) && prot
) {
12378 * HACK -- if not a stack, then allow execution
12380 prot
|= VM_PROT_EXECUTE
;
12383 if (mask_protections
) {
12384 fault_type
&= prot
;
12385 if (fault_type
== VM_PROT_NONE
) {
12386 goto protection_failure
;
12389 if (((fault_type
& prot
) != fault_type
)
12391 /* prefetch abort in execute-only page */
12392 && !(prot
== VM_PROT_EXECUTE
&& fault_type
== (VM_PROT_READ
| VM_PROT_EXECUTE
))
12395 protection_failure
:
12396 if (*real_map
!= map
) {
12397 vm_map_unlock(*real_map
);
12401 if ((fault_type
& VM_PROT_EXECUTE
) && prot
)
12402 log_stack_execution_failure((addr64_t
)vaddr
, prot
);
12404 DTRACE_VM2(prot_fault
, int, 1, (uint64_t *), NULL
);
12405 return KERN_PROTECTION_FAILURE
;
12409 * If this page is not pageable, we have to get
12410 * it for all possible accesses.
12413 *wired
= (entry
->wired_count
!= 0);
12418 * If the entry was copy-on-write, we either ...
12421 if (entry
->needs_copy
) {
12423 * If we want to write the page, we may as well
12424 * handle that now since we've got the map locked.
12426 * If we don't need to write the page, we just
12427 * demote the permissions allowed.
12430 if ((fault_type
& VM_PROT_WRITE
) || *wired
|| force_copy
) {
12432 * Make a new object, and place it in the
12433 * object chain. Note that no new references
12434 * have appeared -- one just moved from the
12435 * map to the new object.
12438 if (vm_map_lock_read_to_write(map
)) {
12439 vm_map_lock_read(map
);
12443 if (VME_OBJECT(entry
)->shadowed
== FALSE
) {
12444 vm_object_lock(VME_OBJECT(entry
));
12445 VME_OBJECT(entry
)->shadowed
= TRUE
;
12446 vm_object_unlock(VME_OBJECT(entry
));
12448 VME_OBJECT_SHADOW(entry
,
12449 (vm_map_size_t
) (entry
->vme_end
-
12450 entry
->vme_start
));
12451 entry
->needs_copy
= FALSE
;
12453 vm_map_lock_write_to_read(map
);
12455 if ((fault_type
& VM_PROT_WRITE
) == 0 && *wired
== 0) {
12457 * We're attempting to read a copy-on-write
12458 * page -- don't allow writes.
12461 prot
&= (~VM_PROT_WRITE
);
12466 * Create an object if necessary.
12468 if (VME_OBJECT(entry
) == VM_OBJECT_NULL
) {
12470 if (vm_map_lock_read_to_write(map
)) {
12471 vm_map_lock_read(map
);
12475 VME_OBJECT_SET(entry
,
12476 vm_object_allocate(
12477 (vm_map_size_t
)(entry
->vme_end
-
12478 entry
->vme_start
)));
12479 VME_OFFSET_SET(entry
, 0);
12480 vm_map_lock_write_to_read(map
);
12484 * Return the object/offset from this entry. If the entry
12485 * was copy-on-write or empty, it has been fixed up. Also
12486 * return the protection.
12489 *offset
= (vaddr
- entry
->vme_start
) + VME_OFFSET(entry
);
12490 *object
= VME_OBJECT(entry
);
12494 fault_info
->interruptible
= THREAD_UNINT
; /* for now... */
12495 /* ... the caller will change "interruptible" if needed */
12496 fault_info
->cluster_size
= 0;
12497 fault_info
->user_tag
= VME_ALIAS(entry
);
12498 fault_info
->pmap_options
= 0;
12499 if (entry
->iokit_acct
||
12500 (!entry
->is_sub_map
&& !entry
->use_pmap
)) {
12501 fault_info
->pmap_options
|= PMAP_OPTIONS_ALT_ACCT
;
12503 fault_info
->behavior
= entry
->behavior
;
12504 fault_info
->lo_offset
= VME_OFFSET(entry
);
12505 fault_info
->hi_offset
=
12506 (entry
->vme_end
- entry
->vme_start
) + VME_OFFSET(entry
);
12507 fault_info
->no_cache
= entry
->no_cache
;
12508 fault_info
->stealth
= FALSE
;
12509 fault_info
->io_sync
= FALSE
;
12510 if (entry
->used_for_jit
||
12511 entry
->vme_resilient_codesign
) {
12512 fault_info
->cs_bypass
= TRUE
;
12514 fault_info
->cs_bypass
= FALSE
;
12516 fault_info
->mark_zf_absent
= FALSE
;
12517 fault_info
->batch_pmap_op
= FALSE
;
12521 * Lock the object to prevent it from disappearing
12523 if (object_lock_type
== OBJECT_LOCK_EXCLUSIVE
)
12524 vm_object_lock(*object
);
12526 vm_object_lock_shared(*object
);
12529 * Save the version number
12532 out_version
->main_timestamp
= map
->timestamp
;
12534 return KERN_SUCCESS
;
12541 * Verifies that the map in question has not changed
12542 * since the given version. The map has to be locked
12543 * ("shared" mode is fine) before calling this function
12544 * and it will be returned locked too.
12549 vm_map_version_t
*version
) /* REF */
12553 vm_map_lock_assert_held(map
);
12554 result
= (map
->timestamp
== version
->main_timestamp
);
12560 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
12561 * Goes away after regular vm_region_recurse function migrates to
12563 * vm_region_recurse: A form of vm_region which follows the
12564 * submaps in a target map
12568 #if DEVELOPMENT || DEBUG
12569 int vm_region_footprint
= 0;
12570 #endif /* DEVELOPMENT || DEBUG */
12573 vm_map_region_recurse_64(
12575 vm_map_offset_t
*address
, /* IN/OUT */
12576 vm_map_size_t
*size
, /* OUT */
12577 natural_t
*nesting_depth
, /* IN/OUT */
12578 vm_region_submap_info_64_t submap_info
, /* IN/OUT */
12579 mach_msg_type_number_t
*count
) /* IN/OUT */
12581 mach_msg_type_number_t original_count
;
12582 vm_region_extended_info_data_t extended
;
12583 vm_map_entry_t tmp_entry
;
12584 vm_map_offset_t user_address
;
12585 unsigned int user_max_depth
;
12588 * "curr_entry" is the VM map entry preceding or including the
12589 * address we're looking for.
12590 * "curr_map" is the map or sub-map containing "curr_entry".
12591 * "curr_address" is the equivalent of the top map's "user_address"
12592 * in the current map.
12593 * "curr_offset" is the cumulated offset of "curr_map" in the
12594 * target task's address space.
12595 * "curr_depth" is the depth of "curr_map" in the chain of
12598 * "curr_max_below" and "curr_max_above" limit the range (around
12599 * "curr_address") we should take into account in the current (sub)map.
12600 * They limit the range to what's visible through the map entries
12601 * we've traversed from the top map to the current map.
12604 vm_map_entry_t curr_entry
;
12605 vm_map_address_t curr_address
;
12606 vm_map_offset_t curr_offset
;
12608 unsigned int curr_depth
;
12609 vm_map_offset_t curr_max_below
, curr_max_above
;
12610 vm_map_offset_t curr_skip
;
12613 * "next_" is the same as "curr_" but for the VM region immediately
12614 * after the address we're looking for. We need to keep track of this
12615 * too because we want to return info about that region if the
12616 * address we're looking for is not mapped.
12618 vm_map_entry_t next_entry
;
12619 vm_map_offset_t next_offset
;
12620 vm_map_offset_t next_address
;
12622 unsigned int next_depth
;
12623 vm_map_offset_t next_max_below
, next_max_above
;
12624 vm_map_offset_t next_skip
;
12626 boolean_t look_for_pages
;
12627 vm_region_submap_short_info_64_t short_info
;
12629 if (map
== VM_MAP_NULL
) {
12630 /* no address space to work on */
12631 return KERN_INVALID_ARGUMENT
;
12635 if (*count
< VM_REGION_SUBMAP_SHORT_INFO_COUNT_64
) {
12637 * "info" structure is not big enough and
12640 return KERN_INVALID_ARGUMENT
;
12643 original_count
= *count
;
12645 if (original_count
< VM_REGION_SUBMAP_INFO_V0_COUNT_64
) {
12646 *count
= VM_REGION_SUBMAP_SHORT_INFO_COUNT_64
;
12647 look_for_pages
= FALSE
;
12648 short_info
= (vm_region_submap_short_info_64_t
) submap_info
;
12649 submap_info
= NULL
;
12651 look_for_pages
= TRUE
;
12652 *count
= VM_REGION_SUBMAP_INFO_V0_COUNT_64
;
12655 if (original_count
>= VM_REGION_SUBMAP_INFO_V1_COUNT_64
) {
12656 *count
= VM_REGION_SUBMAP_INFO_V1_COUNT_64
;
12660 user_address
= *address
;
12661 user_max_depth
= *nesting_depth
;
12664 vm_map_lock_read(map
);
12670 curr_address
= user_address
;
12674 curr_max_above
= ((vm_map_offset_t
) -1) - curr_address
;
12675 curr_max_below
= curr_address
;
12683 next_max_above
= (vm_map_offset_t
) -1;
12684 next_max_below
= (vm_map_offset_t
) -1;
12687 if (vm_map_lookup_entry(curr_map
,
12690 /* tmp_entry contains the address we're looking for */
12691 curr_entry
= tmp_entry
;
12693 vm_map_offset_t skip
;
12695 * The address is not mapped. "tmp_entry" is the
12696 * map entry preceding the address. We want the next
12697 * one, if it exists.
12699 curr_entry
= tmp_entry
->vme_next
;
12701 if (curr_entry
== vm_map_to_entry(curr_map
) ||
12702 (curr_entry
->vme_start
>=
12703 curr_address
+ curr_max_above
)) {
12704 /* no next entry at this level: stop looking */
12706 vm_map_unlock_read(curr_map
);
12713 curr_max_above
= 0;
12714 curr_max_below
= 0;
12718 /* adjust current address and offset */
12719 skip
= curr_entry
->vme_start
- curr_address
;
12720 curr_address
= curr_entry
->vme_start
;
12722 curr_offset
+= skip
;
12723 curr_max_above
-= skip
;
12724 curr_max_below
= 0;
12728 * Is the next entry at this level closer to the address (or
12729 * deeper in the submap chain) than the one we had
12732 tmp_entry
= curr_entry
->vme_next
;
12733 if (tmp_entry
== vm_map_to_entry(curr_map
)) {
12734 /* no next entry at this level */
12735 } else if (tmp_entry
->vme_start
>=
12736 curr_address
+ curr_max_above
) {
12738 * tmp_entry is beyond the scope of what we mapped of
12739 * this submap in the upper level: ignore it.
12741 } else if ((next_entry
== NULL
) ||
12742 (tmp_entry
->vme_start
+ curr_offset
<=
12743 next_entry
->vme_start
+ next_offset
)) {
12745 * We didn't have a "next_entry" or this one is
12746 * closer to the address we're looking for:
12747 * use this "tmp_entry" as the new "next_entry".
12749 if (next_entry
!= NULL
) {
12750 /* unlock the last "next_map" */
12751 if (next_map
!= curr_map
&& not_in_kdp
) {
12752 vm_map_unlock_read(next_map
);
12755 next_entry
= tmp_entry
;
12756 next_map
= curr_map
;
12757 next_depth
= curr_depth
;
12758 next_address
= next_entry
->vme_start
;
12759 next_skip
= curr_skip
;
12760 next_skip
+= (next_address
- curr_address
);
12761 next_offset
= curr_offset
;
12762 next_offset
+= (next_address
- curr_address
);
12763 next_max_above
= MIN(next_max_above
, curr_max_above
);
12764 next_max_above
= MIN(next_max_above
,
12765 next_entry
->vme_end
- next_address
);
12766 next_max_below
= MIN(next_max_below
, curr_max_below
);
12767 next_max_below
= MIN(next_max_below
,
12768 next_address
- next_entry
->vme_start
);
12772 * "curr_max_{above,below}" allow us to keep track of the
12773 * portion of the submap that is actually mapped at this level:
12774 * the rest of that submap is irrelevant to us, since it's not
12776 * The relevant portion of the map starts at
12777 * "VME_OFFSET(curr_entry)" up to the size of "curr_entry".
12779 curr_max_above
= MIN(curr_max_above
,
12780 curr_entry
->vme_end
- curr_address
);
12781 curr_max_below
= MIN(curr_max_below
,
12782 curr_address
- curr_entry
->vme_start
);
12784 if (!curr_entry
->is_sub_map
||
12785 curr_depth
>= user_max_depth
) {
12787 * We hit a leaf map or we reached the maximum depth
12788 * we could, so stop looking. Keep the current map
12795 * Get down to the next submap level.
12799 * Lock the next level and unlock the current level,
12800 * unless we need to keep it locked to access the "next_entry"
12804 vm_map_lock_read(VME_SUBMAP(curr_entry
));
12806 if (curr_map
== next_map
) {
12807 /* keep "next_map" locked in case we need it */
12809 /* release this map */
12811 vm_map_unlock_read(curr_map
);
12815 * Adjust the offset. "curr_entry" maps the submap
12816 * at relative address "curr_entry->vme_start" in the
12817 * curr_map but skips the first "VME_OFFSET(curr_entry)"
12818 * bytes of the submap.
12819 * "curr_offset" always represents the offset of a virtual
12820 * address in the curr_map relative to the absolute address
12821 * space (i.e. the top-level VM map).
12824 (VME_OFFSET(curr_entry
) - curr_entry
->vme_start
);
12825 curr_address
= user_address
+ curr_offset
;
12826 /* switch to the submap */
12827 curr_map
= VME_SUBMAP(curr_entry
);
12832 if (curr_entry
== NULL
) {
12833 /* no VM region contains the address... */
12834 #if DEVELOPMENT || DEBUG
12835 if (vm_region_footprint
&& /* we want footprint numbers */
12836 look_for_pages
&& /* & we want page counts */
12837 next_entry
== NULL
&& /* & there are no more regions */
12838 /* & we haven't already provided our fake region: */
12839 user_address
== vm_map_last_entry(map
)->vme_end
) {
12840 ledger_amount_t nonvol
, nonvol_compressed
;
12842 * Add a fake memory region to account for
12843 * purgeable memory that counts towards this
12844 * task's memory footprint, i.e. the resident
12845 * compressed pages of non-volatile objects
12846 * owned by that task.
12848 ledger_get_balance(
12850 task_ledgers
.purgeable_nonvolatile
,
12852 ledger_get_balance(
12854 task_ledgers
.purgeable_nonvolatile_compressed
,
12855 &nonvol_compressed
);
12856 if (nonvol
+ nonvol_compressed
== 0) {
12857 /* no purgeable memory usage to report */
12858 return KERN_FAILURE
;
12860 /* fake region to show nonvolatile footprint */
12861 submap_info
->protection
= VM_PROT_DEFAULT
;
12862 submap_info
->max_protection
= VM_PROT_DEFAULT
;
12863 submap_info
->inheritance
= VM_INHERIT_DEFAULT
;
12864 submap_info
->offset
= 0;
12865 submap_info
->user_tag
= 0;
12866 submap_info
->pages_resident
= (unsigned int) (nonvol
/ PAGE_SIZE
);
12867 submap_info
->pages_shared_now_private
= 0;
12868 submap_info
->pages_swapped_out
= (unsigned int) (nonvol_compressed
/ PAGE_SIZE
);
12869 submap_info
->pages_dirtied
= submap_info
->pages_resident
;
12870 submap_info
->ref_count
= 1;
12871 submap_info
->shadow_depth
= 0;
12872 submap_info
->external_pager
= 0;
12873 submap_info
->share_mode
= SM_PRIVATE
;
12874 submap_info
->is_submap
= 0;
12875 submap_info
->behavior
= VM_BEHAVIOR_DEFAULT
;
12876 submap_info
->object_id
= 0x11111111;
12877 submap_info
->user_wired_count
= 0;
12878 submap_info
->pages_reusable
= 0;
12879 *nesting_depth
= 0;
12880 *size
= (vm_map_size_t
) (nonvol
+ nonvol_compressed
);
12881 *address
= user_address
;
12882 return KERN_SUCCESS
;
12884 #endif /* DEVELOPMENT || DEBUG */
12885 if (next_entry
== NULL
) {
12886 /* ... and no VM region follows it either */
12887 return KERN_INVALID_ADDRESS
;
12889 /* ... gather info about the next VM region */
12890 curr_entry
= next_entry
;
12891 curr_map
= next_map
; /* still locked ... */
12892 curr_address
= next_address
;
12893 curr_skip
= next_skip
;
12894 curr_offset
= next_offset
;
12895 curr_depth
= next_depth
;
12896 curr_max_above
= next_max_above
;
12897 curr_max_below
= next_max_below
;
12899 /* we won't need "next_entry" after all */
12900 if (next_entry
!= NULL
) {
12901 /* release "next_map" */
12902 if (next_map
!= curr_map
&& not_in_kdp
) {
12903 vm_map_unlock_read(next_map
);
12912 next_max_below
= -1;
12913 next_max_above
= -1;
12915 if (curr_entry
->is_sub_map
&&
12916 curr_depth
< user_max_depth
) {
12918 * We're not as deep as we could be: we must have
12919 * gone back up after not finding anything mapped
12920 * below the original top-level map entry's.
12921 * Let's move "curr_address" forward and recurse again.
12923 user_address
= curr_address
;
12924 goto recurse_again
;
12927 *nesting_depth
= curr_depth
;
12928 *size
= curr_max_above
+ curr_max_below
;
12929 *address
= user_address
+ curr_skip
- curr_max_below
;
12931 // LP64todo: all the current tools are 32bit, obviously never worked for 64b
12932 // so probably should be a real 32b ID vs. ptr.
12933 // Current users just check for equality
12934 #define INFO_MAKE_OBJECT_ID(p) ((uint32_t)(uintptr_t)VM_KERNEL_ADDRPERM(p))
12936 if (look_for_pages
) {
12937 submap_info
->user_tag
= VME_ALIAS(curr_entry
);
12938 submap_info
->offset
= VME_OFFSET(curr_entry
);
12939 submap_info
->protection
= curr_entry
->protection
;
12940 submap_info
->inheritance
= curr_entry
->inheritance
;
12941 submap_info
->max_protection
= curr_entry
->max_protection
;
12942 submap_info
->behavior
= curr_entry
->behavior
;
12943 submap_info
->user_wired_count
= curr_entry
->user_wired_count
;
12944 submap_info
->is_submap
= curr_entry
->is_sub_map
;
12945 submap_info
->object_id
= INFO_MAKE_OBJECT_ID(VME_OBJECT(curr_entry
));
12947 short_info
->user_tag
= VME_ALIAS(curr_entry
);
12948 short_info
->offset
= VME_OFFSET(curr_entry
);
12949 short_info
->protection
= curr_entry
->protection
;
12950 short_info
->inheritance
= curr_entry
->inheritance
;
12951 short_info
->max_protection
= curr_entry
->max_protection
;
12952 short_info
->behavior
= curr_entry
->behavior
;
12953 short_info
->user_wired_count
= curr_entry
->user_wired_count
;
12954 short_info
->is_submap
= curr_entry
->is_sub_map
;
12955 short_info
->object_id
= INFO_MAKE_OBJECT_ID(VME_OBJECT(curr_entry
));
12958 extended
.pages_resident
= 0;
12959 extended
.pages_swapped_out
= 0;
12960 extended
.pages_shared_now_private
= 0;
12961 extended
.pages_dirtied
= 0;
12962 extended
.pages_reusable
= 0;
12963 extended
.external_pager
= 0;
12964 extended
.shadow_depth
= 0;
12965 extended
.share_mode
= SM_EMPTY
;
12966 extended
.ref_count
= 0;
12969 if (!curr_entry
->is_sub_map
) {
12970 vm_map_offset_t range_start
, range_end
;
12971 range_start
= MAX((curr_address
- curr_max_below
),
12972 curr_entry
->vme_start
);
12973 range_end
= MIN((curr_address
+ curr_max_above
),
12974 curr_entry
->vme_end
);
12975 vm_map_region_walk(curr_map
,
12978 (VME_OFFSET(curr_entry
) +
12980 curr_entry
->vme_start
)),
12981 range_end
- range_start
,
12983 look_for_pages
, VM_REGION_EXTENDED_INFO_COUNT
);
12984 if (extended
.external_pager
&&
12985 extended
.ref_count
== 2 &&
12986 extended
.share_mode
== SM_SHARED
) {
12987 extended
.share_mode
= SM_PRIVATE
;
12990 if (curr_entry
->use_pmap
) {
12991 extended
.share_mode
= SM_TRUESHARED
;
12993 extended
.share_mode
= SM_PRIVATE
;
12995 extended
.ref_count
= VME_SUBMAP(curr_entry
)->ref_count
;
12999 if (look_for_pages
) {
13000 submap_info
->pages_resident
= extended
.pages_resident
;
13001 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
13002 submap_info
->pages_shared_now_private
=
13003 extended
.pages_shared_now_private
;
13004 submap_info
->pages_dirtied
= extended
.pages_dirtied
;
13005 submap_info
->external_pager
= extended
.external_pager
;
13006 submap_info
->shadow_depth
= extended
.shadow_depth
;
13007 submap_info
->share_mode
= extended
.share_mode
;
13008 submap_info
->ref_count
= extended
.ref_count
;
13010 if (original_count
>= VM_REGION_SUBMAP_INFO_V1_COUNT_64
) {
13011 submap_info
->pages_reusable
= extended
.pages_reusable
;
13014 short_info
->external_pager
= extended
.external_pager
;
13015 short_info
->shadow_depth
= extended
.shadow_depth
;
13016 short_info
->share_mode
= extended
.share_mode
;
13017 short_info
->ref_count
= extended
.ref_count
;
13021 vm_map_unlock_read(curr_map
);
13024 return KERN_SUCCESS
;
13030 * User call to obtain information about a region in
13031 * a task's address map. Currently, only one flavor is
13034 * XXX The reserved and behavior fields cannot be filled
13035 * in until the vm merge from the IK is completed, and
13036 * vm_reserve is implemented.
13042 vm_map_offset_t
*address
, /* IN/OUT */
13043 vm_map_size_t
*size
, /* OUT */
13044 vm_region_flavor_t flavor
, /* IN */
13045 vm_region_info_t info
, /* OUT */
13046 mach_msg_type_number_t
*count
, /* IN/OUT */
13047 mach_port_t
*object_name
) /* OUT */
13049 vm_map_entry_t tmp_entry
;
13050 vm_map_entry_t entry
;
13051 vm_map_offset_t start
;
13053 if (map
== VM_MAP_NULL
)
13054 return(KERN_INVALID_ARGUMENT
);
13058 case VM_REGION_BASIC_INFO
:
13059 /* legacy for old 32-bit objects info */
13061 vm_region_basic_info_t basic
;
13063 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
13064 return(KERN_INVALID_ARGUMENT
);
13066 basic
= (vm_region_basic_info_t
) info
;
13067 *count
= VM_REGION_BASIC_INFO_COUNT
;
13069 vm_map_lock_read(map
);
13072 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
13073 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
13074 vm_map_unlock_read(map
);
13075 return(KERN_INVALID_ADDRESS
);
13081 start
= entry
->vme_start
;
13083 basic
->offset
= (uint32_t)VME_OFFSET(entry
);
13084 basic
->protection
= entry
->protection
;
13085 basic
->inheritance
= entry
->inheritance
;
13086 basic
->max_protection
= entry
->max_protection
;
13087 basic
->behavior
= entry
->behavior
;
13088 basic
->user_wired_count
= entry
->user_wired_count
;
13089 basic
->reserved
= entry
->is_sub_map
;
13091 *size
= (entry
->vme_end
- start
);
13093 if (object_name
) *object_name
= IP_NULL
;
13094 if (entry
->is_sub_map
) {
13095 basic
->shared
= FALSE
;
13097 basic
->shared
= entry
->is_shared
;
13100 vm_map_unlock_read(map
);
13101 return(KERN_SUCCESS
);
13104 case VM_REGION_BASIC_INFO_64
:
13106 vm_region_basic_info_64_t basic
;
13108 if (*count
< VM_REGION_BASIC_INFO_COUNT_64
)
13109 return(KERN_INVALID_ARGUMENT
);
13111 basic
= (vm_region_basic_info_64_t
) info
;
13112 *count
= VM_REGION_BASIC_INFO_COUNT_64
;
13114 vm_map_lock_read(map
);
13117 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
13118 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
13119 vm_map_unlock_read(map
);
13120 return(KERN_INVALID_ADDRESS
);
13126 start
= entry
->vme_start
;
13128 basic
->offset
= VME_OFFSET(entry
);
13129 basic
->protection
= entry
->protection
;
13130 basic
->inheritance
= entry
->inheritance
;
13131 basic
->max_protection
= entry
->max_protection
;
13132 basic
->behavior
= entry
->behavior
;
13133 basic
->user_wired_count
= entry
->user_wired_count
;
13134 basic
->reserved
= entry
->is_sub_map
;
13136 *size
= (entry
->vme_end
- start
);
13138 if (object_name
) *object_name
= IP_NULL
;
13139 if (entry
->is_sub_map
) {
13140 basic
->shared
= FALSE
;
13142 basic
->shared
= entry
->is_shared
;
13145 vm_map_unlock_read(map
);
13146 return(KERN_SUCCESS
);
13148 case VM_REGION_EXTENDED_INFO
:
13149 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
13150 return(KERN_INVALID_ARGUMENT
);
13152 case VM_REGION_EXTENDED_INFO__legacy
:
13153 if (*count
< VM_REGION_EXTENDED_INFO_COUNT__legacy
)
13154 return KERN_INVALID_ARGUMENT
;
13157 vm_region_extended_info_t extended
;
13158 mach_msg_type_number_t original_count
;
13160 extended
= (vm_region_extended_info_t
) info
;
13162 vm_map_lock_read(map
);
13165 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
13166 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
13167 vm_map_unlock_read(map
);
13168 return(KERN_INVALID_ADDRESS
);
13173 start
= entry
->vme_start
;
13175 extended
->protection
= entry
->protection
;
13176 extended
->user_tag
= VME_ALIAS(entry
);
13177 extended
->pages_resident
= 0;
13178 extended
->pages_swapped_out
= 0;
13179 extended
->pages_shared_now_private
= 0;
13180 extended
->pages_dirtied
= 0;
13181 extended
->external_pager
= 0;
13182 extended
->shadow_depth
= 0;
13184 original_count
= *count
;
13185 if (flavor
== VM_REGION_EXTENDED_INFO__legacy
) {
13186 *count
= VM_REGION_EXTENDED_INFO_COUNT__legacy
;
13188 extended
->pages_reusable
= 0;
13189 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
13192 vm_map_region_walk(map
, start
, entry
, VME_OFFSET(entry
), entry
->vme_end
- start
, extended
, TRUE
, *count
);
13194 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
13195 extended
->share_mode
= SM_PRIVATE
;
13198 *object_name
= IP_NULL
;
13200 *size
= (entry
->vme_end
- start
);
13202 vm_map_unlock_read(map
);
13203 return(KERN_SUCCESS
);
13205 case VM_REGION_TOP_INFO
:
13207 vm_region_top_info_t top
;
13209 if (*count
< VM_REGION_TOP_INFO_COUNT
)
13210 return(KERN_INVALID_ARGUMENT
);
13212 top
= (vm_region_top_info_t
) info
;
13213 *count
= VM_REGION_TOP_INFO_COUNT
;
13215 vm_map_lock_read(map
);
13218 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
13219 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
13220 vm_map_unlock_read(map
);
13221 return(KERN_INVALID_ADDRESS
);
13227 start
= entry
->vme_start
;
13229 top
->private_pages_resident
= 0;
13230 top
->shared_pages_resident
= 0;
13232 vm_map_region_top_walk(entry
, top
);
13235 *object_name
= IP_NULL
;
13237 *size
= (entry
->vme_end
- start
);
13239 vm_map_unlock_read(map
);
13240 return(KERN_SUCCESS
);
13243 return(KERN_INVALID_ARGUMENT
);
13247 #define OBJ_RESIDENT_COUNT(obj, entry_size) \
13248 MIN((entry_size), \
13249 ((obj)->all_reusable ? \
13250 (obj)->wired_page_count : \
13251 (obj)->resident_page_count - (obj)->reusable_page_count))
13254 vm_map_region_top_walk(
13255 vm_map_entry_t entry
,
13256 vm_region_top_info_t top
)
13259 if (VME_OBJECT(entry
) == 0 || entry
->is_sub_map
) {
13260 top
->share_mode
= SM_EMPTY
;
13261 top
->ref_count
= 0;
13267 struct vm_object
*obj
, *tmp_obj
;
13269 uint32_t entry_size
;
13271 entry_size
= (uint32_t) ((entry
->vme_end
- entry
->vme_start
) / PAGE_SIZE_64
);
13273 obj
= VME_OBJECT(entry
);
13275 vm_object_lock(obj
);
13277 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
13280 assert(obj
->reusable_page_count
<= obj
->resident_page_count
);
13282 if (ref_count
== 1)
13283 top
->private_pages_resident
=
13284 OBJ_RESIDENT_COUNT(obj
, entry_size
);
13286 top
->shared_pages_resident
=
13287 OBJ_RESIDENT_COUNT(obj
, entry_size
);
13288 top
->ref_count
= ref_count
;
13289 top
->share_mode
= SM_COW
;
13291 while ((tmp_obj
= obj
->shadow
)) {
13292 vm_object_lock(tmp_obj
);
13293 vm_object_unlock(obj
);
13296 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
13299 assert(obj
->reusable_page_count
<= obj
->resident_page_count
);
13300 top
->shared_pages_resident
+=
13301 OBJ_RESIDENT_COUNT(obj
, entry_size
);
13302 top
->ref_count
+= ref_count
- 1;
13305 if (entry
->superpage_size
) {
13306 top
->share_mode
= SM_LARGE_PAGE
;
13307 top
->shared_pages_resident
= 0;
13308 top
->private_pages_resident
= entry_size
;
13309 } else if (entry
->needs_copy
) {
13310 top
->share_mode
= SM_COW
;
13311 top
->shared_pages_resident
=
13312 OBJ_RESIDENT_COUNT(obj
, entry_size
);
13314 if (ref_count
== 1 ||
13315 (ref_count
== 2 && !(obj
->pager_trusted
) && !(obj
->internal
))) {
13316 top
->share_mode
= SM_PRIVATE
;
13317 top
->private_pages_resident
=
13318 OBJ_RESIDENT_COUNT(obj
,
13321 top
->share_mode
= SM_SHARED
;
13322 top
->shared_pages_resident
=
13323 OBJ_RESIDENT_COUNT(obj
,
13327 top
->ref_count
= ref_count
;
13329 /* XXX K64: obj_id will be truncated */
13330 top
->obj_id
= (unsigned int) (uintptr_t)VM_KERNEL_ADDRPERM(obj
);
13332 vm_object_unlock(obj
);
13337 vm_map_region_walk(
13339 vm_map_offset_t va
,
13340 vm_map_entry_t entry
,
13341 vm_object_offset_t offset
,
13342 vm_object_size_t range
,
13343 vm_region_extended_info_t extended
,
13344 boolean_t look_for_pages
,
13345 mach_msg_type_number_t count
)
13347 struct vm_object
*obj
, *tmp_obj
;
13348 vm_map_offset_t last_offset
;
13351 struct vm_object
*shadow_object
;
13354 if ((VME_OBJECT(entry
) == 0) ||
13355 (entry
->is_sub_map
) ||
13356 (VME_OBJECT(entry
)->phys_contiguous
&&
13357 !entry
->superpage_size
)) {
13358 extended
->share_mode
= SM_EMPTY
;
13359 extended
->ref_count
= 0;
13363 if (entry
->superpage_size
) {
13364 extended
->shadow_depth
= 0;
13365 extended
->share_mode
= SM_LARGE_PAGE
;
13366 extended
->ref_count
= 1;
13367 extended
->external_pager
= 0;
13368 extended
->pages_resident
= (unsigned int)(range
>> PAGE_SHIFT
);
13369 extended
->shadow_depth
= 0;
13373 obj
= VME_OBJECT(entry
);
13375 vm_object_lock(obj
);
13377 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
13380 if (look_for_pages
) {
13381 for (last_offset
= offset
+ range
;
13382 offset
< last_offset
;
13383 offset
+= PAGE_SIZE_64
, va
+= PAGE_SIZE
) {
13384 #if DEVELOPMENT || DEBUG
13385 if (vm_region_footprint
) {
13386 if (obj
->purgable
!= VM_PURGABLE_DENY
) {
13387 /* alternate accounting */
13388 } else if (entry
->iokit_acct
) {
13389 /* alternate accounting */
13390 extended
->pages_resident
++;
13391 extended
->pages_dirtied
++;
13396 pmap_query_page_info(map
->pmap
, va
, &disp
);
13397 if (disp
& PMAP_QUERY_PAGE_PRESENT
) {
13398 extended
->pages_resident
++;
13399 if (disp
& PMAP_QUERY_PAGE_REUSABLE
) {
13400 extended
->pages_reusable
++;
13401 } else if (!(disp
& PMAP_QUERY_PAGE_INTERNAL
) ||
13402 (disp
& PMAP_QUERY_PAGE_ALTACCT
)) {
13403 /* alternate accounting */
13405 extended
->pages_dirtied
++;
13407 } else if (disp
& PMAP_QUERY_PAGE_COMPRESSED
) {
13408 if (disp
& PMAP_QUERY_PAGE_COMPRESSED_ALTACCT
) {
13409 /* alternate accounting */
13411 extended
->pages_swapped_out
++;
13417 #endif /* DEVELOPMENT || DEBUG */
13418 vm_map_region_look_for_page(map
, va
, obj
,
13420 0, extended
, count
);
13422 #if DEVELOPMENT || DEBUG
13423 if (vm_region_footprint
) {
13424 goto collect_object_info
;
13426 #endif /* DEVELOPMENT || DEBUG */
13428 #if DEVELOPMENT || DEBUG
13429 collect_object_info
:
13430 #endif /* DEVELOPMENT || DEBUG */
13431 shadow_object
= obj
->shadow
;
13434 if ( !(obj
->pager_trusted
) && !(obj
->internal
))
13435 extended
->external_pager
= 1;
13437 if (shadow_object
!= VM_OBJECT_NULL
) {
13438 vm_object_lock(shadow_object
);
13440 shadow_object
!= VM_OBJECT_NULL
;
13442 vm_object_t next_shadow
;
13444 if ( !(shadow_object
->pager_trusted
) &&
13445 !(shadow_object
->internal
))
13446 extended
->external_pager
= 1;
13448 next_shadow
= shadow_object
->shadow
;
13450 vm_object_lock(next_shadow
);
13452 vm_object_unlock(shadow_object
);
13453 shadow_object
= next_shadow
;
13456 extended
->shadow_depth
= shadow_depth
;
13459 if (extended
->shadow_depth
|| entry
->needs_copy
)
13460 extended
->share_mode
= SM_COW
;
13462 if (ref_count
== 1)
13463 extended
->share_mode
= SM_PRIVATE
;
13465 if (obj
->true_share
)
13466 extended
->share_mode
= SM_TRUESHARED
;
13468 extended
->share_mode
= SM_SHARED
;
13471 extended
->ref_count
= ref_count
- extended
->shadow_depth
;
13473 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
13474 if ((tmp_obj
= obj
->shadow
) == 0)
13476 vm_object_lock(tmp_obj
);
13477 vm_object_unlock(obj
);
13479 if ((ref_count
= tmp_obj
->ref_count
) > 1 && tmp_obj
->paging_in_progress
)
13482 extended
->ref_count
+= ref_count
;
13485 vm_object_unlock(obj
);
13487 if (extended
->share_mode
== SM_SHARED
) {
13488 vm_map_entry_t cur
;
13489 vm_map_entry_t last
;
13492 obj
= VME_OBJECT(entry
);
13493 last
= vm_map_to_entry(map
);
13496 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
13498 for (cur
= vm_map_first_entry(map
); cur
!= last
; cur
= cur
->vme_next
)
13499 my_refs
+= vm_map_region_count_obj_refs(cur
, obj
);
13501 if (my_refs
== ref_count
)
13502 extended
->share_mode
= SM_PRIVATE_ALIASED
;
13503 else if (my_refs
> 1)
13504 extended
->share_mode
= SM_SHARED_ALIASED
;
13509 /* object is locked on entry and locked on return */
13513 vm_map_region_look_for_page(
13514 __unused vm_map_t map
,
13515 __unused vm_map_offset_t va
,
13516 vm_object_t object
,
13517 vm_object_offset_t offset
,
13520 vm_region_extended_info_t extended
,
13521 mach_msg_type_number_t count
)
13524 vm_object_t shadow
;
13526 vm_object_t caller_object
;
13528 shadow
= object
->shadow
;
13529 caller_object
= object
;
13534 if ( !(object
->pager_trusted
) && !(object
->internal
))
13535 extended
->external_pager
= 1;
13537 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
13538 if (shadow
&& (max_refcnt
== 1))
13539 extended
->pages_shared_now_private
++;
13541 if (!p
->fictitious
&&
13542 (p
->dirty
|| pmap_is_modified(VM_PAGE_GET_PHYS_PAGE(p
))))
13543 extended
->pages_dirtied
++;
13544 else if (count
>= VM_REGION_EXTENDED_INFO_COUNT
) {
13545 if (p
->reusable
|| object
->all_reusable
) {
13546 extended
->pages_reusable
++;
13550 extended
->pages_resident
++;
13552 if(object
!= caller_object
)
13553 vm_object_unlock(object
);
13557 if (object
->internal
&&
13559 !object
->terminating
&&
13560 object
->pager_ready
) {
13562 if (VM_COMPRESSOR_PAGER_STATE_GET(object
, offset
)
13563 == VM_EXTERNAL_STATE_EXISTS
) {
13564 /* the pager has that page */
13565 extended
->pages_swapped_out
++;
13566 if (object
!= caller_object
)
13567 vm_object_unlock(object
);
13573 vm_object_lock(shadow
);
13575 if ((ref_count
= shadow
->ref_count
) > 1 && shadow
->paging_in_progress
)
13578 if (++depth
> extended
->shadow_depth
)
13579 extended
->shadow_depth
= depth
;
13581 if (ref_count
> max_refcnt
)
13582 max_refcnt
= ref_count
;
13584 if(object
!= caller_object
)
13585 vm_object_unlock(object
);
13587 offset
= offset
+ object
->vo_shadow_offset
;
13589 shadow
= object
->shadow
;
13592 if(object
!= caller_object
)
13593 vm_object_unlock(object
);
13599 vm_map_region_count_obj_refs(
13600 vm_map_entry_t entry
,
13601 vm_object_t object
)
13604 vm_object_t chk_obj
;
13605 vm_object_t tmp_obj
;
13607 if (VME_OBJECT(entry
) == 0)
13610 if (entry
->is_sub_map
)
13615 chk_obj
= VME_OBJECT(entry
);
13616 vm_object_lock(chk_obj
);
13619 if (chk_obj
== object
)
13621 tmp_obj
= chk_obj
->shadow
;
13623 vm_object_lock(tmp_obj
);
13624 vm_object_unlock(chk_obj
);
13634 * Routine: vm_map_simplify
13637 * Attempt to simplify the map representation in
13638 * the vicinity of the given starting address.
13640 * This routine is intended primarily to keep the
13641 * kernel maps more compact -- they generally don't
13642 * benefit from the "expand a map entry" technology
13643 * at allocation time because the adjacent entry
13644 * is often wired down.
13647 vm_map_simplify_entry(
13649 vm_map_entry_t this_entry
)
13651 vm_map_entry_t prev_entry
;
13653 counter(c_vm_map_simplify_entry_called
++);
13655 prev_entry
= this_entry
->vme_prev
;
13657 if ((this_entry
!= vm_map_to_entry(map
)) &&
13658 (prev_entry
!= vm_map_to_entry(map
)) &&
13660 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
13662 (prev_entry
->is_sub_map
== this_entry
->is_sub_map
) &&
13663 (VME_OBJECT(prev_entry
) == VME_OBJECT(this_entry
)) &&
13664 ((VME_OFFSET(prev_entry
) + (prev_entry
->vme_end
-
13665 prev_entry
->vme_start
))
13666 == VME_OFFSET(this_entry
)) &&
13668 (prev_entry
->behavior
== this_entry
->behavior
) &&
13669 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
13670 (prev_entry
->protection
== this_entry
->protection
) &&
13671 (prev_entry
->max_protection
== this_entry
->max_protection
) &&
13672 (prev_entry
->inheritance
== this_entry
->inheritance
) &&
13673 (prev_entry
->use_pmap
== this_entry
->use_pmap
) &&
13674 (VME_ALIAS(prev_entry
) == VME_ALIAS(this_entry
)) &&
13675 (prev_entry
->no_cache
== this_entry
->no_cache
) &&
13676 (prev_entry
->permanent
== this_entry
->permanent
) &&
13677 (prev_entry
->map_aligned
== this_entry
->map_aligned
) &&
13678 (prev_entry
->zero_wired_pages
== this_entry
->zero_wired_pages
) &&
13679 (prev_entry
->used_for_jit
== this_entry
->used_for_jit
) &&
13680 /* from_reserved_zone: OK if that field doesn't match */
13681 (prev_entry
->iokit_acct
== this_entry
->iokit_acct
) &&
13682 (prev_entry
->vme_resilient_codesign
==
13683 this_entry
->vme_resilient_codesign
) &&
13684 (prev_entry
->vme_resilient_media
==
13685 this_entry
->vme_resilient_media
) &&
13687 (prev_entry
->wired_count
== this_entry
->wired_count
) &&
13688 (prev_entry
->user_wired_count
== this_entry
->user_wired_count
) &&
13690 ((prev_entry
->vme_atomic
== FALSE
) && (this_entry
->vme_atomic
== FALSE
)) &&
13691 (prev_entry
->in_transition
== FALSE
) &&
13692 (this_entry
->in_transition
== FALSE
) &&
13693 (prev_entry
->needs_wakeup
== FALSE
) &&
13694 (this_entry
->needs_wakeup
== FALSE
) &&
13695 (prev_entry
->is_shared
== FALSE
) &&
13696 (this_entry
->is_shared
== FALSE
) &&
13697 (prev_entry
->superpage_size
== FALSE
) &&
13698 (this_entry
->superpage_size
== FALSE
)
13700 vm_map_store_entry_unlink(map
, prev_entry
);
13701 assert(prev_entry
->vme_start
< this_entry
->vme_end
);
13702 if (prev_entry
->map_aligned
)
13703 assert(VM_MAP_PAGE_ALIGNED(prev_entry
->vme_start
,
13704 VM_MAP_PAGE_MASK(map
)));
13705 this_entry
->vme_start
= prev_entry
->vme_start
;
13706 VME_OFFSET_SET(this_entry
, VME_OFFSET(prev_entry
));
13708 if (map
->holelistenabled
) {
13709 vm_map_store_update_first_free(map
, this_entry
, TRUE
);
13712 if (prev_entry
->is_sub_map
) {
13713 vm_map_deallocate(VME_SUBMAP(prev_entry
));
13715 vm_object_deallocate(VME_OBJECT(prev_entry
));
13717 vm_map_entry_dispose(map
, prev_entry
);
13718 SAVE_HINT_MAP_WRITE(map
, this_entry
);
13719 counter(c_vm_map_simplified
++);
13726 vm_map_offset_t start
)
13728 vm_map_entry_t this_entry
;
13731 if (vm_map_lookup_entry(map
, start
, &this_entry
)) {
13732 vm_map_simplify_entry(map
, this_entry
);
13733 vm_map_simplify_entry(map
, this_entry
->vme_next
);
13735 counter(c_vm_map_simplify_called
++);
13736 vm_map_unlock(map
);
13740 vm_map_simplify_range(
13742 vm_map_offset_t start
,
13743 vm_map_offset_t end
)
13745 vm_map_entry_t entry
;
13748 * The map should be locked (for "write") by the caller.
13751 if (start
>= end
) {
13752 /* invalid address range */
13756 start
= vm_map_trunc_page(start
,
13757 VM_MAP_PAGE_MASK(map
));
13758 end
= vm_map_round_page(end
,
13759 VM_MAP_PAGE_MASK(map
));
13761 if (!vm_map_lookup_entry(map
, start
, &entry
)) {
13762 /* "start" is not mapped and "entry" ends before "start" */
13763 if (entry
== vm_map_to_entry(map
)) {
13764 /* start with first entry in the map */
13765 entry
= vm_map_first_entry(map
);
13767 /* start with next entry */
13768 entry
= entry
->vme_next
;
13772 while (entry
!= vm_map_to_entry(map
) &&
13773 entry
->vme_start
<= end
) {
13774 /* try and coalesce "entry" with its previous entry */
13775 vm_map_simplify_entry(map
, entry
);
13776 entry
= entry
->vme_next
;
13782 * Routine: vm_map_machine_attribute
13784 * Provide machine-specific attributes to mappings,
13785 * such as cachability etc. for machines that provide
13786 * them. NUMA architectures and machines with big/strange
13787 * caches will use this.
13789 * Responsibilities for locking and checking are handled here,
13790 * everything else in the pmap module. If any non-volatile
13791 * information must be kept, the pmap module should handle
13792 * it itself. [This assumes that attributes do not
13793 * need to be inherited, which seems ok to me]
13796 vm_map_machine_attribute(
13798 vm_map_offset_t start
,
13799 vm_map_offset_t end
,
13800 vm_machine_attribute_t attribute
,
13801 vm_machine_attribute_val_t
* value
) /* IN/OUT */
13804 vm_map_size_t sync_size
;
13805 vm_map_entry_t entry
;
13807 if (start
< vm_map_min(map
) || end
> vm_map_max(map
))
13808 return KERN_INVALID_ADDRESS
;
13810 /* Figure how much memory we need to flush (in page increments) */
13811 sync_size
= end
- start
;
13815 if (attribute
!= MATTR_CACHE
) {
13816 /* If we don't have to find physical addresses, we */
13817 /* don't have to do an explicit traversal here. */
13818 ret
= pmap_attribute(map
->pmap
, start
, end
-start
,
13820 vm_map_unlock(map
);
13824 ret
= KERN_SUCCESS
; /* Assume it all worked */
13827 if (vm_map_lookup_entry(map
, start
, &entry
)) {
13828 vm_map_size_t sub_size
;
13829 if((entry
->vme_end
- start
) > sync_size
) {
13830 sub_size
= sync_size
;
13833 sub_size
= entry
->vme_end
- start
;
13834 sync_size
-= sub_size
;
13836 if(entry
->is_sub_map
) {
13837 vm_map_offset_t sub_start
;
13838 vm_map_offset_t sub_end
;
13840 sub_start
= (start
- entry
->vme_start
)
13841 + VME_OFFSET(entry
);
13842 sub_end
= sub_start
+ sub_size
;
13843 vm_map_machine_attribute(
13849 if (VME_OBJECT(entry
)) {
13851 vm_object_t object
;
13852 vm_object_t base_object
;
13853 vm_object_t last_object
;
13854 vm_object_offset_t offset
;
13855 vm_object_offset_t base_offset
;
13856 vm_map_size_t range
;
13858 offset
= (start
- entry
->vme_start
)
13859 + VME_OFFSET(entry
);
13860 base_offset
= offset
;
13861 object
= VME_OBJECT(entry
);
13862 base_object
= object
;
13863 last_object
= NULL
;
13865 vm_object_lock(object
);
13868 m
= vm_page_lookup(
13871 if (m
&& !m
->fictitious
) {
13873 pmap_attribute_cache_sync(
13874 VM_PAGE_GET_PHYS_PAGE(m
),
13878 } else if (object
->shadow
) {
13879 offset
= offset
+ object
->vo_shadow_offset
;
13880 last_object
= object
;
13881 object
= object
->shadow
;
13882 vm_object_lock(last_object
->shadow
);
13883 vm_object_unlock(last_object
);
13886 range
-= PAGE_SIZE
;
13888 if (base_object
!= object
) {
13889 vm_object_unlock(object
);
13890 vm_object_lock(base_object
);
13891 object
= base_object
;
13893 /* Bump to the next page */
13894 base_offset
+= PAGE_SIZE
;
13895 offset
= base_offset
;
13897 vm_object_unlock(object
);
13902 vm_map_unlock(map
);
13903 return KERN_FAILURE
;
13908 vm_map_unlock(map
);
13914 * vm_map_behavior_set:
13916 * Sets the paging reference behavior of the specified address
13917 * range in the target map. Paging reference behavior affects
13918 * how pagein operations resulting from faults on the map will be
13922 vm_map_behavior_set(
13924 vm_map_offset_t start
,
13925 vm_map_offset_t end
,
13926 vm_behavior_t new_behavior
)
13928 vm_map_entry_t entry
;
13929 vm_map_entry_t temp_entry
;
13932 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
13933 map
, start
, end
, new_behavior
, 0);
13936 start
< vm_map_min(map
) ||
13937 end
> vm_map_max(map
)) {
13938 return KERN_NO_SPACE
;
13941 switch (new_behavior
) {
13944 * This first block of behaviors all set a persistent state on the specified
13945 * memory range. All we have to do here is to record the desired behavior
13946 * in the vm_map_entry_t's.
13949 case VM_BEHAVIOR_DEFAULT
:
13950 case VM_BEHAVIOR_RANDOM
:
13951 case VM_BEHAVIOR_SEQUENTIAL
:
13952 case VM_BEHAVIOR_RSEQNTL
:
13953 case VM_BEHAVIOR_ZERO_WIRED_PAGES
:
13957 * The entire address range must be valid for the map.
13958 * Note that vm_map_range_check() does a
13959 * vm_map_lookup_entry() internally and returns the
13960 * entry containing the start of the address range if
13961 * the entire range is valid.
13963 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
13964 entry
= temp_entry
;
13965 vm_map_clip_start(map
, entry
, start
);
13968 vm_map_unlock(map
);
13969 return(KERN_INVALID_ADDRESS
);
13972 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
13973 vm_map_clip_end(map
, entry
, end
);
13974 if (entry
->is_sub_map
) {
13975 assert(!entry
->use_pmap
);
13978 if( new_behavior
== VM_BEHAVIOR_ZERO_WIRED_PAGES
) {
13979 entry
->zero_wired_pages
= TRUE
;
13981 entry
->behavior
= new_behavior
;
13983 entry
= entry
->vme_next
;
13986 vm_map_unlock(map
);
13990 * The rest of these are different from the above in that they cause
13991 * an immediate action to take place as opposed to setting a behavior that
13992 * affects future actions.
13995 case VM_BEHAVIOR_WILLNEED
:
13996 return vm_map_willneed(map
, start
, end
);
13998 case VM_BEHAVIOR_DONTNEED
:
13999 return vm_map_msync(map
, start
, end
- start
, VM_SYNC_DEACTIVATE
| VM_SYNC_CONTIGUOUS
);
14001 case VM_BEHAVIOR_FREE
:
14002 return vm_map_msync(map
, start
, end
- start
, VM_SYNC_KILLPAGES
| VM_SYNC_CONTIGUOUS
);
14004 case VM_BEHAVIOR_REUSABLE
:
14005 return vm_map_reusable_pages(map
, start
, end
);
14007 case VM_BEHAVIOR_REUSE
:
14008 return vm_map_reuse_pages(map
, start
, end
);
14010 case VM_BEHAVIOR_CAN_REUSE
:
14011 return vm_map_can_reuse(map
, start
, end
);
14014 case VM_BEHAVIOR_PAGEOUT
:
14015 return vm_map_pageout(map
, start
, end
);
14016 #endif /* MACH_ASSERT */
14019 return(KERN_INVALID_ARGUMENT
);
14022 return(KERN_SUCCESS
);
14027 * Internals for madvise(MADV_WILLNEED) system call.
14029 * The present implementation is to do a read-ahead if the mapping corresponds
14030 * to a mapped regular file. If it's an anonymous mapping, then we do nothing
14031 * and basically ignore the "advice" (which we are always free to do).
14035 static kern_return_t
14038 vm_map_offset_t start
,
14039 vm_map_offset_t end
14042 vm_map_entry_t entry
;
14043 vm_object_t object
;
14044 memory_object_t pager
;
14045 struct vm_object_fault_info fault_info
;
14047 vm_object_size_t len
;
14048 vm_object_offset_t offset
;
14051 * Fill in static values in fault_info. Several fields get ignored by the code
14052 * we call, but we'll fill them in anyway since uninitialized fields are bad
14053 * when it comes to future backwards compatibility.
14056 fault_info
.interruptible
= THREAD_UNINT
; /* ignored value */
14057 fault_info
.behavior
= VM_BEHAVIOR_SEQUENTIAL
;
14058 fault_info
.no_cache
= FALSE
; /* ignored value */
14059 fault_info
.stealth
= TRUE
;
14060 fault_info
.io_sync
= FALSE
;
14061 fault_info
.cs_bypass
= FALSE
;
14062 fault_info
.mark_zf_absent
= FALSE
;
14063 fault_info
.batch_pmap_op
= FALSE
;
14066 * The MADV_WILLNEED operation doesn't require any changes to the
14067 * vm_map_entry_t's, so the read lock is sufficient.
14070 vm_map_lock_read(map
);
14073 * The madvise semantics require that the address range be fully
14074 * allocated with no holes. Otherwise, we're required to return
14078 if (! vm_map_range_check(map
, start
, end
, &entry
)) {
14079 vm_map_unlock_read(map
);
14080 return KERN_INVALID_ADDRESS
;
14084 * Examine each vm_map_entry_t in the range.
14086 for (; entry
!= vm_map_to_entry(map
) && start
< end
; ) {
14089 * The first time through, the start address could be anywhere
14090 * within the vm_map_entry we found. So adjust the offset to
14091 * correspond. After that, the offset will always be zero to
14092 * correspond to the beginning of the current vm_map_entry.
14094 offset
= (start
- entry
->vme_start
) + VME_OFFSET(entry
);
14097 * Set the length so we don't go beyond the end of the
14098 * map_entry or beyond the end of the range we were given.
14099 * This range could span also multiple map entries all of which
14100 * map different files, so make sure we only do the right amount
14101 * of I/O for each object. Note that it's possible for there
14102 * to be multiple map entries all referring to the same object
14103 * but with different page permissions, but it's not worth
14104 * trying to optimize that case.
14106 len
= MIN(entry
->vme_end
- start
, end
- start
);
14108 if ((vm_size_t
) len
!= len
) {
14109 /* 32-bit overflow */
14110 len
= (vm_size_t
) (0 - PAGE_SIZE
);
14112 fault_info
.cluster_size
= (vm_size_t
) len
;
14113 fault_info
.lo_offset
= offset
;
14114 fault_info
.hi_offset
= offset
+ len
;
14115 fault_info
.user_tag
= VME_ALIAS(entry
);
14116 fault_info
.pmap_options
= 0;
14117 if (entry
->iokit_acct
||
14118 (!entry
->is_sub_map
&& !entry
->use_pmap
)) {
14119 fault_info
.pmap_options
|= PMAP_OPTIONS_ALT_ACCT
;
14123 * If there's no read permission to this mapping, then just
14126 if ((entry
->protection
& VM_PROT_READ
) == 0) {
14127 entry
= entry
->vme_next
;
14128 start
= entry
->vme_start
;
14133 * Find the file object backing this map entry. If there is
14134 * none, then we simply ignore the "will need" advice for this
14135 * entry and go on to the next one.
14137 if ((object
= find_vnode_object(entry
)) == VM_OBJECT_NULL
) {
14138 entry
= entry
->vme_next
;
14139 start
= entry
->vme_start
;
14144 * The data_request() could take a long time, so let's
14145 * release the map lock to avoid blocking other threads.
14147 vm_map_unlock_read(map
);
14149 vm_object_paging_begin(object
);
14150 pager
= object
->pager
;
14151 vm_object_unlock(object
);
14154 * Get the data from the object asynchronously.
14156 * Note that memory_object_data_request() places limits on the
14157 * amount of I/O it will do. Regardless of the len we
14158 * specified, it won't do more than MAX_UPL_TRANSFER_BYTES and it
14159 * silently truncates the len to that size. This isn't
14160 * necessarily bad since madvise shouldn't really be used to
14161 * page in unlimited amounts of data. Other Unix variants
14162 * limit the willneed case as well. If this turns out to be an
14163 * issue for developers, then we can always adjust the policy
14164 * here and still be backwards compatible since this is all
14167 kr
= memory_object_data_request(
14169 offset
+ object
->paging_offset
,
14172 (memory_object_fault_info_t
)&fault_info
);
14174 vm_object_lock(object
);
14175 vm_object_paging_end(object
);
14176 vm_object_unlock(object
);
14179 * If we couldn't do the I/O for some reason, just give up on
14180 * the madvise. We still return success to the user since
14181 * madvise isn't supposed to fail when the advice can't be
14184 if (kr
!= KERN_SUCCESS
) {
14185 return KERN_SUCCESS
;
14189 if (start
>= end
) {
14191 return KERN_SUCCESS
;
14194 /* look up next entry */
14195 vm_map_lock_read(map
);
14196 if (! vm_map_lookup_entry(map
, start
, &entry
)) {
14198 * There's a new hole in the address range.
14200 vm_map_unlock_read(map
);
14201 return KERN_INVALID_ADDRESS
;
14205 vm_map_unlock_read(map
);
14206 return KERN_SUCCESS
;
14210 vm_map_entry_is_reusable(
14211 vm_map_entry_t entry
)
14213 /* Only user map entries */
14215 vm_object_t object
;
14217 if (entry
->is_sub_map
) {
14221 switch (VME_ALIAS(entry
)) {
14222 case VM_MEMORY_MALLOC
:
14223 case VM_MEMORY_MALLOC_SMALL
:
14224 case VM_MEMORY_MALLOC_LARGE
:
14225 case VM_MEMORY_REALLOC
:
14226 case VM_MEMORY_MALLOC_TINY
:
14227 case VM_MEMORY_MALLOC_LARGE_REUSABLE
:
14228 case VM_MEMORY_MALLOC_LARGE_REUSED
:
14230 * This is a malloc() memory region: check if it's still
14231 * in its original state and can be re-used for more
14232 * malloc() allocations.
14237 * Not a malloc() memory region: let the caller decide if
14243 if (entry
->is_shared
||
14244 entry
->is_sub_map
||
14245 entry
->in_transition
||
14246 entry
->protection
!= VM_PROT_DEFAULT
||
14247 entry
->max_protection
!= VM_PROT_ALL
||
14248 entry
->inheritance
!= VM_INHERIT_DEFAULT
||
14250 entry
->permanent
||
14251 entry
->superpage_size
!= FALSE
||
14252 entry
->zero_wired_pages
||
14253 entry
->wired_count
!= 0 ||
14254 entry
->user_wired_count
!= 0) {
14258 object
= VME_OBJECT(entry
);
14259 if (object
== VM_OBJECT_NULL
) {
14265 * Let's proceed even if the VM object is potentially
14267 * We check for this later when processing the actual
14268 * VM pages, so the contents will be safe if shared.
14270 * But we can still mark this memory region as "reusable" to
14271 * acknowledge that the caller did let us know that the memory
14272 * could be re-used and should not be penalized for holding
14273 * on to it. This allows its "resident size" to not include
14274 * the reusable range.
14276 object
->ref_count
== 1 &&
14278 object
->wired_page_count
== 0 &&
14279 object
->copy
== VM_OBJECT_NULL
&&
14280 object
->shadow
== VM_OBJECT_NULL
&&
14281 object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
14282 object
->internal
&&
14283 !object
->true_share
&&
14284 object
->wimg_bits
== VM_WIMG_USE_DEFAULT
&&
14285 !object
->code_signed
) {
14293 static kern_return_t
14294 vm_map_reuse_pages(
14296 vm_map_offset_t start
,
14297 vm_map_offset_t end
)
14299 vm_map_entry_t entry
;
14300 vm_object_t object
;
14301 vm_object_offset_t start_offset
, end_offset
;
14304 * The MADV_REUSE operation doesn't require any changes to the
14305 * vm_map_entry_t's, so the read lock is sufficient.
14308 vm_map_lock_read(map
);
14309 assert(map
->pmap
!= kernel_pmap
); /* protect alias access */
14312 * The madvise semantics require that the address range be fully
14313 * allocated with no holes. Otherwise, we're required to return
14317 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
14318 vm_map_unlock_read(map
);
14319 vm_page_stats_reusable
.reuse_pages_failure
++;
14320 return KERN_INVALID_ADDRESS
;
14324 * Examine each vm_map_entry_t in the range.
14326 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
14327 entry
= entry
->vme_next
) {
14329 * Sanity check on the VM map entry.
14331 if (! vm_map_entry_is_reusable(entry
)) {
14332 vm_map_unlock_read(map
);
14333 vm_page_stats_reusable
.reuse_pages_failure
++;
14334 return KERN_INVALID_ADDRESS
;
14338 * The first time through, the start address could be anywhere
14339 * within the vm_map_entry we found. So adjust the offset to
14342 if (entry
->vme_start
< start
) {
14343 start_offset
= start
- entry
->vme_start
;
14347 end_offset
= MIN(end
, entry
->vme_end
) - entry
->vme_start
;
14348 start_offset
+= VME_OFFSET(entry
);
14349 end_offset
+= VME_OFFSET(entry
);
14351 assert(!entry
->is_sub_map
);
14352 object
= VME_OBJECT(entry
);
14353 if (object
!= VM_OBJECT_NULL
) {
14354 vm_object_lock(object
);
14355 vm_object_reuse_pages(object
, start_offset
, end_offset
,
14357 vm_object_unlock(object
);
14360 if (VME_ALIAS(entry
) == VM_MEMORY_MALLOC_LARGE_REUSABLE
) {
14363 * We do not hold the VM map exclusively here.
14364 * The "alias" field is not that critical, so it's
14365 * safe to update it here, as long as it is the only
14366 * one that can be modified while holding the VM map
14369 VME_ALIAS_SET(entry
, VM_MEMORY_MALLOC_LARGE_REUSED
);
14373 vm_map_unlock_read(map
);
14374 vm_page_stats_reusable
.reuse_pages_success
++;
14375 return KERN_SUCCESS
;
14379 static kern_return_t
14380 vm_map_reusable_pages(
14382 vm_map_offset_t start
,
14383 vm_map_offset_t end
)
14385 vm_map_entry_t entry
;
14386 vm_object_t object
;
14387 vm_object_offset_t start_offset
, end_offset
;
14388 vm_map_offset_t pmap_offset
;
14391 * The MADV_REUSABLE operation doesn't require any changes to the
14392 * vm_map_entry_t's, so the read lock is sufficient.
14395 vm_map_lock_read(map
);
14396 assert(map
->pmap
!= kernel_pmap
); /* protect alias access */
14399 * The madvise semantics require that the address range be fully
14400 * allocated with no holes. Otherwise, we're required to return
14404 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
14405 vm_map_unlock_read(map
);
14406 vm_page_stats_reusable
.reusable_pages_failure
++;
14407 return KERN_INVALID_ADDRESS
;
14411 * Examine each vm_map_entry_t in the range.
14413 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
14414 entry
= entry
->vme_next
) {
14415 int kill_pages
= 0;
14418 * Sanity check on the VM map entry.
14420 if (! vm_map_entry_is_reusable(entry
)) {
14421 vm_map_unlock_read(map
);
14422 vm_page_stats_reusable
.reusable_pages_failure
++;
14423 return KERN_INVALID_ADDRESS
;
14426 if (! (entry
->protection
& VM_PROT_WRITE
) && !entry
->used_for_jit
) {
14427 /* not writable: can't discard contents */
14428 vm_map_unlock_read(map
);
14429 vm_page_stats_reusable
.reusable_nonwritable
++;
14430 vm_page_stats_reusable
.reusable_pages_failure
++;
14431 return KERN_PROTECTION_FAILURE
;
14435 * The first time through, the start address could be anywhere
14436 * within the vm_map_entry we found. So adjust the offset to
14439 if (entry
->vme_start
< start
) {
14440 start_offset
= start
- entry
->vme_start
;
14441 pmap_offset
= start
;
14444 pmap_offset
= entry
->vme_start
;
14446 end_offset
= MIN(end
, entry
->vme_end
) - entry
->vme_start
;
14447 start_offset
+= VME_OFFSET(entry
);
14448 end_offset
+= VME_OFFSET(entry
);
14450 assert(!entry
->is_sub_map
);
14451 object
= VME_OBJECT(entry
);
14452 if (object
== VM_OBJECT_NULL
)
14456 vm_object_lock(object
);
14457 if (((object
->ref_count
== 1) ||
14458 (object
->copy_strategy
!= MEMORY_OBJECT_COPY_SYMMETRIC
&&
14459 object
->copy
== VM_OBJECT_NULL
)) &&
14460 object
->shadow
== VM_OBJECT_NULL
&&
14462 * "iokit_acct" entries are billed for their virtual size
14463 * (rather than for their resident pages only), so they
14464 * wouldn't benefit from making pages reusable, and it
14465 * would be hard to keep track of pages that are both
14466 * "iokit_acct" and "reusable" in the pmap stats and
14469 !(entry
->iokit_acct
||
14470 (!entry
->is_sub_map
&& !entry
->use_pmap
))) {
14471 if (object
->ref_count
!= 1) {
14472 vm_page_stats_reusable
.reusable_shared
++;
14478 if (kill_pages
!= -1) {
14479 vm_object_deactivate_pages(object
,
14481 end_offset
- start_offset
,
14483 TRUE
/*reusable_pages*/,
14487 vm_page_stats_reusable
.reusable_pages_shared
++;
14489 vm_object_unlock(object
);
14491 if (VME_ALIAS(entry
) == VM_MEMORY_MALLOC_LARGE
||
14492 VME_ALIAS(entry
) == VM_MEMORY_MALLOC_LARGE_REUSED
) {
14495 * We do not hold the VM map exclusively here.
14496 * The "alias" field is not that critical, so it's
14497 * safe to update it here, as long as it is the only
14498 * one that can be modified while holding the VM map
14501 VME_ALIAS_SET(entry
, VM_MEMORY_MALLOC_LARGE_REUSABLE
);
14505 vm_map_unlock_read(map
);
14506 vm_page_stats_reusable
.reusable_pages_success
++;
14507 return KERN_SUCCESS
;
14511 static kern_return_t
14514 vm_map_offset_t start
,
14515 vm_map_offset_t end
)
14517 vm_map_entry_t entry
;
14520 * The MADV_REUSABLE operation doesn't require any changes to the
14521 * vm_map_entry_t's, so the read lock is sufficient.
14524 vm_map_lock_read(map
);
14525 assert(map
->pmap
!= kernel_pmap
); /* protect alias access */
14528 * The madvise semantics require that the address range be fully
14529 * allocated with no holes. Otherwise, we're required to return
14533 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
14534 vm_map_unlock_read(map
);
14535 vm_page_stats_reusable
.can_reuse_failure
++;
14536 return KERN_INVALID_ADDRESS
;
14540 * Examine each vm_map_entry_t in the range.
14542 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
14543 entry
= entry
->vme_next
) {
14545 * Sanity check on the VM map entry.
14547 if (! vm_map_entry_is_reusable(entry
)) {
14548 vm_map_unlock_read(map
);
14549 vm_page_stats_reusable
.can_reuse_failure
++;
14550 return KERN_INVALID_ADDRESS
;
14554 vm_map_unlock_read(map
);
14555 vm_page_stats_reusable
.can_reuse_success
++;
14556 return KERN_SUCCESS
;
14561 static kern_return_t
14564 vm_map_offset_t start
,
14565 vm_map_offset_t end
)
14567 vm_map_entry_t entry
;
14570 * The MADV_PAGEOUT operation doesn't require any changes to the
14571 * vm_map_entry_t's, so the read lock is sufficient.
14574 vm_map_lock_read(map
);
14577 * The madvise semantics require that the address range be fully
14578 * allocated with no holes. Otherwise, we're required to return
14582 if (!vm_map_range_check(map
, start
, end
, &entry
)) {
14583 vm_map_unlock_read(map
);
14584 return KERN_INVALID_ADDRESS
;
14588 * Examine each vm_map_entry_t in the range.
14590 for (; entry
!= vm_map_to_entry(map
) && entry
->vme_start
< end
;
14591 entry
= entry
->vme_next
) {
14592 vm_object_t object
;
14595 * Sanity check on the VM map entry.
14597 if (entry
->is_sub_map
) {
14599 vm_map_offset_t submap_start
;
14600 vm_map_offset_t submap_end
;
14601 vm_map_entry_t submap_entry
;
14603 submap
= VME_SUBMAP(entry
);
14604 submap_start
= VME_OFFSET(entry
);
14605 submap_end
= submap_start
+ (entry
->vme_end
-
14608 vm_map_lock_read(submap
);
14610 if (! vm_map_range_check(submap
,
14614 vm_map_unlock_read(submap
);
14615 vm_map_unlock_read(map
);
14616 return KERN_INVALID_ADDRESS
;
14619 object
= VME_OBJECT(submap_entry
);
14620 if (submap_entry
->is_sub_map
||
14621 object
== VM_OBJECT_NULL
||
14622 !object
->internal
) {
14623 vm_map_unlock_read(submap
);
14627 vm_object_pageout(object
);
14629 vm_map_unlock_read(submap
);
14630 submap
= VM_MAP_NULL
;
14631 submap_entry
= VM_MAP_ENTRY_NULL
;
14635 object
= VME_OBJECT(entry
);
14636 if (entry
->is_sub_map
||
14637 object
== VM_OBJECT_NULL
||
14638 !object
->internal
) {
14642 vm_object_pageout(object
);
14645 vm_map_unlock_read(map
);
14646 return KERN_SUCCESS
;
14648 #endif /* MACH_ASSERT */
14652 * Routine: vm_map_entry_insert
14654 * Descritpion: This routine inserts a new vm_entry in a locked map.
14657 vm_map_entry_insert(
14659 vm_map_entry_t insp_entry
,
14660 vm_map_offset_t start
,
14661 vm_map_offset_t end
,
14662 vm_object_t object
,
14663 vm_object_offset_t offset
,
14664 boolean_t needs_copy
,
14665 boolean_t is_shared
,
14666 boolean_t in_transition
,
14667 vm_prot_t cur_protection
,
14668 vm_prot_t max_protection
,
14669 vm_behavior_t behavior
,
14670 vm_inherit_t inheritance
,
14671 unsigned wired_count
,
14672 boolean_t no_cache
,
14673 boolean_t permanent
,
14674 unsigned int superpage_size
,
14675 boolean_t clear_map_aligned
,
14676 boolean_t is_submap
,
14677 boolean_t used_for_jit
,
14680 vm_map_entry_t new_entry
;
14682 assert(insp_entry
!= (vm_map_entry_t
)0);
14684 new_entry
= vm_map_entry_create(map
, !map
->hdr
.entries_pageable
);
14686 if (VM_MAP_PAGE_SHIFT(map
) != PAGE_SHIFT
) {
14687 new_entry
->map_aligned
= TRUE
;
14689 new_entry
->map_aligned
= FALSE
;
14691 if (clear_map_aligned
&&
14692 (! VM_MAP_PAGE_ALIGNED(start
, VM_MAP_PAGE_MASK(map
)) ||
14693 ! VM_MAP_PAGE_ALIGNED(end
, VM_MAP_PAGE_MASK(map
)))) {
14694 new_entry
->map_aligned
= FALSE
;
14697 new_entry
->vme_start
= start
;
14698 new_entry
->vme_end
= end
;
14699 assert(page_aligned(new_entry
->vme_start
));
14700 assert(page_aligned(new_entry
->vme_end
));
14701 if (new_entry
->map_aligned
) {
14702 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_start
,
14703 VM_MAP_PAGE_MASK(map
)));
14704 assert(VM_MAP_PAGE_ALIGNED(new_entry
->vme_end
,
14705 VM_MAP_PAGE_MASK(map
)));
14707 assert(new_entry
->vme_start
< new_entry
->vme_end
);
14709 VME_OBJECT_SET(new_entry
, object
);
14710 VME_OFFSET_SET(new_entry
, offset
);
14711 new_entry
->is_shared
= is_shared
;
14712 new_entry
->is_sub_map
= is_submap
;
14713 new_entry
->needs_copy
= needs_copy
;
14714 new_entry
->in_transition
= in_transition
;
14715 new_entry
->needs_wakeup
= FALSE
;
14716 new_entry
->inheritance
= inheritance
;
14717 new_entry
->protection
= cur_protection
;
14718 new_entry
->max_protection
= max_protection
;
14719 new_entry
->behavior
= behavior
;
14720 new_entry
->wired_count
= wired_count
;
14721 new_entry
->user_wired_count
= 0;
14724 * submap: "use_pmap" means "nested".
14727 new_entry
->use_pmap
= FALSE
;
14730 * object: "use_pmap" means "use pmap accounting" for footprint.
14733 new_entry
->use_pmap
= TRUE
;
14735 VME_ALIAS_SET(new_entry
, alias
);
14736 new_entry
->zero_wired_pages
= FALSE
;
14737 new_entry
->no_cache
= no_cache
;
14738 new_entry
->permanent
= permanent
;
14739 if (superpage_size
)
14740 new_entry
->superpage_size
= TRUE
;
14742 new_entry
->superpage_size
= FALSE
;
14744 if (!(map
->jit_entry_exists
)){
14745 new_entry
->used_for_jit
= TRUE
;
14746 map
->jit_entry_exists
= TRUE
;
14748 /* Tell the pmap that it supports JIT. */
14749 pmap_set_jit_entitled(map
->pmap
);
14752 new_entry
->used_for_jit
= FALSE
;
14754 new_entry
->iokit_acct
= FALSE
;
14755 new_entry
->vme_resilient_codesign
= FALSE
;
14756 new_entry
->vme_resilient_media
= FALSE
;
14757 new_entry
->vme_atomic
= FALSE
;
14760 * Insert the new entry into the list.
14763 vm_map_store_entry_link(map
, insp_entry
, new_entry
);
14764 map
->size
+= end
- start
;
14767 * Update the free space hint and the lookup hint.
14770 SAVE_HINT_MAP_WRITE(map
, new_entry
);
14775 * Routine: vm_map_remap_extract
14777 * Descritpion: This routine returns a vm_entry list from a map.
14779 static kern_return_t
14780 vm_map_remap_extract(
14782 vm_map_offset_t addr
,
14783 vm_map_size_t size
,
14785 struct vm_map_header
*map_header
,
14786 vm_prot_t
*cur_protection
,
14787 vm_prot_t
*max_protection
,
14788 /* What, no behavior? */
14789 vm_inherit_t inheritance
,
14790 boolean_t pageable
,
14791 boolean_t same_map
,
14792 vm_map_kernel_flags_t vmk_flags
)
14794 kern_return_t result
;
14795 vm_map_size_t mapped_size
;
14796 vm_map_size_t tmp_size
;
14797 vm_map_entry_t src_entry
; /* result of last map lookup */
14798 vm_map_entry_t new_entry
;
14799 vm_object_offset_t offset
;
14800 vm_map_offset_t map_address
;
14801 vm_map_offset_t src_start
; /* start of entry to map */
14802 vm_map_offset_t src_end
; /* end of region to be mapped */
14803 vm_object_t object
;
14804 vm_map_version_t version
;
14805 boolean_t src_needs_copy
;
14806 boolean_t new_entry_needs_copy
;
14808 assert(map
!= VM_MAP_NULL
);
14810 assert(size
== vm_map_round_page(size
, PAGE_MASK
));
14811 assert(inheritance
== VM_INHERIT_NONE
||
14812 inheritance
== VM_INHERIT_COPY
||
14813 inheritance
== VM_INHERIT_SHARE
);
14816 * Compute start and end of region.
14818 src_start
= vm_map_trunc_page(addr
, PAGE_MASK
);
14819 src_end
= vm_map_round_page(src_start
+ size
, PAGE_MASK
);
14823 * Initialize map_header.
14825 map_header
->links
.next
= (struct vm_map_entry
*)&map_header
->links
;
14826 map_header
->links
.prev
= (struct vm_map_entry
*)&map_header
->links
;
14827 map_header
->nentries
= 0;
14828 map_header
->entries_pageable
= pageable
;
14829 map_header
->page_shift
= PAGE_SHIFT
;
14831 vm_map_store_init( map_header
);
14833 *cur_protection
= VM_PROT_ALL
;
14834 *max_protection
= VM_PROT_ALL
;
14838 result
= KERN_SUCCESS
;
14841 * The specified source virtual space might correspond to
14842 * multiple map entries, need to loop on them.
14845 while (mapped_size
!= size
) {
14846 vm_map_size_t entry_size
;
14849 * Find the beginning of the region.
14851 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
14852 result
= KERN_INVALID_ADDRESS
;
14856 if (src_start
< src_entry
->vme_start
||
14857 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
14858 result
= KERN_INVALID_ADDRESS
;
14862 tmp_size
= size
- mapped_size
;
14863 if (src_end
> src_entry
->vme_end
)
14864 tmp_size
-= (src_end
- src_entry
->vme_end
);
14866 entry_size
= (vm_map_size_t
)(src_entry
->vme_end
-
14867 src_entry
->vme_start
);
14869 if(src_entry
->is_sub_map
) {
14870 vm_map_reference(VME_SUBMAP(src_entry
));
14871 object
= VM_OBJECT_NULL
;
14873 object
= VME_OBJECT(src_entry
);
14874 if (src_entry
->iokit_acct
) {
14876 * This entry uses "IOKit accounting".
14878 } else if (object
!= VM_OBJECT_NULL
&&
14879 object
->purgable
!= VM_PURGABLE_DENY
) {
14881 * Purgeable objects have their own accounting:
14882 * no pmap accounting for them.
14884 assert(!src_entry
->use_pmap
);
14887 * Not IOKit or purgeable:
14888 * must be accounted by pmap stats.
14890 assert(src_entry
->use_pmap
);
14893 if (object
== VM_OBJECT_NULL
) {
14894 object
= vm_object_allocate(entry_size
);
14895 VME_OFFSET_SET(src_entry
, 0);
14896 VME_OBJECT_SET(src_entry
, object
);
14897 } else if (object
->copy_strategy
!=
14898 MEMORY_OBJECT_COPY_SYMMETRIC
) {
14900 * We are already using an asymmetric
14901 * copy, and therefore we already have
14902 * the right object.
14904 assert(!src_entry
->needs_copy
);
14905 } else if (src_entry
->needs_copy
|| object
->shadowed
||
14906 (object
->internal
&& !object
->true_share
&&
14907 !src_entry
->is_shared
&&
14908 object
->vo_size
> entry_size
)) {
14910 VME_OBJECT_SHADOW(src_entry
, entry_size
);
14912 if (!src_entry
->needs_copy
&&
14913 (src_entry
->protection
& VM_PROT_WRITE
)) {
14916 assert(!pmap_has_prot_policy(src_entry
->protection
));
14918 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
14920 if (override_nx(map
,
14921 VME_ALIAS(src_entry
))
14923 prot
|= VM_PROT_EXECUTE
;
14925 assert(!pmap_has_prot_policy(prot
));
14927 if(map
->mapped_in_other_pmaps
) {
14928 vm_object_pmap_protect(
14929 VME_OBJECT(src_entry
),
14930 VME_OFFSET(src_entry
),
14933 src_entry
->vme_start
,
14936 pmap_protect(vm_map_pmap(map
),
14937 src_entry
->vme_start
,
14938 src_entry
->vme_end
,
14943 object
= VME_OBJECT(src_entry
);
14944 src_entry
->needs_copy
= FALSE
;
14948 vm_object_lock(object
);
14949 vm_object_reference_locked(object
); /* object ref. for new entry */
14950 if (object
->copy_strategy
==
14951 MEMORY_OBJECT_COPY_SYMMETRIC
) {
14952 object
->copy_strategy
=
14953 MEMORY_OBJECT_COPY_DELAY
;
14955 vm_object_unlock(object
);
14958 offset
= (VME_OFFSET(src_entry
) +
14959 (src_start
- src_entry
->vme_start
));
14961 new_entry
= _vm_map_entry_create(map_header
, !map_header
->entries_pageable
);
14962 vm_map_entry_copy(new_entry
, src_entry
);
14963 if (new_entry
->is_sub_map
) {
14964 /* clr address space specifics */
14965 new_entry
->use_pmap
= FALSE
;
14968 new_entry
->map_aligned
= FALSE
;
14970 new_entry
->vme_start
= map_address
;
14971 new_entry
->vme_end
= map_address
+ tmp_size
;
14972 assert(new_entry
->vme_start
< new_entry
->vme_end
);
14973 if (copy
&& vmk_flags
.vmkf_remap_prot_copy
) {
14975 * Remapping for vm_map_protect(VM_PROT_COPY)
14976 * to convert a read-only mapping into a
14977 * copy-on-write version of itself but
14978 * with write access:
14979 * keep the original inheritance and add
14980 * VM_PROT_WRITE to the max protection.
14982 new_entry
->inheritance
= src_entry
->inheritance
;
14983 new_entry
->max_protection
|= VM_PROT_WRITE
;
14985 new_entry
->inheritance
= inheritance
;
14987 VME_OFFSET_SET(new_entry
, offset
);
14990 * The new region has to be copied now if required.
14995 * Cannot allow an entry describing a JIT
14996 * region to be shared across address spaces.
14998 if (src_entry
->used_for_jit
== TRUE
&& !same_map
) {
14999 result
= KERN_INVALID_ARGUMENT
;
15002 src_entry
->is_shared
= TRUE
;
15003 new_entry
->is_shared
= TRUE
;
15004 if (!(new_entry
->is_sub_map
))
15005 new_entry
->needs_copy
= FALSE
;
15007 } else if (src_entry
->is_sub_map
) {
15008 /* make this a COW sub_map if not already */
15009 assert(new_entry
->wired_count
== 0);
15010 new_entry
->needs_copy
= TRUE
;
15011 object
= VM_OBJECT_NULL
;
15012 } else if (src_entry
->wired_count
== 0 &&
15013 vm_object_copy_quickly(&VME_OBJECT(new_entry
),
15014 VME_OFFSET(new_entry
),
15015 (new_entry
->vme_end
-
15016 new_entry
->vme_start
),
15018 &new_entry_needs_copy
)) {
15020 new_entry
->needs_copy
= new_entry_needs_copy
;
15021 new_entry
->is_shared
= FALSE
;
15024 * Handle copy_on_write semantics.
15026 if (src_needs_copy
&& !src_entry
->needs_copy
) {
15029 assert(!pmap_has_prot_policy(src_entry
->protection
));
15031 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
15033 if (override_nx(map
,
15034 VME_ALIAS(src_entry
))
15036 prot
|= VM_PROT_EXECUTE
;
15038 assert(!pmap_has_prot_policy(prot
));
15040 vm_object_pmap_protect(object
,
15043 ((src_entry
->is_shared
15044 || map
->mapped_in_other_pmaps
) ?
15045 PMAP_NULL
: map
->pmap
),
15046 src_entry
->vme_start
,
15049 assert(src_entry
->wired_count
== 0);
15050 src_entry
->needs_copy
= TRUE
;
15053 * Throw away the old object reference of the new entry.
15055 vm_object_deallocate(object
);
15058 new_entry
->is_shared
= FALSE
;
15061 * The map can be safely unlocked since we
15062 * already hold a reference on the object.
15064 * Record the timestamp of the map for later
15065 * verification, and unlock the map.
15067 version
.main_timestamp
= map
->timestamp
;
15068 vm_map_unlock(map
); /* Increments timestamp once! */
15071 * Perform the copy.
15073 if (src_entry
->wired_count
> 0) {
15074 vm_object_lock(object
);
15075 result
= vm_object_copy_slowly(
15078 (new_entry
->vme_end
-
15079 new_entry
->vme_start
),
15081 &VME_OBJECT(new_entry
));
15083 VME_OFFSET_SET(new_entry
, 0);
15084 new_entry
->needs_copy
= FALSE
;
15086 vm_object_offset_t new_offset
;
15088 new_offset
= VME_OFFSET(new_entry
);
15089 result
= vm_object_copy_strategically(
15092 (new_entry
->vme_end
-
15093 new_entry
->vme_start
),
15094 &VME_OBJECT(new_entry
),
15096 &new_entry_needs_copy
);
15097 if (new_offset
!= VME_OFFSET(new_entry
)) {
15098 VME_OFFSET_SET(new_entry
, new_offset
);
15101 new_entry
->needs_copy
= new_entry_needs_copy
;
15105 * Throw away the old object reference of the new entry.
15107 vm_object_deallocate(object
);
15109 if (result
!= KERN_SUCCESS
&&
15110 result
!= KERN_MEMORY_RESTART_COPY
) {
15111 _vm_map_entry_dispose(map_header
, new_entry
);
15117 * Verify that the map has not substantially
15118 * changed while the copy was being made.
15122 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
15124 * Simple version comparison failed.
15126 * Retry the lookup and verify that the
15127 * same object/offset are still present.
15129 vm_object_deallocate(VME_OBJECT(new_entry
));
15130 _vm_map_entry_dispose(map_header
, new_entry
);
15131 if (result
== KERN_MEMORY_RESTART_COPY
)
15132 result
= KERN_SUCCESS
;
15136 if (result
== KERN_MEMORY_RESTART_COPY
) {
15137 vm_object_reference(object
);
15142 _vm_map_store_entry_link(map_header
,
15143 map_header
->links
.prev
, new_entry
);
15145 /*Protections for submap mapping are irrelevant here*/
15146 if( !src_entry
->is_sub_map
) {
15147 *cur_protection
&= src_entry
->protection
;
15148 *max_protection
&= src_entry
->max_protection
;
15150 map_address
+= tmp_size
;
15151 mapped_size
+= tmp_size
;
15152 src_start
+= tmp_size
;
15156 vm_map_unlock(map
);
15157 if (result
!= KERN_SUCCESS
) {
15159 * Free all allocated elements.
15161 for (src_entry
= map_header
->links
.next
;
15162 src_entry
!= (struct vm_map_entry
*)&map_header
->links
;
15163 src_entry
= new_entry
) {
15164 new_entry
= src_entry
->vme_next
;
15165 _vm_map_store_entry_unlink(map_header
, src_entry
);
15166 if (src_entry
->is_sub_map
) {
15167 vm_map_deallocate(VME_SUBMAP(src_entry
));
15169 vm_object_deallocate(VME_OBJECT(src_entry
));
15171 _vm_map_entry_dispose(map_header
, src_entry
);
15178 * Routine: vm_remap
15180 * Map portion of a task's address space.
15181 * Mapped region must not overlap more than
15182 * one vm memory object. Protections and
15183 * inheritance attributes remain the same
15184 * as in the original task and are out parameters.
15185 * Source and Target task can be identical
15186 * Other attributes are identical as for vm_map()
15190 vm_map_t target_map
,
15191 vm_map_address_t
*address
,
15192 vm_map_size_t size
,
15193 vm_map_offset_t mask
,
15195 vm_map_kernel_flags_t vmk_flags
,
15198 vm_map_offset_t memory_address
,
15200 vm_prot_t
*cur_protection
,
15201 vm_prot_t
*max_protection
,
15202 vm_inherit_t inheritance
)
15204 kern_return_t result
;
15205 vm_map_entry_t entry
;
15206 vm_map_entry_t insp_entry
= VM_MAP_ENTRY_NULL
;
15207 vm_map_entry_t new_entry
;
15208 struct vm_map_header map_header
;
15209 vm_map_offset_t offset_in_mapping
;
15211 if (target_map
== VM_MAP_NULL
)
15212 return KERN_INVALID_ARGUMENT
;
15214 switch (inheritance
) {
15215 case VM_INHERIT_NONE
:
15216 case VM_INHERIT_COPY
:
15217 case VM_INHERIT_SHARE
:
15218 if (size
!= 0 && src_map
!= VM_MAP_NULL
)
15222 return KERN_INVALID_ARGUMENT
;
15226 * If the user is requesting that we return the address of the
15227 * first byte of the data (rather than the base of the page),
15228 * then we use different rounding semantics: specifically,
15229 * we assume that (memory_address, size) describes a region
15230 * all of whose pages we must cover, rather than a base to be truncated
15231 * down and a size to be added to that base. So we figure out
15232 * the highest page that the requested region includes and make
15233 * sure that the size will cover it.
15235 * The key example we're worried about it is of the form:
15237 * memory_address = 0x1ff0, size = 0x20
15239 * With the old semantics, we round down the memory_address to 0x1000
15240 * and round up the size to 0x1000, resulting in our covering *only*
15241 * page 0x1000. With the new semantics, we'd realize that the region covers
15242 * 0x1ff0-0x2010, and compute a size of 0x2000. Thus, we cover both page
15243 * 0x1000 and page 0x2000 in the region we remap.
15245 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
15246 offset_in_mapping
= memory_address
- vm_map_trunc_page(memory_address
, PAGE_MASK
);
15247 size
= vm_map_round_page(memory_address
+ size
- vm_map_trunc_page(memory_address
, PAGE_MASK
), PAGE_MASK
);
15249 size
= vm_map_round_page(size
, PAGE_MASK
);
15252 return KERN_INVALID_ARGUMENT
;
15255 result
= vm_map_remap_extract(src_map
, memory_address
,
15256 size
, copy
, &map_header
,
15260 target_map
->hdr
.entries_pageable
,
15261 src_map
== target_map
,
15264 if (result
!= KERN_SUCCESS
) {
15269 * Allocate/check a range of free virtual address
15270 * space for the target
15272 *address
= vm_map_trunc_page(*address
,
15273 VM_MAP_PAGE_MASK(target_map
));
15274 vm_map_lock(target_map
);
15275 result
= vm_map_remap_range_allocate(target_map
, address
, size
,
15276 mask
, flags
, vmk_flags
, tag
,
15279 for (entry
= map_header
.links
.next
;
15280 entry
!= (struct vm_map_entry
*)&map_header
.links
;
15281 entry
= new_entry
) {
15282 new_entry
= entry
->vme_next
;
15283 _vm_map_store_entry_unlink(&map_header
, entry
);
15284 if (result
== KERN_SUCCESS
) {
15285 if (flags
& VM_FLAGS_RESILIENT_CODESIGN
) {
15286 /* no codesigning -> read-only access */
15287 assert(!entry
->used_for_jit
);
15288 entry
->max_protection
= VM_PROT_READ
;
15289 entry
->protection
= VM_PROT_READ
;
15290 entry
->vme_resilient_codesign
= TRUE
;
15292 entry
->vme_start
+= *address
;
15293 entry
->vme_end
+= *address
;
15294 assert(!entry
->map_aligned
);
15295 vm_map_store_entry_link(target_map
, insp_entry
, entry
);
15296 insp_entry
= entry
;
15298 if (!entry
->is_sub_map
) {
15299 vm_object_deallocate(VME_OBJECT(entry
));
15301 vm_map_deallocate(VME_SUBMAP(entry
));
15303 _vm_map_entry_dispose(&map_header
, entry
);
15307 if (flags
& VM_FLAGS_RESILIENT_CODESIGN
) {
15308 *cur_protection
= VM_PROT_READ
;
15309 *max_protection
= VM_PROT_READ
;
15312 if( target_map
->disable_vmentry_reuse
== TRUE
) {
15313 assert(!target_map
->is_nested_map
);
15314 if( target_map
->highest_entry_end
< insp_entry
->vme_end
){
15315 target_map
->highest_entry_end
= insp_entry
->vme_end
;
15319 if (result
== KERN_SUCCESS
) {
15320 target_map
->size
+= size
;
15321 SAVE_HINT_MAP_WRITE(target_map
, insp_entry
);
15324 vm_map_unlock(target_map
);
15326 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
15327 result
= vm_map_wire_kernel(target_map
, *address
,
15328 *address
+ size
, *cur_protection
, VM_KERN_MEMORY_MLOCK
,
15332 * If requested, return the address of the data pointed to by the
15333 * request, rather than the base of the resulting page.
15335 if ((flags
& VM_FLAGS_RETURN_DATA_ADDR
) != 0) {
15336 *address
+= offset_in_mapping
;
15343 * Routine: vm_map_remap_range_allocate
15346 * Allocate a range in the specified virtual address map.
15347 * returns the address and the map entry just before the allocated
15350 * Map must be locked.
15353 static kern_return_t
15354 vm_map_remap_range_allocate(
15356 vm_map_address_t
*address
, /* IN/OUT */
15357 vm_map_size_t size
,
15358 vm_map_offset_t mask
,
15360 __unused vm_map_kernel_flags_t vmk_flags
,
15361 __unused vm_tag_t tag
,
15362 vm_map_entry_t
*map_entry
) /* OUT */
15364 vm_map_entry_t entry
;
15365 vm_map_offset_t start
;
15366 vm_map_offset_t end
;
15368 vm_map_entry_t hole_entry
;
15374 if (flags
& VM_FLAGS_ANYWHERE
)
15376 if (flags
& VM_FLAGS_RANDOM_ADDR
)
15379 * Get a random start address.
15381 kr
= vm_map_random_address_for_size(map
, address
, size
);
15382 if (kr
!= KERN_SUCCESS
) {
15389 * Calculate the first possible address.
15392 if (start
< map
->min_offset
)
15393 start
= map
->min_offset
;
15394 if (start
> map
->max_offset
)
15395 return(KERN_NO_SPACE
);
15398 * Look for the first possible address;
15399 * if there's already something at this
15400 * address, we have to start after it.
15403 if( map
->disable_vmentry_reuse
== TRUE
) {
15404 VM_MAP_HIGHEST_ENTRY(map
, entry
, start
);
15407 if (map
->holelistenabled
) {
15408 hole_entry
= (vm_map_entry_t
)map
->holes_list
;
15410 if (hole_entry
== NULL
) {
15412 * No more space in the map?
15414 return(KERN_NO_SPACE
);
15417 boolean_t found_hole
= FALSE
;
15420 if (hole_entry
->vme_start
>= start
) {
15421 start
= hole_entry
->vme_start
;
15426 if (hole_entry
->vme_end
> start
) {
15430 hole_entry
= hole_entry
->vme_next
;
15432 } while (hole_entry
!= (vm_map_entry_t
) map
->holes_list
);
15434 if (found_hole
== FALSE
) {
15435 return (KERN_NO_SPACE
);
15438 entry
= hole_entry
;
15441 assert(first_free_is_valid(map
));
15442 if (start
== map
->min_offset
) {
15443 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
15444 start
= entry
->vme_end
;
15446 vm_map_entry_t tmp_entry
;
15447 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
15448 start
= tmp_entry
->vme_end
;
15452 start
= vm_map_round_page(start
,
15453 VM_MAP_PAGE_MASK(map
));
15457 * In any case, the "entry" always precedes
15458 * the proposed new region throughout the
15463 vm_map_entry_t next
;
15466 * Find the end of the proposed new region.
15467 * Be sure we didn't go beyond the end, or
15468 * wrap around the address.
15471 end
= ((start
+ mask
) & ~mask
);
15472 end
= vm_map_round_page(end
,
15473 VM_MAP_PAGE_MASK(map
));
15475 return(KERN_NO_SPACE
);
15479 if ((end
> map
->max_offset
) || (end
< start
)) {
15480 if (map
->wait_for_space
) {
15481 if (size
<= (map
->max_offset
-
15482 map
->min_offset
)) {
15483 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
15484 vm_map_unlock(map
);
15485 thread_block(THREAD_CONTINUE_NULL
);
15491 return(KERN_NO_SPACE
);
15494 next
= entry
->vme_next
;
15496 if (map
->holelistenabled
) {
15497 if (entry
->vme_end
>= end
)
15501 * If there are no more entries, we must win.
15505 * If there is another entry, it must be
15506 * after the end of the potential new region.
15509 if (next
== vm_map_to_entry(map
))
15512 if (next
->vme_start
>= end
)
15517 * Didn't fit -- move to the next entry.
15522 if (map
->holelistenabled
) {
15523 if (entry
== (vm_map_entry_t
) map
->holes_list
) {
15527 return(KERN_NO_SPACE
);
15529 start
= entry
->vme_start
;
15531 start
= entry
->vme_end
;
15535 if (map
->holelistenabled
) {
15537 if (vm_map_lookup_entry(map
, entry
->vme_start
, &entry
)) {
15538 panic("Found an existing entry (%p) instead of potential hole at address: 0x%llx.\n", entry
, (unsigned long long)entry
->vme_start
);
15545 vm_map_entry_t temp_entry
;
15549 * the address doesn't itself violate
15550 * the mask requirement.
15553 if ((start
& mask
) != 0)
15554 return(KERN_NO_SPACE
);
15558 * ... the address is within bounds
15561 end
= start
+ size
;
15563 if ((start
< map
->min_offset
) ||
15564 (end
> map
->max_offset
) ||
15566 return(KERN_INVALID_ADDRESS
);
15570 * If we're asked to overwrite whatever was mapped in that
15571 * range, first deallocate that range.
15573 if (flags
& VM_FLAGS_OVERWRITE
) {
15577 * We use a "zap_map" to avoid having to unlock
15578 * the "map" in vm_map_delete(), which would compromise
15579 * the atomicity of the "deallocate" and then "remap"
15582 zap_map
= vm_map_create(PMAP_NULL
,
15585 map
->hdr
.entries_pageable
);
15586 if (zap_map
== VM_MAP_NULL
) {
15587 return KERN_RESOURCE_SHORTAGE
;
15589 vm_map_set_page_shift(zap_map
, VM_MAP_PAGE_SHIFT(map
));
15590 vm_map_disable_hole_optimization(zap_map
);
15592 kr
= vm_map_delete(map
, start
, end
,
15593 (VM_MAP_REMOVE_SAVE_ENTRIES
|
15594 VM_MAP_REMOVE_NO_MAP_ALIGN
),
15596 if (kr
== KERN_SUCCESS
) {
15597 vm_map_destroy(zap_map
,
15598 VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
15599 zap_map
= VM_MAP_NULL
;
15604 * ... the starting address isn't allocated
15607 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
15608 return(KERN_NO_SPACE
);
15610 entry
= temp_entry
;
15613 * ... the next region doesn't overlap the
15617 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
15618 (entry
->vme_next
->vme_start
< end
))
15619 return(KERN_NO_SPACE
);
15621 *map_entry
= entry
;
15622 return(KERN_SUCCESS
);
15628 * Set the address map for the current thread to the specified map
15636 thread_t thread
= current_thread();
15637 vm_map_t oldmap
= thread
->map
;
15639 mp_disable_preemption();
15640 mycpu
= cpu_number();
15643 * Deactivate the current map and activate the requested map
15645 PMAP_SWITCH_USER(thread
, map
, mycpu
);
15647 mp_enable_preemption();
15653 * Routine: vm_map_write_user
15656 * Copy out data from a kernel space into space in the
15657 * destination map. The space must already exist in the
15659 * NOTE: This routine should only be called by threads
15660 * which can block on a page fault. i.e. kernel mode user
15668 vm_map_address_t dst_addr
,
15671 kern_return_t kr
= KERN_SUCCESS
;
15673 if(current_map() == map
) {
15674 if (copyout(src_p
, dst_addr
, size
)) {
15675 kr
= KERN_INVALID_ADDRESS
;
15680 /* take on the identity of the target map while doing */
15683 vm_map_reference(map
);
15684 oldmap
= vm_map_switch(map
);
15685 if (copyout(src_p
, dst_addr
, size
)) {
15686 kr
= KERN_INVALID_ADDRESS
;
15688 vm_map_switch(oldmap
);
15689 vm_map_deallocate(map
);
15695 * Routine: vm_map_read_user
15698 * Copy in data from a user space source map into the
15699 * kernel map. The space must already exist in the
15701 * NOTE: This routine should only be called by threads
15702 * which can block on a page fault. i.e. kernel mode user
15709 vm_map_address_t src_addr
,
15713 kern_return_t kr
= KERN_SUCCESS
;
15715 if(current_map() == map
) {
15716 if (copyin(src_addr
, dst_p
, size
)) {
15717 kr
= KERN_INVALID_ADDRESS
;
15722 /* take on the identity of the target map while doing */
15725 vm_map_reference(map
);
15726 oldmap
= vm_map_switch(map
);
15727 if (copyin(src_addr
, dst_p
, size
)) {
15728 kr
= KERN_INVALID_ADDRESS
;
15730 vm_map_switch(oldmap
);
15731 vm_map_deallocate(map
);
15738 * vm_map_check_protection:
15740 * Assert that the target map allows the specified
15741 * privilege on the entire address region given.
15742 * The entire region must be allocated.
15745 vm_map_check_protection(vm_map_t map
, vm_map_offset_t start
,
15746 vm_map_offset_t end
, vm_prot_t protection
)
15748 vm_map_entry_t entry
;
15749 vm_map_entry_t tmp_entry
;
15753 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
15755 vm_map_unlock(map
);
15759 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
15760 vm_map_unlock(map
);
15766 while (start
< end
) {
15767 if (entry
== vm_map_to_entry(map
)) {
15768 vm_map_unlock(map
);
15773 * No holes allowed!
15776 if (start
< entry
->vme_start
) {
15777 vm_map_unlock(map
);
15782 * Check protection associated with entry.
15785 if ((entry
->protection
& protection
) != protection
) {
15786 vm_map_unlock(map
);
15790 /* go to next entry */
15792 start
= entry
->vme_end
;
15793 entry
= entry
->vme_next
;
15795 vm_map_unlock(map
);
15800 vm_map_purgable_control(
15802 vm_map_offset_t address
,
15803 vm_purgable_t control
,
15806 vm_map_entry_t entry
;
15807 vm_object_t object
;
15809 boolean_t was_nonvolatile
;
15812 * Vet all the input parameters and current type and state of the
15813 * underlaying object. Return with an error if anything is amiss.
15815 if (map
== VM_MAP_NULL
)
15816 return(KERN_INVALID_ARGUMENT
);
15818 if (control
!= VM_PURGABLE_SET_STATE
&&
15819 control
!= VM_PURGABLE_GET_STATE
&&
15820 control
!= VM_PURGABLE_PURGE_ALL
&&
15821 control
!= VM_PURGABLE_SET_STATE_FROM_KERNEL
)
15822 return(KERN_INVALID_ARGUMENT
);
15824 if (control
== VM_PURGABLE_PURGE_ALL
) {
15825 vm_purgeable_object_purge_all();
15826 return KERN_SUCCESS
;
15829 if ((control
== VM_PURGABLE_SET_STATE
||
15830 control
== VM_PURGABLE_SET_STATE_FROM_KERNEL
) &&
15831 (((*state
& ~(VM_PURGABLE_ALL_MASKS
)) != 0) ||
15832 ((*state
& VM_PURGABLE_STATE_MASK
) > VM_PURGABLE_STATE_MASK
)))
15833 return(KERN_INVALID_ARGUMENT
);
15835 vm_map_lock_read(map
);
15837 if (!vm_map_lookup_entry(map
, address
, &entry
) || entry
->is_sub_map
) {
15840 * Must pass a valid non-submap address.
15842 vm_map_unlock_read(map
);
15843 return(KERN_INVALID_ADDRESS
);
15846 if ((entry
->protection
& VM_PROT_WRITE
) == 0) {
15848 * Can't apply purgable controls to something you can't write.
15850 vm_map_unlock_read(map
);
15851 return(KERN_PROTECTION_FAILURE
);
15854 object
= VME_OBJECT(entry
);
15855 if (object
== VM_OBJECT_NULL
||
15856 object
->purgable
== VM_PURGABLE_DENY
) {
15858 * Object must already be present and be purgeable.
15860 vm_map_unlock_read(map
);
15861 return KERN_INVALID_ARGUMENT
;
15864 vm_object_lock(object
);
15867 if (VME_OFFSET(entry
) != 0 ||
15868 entry
->vme_end
- entry
->vme_start
!= object
->vo_size
) {
15870 * Can only apply purgable controls to the whole (existing)
15873 vm_map_unlock_read(map
);
15874 vm_object_unlock(object
);
15875 return KERN_INVALID_ARGUMENT
;
15879 assert(!entry
->is_sub_map
);
15880 assert(!entry
->use_pmap
); /* purgeable has its own accounting */
15882 vm_map_unlock_read(map
);
15884 was_nonvolatile
= (object
->purgable
== VM_PURGABLE_NONVOLATILE
);
15886 kr
= vm_object_purgable_control(object
, control
, state
);
15888 if (was_nonvolatile
&&
15889 object
->purgable
!= VM_PURGABLE_NONVOLATILE
&&
15890 map
->pmap
== kernel_pmap
) {
15892 object
->vo_purgeable_volatilizer
= kernel_task
;
15896 vm_object_unlock(object
);
15902 vm_map_page_query_internal(
15903 vm_map_t target_map
,
15904 vm_map_offset_t offset
,
15909 vm_page_info_basic_data_t info
;
15910 mach_msg_type_number_t count
;
15912 count
= VM_PAGE_INFO_BASIC_COUNT
;
15913 kr
= vm_map_page_info(target_map
,
15915 VM_PAGE_INFO_BASIC
,
15916 (vm_page_info_t
) &info
,
15918 if (kr
== KERN_SUCCESS
) {
15919 *disposition
= info
.disposition
;
15920 *ref_count
= info
.ref_count
;
15932 vm_map_offset_t offset
,
15933 vm_page_info_flavor_t flavor
,
15934 vm_page_info_t info
,
15935 mach_msg_type_number_t
*count
)
15937 return (vm_map_page_range_info_internal(map
,
15938 offset
, /* start of range */
15939 (offset
+ 1), /* this will get rounded in the call to the page boundary */
15946 vm_map_page_range_info_internal(
15948 vm_map_offset_t start_offset
,
15949 vm_map_offset_t end_offset
,
15950 vm_page_info_flavor_t flavor
,
15951 vm_page_info_t info
,
15952 mach_msg_type_number_t
*count
)
15954 vm_map_entry_t map_entry
= VM_MAP_ENTRY_NULL
;
15955 vm_object_t object
= VM_OBJECT_NULL
, curr_object
= VM_OBJECT_NULL
;
15956 vm_page_t m
= VM_PAGE_NULL
;
15957 kern_return_t retval
= KERN_SUCCESS
;
15958 int disposition
= 0;
15960 int depth
= 0, info_idx
= 0;
15961 vm_page_info_basic_t basic_info
= 0;
15962 vm_map_offset_t offset_in_page
= 0, offset_in_object
= 0, curr_offset_in_object
= 0;
15963 vm_map_offset_t start
= 0, end
= 0, curr_s_offset
= 0, curr_e_offset
= 0;
15966 case VM_PAGE_INFO_BASIC
:
15967 if (*count
!= VM_PAGE_INFO_BASIC_COUNT
) {
15969 * The "vm_page_info_basic_data" structure was not
15970 * properly padded, so allow the size to be off by
15971 * one to maintain backwards binary compatibility...
15973 if (*count
!= VM_PAGE_INFO_BASIC_COUNT
- 1)
15974 return KERN_INVALID_ARGUMENT
;
15978 return KERN_INVALID_ARGUMENT
;
15984 info_idx
= 0; /* Tracks the next index within the info structure to be filled.*/
15985 retval
= KERN_SUCCESS
;
15987 offset_in_page
= start_offset
& PAGE_MASK
;
15988 start
= vm_map_trunc_page(start_offset
, PAGE_MASK
);
15989 end
= vm_map_round_page(end_offset
, PAGE_MASK
);
15991 assert ((end
- start
) <= MAX_PAGE_RANGE_QUERY
);
15993 vm_map_lock_read(map
);
15995 for (curr_s_offset
= start
; curr_s_offset
< end
;) {
15997 * New lookup needs reset of these variables.
15999 curr_object
= object
= VM_OBJECT_NULL
;
16000 offset_in_object
= 0;
16005 * First, find the map entry covering "curr_s_offset", going down
16006 * submaps if necessary.
16008 if (!vm_map_lookup_entry(map
, curr_s_offset
, &map_entry
)) {
16009 /* no entry -> no object -> no page */
16011 if (curr_s_offset
< vm_map_min(map
)) {
16013 * Illegal address that falls below map min.
16015 curr_e_offset
= MIN(end
, vm_map_min(map
));
16017 } else if (curr_s_offset
>= vm_map_max(map
)) {
16019 * Illegal address that falls on/after map max.
16021 curr_e_offset
= end
;
16023 } else if (map_entry
== vm_map_to_entry(map
)) {
16027 if (map_entry
->vme_next
== vm_map_to_entry(map
)) {
16031 curr_e_offset
= MIN(map
->max_offset
, end
);
16034 * Hole at start of the map.
16036 curr_e_offset
= MIN(map_entry
->vme_next
->vme_start
, end
);
16039 if (map_entry
->vme_next
== vm_map_to_entry(map
)) {
16041 * Hole at the end of the map.
16043 curr_e_offset
= MIN(map
->max_offset
, end
);
16045 curr_e_offset
= MIN(map_entry
->vme_next
->vme_start
, end
);
16049 assert(curr_e_offset
>= curr_s_offset
);
16051 uint64_t num_pages
= (curr_e_offset
- curr_s_offset
) >> PAGE_SHIFT
;
16053 void *info_ptr
= (void*) (((uintptr_t) info
) + (info_idx
* sizeof(struct vm_page_info_basic
)));
16055 bzero(info_ptr
, num_pages
* sizeof(struct vm_page_info_basic
));
16057 curr_s_offset
= curr_e_offset
;
16059 info_idx
+= num_pages
;
16064 /* compute offset from this map entry's start */
16065 offset_in_object
= curr_s_offset
- map_entry
->vme_start
;
16067 /* compute offset into this map entry's object (or submap) */
16068 offset_in_object
+= VME_OFFSET(map_entry
);
16070 if (map_entry
->is_sub_map
) {
16071 vm_map_t sub_map
= VM_MAP_NULL
;
16072 vm_page_info_t submap_info
= 0;
16073 vm_map_offset_t submap_s_offset
= 0, submap_e_offset
= 0, range_len
= 0;
16075 range_len
= MIN(map_entry
->vme_end
, end
) - curr_s_offset
;
16077 submap_s_offset
= offset_in_object
;
16078 submap_e_offset
= submap_s_offset
+ range_len
;
16080 sub_map
= VME_SUBMAP(map_entry
);
16082 vm_map_reference(sub_map
);
16083 vm_map_unlock_read(map
);
16085 submap_info
= (vm_page_info_t
) (((uintptr_t) info
) + (info_idx
* sizeof(struct vm_page_info_basic
)));
16087 retval
= vm_map_page_range_info_internal(sub_map
,
16090 VM_PAGE_INFO_BASIC
,
16091 (vm_page_info_t
) submap_info
,
16094 assert(retval
== KERN_SUCCESS
);
16096 vm_map_lock_read(map
);
16097 vm_map_deallocate(sub_map
);
16099 /* Move the "info" index by the number of pages we inspected.*/
16100 info_idx
+= range_len
>> PAGE_SHIFT
;
16102 /* Move our current offset by the size of the range we inspected.*/
16103 curr_s_offset
+= range_len
;
16108 object
= VME_OBJECT(map_entry
);
16109 if (object
== VM_OBJECT_NULL
) {
16112 * We don't have an object here and, hence,
16113 * no pages to inspect. We'll fill up the
16114 * info structure appropriately.
16117 curr_e_offset
= MIN(map_entry
->vme_end
, end
);
16119 uint64_t num_pages
= (curr_e_offset
- curr_s_offset
) >> PAGE_SHIFT
;
16121 void *info_ptr
= (void*) (((uintptr_t) info
) + (info_idx
* sizeof(struct vm_page_info_basic
)));
16123 bzero(info_ptr
, num_pages
* sizeof(struct vm_page_info_basic
));
16125 curr_s_offset
= curr_e_offset
;
16127 info_idx
+= num_pages
;
16132 vm_object_reference(object
);
16134 * Shared mode -- so we can allow other readers
16135 * to grab the lock too.
16137 vm_object_lock_shared(object
);
16139 curr_e_offset
= MIN(map_entry
->vme_end
, end
);
16141 vm_map_unlock_read(map
);
16143 map_entry
= NULL
; /* map is unlocked, the entry is no longer valid. */
16145 curr_object
= object
;
16147 for (; curr_s_offset
< curr_e_offset
;) {
16149 if (object
== curr_object
) {
16150 ref_count
= curr_object
->ref_count
- 1; /* account for our object reference above. */
16152 ref_count
= curr_object
->ref_count
;
16155 curr_offset_in_object
= offset_in_object
;
16158 m
= vm_page_lookup(curr_object
, curr_offset_in_object
);
16160 if (m
!= VM_PAGE_NULL
) {
16162 disposition
|= VM_PAGE_QUERY_PAGE_PRESENT
;
16166 if (curr_object
->internal
&&
16167 curr_object
->alive
&&
16168 !curr_object
->terminating
&&
16169 curr_object
->pager_ready
) {
16171 if (VM_COMPRESSOR_PAGER_STATE_GET(curr_object
, curr_offset_in_object
)
16172 == VM_EXTERNAL_STATE_EXISTS
) {
16173 /* the pager has that page */
16174 disposition
|= VM_PAGE_QUERY_PAGE_PAGED_OUT
;
16180 * Go down the VM object shadow chain until we find the page
16181 * we're looking for.
16184 if (curr_object
->shadow
!= VM_OBJECT_NULL
) {
16185 vm_object_t shadow
= VM_OBJECT_NULL
;
16187 curr_offset_in_object
+= curr_object
->vo_shadow_offset
;
16188 shadow
= curr_object
->shadow
;
16190 vm_object_lock_shared(shadow
);
16191 vm_object_unlock(curr_object
);
16193 curr_object
= shadow
;
16203 /* The ref_count is not strictly accurate, it measures the number */
16204 /* of entities holding a ref on the object, they may not be mapping */
16205 /* the object or may not be mapping the section holding the */
16206 /* target page but its still a ball park number and though an over- */
16207 /* count, it picks up the copy-on-write cases */
16209 /* We could also get a picture of page sharing from pmap_attributes */
16210 /* but this would under count as only faulted-in mappings would */
16213 if ((curr_object
== object
) && curr_object
->shadow
)
16214 disposition
|= VM_PAGE_QUERY_PAGE_COPIED
;
16216 if (! curr_object
->internal
)
16217 disposition
|= VM_PAGE_QUERY_PAGE_EXTERNAL
;
16219 if (m
!= VM_PAGE_NULL
) {
16221 if (m
->fictitious
) {
16223 disposition
|= VM_PAGE_QUERY_PAGE_FICTITIOUS
;
16226 if (m
->dirty
|| pmap_is_modified(VM_PAGE_GET_PHYS_PAGE(m
)))
16227 disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
16229 if (m
->reference
|| pmap_is_referenced(VM_PAGE_GET_PHYS_PAGE(m
)))
16230 disposition
|= VM_PAGE_QUERY_PAGE_REF
;
16232 if (m
->vm_page_q_state
== VM_PAGE_ON_SPECULATIVE_Q
)
16233 disposition
|= VM_PAGE_QUERY_PAGE_SPECULATIVE
;
16235 if (m
->cs_validated
)
16236 disposition
|= VM_PAGE_QUERY_PAGE_CS_VALIDATED
;
16238 disposition
|= VM_PAGE_QUERY_PAGE_CS_TAINTED
;
16240 disposition
|= VM_PAGE_QUERY_PAGE_CS_NX
;
16245 case VM_PAGE_INFO_BASIC
:
16246 basic_info
= (vm_page_info_basic_t
) (((uintptr_t) info
) + (info_idx
* sizeof(struct vm_page_info_basic
)));
16247 basic_info
->disposition
= disposition
;
16248 basic_info
->ref_count
= ref_count
;
16249 basic_info
->object_id
= (vm_object_id_t
) (uintptr_t)
16250 VM_KERNEL_ADDRPERM(curr_object
);
16251 basic_info
->offset
=
16252 (memory_object_offset_t
) curr_offset_in_object
+ offset_in_page
;
16253 basic_info
->depth
= depth
;
16260 offset_in_page
= 0; // This doesn't really make sense for any offset other than the starting offset.
16263 * Move to next offset in the range and in our object.
16265 curr_s_offset
+= PAGE_SIZE
;
16266 offset_in_object
+= PAGE_SIZE
;
16267 curr_offset_in_object
= offset_in_object
;
16269 if (curr_object
!= object
) {
16271 vm_object_unlock(curr_object
);
16273 curr_object
= object
;
16275 vm_object_lock_shared(curr_object
);
16278 vm_object_lock_yield_shared(curr_object
);
16282 vm_object_unlock(curr_object
);
16283 vm_object_deallocate(curr_object
);
16285 vm_map_lock_read(map
);
16288 vm_map_unlock_read(map
);
16295 * Synchronises the memory range specified with its backing store
16296 * image by either flushing or cleaning the contents to the appropriate
16297 * memory manager engaging in a memory object synchronize dialog with
16298 * the manager. The client doesn't return until the manager issues
16299 * m_o_s_completed message. MIG Magically converts user task parameter
16300 * to the task's address map.
16302 * interpretation of sync_flags
16303 * VM_SYNC_INVALIDATE - discard pages, only return precious
16304 * pages to manager.
16306 * VM_SYNC_INVALIDATE & (VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS)
16307 * - discard pages, write dirty or precious
16308 * pages back to memory manager.
16310 * VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS
16311 * - write dirty or precious pages back to
16312 * the memory manager.
16314 * VM_SYNC_CONTIGUOUS - does everything normally, but if there
16315 * is a hole in the region, and we would
16316 * have returned KERN_SUCCESS, return
16317 * KERN_INVALID_ADDRESS instead.
16320 * The memory object attributes have not yet been implemented, this
16321 * function will have to deal with the invalidate attribute
16324 * KERN_INVALID_TASK Bad task parameter
16325 * KERN_INVALID_ARGUMENT both sync and async were specified.
16326 * KERN_SUCCESS The usual.
16327 * KERN_INVALID_ADDRESS There was a hole in the region.
16333 vm_map_address_t address
,
16334 vm_map_size_t size
,
16335 vm_sync_t sync_flags
)
16337 vm_map_entry_t entry
;
16338 vm_map_size_t amount_left
;
16339 vm_object_offset_t offset
;
16340 boolean_t do_sync_req
;
16341 boolean_t had_hole
= FALSE
;
16342 vm_map_offset_t pmap_offset
;
16344 if ((sync_flags
& VM_SYNC_ASYNCHRONOUS
) &&
16345 (sync_flags
& VM_SYNC_SYNCHRONOUS
))
16346 return(KERN_INVALID_ARGUMENT
);
16349 * align address and size on page boundaries
16351 size
= (vm_map_round_page(address
+ size
,
16352 VM_MAP_PAGE_MASK(map
)) -
16353 vm_map_trunc_page(address
,
16354 VM_MAP_PAGE_MASK(map
)));
16355 address
= vm_map_trunc_page(address
,
16356 VM_MAP_PAGE_MASK(map
));
16358 if (map
== VM_MAP_NULL
)
16359 return(KERN_INVALID_TASK
);
16362 return(KERN_SUCCESS
);
16364 amount_left
= size
;
16366 while (amount_left
> 0) {
16367 vm_object_size_t flush_size
;
16368 vm_object_t object
;
16371 if (!vm_map_lookup_entry(map
,
16375 vm_map_size_t skip
;
16378 * hole in the address map.
16382 if (sync_flags
& VM_SYNC_KILLPAGES
) {
16384 * For VM_SYNC_KILLPAGES, there should be
16385 * no holes in the range, since we couldn't
16386 * prevent someone else from allocating in
16387 * that hole and we wouldn't want to "kill"
16390 vm_map_unlock(map
);
16395 * Check for empty map.
16397 if (entry
== vm_map_to_entry(map
) &&
16398 entry
->vme_next
== entry
) {
16399 vm_map_unlock(map
);
16403 * Check that we don't wrap and that
16404 * we have at least one real map entry.
16406 if ((map
->hdr
.nentries
== 0) ||
16407 (entry
->vme_next
->vme_start
< address
)) {
16408 vm_map_unlock(map
);
16412 * Move up to the next entry if needed
16414 skip
= (entry
->vme_next
->vme_start
- address
);
16415 if (skip
>= amount_left
)
16418 amount_left
-= skip
;
16419 address
= entry
->vme_next
->vme_start
;
16420 vm_map_unlock(map
);
16424 offset
= address
- entry
->vme_start
;
16425 pmap_offset
= address
;
16428 * do we have more to flush than is contained in this
16431 if (amount_left
+ entry
->vme_start
+ offset
> entry
->vme_end
) {
16432 flush_size
= entry
->vme_end
-
16433 (entry
->vme_start
+ offset
);
16435 flush_size
= amount_left
;
16437 amount_left
-= flush_size
;
16438 address
+= flush_size
;
16440 if (entry
->is_sub_map
== TRUE
) {
16441 vm_map_t local_map
;
16442 vm_map_offset_t local_offset
;
16444 local_map
= VME_SUBMAP(entry
);
16445 local_offset
= VME_OFFSET(entry
);
16446 vm_map_unlock(map
);
16451 sync_flags
) == KERN_INVALID_ADDRESS
) {
16456 object
= VME_OBJECT(entry
);
16459 * We can't sync this object if the object has not been
16462 if (object
== VM_OBJECT_NULL
) {
16463 vm_map_unlock(map
);
16466 offset
+= VME_OFFSET(entry
);
16468 vm_object_lock(object
);
16470 if (sync_flags
& (VM_SYNC_KILLPAGES
| VM_SYNC_DEACTIVATE
)) {
16471 int kill_pages
= 0;
16472 boolean_t reusable_pages
= FALSE
;
16474 if (sync_flags
& VM_SYNC_KILLPAGES
) {
16475 if (((object
->ref_count
== 1) ||
16476 ((object
->copy_strategy
!=
16477 MEMORY_OBJECT_COPY_SYMMETRIC
) &&
16478 (object
->copy
== VM_OBJECT_NULL
))) &&
16479 (object
->shadow
== VM_OBJECT_NULL
)) {
16480 if (object
->ref_count
!= 1) {
16481 vm_page_stats_reusable
.free_shared
++;
16488 if (kill_pages
!= -1)
16489 vm_object_deactivate_pages(
16492 (vm_object_size_t
) flush_size
,
16497 vm_object_unlock(object
);
16498 vm_map_unlock(map
);
16502 * We can't sync this object if there isn't a pager.
16503 * Don't bother to sync internal objects, since there can't
16504 * be any "permanent" storage for these objects anyway.
16506 if ((object
->pager
== MEMORY_OBJECT_NULL
) ||
16507 (object
->internal
) || (object
->private)) {
16508 vm_object_unlock(object
);
16509 vm_map_unlock(map
);
16513 * keep reference on the object until syncing is done
16515 vm_object_reference_locked(object
);
16516 vm_object_unlock(object
);
16518 vm_map_unlock(map
);
16520 do_sync_req
= vm_object_sync(object
,
16523 sync_flags
& VM_SYNC_INVALIDATE
,
16524 ((sync_flags
& VM_SYNC_SYNCHRONOUS
) ||
16525 (sync_flags
& VM_SYNC_ASYNCHRONOUS
)),
16526 sync_flags
& VM_SYNC_SYNCHRONOUS
);
16528 if ((sync_flags
& VM_SYNC_INVALIDATE
) && object
->resident_page_count
== 0) {
16530 * clear out the clustering and read-ahead hints
16532 vm_object_lock(object
);
16534 object
->pages_created
= 0;
16535 object
->pages_used
= 0;
16536 object
->sequential
= 0;
16537 object
->last_alloc
= 0;
16539 vm_object_unlock(object
);
16541 vm_object_deallocate(object
);
16544 /* for proper msync() behaviour */
16545 if (had_hole
== TRUE
&& (sync_flags
& VM_SYNC_CONTIGUOUS
))
16546 return(KERN_INVALID_ADDRESS
);
16548 return(KERN_SUCCESS
);
16552 * Routine: convert_port_entry_to_map
16554 * Convert from a port specifying an entry or a task
16555 * to a map. Doesn't consume the port ref; produces a map ref,
16556 * which may be null. Unlike convert_port_to_map, the
16557 * port may be task or a named entry backed.
16564 convert_port_entry_to_map(
16568 vm_named_entry_t named_entry
;
16569 uint32_t try_failed_count
= 0;
16571 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
16574 if(ip_active(port
) && (ip_kotype(port
)
16575 == IKOT_NAMED_ENTRY
)) {
16577 (vm_named_entry_t
)port
->ip_kobject
;
16578 if (!(lck_mtx_try_lock(&(named_entry
)->Lock
))) {
16581 try_failed_count
++;
16582 mutex_pause(try_failed_count
);
16585 named_entry
->ref_count
++;
16586 lck_mtx_unlock(&(named_entry
)->Lock
);
16588 if ((named_entry
->is_sub_map
) &&
16589 (named_entry
->protection
16590 & VM_PROT_WRITE
)) {
16591 map
= named_entry
->backing
.map
;
16593 mach_destroy_memory_entry(port
);
16594 return VM_MAP_NULL
;
16596 vm_map_reference_swap(map
);
16597 mach_destroy_memory_entry(port
);
16601 return VM_MAP_NULL
;
16605 map
= convert_port_to_map(port
);
16611 * Routine: convert_port_entry_to_object
16613 * Convert from a port specifying a named entry to an
16614 * object. Doesn't consume the port ref; produces a map ref,
16615 * which may be null.
16622 convert_port_entry_to_object(
16625 vm_object_t object
= VM_OBJECT_NULL
;
16626 vm_named_entry_t named_entry
;
16627 uint32_t try_failed_count
= 0;
16629 if (IP_VALID(port
) &&
16630 (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
16633 if (ip_active(port
) &&
16634 (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
16635 named_entry
= (vm_named_entry_t
)port
->ip_kobject
;
16636 if (!(lck_mtx_try_lock(&(named_entry
)->Lock
))) {
16638 try_failed_count
++;
16639 mutex_pause(try_failed_count
);
16642 named_entry
->ref_count
++;
16643 lck_mtx_unlock(&(named_entry
)->Lock
);
16645 if (!(named_entry
->is_sub_map
) &&
16646 !(named_entry
->is_copy
) &&
16647 (named_entry
->protection
& VM_PROT_WRITE
)) {
16648 object
= named_entry
->backing
.object
;
16649 vm_object_reference(object
);
16651 mach_destroy_memory_entry(port
);
16659 * Export routines to other components for the things we access locally through
16666 return (current_map_fast());
16670 * vm_map_reference:
16672 * Most code internal to the osfmk will go through a
16673 * macro defining this. This is always here for the
16674 * use of other kernel components.
16676 #undef vm_map_reference
16681 if (map
== VM_MAP_NULL
)
16684 lck_mtx_lock(&map
->s_lock
);
16686 assert(map
->res_count
> 0);
16687 assert(map
->ref_count
>= map
->res_count
);
16691 lck_mtx_unlock(&map
->s_lock
);
16695 * vm_map_deallocate:
16697 * Removes a reference from the specified map,
16698 * destroying it if no references remain.
16699 * The map should not be locked.
16707 if (map
== VM_MAP_NULL
)
16710 lck_mtx_lock(&map
->s_lock
);
16711 ref
= --map
->ref_count
;
16713 vm_map_res_deallocate(map
);
16714 lck_mtx_unlock(&map
->s_lock
);
16717 assert(map
->ref_count
== 0);
16718 lck_mtx_unlock(&map
->s_lock
);
16722 * The map residence count isn't decremented here because
16723 * the vm_map_delete below will traverse the entire map,
16724 * deleting entries, and the residence counts on objects
16725 * and sharing maps will go away then.
16729 vm_map_destroy(map
, VM_MAP_NO_FLAGS
);
16734 vm_map_disable_NX(vm_map_t map
)
16738 if (map
->pmap
== NULL
)
16741 pmap_disable_NX(map
->pmap
);
16745 vm_map_disallow_data_exec(vm_map_t map
)
16750 map
->map_disallow_data_exec
= TRUE
;
16753 /* XXX Consider making these constants (VM_MAX_ADDRESS and MACH_VM_MAX_ADDRESS)
16754 * more descriptive.
16757 vm_map_set_32bit(vm_map_t map
)
16759 #if defined(__arm__) || defined(__arm64__)
16760 map
->max_offset
= pmap_max_offset(FALSE
, ARM_PMAP_MAX_OFFSET_DEVICE
);
16762 map
->max_offset
= (vm_map_offset_t
)VM_MAX_ADDRESS
;
16768 vm_map_set_64bit(vm_map_t map
)
16770 #if defined(__arm__) || defined(__arm64__)
16771 map
->max_offset
= pmap_max_offset(TRUE
, ARM_PMAP_MAX_OFFSET_DEVICE
);
16773 map
->max_offset
= (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
;
16778 * Expand the maximum size of an existing map.
16781 vm_map_set_jumbo(vm_map_t map
)
16783 #if defined (__arm64__)
16784 vm_map_offset_t old_max_offset
= map
->max_offset
;
16785 map
->max_offset
= pmap_max_offset(TRUE
, ARM_PMAP_MAX_OFFSET_JUMBO
);
16786 if (map
->holes_list
->prev
->vme_end
== pmap_max_offset(TRUE
, ARM_PMAP_MAX_OFFSET_DEVICE
)) {
16788 * There is already a hole at the end of the map; simply make it bigger.
16790 map
->holes_list
->prev
->vme_end
= map
->max_offset
;
16793 * There is no hole at the end, so we need to create a new hole
16794 * for the new empty space we're creating.
16796 struct vm_map_links
*new_hole
= zalloc(vm_map_holes_zone
);
16797 new_hole
->start
= old_max_offset
;
16798 new_hole
->end
= map
->max_offset
;
16799 new_hole
->prev
= map
->holes_list
->prev
;
16800 new_hole
->next
= (struct vm_map_entry
*)map
->holes_list
;
16801 map
->holes_list
->prev
->links
.next
= (struct vm_map_entry
*)new_hole
;
16802 map
->holes_list
->prev
= (struct vm_map_entry
*)new_hole
;
16810 vm_compute_max_offset(boolean_t is64
)
16812 #if defined(__arm__) || defined(__arm64__)
16813 return (pmap_max_offset(is64
, ARM_PMAP_MAX_OFFSET_DEVICE
));
16815 return (is64
? (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
: (vm_map_offset_t
)VM_MAX_ADDRESS
);
16820 vm_map_get_max_aslr_slide_section(
16821 vm_map_t map __unused
,
16822 int64_t *max_sections
,
16823 int64_t *section_size
)
16825 #if defined(__arm64__)
16827 *section_size
= ARM_TT_TWIG_SIZE
;
16835 vm_map_get_max_aslr_slide_pages(vm_map_t map
)
16837 #if defined(__arm64__)
16838 /* Limit arm64 slide to 16MB to conserve contiguous VA space in the more
16839 * limited embedded address space; this is also meant to minimize pmap
16840 * memory usage on 16KB page systems.
16842 return (1 << (24 - VM_MAP_PAGE_SHIFT(map
)));
16844 return (1 << (vm_map_is_64bit(map
) ? 16 : 8));
16849 vm_map_get_max_loader_aslr_slide_pages(vm_map_t map
)
16851 #if defined(__arm64__)
16852 /* We limit the loader slide to 4MB, in order to ensure at least 8 bits
16853 * of independent entropy on 16KB page systems.
16855 return (1 << (22 - VM_MAP_PAGE_SHIFT(map
)));
16857 return (1 << (vm_map_is_64bit(map
) ? 16 : 8));
16866 return map
->max_offset
> ((vm_map_offset_t
)VM_MAX_ADDRESS
);
16871 vm_map_has_hard_pagezero(
16873 vm_map_offset_t pagezero_size
)
16877 * We should lock the VM map (for read) here but we can get away
16878 * with it for now because there can't really be any race condition:
16879 * the VM map's min_offset is changed only when the VM map is created
16880 * and when the zero page is established (when the binary gets loaded),
16881 * and this routine gets called only when the task terminates and the
16882 * VM map is being torn down, and when a new map is created via
16883 * load_machfile()/execve().
16885 return (map
->min_offset
>= pagezero_size
);
16889 * Raise a VM map's maximun offset.
16892 vm_map_raise_max_offset(
16894 vm_map_offset_t new_max_offset
)
16899 ret
= KERN_INVALID_ADDRESS
;
16901 if (new_max_offset
>= map
->max_offset
) {
16902 if (!vm_map_is_64bit(map
)) {
16903 if (new_max_offset
<= (vm_map_offset_t
)VM_MAX_ADDRESS
) {
16904 map
->max_offset
= new_max_offset
;
16905 ret
= KERN_SUCCESS
;
16908 if (new_max_offset
<= (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
) {
16909 map
->max_offset
= new_max_offset
;
16910 ret
= KERN_SUCCESS
;
16915 vm_map_unlock(map
);
16921 * Raise a VM map's minimum offset.
16922 * To strictly enforce "page zero" reservation.
16925 vm_map_raise_min_offset(
16927 vm_map_offset_t new_min_offset
)
16929 vm_map_entry_t first_entry
;
16931 new_min_offset
= vm_map_round_page(new_min_offset
,
16932 VM_MAP_PAGE_MASK(map
));
16936 if (new_min_offset
< map
->min_offset
) {
16938 * Can't move min_offset backwards, as that would expose
16939 * a part of the address space that was previously, and for
16940 * possibly good reasons, inaccessible.
16942 vm_map_unlock(map
);
16943 return KERN_INVALID_ADDRESS
;
16945 if (new_min_offset
>= map
->max_offset
) {
16946 /* can't go beyond the end of the address space */
16947 vm_map_unlock(map
);
16948 return KERN_INVALID_ADDRESS
;
16951 first_entry
= vm_map_first_entry(map
);
16952 if (first_entry
!= vm_map_to_entry(map
) &&
16953 first_entry
->vme_start
< new_min_offset
) {
16955 * Some memory was already allocated below the new
16956 * minimun offset. It's too late to change it now...
16958 vm_map_unlock(map
);
16959 return KERN_NO_SPACE
;
16962 map
->min_offset
= new_min_offset
;
16964 assert(map
->holes_list
);
16965 map
->holes_list
->start
= new_min_offset
;
16966 assert(new_min_offset
< map
->holes_list
->end
);
16968 vm_map_unlock(map
);
16970 return KERN_SUCCESS
;
16974 * Set the limit on the maximum amount of user wired memory allowed for this map.
16975 * This is basically a copy of the MEMLOCK rlimit value maintained by the BSD side of
16976 * the kernel. The limits are checked in the mach VM side, so we keep a copy so we
16977 * don't have to reach over to the BSD data structures.
16981 vm_map_set_user_wire_limit(vm_map_t map
,
16984 map
->user_wire_limit
= limit
;
16988 void vm_map_switch_protect(vm_map_t map
,
16992 map
->switch_protect
=val
;
16993 vm_map_unlock(map
);
16997 * IOKit has mapped a region into this map; adjust the pmap's ledgers appropriately.
16998 * phys_footprint is a composite limit consisting of iokit + physmem, so we need to
16999 * bump both counters.
17002 vm_map_iokit_mapped_region(vm_map_t map
, vm_size_t bytes
)
17004 pmap_t pmap
= vm_map_pmap(map
);
17006 ledger_credit(pmap
->ledger
, task_ledgers
.iokit_mapped
, bytes
);
17007 ledger_credit(pmap
->ledger
, task_ledgers
.phys_footprint
, bytes
);
17011 vm_map_iokit_unmapped_region(vm_map_t map
, vm_size_t bytes
)
17013 pmap_t pmap
= vm_map_pmap(map
);
17015 ledger_debit(pmap
->ledger
, task_ledgers
.iokit_mapped
, bytes
);
17016 ledger_debit(pmap
->ledger
, task_ledgers
.phys_footprint
, bytes
);
17019 /* Add (generate) code signature for memory range */
17020 #if CONFIG_DYNAMIC_CODE_SIGNING
17021 kern_return_t
vm_map_sign(vm_map_t map
,
17022 vm_map_offset_t start
,
17023 vm_map_offset_t end
)
17025 vm_map_entry_t entry
;
17027 vm_object_t object
;
17030 * Vet all the input parameters and current type and state of the
17031 * underlaying object. Return with an error if anything is amiss.
17033 if (map
== VM_MAP_NULL
)
17034 return(KERN_INVALID_ARGUMENT
);
17036 vm_map_lock_read(map
);
17038 if (!vm_map_lookup_entry(map
, start
, &entry
) || entry
->is_sub_map
) {
17040 * Must pass a valid non-submap address.
17042 vm_map_unlock_read(map
);
17043 return(KERN_INVALID_ADDRESS
);
17046 if((entry
->vme_start
> start
) || (entry
->vme_end
< end
)) {
17048 * Map entry doesn't cover the requested range. Not handling
17049 * this situation currently.
17051 vm_map_unlock_read(map
);
17052 return(KERN_INVALID_ARGUMENT
);
17055 object
= VME_OBJECT(entry
);
17056 if (object
== VM_OBJECT_NULL
) {
17058 * Object must already be present or we can't sign.
17060 vm_map_unlock_read(map
);
17061 return KERN_INVALID_ARGUMENT
;
17064 vm_object_lock(object
);
17065 vm_map_unlock_read(map
);
17067 while(start
< end
) {
17070 m
= vm_page_lookup(object
,
17071 start
- entry
->vme_start
+ VME_OFFSET(entry
));
17072 if (m
==VM_PAGE_NULL
) {
17073 /* shoud we try to fault a page here? we can probably
17074 * demand it exists and is locked for this request */
17075 vm_object_unlock(object
);
17076 return KERN_FAILURE
;
17078 /* deal with special page status */
17080 (m
->unusual
&& (m
->error
|| m
->restart
|| m
->private || m
->absent
))) {
17081 vm_object_unlock(object
);
17082 return KERN_FAILURE
;
17085 /* Page is OK... now "validate" it */
17086 /* This is the place where we'll call out to create a code
17087 * directory, later */
17088 m
->cs_validated
= TRUE
;
17090 /* The page is now "clean" for codesigning purposes. That means
17091 * we don't consider it as modified (wpmapped) anymore. But
17092 * we'll disconnect the page so we note any future modification
17094 m
->wpmapped
= FALSE
;
17095 refmod
= pmap_disconnect(VM_PAGE_GET_PHYS_PAGE(m
));
17097 /* Pull the dirty status from the pmap, since we cleared the
17099 if ((refmod
& VM_MEM_MODIFIED
) && !m
->dirty
) {
17100 SET_PAGE_DIRTY(m
, FALSE
);
17103 /* On to the next page */
17104 start
+= PAGE_SIZE
;
17106 vm_object_unlock(object
);
17108 return KERN_SUCCESS
;
17112 kern_return_t
vm_map_partial_reap(vm_map_t map
, unsigned int *reclaimed_resident
, unsigned int *reclaimed_compressed
)
17114 vm_map_entry_t entry
= VM_MAP_ENTRY_NULL
;
17115 vm_map_entry_t next_entry
;
17116 kern_return_t kr
= KERN_SUCCESS
;
17122 * We use a "zap_map" to avoid having to unlock
17123 * the "map" in vm_map_delete().
17125 zap_map
= vm_map_create(PMAP_NULL
,
17128 map
->hdr
.entries_pageable
);
17130 if (zap_map
== VM_MAP_NULL
) {
17131 return KERN_RESOURCE_SHORTAGE
;
17134 vm_map_set_page_shift(zap_map
,
17135 VM_MAP_PAGE_SHIFT(map
));
17136 vm_map_disable_hole_optimization(zap_map
);
17138 for (entry
= vm_map_first_entry(map
);
17139 entry
!= vm_map_to_entry(map
);
17140 entry
= next_entry
) {
17141 next_entry
= entry
->vme_next
;
17143 if (VME_OBJECT(entry
) &&
17144 !entry
->is_sub_map
&&
17145 (VME_OBJECT(entry
)->internal
== TRUE
) &&
17146 (VME_OBJECT(entry
)->ref_count
== 1)) {
17148 *reclaimed_resident
+= VME_OBJECT(entry
)->resident_page_count
;
17149 *reclaimed_compressed
+= vm_compressor_pager_get_count(VME_OBJECT(entry
)->pager
);
17151 (void)vm_map_delete(map
,
17154 VM_MAP_REMOVE_SAVE_ENTRIES
,
17159 vm_map_unlock(map
);
17162 * Get rid of the "zap_maps" and all the map entries that
17163 * they may still contain.
17165 if (zap_map
!= VM_MAP_NULL
) {
17166 vm_map_destroy(zap_map
, VM_MAP_REMOVE_NO_PMAP_CLEANUP
);
17167 zap_map
= VM_MAP_NULL
;
17174 #if DEVELOPMENT || DEBUG
17177 vm_map_disconnect_page_mappings(
17179 boolean_t do_unnest
)
17181 vm_map_entry_t entry
;
17182 int page_count
= 0;
17184 if (do_unnest
== TRUE
) {
17185 #ifndef NO_NESTED_PMAP
17188 for (entry
= vm_map_first_entry(map
);
17189 entry
!= vm_map_to_entry(map
);
17190 entry
= entry
->vme_next
) {
17192 if (entry
->is_sub_map
&& entry
->use_pmap
) {
17194 * Make sure the range between the start of this entry and
17195 * the end of this entry is no longer nested, so that
17196 * we will only remove mappings from the pmap in use by this
17199 vm_map_clip_unnest(map
, entry
, entry
->vme_start
, entry
->vme_end
);
17202 vm_map_unlock(map
);
17205 vm_map_lock_read(map
);
17207 page_count
= map
->pmap
->stats
.resident_count
;
17209 for (entry
= vm_map_first_entry(map
);
17210 entry
!= vm_map_to_entry(map
);
17211 entry
= entry
->vme_next
) {
17213 if (!entry
->is_sub_map
&& ((VME_OBJECT(entry
) == 0) ||
17214 (VME_OBJECT(entry
)->phys_contiguous
))) {
17217 if (entry
->is_sub_map
)
17218 assert(!entry
->use_pmap
);
17220 pmap_remove_options(map
->pmap
, entry
->vme_start
, entry
->vme_end
, 0);
17222 vm_map_unlock_read(map
);
17233 int c_freezer_swapout_count
;
17234 int c_freezer_compression_count
= 0;
17235 AbsoluteTime c_freezer_last_yield_ts
= 0;
17237 kern_return_t
vm_map_freeze(
17239 unsigned int *purgeable_count
,
17240 unsigned int *wired_count
,
17241 unsigned int *clean_count
,
17242 unsigned int *dirty_count
,
17243 __unused
unsigned int dirty_budget
,
17244 boolean_t
*has_shared
)
17246 vm_map_entry_t entry2
= VM_MAP_ENTRY_NULL
;
17247 kern_return_t kr
= KERN_SUCCESS
;
17249 *purgeable_count
= *wired_count
= *clean_count
= *dirty_count
= 0;
17250 *has_shared
= FALSE
;
17253 * We need the exclusive lock here so that we can
17254 * block any page faults or lookups while we are
17255 * in the middle of freezing this vm map.
17259 assert(VM_CONFIG_COMPRESSOR_IS_PRESENT
);
17261 if (vm_compressor_low_on_space() || vm_swap_low_on_space()) {
17262 kr
= KERN_NO_SPACE
;
17266 c_freezer_compression_count
= 0;
17267 clock_get_uptime(&c_freezer_last_yield_ts
);
17269 for (entry2
= vm_map_first_entry(map
);
17270 entry2
!= vm_map_to_entry(map
);
17271 entry2
= entry2
->vme_next
) {
17273 vm_object_t src_object
= VME_OBJECT(entry2
);
17276 !entry2
->is_sub_map
&&
17277 !src_object
->phys_contiguous
) {
17278 /* If eligible, scan the entry, moving eligible pages over to our parent object */
17280 if (src_object
->internal
== TRUE
) {
17282 if (VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
17284 * Pages belonging to this object could be swapped to disk.
17285 * Make sure it's not a shared object because we could end
17286 * up just bringing it back in again.
17288 if (src_object
->ref_count
> 1) {
17292 vm_object_compressed_freezer_pageout(src_object
);
17294 if (vm_compressor_low_on_space() || vm_swap_low_on_space()) {
17295 kr
= KERN_NO_SPACE
;
17302 vm_map_unlock(map
);
17304 vm_object_compressed_freezer_done();
17306 if (VM_CONFIG_FREEZER_SWAP_IS_ACTIVE
) {
17308 * reset the counter tracking the # of swapped c_segs
17309 * because we are now done with this freeze session and task.
17311 c_freezer_swapout_count
= 0;
17319 * vm_map_entry_should_cow_for_true_share:
17321 * Determines if the map entry should be clipped and setup for copy-on-write
17322 * to avoid applying "true_share" to a large VM object when only a subset is
17325 * For now, we target only the map entries created for the Objective C
17326 * Garbage Collector, which initially have the following properties:
17327 * - alias == VM_MEMORY_MALLOC
17328 * - wired_count == 0
17330 * and a VM object with:
17332 * - copy_strategy == MEMORY_OBJECT_COPY_SYMMETRIC
17334 * - vo_size == ANON_CHUNK_SIZE
17336 * Only non-kernel map entries.
17339 vm_map_entry_should_cow_for_true_share(
17340 vm_map_entry_t entry
)
17342 vm_object_t object
;
17344 if (entry
->is_sub_map
) {
17345 /* entry does not point at a VM object */
17349 if (entry
->needs_copy
) {
17350 /* already set for copy_on_write: done! */
17354 if (VME_ALIAS(entry
) != VM_MEMORY_MALLOC
&&
17355 VME_ALIAS(entry
) != VM_MEMORY_MALLOC_SMALL
) {
17356 /* not a malloc heap or Obj-C Garbage Collector heap */
17360 if (entry
->wired_count
) {
17361 /* wired: can't change the map entry... */
17362 vm_counters
.should_cow_but_wired
++;
17366 object
= VME_OBJECT(entry
);
17368 if (object
== VM_OBJECT_NULL
) {
17369 /* no object yet... */
17373 if (!object
->internal
) {
17374 /* not an internal object */
17378 if (object
->copy_strategy
!= MEMORY_OBJECT_COPY_SYMMETRIC
) {
17379 /* not the default copy strategy */
17383 if (object
->true_share
) {
17384 /* already true_share: too late to avoid it */
17388 if (VME_ALIAS(entry
) == VM_MEMORY_MALLOC
&&
17389 object
->vo_size
!= ANON_CHUNK_SIZE
) {
17390 /* ... not an object created for the ObjC Garbage Collector */
17394 if (VME_ALIAS(entry
) == VM_MEMORY_MALLOC_SMALL
&&
17395 object
->vo_size
!= 2048 * 4096) {
17396 /* ... not a "MALLOC_SMALL" heap */
17401 * All the criteria match: we have a large object being targeted for "true_share".
17402 * To limit the adverse side-effects linked with "true_share", tell the caller to
17403 * try and avoid setting up the entire object for "true_share" by clipping the
17404 * targeted range and setting it up for copy-on-write.
17410 vm_map_round_page_mask(
17411 vm_map_offset_t offset
,
17412 vm_map_offset_t mask
)
17414 return VM_MAP_ROUND_PAGE(offset
, mask
);
17418 vm_map_trunc_page_mask(
17419 vm_map_offset_t offset
,
17420 vm_map_offset_t mask
)
17422 return VM_MAP_TRUNC_PAGE(offset
, mask
);
17426 vm_map_page_aligned(
17427 vm_map_offset_t offset
,
17428 vm_map_offset_t mask
)
17430 return ((offset
) & mask
) == 0;
17437 return VM_MAP_PAGE_SHIFT(map
);
17444 return VM_MAP_PAGE_SIZE(map
);
17451 return VM_MAP_PAGE_MASK(map
);
17455 vm_map_set_page_shift(
17459 if (map
->hdr
.nentries
!= 0) {
17460 /* too late to change page size */
17461 return KERN_FAILURE
;
17464 map
->hdr
.page_shift
= pageshift
;
17466 return KERN_SUCCESS
;
17470 vm_map_query_volatile(
17472 mach_vm_size_t
*volatile_virtual_size_p
,
17473 mach_vm_size_t
*volatile_resident_size_p
,
17474 mach_vm_size_t
*volatile_compressed_size_p
,
17475 mach_vm_size_t
*volatile_pmap_size_p
,
17476 mach_vm_size_t
*volatile_compressed_pmap_size_p
)
17478 mach_vm_size_t volatile_virtual_size
;
17479 mach_vm_size_t volatile_resident_count
;
17480 mach_vm_size_t volatile_compressed_count
;
17481 mach_vm_size_t volatile_pmap_count
;
17482 mach_vm_size_t volatile_compressed_pmap_count
;
17483 mach_vm_size_t resident_count
;
17484 vm_map_entry_t entry
;
17485 vm_object_t object
;
17487 /* map should be locked by caller */
17489 volatile_virtual_size
= 0;
17490 volatile_resident_count
= 0;
17491 volatile_compressed_count
= 0;
17492 volatile_pmap_count
= 0;
17493 volatile_compressed_pmap_count
= 0;
17495 for (entry
= vm_map_first_entry(map
);
17496 entry
!= vm_map_to_entry(map
);
17497 entry
= entry
->vme_next
) {
17498 mach_vm_size_t pmap_resident_bytes
, pmap_compressed_bytes
;
17500 if (entry
->is_sub_map
) {
17503 if (! (entry
->protection
& VM_PROT_WRITE
)) {
17506 object
= VME_OBJECT(entry
);
17507 if (object
== VM_OBJECT_NULL
) {
17510 if (object
->purgable
!= VM_PURGABLE_VOLATILE
&&
17511 object
->purgable
!= VM_PURGABLE_EMPTY
) {
17514 if (VME_OFFSET(entry
)) {
17516 * If the map entry has been split and the object now
17517 * appears several times in the VM map, we don't want
17518 * to count the object's resident_page_count more than
17519 * once. We count it only for the first one, starting
17520 * at offset 0 and ignore the other VM map entries.
17524 resident_count
= object
->resident_page_count
;
17525 if ((VME_OFFSET(entry
) / PAGE_SIZE
) >= resident_count
) {
17526 resident_count
= 0;
17528 resident_count
-= (VME_OFFSET(entry
) / PAGE_SIZE
);
17531 volatile_virtual_size
+= entry
->vme_end
- entry
->vme_start
;
17532 volatile_resident_count
+= resident_count
;
17533 if (object
->pager
) {
17534 volatile_compressed_count
+=
17535 vm_compressor_pager_get_count(object
->pager
);
17537 pmap_compressed_bytes
= 0;
17538 pmap_resident_bytes
=
17539 pmap_query_resident(map
->pmap
,
17542 &pmap_compressed_bytes
);
17543 volatile_pmap_count
+= (pmap_resident_bytes
/ PAGE_SIZE
);
17544 volatile_compressed_pmap_count
+= (pmap_compressed_bytes
17548 /* map is still locked on return */
17550 *volatile_virtual_size_p
= volatile_virtual_size
;
17551 *volatile_resident_size_p
= volatile_resident_count
* PAGE_SIZE
;
17552 *volatile_compressed_size_p
= volatile_compressed_count
* PAGE_SIZE
;
17553 *volatile_pmap_size_p
= volatile_pmap_count
* PAGE_SIZE
;
17554 *volatile_compressed_pmap_size_p
= volatile_compressed_pmap_count
* PAGE_SIZE
;
17556 return KERN_SUCCESS
;
17560 vm_map_sizes(vm_map_t map
,
17561 vm_map_size_t
* psize
,
17562 vm_map_size_t
* pfree
,
17563 vm_map_size_t
* plargest_free
)
17565 vm_map_entry_t entry
;
17566 vm_map_offset_t prev
;
17567 vm_map_size_t free
, total_free
, largest_free
;
17572 *psize
= *pfree
= *plargest_free
= 0;
17575 total_free
= largest_free
= 0;
17577 vm_map_lock_read(map
);
17578 if (psize
) *psize
= map
->max_offset
- map
->min_offset
;
17580 prev
= map
->min_offset
;
17581 for (entry
= vm_map_first_entry(map
);; entry
= entry
->vme_next
)
17583 end
= (entry
== vm_map_to_entry(map
));
17585 if (end
) free
= entry
->vme_end
- prev
;
17586 else free
= entry
->vme_start
- prev
;
17588 total_free
+= free
;
17589 if (free
> largest_free
) largest_free
= free
;
17592 prev
= entry
->vme_end
;
17594 vm_map_unlock_read(map
);
17595 if (pfree
) *pfree
= total_free
;
17596 if (plargest_free
) *plargest_free
= largest_free
;
17599 #if VM_SCAN_FOR_SHADOW_CHAIN
17600 int vm_map_shadow_max(vm_map_t map
);
17601 int vm_map_shadow_max(
17604 int shadows
, shadows_max
;
17605 vm_map_entry_t entry
;
17606 vm_object_t object
, next_object
;
17613 vm_map_lock_read(map
);
17615 for (entry
= vm_map_first_entry(map
);
17616 entry
!= vm_map_to_entry(map
);
17617 entry
= entry
->vme_next
) {
17618 if (entry
->is_sub_map
) {
17621 object
= VME_OBJECT(entry
);
17622 if (object
== NULL
) {
17625 vm_object_lock_shared(object
);
17627 object
->shadow
!= NULL
;
17628 shadows
++, object
= next_object
) {
17629 next_object
= object
->shadow
;
17630 vm_object_lock_shared(next_object
);
17631 vm_object_unlock(object
);
17633 vm_object_unlock(object
);
17634 if (shadows
> shadows_max
) {
17635 shadows_max
= shadows
;
17639 vm_map_unlock_read(map
);
17641 return shadows_max
;
17643 #endif /* VM_SCAN_FOR_SHADOW_CHAIN */
17645 void vm_commit_pagezero_status(vm_map_t lmap
) {
17646 pmap_advise_pagezero_range(lmap
->pmap
, lmap
->min_offset
);
17651 vm_map_set_high_start(
17653 vm_map_offset_t high_start
)
17655 map
->vmmap_high_start
= high_start
;
17657 #endif /* __x86_64__ */