xref: /xnu-8796.101.5/osfmk/vm/vm32_user.c (revision aca3beaa3dfbd42498b42c5e5ce20a938e6554e5)
1 /*
2  * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
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.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
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.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*
29  * @OSF_COPYRIGHT@
30  */
31 /*
32  * Mach Operating System
33  * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
34  * All Rights Reserved.
35  *
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.
41  *
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.
45  *
46  * Carnegie Mellon requests users of this software to return to
47  *
48  *  Software Distribution Coordinator  or  [email protected]
49  *  School of Computer Science
50  *  Carnegie Mellon University
51  *  Pittsburgh PA 15213-3890
52  *
53  * any improvements or extensions that they make and grant Carnegie Mellon
54  * the rights to redistribute these changes.
55  */
56 /*
57  */
58 /*
59  *	File:	vm/vm32_user.c
60  *	Author:	Avadis Tevanian, Jr., Michael Wayne Young
61  *
62  *	User-exported virtual memory functions.
63  */
64 
65 #include <debug.h>
66 
67 #include <mach/boolean.h>
68 #include <mach/kern_return.h>
69 #include <mach/mach_types.h>    /* to get vm_address_t */
70 #include <mach/memory_object.h>
71 #include <mach/std_types.h>     /* to get pointer_t */
72 #include <mach/vm_attributes.h>
73 #include <mach/vm_param.h>
74 #include <mach/vm_statistics.h>
75 #include <mach/mach_syscalls.h>
76 
77 #include <mach/host_priv_server.h>
78 #include <mach/mach_vm_server.h>
79 #include <mach/vm32_map_server.h>
80 
81 #include <kern/host.h>
82 #include <kern/task.h>
83 #include <kern/misc_protos.h>
84 #include <vm/vm_fault.h>
85 #include <vm/vm_map.h>
86 #include <vm/vm_object.h>
87 #include <vm/vm_page.h>
88 #include <vm/memory_object.h>
89 #include <vm/vm_pageout.h>
90 #include <vm/vm_protos.h>
91 
92 #ifdef VM32_SUPPORT
93 
94 /*
95  * See vm_user.c for the real implementation of all of these functions.
96  * We call through to the mach_ "wide" versions of the routines, and trust
97  * that the VM system verifies the arguments and only returns address that
98  * are appropriate for the task's address space size.
99  *
100  * New VM call implementations should not be added here, because they would
101  * be available only to 32-bit userspace clients. Add them to vm_user.c
102  * and the corresponding prototype to mach_vm.defs (subsystem 4800).
103  */
104 
105 kern_return_t
vm32_allocate(vm_map_t map,vm32_offset_t * addr,vm32_size_t size,int flags)106 vm32_allocate(
107 	vm_map_t        map,
108 	vm32_offset_t   *addr,
109 	vm32_size_t     size,
110 	int             flags)
111 {
112 	mach_vm_offset_t        maddr;
113 	kern_return_t           result;
114 
115 	maddr = *addr;
116 	result = mach_vm_allocate_external(map, &maddr, size, flags);
117 	*addr = CAST_DOWN_EXPLICIT(vm32_offset_t, maddr);
118 
119 	return result;
120 }
121 
122 kern_return_t
vm32_deallocate(vm_map_t map,vm32_offset_t start,vm32_size_t size)123 vm32_deallocate(
124 	vm_map_t        map,
125 	vm32_offset_t           start,
126 	vm32_size_t             size)
127 {
128 	if ((map == VM_MAP_NULL) || (start + size < start)) {
129 		return KERN_INVALID_ARGUMENT;
130 	}
131 
132 	return mach_vm_deallocate(map, start, size);
133 }
134 
135 kern_return_t
vm32_inherit(vm_map_t map,vm32_offset_t start,vm32_size_t size,vm_inherit_t new_inheritance)136 vm32_inherit(
137 	vm_map_t        map,
138 	vm32_offset_t           start,
139 	vm32_size_t             size,
140 	vm_inherit_t            new_inheritance)
141 {
142 	if ((map == VM_MAP_NULL) || (start + size < start)) {
143 		return KERN_INVALID_ARGUMENT;
144 	}
145 
146 	return mach_vm_inherit(map, start, size, new_inheritance);
147 }
148 
149 kern_return_t
vm32_protect(vm_map_t map,vm32_offset_t start,vm32_size_t size,boolean_t set_maximum,vm_prot_t new_protection)150 vm32_protect(
151 	vm_map_t                map,
152 	vm32_offset_t           start,
153 	vm32_size_t             size,
154 	boolean_t               set_maximum,
155 	vm_prot_t               new_protection)
156 {
157 	if ((map == VM_MAP_NULL) || (start + size < start)) {
158 		return KERN_INVALID_ARGUMENT;
159 	}
160 
161 	return mach_vm_protect(map, start, size, set_maximum, new_protection);
162 }
163 
164 kern_return_t
vm32_machine_attribute(vm_map_t map,vm32_address_t addr,vm32_size_t size,vm_machine_attribute_t attribute,vm_machine_attribute_val_t * value)165 vm32_machine_attribute(
166 	vm_map_t        map,
167 	vm32_address_t  addr,
168 	vm32_size_t     size,
169 	vm_machine_attribute_t  attribute,
170 	vm_machine_attribute_val_t* value)              /* IN/OUT */
171 {
172 	if ((map == VM_MAP_NULL) || (addr + size < addr)) {
173 		return KERN_INVALID_ARGUMENT;
174 	}
175 
176 	return mach_vm_machine_attribute(map, addr, size, attribute, value);
177 }
178 
179 kern_return_t
vm32_read(vm_map_t map,vm32_address_t addr,vm32_size_t size,pointer_t * data,mach_msg_type_number_t * data_size)180 vm32_read(
181 	vm_map_t                map,
182 	vm32_address_t          addr,
183 	vm32_size_t             size,
184 	pointer_t               *data,
185 	mach_msg_type_number_t  *data_size)
186 {
187 	return mach_vm_read(map, addr, size, data, data_size);
188 }
189 
190 kern_return_t
vm32_read_list(vm_map_t map,vm32_read_entry_t data_list,natural_t count)191 vm32_read_list(
192 	vm_map_t                map,
193 	vm32_read_entry_t       data_list,
194 	natural_t               count)
195 {
196 	mach_vm_read_entry_t    mdata_list;
197 	mach_msg_type_number_t  i;
198 	kern_return_t                   result;
199 
200 	for (i = 0; i < VM_MAP_ENTRY_MAX; i++) {
201 		mdata_list[i].address = data_list[i].address;
202 		mdata_list[i].size = data_list[i].size;
203 	}
204 
205 	result = mach_vm_read_list(map, mdata_list, count);
206 
207 	for (i = 0; i < VM_MAP_ENTRY_MAX; i++) {
208 		data_list[i].address = CAST_DOWN_EXPLICIT(vm32_address_t, mdata_list[i].address);
209 		data_list[i].size = CAST_DOWN_EXPLICIT(vm32_size_t, mdata_list[i].size);
210 	}
211 
212 	return result;
213 }
214 
215 kern_return_t
vm32_read_overwrite(vm_map_t map,vm32_address_t address,vm32_size_t size,vm32_address_t data,vm32_size_t * data_size)216 vm32_read_overwrite(
217 	vm_map_t        map,
218 	vm32_address_t  address,
219 	vm32_size_t     size,
220 	vm32_address_t  data,
221 	vm32_size_t     *data_size)
222 {
223 	kern_return_t   result;
224 	mach_vm_size_t  mdata_size;
225 
226 	mdata_size = *data_size;
227 	result = mach_vm_read_overwrite(map, address, size, data, &mdata_size);
228 	*data_size = CAST_DOWN_EXPLICIT(vm32_size_t, mdata_size);
229 
230 	return result;
231 }
232 
233 kern_return_t
vm32_write(vm_map_t map,vm32_address_t address,pointer_t data,mach_msg_type_number_t size)234 vm32_write(
235 	vm_map_t                        map,
236 	vm32_address_t                  address,
237 	pointer_t                       data,
238 	mach_msg_type_number_t  size)
239 {
240 	return mach_vm_write(map, address, data, size);
241 }
242 
243 kern_return_t
vm32_copy(vm_map_t map,vm32_address_t source_address,vm32_size_t size,vm32_address_t dest_address)244 vm32_copy(
245 	vm_map_t        map,
246 	vm32_address_t  source_address,
247 	vm32_size_t     size,
248 	vm32_address_t  dest_address)
249 {
250 	return mach_vm_copy(map, source_address, size, dest_address);
251 }
252 
253 kern_return_t
vm32_map_64(vm_map_t target_map,vm32_offset_t * address,vm32_size_t size,vm32_offset_t mask,int flags,ipc_port_t port,vm_object_offset_t offset,boolean_t copy,vm_prot_t cur_protection,vm_prot_t max_protection,vm_inherit_t inheritance)254 vm32_map_64(
255 	vm_map_t                target_map,
256 	vm32_offset_t           *address,
257 	vm32_size_t             size,
258 	vm32_offset_t           mask,
259 	int                     flags,
260 	ipc_port_t              port,
261 	vm_object_offset_t      offset,
262 	boolean_t               copy,
263 	vm_prot_t               cur_protection,
264 	vm_prot_t               max_protection,
265 	vm_inherit_t            inheritance)
266 {
267 	mach_vm_offset_t        maddress;
268 	kern_return_t           result;
269 
270 	maddress = *address;
271 	result = mach_vm_map_external(target_map, &maddress, size, mask,
272 	    flags, port, offset, copy,
273 	    cur_protection, max_protection, inheritance);
274 	*address = CAST_DOWN_EXPLICIT(vm32_offset_t, maddress);
275 
276 	return result;
277 }
278 
279 kern_return_t
vm32_map(vm_map_t target_map,vm32_offset_t * address,vm32_size_t size,vm32_offset_t mask,int flags,ipc_port_t port,vm32_offset_t offset,boolean_t copy,vm_prot_t cur_protection,vm_prot_t max_protection,vm_inherit_t inheritance)280 vm32_map(
281 	vm_map_t                target_map,
282 	vm32_offset_t           *address,
283 	vm32_size_t             size,
284 	vm32_offset_t           mask,
285 	int                     flags,
286 	ipc_port_t              port,
287 	vm32_offset_t           offset,
288 	boolean_t               copy,
289 	vm_prot_t               cur_protection,
290 	vm_prot_t               max_protection,
291 	vm_inherit_t            inheritance)
292 {
293 	return vm32_map_64(target_map, address, size, mask,
294 	           flags, port, offset, copy,
295 	           cur_protection, max_protection, inheritance);
296 }
297 
298 kern_return_t
vm32_remap(vm_map_t target_map,vm32_offset_t * address,vm32_size_t size,vm32_offset_t mask,boolean_t anywhere,vm_map_t src_map,vm32_offset_t memory_address,boolean_t copy,vm_prot_t * cur_protection,vm_prot_t * max_protection,vm_inherit_t inheritance)299 vm32_remap(
300 	vm_map_t                target_map,
301 	vm32_offset_t           *address,
302 	vm32_size_t             size,
303 	vm32_offset_t           mask,
304 	boolean_t               anywhere,
305 	vm_map_t                src_map,
306 	vm32_offset_t           memory_address,
307 	boolean_t               copy,
308 	vm_prot_t               *cur_protection,
309 	vm_prot_t               *max_protection,
310 	vm_inherit_t            inheritance)
311 {
312 	mach_vm_offset_t        maddress;
313 	kern_return_t           result;
314 
315 	maddress = *address;
316 	result = mach_vm_remap_external(target_map, &maddress, size, mask,
317 	    anywhere, src_map, memory_address, copy,
318 	    cur_protection, max_protection, inheritance);
319 	*address = CAST_DOWN_EXPLICIT(vm32_offset_t, maddress);
320 
321 	return result;
322 }
323 
324 kern_return_t
vm32_msync(vm_map_t map,vm32_address_t address,vm32_size_t size,vm_sync_t sync_flags)325 vm32_msync(
326 	vm_map_t        map,
327 	vm32_address_t  address,
328 	vm32_size_t     size,
329 	vm_sync_t       sync_flags)
330 {
331 	return mach_vm_msync(map, address, size, sync_flags);
332 }
333 
334 kern_return_t
vm32_behavior_set(vm_map_t map,vm32_offset_t start,vm32_size_t size,vm_behavior_t new_behavior)335 vm32_behavior_set(
336 	vm_map_t                map,
337 	vm32_offset_t           start,
338 	vm32_size_t             size,
339 	vm_behavior_t           new_behavior)
340 {
341 	if ((map == VM_MAP_NULL) || (start + size < start)) {
342 		return KERN_INVALID_ARGUMENT;
343 	}
344 
345 	return mach_vm_behavior_set(map, start, size, new_behavior);
346 }
347 
348 kern_return_t
vm32_region_64(vm_map_t map,vm32_offset_t * address,vm32_size_t * size,vm_region_flavor_t flavor,vm_region_info_t info,mach_msg_type_number_t * count,mach_port_t * object_name)349 vm32_region_64(
350 	vm_map_t                 map,
351 	vm32_offset_t           *address,               /* IN/OUT */
352 	vm32_size_t             *size,                  /* OUT */
353 	vm_region_flavor_t       flavor,                /* IN */
354 	vm_region_info_t         info,                  /* OUT */
355 	mach_msg_type_number_t  *count,                 /* IN/OUT */
356 	mach_port_t             *object_name)           /* OUT */
357 {
358 	mach_vm_offset_t        maddress;
359 	mach_vm_size_t          msize;
360 	kern_return_t           result;
361 
362 	maddress = *address;
363 	msize = *size;
364 	result = mach_vm_region(map, &maddress, &msize, flavor, info, count, object_name);
365 	*size = CAST_DOWN_EXPLICIT(vm32_size_t, msize);
366 	*address = CAST_DOWN_EXPLICIT(vm32_offset_t, maddress);
367 
368 	return result;
369 }
370 
371 kern_return_t
vm32_region(vm_map_t map,vm32_address_t * address,vm32_size_t * size,vm_region_flavor_t flavor,vm_region_info_t info,mach_msg_type_number_t * count,mach_port_t * object_name)372 vm32_region(
373 	vm_map_t                        map,
374 	vm32_address_t                  *address,       /* IN/OUT */
375 	vm32_size_t                     *size,          /* OUT */
376 	vm_region_flavor_t              flavor, /* IN */
377 	vm_region_info_t                info,           /* OUT */
378 	mach_msg_type_number_t  *count, /* IN/OUT */
379 	mach_port_t                     *object_name)   /* OUT */
380 {
381 	vm_map_address_t        map_addr;
382 	vm_map_size_t           map_size;
383 	kern_return_t           kr;
384 
385 	if (VM_MAP_NULL == map) {
386 		return KERN_INVALID_ARGUMENT;
387 	}
388 
389 	map_addr = (vm_map_address_t)*address;
390 	map_size = (vm_map_size_t)*size;
391 
392 	kr = vm_map_region(map,
393 	    &map_addr, &map_size,
394 	    flavor, info, count,
395 	    object_name);
396 
397 	*address = CAST_DOWN_EXPLICIT(vm32_address_t, map_addr);
398 	*size = CAST_DOWN_EXPLICIT(vm32_size_t, map_size);
399 
400 	if (KERN_SUCCESS == kr && map_addr + map_size > VM32_MAX_ADDRESS) {
401 		return KERN_INVALID_ADDRESS;
402 	}
403 	return kr;
404 }
405 
406 kern_return_t
vm32_region_recurse_64(vm_map_t map,vm32_address_t * address,vm32_size_t * size,uint32_t * depth,vm_region_recurse_info_64_t info,mach_msg_type_number_t * infoCnt)407 vm32_region_recurse_64(
408 	vm_map_t                        map,
409 	vm32_address_t                  *address,
410 	vm32_size_t                     *size,
411 	uint32_t                        *depth,
412 	vm_region_recurse_info_64_t     info,
413 	mach_msg_type_number_t  *infoCnt)
414 {
415 	mach_vm_address_t       maddress;
416 	mach_vm_size_t          msize;
417 	kern_return_t           result;
418 
419 	maddress = *address;
420 	msize = *size;
421 	result = mach_vm_region_recurse(map, &maddress, &msize, depth, info, infoCnt);
422 	*address = CAST_DOWN_EXPLICIT(vm32_address_t, maddress);
423 	*size = CAST_DOWN_EXPLICIT(vm32_size_t, msize);
424 
425 	return result;
426 }
427 
428 kern_return_t
vm32_region_recurse(vm_map_t map,vm32_offset_t * address,vm32_size_t * size,natural_t * depth,vm_region_recurse_info_t info32,mach_msg_type_number_t * infoCnt)429 vm32_region_recurse(
430 	vm_map_t                        map,
431 	vm32_offset_t           *address,       /* IN/OUT */
432 	vm32_size_t                     *size,          /* OUT */
433 	natural_t                       *depth, /* IN/OUT */
434 	vm_region_recurse_info_t        info32, /* IN/OUT */
435 	mach_msg_type_number_t  *infoCnt)       /* IN/OUT */
436 {
437 	vm_region_submap_info_data_64_t info64;
438 	vm_region_submap_info_t info;
439 	vm_map_address_t        map_addr;
440 	vm_map_size_t           map_size;
441 	kern_return_t           kr;
442 
443 	if (VM_MAP_NULL == map || *infoCnt < VM_REGION_SUBMAP_INFO_COUNT) {
444 		return KERN_INVALID_ARGUMENT;
445 	}
446 
447 
448 	map_addr = (vm_map_address_t)*address;
449 	map_size = (vm_map_size_t)*size;
450 	info = (vm_region_submap_info_t)info32;
451 	*infoCnt = VM_REGION_SUBMAP_INFO_COUNT_64;
452 
453 	kr = vm_map_region_recurse_64(map, &map_addr, &map_size,
454 	    depth, &info64, infoCnt);
455 
456 	info->protection = info64.protection;
457 	info->max_protection = info64.max_protection;
458 	info->inheritance = info64.inheritance;
459 	info->offset = (uint32_t)info64.offset; /* trouble-maker */
460 	info->user_tag = info64.user_tag;
461 	info->pages_resident = info64.pages_resident;
462 	info->pages_shared_now_private = info64.pages_shared_now_private;
463 	info->pages_swapped_out = info64.pages_swapped_out;
464 	info->pages_dirtied = info64.pages_dirtied;
465 	info->ref_count = info64.ref_count;
466 	info->shadow_depth = info64.shadow_depth;
467 	info->external_pager = info64.external_pager;
468 	info->share_mode = info64.share_mode;
469 	info->is_submap = info64.is_submap;
470 	info->behavior = info64.behavior;
471 	info->object_id = info64.object_id;
472 	info->user_wired_count = info64.user_wired_count;
473 
474 	*address = CAST_DOWN_EXPLICIT(vm32_address_t, map_addr);
475 	*size = CAST_DOWN_EXPLICIT(vm32_size_t, map_size);
476 	*infoCnt = VM_REGION_SUBMAP_INFO_COUNT;
477 
478 	if (KERN_SUCCESS == kr && map_addr + map_size > VM32_MAX_ADDRESS) {
479 		return KERN_INVALID_ADDRESS;
480 	}
481 	return kr;
482 }
483 
484 kern_return_t
vm32_purgable_control(vm_map_t map,vm32_offset_t address,vm_purgable_t control,int * state)485 vm32_purgable_control(
486 	vm_map_t                map,
487 	vm32_offset_t           address,
488 	vm_purgable_t           control,
489 	int                     *state)
490 {
491 	if (VM_MAP_NULL == map) {
492 		return KERN_INVALID_ARGUMENT;
493 	}
494 
495 	return vm_map_purgable_control(map,
496 	           vm_map_trunc_page(address, PAGE_MASK),
497 	           control,
498 	           state);
499 }
500 
501 kern_return_t
vm32_map_page_query(vm_map_t map,vm32_offset_t offset,int * disposition,int * ref_count)502 vm32_map_page_query(
503 	vm_map_t                map,
504 	vm32_offset_t           offset,
505 	int                     *disposition,
506 	int                     *ref_count)
507 {
508 	if (VM_MAP_NULL == map) {
509 		return KERN_INVALID_ARGUMENT;
510 	}
511 
512 	return vm_map_page_query_internal(
513 		map,
514 		vm_map_trunc_page(offset, PAGE_MASK),
515 		disposition,
516 		ref_count);
517 }
518 
519 kern_return_t
vm32_make_memory_entry_64(vm_map_t target_map,memory_object_size_t * size,memory_object_offset_t offset,vm_prot_t permission,ipc_port_t * object_handle,ipc_port_t parent_handle)520 vm32_make_memory_entry_64(
521 	vm_map_t                target_map,
522 	memory_object_size_t    *size,
523 	memory_object_offset_t offset,
524 	vm_prot_t               permission,
525 	ipc_port_t              *object_handle,
526 	ipc_port_t              parent_handle)
527 {
528 	// use the existing entrypoint
529 	return _mach_make_memory_entry(target_map, size, offset, permission, object_handle, parent_handle);
530 }
531 
532 kern_return_t
vm32_make_memory_entry(vm_map_t target_map,vm32_size_t * size,vm32_offset_t offset,vm_prot_t permission,ipc_port_t * object_handle,ipc_port_t parent_entry)533 vm32_make_memory_entry(
534 	vm_map_t                target_map,
535 	vm32_size_t             *size,
536 	vm32_offset_t           offset,
537 	vm_prot_t               permission,
538 	ipc_port_t              *object_handle,
539 	ipc_port_t              parent_entry)
540 {
541 	memory_object_size_t    mo_size;
542 	kern_return_t           kr;
543 
544 	mo_size = (memory_object_size_t)*size;
545 	kr = _mach_make_memory_entry(target_map, &mo_size,
546 	    (memory_object_offset_t)offset, permission, object_handle,
547 	    parent_entry);
548 	*size = CAST_DOWN_EXPLICIT(vm32_size_t, mo_size);
549 	return kr;
550 }
551 
552 kern_return_t
vm32__task_wire(vm_map_t map,boolean_t must_wire)553 vm32__task_wire(
554 	vm_map_t        map,
555 	boolean_t       must_wire)
556 {
557 	if (map == VM_MAP_NULL) {
558 		return KERN_INVALID_ARGUMENT;
559 	}
560 
561 	vm_map_lock(map);
562 	map->wiring_required = (must_wire == TRUE);
563 	vm_map_unlock(map);
564 
565 	return KERN_SUCCESS;
566 }
567 
568 kern_return_t
vm32__map_exec_lockdown(vm_map_t map)569 vm32__map_exec_lockdown(
570 	vm_map_t        map)
571 {
572 	if (map == VM_MAP_NULL) {
573 		return KERN_INVALID_ARGUMENT;
574 	}
575 
576 	vm_map_lock(map);
577 	map->map_disallow_new_exec = TRUE;
578 	vm_map_unlock(map);
579 
580 	return KERN_SUCCESS;
581 }
582 
583 
584 #endif /* VM32_SUPPORT */
585