2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
60 * Author: Avadis Tevanian, Jr., Michael Wayne Young
63 * Virtual memory mapping module.
66 #include <task_swapper.h>
67 #include <mach_assert.h>
68 #include <libkern/OSAtomic.h>
70 #include <mach/kern_return.h>
71 #include <mach/port.h>
72 #include <mach/vm_attributes.h>
73 #include <mach/vm_param.h>
74 #include <mach/vm_behavior.h>
75 #include <mach/vm_statistics.h>
76 #include <mach/memory_object.h>
77 #include <mach/mach_vm.h>
78 #include <machine/cpu_capabilities.h>
80 #include <kern/assert.h>
81 #include <kern/counters.h>
82 #include <kern/kalloc.h>
83 #include <kern/zalloc.h>
86 #include <vm/vm_init.h>
87 #include <vm/vm_fault.h>
88 #include <vm/vm_map.h>
89 #include <vm/vm_object.h>
90 #include <vm/vm_page.h>
91 #include <vm/vm_kern.h>
92 #include <ipc/ipc_port.h>
93 #include <kern/sched_prim.h>
94 #include <kern/misc_protos.h>
96 #include <machine/db_machdep.h>
99 #include <mach/vm_map_server.h>
100 #include <mach/mach_host_server.h>
101 #include <vm/vm_shared_memory_server.h>
102 #include <vm/vm_protos.h> // for vm_map_commpage64 and vm_map_remove_compage64
105 #include <ppc/mappings.h>
108 #include <vm/vm_protos.h>
110 /* Internal prototypes
113 static void vm_map_simplify_range(
115 vm_map_offset_t start
,
116 vm_map_offset_t end
); /* forward */
118 static boolean_t
vm_map_range_check(
120 vm_map_offset_t start
,
122 vm_map_entry_t
*entry
);
124 static vm_map_entry_t
_vm_map_entry_create(
125 struct vm_map_header
*map_header
);
127 static void _vm_map_entry_dispose(
128 struct vm_map_header
*map_header
,
129 vm_map_entry_t entry
);
131 static void vm_map_pmap_enter(
133 vm_map_offset_t addr
,
134 vm_map_offset_t end_addr
,
136 vm_object_offset_t offset
,
137 vm_prot_t protection
);
139 static void _vm_map_clip_end(
140 struct vm_map_header
*map_header
,
141 vm_map_entry_t entry
,
142 vm_map_offset_t end
);
144 static void _vm_map_clip_start(
145 struct vm_map_header
*map_header
,
146 vm_map_entry_t entry
,
147 vm_map_offset_t start
);
149 static void vm_map_entry_delete(
151 vm_map_entry_t entry
);
153 static kern_return_t
vm_map_delete(
155 vm_map_offset_t start
,
160 static kern_return_t
vm_map_copy_overwrite_unaligned(
162 vm_map_entry_t entry
,
164 vm_map_address_t start
);
166 static kern_return_t
vm_map_copy_overwrite_aligned(
168 vm_map_entry_t tmp_entry
,
170 vm_map_offset_t start
,
173 static kern_return_t
vm_map_copyin_kernel_buffer(
175 vm_map_address_t src_addr
,
177 boolean_t src_destroy
,
178 vm_map_copy_t
*copy_result
); /* OUT */
180 static kern_return_t
vm_map_copyout_kernel_buffer(
182 vm_map_address_t
*addr
, /* IN/OUT */
184 boolean_t overwrite
);
186 static void vm_map_fork_share(
188 vm_map_entry_t old_entry
,
191 static boolean_t
vm_map_fork_copy(
193 vm_map_entry_t
*old_entry_p
,
196 void vm_map_region_top_walk(
197 vm_map_entry_t entry
,
198 vm_region_top_info_t top
);
200 void vm_map_region_walk(
203 vm_map_entry_t entry
,
204 vm_object_offset_t offset
,
205 vm_object_size_t range
,
206 vm_region_extended_info_t extended
);
208 static kern_return_t
vm_map_wire_nested(
210 vm_map_offset_t start
,
212 vm_prot_t access_type
,
215 vm_map_offset_t pmap_addr
);
217 static kern_return_t
vm_map_unwire_nested(
219 vm_map_offset_t start
,
223 vm_map_offset_t pmap_addr
);
225 static kern_return_t
vm_map_overwrite_submap_recurse(
227 vm_map_offset_t dst_addr
,
228 vm_map_size_t dst_size
);
230 static kern_return_t
vm_map_copy_overwrite_nested(
232 vm_map_offset_t dst_addr
,
234 boolean_t interruptible
,
237 static kern_return_t
vm_map_remap_extract(
239 vm_map_offset_t addr
,
242 struct vm_map_header
*map_header
,
243 vm_prot_t
*cur_protection
,
244 vm_prot_t
*max_protection
,
245 vm_inherit_t inheritance
,
248 static kern_return_t
vm_map_remap_range_allocate(
250 vm_map_address_t
*address
,
252 vm_map_offset_t mask
,
254 vm_map_entry_t
*map_entry
);
256 static void vm_map_region_look_for_page(
260 vm_object_offset_t offset
,
263 vm_region_extended_info_t extended
);
265 static int vm_map_region_count_obj_refs(
266 vm_map_entry_t entry
,
270 * Macros to copy a vm_map_entry. We must be careful to correctly
271 * manage the wired page count. vm_map_entry_copy() creates a new
272 * map entry to the same memory - the wired count in the new entry
273 * must be set to zero. vm_map_entry_copy_full() creates a new
274 * entry that is identical to the old entry. This preserves the
275 * wire count; it's used for map splitting and zone changing in
278 #define vm_map_entry_copy(NEW,OLD) \
281 (NEW)->is_shared = FALSE; \
282 (NEW)->needs_wakeup = FALSE; \
283 (NEW)->in_transition = FALSE; \
284 (NEW)->wired_count = 0; \
285 (NEW)->user_wired_count = 0; \
288 #define vm_map_entry_copy_full(NEW,OLD) (*(NEW) = *(OLD))
291 * Virtual memory maps provide for the mapping, protection,
292 * and sharing of virtual memory objects. In addition,
293 * this module provides for an efficient virtual copy of
294 * memory from one map to another.
296 * Synchronization is required prior to most operations.
298 * Maps consist of an ordered doubly-linked list of simple
299 * entries; a single hint is used to speed up lookups.
301 * Sharing maps have been deleted from this version of Mach.
302 * All shared objects are now mapped directly into the respective
303 * maps. This requires a change in the copy on write strategy;
304 * the asymmetric (delayed) strategy is used for shared temporary
305 * objects instead of the symmetric (shadow) strategy. All maps
306 * are now "top level" maps (either task map, kernel map or submap
307 * of the kernel map).
309 * Since portions of maps are specified by start/end addreses,
310 * which may not align with existing map entries, all
311 * routines merely "clip" entries to these start/end values.
312 * [That is, an entry is split into two, bordering at a
313 * start or end value.] Note that these clippings may not
314 * always be necessary (as the two resulting entries are then
315 * not changed); however, the clipping is done for convenience.
316 * No attempt is currently made to "glue back together" two
319 * The symmetric (shadow) copy strategy implements virtual copy
320 * by copying VM object references from one map to
321 * another, and then marking both regions as copy-on-write.
322 * It is important to note that only one writeable reference
323 * to a VM object region exists in any map when this strategy
324 * is used -- this means that shadow object creation can be
325 * delayed until a write operation occurs. The symmetric (delayed)
326 * strategy allows multiple maps to have writeable references to
327 * the same region of a vm object, and hence cannot delay creating
328 * its copy objects. See vm_object_copy_quickly() in vm_object.c.
329 * Copying of permanent objects is completely different; see
330 * vm_object_copy_strategically() in vm_object.c.
333 static zone_t vm_map_zone
; /* zone for vm_map structures */
334 static zone_t vm_map_entry_zone
; /* zone for vm_map_entry structures */
335 static zone_t vm_map_kentry_zone
; /* zone for kernel entry structures */
336 static zone_t vm_map_copy_zone
; /* zone for vm_map_copy structures */
340 * Placeholder object for submap operations. This object is dropped
341 * into the range by a call to vm_map_find, and removed when
342 * vm_map_submap creates the submap.
345 vm_object_t vm_submap_object
;
350 * Initialize the vm_map module. Must be called before
351 * any other vm_map routines.
353 * Map and entry structures are allocated from zones -- we must
354 * initialize those zones.
356 * There are three zones of interest:
358 * vm_map_zone: used to allocate maps.
359 * vm_map_entry_zone: used to allocate map entries.
360 * vm_map_kentry_zone: used to allocate map entries for the kernel.
362 * The kernel allocates map entries from a special zone that is initially
363 * "crammed" with memory. It would be difficult (perhaps impossible) for
364 * the kernel to allocate more memory to a entry zone when it became
365 * empty since the very act of allocating memory implies the creation
369 static void *map_data
;
370 static vm_map_size_t map_data_size
;
371 static void *kentry_data
;
372 static vm_map_size_t kentry_data_size
;
373 static int kentry_count
= 2048; /* to init kentry_data_size */
375 #define NO_COALESCE_LIMIT (1024 * 128)
378 * Threshold for aggressive (eager) page map entering for vm copyout
379 * operations. Any copyout larger will NOT be aggressively entered.
381 static vm_map_size_t vm_map_aggressive_enter_max
; /* set by bootstrap */
383 /* Skip acquiring locks if we're in the midst of a kernel core dump */
384 extern unsigned int not_in_kdp
;
388 vm_map_apple_protected(
390 vm_map_offset_t start
,
393 boolean_t map_locked
;
395 vm_map_entry_t map_entry
;
396 memory_object_t protected_mem_obj
;
397 vm_object_t protected_object
;
398 vm_map_offset_t map_addr
;
400 vm_map_lock_read(map
);
403 /* lookup the protected VM object */
404 if (!vm_map_lookup_entry(map
,
407 map_entry
->vme_end
!= end
||
408 map_entry
->is_sub_map
) {
409 /* that memory is not properly mapped */
410 kr
= KERN_INVALID_ARGUMENT
;
413 protected_object
= map_entry
->object
.vm_object
;
414 if (protected_object
== VM_OBJECT_NULL
) {
415 /* there should be a VM object here at this point */
416 kr
= KERN_INVALID_ARGUMENT
;
421 * Lookup (and create if necessary) the protected memory object
422 * matching that VM object.
423 * If successful, this also grabs a reference on the memory object,
424 * to guarantee that it doesn't go away before we get a chance to map
428 protected_mem_obj
= apple_protect_pager_setup(protected_object
);
429 if (protected_mem_obj
== NULL
) {
434 vm_map_unlock_read(map
);
437 /* map this memory object in place of the current one */
439 kr
= mach_vm_map(map
,
442 (mach_vm_offset_t
) 0,
443 VM_FLAGS_FIXED
| VM_FLAGS_OVERWRITE
,
444 (ipc_port_t
) protected_mem_obj
,
445 map_entry
->offset
+ (start
- map_entry
->vme_start
),
447 map_entry
->protection
,
448 map_entry
->max_protection
,
449 map_entry
->inheritance
);
450 assert(map_addr
== start
);
451 if (kr
== KERN_SUCCESS
) {
452 /* let the pager know that this mem_obj is mapped */
453 apple_protect_pager_map(protected_mem_obj
);
456 * Release the reference obtained by apple_protect_pager_setup().
457 * The mapping (if it succeeded) is now holding a reference on the
460 memory_object_deallocate(protected_mem_obj
);
464 vm_map_unlock_read(map
);
468 #endif /* __i386__ */
475 vm_map_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map
), 40*1024,
478 vm_map_entry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
479 1024*1024, PAGE_SIZE
*5,
480 "non-kernel map entries");
482 vm_map_kentry_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_entry
),
483 kentry_data_size
, kentry_data_size
,
484 "kernel map entries");
486 vm_map_copy_zone
= zinit((vm_map_size_t
) sizeof(struct vm_map_copy
),
487 16*1024, PAGE_SIZE
, "map copies");
490 * Cram the map and kentry zones with initial data.
491 * Set kentry_zone non-collectible to aid zone_gc().
493 zone_change(vm_map_zone
, Z_COLLECT
, FALSE
);
494 zone_change(vm_map_kentry_zone
, Z_COLLECT
, FALSE
);
495 zone_change(vm_map_kentry_zone
, Z_EXPAND
, FALSE
);
496 zcram(vm_map_zone
, map_data
, map_data_size
);
497 zcram(vm_map_kentry_zone
, kentry_data
, kentry_data_size
);
504 map_data_size
= vm_map_round_page(10 * sizeof(struct vm_map
));
505 map_data
= pmap_steal_memory(map_data_size
);
509 * Limiting worst case: vm_map_kentry_zone needs to map each "available"
510 * physical page (i.e. that beyond the kernel image and page tables)
511 * individually; we guess at most one entry per eight pages in the
512 * real world. This works out to roughly .1 of 1% of physical memory,
513 * or roughly 1900 entries (64K) for a 64M machine with 4K pages.
516 kentry_count
= pmap_free_pages() / 8;
520 vm_map_round_page(kentry_count
* sizeof(struct vm_map_entry
));
521 kentry_data
= pmap_steal_memory(kentry_data_size
);
527 * Creates and returns a new empty VM map with
528 * the given physical map structure, and having
529 * the given lower and upper address bounds.
538 register vm_map_t result
;
540 result
= (vm_map_t
) zalloc(vm_map_zone
);
541 if (result
== VM_MAP_NULL
)
542 panic("vm_map_create");
544 vm_map_first_entry(result
) = vm_map_to_entry(result
);
545 vm_map_last_entry(result
) = vm_map_to_entry(result
);
546 result
->hdr
.nentries
= 0;
547 result
->hdr
.entries_pageable
= pageable
;
550 result
->ref_count
= 1;
552 result
->res_count
= 1;
553 result
->sw_state
= MAP_SW_IN
;
554 #endif /* TASK_SWAPPER */
556 result
->min_offset
= min
;
557 result
->max_offset
= max
;
558 result
->wiring_required
= FALSE
;
559 result
->no_zero_fill
= FALSE
;
560 result
->mapped
= FALSE
;
561 result
->wait_for_space
= FALSE
;
562 result
->first_free
= vm_map_to_entry(result
);
563 result
->hint
= vm_map_to_entry(result
);
564 vm_map_lock_init(result
);
565 mutex_init(&result
->s_lock
, 0);
571 * vm_map_entry_create: [ internal use only ]
573 * Allocates a VM map entry for insertion in the
574 * given map (or map copy). No fields are filled.
576 #define vm_map_entry_create(map) \
577 _vm_map_entry_create(&(map)->hdr)
579 #define vm_map_copy_entry_create(copy) \
580 _vm_map_entry_create(&(copy)->cpy_hdr)
582 static vm_map_entry_t
583 _vm_map_entry_create(
584 register struct vm_map_header
*map_header
)
586 register zone_t zone
;
587 register vm_map_entry_t entry
;
589 if (map_header
->entries_pageable
)
590 zone
= vm_map_entry_zone
;
592 zone
= vm_map_kentry_zone
;
594 entry
= (vm_map_entry_t
) zalloc(zone
);
595 if (entry
== VM_MAP_ENTRY_NULL
)
596 panic("vm_map_entry_create");
602 * vm_map_entry_dispose: [ internal use only ]
604 * Inverse of vm_map_entry_create.
606 #define vm_map_entry_dispose(map, entry) \
608 if((entry) == (map)->first_free) \
609 (map)->first_free = vm_map_to_entry(map); \
610 if((entry) == (map)->hint) \
611 (map)->hint = vm_map_to_entry(map); \
612 _vm_map_entry_dispose(&(map)->hdr, (entry)); \
615 #define vm_map_copy_entry_dispose(map, entry) \
616 _vm_map_entry_dispose(&(copy)->cpy_hdr, (entry))
619 _vm_map_entry_dispose(
620 register struct vm_map_header
*map_header
,
621 register vm_map_entry_t entry
)
623 register zone_t zone
;
625 if (map_header
->entries_pageable
)
626 zone
= vm_map_entry_zone
;
628 zone
= vm_map_kentry_zone
;
634 static boolean_t
first_free_is_valid(vm_map_t map
); /* forward */
635 static boolean_t first_free_check
= FALSE
;
640 vm_map_entry_t entry
, next
;
642 if (!first_free_check
)
645 entry
= vm_map_to_entry(map
);
646 next
= entry
->vme_next
;
647 while (vm_map_trunc_page(next
->vme_start
) == vm_map_trunc_page(entry
->vme_end
) ||
648 (vm_map_trunc_page(next
->vme_start
) == vm_map_trunc_page(entry
->vme_start
) &&
649 next
!= vm_map_to_entry(map
))) {
651 next
= entry
->vme_next
;
652 if (entry
== vm_map_to_entry(map
))
655 if (map
->first_free
!= entry
) {
656 printf("Bad first_free for map 0x%x: 0x%x should be 0x%x\n",
657 map
, map
->first_free
, entry
);
662 #endif /* MACH_ASSERT */
667 * Updates the map->first_free pointer to the
668 * entry immediately before the first hole in the map.
669 * The map should be locked.
671 #define UPDATE_FIRST_FREE(map, new_first_free) \
674 vm_map_entry_t UFF_first_free; \
675 vm_map_entry_t UFF_next_entry; \
677 UFF_first_free = (new_first_free); \
678 UFF_next_entry = UFF_first_free->vme_next; \
679 while (vm_map_trunc_page(UFF_next_entry->vme_start) == \
680 vm_map_trunc_page(UFF_first_free->vme_end) || \
681 (vm_map_trunc_page(UFF_next_entry->vme_start) == \
682 vm_map_trunc_page(UFF_first_free->vme_start) && \
683 UFF_next_entry != vm_map_to_entry(UFF_map))) { \
684 UFF_first_free = UFF_next_entry; \
685 UFF_next_entry = UFF_first_free->vme_next; \
686 if (UFF_first_free == vm_map_to_entry(UFF_map)) \
689 UFF_map->first_free = UFF_first_free; \
690 assert(first_free_is_valid(UFF_map)); \
694 * vm_map_entry_{un,}link:
696 * Insert/remove entries from maps (or map copies).
698 #define vm_map_entry_link(map, after_where, entry) \
701 vm_map_entry_t VMEL_entry; \
703 VMEL_entry = (entry); \
704 _vm_map_entry_link(&VMEL_map->hdr, after_where, VMEL_entry); \
705 UPDATE_FIRST_FREE(VMEL_map, VMEL_map->first_free); \
709 #define vm_map_copy_entry_link(copy, after_where, entry) \
710 _vm_map_entry_link(&(copy)->cpy_hdr, after_where, (entry))
712 #define _vm_map_entry_link(hdr, after_where, entry) \
715 (entry)->vme_prev = (after_where); \
716 (entry)->vme_next = (after_where)->vme_next; \
717 (entry)->vme_prev->vme_next = (entry)->vme_next->vme_prev = (entry); \
720 #define vm_map_entry_unlink(map, entry) \
723 vm_map_entry_t VMEU_entry; \
724 vm_map_entry_t VMEU_first_free; \
726 VMEU_entry = (entry); \
727 if (VMEU_entry->vme_start <= VMEU_map->first_free->vme_start) \
728 VMEU_first_free = VMEU_entry->vme_prev; \
730 VMEU_first_free = VMEU_map->first_free; \
731 _vm_map_entry_unlink(&VMEU_map->hdr, VMEU_entry); \
732 UPDATE_FIRST_FREE(VMEU_map, VMEU_first_free); \
735 #define vm_map_copy_entry_unlink(copy, entry) \
736 _vm_map_entry_unlink(&(copy)->cpy_hdr, (entry))
738 #define _vm_map_entry_unlink(hdr, entry) \
741 (entry)->vme_next->vme_prev = (entry)->vme_prev; \
742 (entry)->vme_prev->vme_next = (entry)->vme_next; \
745 #if MACH_ASSERT && TASK_SWAPPER
747 * vm_map_res_reference:
749 * Adds another valid residence count to the given map.
751 * Map is locked so this function can be called from
755 void vm_map_res_reference(register vm_map_t map
)
757 /* assert map is locked */
758 assert(map
->res_count
>= 0);
759 assert(map
->ref_count
>= map
->res_count
);
760 if (map
->res_count
== 0) {
761 mutex_unlock(&map
->s_lock
);
764 mutex_lock(&map
->s_lock
);
772 * vm_map_reference_swap:
774 * Adds valid reference and residence counts to the given map.
776 * The map may not be in memory (i.e. zero residence count).
779 void vm_map_reference_swap(register vm_map_t map
)
781 assert(map
!= VM_MAP_NULL
);
782 mutex_lock(&map
->s_lock
);
783 assert(map
->res_count
>= 0);
784 assert(map
->ref_count
>= map
->res_count
);
786 vm_map_res_reference(map
);
787 mutex_unlock(&map
->s_lock
);
791 * vm_map_res_deallocate:
793 * Decrement residence count on a map; possibly causing swapout.
795 * The map must be in memory (i.e. non-zero residence count).
797 * The map is locked, so this function is callable from vm_map_deallocate.
800 void vm_map_res_deallocate(register vm_map_t map
)
802 assert(map
->res_count
> 0);
803 if (--map
->res_count
== 0) {
804 mutex_unlock(&map
->s_lock
);
808 mutex_lock(&map
->s_lock
);
810 assert(map
->ref_count
>= map
->res_count
);
812 #endif /* MACH_ASSERT && TASK_SWAPPER */
817 * Actually destroy a map.
821 register vm_map_t map
)
824 (void) vm_map_delete(map
, map
->min_offset
,
825 map
->max_offset
, VM_MAP_NO_FLAGS
,
829 if (map
->hdr
.nentries
!=0)
830 vm_map_remove_commpage(map
);
832 // assert(map->hdr.nentries==0);
833 // if(map->hdr.nentries) { /* (BRINGUP) */
834 // panic("vm_map_destroy: hdr.nentries is not 0 (%d) in map %08X\n", map->hdr.nentries, map);
838 pmap_destroy(map
->pmap
);
840 zfree(vm_map_zone
, map
);
845 * vm_map_swapin/vm_map_swapout
847 * Swap a map in and out, either referencing or releasing its resources.
848 * These functions are internal use only; however, they must be exported
849 * because they may be called from macros, which are exported.
851 * In the case of swapout, there could be races on the residence count,
852 * so if the residence count is up, we return, assuming that a
853 * vm_map_deallocate() call in the near future will bring us back.
856 * -- We use the map write lock for synchronization among races.
857 * -- The map write lock, and not the simple s_lock, protects the
858 * swap state of the map.
859 * -- If a map entry is a share map, then we hold both locks, in
860 * hierarchical order.
862 * Synchronization Notes:
863 * 1) If a vm_map_swapin() call happens while swapout in progress, it
864 * will block on the map lock and proceed when swapout is through.
865 * 2) A vm_map_reference() call at this time is illegal, and will
866 * cause a panic. vm_map_reference() is only allowed on resident
867 * maps, since it refuses to block.
868 * 3) A vm_map_swapin() call during a swapin will block, and
869 * proceeed when the first swapin is done, turning into a nop.
870 * This is the reason the res_count is not incremented until
871 * after the swapin is complete.
872 * 4) There is a timing hole after the checks of the res_count, before
873 * the map lock is taken, during which a swapin may get the lock
874 * before a swapout about to happen. If this happens, the swapin
875 * will detect the state and increment the reference count, causing
876 * the swapout to be a nop, thereby delaying it until a later
877 * vm_map_deallocate. If the swapout gets the lock first, then
878 * the swapin will simply block until the swapout is done, and
881 * Because vm_map_swapin() is potentially an expensive operation, it
882 * should be used with caution.
885 * 1) A map with a residence count of zero is either swapped, or
887 * 2) A map with a non-zero residence count is either resident,
888 * or being swapped in.
891 int vm_map_swap_enable
= 1;
893 void vm_map_swapin (vm_map_t map
)
895 register vm_map_entry_t entry
;
897 if (!vm_map_swap_enable
) /* debug */
902 * First deal with various races.
904 if (map
->sw_state
== MAP_SW_IN
)
906 * we raced with swapout and won. Returning will incr.
907 * the res_count, turning the swapout into a nop.
912 * The residence count must be zero. If we raced with another
913 * swapin, the state would have been IN; if we raced with a
914 * swapout (after another competing swapin), we must have lost
915 * the race to get here (see above comment), in which case
916 * res_count is still 0.
918 assert(map
->res_count
== 0);
921 * There are no intermediate states of a map going out or
922 * coming in, since the map is locked during the transition.
924 assert(map
->sw_state
== MAP_SW_OUT
);
927 * We now operate upon each map entry. If the entry is a sub-
928 * or share-map, we call vm_map_res_reference upon it.
929 * If the entry is an object, we call vm_object_res_reference
930 * (this may iterate through the shadow chain).
931 * Note that we hold the map locked the entire time,
932 * even if we get back here via a recursive call in
933 * vm_map_res_reference.
935 entry
= vm_map_first_entry(map
);
937 while (entry
!= vm_map_to_entry(map
)) {
938 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
939 if (entry
->is_sub_map
) {
940 vm_map_t lmap
= entry
->object
.sub_map
;
941 mutex_lock(&lmap
->s_lock
);
942 vm_map_res_reference(lmap
);
943 mutex_unlock(&lmap
->s_lock
);
945 vm_object_t object
= entry
->object
.vm_object
;
946 vm_object_lock(object
);
948 * This call may iterate through the
951 vm_object_res_reference(object
);
952 vm_object_unlock(object
);
955 entry
= entry
->vme_next
;
957 assert(map
->sw_state
== MAP_SW_OUT
);
958 map
->sw_state
= MAP_SW_IN
;
961 void vm_map_swapout(vm_map_t map
)
963 register vm_map_entry_t entry
;
967 * First deal with various races.
968 * If we raced with a swapin and lost, the residence count
969 * will have been incremented to 1, and we simply return.
971 mutex_lock(&map
->s_lock
);
972 if (map
->res_count
!= 0) {
973 mutex_unlock(&map
->s_lock
);
976 mutex_unlock(&map
->s_lock
);
979 * There are no intermediate states of a map going out or
980 * coming in, since the map is locked during the transition.
982 assert(map
->sw_state
== MAP_SW_IN
);
984 if (!vm_map_swap_enable
)
988 * We now operate upon each map entry. If the entry is a sub-
989 * or share-map, we call vm_map_res_deallocate upon it.
990 * If the entry is an object, we call vm_object_res_deallocate
991 * (this may iterate through the shadow chain).
992 * Note that we hold the map locked the entire time,
993 * even if we get back here via a recursive call in
994 * vm_map_res_deallocate.
996 entry
= vm_map_first_entry(map
);
998 while (entry
!= vm_map_to_entry(map
)) {
999 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
1000 if (entry
->is_sub_map
) {
1001 vm_map_t lmap
= entry
->object
.sub_map
;
1002 mutex_lock(&lmap
->s_lock
);
1003 vm_map_res_deallocate(lmap
);
1004 mutex_unlock(&lmap
->s_lock
);
1006 vm_object_t object
= entry
->object
.vm_object
;
1007 vm_object_lock(object
);
1009 * This call may take a long time,
1010 * since it could actively push
1011 * out pages (if we implement it
1014 vm_object_res_deallocate(object
);
1015 vm_object_unlock(object
);
1018 entry
= entry
->vme_next
;
1020 assert(map
->sw_state
== MAP_SW_IN
);
1021 map
->sw_state
= MAP_SW_OUT
;
1024 #endif /* TASK_SWAPPER */
1028 * SAVE_HINT_MAP_READ:
1030 * Saves the specified entry as the hint for
1031 * future lookups. only a read lock is held on map,
1032 * so make sure the store is atomic... OSCompareAndSwap
1033 * guarantees this... also, we don't care if we collide
1034 * and someone else wins and stores their 'hint'
1036 #define SAVE_HINT_MAP_READ(map,value) \
1038 OSCompareAndSwap((UInt32)((map)->hint), (UInt32)value, (UInt32 *)(&(map)->hint)); \
1043 * SAVE_HINT_MAP_WRITE:
1045 * Saves the specified entry as the hint for
1046 * future lookups. write lock held on map,
1047 * so no one else can be writing or looking
1048 * until the lock is dropped, so it's safe
1049 * to just do an assignment
1051 #define SAVE_HINT_MAP_WRITE(map,value) \
1053 (map)->hint = (value); \
1057 * vm_map_lookup_entry: [ internal use only ]
1059 * Finds the map entry containing (or
1060 * immediately preceding) the specified address
1061 * in the given map; the entry is returned
1062 * in the "entry" parameter. The boolean
1063 * result indicates whether the address is
1064 * actually contained in the map.
1067 vm_map_lookup_entry(
1068 register vm_map_t map
,
1069 register vm_map_offset_t address
,
1070 vm_map_entry_t
*entry
) /* OUT */
1072 register vm_map_entry_t cur
;
1073 register vm_map_entry_t last
;
1076 * Start looking either from the head of the
1077 * list, or from the hint.
1081 if (cur
== vm_map_to_entry(map
))
1082 cur
= cur
->vme_next
;
1084 if (address
>= cur
->vme_start
) {
1086 * Go from hint to end of list.
1088 * But first, make a quick check to see if
1089 * we are already looking at the entry we
1090 * want (which is usually the case).
1091 * Note also that we don't need to save the hint
1092 * here... it is the same hint (unless we are
1093 * at the header, in which case the hint didn't
1094 * buy us anything anyway).
1096 last
= vm_map_to_entry(map
);
1097 if ((cur
!= last
) && (cur
->vme_end
> address
)) {
1104 * Go from start to hint, *inclusively*
1106 last
= cur
->vme_next
;
1107 cur
= vm_map_first_entry(map
);
1114 while (cur
!= last
) {
1115 if (cur
->vme_end
> address
) {
1116 if (address
>= cur
->vme_start
) {
1118 * Save this lookup for future
1123 SAVE_HINT_MAP_READ(map
, cur
);
1129 cur
= cur
->vme_next
;
1131 *entry
= cur
->vme_prev
;
1132 SAVE_HINT_MAP_READ(map
, *entry
);
1138 * Routine: vm_map_find_space
1140 * Allocate a range in the specified virtual address map,
1141 * returning the entry allocated for that range.
1142 * Used by kmem_alloc, etc.
1144 * The map must be NOT be locked. It will be returned locked
1145 * on KERN_SUCCESS, unlocked on failure.
1147 * If an entry is allocated, the object/offset fields
1148 * are initialized to zero.
1152 register vm_map_t map
,
1153 vm_map_offset_t
*address
, /* OUT */
1155 vm_map_offset_t mask
,
1157 vm_map_entry_t
*o_entry
) /* OUT */
1159 register vm_map_entry_t entry
, new_entry
;
1160 register vm_map_offset_t start
;
1161 register vm_map_offset_t end
;
1165 return KERN_INVALID_ARGUMENT
;
1168 new_entry
= vm_map_entry_create(map
);
1171 * Look for the first possible address; if there's already
1172 * something at this address, we have to start after it.
1177 assert(first_free_is_valid(map
));
1178 if ((entry
= map
->first_free
) == vm_map_to_entry(map
))
1179 start
= map
->min_offset
;
1181 start
= entry
->vme_end
;
1184 * In any case, the "entry" always precedes
1185 * the proposed new region throughout the loop:
1189 register vm_map_entry_t next
;
1192 * Find the end of the proposed new region.
1193 * Be sure we didn't go beyond the end, or
1194 * wrap around the address.
1197 end
= ((start
+ mask
) & ~mask
);
1199 vm_map_entry_dispose(map
, new_entry
);
1201 return(KERN_NO_SPACE
);
1206 if ((end
> map
->max_offset
) || (end
< start
)) {
1207 vm_map_entry_dispose(map
, new_entry
);
1209 return(KERN_NO_SPACE
);
1213 * If there are no more entries, we must win.
1216 next
= entry
->vme_next
;
1217 if (next
== vm_map_to_entry(map
))
1221 * If there is another entry, it must be
1222 * after the end of the potential new region.
1225 if (next
->vme_start
>= end
)
1229 * Didn't fit -- move to the next entry.
1233 start
= entry
->vme_end
;
1238 * "start" and "end" should define the endpoints of the
1239 * available new range, and
1240 * "entry" should refer to the region before the new
1243 * the map should be locked.
1248 new_entry
->vme_start
= start
;
1249 new_entry
->vme_end
= end
;
1250 assert(page_aligned(new_entry
->vme_start
));
1251 assert(page_aligned(new_entry
->vme_end
));
1253 new_entry
->is_shared
= FALSE
;
1254 new_entry
->is_sub_map
= FALSE
;
1255 new_entry
->use_pmap
= FALSE
;
1256 new_entry
->object
.vm_object
= VM_OBJECT_NULL
;
1257 new_entry
->offset
= (vm_object_offset_t
) 0;
1259 new_entry
->needs_copy
= FALSE
;
1261 new_entry
->inheritance
= VM_INHERIT_DEFAULT
;
1262 new_entry
->protection
= VM_PROT_DEFAULT
;
1263 new_entry
->max_protection
= VM_PROT_ALL
;
1264 new_entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
1265 new_entry
->wired_count
= 0;
1266 new_entry
->user_wired_count
= 0;
1268 new_entry
->in_transition
= FALSE
;
1269 new_entry
->needs_wakeup
= FALSE
;
1271 VM_GET_FLAGS_ALIAS(flags
, new_entry
->alias
);
1274 * Insert the new entry into the list
1277 vm_map_entry_link(map
, entry
, new_entry
);
1282 * Update the lookup hint
1284 SAVE_HINT_MAP_WRITE(map
, new_entry
);
1286 *o_entry
= new_entry
;
1287 return(KERN_SUCCESS
);
1290 int vm_map_pmap_enter_print
= FALSE
;
1291 int vm_map_pmap_enter_enable
= FALSE
;
1294 * Routine: vm_map_pmap_enter [internal only]
1297 * Force pages from the specified object to be entered into
1298 * the pmap at the specified address if they are present.
1299 * As soon as a page not found in the object the scan ends.
1304 * In/out conditions:
1305 * The source map should not be locked on entry.
1310 register vm_map_offset_t addr
,
1311 register vm_map_offset_t end_addr
,
1312 register vm_object_t object
,
1313 vm_object_offset_t offset
,
1314 vm_prot_t protection
)
1316 unsigned int cache_attr
;
1321 while (addr
< end_addr
) {
1322 register vm_page_t m
;
1324 vm_object_lock(object
);
1325 vm_object_paging_begin(object
);
1327 m
= vm_page_lookup(object
, offset
);
1330 * The user should never see encrypted data, so do not
1331 * enter an encrypted page in the page table.
1333 if (m
== VM_PAGE_NULL
|| m
->busy
|| m
->encrypted
||
1334 (m
->unusual
&& ( m
->error
|| m
->restart
|| m
->absent
||
1335 protection
& m
->page_lock
))) {
1337 vm_object_paging_end(object
);
1338 vm_object_unlock(object
);
1342 assert(!m
->fictitious
); /* XXX is this possible ??? */
1344 if (vm_map_pmap_enter_print
) {
1345 printf("vm_map_pmap_enter:");
1346 printf("map: %x, addr: %llx, object: %x, offset: %llx\n",
1347 map
, (unsigned long long)addr
, object
, (unsigned long long)offset
);
1351 if (m
->no_isync
== TRUE
) {
1352 pmap_sync_page_data_phys(m
->phys_page
);
1353 m
->no_isync
= FALSE
;
1356 cache_attr
= ((unsigned int)object
->wimg_bits
) & VM_WIMG_MASK
;
1357 vm_object_unlock(object
);
1359 PMAP_ENTER(map
->pmap
, addr
, m
,
1360 protection
, cache_attr
, FALSE
);
1362 vm_object_lock(object
);
1364 PAGE_WAKEUP_DONE(m
);
1365 vm_page_lock_queues();
1366 if (!m
->active
&& !m
->inactive
)
1367 vm_page_activate(m
);
1368 vm_page_unlock_queues();
1369 vm_object_paging_end(object
);
1370 vm_object_unlock(object
);
1372 offset
+= PAGE_SIZE_64
;
1377 boolean_t
vm_map_pmap_is_empty(
1379 vm_map_offset_t start
,
1380 vm_map_offset_t end
);
1381 boolean_t
vm_map_pmap_is_empty(
1383 vm_map_offset_t start
,
1384 vm_map_offset_t end
)
1386 vm_map_offset_t offset
;
1389 if (map
->pmap
== NULL
) {
1392 for (offset
= start
;
1394 offset
+= PAGE_SIZE
) {
1395 phys_page
= pmap_find_phys(map
->pmap
, offset
);
1397 kprintf("vm_map_pmap_is_empty(%p,0x%llx,0x%llx): "
1398 "page %d at 0x%llx\n",
1399 map
, start
, end
, phys_page
, offset
);
1407 * Routine: vm_map_enter
1410 * Allocate a range in the specified virtual address map.
1411 * The resulting range will refer to memory defined by
1412 * the given memory object and offset into that object.
1414 * Arguments are as defined in the vm_map call.
1416 int _map_enter_debug
= 0;
1417 static unsigned int vm_map_enter_restore_successes
= 0;
1418 static unsigned int vm_map_enter_restore_failures
= 0;
1422 vm_map_offset_t
*address
, /* IN/OUT */
1424 vm_map_offset_t mask
,
1427 vm_object_offset_t offset
,
1428 boolean_t needs_copy
,
1429 vm_prot_t cur_protection
,
1430 vm_prot_t max_protection
,
1431 vm_inherit_t inheritance
)
1433 vm_map_entry_t entry
, new_entry
;
1434 vm_map_offset_t start
, tmp_start
;
1435 vm_map_offset_t end
, tmp_end
;
1436 kern_return_t result
= KERN_SUCCESS
;
1437 vm_map_t zap_old_map
= VM_MAP_NULL
;
1438 vm_map_t zap_new_map
= VM_MAP_NULL
;
1439 boolean_t map_locked
= FALSE
;
1440 boolean_t pmap_empty
= TRUE
;
1441 boolean_t new_mapping_established
= FALSE
;
1442 boolean_t anywhere
= ((flags
& VM_FLAGS_ANYWHERE
) != 0);
1443 boolean_t purgable
= ((flags
& VM_FLAGS_PURGABLE
) != 0);
1444 boolean_t overwrite
= ((flags
& VM_FLAGS_OVERWRITE
) != 0);
1449 return KERN_INVALID_ARGUMENT
;
1452 VM_GET_FLAGS_ALIAS(flags
, alias
);
1454 #define RETURN(value) { result = value; goto BailOut; }
1456 assert(page_aligned(*address
));
1457 assert(page_aligned(size
));
1460 * Only zero-fill objects are allowed to be purgable.
1461 * LP64todo - limit purgable objects to 32-bits for now
1465 (object
!= VM_OBJECT_NULL
&&
1466 (object
->size
!= size
||
1467 object
->purgable
== VM_OBJECT_NONPURGABLE
))
1468 || size
> VM_MAX_ADDRESS
)) /* LP64todo: remove when dp capable */
1469 return KERN_INVALID_ARGUMENT
;
1471 if (!anywhere
&& overwrite
) {
1473 * Create a temporary VM map to hold the old mappings in the
1474 * affected area while we create the new one.
1475 * This avoids releasing the VM map lock in
1476 * vm_map_entry_delete() and allows atomicity
1477 * when we want to replace some mappings with a new one.
1478 * It also allows us to restore the old VM mappings if the
1479 * new mapping fails.
1481 zap_old_map
= vm_map_create(PMAP_NULL
,
1496 * Calculate the first possible address.
1499 if (start
< map
->min_offset
)
1500 start
= map
->min_offset
;
1501 if (start
> map
->max_offset
)
1502 RETURN(KERN_NO_SPACE
);
1505 * Look for the first possible address;
1506 * if there's already something at this
1507 * address, we have to start after it.
1510 assert(first_free_is_valid(map
));
1511 if (start
== map
->min_offset
) {
1512 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
1513 start
= entry
->vme_end
;
1515 vm_map_entry_t tmp_entry
;
1516 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
1517 start
= tmp_entry
->vme_end
;
1522 * In any case, the "entry" always precedes
1523 * the proposed new region throughout the
1528 register vm_map_entry_t next
;
1531 * Find the end of the proposed new region.
1532 * Be sure we didn't go beyond the end, or
1533 * wrap around the address.
1536 end
= ((start
+ mask
) & ~mask
);
1538 RETURN(KERN_NO_SPACE
);
1542 if ((end
> map
->max_offset
) || (end
< start
)) {
1543 if (map
->wait_for_space
) {
1544 if (size
<= (map
->max_offset
-
1546 assert_wait((event_t
)map
,
1550 thread_block(THREAD_CONTINUE_NULL
);
1554 RETURN(KERN_NO_SPACE
);
1558 * If there are no more entries, we must win.
1561 next
= entry
->vme_next
;
1562 if (next
== vm_map_to_entry(map
))
1566 * If there is another entry, it must be
1567 * after the end of the potential new region.
1570 if (next
->vme_start
>= end
)
1574 * Didn't fit -- move to the next entry.
1578 start
= entry
->vme_end
;
1582 vm_map_entry_t temp_entry
;
1586 * the address doesn't itself violate
1587 * the mask requirement.
1592 if ((start
& mask
) != 0)
1593 RETURN(KERN_NO_SPACE
);
1596 * ... the address is within bounds
1601 if ((start
< map
->min_offset
) ||
1602 (end
> map
->max_offset
) ||
1604 RETURN(KERN_INVALID_ADDRESS
);
1607 if (overwrite
&& zap_old_map
!= VM_MAP_NULL
) {
1609 * Fixed mapping and "overwrite" flag: attempt to
1610 * remove all existing mappings in the specified
1611 * address range, saving them in our "zap_old_map".
1613 (void) vm_map_delete(map
, start
, end
,
1614 VM_MAP_REMOVE_SAVE_ENTRIES
,
1619 * ... the starting address isn't allocated
1622 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
1623 RETURN(KERN_NO_SPACE
);
1628 * ... the next region doesn't overlap the
1632 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
1633 (entry
->vme_next
->vme_start
< end
))
1634 RETURN(KERN_NO_SPACE
);
1639 * "start" and "end" should define the endpoints of the
1640 * available new range, and
1641 * "entry" should refer to the region before the new
1644 * the map should be locked.
1648 * See whether we can avoid creating a new entry (and object) by
1649 * extending one of our neighbors. [So far, we only attempt to
1650 * extend from below.] Note that we can never extend/join
1651 * purgable objects because they need to remain distinct
1652 * entities in order to implement their "volatile object"
1657 if (object
== VM_OBJECT_NULL
) {
1658 object
= vm_object_allocate(size
);
1659 object
->copy_strategy
= MEMORY_OBJECT_COPY_NONE
;
1660 object
->purgable
= VM_OBJECT_PURGABLE_NONVOLATILE
;
1661 offset
= (vm_object_offset_t
)0;
1663 } else if ((object
== VM_OBJECT_NULL
) &&
1664 (entry
!= vm_map_to_entry(map
)) &&
1665 (entry
->vme_end
== start
) &&
1666 (!entry
->is_shared
) &&
1667 (!entry
->is_sub_map
) &&
1668 (entry
->alias
== alias
) &&
1669 (entry
->inheritance
== inheritance
) &&
1670 (entry
->protection
== cur_protection
) &&
1671 (entry
->max_protection
== max_protection
) &&
1672 (entry
->behavior
== VM_BEHAVIOR_DEFAULT
) &&
1673 (entry
->in_transition
== 0) &&
1674 ((alias
== VM_MEMORY_REALLOC
) || ((entry
->vme_end
- entry
->vme_start
) + size
< NO_COALESCE_LIMIT
)) &&
1675 (entry
->wired_count
== 0)) { /* implies user_wired_count == 0 */
1676 if (vm_object_coalesce(entry
->object
.vm_object
,
1679 (vm_object_offset_t
) 0,
1680 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
),
1681 (vm_map_size_t
)(end
- entry
->vme_end
))) {
1684 * Coalesced the two objects - can extend
1685 * the previous map entry to include the
1688 map
->size
+= (end
- entry
->vme_end
);
1689 entry
->vme_end
= end
;
1690 UPDATE_FIRST_FREE(map
, map
->first_free
);
1691 RETURN(KERN_SUCCESS
);
1696 * Create a new entry
1697 * LP64todo - for now, we can only allocate 4GB internal objects
1698 * because the default pager can't page bigger ones. Remove this
1702 * The reserved "page zero" in each process's address space can
1703 * be arbitrarily large. Splitting it into separate 4GB objects and
1704 * therefore different VM map entries serves no purpose and just
1705 * slows down operations on the VM map, so let's not split the
1706 * allocation into 4GB chunks if the max protection is NONE. That
1707 * memory should never be accessible, so it will never get to the
1711 if (object
== VM_OBJECT_NULL
&&
1712 size
> (vm_map_size_t
)VM_MAX_ADDRESS
&&
1713 max_protection
!= VM_PROT_NONE
)
1714 tmp_end
= tmp_start
+ (vm_map_size_t
)VM_MAX_ADDRESS
;
1718 new_entry
= vm_map_entry_insert(map
, entry
, tmp_start
, tmp_end
,
1719 object
, offset
, needs_copy
, FALSE
, FALSE
,
1720 cur_protection
, max_protection
,
1721 VM_BEHAVIOR_DEFAULT
, inheritance
, 0);
1722 new_entry
->alias
= alias
;
1724 } while (tmp_end
!= end
&&
1725 (tmp_start
= tmp_end
) &&
1726 (tmp_end
= (end
- tmp_end
> (vm_map_size_t
)VM_MAX_ADDRESS
) ?
1727 tmp_end
+ (vm_map_size_t
)VM_MAX_ADDRESS
: end
));
1732 new_mapping_established
= TRUE
;
1734 /* Wire down the new entry if the user
1735 * requested all new map entries be wired.
1737 if (map
->wiring_required
) {
1738 pmap_empty
= FALSE
; /* pmap won't be empty */
1739 result
= vm_map_wire(map
, start
, end
,
1740 new_entry
->protection
, TRUE
);
1744 if ((object
!= VM_OBJECT_NULL
) &&
1745 (vm_map_pmap_enter_enable
) &&
1748 (size
< (128*1024))) {
1749 pmap_empty
= FALSE
; /* pmap won't be empty */
1751 #ifdef STACK_ONLY_NX
1752 if (alias
!= VM_MEMORY_STACK
&& cur_protection
)
1753 cur_protection
|= VM_PROT_EXECUTE
;
1755 vm_map_pmap_enter(map
, start
, end
,
1756 object
, offset
, cur_protection
);
1760 if (result
== KERN_SUCCESS
&&
1762 !(flags
& VM_FLAGS_NO_PMAP_CHECK
)) {
1763 assert(vm_map_pmap_is_empty(map
, *address
, *address
+size
));
1766 if (result
!= KERN_SUCCESS
) {
1767 if (new_mapping_established
) {
1769 * We have to get rid of the new mappings since we
1770 * won't make them available to the user.
1771 * Try and do that atomically, to minimize the risk
1772 * that someone else create new mappings that range.
1774 zap_new_map
= vm_map_create(PMAP_NULL
,
1782 (void) vm_map_delete(map
, *address
, *address
+size
,
1783 VM_MAP_REMOVE_SAVE_ENTRIES
,
1786 if (zap_old_map
!= VM_MAP_NULL
&&
1787 zap_old_map
->hdr
.nentries
!= 0) {
1788 vm_map_entry_t entry1
, entry2
;
1791 * The new mapping failed. Attempt to restore
1792 * the old mappings, saved in the "zap_old_map".
1799 /* first check if the coast is still clear */
1800 start
= vm_map_first_entry(zap_old_map
)->vme_start
;
1801 end
= vm_map_last_entry(zap_old_map
)->vme_end
;
1802 if (vm_map_lookup_entry(map
, start
, &entry1
) ||
1803 vm_map_lookup_entry(map
, end
, &entry2
) ||
1806 * Part of that range has already been
1807 * re-mapped: we can't restore the old
1810 vm_map_enter_restore_failures
++;
1813 * Transfer the saved map entries from
1814 * "zap_old_map" to the original "map",
1815 * inserting them all after "entry1".
1817 for (entry2
= vm_map_first_entry(zap_old_map
);
1818 entry2
!= vm_map_to_entry(zap_old_map
);
1819 entry2
= vm_map_first_entry(zap_old_map
)) {
1820 vm_map_entry_unlink(zap_old_map
,
1822 vm_map_entry_link(map
, entry1
, entry2
);
1825 if (map
->wiring_required
) {
1827 * XXX TODO: we should rewire the
1831 vm_map_enter_restore_successes
++;
1841 * Get rid of the "zap_maps" and all the map entries that
1842 * they may still contain.
1844 if (zap_old_map
!= VM_MAP_NULL
) {
1845 vm_map_destroy(zap_old_map
);
1846 zap_old_map
= VM_MAP_NULL
;
1848 if (zap_new_map
!= VM_MAP_NULL
) {
1849 vm_map_destroy(zap_new_map
);
1850 zap_new_map
= VM_MAP_NULL
;
1862 extern pmap_paddr_t avail_start
, avail_end
;
1866 * Allocate memory in the specified map, with the caveat that
1867 * the memory is physically contiguous. This call may fail
1868 * if the system can't find sufficient contiguous memory.
1869 * This call may cause or lead to heart-stopping amounts of
1872 * Memory obtained from this call should be freed in the
1873 * normal way, viz., via vm_deallocate.
1878 vm_map_offset_t
*addr
,
1882 vm_object_t cpm_obj
;
1886 vm_map_offset_t va
, start
, end
, offset
;
1888 vm_map_offset_t prev_addr
;
1889 #endif /* MACH_ASSERT */
1891 boolean_t anywhere
= ((VM_FLAGS_ANYWHERE
& flags
) != 0);
1893 if (!vm_allocate_cpm_enabled
)
1894 return KERN_FAILURE
;
1898 return KERN_SUCCESS
;
1902 *addr
= vm_map_min(map
);
1904 *addr
= vm_map_trunc_page(*addr
);
1905 size
= vm_map_round_page(size
);
1908 * LP64todo - cpm_allocate should probably allow
1909 * allocations of >4GB, but not with the current
1910 * algorithm, so just cast down the size for now.
1912 if (size
> VM_MAX_ADDRESS
)
1913 return KERN_RESOURCE_SHORTAGE
;
1914 if ((kr
= cpm_allocate(CAST_DOWN(vm_size_t
, size
),
1915 &pages
, TRUE
)) != KERN_SUCCESS
)
1918 cpm_obj
= vm_object_allocate((vm_object_size_t
)size
);
1919 assert(cpm_obj
!= VM_OBJECT_NULL
);
1920 assert(cpm_obj
->internal
);
1921 assert(cpm_obj
->size
== (vm_object_size_t
)size
);
1922 assert(cpm_obj
->can_persist
== FALSE
);
1923 assert(cpm_obj
->pager_created
== FALSE
);
1924 assert(cpm_obj
->pageout
== FALSE
);
1925 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
1928 * Insert pages into object.
1931 vm_object_lock(cpm_obj
);
1932 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
1934 pages
= NEXT_PAGE(m
);
1935 *(NEXT_PAGE_PTR(m
)) = VM_PAGE_NULL
;
1937 assert(!m
->gobbled
);
1939 assert(!m
->pageout
);
1943 * "m" is not supposed to be pageable, so it
1944 * should not be encrypted. It wouldn't be safe
1945 * to enter it in a new VM object while encrypted.
1947 ASSERT_PAGE_DECRYPTED(m
);
1949 assert(m
->phys_page
>=(avail_start
>>PAGE_SHIFT
) && m
->phys_page
<=(avail_end
>>PAGE_SHIFT
));
1952 vm_page_insert(m
, cpm_obj
, offset
);
1954 assert(cpm_obj
->resident_page_count
== size
/ PAGE_SIZE
);
1955 vm_object_unlock(cpm_obj
);
1958 * Hang onto a reference on the object in case a
1959 * multi-threaded application for some reason decides
1960 * to deallocate the portion of the address space into
1961 * which we will insert this object.
1963 * Unfortunately, we must insert the object now before
1964 * we can talk to the pmap module about which addresses
1965 * must be wired down. Hence, the race with a multi-
1968 vm_object_reference(cpm_obj
);
1971 * Insert object into map.
1981 (vm_object_offset_t
)0,
1985 VM_INHERIT_DEFAULT
);
1987 if (kr
!= KERN_SUCCESS
) {
1989 * A CPM object doesn't have can_persist set,
1990 * so all we have to do is deallocate it to
1991 * free up these pages.
1993 assert(cpm_obj
->pager_created
== FALSE
);
1994 assert(cpm_obj
->can_persist
== FALSE
);
1995 assert(cpm_obj
->pageout
== FALSE
);
1996 assert(cpm_obj
->shadow
== VM_OBJECT_NULL
);
1997 vm_object_deallocate(cpm_obj
); /* kill acquired ref */
1998 vm_object_deallocate(cpm_obj
); /* kill creation ref */
2002 * Inform the physical mapping system that the
2003 * range of addresses may not fault, so that
2004 * page tables and such can be locked down as well.
2008 pmap
= vm_map_pmap(map
);
2009 pmap_pageable(pmap
, start
, end
, FALSE
);
2012 * Enter each page into the pmap, to avoid faults.
2013 * Note that this loop could be coded more efficiently,
2014 * if the need arose, rather than looking up each page
2017 for (offset
= 0, va
= start
; offset
< size
;
2018 va
+= PAGE_SIZE
, offset
+= PAGE_SIZE
) {
2019 vm_object_lock(cpm_obj
);
2020 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
2021 vm_object_unlock(cpm_obj
);
2022 assert(m
!= VM_PAGE_NULL
);
2023 PMAP_ENTER(pmap
, va
, m
, VM_PROT_ALL
,
2024 ((unsigned int)(m
->object
->wimg_bits
)) & VM_WIMG_MASK
,
2030 * Verify ordering in address space.
2032 for (offset
= 0; offset
< size
; offset
+= PAGE_SIZE
) {
2033 vm_object_lock(cpm_obj
);
2034 m
= vm_page_lookup(cpm_obj
, (vm_object_offset_t
)offset
);
2035 vm_object_unlock(cpm_obj
);
2036 if (m
== VM_PAGE_NULL
)
2037 panic("vm_allocate_cpm: obj 0x%x off 0x%x no page",
2042 assert(!m
->fictitious
);
2043 assert(!m
->private);
2046 assert(!m
->cleaning
);
2047 assert(!m
->precious
);
2048 assert(!m
->clustered
);
2050 if (m
->phys_page
!= prev_addr
+ 1) {
2051 printf("start 0x%x end 0x%x va 0x%x\n",
2053 printf("obj 0x%x off 0x%x\n", cpm_obj
, offset
);
2054 printf("m 0x%x prev_address 0x%x\n", m
,
2056 panic("vm_allocate_cpm: pages not contig!");
2059 prev_addr
= m
->phys_page
;
2061 #endif /* MACH_ASSERT */
2063 vm_object_deallocate(cpm_obj
); /* kill extra ref */
2072 * Interface is defined in all cases, but unless the kernel
2073 * is built explicitly for this option, the interface does
2079 __unused vm_map_t map
,
2080 __unused vm_map_offset_t
*addr
,
2081 __unused vm_map_size_t size
,
2084 return KERN_FAILURE
;
2089 * vm_map_clip_start: [ internal use only ]
2091 * Asserts that the given entry begins at or after
2092 * the specified address; if necessary,
2093 * it splits the entry into two.
2095 #ifndef NO_NESTED_PMAP
2096 #define vm_map_clip_start(map, entry, startaddr) \
2098 vm_map_t VMCS_map; \
2099 vm_map_entry_t VMCS_entry; \
2100 vm_map_offset_t VMCS_startaddr; \
2102 VMCS_entry = (entry); \
2103 VMCS_startaddr = (startaddr); \
2104 if (VMCS_startaddr > VMCS_entry->vme_start) { \
2105 if(entry->use_pmap) { \
2106 vm_map_offset_t pmap_base_addr; \
2108 pmap_base_addr = 0xF0000000 & entry->vme_start; \
2109 pmap_unnest(map->pmap, (addr64_t)pmap_base_addr); \
2110 entry->use_pmap = FALSE; \
2111 } else if(entry->object.vm_object \
2112 && !entry->is_sub_map \
2113 && entry->object.vm_object->phys_contiguous) { \
2114 pmap_remove(map->pmap, \
2115 (addr64_t)(entry->vme_start), \
2116 (addr64_t)(entry->vme_end)); \
2118 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
2120 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2122 #else /* NO_NESTED_PMAP */
2123 #define vm_map_clip_start(map, entry, startaddr) \
2125 vm_map_t VMCS_map; \
2126 vm_map_entry_t VMCS_entry; \
2127 vm_map_offset_t VMCS_startaddr; \
2129 VMCS_entry = (entry); \
2130 VMCS_startaddr = (startaddr); \
2131 if (VMCS_startaddr > VMCS_entry->vme_start) { \
2132 _vm_map_clip_start(&VMCS_map->hdr,VMCS_entry,VMCS_startaddr);\
2134 UPDATE_FIRST_FREE(VMCS_map, VMCS_map->first_free); \
2136 #endif /* NO_NESTED_PMAP */
2138 #define vm_map_copy_clip_start(copy, entry, startaddr) \
2140 if ((startaddr) > (entry)->vme_start) \
2141 _vm_map_clip_start(&(copy)->cpy_hdr,(entry),(startaddr)); \
2145 * This routine is called only when it is known that
2146 * the entry must be split.
2150 register struct vm_map_header
*map_header
,
2151 register vm_map_entry_t entry
,
2152 register vm_map_offset_t start
)
2154 register vm_map_entry_t new_entry
;
2157 * Split off the front portion --
2158 * note that we must insert the new
2159 * entry BEFORE this one, so that
2160 * this entry has the specified starting
2164 new_entry
= _vm_map_entry_create(map_header
);
2165 vm_map_entry_copy_full(new_entry
, entry
);
2167 new_entry
->vme_end
= start
;
2168 entry
->offset
+= (start
- entry
->vme_start
);
2169 entry
->vme_start
= start
;
2171 _vm_map_entry_link(map_header
, entry
->vme_prev
, new_entry
);
2173 if (entry
->is_sub_map
)
2174 vm_map_reference(new_entry
->object
.sub_map
);
2176 vm_object_reference(new_entry
->object
.vm_object
);
2181 * vm_map_clip_end: [ internal use only ]
2183 * Asserts that the given entry ends at or before
2184 * the specified address; if necessary,
2185 * it splits the entry into two.
2187 #ifndef NO_NESTED_PMAP
2188 #define vm_map_clip_end(map, entry, endaddr) \
2190 vm_map_t VMCE_map; \
2191 vm_map_entry_t VMCE_entry; \
2192 vm_map_offset_t VMCE_endaddr; \
2194 VMCE_entry = (entry); \
2195 VMCE_endaddr = (endaddr); \
2196 if (VMCE_endaddr < VMCE_entry->vme_end) { \
2197 if(entry->use_pmap) { \
2198 vm_map_offset_t pmap_base_addr; \
2200 pmap_base_addr = 0xF0000000 & entry->vme_start; \
2201 pmap_unnest(map->pmap, (addr64_t)pmap_base_addr); \
2202 entry->use_pmap = FALSE; \
2203 } else if(entry->object.vm_object \
2204 && !entry->is_sub_map \
2205 && entry->object.vm_object->phys_contiguous) { \
2206 pmap_remove(map->pmap, \
2207 (addr64_t)(entry->vme_start), \
2208 (addr64_t)(entry->vme_end)); \
2210 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
2212 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2214 #else /* NO_NESTED_PMAP */
2215 #define vm_map_clip_end(map, entry, endaddr) \
2217 vm_map_t VMCE_map; \
2218 vm_map_entry_t VMCE_entry; \
2219 vm_map_offset_t VMCE_endaddr; \
2221 VMCE_entry = (entry); \
2222 VMCE_endaddr = (endaddr); \
2223 if (VMCE_endaddr < VMCE_entry->vme_end) { \
2224 _vm_map_clip_end(&VMCE_map->hdr,VMCE_entry,VMCE_endaddr); \
2226 UPDATE_FIRST_FREE(VMCE_map, VMCE_map->first_free); \
2228 #endif /* NO_NESTED_PMAP */
2231 #define vm_map_copy_clip_end(copy, entry, endaddr) \
2233 if ((endaddr) < (entry)->vme_end) \
2234 _vm_map_clip_end(&(copy)->cpy_hdr,(entry),(endaddr)); \
2238 * This routine is called only when it is known that
2239 * the entry must be split.
2243 register struct vm_map_header
*map_header
,
2244 register vm_map_entry_t entry
,
2245 register vm_map_offset_t end
)
2247 register vm_map_entry_t new_entry
;
2250 * Create a new entry and insert it
2251 * AFTER the specified entry
2254 new_entry
= _vm_map_entry_create(map_header
);
2255 vm_map_entry_copy_full(new_entry
, entry
);
2257 new_entry
->vme_start
= entry
->vme_end
= end
;
2258 new_entry
->offset
+= (end
- entry
->vme_start
);
2260 _vm_map_entry_link(map_header
, entry
, new_entry
);
2262 if (entry
->is_sub_map
)
2263 vm_map_reference(new_entry
->object
.sub_map
);
2265 vm_object_reference(new_entry
->object
.vm_object
);
2270 * VM_MAP_RANGE_CHECK: [ internal use only ]
2272 * Asserts that the starting and ending region
2273 * addresses fall within the valid range of the map.
2275 #define VM_MAP_RANGE_CHECK(map, start, end) \
2277 if (start < vm_map_min(map)) \
2278 start = vm_map_min(map); \
2279 if (end > vm_map_max(map)) \
2280 end = vm_map_max(map); \
2286 * vm_map_range_check: [ internal use only ]
2288 * Check that the region defined by the specified start and
2289 * end addresses are wholly contained within a single map
2290 * entry or set of adjacent map entries of the spacified map,
2291 * i.e. the specified region contains no unmapped space.
2292 * If any or all of the region is unmapped, FALSE is returned.
2293 * Otherwise, TRUE is returned and if the output argument 'entry'
2294 * is not NULL it points to the map entry containing the start
2297 * The map is locked for reading on entry and is left locked.
2301 register vm_map_t map
,
2302 register vm_map_offset_t start
,
2303 register vm_map_offset_t end
,
2304 vm_map_entry_t
*entry
)
2307 register vm_map_offset_t prev
;
2310 * Basic sanity checks first
2312 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
2316 * Check first if the region starts within a valid
2317 * mapping for the map.
2319 if (!vm_map_lookup_entry(map
, start
, &cur
))
2323 * Optimize for the case that the region is contained
2324 * in a single map entry.
2326 if (entry
!= (vm_map_entry_t
*) NULL
)
2328 if (end
<= cur
->vme_end
)
2332 * If the region is not wholly contained within a
2333 * single entry, walk the entries looking for holes.
2335 prev
= cur
->vme_end
;
2336 cur
= cur
->vme_next
;
2337 while ((cur
!= vm_map_to_entry(map
)) && (prev
== cur
->vme_start
)) {
2338 if (end
<= cur
->vme_end
)
2340 prev
= cur
->vme_end
;
2341 cur
= cur
->vme_next
;
2347 * vm_map_submap: [ kernel use only ]
2349 * Mark the given range as handled by a subordinate map.
2351 * This range must have been created with vm_map_find using
2352 * the vm_submap_object, and no other operations may have been
2353 * performed on this range prior to calling vm_map_submap.
2355 * Only a limited number of operations can be performed
2356 * within this rage after calling vm_map_submap:
2358 * [Don't try vm_map_copyin!]
2360 * To remove a submapping, one must first remove the
2361 * range from the superior map, and then destroy the
2362 * submap (if desired). [Better yet, don't try it.]
2367 vm_map_offset_t start
,
2368 vm_map_offset_t end
,
2370 vm_map_offset_t offset
,
2371 #ifdef NO_NESTED_PMAP
2373 #endif /* NO_NESTED_PMAP */
2376 vm_map_entry_t entry
;
2377 register kern_return_t result
= KERN_INVALID_ARGUMENT
;
2378 register vm_object_t object
;
2382 submap
->mapped
= TRUE
;
2384 VM_MAP_RANGE_CHECK(map
, start
, end
);
2386 if (vm_map_lookup_entry(map
, start
, &entry
)) {
2387 vm_map_clip_start(map
, entry
, start
);
2390 entry
= entry
->vme_next
;
2392 if(entry
== vm_map_to_entry(map
)) {
2394 return KERN_INVALID_ARGUMENT
;
2397 vm_map_clip_end(map
, entry
, end
);
2399 if ((entry
->vme_start
== start
) && (entry
->vme_end
== end
) &&
2400 (!entry
->is_sub_map
) &&
2401 ((object
= entry
->object
.vm_object
) == vm_submap_object
) &&
2402 (object
->resident_page_count
== 0) &&
2403 (object
->copy
== VM_OBJECT_NULL
) &&
2404 (object
->shadow
== VM_OBJECT_NULL
) &&
2405 (!object
->pager_created
)) {
2406 entry
->offset
= (vm_object_offset_t
)offset
;
2407 entry
->object
.vm_object
= VM_OBJECT_NULL
;
2408 vm_object_deallocate(object
);
2409 entry
->is_sub_map
= TRUE
;
2410 entry
->object
.sub_map
= submap
;
2411 vm_map_reference(submap
);
2412 #ifndef NO_NESTED_PMAP
2413 if ((use_pmap
) && (offset
== 0)) {
2414 /* nest if platform code will allow */
2415 if(submap
->pmap
== NULL
) {
2416 submap
->pmap
= pmap_create((vm_map_size_t
) 0, FALSE
);
2417 if(submap
->pmap
== PMAP_NULL
) {
2419 return(KERN_NO_SPACE
);
2422 result
= pmap_nest(map
->pmap
, (entry
->object
.sub_map
)->pmap
,
2425 (uint64_t)(end
- start
));
2427 panic("vm_map_submap: pmap_nest failed, rc = %08X\n", result
);
2428 entry
->use_pmap
= TRUE
;
2430 #else /* NO_NESTED_PMAP */
2431 pmap_remove(map
->pmap
, (addr64_t
)start
, (addr64_t
)end
);
2432 #endif /* NO_NESTED_PMAP */
2433 result
= KERN_SUCCESS
;
2443 * Sets the protection of the specified address
2444 * region in the target map. If "set_max" is
2445 * specified, the maximum protection is to be set;
2446 * otherwise, only the current protection is affected.
2450 register vm_map_t map
,
2451 register vm_map_offset_t start
,
2452 register vm_map_offset_t end
,
2453 register vm_prot_t new_prot
,
2454 register boolean_t set_max
)
2456 register vm_map_entry_t current
;
2457 register vm_map_offset_t prev
;
2458 vm_map_entry_t entry
;
2463 "vm_map_protect, 0x%X start 0x%X end 0x%X, new 0x%X %d",
2464 (integer_t
)map
, start
, end
, new_prot
, set_max
);
2468 /* LP64todo - remove this check when vm_map_commpage64()
2469 * no longer has to stuff in a map_entry for the commpage
2470 * above the map's max_offset.
2472 if (start
>= map
->max_offset
) {
2474 return(KERN_INVALID_ADDRESS
);
2478 * Lookup the entry. If it doesn't start in a valid
2479 * entry, return an error. Remember if we need to
2480 * clip the entry. We don't do it here because we don't
2481 * want to make any changes until we've scanned the
2482 * entire range below for address and protection
2485 if (!(clip
= vm_map_lookup_entry(map
, start
, &entry
))) {
2487 return(KERN_INVALID_ADDRESS
);
2491 * Make a first pass to check for protection and address
2496 prev
= current
->vme_start
;
2497 while ((current
!= vm_map_to_entry(map
)) &&
2498 (current
->vme_start
< end
)) {
2501 * If there is a hole, return an error.
2503 if (current
->vme_start
!= prev
) {
2505 return(KERN_INVALID_ADDRESS
);
2508 new_max
= current
->max_protection
;
2509 if(new_prot
& VM_PROT_COPY
) {
2510 new_max
|= VM_PROT_WRITE
;
2511 if ((new_prot
& (new_max
| VM_PROT_COPY
)) != new_prot
) {
2513 return(KERN_PROTECTION_FAILURE
);
2516 if ((new_prot
& new_max
) != new_prot
) {
2518 return(KERN_PROTECTION_FAILURE
);
2522 prev
= current
->vme_end
;
2523 current
= current
->vme_next
;
2527 return(KERN_INVALID_ADDRESS
);
2531 * Go back and fix up protections.
2532 * Clip to start here if the range starts within
2538 vm_map_clip_start(map
, entry
, start
);
2540 while ((current
!= vm_map_to_entry(map
)) &&
2541 (current
->vme_start
< end
)) {
2545 vm_map_clip_end(map
, current
, end
);
2547 old_prot
= current
->protection
;
2549 if(new_prot
& VM_PROT_COPY
) {
2550 /* caller is asking specifically to copy the */
2551 /* mapped data, this implies that max protection */
2552 /* will include write. Caller must be prepared */
2553 /* for loss of shared memory communication in the */
2554 /* target area after taking this step */
2555 current
->needs_copy
= TRUE
;
2556 current
->max_protection
|= VM_PROT_WRITE
;
2560 current
->protection
=
2561 (current
->max_protection
=
2562 new_prot
& ~VM_PROT_COPY
) &
2565 current
->protection
= new_prot
& ~VM_PROT_COPY
;
2568 * Update physical map if necessary.
2569 * If the request is to turn off write protection,
2570 * we won't do it for real (in pmap). This is because
2571 * it would cause copy-on-write to fail. We've already
2572 * set, the new protection in the map, so if a
2573 * write-protect fault occurred, it will be fixed up
2574 * properly, COW or not.
2576 /* the 256M hack for existing hardware limitations */
2577 if (current
->protection
!= old_prot
) {
2578 if(current
->is_sub_map
&& current
->use_pmap
) {
2579 vm_map_offset_t pmap_base_addr
;
2580 vm_map_offset_t pmap_end_addr
;
2581 #ifdef NO_NESTED_PMAP
2583 #endif /* NO_NESTED_PMAP */
2584 vm_map_entry_t local_entry
;
2587 pmap_base_addr
= 0xF0000000 & current
->vme_start
;
2588 pmap_end_addr
= (pmap_base_addr
+ 0x10000000) - 1;
2589 #ifndef NO_NESTED_PMAP
2590 if(!vm_map_lookup_entry(map
,
2591 pmap_base_addr
, &local_entry
))
2592 panic("vm_map_protect: nested pmap area is missing");
2593 while ((local_entry
!= vm_map_to_entry(map
)) &&
2594 (local_entry
->vme_start
< pmap_end_addr
)) {
2595 local_entry
->use_pmap
= FALSE
;
2596 local_entry
= local_entry
->vme_next
;
2598 pmap_unnest(map
->pmap
, (addr64_t
)pmap_base_addr
);
2599 #endif /* NO_NESTED_PMAP */
2601 if (!(current
->protection
& VM_PROT_WRITE
)) {
2602 /* Look one level in we support nested pmaps */
2603 /* from mapped submaps which are direct entries */
2608 prot
= current
->protection
;
2609 #ifdef STACK_ONLY_NX
2610 if (current
->alias
!= VM_MEMORY_STACK
&& prot
)
2611 prot
|= VM_PROT_EXECUTE
;
2613 if (current
->is_sub_map
&& current
->use_pmap
) {
2614 pmap_protect(current
->object
.sub_map
->pmap
,
2619 pmap_protect(map
->pmap
, current
->vme_start
,
2625 current
= current
->vme_next
;
2629 while ((current
!= vm_map_to_entry(map
)) &&
2630 (current
->vme_start
<= end
)) {
2631 vm_map_simplify_entry(map
, current
);
2632 current
= current
->vme_next
;
2636 return(KERN_SUCCESS
);
2642 * Sets the inheritance of the specified address
2643 * range in the target map. Inheritance
2644 * affects how the map will be shared with
2645 * child maps at the time of vm_map_fork.
2649 register vm_map_t map
,
2650 register vm_map_offset_t start
,
2651 register vm_map_offset_t end
,
2652 register vm_inherit_t new_inheritance
)
2654 register vm_map_entry_t entry
;
2655 vm_map_entry_t temp_entry
;
2659 VM_MAP_RANGE_CHECK(map
, start
, end
);
2661 if (vm_map_lookup_entry(map
, start
, &temp_entry
)) {
2663 vm_map_clip_start(map
, entry
, start
);
2666 temp_entry
= temp_entry
->vme_next
;
2670 /* first check entire range for submaps which can't support the */
2671 /* given inheritance. */
2672 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2673 if(entry
->is_sub_map
) {
2674 if(new_inheritance
== VM_INHERIT_COPY
) {
2676 return(KERN_INVALID_ARGUMENT
);
2680 entry
= entry
->vme_next
;
2685 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2686 vm_map_clip_end(map
, entry
, end
);
2688 entry
->inheritance
= new_inheritance
;
2690 entry
= entry
->vme_next
;
2694 return(KERN_SUCCESS
);
2700 * Sets the pageability of the specified address range in the
2701 * target map as wired. Regions specified as not pageable require
2702 * locked-down physical memory and physical page maps. The
2703 * access_type variable indicates types of accesses that must not
2704 * generate page faults. This is checked against protection of
2705 * memory being locked-down.
2707 * The map must not be locked, but a reference must remain to the
2708 * map throughout the call.
2710 static kern_return_t
2712 register vm_map_t map
,
2713 register vm_map_offset_t start
,
2714 register vm_map_offset_t end
,
2715 register vm_prot_t access_type
,
2716 boolean_t user_wire
,
2718 vm_map_offset_t pmap_addr
)
2720 register vm_map_entry_t entry
;
2721 struct vm_map_entry
*first_entry
, tmp_entry
;
2723 register vm_map_offset_t s
,e
;
2725 boolean_t need_wakeup
;
2726 boolean_t main_map
= FALSE
;
2727 wait_interrupt_t interruptible_state
;
2728 thread_t cur_thread
;
2729 unsigned int last_timestamp
;
2733 if(map_pmap
== NULL
)
2735 last_timestamp
= map
->timestamp
;
2737 VM_MAP_RANGE_CHECK(map
, start
, end
);
2738 assert(page_aligned(start
));
2739 assert(page_aligned(end
));
2741 /* We wired what the caller asked for, zero pages */
2743 return KERN_SUCCESS
;
2746 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
2747 entry
= first_entry
;
2748 /* vm_map_clip_start will be done later. */
2750 /* Start address is not in map */
2752 return(KERN_INVALID_ADDRESS
);
2756 need_wakeup
= FALSE
;
2757 cur_thread
= current_thread();
2758 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
2760 * If another thread is wiring/unwiring this entry then
2761 * block after informing other thread to wake us up.
2763 if (entry
->in_transition
) {
2764 wait_result_t wait_result
;
2767 * We have not clipped the entry. Make sure that
2768 * the start address is in range so that the lookup
2769 * below will succeed.
2771 s
= entry
->vme_start
< start
? start
: entry
->vme_start
;
2773 entry
->needs_wakeup
= TRUE
;
2776 * wake up anybody waiting on entries that we have
2780 vm_map_entry_wakeup(map
);
2781 need_wakeup
= FALSE
;
2784 * User wiring is interruptible
2786 wait_result
= vm_map_entry_wait(map
,
2787 (user_wire
) ? THREAD_ABORTSAFE
:
2789 if (user_wire
&& wait_result
== THREAD_INTERRUPTED
) {
2791 * undo the wirings we have done so far
2792 * We do not clear the needs_wakeup flag,
2793 * because we cannot tell if we were the
2797 vm_map_unwire(map
, start
, s
, user_wire
);
2798 return(KERN_FAILURE
);
2802 * Cannot avoid a lookup here. reset timestamp.
2804 last_timestamp
= map
->timestamp
;
2807 * The entry could have been clipped, look it up again.
2808 * Worse that can happen is, it may not exist anymore.
2810 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
2812 panic("vm_map_wire: re-lookup failed");
2815 * User: undo everything upto the previous
2816 * entry. let vm_map_unwire worry about
2817 * checking the validity of the range.
2820 vm_map_unwire(map
, start
, s
, user_wire
);
2821 return(KERN_FAILURE
);
2823 entry
= first_entry
;
2827 if(entry
->is_sub_map
) {
2828 vm_map_offset_t sub_start
;
2829 vm_map_offset_t sub_end
;
2830 vm_map_offset_t local_start
;
2831 vm_map_offset_t local_end
;
2834 vm_map_clip_start(map
, entry
, start
);
2835 vm_map_clip_end(map
, entry
, end
);
2837 sub_start
= entry
->offset
;
2838 sub_end
= entry
->vme_end
- entry
->vme_start
;
2839 sub_end
+= entry
->offset
;
2841 local_end
= entry
->vme_end
;
2842 if(map_pmap
== NULL
) {
2843 if(entry
->use_pmap
) {
2844 pmap
= entry
->object
.sub_map
->pmap
;
2845 /* ppc implementation requires that */
2846 /* submaps pmap address ranges line */
2847 /* up with parent map */
2849 pmap_addr
= sub_start
;
2856 if (entry
->wired_count
) {
2857 if (entry
->wired_count
2859 panic("vm_map_wire: too many wirings");
2862 entry
->user_wired_count
2863 >= MAX_WIRE_COUNT
) {
2865 vm_map_unwire(map
, start
,
2866 entry
->vme_start
, user_wire
);
2867 return(KERN_FAILURE
);
2870 entry
->user_wired_count
++;
2872 (entry
->user_wired_count
== 0))
2873 entry
->wired_count
++;
2874 entry
= entry
->vme_next
;
2879 vm_map_offset_t offset_hi
;
2880 vm_map_offset_t offset_lo
;
2881 vm_object_offset_t offset
;
2884 vm_behavior_t behavior
;
2885 vm_map_entry_t local_entry
;
2886 vm_map_version_t version
;
2887 vm_map_t lookup_map
;
2889 /* call vm_map_lookup_locked to */
2890 /* cause any needs copy to be */
2892 local_start
= entry
->vme_start
;
2894 vm_map_lock_write_to_read(map
);
2895 if(vm_map_lookup_locked(
2896 &lookup_map
, local_start
,
2899 &offset
, &prot
, &wired
,
2900 &behavior
, &offset_lo
,
2901 &offset_hi
, &real_map
)) {
2903 vm_map_unlock_read(lookup_map
);
2904 vm_map_unwire(map
, start
,
2905 entry
->vme_start
, user_wire
);
2906 return(KERN_FAILURE
);
2908 if(real_map
!= lookup_map
)
2909 vm_map_unlock(real_map
);
2910 vm_map_unlock_read(lookup_map
);
2912 vm_object_unlock(object
);
2914 if (!vm_map_lookup_entry(map
,
2915 local_start
, &local_entry
)) {
2917 vm_map_unwire(map
, start
,
2918 entry
->vme_start
, user_wire
);
2919 return(KERN_FAILURE
);
2921 /* did we have a change of type? */
2922 if (!local_entry
->is_sub_map
) {
2923 last_timestamp
= map
->timestamp
;
2926 entry
= local_entry
;
2928 entry
->user_wired_count
++;
2930 (entry
->user_wired_count
== 1))
2931 entry
->wired_count
++;
2933 entry
->in_transition
= TRUE
;
2936 rc
= vm_map_wire_nested(
2937 entry
->object
.sub_map
,
2940 user_wire
, pmap
, pmap_addr
);
2944 local_start
= entry
->vme_start
;
2946 entry
->user_wired_count
++;
2948 (entry
->user_wired_count
== 1))
2949 entry
->wired_count
++;
2951 rc
= vm_map_wire_nested(entry
->object
.sub_map
,
2954 user_wire
, map_pmap
, pmap_addr
);
2957 s
= entry
->vme_start
;
2961 * Find the entry again. It could have been clipped
2962 * after we unlocked the map.
2964 if (!vm_map_lookup_entry(map
, local_start
,
2966 panic("vm_map_wire: re-lookup failed");
2967 entry
= first_entry
;
2969 last_timestamp
= map
->timestamp
;
2970 while ((entry
!= vm_map_to_entry(map
)) &&
2971 (entry
->vme_start
< e
)) {
2972 assert(entry
->in_transition
);
2973 entry
->in_transition
= FALSE
;
2974 if (entry
->needs_wakeup
) {
2975 entry
->needs_wakeup
= FALSE
;
2978 if (rc
!= KERN_SUCCESS
) {/* from vm_*_wire */
2980 entry
->user_wired_count
--;
2982 (entry
->user_wired_count
== 0))
2983 entry
->wired_count
--;
2985 entry
= entry
->vme_next
;
2987 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
2990 vm_map_entry_wakeup(map
);
2992 * undo everything upto the previous entry.
2994 (void)vm_map_unwire(map
, start
, s
, user_wire
);
3001 * If this entry is already wired then increment
3002 * the appropriate wire reference count.
3004 if (entry
->wired_count
) {
3005 /* sanity check: wired_count is a short */
3006 if (entry
->wired_count
>= MAX_WIRE_COUNT
)
3007 panic("vm_map_wire: too many wirings");
3010 entry
->user_wired_count
>= MAX_WIRE_COUNT
) {
3012 vm_map_unwire(map
, start
,
3013 entry
->vme_start
, user_wire
);
3014 return(KERN_FAILURE
);
3017 * entry is already wired down, get our reference
3018 * after clipping to our range.
3020 vm_map_clip_start(map
, entry
, start
);
3021 vm_map_clip_end(map
, entry
, end
);
3023 entry
->user_wired_count
++;
3024 if ((!user_wire
) || (entry
->user_wired_count
== 1))
3025 entry
->wired_count
++;
3027 entry
= entry
->vme_next
;
3032 * Unwired entry or wire request transmitted via submap
3037 * Perform actions of vm_map_lookup that need the write
3038 * lock on the map: create a shadow object for a
3039 * copy-on-write region, or an object for a zero-fill
3042 size
= entry
->vme_end
- entry
->vme_start
;
3044 * If wiring a copy-on-write page, we need to copy it now
3045 * even if we're only (currently) requesting read access.
3046 * This is aggressive, but once it's wired we can't move it.
3048 if (entry
->needs_copy
) {
3049 vm_object_shadow(&entry
->object
.vm_object
,
3050 &entry
->offset
, size
);
3051 entry
->needs_copy
= FALSE
;
3052 } else if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
3053 entry
->object
.vm_object
= vm_object_allocate(size
);
3054 entry
->offset
= (vm_object_offset_t
)0;
3057 vm_map_clip_start(map
, entry
, start
);
3058 vm_map_clip_end(map
, entry
, end
);
3060 s
= entry
->vme_start
;
3064 * Check for holes and protection mismatch.
3065 * Holes: Next entry should be contiguous unless this
3066 * is the end of the region.
3067 * Protection: Access requested must be allowed, unless
3068 * wiring is by protection class
3070 if ((((entry
->vme_end
< end
) &&
3071 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3072 (entry
->vme_next
->vme_start
> entry
->vme_end
))) ||
3073 ((entry
->protection
& access_type
) != access_type
))) {
3075 * Found a hole or protection problem.
3076 * Unwire the region we wired so far.
3078 if (start
!= entry
->vme_start
) {
3080 vm_map_unwire(map
, start
, s
, user_wire
);
3084 return((entry
->protection
&access_type
) != access_type
?
3085 KERN_PROTECTION_FAILURE
: KERN_INVALID_ADDRESS
);
3088 assert(entry
->wired_count
== 0 && entry
->user_wired_count
== 0);
3091 entry
->user_wired_count
++;
3092 if ((!user_wire
) || (entry
->user_wired_count
== 1))
3093 entry
->wired_count
++;
3095 entry
->in_transition
= TRUE
;
3098 * This entry might get split once we unlock the map.
3099 * In vm_fault_wire(), we need the current range as
3100 * defined by this entry. In order for this to work
3101 * along with a simultaneous clip operation, we make a
3102 * temporary copy of this entry and use that for the
3103 * wiring. Note that the underlying objects do not
3104 * change during a clip.
3109 * The in_transition state guarentees that the entry
3110 * (or entries for this range, if split occured) will be
3111 * there when the map lock is acquired for the second time.
3115 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
3116 interruptible_state
= thread_interrupt_level(THREAD_UNINT
);
3118 interruptible_state
= THREAD_UNINT
;
3121 rc
= vm_fault_wire(map
,
3122 &tmp_entry
, map_pmap
, pmap_addr
);
3124 rc
= vm_fault_wire(map
,
3125 &tmp_entry
, map
->pmap
,
3126 tmp_entry
.vme_start
);
3128 if (!user_wire
&& cur_thread
!= THREAD_NULL
)
3129 thread_interrupt_level(interruptible_state
);
3133 if (last_timestamp
+1 != map
->timestamp
) {
3135 * Find the entry again. It could have been clipped
3136 * after we unlocked the map.
3138 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3140 panic("vm_map_wire: re-lookup failed");
3142 entry
= first_entry
;
3145 last_timestamp
= map
->timestamp
;
3147 while ((entry
!= vm_map_to_entry(map
)) &&
3148 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3149 assert(entry
->in_transition
);
3150 entry
->in_transition
= FALSE
;
3151 if (entry
->needs_wakeup
) {
3152 entry
->needs_wakeup
= FALSE
;
3155 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3157 entry
->user_wired_count
--;
3159 (entry
->user_wired_count
== 0))
3160 entry
->wired_count
--;
3162 entry
= entry
->vme_next
;
3165 if (rc
!= KERN_SUCCESS
) { /* from vm_*_wire */
3168 vm_map_entry_wakeup(map
);
3170 * undo everything upto the previous entry.
3172 (void)vm_map_unwire(map
, start
, s
, user_wire
);
3175 } /* end while loop through map entries */
3179 * wake up anybody waiting on entries we wired.
3182 vm_map_entry_wakeup(map
);
3184 return(KERN_SUCCESS
);
3190 register vm_map_t map
,
3191 register vm_map_offset_t start
,
3192 register vm_map_offset_t end
,
3193 register vm_prot_t access_type
,
3194 boolean_t user_wire
)
3201 * the calls to mapping_prealloc and mapping_relpre
3202 * (along with the VM_MAP_RANGE_CHECK to insure a
3203 * resonable range was passed in) are
3204 * currently necessary because
3205 * we haven't enabled kernel pre-emption
3206 * and/or the pmap_enter cannot purge and re-use
3209 VM_MAP_RANGE_CHECK(map
, start
, end
);
3210 mapping_prealloc(end
- start
);
3212 kret
= vm_map_wire_nested(map
, start
, end
, access_type
,
3213 user_wire
, (pmap_t
)NULL
, 0);
3223 * Sets the pageability of the specified address range in the target
3224 * as pageable. Regions specified must have been wired previously.
3226 * The map must not be locked, but a reference must remain to the map
3227 * throughout the call.
3229 * Kernel will panic on failures. User unwire ignores holes and
3230 * unwired and intransition entries to avoid losing memory by leaving
3233 static kern_return_t
3234 vm_map_unwire_nested(
3235 register vm_map_t map
,
3236 register vm_map_offset_t start
,
3237 register vm_map_offset_t end
,
3238 boolean_t user_wire
,
3240 vm_map_offset_t pmap_addr
)
3242 register vm_map_entry_t entry
;
3243 struct vm_map_entry
*first_entry
, tmp_entry
;
3244 boolean_t need_wakeup
;
3245 boolean_t main_map
= FALSE
;
3246 unsigned int last_timestamp
;
3249 if(map_pmap
== NULL
)
3251 last_timestamp
= map
->timestamp
;
3253 VM_MAP_RANGE_CHECK(map
, start
, end
);
3254 assert(page_aligned(start
));
3255 assert(page_aligned(end
));
3257 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3258 entry
= first_entry
;
3259 /* vm_map_clip_start will be done later. */
3262 /* Start address is not in map. */
3264 return(KERN_INVALID_ADDRESS
);
3267 need_wakeup
= FALSE
;
3268 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3269 if (entry
->in_transition
) {
3272 * Another thread is wiring down this entry. Note
3273 * that if it is not for the other thread we would
3274 * be unwiring an unwired entry. This is not
3275 * permitted. If we wait, we will be unwiring memory
3279 * Another thread is unwiring this entry. We did not
3280 * have a reference to it, because if we did, this
3281 * entry will not be getting unwired now.
3284 panic("vm_map_unwire: in_transition entry");
3286 entry
= entry
->vme_next
;
3290 if(entry
->is_sub_map
) {
3291 vm_map_offset_t sub_start
;
3292 vm_map_offset_t sub_end
;
3293 vm_map_offset_t local_end
;
3297 vm_map_clip_start(map
, entry
, start
);
3298 vm_map_clip_end(map
, entry
, end
);
3300 sub_start
= entry
->offset
;
3301 sub_end
= entry
->vme_end
- entry
->vme_start
;
3302 sub_end
+= entry
->offset
;
3303 local_end
= entry
->vme_end
;
3304 if(map_pmap
== NULL
) {
3305 if(entry
->use_pmap
) {
3306 pmap
= entry
->object
.sub_map
->pmap
;
3307 pmap_addr
= sub_start
;
3312 if (entry
->wired_count
== 0 ||
3313 (user_wire
&& entry
->user_wired_count
== 0)) {
3315 panic("vm_map_unwire: entry is unwired");
3316 entry
= entry
->vme_next
;
3322 * Holes: Next entry should be contiguous unless
3323 * this is the end of the region.
3325 if (((entry
->vme_end
< end
) &&
3326 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3327 (entry
->vme_next
->vme_start
3328 > entry
->vme_end
)))) {
3330 panic("vm_map_unwire: non-contiguous region");
3332 entry = entry->vme_next;
3337 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3338 entry
->wired_count
--;
3340 if (entry
->wired_count
!= 0) {
3341 entry
= entry
->vme_next
;
3345 entry
->in_transition
= TRUE
;
3346 tmp_entry
= *entry
;/* see comment in vm_map_wire() */
3349 * We can unlock the map now. The in_transition state
3350 * guarantees existance of the entry.
3353 vm_map_unwire_nested(entry
->object
.sub_map
,
3354 sub_start
, sub_end
, user_wire
, pmap
, pmap_addr
);
3357 if (last_timestamp
+1 != map
->timestamp
) {
3359 * Find the entry again. It could have been
3360 * clipped or deleted after we unlocked the map.
3362 if (!vm_map_lookup_entry(map
,
3363 tmp_entry
.vme_start
,
3366 panic("vm_map_unwire: re-lookup failed");
3367 entry
= first_entry
->vme_next
;
3369 entry
= first_entry
;
3371 last_timestamp
= map
->timestamp
;
3374 * clear transition bit for all constituent entries
3375 * that were in the original entry (saved in
3376 * tmp_entry). Also check for waiters.
3378 while ((entry
!= vm_map_to_entry(map
)) &&
3379 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3380 assert(entry
->in_transition
);
3381 entry
->in_transition
= FALSE
;
3382 if (entry
->needs_wakeup
) {
3383 entry
->needs_wakeup
= FALSE
;
3386 entry
= entry
->vme_next
;
3391 vm_map_unwire_nested(entry
->object
.sub_map
,
3392 sub_start
, sub_end
, user_wire
, map_pmap
,
3396 if (last_timestamp
+1 != map
->timestamp
) {
3398 * Find the entry again. It could have been
3399 * clipped or deleted after we unlocked the map.
3401 if (!vm_map_lookup_entry(map
,
3402 tmp_entry
.vme_start
,
3405 panic("vm_map_unwire: re-lookup failed");
3406 entry
= first_entry
->vme_next
;
3408 entry
= first_entry
;
3410 last_timestamp
= map
->timestamp
;
3415 if ((entry
->wired_count
== 0) ||
3416 (user_wire
&& entry
->user_wired_count
== 0)) {
3418 panic("vm_map_unwire: entry is unwired");
3420 entry
= entry
->vme_next
;
3424 assert(entry
->wired_count
> 0 &&
3425 (!user_wire
|| entry
->user_wired_count
> 0));
3427 vm_map_clip_start(map
, entry
, start
);
3428 vm_map_clip_end(map
, entry
, end
);
3432 * Holes: Next entry should be contiguous unless
3433 * this is the end of the region.
3435 if (((entry
->vme_end
< end
) &&
3436 ((entry
->vme_next
== vm_map_to_entry(map
)) ||
3437 (entry
->vme_next
->vme_start
> entry
->vme_end
)))) {
3440 panic("vm_map_unwire: non-contiguous region");
3441 entry
= entry
->vme_next
;
3445 if (!user_wire
|| (--entry
->user_wired_count
== 0))
3446 entry
->wired_count
--;
3448 if (entry
->wired_count
!= 0) {
3449 entry
= entry
->vme_next
;
3453 entry
->in_transition
= TRUE
;
3454 tmp_entry
= *entry
; /* see comment in vm_map_wire() */
3457 * We can unlock the map now. The in_transition state
3458 * guarantees existance of the entry.
3462 vm_fault_unwire(map
,
3463 &tmp_entry
, FALSE
, map_pmap
, pmap_addr
);
3465 vm_fault_unwire(map
,
3466 &tmp_entry
, FALSE
, map
->pmap
,
3467 tmp_entry
.vme_start
);
3471 if (last_timestamp
+1 != map
->timestamp
) {
3473 * Find the entry again. It could have been clipped
3474 * or deleted after we unlocked the map.
3476 if (!vm_map_lookup_entry(map
, tmp_entry
.vme_start
,
3479 panic("vm_map_unwire: re-lookup failed");
3480 entry
= first_entry
->vme_next
;
3482 entry
= first_entry
;
3484 last_timestamp
= map
->timestamp
;
3487 * clear transition bit for all constituent entries that
3488 * were in the original entry (saved in tmp_entry). Also
3489 * check for waiters.
3491 while ((entry
!= vm_map_to_entry(map
)) &&
3492 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3493 assert(entry
->in_transition
);
3494 entry
->in_transition
= FALSE
;
3495 if (entry
->needs_wakeup
) {
3496 entry
->needs_wakeup
= FALSE
;
3499 entry
= entry
->vme_next
;
3504 * We might have fragmented the address space when we wired this
3505 * range of addresses. Attempt to re-coalesce these VM map entries
3506 * with their neighbors now that they're no longer wired.
3507 * Under some circumstances, address space fragmentation can
3508 * prevent VM object shadow chain collapsing, which can cause
3511 vm_map_simplify_range(map
, start
, end
);
3515 * wake up anybody waiting on entries that we have unwired.
3518 vm_map_entry_wakeup(map
);
3519 return(KERN_SUCCESS
);
3525 register vm_map_t map
,
3526 register vm_map_offset_t start
,
3527 register vm_map_offset_t end
,
3528 boolean_t user_wire
)
3530 return vm_map_unwire_nested(map
, start
, end
,
3531 user_wire
, (pmap_t
)NULL
, 0);
3536 * vm_map_entry_delete: [ internal use only ]
3538 * Deallocate the given entry from the target map.
3541 vm_map_entry_delete(
3542 register vm_map_t map
,
3543 register vm_map_entry_t entry
)
3545 register vm_map_offset_t s
, e
;
3546 register vm_object_t object
;
3547 register vm_map_t submap
;
3549 s
= entry
->vme_start
;
3551 assert(page_aligned(s
));
3552 assert(page_aligned(e
));
3553 assert(entry
->wired_count
== 0);
3554 assert(entry
->user_wired_count
== 0);
3556 if (entry
->is_sub_map
) {
3558 submap
= entry
->object
.sub_map
;
3561 object
= entry
->object
.vm_object
;
3564 vm_map_entry_unlink(map
, entry
);
3567 vm_map_entry_dispose(map
, entry
);
3571 * Deallocate the object only after removing all
3572 * pmap entries pointing to its pages.
3575 vm_map_deallocate(submap
);
3577 vm_object_deallocate(object
);
3583 vm_map_submap_pmap_clean(
3585 vm_map_offset_t start
,
3586 vm_map_offset_t end
,
3588 vm_map_offset_t offset
)
3590 vm_map_offset_t submap_start
;
3591 vm_map_offset_t submap_end
;
3592 vm_map_size_t remove_size
;
3593 vm_map_entry_t entry
;
3595 submap_end
= offset
+ (end
- start
);
3596 submap_start
= offset
;
3597 if(vm_map_lookup_entry(sub_map
, offset
, &entry
)) {
3599 remove_size
= (entry
->vme_end
- entry
->vme_start
);
3600 if(offset
> entry
->vme_start
)
3601 remove_size
-= offset
- entry
->vme_start
;
3604 if(submap_end
< entry
->vme_end
) {
3606 entry
->vme_end
- submap_end
;
3608 if(entry
->is_sub_map
) {
3609 vm_map_submap_pmap_clean(
3612 start
+ remove_size
,
3613 entry
->object
.sub_map
,
3617 if((map
->mapped
) && (map
->ref_count
)
3618 && (entry
->object
.vm_object
!= NULL
)) {
3619 vm_object_pmap_protect(
3620 entry
->object
.vm_object
,
3627 pmap_remove(map
->pmap
,
3629 (addr64_t
)(start
+ remove_size
));
3634 entry
= entry
->vme_next
;
3636 while((entry
!= vm_map_to_entry(sub_map
))
3637 && (entry
->vme_start
< submap_end
)) {
3638 remove_size
= (entry
->vme_end
- entry
->vme_start
);
3639 if(submap_end
< entry
->vme_end
) {
3640 remove_size
-= entry
->vme_end
- submap_end
;
3642 if(entry
->is_sub_map
) {
3643 vm_map_submap_pmap_clean(
3645 (start
+ entry
->vme_start
) - offset
,
3646 ((start
+ entry
->vme_start
) - offset
) + remove_size
,
3647 entry
->object
.sub_map
,
3650 if((map
->mapped
) && (map
->ref_count
)
3651 && (entry
->object
.vm_object
!= NULL
)) {
3652 vm_object_pmap_protect(
3653 entry
->object
.vm_object
,
3660 pmap_remove(map
->pmap
,
3661 (addr64_t
)((start
+ entry
->vme_start
)
3663 (addr64_t
)(((start
+ entry
->vme_start
)
3664 - offset
) + remove_size
));
3667 entry
= entry
->vme_next
;
3673 * vm_map_delete: [ internal use only ]
3675 * Deallocates the given address range from the target map.
3676 * Removes all user wirings. Unwires one kernel wiring if
3677 * VM_MAP_REMOVE_KUNWIRE is set. Waits for kernel wirings to go
3678 * away if VM_MAP_REMOVE_WAIT_FOR_KWIRE is set. Sleeps
3679 * interruptibly if VM_MAP_REMOVE_INTERRUPTIBLE is set.
3681 * This routine is called with map locked and leaves map locked.
3683 static kern_return_t
3686 vm_map_offset_t start
,
3687 vm_map_offset_t end
,
3691 vm_map_entry_t entry
, next
;
3692 struct vm_map_entry
*first_entry
, tmp_entry
;
3693 register vm_map_offset_t s
, e
;
3694 register vm_object_t object
;
3695 boolean_t need_wakeup
;
3696 unsigned int last_timestamp
= ~0; /* unlikely value */
3699 interruptible
= (flags
& VM_MAP_REMOVE_INTERRUPTIBLE
) ?
3700 THREAD_ABORTSAFE
: THREAD_UNINT
;
3703 * All our DMA I/O operations in IOKit are currently done by
3704 * wiring through the map entries of the task requesting the I/O.
3705 * Because of this, we must always wait for kernel wirings
3706 * to go away on the entries before deleting them.
3708 * Any caller who wants to actually remove a kernel wiring
3709 * should explicitly set the VM_MAP_REMOVE_KUNWIRE flag to
3710 * properly remove one wiring instead of blasting through
3713 flags
|= VM_MAP_REMOVE_WAIT_FOR_KWIRE
;
3716 * Find the start of the region, and clip it
3718 if (vm_map_lookup_entry(map
, start
, &first_entry
)) {
3719 entry
= first_entry
;
3720 vm_map_clip_start(map
, entry
, start
);
3723 * Fix the lookup hint now, rather than each
3724 * time through the loop.
3726 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
3728 entry
= first_entry
->vme_next
;
3731 need_wakeup
= FALSE
;
3733 * Step through all entries in this region
3735 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
3737 vm_map_clip_end(map
, entry
, end
);
3738 if (entry
->in_transition
) {
3739 wait_result_t wait_result
;
3742 * Another thread is wiring/unwiring this entry.
3743 * Let the other thread know we are waiting.
3745 s
= entry
->vme_start
;
3746 entry
->needs_wakeup
= TRUE
;
3749 * wake up anybody waiting on entries that we have
3750 * already unwired/deleted.
3753 vm_map_entry_wakeup(map
);
3754 need_wakeup
= FALSE
;
3757 wait_result
= vm_map_entry_wait(map
, interruptible
);
3759 if (interruptible
&&
3760 wait_result
== THREAD_INTERRUPTED
) {
3762 * We do not clear the needs_wakeup flag,
3763 * since we cannot tell if we were the only one.
3766 return KERN_ABORTED
;
3770 * The entry could have been clipped or it
3771 * may not exist anymore. Look it up again.
3773 if (!vm_map_lookup_entry(map
, s
, &first_entry
)) {
3774 assert((map
!= kernel_map
) &&
3775 (!entry
->is_sub_map
));
3777 * User: use the next entry
3779 entry
= first_entry
->vme_next
;
3781 entry
= first_entry
;
3782 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
3784 last_timestamp
= map
->timestamp
;
3786 } /* end in_transition */
3788 if (entry
->wired_count
) {
3790 * Remove a kernel wiring if requested or if
3791 * there are user wirings.
3793 if ((flags
& VM_MAP_REMOVE_KUNWIRE
) ||
3794 (entry
->user_wired_count
> 0))
3795 entry
->wired_count
--;
3797 /* remove all user wire references */
3798 entry
->user_wired_count
= 0;
3800 if (entry
->wired_count
!= 0) {
3801 assert((map
!= kernel_map
) &&
3802 (!entry
->is_sub_map
));
3804 * Cannot continue. Typical case is when
3805 * a user thread has physical io pending on
3806 * on this page. Either wait for the
3807 * kernel wiring to go away or return an
3810 if (flags
& VM_MAP_REMOVE_WAIT_FOR_KWIRE
) {
3811 wait_result_t wait_result
;
3813 s
= entry
->vme_start
;
3814 entry
->needs_wakeup
= TRUE
;
3815 wait_result
= vm_map_entry_wait(map
,
3818 if (interruptible
&&
3819 wait_result
== THREAD_INTERRUPTED
) {
3821 * We do not clear the
3822 * needs_wakeup flag, since we
3823 * cannot tell if we were the
3827 return KERN_ABORTED
;
3831 * The entry could have been clipped or
3832 * it may not exist anymore. Look it
3835 if (!vm_map_lookup_entry(map
, s
,
3837 assert((map
!= kernel_map
) &&
3838 (!entry
->is_sub_map
));
3840 * User: use the next entry
3842 entry
= first_entry
->vme_next
;
3844 entry
= first_entry
;
3845 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
3847 last_timestamp
= map
->timestamp
;
3851 return KERN_FAILURE
;
3855 entry
->in_transition
= TRUE
;
3857 * copy current entry. see comment in vm_map_wire()
3860 s
= entry
->vme_start
;
3864 * We can unlock the map now. The in_transition
3865 * state guarentees existance of the entry.
3868 vm_fault_unwire(map
, &tmp_entry
,
3869 tmp_entry
.object
.vm_object
== kernel_object
,
3870 map
->pmap
, tmp_entry
.vme_start
);
3873 if (last_timestamp
+1 != map
->timestamp
) {
3875 * Find the entry again. It could have
3876 * been clipped after we unlocked the map.
3878 if (!vm_map_lookup_entry(map
, s
, &first_entry
)){
3879 assert((map
!= kernel_map
) &&
3880 (!entry
->is_sub_map
));
3881 first_entry
= first_entry
->vme_next
;
3883 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
3886 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
3887 first_entry
= entry
;
3890 last_timestamp
= map
->timestamp
;
3892 entry
= first_entry
;
3893 while ((entry
!= vm_map_to_entry(map
)) &&
3894 (entry
->vme_start
< tmp_entry
.vme_end
)) {
3895 assert(entry
->in_transition
);
3896 entry
->in_transition
= FALSE
;
3897 if (entry
->needs_wakeup
) {
3898 entry
->needs_wakeup
= FALSE
;
3901 entry
= entry
->vme_next
;
3904 * We have unwired the entry(s). Go back and
3907 entry
= first_entry
;
3911 /* entry is unwired */
3912 assert(entry
->wired_count
== 0);
3913 assert(entry
->user_wired_count
== 0);
3915 if ((!entry
->is_sub_map
&&
3916 entry
->object
.vm_object
!= kernel_object
) ||
3917 entry
->is_sub_map
) {
3918 if(entry
->is_sub_map
) {
3919 if(entry
->use_pmap
) {
3920 #ifndef NO_NESTED_PMAP
3921 pmap_unnest(map
->pmap
,
3922 (addr64_t
)entry
->vme_start
);
3923 #endif /* NO_NESTED_PMAP */
3924 if((map
->mapped
) && (map
->ref_count
)) {
3925 /* clean up parent map/maps */
3926 vm_map_submap_pmap_clean(
3927 map
, entry
->vme_start
,
3929 entry
->object
.sub_map
,
3933 vm_map_submap_pmap_clean(
3934 map
, entry
->vme_start
, entry
->vme_end
,
3935 entry
->object
.sub_map
,
3939 object
= entry
->object
.vm_object
;
3940 if((map
->mapped
) && (map
->ref_count
)) {
3941 vm_object_pmap_protect(
3942 object
, entry
->offset
,
3943 entry
->vme_end
- entry
->vme_start
,
3948 pmap_remove(map
->pmap
,
3949 (addr64_t
)entry
->vme_start
,
3950 (addr64_t
)entry
->vme_end
);
3956 * All pmap mappings for this map entry must have been
3959 assert(vm_map_pmap_is_empty(map
,
3963 next
= entry
->vme_next
;
3964 s
= next
->vme_start
;
3965 last_timestamp
= map
->timestamp
;
3967 if ((flags
& VM_MAP_REMOVE_SAVE_ENTRIES
) &&
3968 zap_map
!= VM_MAP_NULL
) {
3970 * The caller wants to save the affected VM map entries
3971 * into the "zap_map". The caller will take care of
3974 /* unlink the entry from "map" ... */
3975 vm_map_entry_unlink(map
, entry
);
3976 /* ... and add it to the end of the "zap_map" */
3977 vm_map_entry_link(zap_map
,
3978 vm_map_last_entry(zap_map
),
3981 vm_map_entry_delete(map
, entry
);
3982 /* vm_map_entry_delete unlocks the map */
3988 if(entry
== vm_map_to_entry(map
)) {
3991 if (last_timestamp
+1 != map
->timestamp
) {
3993 * we are responsible for deleting everything
3994 * from the give space, if someone has interfered
3995 * we pick up where we left off, back fills should
3996 * be all right for anyone except map_delete and
3997 * we have to assume that the task has been fully
3998 * disabled before we get here
4000 if (!vm_map_lookup_entry(map
, s
, &entry
)){
4001 entry
= entry
->vme_next
;
4003 SAVE_HINT_MAP_WRITE(map
, entry
->vme_prev
);
4006 * others can not only allocate behind us, we can
4007 * also see coalesce while we don't have the map lock
4009 if(entry
== vm_map_to_entry(map
)) {
4012 vm_map_clip_start(map
, entry
, s
);
4014 last_timestamp
= map
->timestamp
;
4017 if (map
->wait_for_space
)
4018 thread_wakeup((event_t
) map
);
4020 * wake up anybody waiting on entries that we have already deleted.
4023 vm_map_entry_wakeup(map
);
4025 return KERN_SUCCESS
;
4032 * Remove the given address range from the target map.
4033 * This is the exported form of vm_map_delete.
4037 register vm_map_t map
,
4038 register vm_map_offset_t start
,
4039 register vm_map_offset_t end
,
4040 register boolean_t flags
)
4042 register kern_return_t result
;
4045 VM_MAP_RANGE_CHECK(map
, start
, end
);
4046 result
= vm_map_delete(map
, start
, end
, flags
, VM_MAP_NULL
);
4054 * Routine: vm_map_copy_discard
4057 * Dispose of a map copy object (returned by
4061 vm_map_copy_discard(
4064 TR_DECL("vm_map_copy_discard");
4066 /* tr3("enter: copy 0x%x type %d", copy, copy->type);*/
4068 if (copy
== VM_MAP_COPY_NULL
)
4071 switch (copy
->type
) {
4072 case VM_MAP_COPY_ENTRY_LIST
:
4073 while (vm_map_copy_first_entry(copy
) !=
4074 vm_map_copy_to_entry(copy
)) {
4075 vm_map_entry_t entry
= vm_map_copy_first_entry(copy
);
4077 vm_map_copy_entry_unlink(copy
, entry
);
4078 vm_object_deallocate(entry
->object
.vm_object
);
4079 vm_map_copy_entry_dispose(copy
, entry
);
4082 case VM_MAP_COPY_OBJECT
:
4083 vm_object_deallocate(copy
->cpy_object
);
4085 case VM_MAP_COPY_KERNEL_BUFFER
:
4088 * The vm_map_copy_t and possibly the data buffer were
4089 * allocated by a single call to kalloc(), i.e. the
4090 * vm_map_copy_t was not allocated out of the zone.
4092 kfree(copy
, copy
->cpy_kalloc_size
);
4095 zfree(vm_map_copy_zone
, copy
);
4099 * Routine: vm_map_copy_copy
4102 * Move the information in a map copy object to
4103 * a new map copy object, leaving the old one
4106 * This is used by kernel routines that need
4107 * to look at out-of-line data (in copyin form)
4108 * before deciding whether to return SUCCESS.
4109 * If the routine returns FAILURE, the original
4110 * copy object will be deallocated; therefore,
4111 * these routines must make a copy of the copy
4112 * object and leave the original empty so that
4113 * deallocation will not fail.
4119 vm_map_copy_t new_copy
;
4121 if (copy
== VM_MAP_COPY_NULL
)
4122 return VM_MAP_COPY_NULL
;
4125 * Allocate a new copy object, and copy the information
4126 * from the old one into it.
4129 new_copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
4132 if (copy
->type
== VM_MAP_COPY_ENTRY_LIST
) {
4134 * The links in the entry chain must be
4135 * changed to point to the new copy object.
4137 vm_map_copy_first_entry(copy
)->vme_prev
4138 = vm_map_copy_to_entry(new_copy
);
4139 vm_map_copy_last_entry(copy
)->vme_next
4140 = vm_map_copy_to_entry(new_copy
);
4144 * Change the old copy object into one that contains
4145 * nothing to be deallocated.
4147 copy
->type
= VM_MAP_COPY_OBJECT
;
4148 copy
->cpy_object
= VM_OBJECT_NULL
;
4151 * Return the new object.
4156 static kern_return_t
4157 vm_map_overwrite_submap_recurse(
4159 vm_map_offset_t dst_addr
,
4160 vm_map_size_t dst_size
)
4162 vm_map_offset_t dst_end
;
4163 vm_map_entry_t tmp_entry
;
4164 vm_map_entry_t entry
;
4165 kern_return_t result
;
4166 boolean_t encountered_sub_map
= FALSE
;
4171 * Verify that the destination is all writeable
4172 * initially. We have to trunc the destination
4173 * address and round the copy size or we'll end up
4174 * splitting entries in strange ways.
4177 dst_end
= vm_map_round_page(dst_addr
+ dst_size
);
4178 vm_map_lock(dst_map
);
4181 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4182 vm_map_unlock(dst_map
);
4183 return(KERN_INVALID_ADDRESS
);
4186 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(dst_addr
));
4188 for (entry
= tmp_entry
;;) {
4189 vm_map_entry_t next
;
4191 next
= entry
->vme_next
;
4192 while(entry
->is_sub_map
) {
4193 vm_map_offset_t sub_start
;
4194 vm_map_offset_t sub_end
;
4195 vm_map_offset_t local_end
;
4197 if (entry
->in_transition
) {
4199 * Say that we are waiting, and wait for entry.
4201 entry
->needs_wakeup
= TRUE
;
4202 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4207 encountered_sub_map
= TRUE
;
4208 sub_start
= entry
->offset
;
4210 if(entry
->vme_end
< dst_end
)
4211 sub_end
= entry
->vme_end
;
4214 sub_end
-= entry
->vme_start
;
4215 sub_end
+= entry
->offset
;
4216 local_end
= entry
->vme_end
;
4217 vm_map_unlock(dst_map
);
4219 result
= vm_map_overwrite_submap_recurse(
4220 entry
->object
.sub_map
,
4222 sub_end
- sub_start
);
4224 if(result
!= KERN_SUCCESS
)
4226 if (dst_end
<= entry
->vme_end
)
4227 return KERN_SUCCESS
;
4228 vm_map_lock(dst_map
);
4229 if(!vm_map_lookup_entry(dst_map
, local_end
,
4231 vm_map_unlock(dst_map
);
4232 return(KERN_INVALID_ADDRESS
);
4235 next
= entry
->vme_next
;
4238 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4239 vm_map_unlock(dst_map
);
4240 return(KERN_PROTECTION_FAILURE
);
4244 * If the entry is in transition, we must wait
4245 * for it to exit that state. Anything could happen
4246 * when we unlock the map, so start over.
4248 if (entry
->in_transition
) {
4251 * Say that we are waiting, and wait for entry.
4253 entry
->needs_wakeup
= TRUE
;
4254 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4260 * our range is contained completely within this map entry
4262 if (dst_end
<= entry
->vme_end
) {
4263 vm_map_unlock(dst_map
);
4264 return KERN_SUCCESS
;
4267 * check that range specified is contiguous region
4269 if ((next
== vm_map_to_entry(dst_map
)) ||
4270 (next
->vme_start
!= entry
->vme_end
)) {
4271 vm_map_unlock(dst_map
);
4272 return(KERN_INVALID_ADDRESS
);
4276 * Check for permanent objects in the destination.
4278 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
4279 ((!entry
->object
.vm_object
->internal
) ||
4280 (entry
->object
.vm_object
->true_share
))) {
4281 if(encountered_sub_map
) {
4282 vm_map_unlock(dst_map
);
4283 return(KERN_FAILURE
);
4290 vm_map_unlock(dst_map
);
4291 return(KERN_SUCCESS
);
4295 * Routine: vm_map_copy_overwrite
4298 * Copy the memory described by the map copy
4299 * object (copy; returned by vm_map_copyin) onto
4300 * the specified destination region (dst_map, dst_addr).
4301 * The destination must be writeable.
4303 * Unlike vm_map_copyout, this routine actually
4304 * writes over previously-mapped memory. If the
4305 * previous mapping was to a permanent (user-supplied)
4306 * memory object, it is preserved.
4308 * The attributes (protection and inheritance) of the
4309 * destination region are preserved.
4311 * If successful, consumes the copy object.
4312 * Otherwise, the caller is responsible for it.
4314 * Implementation notes:
4315 * To overwrite aligned temporary virtual memory, it is
4316 * sufficient to remove the previous mapping and insert
4317 * the new copy. This replacement is done either on
4318 * the whole region (if no permanent virtual memory
4319 * objects are embedded in the destination region) or
4320 * in individual map entries.
4322 * To overwrite permanent virtual memory , it is necessary
4323 * to copy each page, as the external memory management
4324 * interface currently does not provide any optimizations.
4326 * Unaligned memory also has to be copied. It is possible
4327 * to use 'vm_trickery' to copy the aligned data. This is
4328 * not done but not hard to implement.
4330 * Once a page of permanent memory has been overwritten,
4331 * it is impossible to interrupt this function; otherwise,
4332 * the call would be neither atomic nor location-independent.
4333 * The kernel-state portion of a user thread must be
4336 * It may be expensive to forward all requests that might
4337 * overwrite permanent memory (vm_write, vm_copy) to
4338 * uninterruptible kernel threads. This routine may be
4339 * called by interruptible threads; however, success is
4340 * not guaranteed -- if the request cannot be performed
4341 * atomically and interruptibly, an error indication is
4345 static kern_return_t
4346 vm_map_copy_overwrite_nested(
4348 vm_map_address_t dst_addr
,
4350 boolean_t interruptible
,
4353 vm_map_offset_t dst_end
;
4354 vm_map_entry_t tmp_entry
;
4355 vm_map_entry_t entry
;
4357 boolean_t aligned
= TRUE
;
4358 boolean_t contains_permanent_objects
= FALSE
;
4359 boolean_t encountered_sub_map
= FALSE
;
4360 vm_map_offset_t base_addr
;
4361 vm_map_size_t copy_size
;
4362 vm_map_size_t total_size
;
4366 * Check for null copy object.
4369 if (copy
== VM_MAP_COPY_NULL
)
4370 return(KERN_SUCCESS
);
4373 * Check for special kernel buffer allocated
4374 * by new_ipc_kmsg_copyin.
4377 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
4378 return(vm_map_copyout_kernel_buffer(
4384 * Only works for entry lists at the moment. Will
4385 * support page lists later.
4388 assert(copy
->type
== VM_MAP_COPY_ENTRY_LIST
);
4390 if (copy
->size
== 0) {
4391 vm_map_copy_discard(copy
);
4392 return(KERN_SUCCESS
);
4396 * Verify that the destination is all writeable
4397 * initially. We have to trunc the destination
4398 * address and round the copy size or we'll end up
4399 * splitting entries in strange ways.
4402 if (!page_aligned(copy
->size
) ||
4403 !page_aligned (copy
->offset
) ||
4404 !page_aligned (dst_addr
))
4407 dst_end
= vm_map_round_page(dst_addr
+ copy
->size
);
4409 dst_end
= dst_addr
+ copy
->size
;
4412 vm_map_lock(dst_map
);
4414 /* LP64todo - remove this check when vm_map_commpage64()
4415 * no longer has to stuff in a map_entry for the commpage
4416 * above the map's max_offset.
4418 if (dst_addr
>= dst_map
->max_offset
) {
4419 vm_map_unlock(dst_map
);
4420 return(KERN_INVALID_ADDRESS
);
4424 if (!vm_map_lookup_entry(dst_map
, dst_addr
, &tmp_entry
)) {
4425 vm_map_unlock(dst_map
);
4426 return(KERN_INVALID_ADDRESS
);
4428 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(dst_addr
));
4429 for (entry
= tmp_entry
;;) {
4430 vm_map_entry_t next
= entry
->vme_next
;
4432 while(entry
->is_sub_map
) {
4433 vm_map_offset_t sub_start
;
4434 vm_map_offset_t sub_end
;
4435 vm_map_offset_t local_end
;
4437 if (entry
->in_transition
) {
4440 * Say that we are waiting, and wait for entry.
4442 entry
->needs_wakeup
= TRUE
;
4443 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4448 local_end
= entry
->vme_end
;
4449 if (!(entry
->needs_copy
)) {
4450 /* if needs_copy we are a COW submap */
4451 /* in such a case we just replace so */
4452 /* there is no need for the follow- */
4454 encountered_sub_map
= TRUE
;
4455 sub_start
= entry
->offset
;
4457 if(entry
->vme_end
< dst_end
)
4458 sub_end
= entry
->vme_end
;
4461 sub_end
-= entry
->vme_start
;
4462 sub_end
+= entry
->offset
;
4463 vm_map_unlock(dst_map
);
4465 kr
= vm_map_overwrite_submap_recurse(
4466 entry
->object
.sub_map
,
4468 sub_end
- sub_start
);
4469 if(kr
!= KERN_SUCCESS
)
4471 vm_map_lock(dst_map
);
4474 if (dst_end
<= entry
->vme_end
)
4475 goto start_overwrite
;
4476 if(!vm_map_lookup_entry(dst_map
, local_end
,
4478 vm_map_unlock(dst_map
);
4479 return(KERN_INVALID_ADDRESS
);
4481 next
= entry
->vme_next
;
4484 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
4485 vm_map_unlock(dst_map
);
4486 return(KERN_PROTECTION_FAILURE
);
4490 * If the entry is in transition, we must wait
4491 * for it to exit that state. Anything could happen
4492 * when we unlock the map, so start over.
4494 if (entry
->in_transition
) {
4497 * Say that we are waiting, and wait for entry.
4499 entry
->needs_wakeup
= TRUE
;
4500 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4506 * our range is contained completely within this map entry
4508 if (dst_end
<= entry
->vme_end
)
4511 * check that range specified is contiguous region
4513 if ((next
== vm_map_to_entry(dst_map
)) ||
4514 (next
->vme_start
!= entry
->vme_end
)) {
4515 vm_map_unlock(dst_map
);
4516 return(KERN_INVALID_ADDRESS
);
4521 * Check for permanent objects in the destination.
4523 if ((entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
4524 ((!entry
->object
.vm_object
->internal
) ||
4525 (entry
->object
.vm_object
->true_share
))) {
4526 contains_permanent_objects
= TRUE
;
4534 * If there are permanent objects in the destination, then
4535 * the copy cannot be interrupted.
4538 if (interruptible
&& contains_permanent_objects
) {
4539 vm_map_unlock(dst_map
);
4540 return(KERN_FAILURE
); /* XXX */
4545 * Make a second pass, overwriting the data
4546 * At the beginning of each loop iteration,
4547 * the next entry to be overwritten is "tmp_entry"
4548 * (initially, the value returned from the lookup above),
4549 * and the starting address expected in that entry
4553 total_size
= copy
->size
;
4554 if(encountered_sub_map
) {
4556 /* re-calculate tmp_entry since we've had the map */
4558 if (!vm_map_lookup_entry( dst_map
, dst_addr
, &tmp_entry
)) {
4559 vm_map_unlock(dst_map
);
4560 return(KERN_INVALID_ADDRESS
);
4563 copy_size
= copy
->size
;
4566 base_addr
= dst_addr
;
4568 /* deconstruct the copy object and do in parts */
4569 /* only in sub_map, interruptable case */
4570 vm_map_entry_t copy_entry
;
4571 vm_map_entry_t previous_prev
= VM_MAP_ENTRY_NULL
;
4572 vm_map_entry_t next_copy
= VM_MAP_ENTRY_NULL
;
4574 int remaining_entries
= 0;
4577 for (entry
= tmp_entry
; copy_size
== 0;) {
4578 vm_map_entry_t next
;
4580 next
= entry
->vme_next
;
4582 /* tmp_entry and base address are moved along */
4583 /* each time we encounter a sub-map. Otherwise */
4584 /* entry can outpase tmp_entry, and the copy_size */
4585 /* may reflect the distance between them */
4586 /* if the current entry is found to be in transition */
4587 /* we will start over at the beginning or the last */
4588 /* encounter of a submap as dictated by base_addr */
4589 /* we will zero copy_size accordingly. */
4590 if (entry
->in_transition
) {
4592 * Say that we are waiting, and wait for entry.
4594 entry
->needs_wakeup
= TRUE
;
4595 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4597 if(!vm_map_lookup_entry(dst_map
, base_addr
,
4599 vm_map_unlock(dst_map
);
4600 return(KERN_INVALID_ADDRESS
);
4606 if(entry
->is_sub_map
) {
4607 vm_map_offset_t sub_start
;
4608 vm_map_offset_t sub_end
;
4609 vm_map_offset_t local_end
;
4611 if (entry
->needs_copy
) {
4612 /* if this is a COW submap */
4613 /* just back the range with a */
4614 /* anonymous entry */
4615 if(entry
->vme_end
< dst_end
)
4616 sub_end
= entry
->vme_end
;
4619 if(entry
->vme_start
< base_addr
)
4620 sub_start
= base_addr
;
4622 sub_start
= entry
->vme_start
;
4624 dst_map
, entry
, sub_end
);
4626 dst_map
, entry
, sub_start
);
4627 entry
->is_sub_map
= FALSE
;
4629 entry
->object
.sub_map
);
4630 entry
->object
.sub_map
= NULL
;
4631 entry
->is_shared
= FALSE
;
4632 entry
->needs_copy
= FALSE
;
4634 entry
->protection
= VM_PROT_ALL
;
4635 entry
->max_protection
= VM_PROT_ALL
;
4636 entry
->wired_count
= 0;
4637 entry
->user_wired_count
= 0;
4638 if(entry
->inheritance
4639 == VM_INHERIT_SHARE
)
4640 entry
->inheritance
= VM_INHERIT_COPY
;
4643 /* first take care of any non-sub_map */
4644 /* entries to send */
4645 if(base_addr
< entry
->vme_start
) {
4648 entry
->vme_start
- base_addr
;
4651 sub_start
= entry
->offset
;
4653 if(entry
->vme_end
< dst_end
)
4654 sub_end
= entry
->vme_end
;
4657 sub_end
-= entry
->vme_start
;
4658 sub_end
+= entry
->offset
;
4659 local_end
= entry
->vme_end
;
4660 vm_map_unlock(dst_map
);
4661 copy_size
= sub_end
- sub_start
;
4663 /* adjust the copy object */
4664 if (total_size
> copy_size
) {
4665 vm_map_size_t local_size
= 0;
4666 vm_map_size_t entry_size
;
4669 new_offset
= copy
->offset
;
4670 copy_entry
= vm_map_copy_first_entry(copy
);
4672 vm_map_copy_to_entry(copy
)){
4673 entry_size
= copy_entry
->vme_end
-
4674 copy_entry
->vme_start
;
4675 if((local_size
< copy_size
) &&
4676 ((local_size
+ entry_size
)
4678 vm_map_copy_clip_end(copy
,
4680 copy_entry
->vme_start
+
4681 (copy_size
- local_size
));
4682 entry_size
= copy_entry
->vme_end
-
4683 copy_entry
->vme_start
;
4684 local_size
+= entry_size
;
4685 new_offset
+= entry_size
;
4687 if(local_size
>= copy_size
) {
4688 next_copy
= copy_entry
->vme_next
;
4689 copy_entry
->vme_next
=
4690 vm_map_copy_to_entry(copy
);
4692 copy
->cpy_hdr
.links
.prev
;
4693 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4694 copy
->size
= copy_size
;
4696 copy
->cpy_hdr
.nentries
;
4697 remaining_entries
-= nentries
;
4698 copy
->cpy_hdr
.nentries
= nentries
;
4701 local_size
+= entry_size
;
4702 new_offset
+= entry_size
;
4705 copy_entry
= copy_entry
->vme_next
;
4709 if((entry
->use_pmap
) && (pmap
== NULL
)) {
4710 kr
= vm_map_copy_overwrite_nested(
4711 entry
->object
.sub_map
,
4715 entry
->object
.sub_map
->pmap
);
4716 } else if (pmap
!= NULL
) {
4717 kr
= vm_map_copy_overwrite_nested(
4718 entry
->object
.sub_map
,
4721 interruptible
, pmap
);
4723 kr
= vm_map_copy_overwrite_nested(
4724 entry
->object
.sub_map
,
4730 if(kr
!= KERN_SUCCESS
) {
4731 if(next_copy
!= NULL
) {
4732 copy
->cpy_hdr
.nentries
+=
4734 copy
->cpy_hdr
.links
.prev
->vme_next
=
4736 copy
->cpy_hdr
.links
.prev
4738 copy
->size
= total_size
;
4742 if (dst_end
<= local_end
) {
4743 return(KERN_SUCCESS
);
4745 /* otherwise copy no longer exists, it was */
4746 /* destroyed after successful copy_overwrite */
4747 copy
= (vm_map_copy_t
)
4748 zalloc(vm_map_copy_zone
);
4749 vm_map_copy_first_entry(copy
) =
4750 vm_map_copy_last_entry(copy
) =
4751 vm_map_copy_to_entry(copy
);
4752 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
4753 copy
->offset
= new_offset
;
4755 total_size
-= copy_size
;
4757 /* put back remainder of copy in container */
4758 if(next_copy
!= NULL
) {
4759 copy
->cpy_hdr
.nentries
= remaining_entries
;
4760 copy
->cpy_hdr
.links
.next
= next_copy
;
4761 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4762 copy
->size
= total_size
;
4763 next_copy
->vme_prev
=
4764 vm_map_copy_to_entry(copy
);
4767 base_addr
= local_end
;
4768 vm_map_lock(dst_map
);
4769 if(!vm_map_lookup_entry(dst_map
,
4770 local_end
, &tmp_entry
)) {
4771 vm_map_unlock(dst_map
);
4772 return(KERN_INVALID_ADDRESS
);
4777 if (dst_end
<= entry
->vme_end
) {
4778 copy_size
= dst_end
- base_addr
;
4782 if ((next
== vm_map_to_entry(dst_map
)) ||
4783 (next
->vme_start
!= entry
->vme_end
)) {
4784 vm_map_unlock(dst_map
);
4785 return(KERN_INVALID_ADDRESS
);
4794 /* adjust the copy object */
4795 if (total_size
> copy_size
) {
4796 vm_map_size_t local_size
= 0;
4797 vm_map_size_t entry_size
;
4799 new_offset
= copy
->offset
;
4800 copy_entry
= vm_map_copy_first_entry(copy
);
4801 while(copy_entry
!= vm_map_copy_to_entry(copy
)) {
4802 entry_size
= copy_entry
->vme_end
-
4803 copy_entry
->vme_start
;
4804 if((local_size
< copy_size
) &&
4805 ((local_size
+ entry_size
)
4807 vm_map_copy_clip_end(copy
, copy_entry
,
4808 copy_entry
->vme_start
+
4809 (copy_size
- local_size
));
4810 entry_size
= copy_entry
->vme_end
-
4811 copy_entry
->vme_start
;
4812 local_size
+= entry_size
;
4813 new_offset
+= entry_size
;
4815 if(local_size
>= copy_size
) {
4816 next_copy
= copy_entry
->vme_next
;
4817 copy_entry
->vme_next
=
4818 vm_map_copy_to_entry(copy
);
4820 copy
->cpy_hdr
.links
.prev
;
4821 copy
->cpy_hdr
.links
.prev
= copy_entry
;
4822 copy
->size
= copy_size
;
4824 copy
->cpy_hdr
.nentries
;
4825 remaining_entries
-= nentries
;
4826 copy
->cpy_hdr
.nentries
= nentries
;
4829 local_size
+= entry_size
;
4830 new_offset
+= entry_size
;
4833 copy_entry
= copy_entry
->vme_next
;
4843 local_pmap
= dst_map
->pmap
;
4845 if ((kr
= vm_map_copy_overwrite_aligned(
4846 dst_map
, tmp_entry
, copy
,
4847 base_addr
, local_pmap
)) != KERN_SUCCESS
) {
4848 if(next_copy
!= NULL
) {
4849 copy
->cpy_hdr
.nentries
+=
4851 copy
->cpy_hdr
.links
.prev
->vme_next
=
4853 copy
->cpy_hdr
.links
.prev
=
4855 copy
->size
+= copy_size
;
4859 vm_map_unlock(dst_map
);
4864 * if the copy and dst address are misaligned but the same
4865 * offset within the page we can copy_not_aligned the
4866 * misaligned parts and copy aligned the rest. If they are
4867 * aligned but len is unaligned we simply need to copy
4868 * the end bit unaligned. We'll need to split the misaligned
4869 * bits of the region in this case !
4871 /* ALWAYS UNLOCKS THE dst_map MAP */
4872 if ((kr
= vm_map_copy_overwrite_unaligned( dst_map
,
4873 tmp_entry
, copy
, base_addr
)) != KERN_SUCCESS
) {
4874 if(next_copy
!= NULL
) {
4875 copy
->cpy_hdr
.nentries
+=
4877 copy
->cpy_hdr
.links
.prev
->vme_next
=
4879 copy
->cpy_hdr
.links
.prev
=
4881 copy
->size
+= copy_size
;
4886 total_size
-= copy_size
;
4889 base_addr
+= copy_size
;
4891 copy
->offset
= new_offset
;
4892 if(next_copy
!= NULL
) {
4893 copy
->cpy_hdr
.nentries
= remaining_entries
;
4894 copy
->cpy_hdr
.links
.next
= next_copy
;
4895 copy
->cpy_hdr
.links
.prev
= previous_prev
;
4896 next_copy
->vme_prev
= vm_map_copy_to_entry(copy
);
4897 copy
->size
= total_size
;
4899 vm_map_lock(dst_map
);
4901 if (!vm_map_lookup_entry(dst_map
,
4902 base_addr
, &tmp_entry
)) {
4903 vm_map_unlock(dst_map
);
4904 return(KERN_INVALID_ADDRESS
);
4906 if (tmp_entry
->in_transition
) {
4907 entry
->needs_wakeup
= TRUE
;
4908 vm_map_entry_wait(dst_map
, THREAD_UNINT
);
4913 vm_map_clip_start(dst_map
, tmp_entry
, vm_map_trunc_page(base_addr
));
4919 * Throw away the vm_map_copy object
4921 vm_map_copy_discard(copy
);
4923 return(KERN_SUCCESS
);
4924 }/* vm_map_copy_overwrite */
4927 vm_map_copy_overwrite(
4929 vm_map_offset_t dst_addr
,
4931 boolean_t interruptible
)
4933 return vm_map_copy_overwrite_nested(
4934 dst_map
, dst_addr
, copy
, interruptible
, (pmap_t
) NULL
);
4939 * Routine: vm_map_copy_overwrite_unaligned [internal use only]
4942 * Physically copy unaligned data
4945 * Unaligned parts of pages have to be physically copied. We use
4946 * a modified form of vm_fault_copy (which understands none-aligned
4947 * page offsets and sizes) to do the copy. We attempt to copy as
4948 * much memory in one go as possibly, however vm_fault_copy copies
4949 * within 1 memory object so we have to find the smaller of "amount left"
4950 * "source object data size" and "target object data size". With
4951 * unaligned data we don't need to split regions, therefore the source
4952 * (copy) object should be one map entry, the target range may be split
4953 * over multiple map entries however. In any event we are pessimistic
4954 * about these assumptions.
4957 * dst_map is locked on entry and is return locked on success,
4958 * unlocked on error.
4961 static kern_return_t
4962 vm_map_copy_overwrite_unaligned(
4964 vm_map_entry_t entry
,
4966 vm_map_offset_t start
)
4968 vm_map_entry_t copy_entry
= vm_map_copy_first_entry(copy
);
4969 vm_map_version_t version
;
4970 vm_object_t dst_object
;
4971 vm_object_offset_t dst_offset
;
4972 vm_object_offset_t src_offset
;
4973 vm_object_offset_t entry_offset
;
4974 vm_map_offset_t entry_end
;
4975 vm_map_size_t src_size
,
4979 kern_return_t kr
= KERN_SUCCESS
;
4981 vm_map_lock_write_to_read(dst_map
);
4983 src_offset
= copy
->offset
- vm_object_trunc_page(copy
->offset
);
4984 amount_left
= copy
->size
;
4986 * unaligned so we never clipped this entry, we need the offset into
4987 * the vm_object not just the data.
4989 while (amount_left
> 0) {
4991 if (entry
== vm_map_to_entry(dst_map
)) {
4992 vm_map_unlock_read(dst_map
);
4993 return KERN_INVALID_ADDRESS
;
4996 /* "start" must be within the current map entry */
4997 assert ((start
>=entry
->vme_start
) && (start
<entry
->vme_end
));
4999 dst_offset
= start
- entry
->vme_start
;
5001 dst_size
= entry
->vme_end
- start
;
5003 src_size
= copy_entry
->vme_end
-
5004 (copy_entry
->vme_start
+ src_offset
);
5006 if (dst_size
< src_size
) {
5008 * we can only copy dst_size bytes before
5009 * we have to get the next destination entry
5011 copy_size
= dst_size
;
5014 * we can only copy src_size bytes before
5015 * we have to get the next source copy entry
5017 copy_size
= src_size
;
5020 if (copy_size
> amount_left
) {
5021 copy_size
= amount_left
;
5024 * Entry needs copy, create a shadow shadow object for
5025 * Copy on write region.
5027 if (entry
->needs_copy
&&
5028 ((entry
->protection
& VM_PROT_WRITE
) != 0))
5030 if (vm_map_lock_read_to_write(dst_map
)) {
5031 vm_map_lock_read(dst_map
);
5034 vm_object_shadow(&entry
->object
.vm_object
,
5036 (vm_map_size_t
)(entry
->vme_end
5037 - entry
->vme_start
));
5038 entry
->needs_copy
= FALSE
;
5039 vm_map_lock_write_to_read(dst_map
);
5041 dst_object
= entry
->object
.vm_object
;
5043 * unlike with the virtual (aligned) copy we're going
5044 * to fault on it therefore we need a target object.
5046 if (dst_object
== VM_OBJECT_NULL
) {
5047 if (vm_map_lock_read_to_write(dst_map
)) {
5048 vm_map_lock_read(dst_map
);
5051 dst_object
= vm_object_allocate((vm_map_size_t
)
5052 entry
->vme_end
- entry
->vme_start
);
5053 entry
->object
.vm_object
= dst_object
;
5055 vm_map_lock_write_to_read(dst_map
);
5058 * Take an object reference and unlock map. The "entry" may
5059 * disappear or change when the map is unlocked.
5061 vm_object_reference(dst_object
);
5062 version
.main_timestamp
= dst_map
->timestamp
;
5063 entry_offset
= entry
->offset
;
5064 entry_end
= entry
->vme_end
;
5065 vm_map_unlock_read(dst_map
);
5067 * Copy as much as possible in one pass
5070 copy_entry
->object
.vm_object
,
5071 copy_entry
->offset
+ src_offset
,
5074 entry_offset
+ dst_offset
,
5080 src_offset
+= copy_size
;
5081 amount_left
-= copy_size
;
5083 * Release the object reference
5085 vm_object_deallocate(dst_object
);
5087 * If a hard error occurred, return it now
5089 if (kr
!= KERN_SUCCESS
)
5092 if ((copy_entry
->vme_start
+ src_offset
) == copy_entry
->vme_end
5093 || amount_left
== 0)
5096 * all done with this copy entry, dispose.
5098 vm_map_copy_entry_unlink(copy
, copy_entry
);
5099 vm_object_deallocate(copy_entry
->object
.vm_object
);
5100 vm_map_copy_entry_dispose(copy
, copy_entry
);
5102 if ((copy_entry
= vm_map_copy_first_entry(copy
))
5103 == vm_map_copy_to_entry(copy
) && amount_left
) {
5105 * not finished copying but run out of source
5107 return KERN_INVALID_ADDRESS
;
5112 if (amount_left
== 0)
5113 return KERN_SUCCESS
;
5115 vm_map_lock_read(dst_map
);
5116 if (version
.main_timestamp
== dst_map
->timestamp
) {
5117 if (start
== entry_end
) {
5119 * destination region is split. Use the version
5120 * information to avoid a lookup in the normal
5123 entry
= entry
->vme_next
;
5125 * should be contiguous. Fail if we encounter
5126 * a hole in the destination.
5128 if (start
!= entry
->vme_start
) {
5129 vm_map_unlock_read(dst_map
);
5130 return KERN_INVALID_ADDRESS
;
5135 * Map version check failed.
5136 * we must lookup the entry because somebody
5137 * might have changed the map behind our backs.
5140 if (!vm_map_lookup_entry(dst_map
, start
, &entry
))
5142 vm_map_unlock_read(dst_map
);
5143 return KERN_INVALID_ADDRESS
;
5148 return KERN_SUCCESS
;
5149 }/* vm_map_copy_overwrite_unaligned */
5152 * Routine: vm_map_copy_overwrite_aligned [internal use only]
5155 * Does all the vm_trickery possible for whole pages.
5159 * If there are no permanent objects in the destination,
5160 * and the source and destination map entry zones match,
5161 * and the destination map entry is not shared,
5162 * then the map entries can be deleted and replaced
5163 * with those from the copy. The following code is the
5164 * basic idea of what to do, but there are lots of annoying
5165 * little details about getting protection and inheritance
5166 * right. Should add protection, inheritance, and sharing checks
5167 * to the above pass and make sure that no wiring is involved.
5170 static kern_return_t
5171 vm_map_copy_overwrite_aligned(
5173 vm_map_entry_t tmp_entry
,
5175 vm_map_offset_t start
,
5176 #if !BAD_OPTIMIZATION
5178 #endif /* !BAD_OPTIMIZATION */
5182 vm_map_entry_t copy_entry
;
5183 vm_map_size_t copy_size
;
5185 vm_map_entry_t entry
;
5187 while ((copy_entry
= vm_map_copy_first_entry(copy
))
5188 != vm_map_copy_to_entry(copy
))
5190 copy_size
= (copy_entry
->vme_end
- copy_entry
->vme_start
);
5193 if (entry
== vm_map_to_entry(dst_map
)) {
5194 vm_map_unlock(dst_map
);
5195 return KERN_INVALID_ADDRESS
;
5197 size
= (entry
->vme_end
- entry
->vme_start
);
5199 * Make sure that no holes popped up in the
5200 * address map, and that the protection is
5201 * still valid, in case the map was unlocked
5205 if ((entry
->vme_start
!= start
) || ((entry
->is_sub_map
)
5206 && !entry
->needs_copy
)) {
5207 vm_map_unlock(dst_map
);
5208 return(KERN_INVALID_ADDRESS
);
5210 assert(entry
!= vm_map_to_entry(dst_map
));
5213 * Check protection again
5216 if ( ! (entry
->protection
& VM_PROT_WRITE
)) {
5217 vm_map_unlock(dst_map
);
5218 return(KERN_PROTECTION_FAILURE
);
5222 * Adjust to source size first
5225 if (copy_size
< size
) {
5226 vm_map_clip_end(dst_map
, entry
, entry
->vme_start
+ copy_size
);
5231 * Adjust to destination size
5234 if (size
< copy_size
) {
5235 vm_map_copy_clip_end(copy
, copy_entry
,
5236 copy_entry
->vme_start
+ size
);
5240 assert((entry
->vme_end
- entry
->vme_start
) == size
);
5241 assert((tmp_entry
->vme_end
- tmp_entry
->vme_start
) == size
);
5242 assert((copy_entry
->vme_end
- copy_entry
->vme_start
) == size
);
5245 * If the destination contains temporary unshared memory,
5246 * we can perform the copy by throwing it away and
5247 * installing the source data.
5250 object
= entry
->object
.vm_object
;
5251 if ((!entry
->is_shared
&&
5252 ((object
== VM_OBJECT_NULL
) ||
5253 (object
->internal
&& !object
->true_share
))) ||
5254 entry
->needs_copy
) {
5255 vm_object_t old_object
= entry
->object
.vm_object
;
5256 vm_object_offset_t old_offset
= entry
->offset
;
5257 vm_object_offset_t offset
;
5260 * Ensure that the source and destination aren't
5263 if (old_object
== copy_entry
->object
.vm_object
&&
5264 old_offset
== copy_entry
->offset
) {
5265 vm_map_copy_entry_unlink(copy
, copy_entry
);
5266 vm_map_copy_entry_dispose(copy
, copy_entry
);
5268 if (old_object
!= VM_OBJECT_NULL
)
5269 vm_object_deallocate(old_object
);
5271 start
= tmp_entry
->vme_end
;
5272 tmp_entry
= tmp_entry
->vme_next
;
5276 if (old_object
!= VM_OBJECT_NULL
) {
5277 if(entry
->is_sub_map
) {
5278 if(entry
->use_pmap
) {
5279 #ifndef NO_NESTED_PMAP
5280 pmap_unnest(dst_map
->pmap
,
5281 (addr64_t
)entry
->vme_start
);
5282 #endif /* NO_NESTED_PMAP */
5283 if(dst_map
->mapped
) {
5284 /* clean up parent */
5286 vm_map_submap_pmap_clean(
5287 dst_map
, entry
->vme_start
,
5289 entry
->object
.sub_map
,
5293 vm_map_submap_pmap_clean(
5294 dst_map
, entry
->vme_start
,
5296 entry
->object
.sub_map
,
5300 entry
->object
.sub_map
);
5302 if(dst_map
->mapped
) {
5303 vm_object_pmap_protect(
5304 entry
->object
.vm_object
,
5312 pmap_remove(dst_map
->pmap
,
5313 (addr64_t
)(entry
->vme_start
),
5314 (addr64_t
)(entry
->vme_end
));
5316 vm_object_deallocate(old_object
);
5320 entry
->is_sub_map
= FALSE
;
5321 entry
->object
= copy_entry
->object
;
5322 object
= entry
->object
.vm_object
;
5323 entry
->needs_copy
= copy_entry
->needs_copy
;
5324 entry
->wired_count
= 0;
5325 entry
->user_wired_count
= 0;
5326 offset
= entry
->offset
= copy_entry
->offset
;
5328 vm_map_copy_entry_unlink(copy
, copy_entry
);
5329 vm_map_copy_entry_dispose(copy
, copy_entry
);
5330 #if BAD_OPTIMIZATION
5332 * if we turn this optimization back on
5333 * we need to revisit our use of pmap mappings
5334 * large copies will cause us to run out and panic
5335 * this optimization only saved on average 2 us per page if ALL
5336 * the pages in the source were currently mapped
5337 * and ALL the pages in the dest were touched, if there were fewer
5338 * than 2/3 of the pages touched, this optimization actually cost more cycles
5342 * Try to aggressively enter physical mappings
5343 * (but avoid uninstantiated objects)
5345 if (object
!= VM_OBJECT_NULL
) {
5346 vm_map_offset_t va
= entry
->vme_start
;
5348 while (va
< entry
->vme_end
) {
5349 register vm_page_t m
;
5353 * Look for the page in the top object
5355 prot
= entry
->protection
;
5356 vm_object_lock(object
);
5357 vm_object_paging_begin(object
);
5361 * If the page is encrypted, skip it:
5362 * we can't let the user see the encrypted
5363 * contents. The page will get decrypted
5364 * on demand when the user generates a
5365 * soft-fault when trying to access it.
5367 if ((m
= vm_page_lookup(object
,offset
)) !=
5368 VM_PAGE_NULL
&& !m
->busy
&&
5369 !m
->fictitious
&& !m
->encrypted
&&
5370 (!m
->unusual
|| (!m
->error
&&
5371 !m
->restart
&& !m
->absent
&&
5372 (prot
& m
->page_lock
) == 0))) {
5375 vm_object_unlock(object
);
5378 * Honor COW obligations
5380 if (entry
->needs_copy
)
5381 prot
&= ~VM_PROT_WRITE
;
5382 #ifdef STACK_ONLY_NX
5383 if (entry
->alias
!= VM_MEMORY_STACK
&& prot
)
5384 prot
|= VM_PROT_EXECUTE
;
5386 /* It is our policy to require */
5387 /* explicit sync from anyone */
5388 /* writing code and then */
5389 /* a pc to execute it. */
5392 PMAP_ENTER(pmap
, va
, m
, prot
,
5394 (m
->object
->wimg_bits
))
5398 vm_object_lock(object
);
5399 vm_page_lock_queues();
5400 if (!m
->active
&& !m
->inactive
)
5401 vm_page_activate(m
);
5402 vm_page_unlock_queues();
5403 PAGE_WAKEUP_DONE(m
);
5405 vm_object_paging_end(object
);
5406 vm_object_unlock(object
);
5408 offset
+= PAGE_SIZE_64
;
5410 } /* end while (va < entry->vme_end) */
5411 } /* end if (object) */
5414 * Set up for the next iteration. The map
5415 * has not been unlocked, so the next
5416 * address should be at the end of this
5417 * entry, and the next map entry should be
5418 * the one following it.
5421 start
= tmp_entry
->vme_end
;
5422 tmp_entry
= tmp_entry
->vme_next
;
5424 vm_map_version_t version
;
5425 vm_object_t dst_object
= entry
->object
.vm_object
;
5426 vm_object_offset_t dst_offset
= entry
->offset
;
5430 * Take an object reference, and record
5431 * the map version information so that the
5432 * map can be safely unlocked.
5435 vm_object_reference(dst_object
);
5437 /* account for unlock bumping up timestamp */
5438 version
.main_timestamp
= dst_map
->timestamp
+ 1;
5440 vm_map_unlock(dst_map
);
5443 * Copy as much as possible in one pass
5448 copy_entry
->object
.vm_object
,
5458 * Release the object reference
5461 vm_object_deallocate(dst_object
);
5464 * If a hard error occurred, return it now
5467 if (r
!= KERN_SUCCESS
)
5470 if (copy_size
!= 0) {
5472 * Dispose of the copied region
5475 vm_map_copy_clip_end(copy
, copy_entry
,
5476 copy_entry
->vme_start
+ copy_size
);
5477 vm_map_copy_entry_unlink(copy
, copy_entry
);
5478 vm_object_deallocate(copy_entry
->object
.vm_object
);
5479 vm_map_copy_entry_dispose(copy
, copy_entry
);
5483 * Pick up in the destination map where we left off.
5485 * Use the version information to avoid a lookup
5486 * in the normal case.
5490 vm_map_lock(dst_map
);
5491 if (version
.main_timestamp
== dst_map
->timestamp
) {
5492 /* We can safely use saved tmp_entry value */
5494 vm_map_clip_end(dst_map
, tmp_entry
, start
);
5495 tmp_entry
= tmp_entry
->vme_next
;
5497 /* Must do lookup of tmp_entry */
5499 if (!vm_map_lookup_entry(dst_map
, start
, &tmp_entry
)) {
5500 vm_map_unlock(dst_map
);
5501 return(KERN_INVALID_ADDRESS
);
5503 vm_map_clip_start(dst_map
, tmp_entry
, start
);
5508 return(KERN_SUCCESS
);
5509 }/* vm_map_copy_overwrite_aligned */
5512 * Routine: vm_map_copyin_kernel_buffer [internal use only]
5515 * Copy in data to a kernel buffer from space in the
5516 * source map. The original space may be optionally
5519 * If successful, returns a new copy object.
5521 static kern_return_t
5522 vm_map_copyin_kernel_buffer(
5524 vm_map_offset_t src_addr
,
5526 boolean_t src_destroy
,
5527 vm_map_copy_t
*copy_result
)
5531 vm_map_size_t kalloc_size
= sizeof(struct vm_map_copy
) + len
;
5533 copy
= (vm_map_copy_t
) kalloc(kalloc_size
);
5534 if (copy
== VM_MAP_COPY_NULL
) {
5535 return KERN_RESOURCE_SHORTAGE
;
5537 copy
->type
= VM_MAP_COPY_KERNEL_BUFFER
;
5540 copy
->cpy_kdata
= (void *) (copy
+ 1);
5541 copy
->cpy_kalloc_size
= kalloc_size
;
5543 kr
= copyinmap(src_map
, src_addr
, copy
->cpy_kdata
, len
);
5544 if (kr
!= KERN_SUCCESS
) {
5545 kfree(copy
, kalloc_size
);
5549 (void) vm_map_remove(src_map
, vm_map_trunc_page(src_addr
),
5550 vm_map_round_page(src_addr
+ len
),
5551 VM_MAP_REMOVE_INTERRUPTIBLE
|
5552 VM_MAP_REMOVE_WAIT_FOR_KWIRE
|
5553 (src_map
== kernel_map
) ?
5554 VM_MAP_REMOVE_KUNWIRE
: 0);
5556 *copy_result
= copy
;
5557 return KERN_SUCCESS
;
5561 * Routine: vm_map_copyout_kernel_buffer [internal use only]
5564 * Copy out data from a kernel buffer into space in the
5565 * destination map. The space may be otpionally dynamically
5568 * If successful, consumes the copy object.
5569 * Otherwise, the caller is responsible for it.
5571 static int vm_map_copyout_kernel_buffer_failures
= 0;
5572 static kern_return_t
5573 vm_map_copyout_kernel_buffer(
5575 vm_map_address_t
*addr
, /* IN/OUT */
5577 boolean_t overwrite
)
5579 kern_return_t kr
= KERN_SUCCESS
;
5580 thread_t thread
= current_thread();
5585 * Allocate space in the target map for the data
5588 kr
= vm_map_enter(map
,
5590 vm_map_round_page(copy
->size
),
5591 (vm_map_offset_t
) 0,
5594 (vm_object_offset_t
) 0,
5598 VM_INHERIT_DEFAULT
);
5599 if (kr
!= KERN_SUCCESS
)
5604 * Copyout the data from the kernel buffer to the target map.
5606 if (thread
->map
== map
) {
5609 * If the target map is the current map, just do
5612 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5613 kr
= KERN_INVALID_ADDRESS
;
5620 * If the target map is another map, assume the
5621 * target's address space identity for the duration
5624 vm_map_reference(map
);
5625 oldmap
= vm_map_switch(map
);
5627 if (copyout(copy
->cpy_kdata
, *addr
, copy
->size
)) {
5628 vm_map_copyout_kernel_buffer_failures
++;
5629 kr
= KERN_INVALID_ADDRESS
;
5632 (void) vm_map_switch(oldmap
);
5633 vm_map_deallocate(map
);
5636 if (kr
!= KERN_SUCCESS
) {
5637 /* the copy failed, clean up */
5640 * Deallocate the space we allocated in the target map.
5642 (void) vm_map_remove(map
,
5643 vm_map_trunc_page(*addr
),
5644 vm_map_round_page(*addr
+
5645 vm_map_round_page(copy
->size
)),
5650 /* copy was successful, dicard the copy structure */
5651 kfree(copy
, copy
->cpy_kalloc_size
);
5658 * Macro: vm_map_copy_insert
5661 * Link a copy chain ("copy") into a map at the
5662 * specified location (after "where").
5664 * The copy chain is destroyed.
5666 * The arguments are evaluated multiple times.
5668 #define vm_map_copy_insert(map, where, copy) \
5670 vm_map_t VMCI_map; \
5671 vm_map_entry_t VMCI_where; \
5672 vm_map_copy_t VMCI_copy; \
5674 VMCI_where = (where); \
5675 VMCI_copy = (copy); \
5676 ((VMCI_where->vme_next)->vme_prev = vm_map_copy_last_entry(VMCI_copy))\
5677 ->vme_next = (VMCI_where->vme_next); \
5678 ((VMCI_where)->vme_next = vm_map_copy_first_entry(VMCI_copy)) \
5679 ->vme_prev = VMCI_where; \
5680 VMCI_map->hdr.nentries += VMCI_copy->cpy_hdr.nentries; \
5681 UPDATE_FIRST_FREE(VMCI_map, VMCI_map->first_free); \
5682 zfree(vm_map_copy_zone, VMCI_copy); \
5686 * Routine: vm_map_copyout
5689 * Copy out a copy chain ("copy") into newly-allocated
5690 * space in the destination map.
5692 * If successful, consumes the copy object.
5693 * Otherwise, the caller is responsible for it.
5698 vm_map_address_t
*dst_addr
, /* OUT */
5702 vm_map_size_t adjustment
;
5703 vm_map_offset_t start
;
5704 vm_object_offset_t vm_copy_start
;
5705 vm_map_entry_t last
;
5707 vm_map_entry_t entry
;
5710 * Check for null copy object.
5713 if (copy
== VM_MAP_COPY_NULL
) {
5715 return(KERN_SUCCESS
);
5719 * Check for special copy object, created
5720 * by vm_map_copyin_object.
5723 if (copy
->type
== VM_MAP_COPY_OBJECT
) {
5724 vm_object_t object
= copy
->cpy_object
;
5726 vm_object_offset_t offset
;
5728 offset
= vm_object_trunc_page(copy
->offset
);
5729 size
= vm_map_round_page(copy
->size
+
5730 (vm_map_size_t
)(copy
->offset
- offset
));
5732 kr
= vm_map_enter(dst_map
, dst_addr
, size
,
5733 (vm_map_offset_t
) 0, VM_FLAGS_ANYWHERE
,
5734 object
, offset
, FALSE
,
5735 VM_PROT_DEFAULT
, VM_PROT_ALL
,
5736 VM_INHERIT_DEFAULT
);
5737 if (kr
!= KERN_SUCCESS
)
5739 /* Account for non-pagealigned copy object */
5740 *dst_addr
+= (vm_map_offset_t
)(copy
->offset
- offset
);
5741 zfree(vm_map_copy_zone
, copy
);
5742 return(KERN_SUCCESS
);
5746 * Check for special kernel buffer allocated
5747 * by new_ipc_kmsg_copyin.
5750 if (copy
->type
== VM_MAP_COPY_KERNEL_BUFFER
) {
5751 return(vm_map_copyout_kernel_buffer(dst_map
, dst_addr
,
5756 * Find space for the data
5759 vm_copy_start
= vm_object_trunc_page(copy
->offset
);
5760 size
= vm_map_round_page((vm_map_size_t
)copy
->offset
+ copy
->size
)
5765 vm_map_lock(dst_map
);
5766 assert(first_free_is_valid(dst_map
));
5767 start
= ((last
= dst_map
->first_free
) == vm_map_to_entry(dst_map
)) ?
5768 vm_map_min(dst_map
) : last
->vme_end
;
5771 vm_map_entry_t next
= last
->vme_next
;
5772 vm_map_offset_t end
= start
+ size
;
5774 if ((end
> dst_map
->max_offset
) || (end
< start
)) {
5775 if (dst_map
->wait_for_space
) {
5776 if (size
<= (dst_map
->max_offset
- dst_map
->min_offset
)) {
5777 assert_wait((event_t
) dst_map
,
5778 THREAD_INTERRUPTIBLE
);
5779 vm_map_unlock(dst_map
);
5780 thread_block(THREAD_CONTINUE_NULL
);
5784 vm_map_unlock(dst_map
);
5785 return(KERN_NO_SPACE
);
5788 if ((next
== vm_map_to_entry(dst_map
)) ||
5789 (next
->vme_start
>= end
))
5793 start
= last
->vme_end
;
5797 * Since we're going to just drop the map
5798 * entries from the copy into the destination
5799 * map, they must come from the same pool.
5802 if (copy
->cpy_hdr
.entries_pageable
!= dst_map
->hdr
.entries_pageable
) {
5804 * Mismatches occur when dealing with the default
5808 vm_map_entry_t next
, new;
5811 * Find the zone that the copies were allocated from
5813 old_zone
= (copy
->cpy_hdr
.entries_pageable
)
5815 : vm_map_kentry_zone
;
5816 entry
= vm_map_copy_first_entry(copy
);
5819 * Reinitialize the copy so that vm_map_copy_entry_link
5822 copy
->cpy_hdr
.nentries
= 0;
5823 copy
->cpy_hdr
.entries_pageable
= dst_map
->hdr
.entries_pageable
;
5824 vm_map_copy_first_entry(copy
) =
5825 vm_map_copy_last_entry(copy
) =
5826 vm_map_copy_to_entry(copy
);
5831 while (entry
!= vm_map_copy_to_entry(copy
)) {
5832 new = vm_map_copy_entry_create(copy
);
5833 vm_map_entry_copy_full(new, entry
);
5834 new->use_pmap
= FALSE
; /* clr address space specifics */
5835 vm_map_copy_entry_link(copy
,
5836 vm_map_copy_last_entry(copy
),
5838 next
= entry
->vme_next
;
5839 zfree(old_zone
, entry
);
5845 * Adjust the addresses in the copy chain, and
5846 * reset the region attributes.
5849 adjustment
= start
- vm_copy_start
;
5850 for (entry
= vm_map_copy_first_entry(copy
);
5851 entry
!= vm_map_copy_to_entry(copy
);
5852 entry
= entry
->vme_next
) {
5853 entry
->vme_start
+= adjustment
;
5854 entry
->vme_end
+= adjustment
;
5856 entry
->inheritance
= VM_INHERIT_DEFAULT
;
5857 entry
->protection
= VM_PROT_DEFAULT
;
5858 entry
->max_protection
= VM_PROT_ALL
;
5859 entry
->behavior
= VM_BEHAVIOR_DEFAULT
;
5862 * If the entry is now wired,
5863 * map the pages into the destination map.
5865 if (entry
->wired_count
!= 0) {
5866 register vm_map_offset_t va
;
5867 vm_object_offset_t offset
;
5868 register vm_object_t object
;
5871 object
= entry
->object
.vm_object
;
5872 offset
= entry
->offset
;
5873 va
= entry
->vme_start
;
5875 pmap_pageable(dst_map
->pmap
,
5880 while (va
< entry
->vme_end
) {
5881 register vm_page_t m
;
5884 * Look up the page in the object.
5885 * Assert that the page will be found in the
5888 * the object was newly created by
5889 * vm_object_copy_slowly, and has
5890 * copies of all of the pages from
5893 * the object was moved from the old
5894 * map entry; because the old map
5895 * entry was wired, all of the pages
5896 * were in the top-level object.
5897 * (XXX not true if we wire pages for
5900 vm_object_lock(object
);
5901 vm_object_paging_begin(object
);
5903 m
= vm_page_lookup(object
, offset
);
5904 if (m
== VM_PAGE_NULL
|| m
->wire_count
== 0 ||
5906 panic("vm_map_copyout: wiring 0x%x", m
);
5910 * The page is assumed to be wired here, so it
5911 * shouldn't be encrypted. Otherwise, we
5912 * couldn't enter it in the page table, since
5913 * we don't want the user to see the encrypted
5916 ASSERT_PAGE_DECRYPTED(m
);
5919 vm_object_unlock(object
);
5920 prot
= entry
->protection
;
5921 #ifdef STACK_ONLY_NX
5922 if (entry
->alias
!= VM_MEMORY_STACK
&& prot
)
5923 prot
|= VM_PROT_EXECUTE
;
5925 PMAP_ENTER(dst_map
->pmap
, va
, m
, prot
,
5927 (m
->object
->wimg_bits
))
5931 vm_object_lock(object
);
5932 PAGE_WAKEUP_DONE(m
);
5933 /* the page is wired, so we don't have to activate */
5934 vm_object_paging_end(object
);
5935 vm_object_unlock(object
);
5937 offset
+= PAGE_SIZE_64
;
5941 else if (size
<= vm_map_aggressive_enter_max
) {
5943 register vm_map_offset_t va
;
5944 vm_object_offset_t offset
;
5945 register vm_object_t object
;
5948 object
= entry
->object
.vm_object
;
5949 if (object
!= VM_OBJECT_NULL
) {
5951 offset
= entry
->offset
;
5952 va
= entry
->vme_start
;
5953 while (va
< entry
->vme_end
) {
5954 register vm_page_t m
;
5957 * Look up the page in the object.
5958 * Assert that the page will be found
5959 * in the top object if at all...
5961 vm_object_lock(object
);
5962 vm_object_paging_begin(object
);
5966 * If the page is encrypted, skip it:
5967 * we can't let the user see the
5968 * encrypted contents. The page will
5969 * get decrypted on demand when the
5970 * user generates a soft-fault when
5971 * trying to access it.
5973 if (((m
= vm_page_lookup(object
,
5976 !m
->busy
&& !m
->fictitious
&&
5978 !m
->absent
&& !m
->error
) {
5980 vm_object_unlock(object
);
5982 /* honor cow obligations */
5983 prot
= entry
->protection
;
5984 if (entry
->needs_copy
)
5985 prot
&= ~VM_PROT_WRITE
;
5986 #ifdef STACK_ONLY_NX
5987 if (entry
->alias
!= VM_MEMORY_STACK
&& prot
)
5988 prot
|= VM_PROT_EXECUTE
;
5990 PMAP_ENTER(dst_map
->pmap
, va
,
5993 (m
->object
->wimg_bits
))
5997 vm_object_lock(object
);
5998 vm_page_lock_queues();
5999 if (!m
->active
&& !m
->inactive
)
6000 vm_page_activate(m
);
6001 vm_page_unlock_queues();
6002 PAGE_WAKEUP_DONE(m
);
6004 vm_object_paging_end(object
);
6005 vm_object_unlock(object
);
6007 offset
+= PAGE_SIZE_64
;
6015 * Correct the page alignment for the result
6018 *dst_addr
= start
+ (copy
->offset
- vm_copy_start
);
6021 * Update the hints and the map size
6024 SAVE_HINT_MAP_WRITE(dst_map
, vm_map_copy_last_entry(copy
));
6026 dst_map
->size
+= size
;
6032 vm_map_copy_insert(dst_map
, last
, copy
);
6034 vm_map_unlock(dst_map
);
6037 * XXX If wiring_required, call vm_map_pageable
6040 return(KERN_SUCCESS
);
6044 * Routine: vm_map_copyin
6047 * Copy the specified region (src_addr, len) from the
6048 * source address space (src_map), possibly removing
6049 * the region from the source address space (src_destroy).
6052 * A vm_map_copy_t object (copy_result), suitable for
6053 * insertion into another address space (using vm_map_copyout),
6054 * copying over another address space region (using
6055 * vm_map_copy_overwrite). If the copy is unused, it
6056 * should be destroyed (using vm_map_copy_discard).
6058 * In/out conditions:
6059 * The source map should not be locked on entry.
6062 typedef struct submap_map
{
6063 vm_map_t parent_map
;
6064 vm_map_offset_t base_start
;
6065 vm_map_offset_t base_end
;
6066 struct submap_map
*next
;
6070 vm_map_copyin_common(
6072 vm_map_address_t src_addr
,
6074 boolean_t src_destroy
,
6075 __unused boolean_t src_volatile
,
6076 vm_map_copy_t
*copy_result
, /* OUT */
6077 boolean_t use_maxprot
)
6079 vm_map_entry_t tmp_entry
; /* Result of last map lookup --
6080 * in multi-level lookup, this
6081 * entry contains the actual
6085 vm_map_entry_t new_entry
= VM_MAP_ENTRY_NULL
; /* Map entry for copy */
6087 vm_map_offset_t src_start
; /* Start of current entry --
6088 * where copy is taking place now
6090 vm_map_offset_t src_end
; /* End of entire region to be
6092 vm_map_t base_map
= src_map
;
6093 boolean_t map_share
=FALSE
;
6094 submap_map_t
*parent_maps
= NULL
;
6097 vm_map_copy_t copy
; /* Resulting copy */
6098 vm_map_address_t copy_addr
;
6101 * Check for copies of zero bytes.
6105 *copy_result
= VM_MAP_COPY_NULL
;
6106 return(KERN_SUCCESS
);
6110 * Check that the end address doesn't overflow
6112 src_end
= src_addr
+ len
;
6113 if (src_end
< src_addr
)
6114 return KERN_INVALID_ADDRESS
;
6117 * If the copy is sufficiently small, use a kernel buffer instead
6118 * of making a virtual copy. The theory being that the cost of
6119 * setting up VM (and taking C-O-W faults) dominates the copy costs
6120 * for small regions.
6122 if ((len
< msg_ool_size_small
) && !use_maxprot
)
6123 return vm_map_copyin_kernel_buffer(src_map
, src_addr
, len
,
6124 src_destroy
, copy_result
);
6127 * Compute (page aligned) start and end of region
6129 src_start
= vm_map_trunc_page(src_addr
);
6130 src_end
= vm_map_round_page(src_end
);
6132 XPR(XPR_VM_MAP
, "vm_map_copyin_common map 0x%x addr 0x%x len 0x%x dest %d\n", (natural_t
)src_map
, src_addr
, len
, src_destroy
, 0);
6135 * Allocate a header element for the list.
6137 * Use the start and end in the header to
6138 * remember the endpoints prior to rounding.
6141 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6142 vm_map_copy_first_entry(copy
) =
6143 vm_map_copy_last_entry(copy
) = vm_map_copy_to_entry(copy
);
6144 copy
->type
= VM_MAP_COPY_ENTRY_LIST
;
6145 copy
->cpy_hdr
.nentries
= 0;
6146 copy
->cpy_hdr
.entries_pageable
= TRUE
;
6148 copy
->offset
= src_addr
;
6151 new_entry
= vm_map_copy_entry_create(copy
);
6155 vm_map_unlock(src_map); \
6156 if(src_map != base_map) \
6157 vm_map_deallocate(src_map); \
6158 if (new_entry != VM_MAP_ENTRY_NULL) \
6159 vm_map_copy_entry_dispose(copy,new_entry); \
6160 vm_map_copy_discard(copy); \
6162 submap_map_t *_ptr; \
6164 for(_ptr = parent_maps; _ptr != NULL; _ptr = parent_maps) { \
6165 parent_maps=parent_maps->next; \
6166 if (_ptr->parent_map != base_map) \
6167 vm_map_deallocate(_ptr->parent_map); \
6168 kfree(_ptr, sizeof(submap_map_t)); \
6175 * Find the beginning of the region.
6178 vm_map_lock(src_map
);
6180 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
))
6181 RETURN(KERN_INVALID_ADDRESS
);
6182 if(!tmp_entry
->is_sub_map
) {
6183 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6185 /* set for later submap fix-up */
6186 copy_addr
= src_start
;
6189 * Go through entries until we get to the end.
6194 vm_map_entry_t src_entry
= tmp_entry
; /* Top-level entry */
6195 vm_map_size_t src_size
; /* Size of source
6196 * map entry (in both
6201 vm_object_t src_object
; /* Object to copy */
6202 vm_object_offset_t src_offset
;
6204 boolean_t src_needs_copy
; /* Should source map
6206 * for copy-on-write?
6209 boolean_t new_entry_needs_copy
; /* Will new entry be COW? */
6211 boolean_t was_wired
; /* Was source wired? */
6212 vm_map_version_t version
; /* Version before locks
6213 * dropped to make copy
6215 kern_return_t result
; /* Return value from
6216 * copy_strategically.
6218 while(tmp_entry
->is_sub_map
) {
6219 vm_map_size_t submap_len
;
6222 ptr
= (submap_map_t
*)kalloc(sizeof(submap_map_t
));
6223 ptr
->next
= parent_maps
;
6225 ptr
->parent_map
= src_map
;
6226 ptr
->base_start
= src_start
;
6227 ptr
->base_end
= src_end
;
6228 submap_len
= tmp_entry
->vme_end
- src_start
;
6229 if(submap_len
> (src_end
-src_start
))
6230 submap_len
= src_end
-src_start
;
6231 ptr
->base_start
+= submap_len
;
6233 src_start
-= tmp_entry
->vme_start
;
6234 src_start
+= tmp_entry
->offset
;
6235 src_end
= src_start
+ submap_len
;
6236 src_map
= tmp_entry
->object
.sub_map
;
6237 vm_map_lock(src_map
);
6238 /* keep an outstanding reference for all maps in */
6239 /* the parents tree except the base map */
6240 vm_map_reference(src_map
);
6241 vm_map_unlock(ptr
->parent_map
);
6242 if (!vm_map_lookup_entry(
6243 src_map
, src_start
, &tmp_entry
))
6244 RETURN(KERN_INVALID_ADDRESS
);
6246 if(!tmp_entry
->is_sub_map
)
6247 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6248 src_entry
= tmp_entry
;
6250 if ((tmp_entry
->object
.vm_object
!= VM_OBJECT_NULL
) &&
6251 (tmp_entry
->object
.vm_object
->phys_contiguous
)) {
6252 /* This is not, supported for now.In future */
6253 /* we will need to detect the phys_contig */
6254 /* condition and then upgrade copy_slowly */
6255 /* to do physical copy from the device mem */
6256 /* based object. We can piggy-back off of */
6257 /* the was wired boolean to set-up the */
6258 /* proper handling */
6259 RETURN(KERN_PROTECTION_FAILURE
);
6262 * Create a new address map entry to hold the result.
6263 * Fill in the fields from the appropriate source entries.
6264 * We must unlock the source map to do this if we need
6265 * to allocate a map entry.
6267 if (new_entry
== VM_MAP_ENTRY_NULL
) {
6268 version
.main_timestamp
= src_map
->timestamp
;
6269 vm_map_unlock(src_map
);
6271 new_entry
= vm_map_copy_entry_create(copy
);
6273 vm_map_lock(src_map
);
6274 if ((version
.main_timestamp
+ 1) != src_map
->timestamp
) {
6275 if (!vm_map_lookup_entry(src_map
, src_start
,
6277 RETURN(KERN_INVALID_ADDRESS
);
6279 vm_map_clip_start(src_map
, tmp_entry
, src_start
);
6280 continue; /* restart w/ new tmp_entry */
6285 * Verify that the region can be read.
6287 if (((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
&&
6289 (src_entry
->max_protection
& VM_PROT_READ
) == 0)
6290 RETURN(KERN_PROTECTION_FAILURE
);
6293 * Clip against the endpoints of the entire region.
6296 vm_map_clip_end(src_map
, src_entry
, src_end
);
6298 src_size
= src_entry
->vme_end
- src_start
;
6299 src_object
= src_entry
->object
.vm_object
;
6300 src_offset
= src_entry
->offset
;
6301 was_wired
= (src_entry
->wired_count
!= 0);
6303 vm_map_entry_copy(new_entry
, src_entry
);
6304 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
6307 * Attempt non-blocking copy-on-write optimizations.
6311 (src_object
== VM_OBJECT_NULL
||
6312 (src_object
->internal
&& !src_object
->true_share
6315 * If we are destroying the source, and the object
6316 * is internal, we can move the object reference
6317 * from the source to the copy. The copy is
6318 * copy-on-write only if the source is.
6319 * We make another reference to the object, because
6320 * destroying the source entry will deallocate it.
6322 vm_object_reference(src_object
);
6325 * Copy is always unwired. vm_map_copy_entry
6326 * set its wired count to zero.
6329 goto CopySuccessful
;
6334 XPR(XPR_VM_MAP
, "vm_map_copyin_common src_obj 0x%x ent 0x%x obj 0x%x was_wired %d\n",
6335 src_object
, new_entry
, new_entry
->object
.vm_object
,
6337 if ((src_object
== VM_OBJECT_NULL
||
6338 (!was_wired
&& !map_share
&& !tmp_entry
->is_shared
)) &&
6339 vm_object_copy_quickly(
6340 &new_entry
->object
.vm_object
,
6344 &new_entry_needs_copy
)) {
6346 new_entry
->needs_copy
= new_entry_needs_copy
;
6349 * Handle copy-on-write obligations
6352 if (src_needs_copy
&& !tmp_entry
->needs_copy
) {
6355 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
6356 #ifdef STACK_ONLY_NX
6357 if (src_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
6358 prot
|= VM_PROT_EXECUTE
;
6360 vm_object_pmap_protect(
6364 (src_entry
->is_shared
?
6367 src_entry
->vme_start
,
6370 tmp_entry
->needs_copy
= TRUE
;
6374 * The map has never been unlocked, so it's safe
6375 * to move to the next entry rather than doing
6379 goto CopySuccessful
;
6383 * Take an object reference, so that we may
6384 * release the map lock(s).
6387 assert(src_object
!= VM_OBJECT_NULL
);
6388 vm_object_reference(src_object
);
6391 * Record the timestamp for later verification.
6395 version
.main_timestamp
= src_map
->timestamp
;
6396 vm_map_unlock(src_map
); /* Increments timestamp once! */
6404 vm_object_lock(src_object
);
6405 result
= vm_object_copy_slowly(
6410 &new_entry
->object
.vm_object
);
6411 new_entry
->offset
= 0;
6412 new_entry
->needs_copy
= FALSE
;
6415 else if (src_object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
&&
6416 (tmp_entry
->is_shared
|| map_share
)) {
6417 vm_object_t new_object
;
6419 vm_object_lock(src_object
);
6420 new_object
= vm_object_copy_delayed(
6424 if (new_object
== VM_OBJECT_NULL
)
6427 new_entry
->object
.vm_object
= new_object
;
6428 new_entry
->needs_copy
= TRUE
;
6429 result
= KERN_SUCCESS
;
6432 result
= vm_object_copy_strategically(src_object
,
6435 &new_entry
->object
.vm_object
,
6437 &new_entry_needs_copy
);
6439 new_entry
->needs_copy
= new_entry_needs_copy
;
6442 if (result
!= KERN_SUCCESS
&&
6443 result
!= KERN_MEMORY_RESTART_COPY
) {
6444 vm_map_lock(src_map
);
6449 * Throw away the extra reference
6452 vm_object_deallocate(src_object
);
6455 * Verify that the map has not substantially
6456 * changed while the copy was being made.
6459 vm_map_lock(src_map
);
6461 if ((version
.main_timestamp
+ 1) == src_map
->timestamp
)
6462 goto VerificationSuccessful
;
6465 * Simple version comparison failed.
6467 * Retry the lookup and verify that the
6468 * same object/offset are still present.
6470 * [Note: a memory manager that colludes with
6471 * the calling task can detect that we have
6472 * cheated. While the map was unlocked, the
6473 * mapping could have been changed and restored.]
6476 if (!vm_map_lookup_entry(src_map
, src_start
, &tmp_entry
)) {
6477 RETURN(KERN_INVALID_ADDRESS
);
6480 src_entry
= tmp_entry
;
6481 vm_map_clip_start(src_map
, src_entry
, src_start
);
6483 if ((((src_entry
->protection
& VM_PROT_READ
) == VM_PROT_NONE
) &&
6485 ((src_entry
->max_protection
& VM_PROT_READ
) == 0))
6486 goto VerificationFailed
;
6488 if (src_entry
->vme_end
< new_entry
->vme_end
)
6489 src_size
= (new_entry
->vme_end
= src_entry
->vme_end
) - src_start
;
6491 if ((src_entry
->object
.vm_object
!= src_object
) ||
6492 (src_entry
->offset
!= src_offset
) ) {
6495 * Verification failed.
6497 * Start over with this top-level entry.
6500 VerificationFailed
: ;
6502 vm_object_deallocate(new_entry
->object
.vm_object
);
6503 tmp_entry
= src_entry
;
6508 * Verification succeeded.
6511 VerificationSuccessful
: ;
6513 if (result
== KERN_MEMORY_RESTART_COPY
)
6523 * Link in the new copy entry.
6526 vm_map_copy_entry_link(copy
, vm_map_copy_last_entry(copy
),
6530 * Determine whether the entire region
6533 src_start
= new_entry
->vme_end
;
6534 new_entry
= VM_MAP_ENTRY_NULL
;
6535 while ((src_start
>= src_end
) && (src_end
!= 0)) {
6536 if (src_map
!= base_map
) {
6540 assert(ptr
!= NULL
);
6541 parent_maps
= parent_maps
->next
;
6542 vm_map_unlock(src_map
);
6543 vm_map_deallocate(src_map
);
6544 vm_map_lock(ptr
->parent_map
);
6545 src_map
= ptr
->parent_map
;
6546 src_start
= ptr
->base_start
;
6547 src_end
= ptr
->base_end
;
6548 if ((src_end
> src_start
) &&
6549 !vm_map_lookup_entry(
6550 src_map
, src_start
, &tmp_entry
))
6551 RETURN(KERN_INVALID_ADDRESS
);
6552 kfree(ptr
, sizeof(submap_map_t
));
6553 if(parent_maps
== NULL
)
6555 src_entry
= tmp_entry
->vme_prev
;
6559 if ((src_start
>= src_end
) && (src_end
!= 0))
6563 * Verify that there are no gaps in the region
6566 tmp_entry
= src_entry
->vme_next
;
6567 if ((tmp_entry
->vme_start
!= src_start
) ||
6568 (tmp_entry
== vm_map_to_entry(src_map
)))
6569 RETURN(KERN_INVALID_ADDRESS
);
6573 * If the source should be destroyed, do it now, since the
6574 * copy was successful.
6577 (void) vm_map_delete(src_map
,
6578 vm_map_trunc_page(src_addr
),
6580 (src_map
== kernel_map
) ?
6581 VM_MAP_REMOVE_KUNWIRE
:
6586 vm_map_unlock(src_map
);
6588 /* Fix-up start and end points in copy. This is necessary */
6589 /* when the various entries in the copy object were picked */
6590 /* up from different sub-maps */
6592 tmp_entry
= vm_map_copy_first_entry(copy
);
6593 while (tmp_entry
!= vm_map_copy_to_entry(copy
)) {
6594 tmp_entry
->vme_end
= copy_addr
+
6595 (tmp_entry
->vme_end
- tmp_entry
->vme_start
);
6596 tmp_entry
->vme_start
= copy_addr
;
6597 copy_addr
+= tmp_entry
->vme_end
- tmp_entry
->vme_start
;
6598 tmp_entry
= (struct vm_map_entry
*)tmp_entry
->vme_next
;
6601 *copy_result
= copy
;
6602 return(KERN_SUCCESS
);
6608 * vm_map_copyin_object:
6610 * Create a copy object from an object.
6611 * Our caller donates an object reference.
6615 vm_map_copyin_object(
6617 vm_object_offset_t offset
, /* offset of region in object */
6618 vm_object_size_t size
, /* size of region in object */
6619 vm_map_copy_t
*copy_result
) /* OUT */
6621 vm_map_copy_t copy
; /* Resulting copy */
6624 * We drop the object into a special copy object
6625 * that contains the object directly.
6628 copy
= (vm_map_copy_t
) zalloc(vm_map_copy_zone
);
6629 copy
->type
= VM_MAP_COPY_OBJECT
;
6630 copy
->cpy_object
= object
;
6631 copy
->offset
= offset
;
6634 *copy_result
= copy
;
6635 return(KERN_SUCCESS
);
6641 vm_map_entry_t old_entry
,
6645 vm_map_entry_t new_entry
;
6648 * New sharing code. New map entry
6649 * references original object. Internal
6650 * objects use asynchronous copy algorithm for
6651 * future copies. First make sure we have
6652 * the right object. If we need a shadow,
6653 * or someone else already has one, then
6654 * make a new shadow and share it.
6657 object
= old_entry
->object
.vm_object
;
6658 if (old_entry
->is_sub_map
) {
6659 assert(old_entry
->wired_count
== 0);
6660 #ifndef NO_NESTED_PMAP
6661 if(old_entry
->use_pmap
) {
6662 kern_return_t result
;
6664 result
= pmap_nest(new_map
->pmap
,
6665 (old_entry
->object
.sub_map
)->pmap
,
6666 (addr64_t
)old_entry
->vme_start
,
6667 (addr64_t
)old_entry
->vme_start
,
6668 (uint64_t)(old_entry
->vme_end
- old_entry
->vme_start
));
6670 panic("vm_map_fork_share: pmap_nest failed!");
6672 #endif /* NO_NESTED_PMAP */
6673 } else if (object
== VM_OBJECT_NULL
) {
6674 object
= vm_object_allocate((vm_map_size_t
)(old_entry
->vme_end
-
6675 old_entry
->vme_start
));
6676 old_entry
->offset
= 0;
6677 old_entry
->object
.vm_object
= object
;
6678 assert(!old_entry
->needs_copy
);
6679 } else if (object
->copy_strategy
!=
6680 MEMORY_OBJECT_COPY_SYMMETRIC
) {
6683 * We are already using an asymmetric
6684 * copy, and therefore we already have
6688 assert(! old_entry
->needs_copy
);
6690 else if (old_entry
->needs_copy
|| /* case 1 */
6691 object
->shadowed
|| /* case 2 */
6692 (!object
->true_share
&& /* case 3 */
6693 !old_entry
->is_shared
&&
6695 (vm_map_size_t
)(old_entry
->vme_end
-
6696 old_entry
->vme_start
)))) {
6699 * We need to create a shadow.
6700 * There are three cases here.
6701 * In the first case, we need to
6702 * complete a deferred symmetrical
6703 * copy that we participated in.
6704 * In the second and third cases,
6705 * we need to create the shadow so
6706 * that changes that we make to the
6707 * object do not interfere with
6708 * any symmetrical copies which
6709 * have occured (case 2) or which
6710 * might occur (case 3).
6712 * The first case is when we had
6713 * deferred shadow object creation
6714 * via the entry->needs_copy mechanism.
6715 * This mechanism only works when
6716 * only one entry points to the source
6717 * object, and we are about to create
6718 * a second entry pointing to the
6719 * same object. The problem is that
6720 * there is no way of mapping from
6721 * an object to the entries pointing
6722 * to it. (Deferred shadow creation
6723 * works with one entry because occurs
6724 * at fault time, and we walk from the
6725 * entry to the object when handling
6728 * The second case is when the object
6729 * to be shared has already been copied
6730 * with a symmetric copy, but we point
6731 * directly to the object without
6732 * needs_copy set in our entry. (This
6733 * can happen because different ranges
6734 * of an object can be pointed to by
6735 * different entries. In particular,
6736 * a single entry pointing to an object
6737 * can be split by a call to vm_inherit,
6738 * which, combined with task_create, can
6739 * result in the different entries
6740 * having different needs_copy values.)
6741 * The shadowed flag in the object allows
6742 * us to detect this case. The problem
6743 * with this case is that if this object
6744 * has or will have shadows, then we
6745 * must not perform an asymmetric copy
6746 * of this object, since such a copy
6747 * allows the object to be changed, which
6748 * will break the previous symmetrical
6749 * copies (which rely upon the object
6750 * not changing). In a sense, the shadowed
6751 * flag says "don't change this object".
6752 * We fix this by creating a shadow
6753 * object for this object, and sharing
6754 * that. This works because we are free
6755 * to change the shadow object (and thus
6756 * to use an asymmetric copy strategy);
6757 * this is also semantically correct,
6758 * since this object is temporary, and
6759 * therefore a copy of the object is
6760 * as good as the object itself. (This
6761 * is not true for permanent objects,
6762 * since the pager needs to see changes,
6763 * which won't happen if the changes
6764 * are made to a copy.)
6766 * The third case is when the object
6767 * to be shared has parts sticking
6768 * outside of the entry we're working
6769 * with, and thus may in the future
6770 * be subject to a symmetrical copy.
6771 * (This is a preemptive version of
6775 assert(!(object
->shadowed
&& old_entry
->is_shared
));
6776 vm_object_shadow(&old_entry
->object
.vm_object
,
6778 (vm_map_size_t
) (old_entry
->vme_end
-
6779 old_entry
->vme_start
));
6782 * If we're making a shadow for other than
6783 * copy on write reasons, then we have
6784 * to remove write permission.
6787 if (!old_entry
->needs_copy
&&
6788 (old_entry
->protection
& VM_PROT_WRITE
)) {
6791 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
6792 #ifdef STACK_ONLY_NX
6793 if (old_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
6794 prot
|= VM_PROT_EXECUTE
;
6796 if (old_map
->mapped
) {
6797 vm_object_pmap_protect(
6798 old_entry
->object
.vm_object
,
6800 (old_entry
->vme_end
-
6801 old_entry
->vme_start
),
6803 old_entry
->vme_start
,
6806 pmap_protect(old_map
->pmap
,
6807 old_entry
->vme_start
,
6813 old_entry
->needs_copy
= FALSE
;
6814 object
= old_entry
->object
.vm_object
;
6818 * If object was using a symmetric copy strategy,
6819 * change its copy strategy to the default
6820 * asymmetric copy strategy, which is copy_delay
6821 * in the non-norma case and copy_call in the
6822 * norma case. Bump the reference count for the
6826 if(old_entry
->is_sub_map
) {
6827 vm_map_lock(old_entry
->object
.sub_map
);
6828 vm_map_reference(old_entry
->object
.sub_map
);
6829 vm_map_unlock(old_entry
->object
.sub_map
);
6831 vm_object_lock(object
);
6832 object
->ref_count
++;
6833 vm_object_res_reference(object
);
6834 if (object
->copy_strategy
== MEMORY_OBJECT_COPY_SYMMETRIC
) {
6835 object
->copy_strategy
= MEMORY_OBJECT_COPY_DELAY
;
6837 vm_object_unlock(object
);
6841 * Clone the entry, using object ref from above.
6842 * Mark both entries as shared.
6845 new_entry
= vm_map_entry_create(new_map
);
6846 vm_map_entry_copy(new_entry
, old_entry
);
6847 old_entry
->is_shared
= TRUE
;
6848 new_entry
->is_shared
= TRUE
;
6851 * Insert the entry into the new map -- we
6852 * know we're inserting at the end of the new
6856 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
), new_entry
);
6859 * Update the physical map
6862 if (old_entry
->is_sub_map
) {
6863 /* Bill Angell pmap support goes here */
6865 pmap_copy(new_map
->pmap
, old_map
->pmap
, new_entry
->vme_start
,
6866 old_entry
->vme_end
- old_entry
->vme_start
,
6867 old_entry
->vme_start
);
6874 vm_map_entry_t
*old_entry_p
,
6877 vm_map_entry_t old_entry
= *old_entry_p
;
6878 vm_map_size_t entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
6879 vm_map_offset_t start
= old_entry
->vme_start
;
6881 vm_map_entry_t last
= vm_map_last_entry(new_map
);
6883 vm_map_unlock(old_map
);
6885 * Use maxprot version of copyin because we
6886 * care about whether this memory can ever
6887 * be accessed, not just whether it's accessible
6890 if (vm_map_copyin_maxprot(old_map
, start
, entry_size
, FALSE
, ©
)
6893 * The map might have changed while it
6894 * was unlocked, check it again. Skip
6895 * any blank space or permanently
6896 * unreadable region.
6898 vm_map_lock(old_map
);
6899 if (!vm_map_lookup_entry(old_map
, start
, &last
) ||
6900 (last
->max_protection
& VM_PROT_READ
) == VM_PROT_NONE
) {
6901 last
= last
->vme_next
;
6903 *old_entry_p
= last
;
6906 * XXX For some error returns, want to
6907 * XXX skip to the next element. Note
6908 * that INVALID_ADDRESS and
6909 * PROTECTION_FAILURE are handled above.
6916 * Insert the copy into the new map
6919 vm_map_copy_insert(new_map
, last
, copy
);
6922 * Pick up the traversal at the end of
6923 * the copied region.
6926 vm_map_lock(old_map
);
6927 start
+= entry_size
;
6928 if (! vm_map_lookup_entry(old_map
, start
, &last
)) {
6929 last
= last
->vme_next
;
6931 vm_map_clip_start(old_map
, last
, start
);
6933 *old_entry_p
= last
;
6941 * Create and return a new map based on the old
6942 * map, according to the inheritance values on the
6943 * regions in that map.
6945 * The source map must not be locked.
6951 pmap_t new_pmap
= pmap_create(
6953 task_has_64BitAddr(current_task()));
6955 vm_map_entry_t old_entry
;
6956 vm_map_size_t new_size
= 0, entry_size
;
6957 vm_map_entry_t new_entry
;
6958 boolean_t src_needs_copy
;
6959 boolean_t new_entry_needs_copy
;
6961 vm_map_reference_swap(old_map
);
6962 vm_map_lock(old_map
);
6964 new_map
= vm_map_create(new_pmap
,
6965 old_map
->min_offset
,
6966 old_map
->max_offset
,
6967 old_map
->hdr
.entries_pageable
);
6970 old_entry
= vm_map_first_entry(old_map
);
6971 old_entry
!= vm_map_to_entry(old_map
);
6974 entry_size
= old_entry
->vme_end
- old_entry
->vme_start
;
6976 switch (old_entry
->inheritance
) {
6977 case VM_INHERIT_NONE
:
6980 case VM_INHERIT_SHARE
:
6981 vm_map_fork_share(old_map
, old_entry
, new_map
);
6982 new_size
+= entry_size
;
6985 case VM_INHERIT_COPY
:
6988 * Inline the copy_quickly case;
6989 * upon failure, fall back on call
6990 * to vm_map_fork_copy.
6993 if(old_entry
->is_sub_map
)
6995 if ((old_entry
->wired_count
!= 0) ||
6996 ((old_entry
->object
.vm_object
!= NULL
) &&
6997 (old_entry
->object
.vm_object
->true_share
))) {
6998 goto slow_vm_map_fork_copy
;
7001 new_entry
= vm_map_entry_create(new_map
);
7002 vm_map_entry_copy(new_entry
, old_entry
);
7003 /* clear address space specifics */
7004 new_entry
->use_pmap
= FALSE
;
7006 if (! vm_object_copy_quickly(
7007 &new_entry
->object
.vm_object
,
7009 (old_entry
->vme_end
-
7010 old_entry
->vme_start
),
7012 &new_entry_needs_copy
)) {
7013 vm_map_entry_dispose(new_map
, new_entry
);
7014 goto slow_vm_map_fork_copy
;
7018 * Handle copy-on-write obligations
7021 if (src_needs_copy
&& !old_entry
->needs_copy
) {
7024 prot
= old_entry
->protection
& ~VM_PROT_WRITE
;
7025 #ifdef STACK_ONLY_NX
7026 if (old_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
7027 prot
|= VM_PROT_EXECUTE
;
7029 vm_object_pmap_protect(
7030 old_entry
->object
.vm_object
,
7032 (old_entry
->vme_end
-
7033 old_entry
->vme_start
),
7034 ((old_entry
->is_shared
7038 old_entry
->vme_start
,
7041 old_entry
->needs_copy
= TRUE
;
7043 new_entry
->needs_copy
= new_entry_needs_copy
;
7046 * Insert the entry at the end
7050 vm_map_entry_link(new_map
, vm_map_last_entry(new_map
),
7052 new_size
+= entry_size
;
7055 slow_vm_map_fork_copy
:
7056 if (vm_map_fork_copy(old_map
, &old_entry
, new_map
)) {
7057 new_size
+= entry_size
;
7061 old_entry
= old_entry
->vme_next
;
7064 new_map
->size
= new_size
;
7065 vm_map_unlock(old_map
);
7066 vm_map_deallocate(old_map
);
7073 * vm_map_lookup_locked:
7075 * Finds the VM object, offset, and
7076 * protection for a given virtual address in the
7077 * specified map, assuming a page fault of the
7080 * Returns the (object, offset, protection) for
7081 * this address, whether it is wired down, and whether
7082 * this map has the only reference to the data in question.
7083 * In order to later verify this lookup, a "version"
7086 * The map MUST be locked by the caller and WILL be
7087 * locked on exit. In order to guarantee the
7088 * existence of the returned object, it is returned
7091 * If a lookup is requested with "write protection"
7092 * specified, the map may be changed to perform virtual
7093 * copying operations, although the data referenced will
7097 vm_map_lookup_locked(
7098 vm_map_t
*var_map
, /* IN/OUT */
7099 vm_map_offset_t vaddr
,
7100 vm_prot_t fault_type
,
7101 vm_map_version_t
*out_version
, /* OUT */
7102 vm_object_t
*object
, /* OUT */
7103 vm_object_offset_t
*offset
, /* OUT */
7104 vm_prot_t
*out_prot
, /* OUT */
7105 boolean_t
*wired
, /* OUT */
7106 int *behavior
, /* OUT */
7107 vm_map_offset_t
*lo_offset
, /* OUT */
7108 vm_map_offset_t
*hi_offset
, /* OUT */
7111 vm_map_entry_t entry
;
7112 register vm_map_t map
= *var_map
;
7113 vm_map_t old_map
= *var_map
;
7114 vm_map_t cow_sub_map_parent
= VM_MAP_NULL
;
7115 vm_map_offset_t cow_parent_vaddr
= 0;
7116 vm_map_offset_t old_start
= 0;
7117 vm_map_offset_t old_end
= 0;
7118 register vm_prot_t prot
;
7124 * If the map has an interesting hint, try it before calling
7125 * full blown lookup routine.
7129 if ((entry
== vm_map_to_entry(map
)) ||
7130 (vaddr
< entry
->vme_start
) || (vaddr
>= entry
->vme_end
)) {
7131 vm_map_entry_t tmp_entry
;
7134 * Entry was either not a valid hint, or the vaddr
7135 * was not contained in the entry, so do a full lookup.
7137 if (!vm_map_lookup_entry(map
, vaddr
, &tmp_entry
)) {
7138 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
))
7139 vm_map_unlock(cow_sub_map_parent
);
7140 if((*real_map
!= map
)
7141 && (*real_map
!= cow_sub_map_parent
))
7142 vm_map_unlock(*real_map
);
7143 return KERN_INVALID_ADDRESS
;
7148 if(map
== old_map
) {
7149 old_start
= entry
->vme_start
;
7150 old_end
= entry
->vme_end
;
7154 * Handle submaps. Drop lock on upper map, submap is
7159 if (entry
->is_sub_map
) {
7160 vm_map_offset_t local_vaddr
;
7161 vm_map_offset_t end_delta
;
7162 vm_map_offset_t start_delta
;
7163 vm_map_entry_t submap_entry
;
7164 boolean_t mapped_needs_copy
=FALSE
;
7166 local_vaddr
= vaddr
;
7168 if ((!entry
->needs_copy
) && (entry
->use_pmap
)) {
7169 /* if real_map equals map we unlock below */
7170 if ((*real_map
!= map
) &&
7171 (*real_map
!= cow_sub_map_parent
))
7172 vm_map_unlock(*real_map
);
7173 *real_map
= entry
->object
.sub_map
;
7176 if(entry
->needs_copy
) {
7177 if (!mapped_needs_copy
) {
7178 if (vm_map_lock_read_to_write(map
)) {
7179 vm_map_lock_read(map
);
7180 if(*real_map
== entry
->object
.sub_map
)
7184 vm_map_lock_read(entry
->object
.sub_map
);
7185 cow_sub_map_parent
= map
;
7186 /* reset base to map before cow object */
7187 /* this is the map which will accept */
7188 /* the new cow object */
7189 old_start
= entry
->vme_start
;
7190 old_end
= entry
->vme_end
;
7191 cow_parent_vaddr
= vaddr
;
7192 mapped_needs_copy
= TRUE
;
7194 vm_map_lock_read(entry
->object
.sub_map
);
7195 if((cow_sub_map_parent
!= map
) &&
7200 vm_map_lock_read(entry
->object
.sub_map
);
7201 /* leave map locked if it is a target */
7202 /* cow sub_map above otherwise, just */
7203 /* follow the maps down to the object */
7204 /* here we unlock knowing we are not */
7205 /* revisiting the map. */
7206 if((*real_map
!= map
) && (map
!= cow_sub_map_parent
))
7207 vm_map_unlock_read(map
);
7210 *var_map
= map
= entry
->object
.sub_map
;
7212 /* calculate the offset in the submap for vaddr */
7213 local_vaddr
= (local_vaddr
- entry
->vme_start
) + entry
->offset
;
7216 if(!vm_map_lookup_entry(map
, local_vaddr
, &submap_entry
)) {
7217 if((cow_sub_map_parent
) && (cow_sub_map_parent
!= map
)){
7218 vm_map_unlock(cow_sub_map_parent
);
7220 if((*real_map
!= map
)
7221 && (*real_map
!= cow_sub_map_parent
)) {
7222 vm_map_unlock(*real_map
);
7225 return KERN_INVALID_ADDRESS
;
7227 /* find the attenuated shadow of the underlying object */
7228 /* on our target map */
7230 /* in english the submap object may extend beyond the */
7231 /* region mapped by the entry or, may only fill a portion */
7232 /* of it. For our purposes, we only care if the object */
7233 /* doesn't fill. In this case the area which will */
7234 /* ultimately be clipped in the top map will only need */
7235 /* to be as big as the portion of the underlying entry */
7236 /* which is mapped */
7237 start_delta
= submap_entry
->vme_start
> entry
->offset
?
7238 submap_entry
->vme_start
- entry
->offset
: 0;
7241 (entry
->offset
+ start_delta
+ (old_end
- old_start
)) <=
7242 submap_entry
->vme_end
?
7243 0 : (entry
->offset
+
7244 (old_end
- old_start
))
7245 - submap_entry
->vme_end
;
7247 old_start
+= start_delta
;
7248 old_end
-= end_delta
;
7250 if(submap_entry
->is_sub_map
) {
7251 entry
= submap_entry
;
7252 vaddr
= local_vaddr
;
7253 goto submap_recurse
;
7256 if(((fault_type
& VM_PROT_WRITE
) && cow_sub_map_parent
)) {
7258 vm_object_t copy_object
;
7259 vm_map_offset_t local_start
;
7260 vm_map_offset_t local_end
;
7261 boolean_t copied_slowly
= FALSE
;
7263 if (vm_map_lock_read_to_write(map
)) {
7264 vm_map_lock_read(map
);
7265 old_start
-= start_delta
;
7266 old_end
+= end_delta
;
7271 if (submap_entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7272 submap_entry
->object
.vm_object
=
7275 (submap_entry
->vme_end
7276 - submap_entry
->vme_start
));
7277 submap_entry
->offset
= 0;
7279 local_start
= local_vaddr
-
7280 (cow_parent_vaddr
- old_start
);
7281 local_end
= local_vaddr
+
7282 (old_end
- cow_parent_vaddr
);
7283 vm_map_clip_start(map
, submap_entry
, local_start
);
7284 vm_map_clip_end(map
, submap_entry
, local_end
);
7286 /* This is the COW case, lets connect */
7287 /* an entry in our space to the underlying */
7288 /* object in the submap, bypassing the */
7292 if(submap_entry
->wired_count
!= 0) {
7294 submap_entry
->object
.vm_object
);
7295 vm_object_copy_slowly(
7296 submap_entry
->object
.vm_object
,
7297 submap_entry
->offset
,
7298 submap_entry
->vme_end
-
7299 submap_entry
->vme_start
,
7302 copied_slowly
= TRUE
;
7304 /* set up shadow object */
7305 copy_object
= submap_entry
->object
.vm_object
;
7306 vm_object_reference(copy_object
);
7307 submap_entry
->object
.vm_object
->shadowed
= TRUE
;
7308 submap_entry
->needs_copy
= TRUE
;
7310 prot
= submap_entry
->protection
& ~VM_PROT_WRITE
;
7311 #ifdef STACK_ONLY_NX
7312 if (submap_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
7313 prot
|= VM_PROT_EXECUTE
;
7315 vm_object_pmap_protect(
7316 submap_entry
->object
.vm_object
,
7317 submap_entry
->offset
,
7318 submap_entry
->vme_end
-
7319 submap_entry
->vme_start
,
7320 (submap_entry
->is_shared
7322 PMAP_NULL
: map
->pmap
,
7323 submap_entry
->vme_start
,
7328 /* This works diffently than the */
7329 /* normal submap case. We go back */
7330 /* to the parent of the cow map and*/
7331 /* clip out the target portion of */
7332 /* the sub_map, substituting the */
7333 /* new copy object, */
7336 local_start
= old_start
;
7337 local_end
= old_end
;
7338 map
= cow_sub_map_parent
;
7339 *var_map
= cow_sub_map_parent
;
7340 vaddr
= cow_parent_vaddr
;
7341 cow_sub_map_parent
= NULL
;
7343 if(!vm_map_lookup_entry(map
,
7345 vm_object_deallocate(
7347 vm_map_lock_write_to_read(map
);
7348 return KERN_INVALID_ADDRESS
;
7351 /* clip out the portion of space */
7352 /* mapped by the sub map which */
7353 /* corresponds to the underlying */
7355 vm_map_clip_start(map
, entry
, local_start
);
7356 vm_map_clip_end(map
, entry
, local_end
);
7359 /* substitute copy object for */
7360 /* shared map entry */
7361 vm_map_deallocate(entry
->object
.sub_map
);
7362 entry
->is_sub_map
= FALSE
;
7363 entry
->object
.vm_object
= copy_object
;
7365 entry
->protection
|= VM_PROT_WRITE
;
7366 entry
->max_protection
|= VM_PROT_WRITE
;
7369 entry
->needs_copy
= FALSE
;
7370 entry
->is_shared
= FALSE
;
7372 entry
->offset
= submap_entry
->offset
;
7373 entry
->needs_copy
= TRUE
;
7374 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7375 entry
->inheritance
= VM_INHERIT_COPY
;
7377 entry
->is_shared
= TRUE
;
7379 if(entry
->inheritance
== VM_INHERIT_SHARE
)
7380 entry
->inheritance
= VM_INHERIT_COPY
;
7382 vm_map_lock_write_to_read(map
);
7384 if((cow_sub_map_parent
)
7385 && (cow_sub_map_parent
!= *real_map
)
7386 && (cow_sub_map_parent
!= map
)) {
7387 vm_map_unlock(cow_sub_map_parent
);
7389 entry
= submap_entry
;
7390 vaddr
= local_vaddr
;
7395 * Check whether this task is allowed to have
7398 prot
= entry
->protection
;
7400 #ifdef STACK_ONLY_NX
7401 if (entry
->alias
!= VM_MEMORY_STACK
&& prot
)
7403 * HACK -- if not a stack, than allow execution
7405 prot
|= VM_PROT_EXECUTE
;
7407 if ((fault_type
& (prot
)) != fault_type
) {
7408 if (*real_map
!= map
) {
7409 vm_map_unlock(*real_map
);
7413 if ((fault_type
& VM_PROT_EXECUTE
) && prot
)
7414 log_nx_failure((addr64_t
)vaddr
, prot
);
7416 return KERN_PROTECTION_FAILURE
;
7420 * If this page is not pageable, we have to get
7421 * it for all possible accesses.
7424 *wired
= (entry
->wired_count
!= 0);
7429 * If the entry was copy-on-write, we either ...
7432 if (entry
->needs_copy
) {
7434 * If we want to write the page, we may as well
7435 * handle that now since we've got the map locked.
7437 * If we don't need to write the page, we just
7438 * demote the permissions allowed.
7441 if ((fault_type
& VM_PROT_WRITE
) || *wired
) {
7443 * Make a new object, and place it in the
7444 * object chain. Note that no new references
7445 * have appeared -- one just moved from the
7446 * map to the new object.
7449 if (vm_map_lock_read_to_write(map
)) {
7450 vm_map_lock_read(map
);
7453 vm_object_shadow(&entry
->object
.vm_object
,
7455 (vm_map_size_t
) (entry
->vme_end
-
7458 entry
->object
.vm_object
->shadowed
= TRUE
;
7459 entry
->needs_copy
= FALSE
;
7460 vm_map_lock_write_to_read(map
);
7464 * We're attempting to read a copy-on-write
7465 * page -- don't allow writes.
7468 prot
&= (~VM_PROT_WRITE
);
7473 * Create an object if necessary.
7475 if (entry
->object
.vm_object
== VM_OBJECT_NULL
) {
7477 if (vm_map_lock_read_to_write(map
)) {
7478 vm_map_lock_read(map
);
7482 entry
->object
.vm_object
= vm_object_allocate(
7483 (vm_map_size_t
)(entry
->vme_end
- entry
->vme_start
));
7485 vm_map_lock_write_to_read(map
);
7489 * Return the object/offset from this entry. If the entry
7490 * was copy-on-write or empty, it has been fixed up. Also
7491 * return the protection.
7494 *offset
= (vaddr
- entry
->vme_start
) + entry
->offset
;
7495 *object
= entry
->object
.vm_object
;
7497 *behavior
= entry
->behavior
;
7498 *lo_offset
= entry
->offset
;
7499 *hi_offset
= (entry
->vme_end
- entry
->vme_start
) + entry
->offset
;
7502 * Lock the object to prevent it from disappearing
7505 vm_object_lock(*object
);
7508 * Save the version number
7511 out_version
->main_timestamp
= map
->timestamp
;
7513 return KERN_SUCCESS
;
7520 * Verifies that the map in question has not changed
7521 * since the given version. If successful, the map
7522 * will not change until vm_map_verify_done() is called.
7526 register vm_map_t map
,
7527 register vm_map_version_t
*version
) /* REF */
7531 vm_map_lock_read(map
);
7532 result
= (map
->timestamp
== version
->main_timestamp
);
7535 vm_map_unlock_read(map
);
7541 * vm_map_verify_done:
7543 * Releases locks acquired by a vm_map_verify.
7545 * This is now a macro in vm/vm_map.h. It does a
7546 * vm_map_unlock_read on the map.
7551 * TEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARYTEMPORARY
7552 * Goes away after regular vm_region_recurse function migrates to
7554 * vm_region_recurse: A form of vm_region which follows the
7555 * submaps in a target map
7560 vm_map_region_recurse_64(
7562 vm_map_offset_t
*address
, /* IN/OUT */
7563 vm_map_size_t
*size
, /* OUT */
7564 natural_t
*nesting_depth
, /* IN/OUT */
7565 vm_region_submap_info_64_t submap_info
, /* IN/OUT */
7566 mach_msg_type_number_t
*count
) /* IN/OUT */
7568 vm_region_extended_info_data_t extended
;
7569 vm_map_entry_t tmp_entry
;
7570 vm_map_offset_t user_address
;
7571 unsigned int user_max_depth
;
7574 * "curr_entry" is the VM map entry preceding or including the
7575 * address we're looking for.
7576 * "curr_map" is the map or sub-map containing "curr_entry".
7577 * "curr_offset" is the cumulated offset of "curr_map" in the
7578 * target task's address space.
7579 * "curr_depth" is the depth of "curr_map" in the chain of
7581 * "curr_max_offset" is the maximum offset we should take into
7582 * account in the current map. It may be smaller than the current
7583 * map's "max_offset" because we might not have mapped it all in
7584 * the upper level map.
7586 vm_map_entry_t curr_entry
;
7587 vm_map_offset_t curr_offset
;
7589 unsigned int curr_depth
;
7590 vm_map_offset_t curr_max_offset
;
7593 * "next_" is the same as "curr_" but for the VM region immediately
7594 * after the address we're looking for. We need to keep track of this
7595 * too because we want to return info about that region if the
7596 * address we're looking for is not mapped.
7598 vm_map_entry_t next_entry
;
7599 vm_map_offset_t next_offset
;
7601 unsigned int next_depth
;
7602 vm_map_offset_t next_max_offset
;
7604 if (map
== VM_MAP_NULL
) {
7605 /* no address space to work on */
7606 return KERN_INVALID_ARGUMENT
;
7609 if (*count
< VM_REGION_SUBMAP_INFO_COUNT_64
) {
7610 /* "info" structure is not big enough and would overflow */
7611 return KERN_INVALID_ARGUMENT
;
7614 *count
= VM_REGION_SUBMAP_INFO_COUNT_64
;
7616 user_address
= *address
;
7617 user_max_depth
= *nesting_depth
;
7623 curr_max_offset
= curr_map
->max_offset
;
7629 next_max_offset
= curr_max_offset
;
7632 vm_map_lock_read(curr_map
);
7636 if (vm_map_lookup_entry(curr_map
,
7637 user_address
- curr_offset
,
7639 /* tmp_entry contains the address we're looking for */
7640 curr_entry
= tmp_entry
;
7643 * The address is not mapped. "tmp_entry" is the
7644 * map entry preceding the address. We want the next
7645 * one, if it exists.
7647 curr_entry
= tmp_entry
->vme_next
;
7648 if (curr_entry
== vm_map_to_entry(curr_map
) ||
7649 curr_entry
->vme_start
>= curr_max_offset
) {
7650 /* no next entry at this level: stop looking */
7652 vm_map_unlock_read(curr_map
);
7658 curr_max_offset
= 0;
7664 * Is the next entry at this level closer to the address (or
7665 * deeper in the submap chain) than the one we had
7668 tmp_entry
= curr_entry
->vme_next
;
7669 if (tmp_entry
== vm_map_to_entry(curr_map
)) {
7670 /* no next entry at this level */
7671 } else if (tmp_entry
->vme_start
>= curr_max_offset
) {
7673 * tmp_entry is beyond the scope of what we mapped of
7674 * this submap in the upper level: ignore it.
7676 } else if ((next_entry
== NULL
) ||
7677 (tmp_entry
->vme_start
+ curr_offset
<=
7678 next_entry
->vme_start
+ next_offset
)) {
7680 * We didn't have a "next_entry" or this one is
7681 * closer to the address we're looking for:
7682 * use this "tmp_entry" as the new "next_entry".
7684 if (next_entry
!= NULL
) {
7685 /* unlock the last "next_map" */
7686 if (next_map
!= curr_map
&& not_in_kdp
) {
7687 vm_map_unlock_read(next_map
);
7690 next_entry
= tmp_entry
;
7691 next_map
= curr_map
;
7692 next_offset
= curr_offset
;
7693 next_depth
= curr_depth
;
7694 next_max_offset
= curr_max_offset
;
7697 if (!curr_entry
->is_sub_map
||
7698 curr_depth
>= user_max_depth
) {
7700 * We hit a leaf map or we reached the maximum depth
7701 * we could, so stop looking. Keep the current map
7708 * Get down to the next submap level.
7712 * Lock the next level and unlock the current level,
7713 * unless we need to keep it locked to access the "next_entry"
7717 vm_map_lock_read(curr_entry
->object
.sub_map
);
7719 if (curr_map
== next_map
) {
7720 /* keep "next_map" locked in case we need it */
7722 /* release this map */
7723 vm_map_unlock_read(curr_map
);
7727 * Adjust the offset. "curr_entry" maps the submap
7728 * at relative address "curr_entry->vme_start" in the
7729 * curr_map but skips the first "curr_entry->offset"
7730 * bytes of the submap.
7731 * "curr_offset" always represents the offset of a virtual
7732 * address in the curr_map relative to the absolute address
7733 * space (i.e. the top-level VM map).
7736 (curr_entry
->vme_start
- curr_entry
->offset
);
7737 /* switch to the submap */
7738 curr_map
= curr_entry
->object
.sub_map
;
7741 * "curr_max_offset" allows us to keep track of the
7742 * portion of the submap that is actually mapped at this level:
7743 * the rest of that submap is irrelevant to us, since it's not
7745 * The relevant portion of the map starts at
7746 * "curr_entry->offset" up to the size of "curr_entry".
7749 curr_entry
->vme_end
- curr_entry
->vme_start
+
7754 if (curr_entry
== NULL
) {
7755 /* no VM region contains the address... */
7756 if (next_entry
== NULL
) {
7757 /* ... and no VM region follows it either */
7758 return KERN_INVALID_ADDRESS
;
7760 /* ... gather info about the next VM region */
7761 curr_entry
= next_entry
;
7762 curr_map
= next_map
; /* still locked ... */
7763 curr_offset
= next_offset
;
7764 curr_depth
= next_depth
;
7765 curr_max_offset
= next_max_offset
;
7767 /* we won't need "next_entry" after all */
7768 if (next_entry
!= NULL
) {
7769 /* release "next_map" */
7770 if (next_map
!= curr_map
&& not_in_kdp
) {
7771 vm_map_unlock_read(next_map
);
7779 next_max_offset
= 0;
7781 *nesting_depth
= curr_depth
;
7782 *size
= curr_entry
->vme_end
- curr_entry
->vme_start
;
7783 *address
= curr_entry
->vme_start
+ curr_offset
;
7785 submap_info
->user_tag
= curr_entry
->alias
;
7786 submap_info
->offset
= curr_entry
->offset
;
7787 submap_info
->protection
= curr_entry
->protection
;
7788 submap_info
->inheritance
= curr_entry
->inheritance
;
7789 submap_info
->max_protection
= curr_entry
->max_protection
;
7790 submap_info
->behavior
= curr_entry
->behavior
;
7791 submap_info
->user_wired_count
= curr_entry
->user_wired_count
;
7792 submap_info
->is_submap
= curr_entry
->is_sub_map
;
7793 submap_info
->object_id
= (uint32_t) curr_entry
->object
.vm_object
;
7795 extended
.pages_resident
= 0;
7796 extended
.pages_swapped_out
= 0;
7797 extended
.pages_shared_now_private
= 0;
7798 extended
.pages_dirtied
= 0;
7799 extended
.external_pager
= 0;
7800 extended
.shadow_depth
= 0;
7803 if (!curr_entry
->is_sub_map
) {
7804 vm_map_region_walk(curr_map
,
7805 curr_entry
->vme_start
,
7808 (curr_entry
->vme_end
-
7809 curr_entry
->vme_start
),
7811 submap_info
->share_mode
= extended
.share_mode
;
7812 if (extended
.external_pager
&&
7813 extended
.ref_count
== 2 &&
7814 extended
.share_mode
== SM_SHARED
) {
7815 submap_info
->share_mode
= SM_PRIVATE
;
7817 submap_info
->ref_count
= extended
.ref_count
;
7819 if (curr_entry
->use_pmap
) {
7820 submap_info
->share_mode
= SM_TRUESHARED
;
7822 submap_info
->share_mode
= SM_PRIVATE
;
7824 submap_info
->ref_count
=
7825 curr_entry
->object
.sub_map
->ref_count
;
7829 submap_info
->pages_resident
= extended
.pages_resident
;
7830 submap_info
->pages_swapped_out
= extended
.pages_swapped_out
;
7831 submap_info
->pages_shared_now_private
=
7832 extended
.pages_shared_now_private
;
7833 submap_info
->pages_dirtied
= extended
.pages_dirtied
;
7834 submap_info
->external_pager
= extended
.external_pager
;
7835 submap_info
->shadow_depth
= extended
.shadow_depth
;
7838 vm_map_unlock_read(curr_map
);
7841 return KERN_SUCCESS
;
7847 * User call to obtain information about a region in
7848 * a task's address map. Currently, only one flavor is
7851 * XXX The reserved and behavior fields cannot be filled
7852 * in until the vm merge from the IK is completed, and
7853 * vm_reserve is implemented.
7859 vm_map_offset_t
*address
, /* IN/OUT */
7860 vm_map_size_t
*size
, /* OUT */
7861 vm_region_flavor_t flavor
, /* IN */
7862 vm_region_info_t info
, /* OUT */
7863 mach_msg_type_number_t
*count
, /* IN/OUT */
7864 mach_port_t
*object_name
) /* OUT */
7866 vm_map_entry_t tmp_entry
;
7867 vm_map_entry_t entry
;
7868 vm_map_offset_t start
;
7870 if (map
== VM_MAP_NULL
)
7871 return(KERN_INVALID_ARGUMENT
);
7875 case VM_REGION_BASIC_INFO
:
7876 /* legacy for old 32-bit objects info */
7878 vm_region_basic_info_t basic
;
7880 if (*count
< VM_REGION_BASIC_INFO_COUNT
)
7881 return(KERN_INVALID_ARGUMENT
);
7883 basic
= (vm_region_basic_info_t
) info
;
7884 *count
= VM_REGION_BASIC_INFO_COUNT
;
7886 vm_map_lock_read(map
);
7889 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7890 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7891 vm_map_unlock_read(map
);
7892 return(KERN_INVALID_ADDRESS
);
7898 start
= entry
->vme_start
;
7900 basic
->offset
= (uint32_t)entry
->offset
;
7901 basic
->protection
= entry
->protection
;
7902 basic
->inheritance
= entry
->inheritance
;
7903 basic
->max_protection
= entry
->max_protection
;
7904 basic
->behavior
= entry
->behavior
;
7905 basic
->user_wired_count
= entry
->user_wired_count
;
7906 basic
->reserved
= entry
->is_sub_map
;
7908 *size
= (entry
->vme_end
- start
);
7910 if (object_name
) *object_name
= IP_NULL
;
7911 if (entry
->is_sub_map
) {
7912 basic
->shared
= FALSE
;
7914 basic
->shared
= entry
->is_shared
;
7917 vm_map_unlock_read(map
);
7918 return(KERN_SUCCESS
);
7921 case VM_REGION_BASIC_INFO_64
:
7923 vm_region_basic_info_64_t basic
;
7925 if (*count
< VM_REGION_BASIC_INFO_COUNT_64
)
7926 return(KERN_INVALID_ARGUMENT
);
7928 basic
= (vm_region_basic_info_64_t
) info
;
7929 *count
= VM_REGION_BASIC_INFO_COUNT_64
;
7931 vm_map_lock_read(map
);
7934 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7935 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7936 vm_map_unlock_read(map
);
7937 return(KERN_INVALID_ADDRESS
);
7943 start
= entry
->vme_start
;
7945 basic
->offset
= entry
->offset
;
7946 basic
->protection
= entry
->protection
;
7947 basic
->inheritance
= entry
->inheritance
;
7948 basic
->max_protection
= entry
->max_protection
;
7949 basic
->behavior
= entry
->behavior
;
7950 basic
->user_wired_count
= entry
->user_wired_count
;
7951 basic
->reserved
= entry
->is_sub_map
;
7953 *size
= (entry
->vme_end
- start
);
7955 if (object_name
) *object_name
= IP_NULL
;
7956 if (entry
->is_sub_map
) {
7957 basic
->shared
= FALSE
;
7959 basic
->shared
= entry
->is_shared
;
7962 vm_map_unlock_read(map
);
7963 return(KERN_SUCCESS
);
7965 case VM_REGION_EXTENDED_INFO
:
7967 vm_region_extended_info_t extended
;
7969 if (*count
< VM_REGION_EXTENDED_INFO_COUNT
)
7970 return(KERN_INVALID_ARGUMENT
);
7972 extended
= (vm_region_extended_info_t
) info
;
7973 *count
= VM_REGION_EXTENDED_INFO_COUNT
;
7975 vm_map_lock_read(map
);
7978 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
7979 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
7980 vm_map_unlock_read(map
);
7981 return(KERN_INVALID_ADDRESS
);
7986 start
= entry
->vme_start
;
7988 extended
->protection
= entry
->protection
;
7989 extended
->user_tag
= entry
->alias
;
7990 extended
->pages_resident
= 0;
7991 extended
->pages_swapped_out
= 0;
7992 extended
->pages_shared_now_private
= 0;
7993 extended
->pages_dirtied
= 0;
7994 extended
->external_pager
= 0;
7995 extended
->shadow_depth
= 0;
7997 vm_map_region_walk(map
, start
, entry
, entry
->offset
, entry
->vme_end
- start
, extended
);
7999 if (extended
->external_pager
&& extended
->ref_count
== 2 && extended
->share_mode
== SM_SHARED
)
8000 extended
->share_mode
= SM_PRIVATE
;
8003 *object_name
= IP_NULL
;
8005 *size
= (entry
->vme_end
- start
);
8007 vm_map_unlock_read(map
);
8008 return(KERN_SUCCESS
);
8010 case VM_REGION_TOP_INFO
:
8012 vm_region_top_info_t top
;
8014 if (*count
< VM_REGION_TOP_INFO_COUNT
)
8015 return(KERN_INVALID_ARGUMENT
);
8017 top
= (vm_region_top_info_t
) info
;
8018 *count
= VM_REGION_TOP_INFO_COUNT
;
8020 vm_map_lock_read(map
);
8023 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
8024 if ((entry
= tmp_entry
->vme_next
) == vm_map_to_entry(map
)) {
8025 vm_map_unlock_read(map
);
8026 return(KERN_INVALID_ADDRESS
);
8032 start
= entry
->vme_start
;
8034 top
->private_pages_resident
= 0;
8035 top
->shared_pages_resident
= 0;
8037 vm_map_region_top_walk(entry
, top
);
8040 *object_name
= IP_NULL
;
8042 *size
= (entry
->vme_end
- start
);
8044 vm_map_unlock_read(map
);
8045 return(KERN_SUCCESS
);
8048 return(KERN_INVALID_ARGUMENT
);
8053 vm_map_region_top_walk(
8054 vm_map_entry_t entry
,
8055 vm_region_top_info_t top
)
8057 register struct vm_object
*obj
, *tmp_obj
;
8058 register int ref_count
;
8060 if (entry
->object
.vm_object
== 0 || entry
->is_sub_map
) {
8061 top
->share_mode
= SM_EMPTY
;
8067 obj
= entry
->object
.vm_object
;
8069 vm_object_lock(obj
);
8071 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
8076 top
->private_pages_resident
= obj
->resident_page_count
;
8078 top
->shared_pages_resident
= obj
->resident_page_count
;
8079 top
->ref_count
= ref_count
;
8080 top
->share_mode
= SM_COW
;
8082 while ((tmp_obj
= obj
->shadow
)) {
8083 vm_object_lock(tmp_obj
);
8084 vm_object_unlock(obj
);
8087 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
8090 top
->shared_pages_resident
+= obj
->resident_page_count
;
8091 top
->ref_count
+= ref_count
- 1;
8094 if (entry
->needs_copy
) {
8095 top
->share_mode
= SM_COW
;
8096 top
->shared_pages_resident
= obj
->resident_page_count
;
8098 if (ref_count
== 1 ||
8099 (ref_count
== 2 && !(obj
->pager_trusted
) && !(obj
->internal
))) {
8100 top
->share_mode
= SM_PRIVATE
;
8101 top
->private_pages_resident
= obj
->resident_page_count
;
8103 top
->share_mode
= SM_SHARED
;
8104 top
->shared_pages_resident
= obj
->resident_page_count
;
8107 top
->ref_count
= ref_count
;
8109 top
->obj_id
= (int)obj
;
8111 vm_object_unlock(obj
);
8119 vm_map_entry_t entry
,
8120 vm_object_offset_t offset
,
8121 vm_object_size_t range
,
8122 vm_region_extended_info_t extended
)
8124 register struct vm_object
*obj
, *tmp_obj
;
8125 register vm_map_offset_t last_offset
;
8127 register int ref_count
;
8128 struct vm_object
*shadow_object
;
8131 if ((entry
->object
.vm_object
== 0) ||
8132 (entry
->is_sub_map
) ||
8133 (entry
->object
.vm_object
->phys_contiguous
)) {
8134 extended
->share_mode
= SM_EMPTY
;
8135 extended
->ref_count
= 0;
8139 obj
= entry
->object
.vm_object
;
8141 vm_object_lock(obj
);
8143 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
8146 for (last_offset
= offset
+ range
; offset
< last_offset
; offset
+= PAGE_SIZE_64
, va
+= PAGE_SIZE
)
8147 vm_map_region_look_for_page(map
, va
, obj
, offset
, ref_count
, 0, extended
);
8149 shadow_object
= obj
->shadow
;
8151 if (shadow_object
!= VM_OBJECT_NULL
) {
8152 vm_object_lock(shadow_object
);
8154 shadow_object
!= VM_OBJECT_NULL
;
8156 vm_object_t next_shadow
;
8158 next_shadow
= shadow_object
->shadow
;
8160 vm_object_lock(next_shadow
);
8162 vm_object_unlock(shadow_object
);
8163 shadow_object
= next_shadow
;
8166 extended
->shadow_depth
= shadow_depth
;
8168 if (extended
->shadow_depth
|| entry
->needs_copy
)
8169 extended
->share_mode
= SM_COW
;
8172 extended
->share_mode
= SM_PRIVATE
;
8174 if (obj
->true_share
)
8175 extended
->share_mode
= SM_TRUESHARED
;
8177 extended
->share_mode
= SM_SHARED
;
8180 extended
->ref_count
= ref_count
- extended
->shadow_depth
;
8182 for (i
= 0; i
< extended
->shadow_depth
; i
++) {
8183 if ((tmp_obj
= obj
->shadow
) == 0)
8185 vm_object_lock(tmp_obj
);
8186 vm_object_unlock(obj
);
8188 if ((ref_count
= tmp_obj
->ref_count
) > 1 && tmp_obj
->paging_in_progress
)
8191 extended
->ref_count
+= ref_count
;
8194 vm_object_unlock(obj
);
8196 if (extended
->share_mode
== SM_SHARED
) {
8197 register vm_map_entry_t cur
;
8198 register vm_map_entry_t last
;
8201 obj
= entry
->object
.vm_object
;
8202 last
= vm_map_to_entry(map
);
8205 if ((ref_count
= obj
->ref_count
) > 1 && obj
->paging_in_progress
)
8207 for (cur
= vm_map_first_entry(map
); cur
!= last
; cur
= cur
->vme_next
)
8208 my_refs
+= vm_map_region_count_obj_refs(cur
, obj
);
8210 if (my_refs
== ref_count
)
8211 extended
->share_mode
= SM_PRIVATE_ALIASED
;
8212 else if (my_refs
> 1)
8213 extended
->share_mode
= SM_SHARED_ALIASED
;
8219 /* object is locked on entry and locked on return */
8223 vm_map_region_look_for_page(
8224 __unused vm_map_t map
,
8225 __unused vm_map_offset_t va
,
8227 vm_object_offset_t offset
,
8230 vm_region_extended_info_t extended
)
8232 register vm_page_t p
;
8233 register vm_object_t shadow
;
8234 register int ref_count
;
8235 vm_object_t caller_object
;
8237 shadow
= object
->shadow
;
8238 caller_object
= object
;
8243 if ( !(object
->pager_trusted
) && !(object
->internal
))
8244 extended
->external_pager
= 1;
8246 if ((p
= vm_page_lookup(object
, offset
)) != VM_PAGE_NULL
) {
8247 if (shadow
&& (max_refcnt
== 1))
8248 extended
->pages_shared_now_private
++;
8250 if (!p
->fictitious
&&
8251 (p
->dirty
|| pmap_is_modified(p
->phys_page
)))
8252 extended
->pages_dirtied
++;
8254 extended
->pages_resident
++;
8256 if(object
!= caller_object
)
8257 vm_object_unlock(object
);
8261 if (object
->existence_map
) {
8262 if (vm_external_state_get(object
->existence_map
, offset
) == VM_EXTERNAL_STATE_EXISTS
) {
8264 extended
->pages_swapped_out
++;
8266 if(object
!= caller_object
)
8267 vm_object_unlock(object
);
8273 vm_object_lock(shadow
);
8275 if ((ref_count
= shadow
->ref_count
) > 1 && shadow
->paging_in_progress
)
8278 if (++depth
> extended
->shadow_depth
)
8279 extended
->shadow_depth
= depth
;
8281 if (ref_count
> max_refcnt
)
8282 max_refcnt
= ref_count
;
8284 if(object
!= caller_object
)
8285 vm_object_unlock(object
);
8287 offset
= offset
+ object
->shadow_offset
;
8289 shadow
= object
->shadow
;
8292 if(object
!= caller_object
)
8293 vm_object_unlock(object
);
8299 vm_map_region_count_obj_refs(
8300 vm_map_entry_t entry
,
8303 register int ref_count
;
8304 register vm_object_t chk_obj
;
8305 register vm_object_t tmp_obj
;
8307 if (entry
->object
.vm_object
== 0)
8310 if (entry
->is_sub_map
)
8315 chk_obj
= entry
->object
.vm_object
;
8316 vm_object_lock(chk_obj
);
8319 if (chk_obj
== object
)
8321 tmp_obj
= chk_obj
->shadow
;
8323 vm_object_lock(tmp_obj
);
8324 vm_object_unlock(chk_obj
);
8334 * Routine: vm_map_simplify
8337 * Attempt to simplify the map representation in
8338 * the vicinity of the given starting address.
8340 * This routine is intended primarily to keep the
8341 * kernel maps more compact -- they generally don't
8342 * benefit from the "expand a map entry" technology
8343 * at allocation time because the adjacent entry
8344 * is often wired down.
8347 vm_map_simplify_entry(
8349 vm_map_entry_t this_entry
)
8351 vm_map_entry_t prev_entry
;
8353 counter(c_vm_map_simplify_entry_called
++);
8355 prev_entry
= this_entry
->vme_prev
;
8357 if ((this_entry
!= vm_map_to_entry(map
)) &&
8358 (prev_entry
!= vm_map_to_entry(map
)) &&
8360 (prev_entry
->vme_end
== this_entry
->vme_start
) &&
8362 (prev_entry
->is_sub_map
== FALSE
) &&
8363 (this_entry
->is_sub_map
== FALSE
) &&
8365 (prev_entry
->object
.vm_object
== this_entry
->object
.vm_object
) &&
8366 ((prev_entry
->offset
+ (prev_entry
->vme_end
-
8367 prev_entry
->vme_start
))
8368 == this_entry
->offset
) &&
8370 (prev_entry
->inheritance
== this_entry
->inheritance
) &&
8371 (prev_entry
->protection
== this_entry
->protection
) &&
8372 (prev_entry
->max_protection
== this_entry
->max_protection
) &&
8373 (prev_entry
->behavior
== this_entry
->behavior
) &&
8374 (prev_entry
->alias
== this_entry
->alias
) &&
8375 (prev_entry
->wired_count
== this_entry
->wired_count
) &&
8376 (prev_entry
->user_wired_count
== this_entry
->user_wired_count
) &&
8378 (prev_entry
->needs_copy
== this_entry
->needs_copy
) &&
8380 (prev_entry
->use_pmap
== FALSE
) &&
8381 (this_entry
->use_pmap
== FALSE
) &&
8382 (prev_entry
->in_transition
== FALSE
) &&
8383 (this_entry
->in_transition
== FALSE
) &&
8384 (prev_entry
->needs_wakeup
== FALSE
) &&
8385 (this_entry
->needs_wakeup
== FALSE
) &&
8386 (prev_entry
->is_shared
== FALSE
) &&
8387 (this_entry
->is_shared
== FALSE
)
8389 _vm_map_entry_unlink(&map
->hdr
, prev_entry
);
8390 this_entry
->vme_start
= prev_entry
->vme_start
;
8391 this_entry
->offset
= prev_entry
->offset
;
8392 vm_object_deallocate(prev_entry
->object
.vm_object
);
8393 vm_map_entry_dispose(map
, prev_entry
);
8394 SAVE_HINT_MAP_WRITE(map
, this_entry
);
8395 counter(c_vm_map_simplified
++);
8402 vm_map_offset_t start
)
8404 vm_map_entry_t this_entry
;
8407 if (vm_map_lookup_entry(map
, start
, &this_entry
)) {
8408 vm_map_simplify_entry(map
, this_entry
);
8409 vm_map_simplify_entry(map
, this_entry
->vme_next
);
8411 counter(c_vm_map_simplify_called
++);
8416 vm_map_simplify_range(
8418 vm_map_offset_t start
,
8419 vm_map_offset_t end
)
8421 vm_map_entry_t entry
;
8424 * The map should be locked (for "write") by the caller.
8428 /* invalid address range */
8432 if (!vm_map_lookup_entry(map
, start
, &entry
)) {
8433 /* "start" is not mapped and "entry" ends before "start" */
8434 if (entry
== vm_map_to_entry(map
)) {
8435 /* start with first entry in the map */
8436 entry
= vm_map_first_entry(map
);
8438 /* start with next entry */
8439 entry
= entry
->vme_next
;
8443 while (entry
!= vm_map_to_entry(map
) &&
8444 entry
->vme_start
<= end
) {
8445 /* try and coalesce "entry" with its previous entry */
8446 vm_map_simplify_entry(map
, entry
);
8447 entry
= entry
->vme_next
;
8453 * Routine: vm_map_machine_attribute
8455 * Provide machine-specific attributes to mappings,
8456 * such as cachability etc. for machines that provide
8457 * them. NUMA architectures and machines with big/strange
8458 * caches will use this.
8460 * Responsibilities for locking and checking are handled here,
8461 * everything else in the pmap module. If any non-volatile
8462 * information must be kept, the pmap module should handle
8463 * it itself. [This assumes that attributes do not
8464 * need to be inherited, which seems ok to me]
8467 vm_map_machine_attribute(
8469 vm_map_offset_t start
,
8470 vm_map_offset_t end
,
8471 vm_machine_attribute_t attribute
,
8472 vm_machine_attribute_val_t
* value
) /* IN/OUT */
8475 vm_map_size_t sync_size
;
8476 vm_map_entry_t entry
;
8478 if (start
< vm_map_min(map
) || end
> vm_map_max(map
))
8479 return KERN_INVALID_ADDRESS
;
8481 /* Figure how much memory we need to flush (in page increments) */
8482 sync_size
= end
- start
;
8486 if (attribute
!= MATTR_CACHE
) {
8487 /* If we don't have to find physical addresses, we */
8488 /* don't have to do an explicit traversal here. */
8489 ret
= pmap_attribute(map
->pmap
, start
, end
-start
,
8495 ret
= KERN_SUCCESS
; /* Assume it all worked */
8498 if (vm_map_lookup_entry(map
, start
, &entry
)) {
8499 vm_map_size_t sub_size
;
8500 if((entry
->vme_end
- start
) > sync_size
) {
8501 sub_size
= sync_size
;
8504 sub_size
= entry
->vme_end
- start
;
8505 sync_size
-= sub_size
;
8507 if(entry
->is_sub_map
) {
8508 vm_map_offset_t sub_start
;
8509 vm_map_offset_t sub_end
;
8511 sub_start
= (start
- entry
->vme_start
)
8513 sub_end
= sub_start
+ sub_size
;
8514 vm_map_machine_attribute(
8515 entry
->object
.sub_map
,
8520 if(entry
->object
.vm_object
) {
8523 vm_object_t base_object
;
8524 vm_object_t last_object
;
8525 vm_object_offset_t offset
;
8526 vm_object_offset_t base_offset
;
8527 vm_map_size_t range
;
8529 offset
= (start
- entry
->vme_start
)
8531 base_offset
= offset
;
8532 object
= entry
->object
.vm_object
;
8533 base_object
= object
;
8536 vm_object_lock(object
);
8542 if (m
&& !m
->fictitious
) {
8544 pmap_attribute_cache_sync(
8549 } else if (object
->shadow
) {
8550 offset
= offset
+ object
->shadow_offset
;
8551 last_object
= object
;
8552 object
= object
->shadow
;
8553 vm_object_lock(last_object
->shadow
);
8554 vm_object_unlock(last_object
);
8559 if (base_object
!= object
) {
8560 vm_object_unlock(object
);
8561 vm_object_lock(base_object
);
8562 object
= base_object
;
8564 /* Bump to the next page */
8565 base_offset
+= PAGE_SIZE
;
8566 offset
= base_offset
;
8568 vm_object_unlock(object
);
8574 return KERN_FAILURE
;
8585 * vm_map_behavior_set:
8587 * Sets the paging reference behavior of the specified address
8588 * range in the target map. Paging reference behavior affects
8589 * how pagein operations resulting from faults on the map will be
8593 vm_map_behavior_set(
8595 vm_map_offset_t start
,
8596 vm_map_offset_t end
,
8597 vm_behavior_t new_behavior
)
8599 register vm_map_entry_t entry
;
8600 vm_map_entry_t temp_entry
;
8603 "vm_map_behavior_set, 0x%X start 0x%X end 0x%X behavior %d",
8604 (integer_t
)map
, start
, end
, new_behavior
, 0);
8606 switch (new_behavior
) {
8607 case VM_BEHAVIOR_DEFAULT
:
8608 case VM_BEHAVIOR_RANDOM
:
8609 case VM_BEHAVIOR_SEQUENTIAL
:
8610 case VM_BEHAVIOR_RSEQNTL
:
8612 case VM_BEHAVIOR_WILLNEED
:
8613 case VM_BEHAVIOR_DONTNEED
:
8614 new_behavior
= VM_BEHAVIOR_DEFAULT
;
8617 return(KERN_INVALID_ARGUMENT
);
8623 * The entire address range must be valid for the map.
8624 * Note that vm_map_range_check() does a
8625 * vm_map_lookup_entry() internally and returns the
8626 * entry containing the start of the address range if
8627 * the entire range is valid.
8629 if (vm_map_range_check(map
, start
, end
, &temp_entry
)) {
8631 vm_map_clip_start(map
, entry
, start
);
8635 return(KERN_INVALID_ADDRESS
);
8638 while ((entry
!= vm_map_to_entry(map
)) && (entry
->vme_start
< end
)) {
8639 vm_map_clip_end(map
, entry
, end
);
8641 entry
->behavior
= new_behavior
;
8643 entry
= entry
->vme_next
;
8647 return(KERN_SUCCESS
);
8651 #include <mach_kdb.h>
8653 #include <ddb/db_output.h>
8654 #include <vm/vm_print.h>
8656 #define printf db_printf
8659 * Forward declarations for internal functions.
8661 extern void vm_map_links_print(
8662 struct vm_map_links
*links
);
8664 extern void vm_map_header_print(
8665 struct vm_map_header
*header
);
8667 extern void vm_map_entry_print(
8668 vm_map_entry_t entry
);
8670 extern void vm_follow_entry(
8671 vm_map_entry_t entry
);
8673 extern void vm_follow_map(
8677 * vm_map_links_print: [ debug ]
8681 struct vm_map_links
*links
)
8683 iprintf("prev = %08X next = %08X start = %016llX end = %016llX\n",
8686 (unsigned long long)links
->start
,
8687 (unsigned long long)links
->end
);
8691 * vm_map_header_print: [ debug ]
8694 vm_map_header_print(
8695 struct vm_map_header
*header
)
8697 vm_map_links_print(&header
->links
);
8698 iprintf("nentries = %08X, %sentries_pageable\n",
8700 (header
->entries_pageable
? "" : "!"));
8704 * vm_follow_entry: [ debug ]
8708 vm_map_entry_t entry
)
8712 iprintf("map entry %08X\n", entry
);
8716 shadows
= vm_follow_object(entry
->object
.vm_object
);
8717 iprintf("Total objects : %d\n",shadows
);
8723 * vm_map_entry_print: [ debug ]
8727 register vm_map_entry_t entry
)
8729 static const char *inheritance_name
[4] =
8730 { "share", "copy", "none", "?"};
8731 static const char *behavior_name
[4] =
8732 { "dflt", "rand", "seqtl", "rseqntl" };
8734 iprintf("map entry %08X - prev = %08X next = %08X\n", entry
, entry
->vme_prev
, entry
->vme_next
);
8738 vm_map_links_print(&entry
->links
);
8740 iprintf("start = %016llX end = %016llX - prot=%x/%x/%s\n",
8741 (unsigned long long)entry
->vme_start
,
8742 (unsigned long long)entry
->vme_end
,
8744 entry
->max_protection
,
8745 inheritance_name
[(entry
->inheritance
& 0x3)]);
8747 iprintf("behavior = %s, wired_count = %d, user_wired_count = %d\n",
8748 behavior_name
[(entry
->behavior
& 0x3)],
8750 entry
->user_wired_count
);
8751 iprintf("%sin_transition, %sneeds_wakeup\n",
8752 (entry
->in_transition
? "" : "!"),
8753 (entry
->needs_wakeup
? "" : "!"));
8755 if (entry
->is_sub_map
) {
8756 iprintf("submap = %08X - offset = %016llX\n",
8757 entry
->object
.sub_map
,
8758 (unsigned long long)entry
->offset
);
8760 iprintf("object = %08X offset = %016llX - ",
8761 entry
->object
.vm_object
,
8762 (unsigned long long)entry
->offset
);
8763 printf("%sis_shared, %sneeds_copy\n",
8764 (entry
->is_shared
? "" : "!"),
8765 (entry
->needs_copy
? "" : "!"));
8772 * vm_follow_map: [ debug ]
8778 register vm_map_entry_t entry
;
8780 iprintf("task map %08X\n", map
);
8784 for (entry
= vm_map_first_entry(map
);
8785 entry
&& entry
!= vm_map_to_entry(map
);
8786 entry
= entry
->vme_next
) {
8787 vm_follow_entry(entry
);
8794 * vm_map_print: [ debug ]
8800 register vm_map_entry_t entry
;
8804 #endif /* TASK_SWAPPER */
8806 map
= (vm_map_t
)(long)
8807 inmap
; /* Make sure we have the right type */
8809 iprintf("task map %08X\n", map
);
8813 vm_map_header_print(&map
->hdr
);
8815 iprintf("pmap = %08X size = %08X ref = %d hint = %08X first_free = %08X\n",
8822 iprintf("%swait_for_space, %swiring_required, timestamp = %d\n",
8823 (map
->wait_for_space
? "" : "!"),
8824 (map
->wiring_required
? "" : "!"),
8828 switch (map
->sw_state
) {
8839 iprintf("res = %d, sw_state = %s\n", map
->res_count
, swstate
);
8840 #endif /* TASK_SWAPPER */
8842 for (entry
= vm_map_first_entry(map
);
8843 entry
&& entry
!= vm_map_to_entry(map
);
8844 entry
= entry
->vme_next
) {
8845 vm_map_entry_print(entry
);
8852 * Routine: vm_map_copy_print
8854 * Pretty-print a copy object for ddb.
8862 vm_map_entry_t entry
;
8864 copy
= (vm_map_copy_t
)(long)
8865 incopy
; /* Make sure we have the right type */
8867 printf("copy object 0x%x\n", copy
);
8871 iprintf("type=%d", copy
->type
);
8872 switch (copy
->type
) {
8873 case VM_MAP_COPY_ENTRY_LIST
:
8874 printf("[entry_list]");
8877 case VM_MAP_COPY_OBJECT
:
8881 case VM_MAP_COPY_KERNEL_BUFFER
:
8882 printf("[kernel_buffer]");
8886 printf("[bad type]");
8889 printf(", offset=0x%llx", (unsigned long long)copy
->offset
);
8890 printf(", size=0x%x\n", copy
->size
);
8892 switch (copy
->type
) {
8893 case VM_MAP_COPY_ENTRY_LIST
:
8894 vm_map_header_print(©
->cpy_hdr
);
8895 for (entry
= vm_map_copy_first_entry(copy
);
8896 entry
&& entry
!= vm_map_copy_to_entry(copy
);
8897 entry
= entry
->vme_next
) {
8898 vm_map_entry_print(entry
);
8902 case VM_MAP_COPY_OBJECT
:
8903 iprintf("object=0x%x\n", copy
->cpy_object
);
8906 case VM_MAP_COPY_KERNEL_BUFFER
:
8907 iprintf("kernel buffer=0x%x", copy
->cpy_kdata
);
8908 printf(", kalloc_size=0x%x\n", copy
->cpy_kalloc_size
);
8917 * db_vm_map_total_size(map) [ debug ]
8919 * return the total virtual size (in bytes) of the map
8922 db_vm_map_total_size(
8925 vm_map_entry_t entry
;
8926 vm_map_size_t total
;
8929 map
= (vm_map_t
)(long)
8930 inmap
; /* Make sure we have the right type */
8933 for (entry
= vm_map_first_entry(map
);
8934 entry
!= vm_map_to_entry(map
);
8935 entry
= entry
->vme_next
) {
8936 total
+= entry
->vme_end
- entry
->vme_start
;
8942 #endif /* MACH_KDB */
8945 * Routine: vm_map_entry_insert
8947 * Descritpion: This routine inserts a new vm_entry in a locked map.
8950 vm_map_entry_insert(
8952 vm_map_entry_t insp_entry
,
8953 vm_map_offset_t start
,
8954 vm_map_offset_t end
,
8956 vm_object_offset_t offset
,
8957 boolean_t needs_copy
,
8958 boolean_t is_shared
,
8959 boolean_t in_transition
,
8960 vm_prot_t cur_protection
,
8961 vm_prot_t max_protection
,
8962 vm_behavior_t behavior
,
8963 vm_inherit_t inheritance
,
8964 unsigned wired_count
)
8966 vm_map_entry_t new_entry
;
8968 assert(insp_entry
!= (vm_map_entry_t
)0);
8970 new_entry
= vm_map_entry_create(map
);
8972 new_entry
->vme_start
= start
;
8973 new_entry
->vme_end
= end
;
8974 assert(page_aligned(new_entry
->vme_start
));
8975 assert(page_aligned(new_entry
->vme_end
));
8977 new_entry
->object
.vm_object
= object
;
8978 new_entry
->offset
= offset
;
8979 new_entry
->is_shared
= is_shared
;
8980 new_entry
->is_sub_map
= FALSE
;
8981 new_entry
->needs_copy
= needs_copy
;
8982 new_entry
->in_transition
= in_transition
;
8983 new_entry
->needs_wakeup
= FALSE
;
8984 new_entry
->inheritance
= inheritance
;
8985 new_entry
->protection
= cur_protection
;
8986 new_entry
->max_protection
= max_protection
;
8987 new_entry
->behavior
= behavior
;
8988 new_entry
->wired_count
= wired_count
;
8989 new_entry
->user_wired_count
= 0;
8990 new_entry
->use_pmap
= FALSE
;
8991 new_entry
->alias
= 0;
8994 * Insert the new entry into the list.
8997 vm_map_entry_link(map
, insp_entry
, new_entry
);
8998 map
->size
+= end
- start
;
9001 * Update the free space hint and the lookup hint.
9004 SAVE_HINT_MAP_WRITE(map
, new_entry
);
9009 * Routine: vm_map_remap_extract
9011 * Descritpion: This routine returns a vm_entry list from a map.
9013 static kern_return_t
9014 vm_map_remap_extract(
9016 vm_map_offset_t addr
,
9019 struct vm_map_header
*map_header
,
9020 vm_prot_t
*cur_protection
,
9021 vm_prot_t
*max_protection
,
9022 /* What, no behavior? */
9023 vm_inherit_t inheritance
,
9026 kern_return_t result
;
9027 vm_map_size_t mapped_size
;
9028 vm_map_size_t tmp_size
;
9029 vm_map_entry_t src_entry
; /* result of last map lookup */
9030 vm_map_entry_t new_entry
;
9031 vm_object_offset_t offset
;
9032 vm_map_offset_t map_address
;
9033 vm_map_offset_t src_start
; /* start of entry to map */
9034 vm_map_offset_t src_end
; /* end of region to be mapped */
9036 vm_map_version_t version
;
9037 boolean_t src_needs_copy
;
9038 boolean_t new_entry_needs_copy
;
9040 assert(map
!= VM_MAP_NULL
);
9041 assert(size
!= 0 && size
== vm_map_round_page(size
));
9042 assert(inheritance
== VM_INHERIT_NONE
||
9043 inheritance
== VM_INHERIT_COPY
||
9044 inheritance
== VM_INHERIT_SHARE
);
9047 * Compute start and end of region.
9049 src_start
= vm_map_trunc_page(addr
);
9050 src_end
= vm_map_round_page(src_start
+ size
);
9053 * Initialize map_header.
9055 map_header
->links
.next
= (struct vm_map_entry
*)&map_header
->links
;
9056 map_header
->links
.prev
= (struct vm_map_entry
*)&map_header
->links
;
9057 map_header
->nentries
= 0;
9058 map_header
->entries_pageable
= pageable
;
9060 *cur_protection
= VM_PROT_ALL
;
9061 *max_protection
= VM_PROT_ALL
;
9065 result
= KERN_SUCCESS
;
9068 * The specified source virtual space might correspond to
9069 * multiple map entries, need to loop on them.
9072 while (mapped_size
!= size
) {
9073 vm_map_size_t entry_size
;
9076 * Find the beginning of the region.
9078 if (! vm_map_lookup_entry(map
, src_start
, &src_entry
)) {
9079 result
= KERN_INVALID_ADDRESS
;
9083 if (src_start
< src_entry
->vme_start
||
9084 (mapped_size
&& src_start
!= src_entry
->vme_start
)) {
9085 result
= KERN_INVALID_ADDRESS
;
9089 if(src_entry
->is_sub_map
) {
9090 result
= KERN_INVALID_ADDRESS
;
9094 tmp_size
= size
- mapped_size
;
9095 if (src_end
> src_entry
->vme_end
)
9096 tmp_size
-= (src_end
- src_entry
->vme_end
);
9098 entry_size
= (vm_map_size_t
)(src_entry
->vme_end
-
9099 src_entry
->vme_start
);
9101 if(src_entry
->is_sub_map
) {
9102 vm_map_reference(src_entry
->object
.sub_map
);
9103 object
= VM_OBJECT_NULL
;
9105 object
= src_entry
->object
.vm_object
;
9107 if (object
== VM_OBJECT_NULL
) {
9108 object
= vm_object_allocate(entry_size
);
9109 src_entry
->offset
= 0;
9110 src_entry
->object
.vm_object
= object
;
9111 } else if (object
->copy_strategy
!=
9112 MEMORY_OBJECT_COPY_SYMMETRIC
) {
9114 * We are already using an asymmetric
9115 * copy, and therefore we already have
9118 assert(!src_entry
->needs_copy
);
9119 } else if (src_entry
->needs_copy
|| object
->shadowed
||
9120 (object
->internal
&& !object
->true_share
&&
9121 !src_entry
->is_shared
&&
9122 object
->size
> entry_size
)) {
9124 vm_object_shadow(&src_entry
->object
.vm_object
,
9128 if (!src_entry
->needs_copy
&&
9129 (src_entry
->protection
& VM_PROT_WRITE
)) {
9132 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
9133 #ifdef STACK_ONLY_NX
9134 if (src_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
9135 prot
|= VM_PROT_EXECUTE
;
9138 vm_object_pmap_protect(
9139 src_entry
->object
.vm_object
,
9143 src_entry
->vme_start
,
9146 pmap_protect(vm_map_pmap(map
),
9147 src_entry
->vme_start
,
9153 object
= src_entry
->object
.vm_object
;
9154 src_entry
->needs_copy
= FALSE
;
9158 vm_object_lock(object
);
9159 object
->ref_count
++; /* object ref. for new entry */
9160 VM_OBJ_RES_INCR(object
);
9161 if (object
->copy_strategy
==
9162 MEMORY_OBJECT_COPY_SYMMETRIC
) {
9163 object
->copy_strategy
=
9164 MEMORY_OBJECT_COPY_DELAY
;
9166 vm_object_unlock(object
);
9169 offset
= src_entry
->offset
+ (src_start
- src_entry
->vme_start
);
9171 new_entry
= _vm_map_entry_create(map_header
);
9172 vm_map_entry_copy(new_entry
, src_entry
);
9173 new_entry
->use_pmap
= FALSE
; /* clr address space specifics */
9175 new_entry
->vme_start
= map_address
;
9176 new_entry
->vme_end
= map_address
+ tmp_size
;
9177 new_entry
->inheritance
= inheritance
;
9178 new_entry
->offset
= offset
;
9181 * The new region has to be copied now if required.
9185 src_entry
->is_shared
= TRUE
;
9186 new_entry
->is_shared
= TRUE
;
9187 if (!(new_entry
->is_sub_map
))
9188 new_entry
->needs_copy
= FALSE
;
9190 } else if (src_entry
->is_sub_map
) {
9191 /* make this a COW sub_map if not already */
9192 new_entry
->needs_copy
= TRUE
;
9193 object
= VM_OBJECT_NULL
;
9194 } else if (src_entry
->wired_count
== 0 &&
9195 vm_object_copy_quickly(&new_entry
->object
.vm_object
,
9197 (new_entry
->vme_end
-
9198 new_entry
->vme_start
),
9200 &new_entry_needs_copy
)) {
9202 new_entry
->needs_copy
= new_entry_needs_copy
;
9203 new_entry
->is_shared
= FALSE
;
9206 * Handle copy_on_write semantics.
9208 if (src_needs_copy
&& !src_entry
->needs_copy
) {
9211 prot
= src_entry
->protection
& ~VM_PROT_WRITE
;
9212 #ifdef STACK_ONLY_NX
9213 if (src_entry
->alias
!= VM_MEMORY_STACK
&& prot
)
9214 prot
|= VM_PROT_EXECUTE
;
9216 vm_object_pmap_protect(object
,
9219 ((src_entry
->is_shared
9221 PMAP_NULL
: map
->pmap
),
9222 src_entry
->vme_start
,
9225 src_entry
->needs_copy
= TRUE
;
9228 * Throw away the old object reference of the new entry.
9230 vm_object_deallocate(object
);
9233 new_entry
->is_shared
= FALSE
;
9236 * The map can be safely unlocked since we
9237 * already hold a reference on the object.
9239 * Record the timestamp of the map for later
9240 * verification, and unlock the map.
9242 version
.main_timestamp
= map
->timestamp
;
9243 vm_map_unlock(map
); /* Increments timestamp once! */
9248 if (src_entry
->wired_count
> 0) {
9249 vm_object_lock(object
);
9250 result
= vm_object_copy_slowly(
9255 &new_entry
->object
.vm_object
);
9257 new_entry
->offset
= 0;
9258 new_entry
->needs_copy
= FALSE
;
9260 result
= vm_object_copy_strategically(
9264 &new_entry
->object
.vm_object
,
9266 &new_entry_needs_copy
);
9268 new_entry
->needs_copy
= new_entry_needs_copy
;
9272 * Throw away the old object reference of the new entry.
9274 vm_object_deallocate(object
);
9276 if (result
!= KERN_SUCCESS
&&
9277 result
!= KERN_MEMORY_RESTART_COPY
) {
9278 _vm_map_entry_dispose(map_header
, new_entry
);
9283 * Verify that the map has not substantially
9284 * changed while the copy was being made.
9288 if (version
.main_timestamp
+ 1 != map
->timestamp
) {
9290 * Simple version comparison failed.
9292 * Retry the lookup and verify that the
9293 * same object/offset are still present.
9295 vm_object_deallocate(new_entry
->
9297 _vm_map_entry_dispose(map_header
, new_entry
);
9298 if (result
== KERN_MEMORY_RESTART_COPY
)
9299 result
= KERN_SUCCESS
;
9303 if (result
== KERN_MEMORY_RESTART_COPY
) {
9304 vm_object_reference(object
);
9309 _vm_map_entry_link(map_header
,
9310 map_header
->links
.prev
, new_entry
);
9312 *cur_protection
&= src_entry
->protection
;
9313 *max_protection
&= src_entry
->max_protection
;
9315 map_address
+= tmp_size
;
9316 mapped_size
+= tmp_size
;
9317 src_start
+= tmp_size
;
9322 if (result
!= KERN_SUCCESS
) {
9324 * Free all allocated elements.
9326 for (src_entry
= map_header
->links
.next
;
9327 src_entry
!= (struct vm_map_entry
*)&map_header
->links
;
9328 src_entry
= new_entry
) {
9329 new_entry
= src_entry
->vme_next
;
9330 _vm_map_entry_unlink(map_header
, src_entry
);
9331 vm_object_deallocate(src_entry
->object
.vm_object
);
9332 _vm_map_entry_dispose(map_header
, src_entry
);
9341 * Map portion of a task's address space.
9342 * Mapped region must not overlap more than
9343 * one vm memory object. Protections and
9344 * inheritance attributes remain the same
9345 * as in the original task and are out parameters.
9346 * Source and Target task can be identical
9347 * Other attributes are identical as for vm_map()
9351 vm_map_t target_map
,
9352 vm_map_address_t
*address
,
9354 vm_map_offset_t mask
,
9357 vm_map_offset_t memory_address
,
9359 vm_prot_t
*cur_protection
,
9360 vm_prot_t
*max_protection
,
9361 vm_inherit_t inheritance
)
9363 kern_return_t result
;
9364 vm_map_entry_t entry
;
9365 vm_map_entry_t insp_entry
= VM_MAP_ENTRY_NULL
;
9366 vm_map_entry_t new_entry
;
9367 struct vm_map_header map_header
;
9369 if (target_map
== VM_MAP_NULL
)
9370 return KERN_INVALID_ARGUMENT
;
9372 switch (inheritance
) {
9373 case VM_INHERIT_NONE
:
9374 case VM_INHERIT_COPY
:
9375 case VM_INHERIT_SHARE
:
9376 if (size
!= 0 && src_map
!= VM_MAP_NULL
)
9380 return KERN_INVALID_ARGUMENT
;
9383 size
= vm_map_round_page(size
);
9385 result
= vm_map_remap_extract(src_map
, memory_address
,
9386 size
, copy
, &map_header
,
9393 if (result
!= KERN_SUCCESS
) {
9398 * Allocate/check a range of free virtual address
9399 * space for the target
9401 *address
= vm_map_trunc_page(*address
);
9402 vm_map_lock(target_map
);
9403 result
= vm_map_remap_range_allocate(target_map
, address
, size
,
9404 mask
, anywhere
, &insp_entry
);
9406 for (entry
= map_header
.links
.next
;
9407 entry
!= (struct vm_map_entry
*)&map_header
.links
;
9408 entry
= new_entry
) {
9409 new_entry
= entry
->vme_next
;
9410 _vm_map_entry_unlink(&map_header
, entry
);
9411 if (result
== KERN_SUCCESS
) {
9412 entry
->vme_start
+= *address
;
9413 entry
->vme_end
+= *address
;
9414 vm_map_entry_link(target_map
, insp_entry
, entry
);
9417 if (!entry
->is_sub_map
) {
9418 vm_object_deallocate(entry
->object
.vm_object
);
9420 vm_map_deallocate(entry
->object
.sub_map
);
9422 _vm_map_entry_dispose(&map_header
, entry
);
9426 if (result
== KERN_SUCCESS
) {
9427 target_map
->size
+= size
;
9428 SAVE_HINT_MAP_WRITE(target_map
, insp_entry
);
9430 vm_map_unlock(target_map
);
9432 if (result
== KERN_SUCCESS
&& target_map
->wiring_required
)
9433 result
= vm_map_wire(target_map
, *address
,
9434 *address
+ size
, *cur_protection
, TRUE
);
9439 * Routine: vm_map_remap_range_allocate
9442 * Allocate a range in the specified virtual address map.
9443 * returns the address and the map entry just before the allocated
9446 * Map must be locked.
9449 static kern_return_t
9450 vm_map_remap_range_allocate(
9452 vm_map_address_t
*address
, /* IN/OUT */
9454 vm_map_offset_t mask
,
9456 vm_map_entry_t
*map_entry
) /* OUT */
9458 register vm_map_entry_t entry
;
9459 register vm_map_offset_t start
;
9460 register vm_map_offset_t end
;
9469 * Calculate the first possible address.
9472 if (start
< map
->min_offset
)
9473 start
= map
->min_offset
;
9474 if (start
> map
->max_offset
)
9475 return(KERN_NO_SPACE
);
9478 * Look for the first possible address;
9479 * if there's already something at this
9480 * address, we have to start after it.
9483 assert(first_free_is_valid(map
));
9484 if (start
== map
->min_offset
) {
9485 if ((entry
= map
->first_free
) != vm_map_to_entry(map
))
9486 start
= entry
->vme_end
;
9488 vm_map_entry_t tmp_entry
;
9489 if (vm_map_lookup_entry(map
, start
, &tmp_entry
))
9490 start
= tmp_entry
->vme_end
;
9495 * In any case, the "entry" always precedes
9496 * the proposed new region throughout the
9501 register vm_map_entry_t next
;
9504 * Find the end of the proposed new region.
9505 * Be sure we didn't go beyond the end, or
9506 * wrap around the address.
9509 end
= ((start
+ mask
) & ~mask
);
9511 return(KERN_NO_SPACE
);
9515 if ((end
> map
->max_offset
) || (end
< start
)) {
9516 if (map
->wait_for_space
) {
9517 if (size
<= (map
->max_offset
-
9519 assert_wait((event_t
) map
, THREAD_INTERRUPTIBLE
);
9521 thread_block(THREAD_CONTINUE_NULL
);
9527 return(KERN_NO_SPACE
);
9531 * If there are no more entries, we must win.
9534 next
= entry
->vme_next
;
9535 if (next
== vm_map_to_entry(map
))
9539 * If there is another entry, it must be
9540 * after the end of the potential new region.
9543 if (next
->vme_start
>= end
)
9547 * Didn't fit -- move to the next entry.
9551 start
= entry
->vme_end
;
9555 vm_map_entry_t temp_entry
;
9559 * the address doesn't itself violate
9560 * the mask requirement.
9563 if ((start
& mask
) != 0)
9564 return(KERN_NO_SPACE
);
9568 * ... the address is within bounds
9573 if ((start
< map
->min_offset
) ||
9574 (end
> map
->max_offset
) ||
9576 return(KERN_INVALID_ADDRESS
);
9580 * ... the starting address isn't allocated
9583 if (vm_map_lookup_entry(map
, start
, &temp_entry
))
9584 return(KERN_NO_SPACE
);
9589 * ... the next region doesn't overlap the
9593 if ((entry
->vme_next
!= vm_map_to_entry(map
)) &&
9594 (entry
->vme_next
->vme_start
< end
))
9595 return(KERN_NO_SPACE
);
9598 return(KERN_SUCCESS
);
9604 * Set the address map for the current thread to the specified map
9612 thread_t thread
= current_thread();
9613 vm_map_t oldmap
= thread
->map
;
9615 mp_disable_preemption();
9616 mycpu
= cpu_number();
9619 * Deactivate the current map and activate the requested map
9621 PMAP_SWITCH_USER(thread
, map
, mycpu
);
9623 mp_enable_preemption();
9629 * Routine: vm_map_write_user
9632 * Copy out data from a kernel space into space in the
9633 * destination map. The space must already exist in the
9635 * NOTE: This routine should only be called by threads
9636 * which can block on a page fault. i.e. kernel mode user
9644 vm_map_address_t dst_addr
,
9647 kern_return_t kr
= KERN_SUCCESS
;
9649 if(current_map() == map
) {
9650 if (copyout(src_p
, dst_addr
, size
)) {
9651 kr
= KERN_INVALID_ADDRESS
;
9656 /* take on the identity of the target map while doing */
9659 vm_map_reference(map
);
9660 oldmap
= vm_map_switch(map
);
9661 if (copyout(src_p
, dst_addr
, size
)) {
9662 kr
= KERN_INVALID_ADDRESS
;
9664 vm_map_switch(oldmap
);
9665 vm_map_deallocate(map
);
9671 * Routine: vm_map_read_user
9674 * Copy in data from a user space source map into the
9675 * kernel map. The space must already exist in the
9677 * NOTE: This routine should only be called by threads
9678 * which can block on a page fault. i.e. kernel mode user
9685 vm_map_address_t src_addr
,
9689 kern_return_t kr
= KERN_SUCCESS
;
9691 if(current_map() == map
) {
9692 if (copyin(src_addr
, dst_p
, size
)) {
9693 kr
= KERN_INVALID_ADDRESS
;
9698 /* take on the identity of the target map while doing */
9701 vm_map_reference(map
);
9702 oldmap
= vm_map_switch(map
);
9703 if (copyin(src_addr
, dst_p
, size
)) {
9704 kr
= KERN_INVALID_ADDRESS
;
9706 vm_map_switch(oldmap
);
9707 vm_map_deallocate(map
);
9714 * vm_map_check_protection:
9716 * Assert that the target map allows the specified
9717 * privilege on the entire address region given.
9718 * The entire region must be allocated.
9720 boolean_t
vm_map_check_protection(map
, start
, end
, protection
)
9721 register vm_map_t map
;
9722 register vm_map_offset_t start
;
9723 register vm_map_offset_t end
;
9724 register vm_prot_t protection
;
9726 register vm_map_entry_t entry
;
9727 vm_map_entry_t tmp_entry
;
9731 if (start
< vm_map_min(map
) || end
> vm_map_max(map
) || start
> end
)
9737 if (!vm_map_lookup_entry(map
, start
, &tmp_entry
)) {
9744 while (start
< end
) {
9745 if (entry
== vm_map_to_entry(map
)) {
9754 if (start
< entry
->vme_start
) {
9760 * Check protection associated with entry.
9763 if ((entry
->protection
& protection
) != protection
) {
9768 /* go to next entry */
9770 start
= entry
->vme_end
;
9771 entry
= entry
->vme_next
;
9778 vm_map_purgable_control(
9780 vm_map_offset_t address
,
9781 vm_purgable_t control
,
9784 vm_map_entry_t entry
;
9789 * Vet all the input parameters and current type and state of the
9790 * underlaying object. Return with an error if anything is amiss.
9792 if (map
== VM_MAP_NULL
)
9793 return(KERN_INVALID_ARGUMENT
);
9795 if (control
!= VM_PURGABLE_SET_STATE
&&
9796 control
!= VM_PURGABLE_GET_STATE
)
9797 return(KERN_INVALID_ARGUMENT
);
9799 if (control
== VM_PURGABLE_SET_STATE
&&
9800 (*state
< VM_PURGABLE_STATE_MIN
||
9801 *state
> VM_PURGABLE_STATE_MAX
))
9802 return(KERN_INVALID_ARGUMENT
);
9806 if (!vm_map_lookup_entry(map
, address
, &entry
) || entry
->is_sub_map
) {
9809 * Must pass a valid non-submap address.
9812 return(KERN_INVALID_ADDRESS
);
9815 if ((entry
->protection
& VM_PROT_WRITE
) == 0) {
9817 * Can't apply purgable controls to something you can't write.
9820 return(KERN_PROTECTION_FAILURE
);
9823 object
= entry
->object
.vm_object
;
9824 if (object
== VM_OBJECT_NULL
) {
9826 * Object must already be present or it can't be purgable.
9829 return KERN_INVALID_ARGUMENT
;
9832 vm_object_lock(object
);
9834 if (entry
->offset
!= 0 ||
9835 entry
->vme_end
- entry
->vme_start
!= object
->size
) {
9837 * Can only apply purgable controls to the whole (existing)
9841 vm_object_unlock(object
);
9842 return KERN_INVALID_ARGUMENT
;
9847 kr
= vm_object_purgable_control(object
, control
, state
);
9849 vm_object_unlock(object
);
9856 vm_map_t target_map
,
9857 vm_map_offset_t offset
,
9861 vm_map_entry_t map_entry
;
9868 vm_map_lock(target_map
);
9869 if(!vm_map_lookup_entry(target_map
, offset
, &map_entry
)) {
9870 vm_map_unlock(target_map
);
9871 return KERN_FAILURE
;
9873 offset
-= map_entry
->vme_start
; /* adjust to offset within entry */
9874 offset
+= map_entry
->offset
; /* adjust to target object offset */
9875 if(map_entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
9876 if(!map_entry
->is_sub_map
) {
9877 object
= map_entry
->object
.vm_object
;
9879 vm_map_unlock(target_map
);
9880 target_map
= map_entry
->object
.sub_map
;
9881 goto restart_page_query
;
9884 vm_map_unlock(target_map
);
9885 return KERN_FAILURE
;
9887 vm_object_lock(object
);
9888 vm_map_unlock(target_map
);
9890 m
= vm_page_lookup(object
, offset
);
9891 if (m
!= VM_PAGE_NULL
) {
9892 *disposition
|= VM_PAGE_QUERY_PAGE_PRESENT
;
9895 if(object
->shadow
) {
9896 offset
+= object
->shadow_offset
;
9897 vm_object_unlock(object
);
9898 object
= object
->shadow
;
9899 vm_object_lock(object
);
9902 vm_object_unlock(object
);
9903 return KERN_FAILURE
;
9907 /* The ref_count is not strictly accurate, it measures the number */
9908 /* of entities holding a ref on the object, they may not be mapping */
9909 /* the object or may not be mapping the section holding the */
9910 /* target page but its still a ball park number and though an over- */
9911 /* count, it picks up the copy-on-write cases */
9913 /* We could also get a picture of page sharing from pmap_attributes */
9914 /* but this would under count as only faulted-in mappings would */
9917 *ref_count
= object
->ref_count
;
9919 if (m
->fictitious
) {
9920 *disposition
|= VM_PAGE_QUERY_PAGE_FICTITIOUS
;
9921 vm_object_unlock(object
);
9922 return KERN_SUCCESS
;
9926 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9927 else if(pmap_is_modified(m
->phys_page
))
9928 *disposition
|= VM_PAGE_QUERY_PAGE_DIRTY
;
9931 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9932 else if(pmap_is_referenced(m
->phys_page
))
9933 *disposition
|= VM_PAGE_QUERY_PAGE_REF
;
9935 vm_object_unlock(object
);
9936 return KERN_SUCCESS
;
9941 /* For a given range, check all map entries. If the entry coresponds to */
9942 /* the old vm_region/map provided on the call, replace it with the */
9943 /* corresponding range in the new vm_region/map */
9944 kern_return_t
vm_map_region_replace(
9945 vm_map_t target_map
,
9946 ipc_port_t old_region
,
9947 ipc_port_t new_region
,
9948 vm_map_offset_t start
,
9949 vm_map_offset_t end
)
9951 vm_named_entry_t old_object
;
9952 vm_named_entry_t new_object
;
9953 vm_map_t old_submap
;
9954 vm_map_t new_submap
;
9955 vm_map_offset_t addr
;
9956 vm_map_entry_t entry
;
9957 int nested_pmap
= 0;
9960 vm_map_lock(target_map
);
9961 old_object
= (vm_named_entry_t
)old_region
->ip_kobject
;
9962 new_object
= (vm_named_entry_t
)new_region
->ip_kobject
;
9963 if((!old_object
->is_sub_map
) || (!new_object
->is_sub_map
)) {
9964 vm_map_unlock(target_map
);
9965 return KERN_INVALID_ARGUMENT
;
9967 old_submap
= (vm_map_t
)old_object
->backing
.map
;
9968 new_submap
= (vm_map_t
)new_object
->backing
.map
;
9969 vm_map_lock(old_submap
);
9970 if((old_submap
->min_offset
!= new_submap
->min_offset
) ||
9971 (old_submap
->max_offset
!= new_submap
->max_offset
)) {
9972 vm_map_unlock(old_submap
);
9973 vm_map_unlock(target_map
);
9974 return KERN_INVALID_ARGUMENT
;
9976 if(!vm_map_lookup_entry(target_map
, start
, &entry
)) {
9977 /* if the src is not contained, the entry preceeds */
9979 addr
= entry
->vme_start
;
9980 if(entry
== vm_map_to_entry(target_map
)) {
9981 vm_map_unlock(old_submap
);
9982 vm_map_unlock(target_map
);
9983 return KERN_SUCCESS
;
9986 if ((entry
->use_pmap
) &&
9987 (new_submap
->pmap
== NULL
)) {
9988 new_submap
->pmap
= pmap_create((vm_map_size_t
) 0, FALSE
);
9989 if(new_submap
->pmap
== PMAP_NULL
) {
9990 vm_map_unlock(old_submap
);
9991 vm_map_unlock(target_map
);
9992 return(KERN_NO_SPACE
);
9997 * Mark the new submap as "mapped", so that we get proper
9998 * cleanup of the sub-pmap when we unmap it.
10000 new_submap
->mapped
= TRUE
;
10002 addr
= entry
->vme_start
;
10003 vm_map_reference(old_submap
);
10004 while((entry
!= vm_map_to_entry(target_map
)) &&
10005 (entry
->vme_start
< end
)) {
10006 if((entry
->is_sub_map
) &&
10007 (entry
->object
.sub_map
== old_submap
)) {
10008 if(entry
->use_pmap
) {
10009 if((start
& 0x0fffffff) ||
10010 ((end
- start
) != 0x10000000)) {
10011 vm_map_unlock(old_submap
);
10012 vm_map_deallocate(old_submap
);
10013 vm_map_unlock(target_map
);
10014 return KERN_INVALID_ARGUMENT
;
10018 entry
->object
.sub_map
= new_submap
;
10019 vm_map_reference(new_submap
);
10020 vm_map_deallocate(old_submap
);
10022 entry
= entry
->vme_next
;
10023 addr
= entry
->vme_start
;
10026 #ifndef NO_NESTED_PMAP
10027 pmap_unnest(target_map
->pmap
, (addr64_t
)start
);
10028 if(target_map
->mapped
) {
10029 vm_map_submap_pmap_clean(target_map
,
10030 start
, end
, old_submap
, 0);
10032 pmap_nest(target_map
->pmap
, new_submap
->pmap
,
10033 (addr64_t
)start
, (addr64_t
)start
,
10034 (uint64_t)(end
- start
));
10035 #endif /* NO_NESTED_PMAP */
10037 vm_map_submap_pmap_clean(target_map
,
10038 start
, end
, old_submap
, 0);
10040 vm_map_unlock(old_submap
);
10041 vm_map_deallocate(old_submap
);
10042 vm_map_unlock(target_map
);
10043 return KERN_SUCCESS
;
10049 * Synchronises the memory range specified with its backing store
10050 * image by either flushing or cleaning the contents to the appropriate
10051 * memory manager engaging in a memory object synchronize dialog with
10052 * the manager. The client doesn't return until the manager issues
10053 * m_o_s_completed message. MIG Magically converts user task parameter
10054 * to the task's address map.
10056 * interpretation of sync_flags
10057 * VM_SYNC_INVALIDATE - discard pages, only return precious
10058 * pages to manager.
10060 * VM_SYNC_INVALIDATE & (VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS)
10061 * - discard pages, write dirty or precious
10062 * pages back to memory manager.
10064 * VM_SYNC_SYNCHRONOUS | VM_SYNC_ASYNCHRONOUS
10065 * - write dirty or precious pages back to
10066 * the memory manager.
10068 * VM_SYNC_CONTIGUOUS - does everything normally, but if there
10069 * is a hole in the region, and we would
10070 * have returned KERN_SUCCESS, return
10071 * KERN_INVALID_ADDRESS instead.
10074 * The memory object attributes have not yet been implemented, this
10075 * function will have to deal with the invalidate attribute
10078 * KERN_INVALID_TASK Bad task parameter
10079 * KERN_INVALID_ARGUMENT both sync and async were specified.
10080 * KERN_SUCCESS The usual.
10081 * KERN_INVALID_ADDRESS There was a hole in the region.
10087 vm_map_address_t address
,
10088 vm_map_size_t size
,
10089 vm_sync_t sync_flags
)
10092 msync_req_t new_msr
;
10093 queue_chain_t req_q
; /* queue of requests for this msync */
10094 vm_map_entry_t entry
;
10095 vm_map_size_t amount_left
;
10096 vm_object_offset_t offset
;
10097 boolean_t do_sync_req
;
10098 boolean_t modifiable
;
10099 boolean_t had_hole
= FALSE
;
10101 if ((sync_flags
& VM_SYNC_ASYNCHRONOUS
) &&
10102 (sync_flags
& VM_SYNC_SYNCHRONOUS
))
10103 return(KERN_INVALID_ARGUMENT
);
10106 * align address and size on page boundaries
10108 size
= vm_map_round_page(address
+ size
) - vm_map_trunc_page(address
);
10109 address
= vm_map_trunc_page(address
);
10111 if (map
== VM_MAP_NULL
)
10112 return(KERN_INVALID_TASK
);
10115 return(KERN_SUCCESS
);
10117 queue_init(&req_q
);
10118 amount_left
= size
;
10120 while (amount_left
> 0) {
10121 vm_object_size_t flush_size
;
10122 vm_object_t object
;
10125 if (!vm_map_lookup_entry(map
,
10126 vm_map_trunc_page(address
), &entry
)) {
10131 * hole in the address map.
10136 * Check for empty map.
10138 if (entry
== vm_map_to_entry(map
) &&
10139 entry
->vme_next
== entry
) {
10140 vm_map_unlock(map
);
10144 * Check that we don't wrap and that
10145 * we have at least one real map entry.
10147 if ((map
->hdr
.nentries
== 0) ||
10148 (entry
->vme_next
->vme_start
< address
)) {
10149 vm_map_unlock(map
);
10153 * Move up to the next entry if needed
10155 skip
= (entry
->vme_next
->vme_start
- address
);
10156 if (skip
>= amount_left
)
10159 amount_left
-= skip
;
10160 address
= entry
->vme_next
->vme_start
;
10161 vm_map_unlock(map
);
10165 offset
= address
- entry
->vme_start
;
10168 * do we have more to flush than is contained in this
10171 if (amount_left
+ entry
->vme_start
+ offset
> entry
->vme_end
) {
10172 flush_size
= entry
->vme_end
-
10173 (entry
->vme_start
+ offset
);
10175 flush_size
= amount_left
;
10177 amount_left
-= flush_size
;
10178 address
+= flush_size
;
10180 if (entry
->is_sub_map
== TRUE
) {
10181 vm_map_t local_map
;
10182 vm_map_offset_t local_offset
;
10184 local_map
= entry
->object
.sub_map
;
10185 local_offset
= entry
->offset
;
10186 vm_map_unlock(map
);
10191 sync_flags
) == KERN_INVALID_ADDRESS
) {
10196 object
= entry
->object
.vm_object
;
10199 * We can't sync this object if the object has not been
10202 if (object
== VM_OBJECT_NULL
) {
10203 vm_map_unlock(map
);
10206 offset
+= entry
->offset
;
10207 modifiable
= (entry
->protection
& VM_PROT_WRITE
)
10210 vm_object_lock(object
);
10212 if (sync_flags
& (VM_SYNC_KILLPAGES
| VM_SYNC_DEACTIVATE
)) {
10213 boolean_t kill_pages
= 0;
10215 if (sync_flags
& VM_SYNC_KILLPAGES
) {
10216 if (object
->ref_count
== 1 && !entry
->needs_copy
&& !object
->shadow
)
10221 if (kill_pages
!= -1)
10222 vm_object_deactivate_pages(object
, offset
,
10223 (vm_object_size_t
)flush_size
, kill_pages
);
10224 vm_object_unlock(object
);
10225 vm_map_unlock(map
);
10229 * We can't sync this object if there isn't a pager.
10230 * Don't bother to sync internal objects, since there can't
10231 * be any "permanent" storage for these objects anyway.
10233 if ((object
->pager
== MEMORY_OBJECT_NULL
) ||
10234 (object
->internal
) || (object
->private)) {
10235 vm_object_unlock(object
);
10236 vm_map_unlock(map
);
10240 * keep reference on the object until syncing is done
10242 assert(object
->ref_count
> 0);
10243 object
->ref_count
++;
10244 vm_object_res_reference(object
);
10245 vm_object_unlock(object
);
10247 vm_map_unlock(map
);
10249 do_sync_req
= vm_object_sync(object
,
10252 sync_flags
& VM_SYNC_INVALIDATE
,
10254 (sync_flags
& VM_SYNC_SYNCHRONOUS
||
10255 sync_flags
& VM_SYNC_ASYNCHRONOUS
)),
10256 sync_flags
& VM_SYNC_SYNCHRONOUS
);
10258 * only send a m_o_s if we returned pages or if the entry
10259 * is writable (ie dirty pages may have already been sent back)
10261 if (!do_sync_req
&& !modifiable
) {
10262 vm_object_deallocate(object
);
10265 msync_req_alloc(new_msr
);
10267 vm_object_lock(object
);
10268 offset
+= object
->paging_offset
;
10270 new_msr
->offset
= offset
;
10271 new_msr
->length
= flush_size
;
10272 new_msr
->object
= object
;
10273 new_msr
->flag
= VM_MSYNC_SYNCHRONIZING
;
10275 queue_iterate(&object
->msr_q
, msr
, msync_req_t
, msr_q
) {
10277 * need to check for overlapping entry, if found, wait
10278 * on overlapping msr to be done, then reiterate
10281 if (msr
->flag
== VM_MSYNC_SYNCHRONIZING
&&
10282 ((offset
>= msr
->offset
&&
10283 offset
< (msr
->offset
+ msr
->length
)) ||
10284 (msr
->offset
>= offset
&&
10285 msr
->offset
< (offset
+ flush_size
))))
10287 assert_wait((event_t
) msr
,THREAD_INTERRUPTIBLE
);
10289 vm_object_unlock(object
);
10290 thread_block(THREAD_CONTINUE_NULL
);
10291 vm_object_lock(object
);
10295 }/* queue_iterate */
10297 queue_enter(&object
->msr_q
, new_msr
, msync_req_t
, msr_q
);
10298 vm_object_unlock(object
);
10300 queue_enter(&req_q
, new_msr
, msync_req_t
, req_q
);
10302 (void) memory_object_synchronize(
10306 sync_flags
& ~VM_SYNC_CONTIGUOUS
);
10310 * wait for memory_object_sychronize_completed messages from pager(s)
10313 while (!queue_empty(&req_q
)) {
10314 msr
= (msync_req_t
)queue_first(&req_q
);
10316 while(msr
->flag
!= VM_MSYNC_DONE
) {
10317 assert_wait((event_t
) msr
, THREAD_INTERRUPTIBLE
);
10319 thread_block(THREAD_CONTINUE_NULL
);
10322 queue_remove(&req_q
, msr
, msync_req_t
, req_q
);
10324 vm_object_deallocate(msr
->object
);
10325 msync_req_free(msr
);
10326 }/* queue_iterate */
10328 /* for proper msync() behaviour */
10329 if (had_hole
== TRUE
&& (sync_flags
& VM_SYNC_CONTIGUOUS
))
10330 return(KERN_INVALID_ADDRESS
);
10332 return(KERN_SUCCESS
);
10335 /* Takes existing source and destination sub-maps and clones the contents of */
10336 /* the source map */
10339 ipc_port_t src_region
,
10340 ipc_port_t dst_region
)
10342 vm_named_entry_t src_object
;
10343 vm_named_entry_t dst_object
;
10346 vm_map_offset_t addr
;
10347 vm_map_offset_t max_off
;
10348 vm_map_entry_t entry
;
10349 vm_map_entry_t new_entry
;
10350 vm_map_entry_t insert_point
;
10352 src_object
= (vm_named_entry_t
)src_region
->ip_kobject
;
10353 dst_object
= (vm_named_entry_t
)dst_region
->ip_kobject
;
10354 if((!src_object
->is_sub_map
) || (!dst_object
->is_sub_map
)) {
10355 return KERN_INVALID_ARGUMENT
;
10357 src_map
= (vm_map_t
)src_object
->backing
.map
;
10358 dst_map
= (vm_map_t
)dst_object
->backing
.map
;
10359 /* destination map is assumed to be unavailable to any other */
10360 /* activity. i.e. it is new */
10361 vm_map_lock(src_map
);
10362 if((src_map
->min_offset
!= dst_map
->min_offset
)
10363 || (src_map
->max_offset
!= dst_map
->max_offset
)) {
10364 vm_map_unlock(src_map
);
10365 return KERN_INVALID_ARGUMENT
;
10367 addr
= src_map
->min_offset
;
10368 vm_map_lookup_entry(dst_map
, addr
, &entry
);
10369 if(entry
== vm_map_to_entry(dst_map
)) {
10370 entry
= entry
->vme_next
;
10372 if(entry
== vm_map_to_entry(dst_map
)) {
10373 max_off
= src_map
->max_offset
;
10375 max_off
= entry
->vme_start
;
10377 vm_map_lookup_entry(src_map
, addr
, &entry
);
10378 if(entry
== vm_map_to_entry(src_map
)) {
10379 entry
= entry
->vme_next
;
10381 vm_map_lookup_entry(dst_map
, addr
, &insert_point
);
10382 while((entry
!= vm_map_to_entry(src_map
)) &&
10383 (entry
->vme_end
<= max_off
)) {
10384 addr
= entry
->vme_start
;
10385 new_entry
= vm_map_entry_create(dst_map
);
10386 vm_map_entry_copy(new_entry
, entry
);
10387 vm_map_entry_link(dst_map
, insert_point
, new_entry
);
10388 insert_point
= new_entry
;
10389 if (entry
->object
.vm_object
!= VM_OBJECT_NULL
) {
10390 if (new_entry
->is_sub_map
) {
10391 vm_map_reference(new_entry
->object
.sub_map
);
10393 vm_object_reference(
10394 new_entry
->object
.vm_object
);
10397 dst_map
->size
+= new_entry
->vme_end
- new_entry
->vme_start
;
10398 entry
= entry
->vme_next
;
10400 vm_map_unlock(src_map
);
10401 return KERN_SUCCESS
;
10405 * Routine: convert_port_entry_to_map
10407 * Convert from a port specifying an entry or a task
10408 * to a map. Doesn't consume the port ref; produces a map ref,
10409 * which may be null. Unlike convert_port_to_map, the
10410 * port may be task or a named entry backed.
10417 convert_port_entry_to_map(
10421 vm_named_entry_t named_entry
;
10423 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10426 if(ip_active(port
) && (ip_kotype(port
)
10427 == IKOT_NAMED_ENTRY
)) {
10429 (vm_named_entry_t
)port
->ip_kobject
;
10430 if (!(mutex_try(&(named_entry
)->Lock
))) {
10435 named_entry
->ref_count
++;
10436 mutex_unlock(&(named_entry
)->Lock
);
10438 if ((named_entry
->is_sub_map
) &&
10439 (named_entry
->protection
10440 & VM_PROT_WRITE
)) {
10441 map
= named_entry
->backing
.map
;
10443 mach_destroy_memory_entry(port
);
10444 return VM_MAP_NULL
;
10446 vm_map_reference_swap(map
);
10447 mach_destroy_memory_entry(port
);
10451 return VM_MAP_NULL
;
10455 map
= convert_port_to_map(port
);
10461 * Routine: convert_port_entry_to_object
10463 * Convert from a port specifying a named entry to an
10464 * object. Doesn't consume the port ref; produces a map ref,
10465 * which may be null.
10472 convert_port_entry_to_object(
10475 vm_object_t object
;
10476 vm_named_entry_t named_entry
;
10478 if(IP_VALID(port
) && (ip_kotype(port
) == IKOT_NAMED_ENTRY
)) {
10481 if(ip_active(port
) && (ip_kotype(port
)
10482 == IKOT_NAMED_ENTRY
)) {
10484 (vm_named_entry_t
)port
->ip_kobject
;
10485 if (!(mutex_try(&(named_entry
)->Lock
))) {
10490 named_entry
->ref_count
++;
10491 mutex_unlock(&(named_entry
)->Lock
);
10493 if ((!named_entry
->is_sub_map
) &&
10494 (!named_entry
->is_pager
) &&
10495 (named_entry
->protection
10496 & VM_PROT_WRITE
)) {
10497 object
= named_entry
->backing
.object
;
10499 mach_destroy_memory_entry(port
);
10500 return (vm_object_t
)NULL
;
10502 vm_object_reference(named_entry
->backing
.object
);
10503 mach_destroy_memory_entry(port
);
10507 return (vm_object_t
)NULL
;
10510 return (vm_object_t
)NULL
;
10517 * Export routines to other components for the things we access locally through
10524 return (current_map_fast());
10528 * vm_map_reference:
10530 * Most code internal to the osfmk will go through a
10531 * macro defining this. This is always here for the
10532 * use of other kernel components.
10534 #undef vm_map_reference
10537 register vm_map_t map
)
10539 if (map
== VM_MAP_NULL
)
10542 mutex_lock(&map
->s_lock
);
10544 assert(map
->res_count
> 0);
10545 assert(map
->ref_count
>= map
->res_count
);
10549 mutex_unlock(&map
->s_lock
);
10553 * vm_map_deallocate:
10555 * Removes a reference from the specified map,
10556 * destroying it if no references remain.
10557 * The map should not be locked.
10561 register vm_map_t map
)
10565 if (map
== VM_MAP_NULL
)
10568 mutex_lock(&map
->s_lock
);
10569 ref
= --map
->ref_count
;
10571 vm_map_res_deallocate(map
);
10572 mutex_unlock(&map
->s_lock
);
10575 assert(map
->ref_count
== 0);
10576 mutex_unlock(&map
->s_lock
);
10580 * The map residence count isn't decremented here because
10581 * the vm_map_delete below will traverse the entire map,
10582 * deleting entries, and the residence counts on objects
10583 * and sharing maps will go away then.
10587 vm_map_destroy(map
);
10591 /* LP64todo - this whole mechanism is temporary. It should be redone when
10592 * the pmap layer can handle 64-bit address spaces. Until then, we trump
10593 * up a map entry for the 64-bit commpage above the map's max_offset.
10595 extern vm_map_t com_region_map64
; /* the submap for 64-bit commpage */
10596 extern vm_map_t com_region_map32
; /* the submap for 32-bit commpage */
10602 vm_map_t com_region_map
, /* com_region_map32 or com_region_map64 */
10603 vm_map_offset_t base_address
,
10604 vm_map_size_t size
)
10606 vm_map_entry_t entry
;
10607 vm_object_t object
;
10609 vm_map_lock(user_map
);
10611 /* The commpage is necessarily the last entry in the map.
10612 * See if one is already there (not sure if this can happen???)
10614 entry
= vm_map_last_entry(user_map
);
10615 if (entry
!= vm_map_to_entry(user_map
)) {
10616 if (entry
->vme_end
>= base_address
) {
10617 vm_map_unlock(user_map
);
10622 entry
= vm_map_first_entry(com_region_map
);
10623 object
= entry
->object
.vm_object
;
10624 vm_object_reference(object
);
10626 /* We bypass vm_map_enter() because we are adding the entry past the
10627 * map's max_offset.
10629 entry
= vm_map_entry_insert(
10631 vm_map_last_entry(user_map
), /* insert after last entry */
10633 base_address
+ size
,
10636 FALSE
, /* needs_copy */
10637 FALSE
, /* is_shared */
10638 FALSE
, /* in_transition */
10639 VM_PROT_READ
|VM_PROT_EXECUTE
,
10640 VM_PROT_READ
|VM_PROT_EXECUTE
,
10641 VM_BEHAVIOR_DEFAULT
,
10643 1 ); /* wired_count */
10645 vm_map_unlock(user_map
);
10653 vm_map_commpage(map
,
10655 (vm_map_offset_t
) (unsigned) _COMM_PAGE32_BASE_ADDRESS
,
10656 (vm_map_size_t
) (unsigned) _COMM_PAGE32_AREA_USED
);
10658 #endif /* __i386__ */
10667 vm_map_commpage(map
,
10669 (vm_map_offset_t
) _COMM_PAGE64_BASE_ADDRESS
,
10670 (vm_map_size_t
) _COMM_PAGE64_AREA_USED
);
10674 vm_map_remove_commpage(
10677 vm_map_entry_t entry
;
10682 entry
= vm_map_last_entry(map
);
10684 if ((entry
== vm_map_to_entry(map
)) ||
10685 (entry
->vme_start
< map
->max_offset
))
10688 /* clearing the wired count isn't strictly correct */
10689 entry
->wired_count
= 0;
10690 vm_map_entry_delete(map
,entry
);
10693 vm_map_unlock(map
);
10697 vm_map_disable_NX(vm_map_t map
)
10701 if (map
->pmap
== NULL
)
10704 pmap_disable_NX(map
->pmap
);
10707 /* XXX Consider making these constants (VM_MAX_ADDRESS and MACH_VM_MAX_ADDRESS)
10708 * more descriptive.
10711 vm_map_set_32bit(vm_map_t map
)
10713 map
->max_offset
= (vm_map_offset_t
)VM_MAX_ADDRESS
;
10718 vm_map_set_64bit(vm_map_t map
)
10720 map
->max_offset
= (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
;
10724 vm_compute_max_offset(unsigned is64
)
10726 return (is64
? (vm_map_offset_t
)MACH_VM_MAX_ADDRESS
: (vm_map_offset_t
)VM_MAX_ADDRESS
);
10730 vm_map_has_4GB_pagezero(vm_map_t map
)
10734 * We should lock the VM map (for read) here but we can get away
10735 * with it for now because there can't really be any race condition:
10736 * the VM map's min_offset is changed only when the VM map is created
10737 * and when the zero page is established (when the binary gets loaded),
10738 * and this routine gets called only when the task terminates and the
10739 * VM map is being torn down, and when a new map is created via
10740 * load_machfile()/execve().
10742 return (map
->min_offset
>= 0x100000000ULL
);
10746 vm_map_set_4GB_pagezero(vm_map_t map
)
10748 pmap_set_4GB_pagezero(map
->pmap
);
10752 vm_map_clear_4GB_pagezero(vm_map_t map
)
10754 pmap_clear_4GB_pagezero(map
->pmap
);
10758 * Raise a VM map's minimum offset.
10759 * To strictly enforce "page zero" reservation.
10762 vm_map_raise_min_offset(
10764 vm_map_offset_t new_min_offset
)
10766 vm_map_entry_t first_entry
;
10768 new_min_offset
= vm_map_round_page(new_min_offset
);
10772 if (new_min_offset
< map
->min_offset
) {
10774 * Can't move min_offset backwards, as that would expose
10775 * a part of the address space that was previously, and for
10776 * possibly good reasons, inaccessible.
10778 vm_map_unlock(map
);
10779 return KERN_INVALID_ADDRESS
;
10782 first_entry
= vm_map_first_entry(map
);
10783 if (first_entry
!= vm_map_to_entry(map
) &&
10784 first_entry
->vme_start
< new_min_offset
) {
10786 * Some memory was already allocated below the new
10787 * minimun offset. It's too late to change it now...
10789 vm_map_unlock(map
);
10790 return KERN_NO_SPACE
;
10793 map
->min_offset
= new_min_offset
;
10795 vm_map_unlock(map
);
10797 return KERN_SUCCESS
;