1/*
2 * Copyright (c) 2000-2008 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,1987 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  Software.Distribution@CS.CMU.EDU
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/memory_object.c
60 *	Author:	Michael Wayne Young
61 *
62 *	External memory management interface control functions.
63 */
64
65#include <advisory_pageout.h>
66
67/*
68 *	Interface dependencies:
69 */
70
71#include <mach/std_types.h>	/* For pointer_t */
72#include <mach/mach_types.h>
73
74#include <mach/mig.h>
75#include <mach/kern_return.h>
76#include <mach/memory_object.h>
77#include <mach/memory_object_default.h>
78#include <mach/memory_object_control_server.h>
79#include <mach/host_priv_server.h>
80#include <mach/boolean.h>
81#include <mach/vm_prot.h>
82#include <mach/message.h>
83
84/*
85 *	Implementation dependencies:
86 */
87#include <string.h>		/* For memcpy() */
88
89#include <kern/xpr.h>
90#include <kern/host.h>
91#include <kern/thread.h>	/* For current_thread() */
92#include <kern/ipc_mig.h>
93#include <kern/misc_protos.h>
94
95#include <vm/vm_object.h>
96#include <vm/vm_fault.h>
97#include <vm/memory_object.h>
98#include <vm/vm_page.h>
99#include <vm/vm_pageout.h>
100#include <vm/pmap.h>		/* For pmap_clear_modify */
101#include <vm/vm_kern.h>		/* For kernel_map, vm_move */
102#include <vm/vm_map.h>		/* For vm_map_pageable */
103#include <vm/vm_purgeable_internal.h>	/* Needed by some vm_page.h macros */
104#include <vm/vm_shared_region.h>
105
106#include <vm/vm_external.h>
107
108#include <vm/vm_protos.h>
109
110
111memory_object_default_t	memory_manager_default = MEMORY_OBJECT_DEFAULT_NULL;
112decl_lck_mtx_data(,	memory_manager_default_lock)
113
114
115/*
116 *	Routine:	memory_object_should_return_page
117 *
118 *	Description:
119 *		Determine whether the given page should be returned,
120 *		based on the page's state and on the given return policy.
121 *
122 *		We should return the page if one of the following is true:
123 *
124 *		1. Page is dirty and should_return is not RETURN_NONE.
125 *		2. Page is precious and should_return is RETURN_ALL.
126 *		3. Should_return is RETURN_ANYTHING.
127 *
128 *		As a side effect, m->dirty will be made consistent
129 *		with pmap_is_modified(m), if should_return is not
130 *		MEMORY_OBJECT_RETURN_NONE.
131 */
132
133#define	memory_object_should_return_page(m, should_return) \
134    (should_return != MEMORY_OBJECT_RETURN_NONE && \
135     (((m)->dirty || ((m)->dirty = pmap_is_modified((m)->phys_page))) || \
136      ((m)->precious && (should_return) == MEMORY_OBJECT_RETURN_ALL) || \
137      (should_return) == MEMORY_OBJECT_RETURN_ANYTHING))
138
139typedef	int	memory_object_lock_result_t;
140
141#define MEMORY_OBJECT_LOCK_RESULT_DONE          	0
142#define MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK    	1
143#define MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN   	2
144#define MEMORY_OBJECT_LOCK_RESULT_MUST_FREE		3
145
146memory_object_lock_result_t memory_object_lock_page(
147				vm_page_t		m,
148				memory_object_return_t	should_return,
149				boolean_t		should_flush,
150				vm_prot_t		prot);
151
152/*
153 *	Routine:	memory_object_lock_page
154 *
155 *	Description:
156 *		Perform the appropriate lock operations on the
157 *		given page.  See the description of
158 *		"memory_object_lock_request" for the meanings
159 *		of the arguments.
160 *
161 *		Returns an indication that the operation
162 *		completed, blocked, or that the page must
163 *		be cleaned.
164 */
165memory_object_lock_result_t
166memory_object_lock_page(
167	vm_page_t		m,
168	memory_object_return_t	should_return,
169	boolean_t		should_flush,
170	vm_prot_t		prot)
171{
172        XPR(XPR_MEMORY_OBJECT,
173            "m_o_lock_page, page 0x%X rtn %d flush %d prot %d\n",
174            m, should_return, should_flush, prot, 0);
175
176
177	if (m->busy || m->cleaning)
178		return (MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK);
179
180	if (m->laundry)
181		vm_pageout_steal_laundry(m, FALSE);
182
183	/*
184	 *	Don't worry about pages for which the kernel
185	 *	does not have any data.
186	 */
187	if (m->absent || m->error || m->restart) {
188		if (m->error && should_flush && !VM_PAGE_WIRED(m)) {
189			/*
190			 * dump the page, pager wants us to
191			 * clean it up and there is no
192			 * relevant data to return
193			 */
194			return (MEMORY_OBJECT_LOCK_RESULT_MUST_FREE);
195		}
196		return (MEMORY_OBJECT_LOCK_RESULT_DONE);
197	}
198	assert(!m->fictitious);
199
200	if (VM_PAGE_WIRED(m)) {
201		/*
202		 * The page is wired... just clean or return the page if needed.
203		 * Wired pages don't get flushed or disconnected from the pmap.
204		 */
205		if (memory_object_should_return_page(m, should_return))
206			return (MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN);
207
208		return (MEMORY_OBJECT_LOCK_RESULT_DONE);
209	}
210
211	if (should_flush) {
212		/*
213		 * must do the pmap_disconnect before determining the
214		 * need to return the page... otherwise it's possible
215		 * for the page to go from the clean to the dirty state
216		 * after we've made our decision
217		 */
218		if (pmap_disconnect(m->phys_page) & VM_MEM_MODIFIED) {
219			SET_PAGE_DIRTY(m, FALSE);
220		}
221	} else {
222		/*
223		 * If we are decreasing permission, do it now;
224		 * let the fault handler take care of increases
225		 * (pmap_page_protect may not increase protection).
226		 */
227		if (prot != VM_PROT_NO_CHANGE)
228			pmap_page_protect(m->phys_page, VM_PROT_ALL & ~prot);
229	}
230	/*
231	 *	Handle returning dirty or precious pages
232	 */
233	if (memory_object_should_return_page(m, should_return)) {
234		/*
235		 * we use to do a pmap_disconnect here in support
236		 * of memory_object_lock_request, but that routine
237		 * no longer requires this...  in any event, in
238		 * our world, it would turn into a big noop since
239		 * we don't lock the page in any way and as soon
240		 * as we drop the object lock, the page can be
241		 * faulted back into an address space
242		 *
243		 *	if (!should_flush)
244		 *		pmap_disconnect(m->phys_page);
245		 */
246		return (MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN);
247	}
248
249	/*
250	 *	Handle flushing clean pages
251	 */
252	if (should_flush)
253		return (MEMORY_OBJECT_LOCK_RESULT_MUST_FREE);
254
255	/*
256	 * we use to deactivate clean pages at this point,
257	 * but we do not believe that an msync should change
258	 * the 'age' of a page in the cache... here is the
259	 * original comment and code concerning this...
260	 *
261	 *	XXX Make clean but not flush a paging hint,
262	 *	and deactivate the pages.  This is a hack
263	 *	because it overloads flush/clean with
264	 *	implementation-dependent meaning.  This only
265	 *	happens to pages that are already clean.
266	 *
267	 *   if (vm_page_deactivate_hint && (should_return != MEMORY_OBJECT_RETURN_NONE))
268	 *	return (MEMORY_OBJECT_LOCK_RESULT_MUST_DEACTIVATE);
269	 */
270
271	return (MEMORY_OBJECT_LOCK_RESULT_DONE);
272}
273
274
275
276/*
277 *	Routine:	memory_object_lock_request [user interface]
278 *
279 *	Description:
280 *		Control use of the data associated with the given
281 *		memory object.  For each page in the given range,
282 *		perform the following operations, in order:
283 *			1)  restrict access to the page (disallow
284 *			    forms specified by "prot");
285 *			2)  return data to the manager (if "should_return"
286 *			    is RETURN_DIRTY and the page is dirty, or
287 * 			    "should_return" is RETURN_ALL and the page
288 *			    is either dirty or precious); and,
289 *			3)  flush the cached copy (if "should_flush"
290 *			    is asserted).
291 *		The set of pages is defined by a starting offset
292 *		("offset") and size ("size").  Only pages with the
293 *		same page alignment as the starting offset are
294 *		considered.
295 *
296 *		A single acknowledgement is sent (to the "reply_to"
297 *		port) when these actions are complete.  If successful,
298 *		the naked send right for reply_to is consumed.
299 */
300
301kern_return_t
302memory_object_lock_request(
303	memory_object_control_t		control,
304	memory_object_offset_t		offset,
305	memory_object_size_t		size,
306	memory_object_offset_t	*	resid_offset,
307	int			*	io_errno,
308	memory_object_return_t		should_return,
309	int				flags,
310	vm_prot_t			prot)
311{
312	vm_object_t	object;
313
314        /*
315	 *	Check for bogus arguments.
316	 */
317	object = memory_object_control_to_vm_object(control);
318	if (object == VM_OBJECT_NULL)
319		return (KERN_INVALID_ARGUMENT);
320
321	if ((prot & ~VM_PROT_ALL) != 0 && prot != VM_PROT_NO_CHANGE)
322		return (KERN_INVALID_ARGUMENT);
323
324	size = round_page_64(size);
325
326	/*
327	 *	Lock the object, and acquire a paging reference to
328	 *	prevent the memory_object reference from being released.
329	 */
330	vm_object_lock(object);
331	vm_object_paging_begin(object);
332
333	if (flags & MEMORY_OBJECT_DATA_FLUSH_ALL) {
334		if ((should_return != MEMORY_OBJECT_RETURN_NONE) || offset || object->copy) {
335			flags &= ~MEMORY_OBJECT_DATA_FLUSH_ALL;
336			flags |= MEMORY_OBJECT_DATA_FLUSH;
337		}
338	}
339	offset -= object->paging_offset;
340
341	if (flags & MEMORY_OBJECT_DATA_FLUSH_ALL)
342		vm_object_reap_pages(object, REAP_DATA_FLUSH);
343	else
344		(void)vm_object_update(object, offset, size, resid_offset,
345				       io_errno, should_return, flags, prot);
346
347	vm_object_paging_end(object);
348	vm_object_unlock(object);
349
350	return (KERN_SUCCESS);
351}
352
353/*
354 *	memory_object_release_name:  [interface]
355 *
356 *	Enforces name semantic on memory_object reference count decrement
357 *	This routine should not be called unless the caller holds a name
358 *	reference gained through the memory_object_named_create or the
359 *	memory_object_rename call.
360 *	If the TERMINATE_IDLE flag is set, the call will return if the
361 *	reference count is not 1. i.e. idle with the only remaining reference
362 *	being the name.
363 *	If the decision is made to proceed the name field flag is set to
364 *	false and the reference count is decremented.  If the RESPECT_CACHE
365 *	flag is set and the reference count has gone to zero, the
366 *	memory_object is checked to see if it is cacheable otherwise when
367 *	the reference count is zero, it is simply terminated.
368 */
369
370kern_return_t
371memory_object_release_name(
372	memory_object_control_t	control,
373	int				flags)
374{
375	vm_object_t	object;
376
377	object = memory_object_control_to_vm_object(control);
378	if (object == VM_OBJECT_NULL)
379		return (KERN_INVALID_ARGUMENT);
380
381	return vm_object_release_name(object, flags);
382}
383
384
385
386/*
387 *	Routine:	memory_object_destroy [user interface]
388 *	Purpose:
389 *		Shut down a memory object, despite the
390 *		presence of address map (or other) references
391 *		to the vm_object.
392 */
393kern_return_t
394memory_object_destroy(
395	memory_object_control_t	control,
396	kern_return_t		reason)
397{
398	vm_object_t		object;
399
400	object = memory_object_control_to_vm_object(control);
401	if (object == VM_OBJECT_NULL)
402		return (KERN_INVALID_ARGUMENT);
403
404	return (vm_object_destroy(object, reason));
405}
406
407/*
408 *	Routine:	vm_object_sync
409 *
410 *	Kernel internal function to synch out pages in a given
411 *	range within an object to its memory manager.  Much the
412 *	same as memory_object_lock_request but page protection
413 *	is not changed.
414 *
415 *	If the should_flush and should_return flags are true pages
416 *	are flushed, that is dirty & precious pages are written to
417 *	the memory manager and then discarded.  If should_return
418 *	is false, only precious pages are returned to the memory
419 *	manager.
420 *
421 *	If should flush is false and should_return true, the memory
422 *	manager's copy of the pages is updated.  If should_return
423 *	is also false, only the precious pages are updated.  This
424 *	last option is of limited utility.
425 *
426 *	Returns:
427 *	FALSE		if no pages were returned to the pager
428 *	TRUE		otherwise.
429 */
430
431boolean_t
432vm_object_sync(
433	vm_object_t		object,
434	vm_object_offset_t	offset,
435	vm_object_size_t	size,
436	boolean_t		should_flush,
437	boolean_t		should_return,
438	boolean_t		should_iosync)
439{
440	boolean_t	rv;
441	int             flags;
442
443        XPR(XPR_VM_OBJECT,
444            "vm_o_sync, object 0x%X, offset 0x%X size 0x%x flush %d rtn %d\n",
445            object, offset, size, should_flush, should_return);
446
447	/*
448	 * Lock the object, and acquire a paging reference to
449	 * prevent the memory_object and control ports from
450	 * being destroyed.
451	 */
452	vm_object_lock(object);
453	vm_object_paging_begin(object);
454
455	if (should_flush) {
456	        flags = MEMORY_OBJECT_DATA_FLUSH;
457		/*
458		 * This flush is from an msync(), not a truncate(), so the
459		 * contents of the file are not affected.
460		 * MEMORY_OBECT_DATA_NO_CHANGE lets vm_object_update() know
461		 * that the data is not changed and that there's no need to
462		 * push the old contents to a copy object.
463		 */
464		flags |= MEMORY_OBJECT_DATA_NO_CHANGE;
465	} else
466	        flags = 0;
467
468	if (should_iosync)
469	        flags |= MEMORY_OBJECT_IO_SYNC;
470
471	rv = vm_object_update(object, offset, (vm_object_size_t)size, NULL, NULL,
472		(should_return) ?
473			MEMORY_OBJECT_RETURN_ALL :
474			MEMORY_OBJECT_RETURN_NONE,
475		flags,
476		VM_PROT_NO_CHANGE);
477
478
479	vm_object_paging_end(object);
480	vm_object_unlock(object);
481	return rv;
482}
483
484
485
486#define LIST_REQ_PAGEOUT_PAGES(object, data_cnt, po, ro, ioerr, iosync)    \
487MACRO_BEGIN								\
488									\
489        int			upl_flags;                              \
490	memory_object_t		pager;					\
491									\
492	if (object->object_slid) {					\
493		panic("Objects with slid pages not allowed\n");		\
494	}								\
495				                   			\
496	if ((pager = (object)->pager) != MEMORY_OBJECT_NULL) {		\
497		vm_object_paging_begin(object);				\
498		vm_object_unlock(object);				\
499									\
500                if (iosync)                                     	\
501                        upl_flags = UPL_MSYNC | UPL_IOSYNC;     	\
502                else                                            	\
503                        upl_flags = UPL_MSYNC;                  	\
504				                   			\
505	   	(void) memory_object_data_return(pager,			\
506			po,						\
507			(memory_object_cluster_size_t)data_cnt,		\
508	                ro,                                             \
509	                ioerr,                                          \
510			FALSE,						\
511			FALSE,		                                \
512			upl_flags);                                 	\
513									\
514		vm_object_lock(object);					\
515		vm_object_paging_end(object);				\
516	}								\
517MACRO_END
518
519
520
521static int
522vm_object_update_extent(
523        vm_object_t		object,
524        vm_object_offset_t	offset,
525	vm_object_offset_t	offset_end,
526	vm_object_offset_t	*offset_resid,
527	int			*io_errno,
528        boolean_t		should_flush,
529	memory_object_return_t	should_return,
530        boolean_t		should_iosync,
531        vm_prot_t		prot)
532{
533        vm_page_t	m;
534        int		retval = 0;
535	vm_object_offset_t	paging_offset = 0;
536	vm_object_offset_t	next_offset = offset;
537        memory_object_lock_result_t	page_lock_result;
538	memory_object_cluster_size_t	data_cnt = 0;
539	struct vm_page_delayed_work	dw_array[DEFAULT_DELAYED_WORK_LIMIT];
540	struct vm_page_delayed_work	*dwp;
541	int		dw_count;
542	int		dw_limit;
543
544        dwp = &dw_array[0];
545        dw_count = 0;
546	dw_limit = DELAYED_WORK_LIMIT(DEFAULT_DELAYED_WORK_LIMIT);
547
548	for (;
549	     offset < offset_end && object->resident_page_count;
550	     offset += PAGE_SIZE_64) {
551
552	        /*
553		 * Limit the number of pages to be cleaned at once to a contiguous
554		 * run, or at most MAX_UPL_TRANSFER size
555		 */
556		if (data_cnt) {
557			if ((data_cnt >= PAGE_SIZE * MAX_UPL_TRANSFER) || (next_offset != offset)) {
558
559				if (dw_count) {
560					vm_page_do_delayed_work(object, &dw_array[0], dw_count);
561					dwp = &dw_array[0];
562					dw_count = 0;
563				}
564				LIST_REQ_PAGEOUT_PAGES(object, data_cnt,
565						       paging_offset, offset_resid, io_errno, should_iosync);
566				data_cnt = 0;
567			}
568		}
569		while ((m = vm_page_lookup(object, offset)) != VM_PAGE_NULL) {
570
571			dwp->dw_mask = 0;
572
573			page_lock_result = memory_object_lock_page(m, should_return, should_flush, prot);
574
575			if (data_cnt && page_lock_result != MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN) {
576				/*
577				 *	End of a run of dirty/precious pages.
578				 */
579				if (dw_count) {
580					vm_page_do_delayed_work(object, &dw_array[0], dw_count);
581					dwp = &dw_array[0];
582					dw_count = 0;
583				}
584				LIST_REQ_PAGEOUT_PAGES(object, data_cnt,
585						       paging_offset, offset_resid, io_errno, should_iosync);
586				/*
587				 * LIST_REQ_PAGEOUT_PAGES will drop the object lock which will
588				 * allow the state of page 'm' to change... we need to re-lookup
589				 * the current offset
590				 */
591				data_cnt = 0;
592				continue;
593			}
594
595			switch (page_lock_result) {
596
597			case MEMORY_OBJECT_LOCK_RESULT_DONE:
598				break;
599
600			case MEMORY_OBJECT_LOCK_RESULT_MUST_FREE:
601				dwp->dw_mask |= DW_vm_page_free;
602				break;
603
604			case MEMORY_OBJECT_LOCK_RESULT_MUST_BLOCK:
605				PAGE_SLEEP(object, m, THREAD_UNINT);
606				continue;
607
608			case MEMORY_OBJECT_LOCK_RESULT_MUST_RETURN:
609				if (data_cnt == 0)
610					paging_offset = offset;
611
612				data_cnt += PAGE_SIZE;
613				next_offset = offset + PAGE_SIZE_64;
614
615				/*
616				 * wired pages shouldn't be flushed and
617				 * since they aren't on any queue,
618				 * no need to remove them
619				 */
620				if (!VM_PAGE_WIRED(m)) {
621
622					if (should_flush) {
623						/*
624						 * add additional state for the flush
625						 */
626						m->pageout = TRUE;
627					}
628					/*
629					 * we use to remove the page from the queues at this
630					 * point, but we do not believe that an msync
631					 * should cause the 'age' of a page to be changed
632					 *
633					 *    else
634					 *	dwp->dw_mask |= DW_VM_PAGE_QUEUES_REMOVE;
635					 */
636				}
637				retval = 1;
638				break;
639			}
640			if (dwp->dw_mask) {
641				VM_PAGE_ADD_DELAYED_WORK(dwp, m, dw_count);
642
643				if (dw_count >= dw_limit) {
644					vm_page_do_delayed_work(object, &dw_array[0], dw_count);
645					dwp = &dw_array[0];
646					dw_count = 0;
647				}
648			}
649			break;
650		}
651	}
652	/*
653	 *	We have completed the scan for applicable pages.
654	 *	Clean any pages that have been saved.
655	 */
656	if (dw_count)
657		vm_page_do_delayed_work(object, &dw_array[0], dw_count);
658
659	if (data_cnt) {
660	        LIST_REQ_PAGEOUT_PAGES(object, data_cnt,
661				       paging_offset, offset_resid, io_errno, should_iosync);
662	}
663	return (retval);
664}
665
666
667
668/*
669 *	Routine:	vm_object_update
670 *	Description:
671 *		Work function for m_o_lock_request(), vm_o_sync().
672 *
673 *		Called with object locked and paging ref taken.
674 */
675kern_return_t
676vm_object_update(
677	vm_object_t		object,
678	vm_object_offset_t	offset,
679	vm_object_size_t	size,
680	vm_object_offset_t	*resid_offset,
681	int			*io_errno,
682	memory_object_return_t	should_return,
683	int			flags,
684	vm_prot_t		protection)
685{
686        vm_object_t		copy_object = VM_OBJECT_NULL;
687	boolean_t		data_returned = FALSE;
688	boolean_t		update_cow;
689	boolean_t		should_flush = (flags & MEMORY_OBJECT_DATA_FLUSH) ? TRUE : FALSE;
690	boolean_t		should_iosync = (flags & MEMORY_OBJECT_IO_SYNC) ? TRUE : FALSE;
691	vm_fault_return_t	result;
692	int			num_of_extents;
693	int			n;
694#define MAX_EXTENTS	8
695#define EXTENT_SIZE	(1024 * 1024 * 256)
696#define RESIDENT_LIMIT	(1024 * 32)
697	struct extent {
698	        vm_object_offset_t e_base;
699	        vm_object_offset_t e_min;
700	        vm_object_offset_t e_max;
701	} extents[MAX_EXTENTS];
702
703	/*
704	 *	To avoid blocking while scanning for pages, save
705	 *	dirty pages to be cleaned all at once.
706	 *
707	 *	XXXO A similar strategy could be used to limit the
708	 *	number of times that a scan must be restarted for
709	 *	other reasons.  Those pages that would require blocking
710	 *	could be temporarily collected in another list, or
711	 *	their offsets could be recorded in a small array.
712	 */
713
714	/*
715	 * XXX	NOTE: May want to consider converting this to a page list
716	 * XXX	vm_map_copy interface.  Need to understand object
717	 * XXX	coalescing implications before doing so.
718	 */
719
720	update_cow = ((flags & MEMORY_OBJECT_DATA_FLUSH)
721			&& (!(flags & MEMORY_OBJECT_DATA_NO_CHANGE) &&
722					!(flags & MEMORY_OBJECT_DATA_PURGE)))
723				|| (flags & MEMORY_OBJECT_COPY_SYNC);
724
725	if (update_cow || (flags & (MEMORY_OBJECT_DATA_PURGE | MEMORY_OBJECT_DATA_SYNC))) {
726	        int collisions = 0;
727
728	        while ((copy_object = object->copy) != VM_OBJECT_NULL) {
729		        /*
730			 * need to do a try here since we're swimming upstream
731			 * against the normal lock ordering... however, we need
732			 * to hold the object stable until we gain control of the
733			 * copy object so we have to be careful how we approach this
734			 */
735		        if (vm_object_lock_try(copy_object)) {
736			       /*
737				* we 'won' the lock on the copy object...
738				* no need to hold the object lock any longer...
739				* take a real reference on the copy object because
740				* we're going to call vm_fault_page on it which may
741				* under certain conditions drop the lock and the paging
742				* reference we're about to take... the reference
743				* will keep the copy object from going away if that happens
744				*/
745			       vm_object_unlock(object);
746			       vm_object_reference_locked(copy_object);
747			       break;
748			}
749			vm_object_unlock(object);
750
751			collisions++;
752			mutex_pause(collisions);
753
754			vm_object_lock(object);
755		}
756	}
757	if ((copy_object != VM_OBJECT_NULL && update_cow) || (flags & MEMORY_OBJECT_DATA_SYNC)) {
758		vm_map_size_t		i;
759		vm_map_size_t		copy_size;
760		vm_map_offset_t		copy_offset;
761		vm_prot_t		prot;
762		vm_page_t		page;
763		vm_page_t		top_page;
764		kern_return_t		error = 0;
765		struct vm_object_fault_info fault_info;
766
767		if (copy_object != VM_OBJECT_NULL) {
768		        /*
769			 * translate offset with respect to shadow's offset
770			 */
771		        copy_offset = (offset >= copy_object->vo_shadow_offset) ?
772			  (vm_map_offset_t)(offset - copy_object->vo_shadow_offset) :
773			  (vm_map_offset_t) 0;
774
775			if (copy_offset > copy_object->vo_size)
776			        copy_offset = copy_object->vo_size;
777
778			/*
779			 * clip size with respect to shadow offset
780			 */
781			if (offset >= copy_object->vo_shadow_offset) {
782			        copy_size = size;
783			} else if (size >= copy_object->vo_shadow_offset - offset) {
784			        copy_size = size - (copy_object->vo_shadow_offset - offset);
785			} else {
786			        copy_size = 0;
787			}
788
789			if (copy_offset + copy_size > copy_object->vo_size) {
790			        if (copy_object->vo_size >= copy_offset) {
791				        copy_size = copy_object->vo_size - copy_offset;
792				} else {
793				        copy_size = 0;
794				}
795			}
796			copy_size+=copy_offset;
797
798		} else {
799			copy_object = object;
800
801			copy_size   = offset + size;
802			copy_offset = offset;
803		}
804		fault_info.interruptible = THREAD_UNINT;
805		fault_info.behavior  = VM_BEHAVIOR_SEQUENTIAL;
806		fault_info.user_tag  = 0;
807		fault_info.lo_offset = copy_offset;
808		fault_info.hi_offset = copy_size;
809		fault_info.no_cache   = FALSE;
810		fault_info.stealth = TRUE;
811		fault_info.io_sync = FALSE;
812		fault_info.cs_bypass = FALSE;
813		fault_info.mark_zf_absent = FALSE;
814		fault_info.batch_pmap_op = FALSE;
815
816		vm_object_paging_begin(copy_object);
817
818		for (i = copy_offset; i < copy_size; i += PAGE_SIZE) {
819	RETRY_COW_OF_LOCK_REQUEST:
820			fault_info.cluster_size = (vm_size_t) (copy_size - i);
821			assert(fault_info.cluster_size == copy_size - i);
822
823			prot = 	VM_PROT_WRITE|VM_PROT_READ;
824			page = VM_PAGE_NULL;
825			result = vm_fault_page(copy_object, i,
826					       VM_PROT_WRITE|VM_PROT_READ,
827					       FALSE,
828					       FALSE, /* page not looked up */
829					       &prot,
830					       &page,
831					       &top_page,
832					       (int *)0,
833					       &error,
834					       FALSE,
835					       FALSE, &fault_info);
836
837			switch (result) {
838			case VM_FAULT_SUCCESS:
839				if (top_page) {
840					vm_fault_cleanup(
841						page->object, top_page);
842					vm_object_lock(copy_object);
843					vm_object_paging_begin(copy_object);
844				}
845				if (!page->active &&
846				    !page->inactive &&
847				    !page->throttled) {
848					vm_page_lockspin_queues();
849					if (!page->active &&
850					    !page->inactive &&
851					    !page->throttled)
852						vm_page_deactivate(page);
853					vm_page_unlock_queues();
854				}
855				PAGE_WAKEUP_DONE(page);
856				break;
857			case VM_FAULT_RETRY:
858				prot = 	VM_PROT_WRITE|VM_PROT_READ;
859				vm_object_lock(copy_object);
860				vm_object_paging_begin(copy_object);
861				goto RETRY_COW_OF_LOCK_REQUEST;
862			case VM_FAULT_INTERRUPTED:
863				prot = 	VM_PROT_WRITE|VM_PROT_READ;
864				vm_object_lock(copy_object);
865				vm_object_paging_begin(copy_object);
866				goto RETRY_COW_OF_LOCK_REQUEST;
867			case VM_FAULT_MEMORY_SHORTAGE:
868				VM_PAGE_WAIT();
869				prot = 	VM_PROT_WRITE|VM_PROT_READ;
870				vm_object_lock(copy_object);
871				vm_object_paging_begin(copy_object);
872				goto RETRY_COW_OF_LOCK_REQUEST;
873			case VM_FAULT_SUCCESS_NO_VM_PAGE:
874				/* success but no VM page: fail */
875				vm_object_paging_end(copy_object);
876				vm_object_unlock(copy_object);
877				/*FALLTHROUGH*/
878			case VM_FAULT_MEMORY_ERROR:
879			        if (object != copy_object)
880				        vm_object_deallocate(copy_object);
881				vm_object_lock(object);
882				goto BYPASS_COW_COPYIN;
883			default:
884				panic("vm_object_update: unexpected error 0x%x"
885				      " from vm_fault_page()\n", result);
886			}
887
888		}
889		vm_object_paging_end(copy_object);
890	}
891	if ((flags & (MEMORY_OBJECT_DATA_SYNC | MEMORY_OBJECT_COPY_SYNC))) {
892	        if (copy_object != VM_OBJECT_NULL && copy_object != object) {
893			vm_object_unlock(copy_object);
894		        vm_object_deallocate(copy_object);
895			vm_object_lock(object);
896		}
897		return KERN_SUCCESS;
898	}
899	if (copy_object != VM_OBJECT_NULL && copy_object != object) {
900	        if ((flags & MEMORY_OBJECT_DATA_PURGE)) {
901		        copy_object->shadow_severed = TRUE;
902			copy_object->shadowed = FALSE;
903			copy_object->shadow = NULL;
904			/*
905			 * delete the ref the COW was holding on the target object
906			 */
907			vm_object_deallocate(object);
908		}
909		vm_object_unlock(copy_object);
910	        vm_object_deallocate(copy_object);
911		vm_object_lock(object);
912	}
913BYPASS_COW_COPYIN:
914
915	/*
916	 * when we have a really large range to check relative
917	 * to the number of actual resident pages, we'd like
918	 * to use the resident page list to drive our checks
919	 * however, the object lock will get dropped while processing
920	 * the page which means the resident queue can change which
921	 * means we can't walk the queue as we process the pages
922	 * we also want to do the processing in offset order to allow
923	 * 'runs' of pages to be collected if we're being told to
924	 * flush to disk... the resident page queue is NOT ordered.
925	 *
926	 * a temporary solution (until we figure out how to deal with
927	 * large address spaces more generically) is to pre-flight
928	 * the resident page queue (if it's small enough) and develop
929	 * a collection of extents (that encompass actual resident pages)
930	 * to visit.  This will at least allow us to deal with some of the
931	 * more pathological cases in a more efficient manner.  The current
932	 * worst case (a single resident page at the end of an extremely large
933	 * range) can take minutes to complete for ranges in the terrabyte
934	 * category... since this routine is called when truncating a file,
935	 * and we currently support files up to 16 Tbytes in size, this
936	 * is not a theoretical problem
937	 */
938
939	if ((object->resident_page_count < RESIDENT_LIMIT) &&
940	    (atop_64(size) > (unsigned)(object->resident_page_count/(8 * MAX_EXTENTS)))) {
941		vm_page_t		next;
942		vm_object_offset_t	start;
943		vm_object_offset_t	end;
944		vm_object_size_t	e_mask;
945		vm_page_t               m;
946
947		start = offset;
948		end   = offset + size;
949		num_of_extents = 0;
950		e_mask = ~((vm_object_size_t)(EXTENT_SIZE - 1));
951
952		m = (vm_page_t) queue_first(&object->memq);
953
954		while (!queue_end(&object->memq, (queue_entry_t) m)) {
955			next = (vm_page_t) queue_next(&m->listq);
956
957			if ((m->offset >= start) && (m->offset < end)) {
958			        /*
959				 * this is a page we're interested in
960				 * try to fit it into a current extent
961				 */
962			        for (n = 0; n < num_of_extents; n++) {
963				        if ((m->offset & e_mask) == extents[n].e_base) {
964					        /*
965						 * use (PAGE_SIZE - 1) to determine the
966						 * max offset so that we don't wrap if
967						 * we're at the last page of the space
968						 */
969					        if (m->offset < extents[n].e_min)
970						        extents[n].e_min = m->offset;
971						else if ((m->offset + (PAGE_SIZE - 1)) > extents[n].e_max)
972						        extents[n].e_max = m->offset + (PAGE_SIZE - 1);
973					        break;
974					}
975				}
976				if (n == num_of_extents) {
977				        /*
978					 * didn't find a current extent that can encompass
979					 * this page
980					 */
981				        if (n < MAX_EXTENTS) {
982					        /*
983						 * if we still have room,
984						 * create a new extent
985						 */
986					        extents[n].e_base = m->offset & e_mask;
987						extents[n].e_min  = m->offset;
988						extents[n].e_max  = m->offset + (PAGE_SIZE - 1);
989
990						num_of_extents++;
991					} else {
992						/*
993						 * no room to create a new extent...
994						 * fall back to a single extent based
995						 * on the min and max page offsets
996						 * we find in the range we're interested in...
997						 * first, look through the extent list and
998						 * develop the overall min and max for the
999						 * pages we've looked at up to this point
1000						 */
1001					        for (n = 1; n < num_of_extents; n++) {
1002						        if (extents[n].e_min < extents[0].e_min)
1003						                extents[0].e_min = extents[n].e_min;
1004							if (extents[n].e_max > extents[0].e_max)
1005						                extents[0].e_max = extents[n].e_max;
1006						}
1007						/*
1008						 * now setup to run through the remaining pages
1009						 * to determine the overall min and max
1010						 * offset for the specified range
1011						 */
1012						extents[0].e_base = 0;
1013						e_mask = 0;
1014						num_of_extents = 1;
1015
1016						/*
1017						 * by continuing, we'll reprocess the
1018						 * page that forced us to abandon trying
1019						 * to develop multiple extents
1020						 */
1021						continue;
1022					}
1023				}
1024			}
1025			m = next;
1026		}
1027	} else {
1028	        extents[0].e_min = offset;
1029		extents[0].e_max = offset + (size - 1);
1030
1031		num_of_extents = 1;
1032	}
1033	for (n = 0; n < num_of_extents; n++) {
1034	        if (vm_object_update_extent(object, extents[n].e_min, extents[n].e_max, resid_offset, io_errno,
1035					    should_flush, should_return, should_iosync, protection))
1036		        data_returned = TRUE;
1037	}
1038	return (data_returned);
1039}
1040
1041
1042/*
1043 *	Routine:	memory_object_synchronize_completed [user interface]
1044 *
1045 *	Tell kernel that previously synchronized data
1046 *	(memory_object_synchronize) has been queue or placed on the
1047 *	backing storage.
1048 *
1049 *	Note: there may be multiple synchronize requests for a given
1050 *	memory object outstanding but they will not overlap.
1051 */
1052
1053kern_return_t
1054memory_object_synchronize_completed(
1055	memory_object_control_t	control,
1056	memory_object_offset_t	offset,
1057	memory_object_size_t    length)
1058{
1059	vm_object_t			object;
1060	msync_req_t			msr;
1061
1062	object = memory_object_control_to_vm_object(control);
1063
1064        XPR(XPR_MEMORY_OBJECT,
1065	    "m_o_sync_completed, object 0x%X, offset 0x%X length 0x%X\n",
1066	    object, offset, length, 0, 0);
1067
1068	/*
1069	 *      Look for bogus arguments
1070	 */
1071
1072	if (object == VM_OBJECT_NULL)
1073		return (KERN_INVALID_ARGUMENT);
1074
1075	vm_object_lock(object);
1076
1077/*
1078 *	search for sync request structure
1079 */
1080	queue_iterate(&object->msr_q, msr, msync_req_t, msr_q) {
1081 		if (msr->offset == offset && msr->length == length) {
1082			queue_remove(&object->msr_q, msr, msync_req_t, msr_q);
1083			break;
1084		}
1085        }/* queue_iterate */
1086
1087	if (queue_end(&object->msr_q, (queue_entry_t)msr)) {
1088		vm_object_unlock(object);
1089		return KERN_INVALID_ARGUMENT;
1090	}
1091
1092	msr_lock(msr);
1093	vm_object_unlock(object);
1094	msr->flag = VM_MSYNC_DONE;
1095	msr_unlock(msr);
1096	thread_wakeup((event_t) msr);
1097
1098	return KERN_SUCCESS;
1099}/* memory_object_synchronize_completed */
1100
1101static kern_return_t
1102vm_object_set_attributes_common(
1103	vm_object_t	object,
1104	boolean_t	may_cache,
1105	memory_object_copy_strategy_t copy_strategy,
1106	boolean_t	temporary,
1107	__unused boolean_t	silent_overwrite,
1108	boolean_t	advisory_pageout)
1109{
1110	boolean_t	object_became_ready;
1111
1112        XPR(XPR_MEMORY_OBJECT,
1113	    "m_o_set_attr_com, object 0x%X flg %x strat %d\n",
1114	    object, (may_cache&1)|((temporary&1)<1), copy_strategy, 0, 0);
1115
1116	if (object == VM_OBJECT_NULL)
1117		return(KERN_INVALID_ARGUMENT);
1118
1119	/*
1120	 *	Verify the attributes of importance
1121	 */
1122
1123	switch(copy_strategy) {
1124		case MEMORY_OBJECT_COPY_NONE:
1125		case MEMORY_OBJECT_COPY_DELAY:
1126			break;
1127		default:
1128			return(KERN_INVALID_ARGUMENT);
1129	}
1130
1131#if	!ADVISORY_PAGEOUT
1132	if (silent_overwrite || advisory_pageout)
1133		return(KERN_INVALID_ARGUMENT);
1134
1135#endif	/* !ADVISORY_PAGEOUT */
1136	if (may_cache)
1137		may_cache = TRUE;
1138	if (temporary)
1139		temporary = TRUE;
1140
1141	vm_object_lock(object);
1142
1143	/*
1144	 *	Copy the attributes
1145	 */
1146	assert(!object->internal);
1147	object_became_ready = !object->pager_ready;
1148	object->copy_strategy = copy_strategy;
1149	object->can_persist = may_cache;
1150	object->temporary = temporary;
1151//	object->silent_overwrite = silent_overwrite;
1152	object->advisory_pageout = advisory_pageout;
1153
1154	/*
1155	 *	Wake up anyone waiting for the ready attribute
1156	 *	to become asserted.
1157	 */
1158
1159	if (object_became_ready) {
1160		object->pager_ready = TRUE;
1161		vm_object_wakeup(object, VM_OBJECT_EVENT_PAGER_READY);
1162	}
1163
1164	vm_object_unlock(object);
1165
1166	return(KERN_SUCCESS);
1167}
1168
1169/*
1170 *	Set the memory object attribute as provided.
1171 *
1172 *	XXX This routine cannot be completed until the vm_msync, clean
1173 *	     in place, and cluster work is completed. See ifdef notyet
1174 *	     below and note that vm_object_set_attributes_common()
1175 *	     may have to be expanded.
1176 */
1177kern_return_t
1178memory_object_change_attributes(
1179	memory_object_control_t		control,
1180	memory_object_flavor_t		flavor,
1181	memory_object_info_t		attributes,
1182	mach_msg_type_number_t		count)
1183{
1184	vm_object_t             	object;
1185	kern_return_t   		result = KERN_SUCCESS;
1186	boolean_t       		temporary;
1187	boolean_t       		may_cache;
1188	boolean_t       		invalidate;
1189	memory_object_copy_strategy_t	copy_strategy;
1190	boolean_t       		silent_overwrite;
1191	boolean_t			advisory_pageout;
1192
1193	object = memory_object_control_to_vm_object(control);
1194	if (object == VM_OBJECT_NULL)
1195		return (KERN_INVALID_ARGUMENT);
1196
1197	vm_object_lock(object);
1198
1199	temporary = object->temporary;
1200	may_cache = object->can_persist;
1201	copy_strategy = object->copy_strategy;
1202//	silent_overwrite = object->silent_overwrite;
1203	silent_overwrite = FALSE;
1204	advisory_pageout = object->advisory_pageout;
1205#if notyet
1206	invalidate = object->invalidate;
1207#endif
1208	vm_object_unlock(object);
1209
1210	switch (flavor) {
1211	    case OLD_MEMORY_OBJECT_BEHAVIOR_INFO:
1212	    {
1213                old_memory_object_behave_info_t     behave;
1214
1215                if (count != OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT) {
1216                        result = KERN_INVALID_ARGUMENT;
1217                        break;
1218                }
1219
1220                behave = (old_memory_object_behave_info_t) attributes;
1221
1222		temporary = behave->temporary;
1223		invalidate = behave->invalidate;
1224		copy_strategy = behave->copy_strategy;
1225
1226		break;
1227	    }
1228
1229	    case MEMORY_OBJECT_BEHAVIOR_INFO:
1230	    {
1231                memory_object_behave_info_t     behave;
1232
1233                if (count != MEMORY_OBJECT_BEHAVE_INFO_COUNT) {
1234                        result = KERN_INVALID_ARGUMENT;
1235                        break;
1236                }
1237
1238                behave = (memory_object_behave_info_t) attributes;
1239
1240		temporary = behave->temporary;
1241		invalidate = behave->invalidate;
1242		copy_strategy = behave->copy_strategy;
1243		silent_overwrite = behave->silent_overwrite;
1244		advisory_pageout = behave->advisory_pageout;
1245		break;
1246	    }
1247
1248	    case MEMORY_OBJECT_PERFORMANCE_INFO:
1249	    {
1250		memory_object_perf_info_t	perf;
1251
1252                if (count != MEMORY_OBJECT_PERF_INFO_COUNT) {
1253                        result = KERN_INVALID_ARGUMENT;
1254                        break;
1255                }
1256
1257                perf = (memory_object_perf_info_t) attributes;
1258
1259		may_cache = perf->may_cache;
1260
1261		break;
1262	    }
1263
1264	    case OLD_MEMORY_OBJECT_ATTRIBUTE_INFO:
1265	    {
1266		old_memory_object_attr_info_t	attr;
1267
1268                if (count != OLD_MEMORY_OBJECT_ATTR_INFO_COUNT) {
1269                        result = KERN_INVALID_ARGUMENT;
1270                        break;
1271                }
1272
1273		attr = (old_memory_object_attr_info_t) attributes;
1274
1275                may_cache = attr->may_cache;
1276                copy_strategy = attr->copy_strategy;
1277
1278		break;
1279	    }
1280
1281	    case MEMORY_OBJECT_ATTRIBUTE_INFO:
1282	    {
1283		memory_object_attr_info_t	attr;
1284
1285                if (count != MEMORY_OBJECT_ATTR_INFO_COUNT) {
1286                        result = KERN_INVALID_ARGUMENT;
1287                        break;
1288                }
1289
1290		attr = (memory_object_attr_info_t) attributes;
1291
1292		copy_strategy = attr->copy_strategy;
1293                may_cache = attr->may_cache_object;
1294		temporary = attr->temporary;
1295
1296		break;
1297	    }
1298
1299	    default:
1300		result = KERN_INVALID_ARGUMENT;
1301		break;
1302	}
1303
1304	if (result != KERN_SUCCESS)
1305		return(result);
1306
1307	if (copy_strategy == MEMORY_OBJECT_COPY_TEMPORARY) {
1308		copy_strategy = MEMORY_OBJECT_COPY_DELAY;
1309		temporary = TRUE;
1310	} else {
1311		temporary = FALSE;
1312	}
1313
1314	/*
1315	 * XXX	may_cache may become a tri-valued variable to handle
1316	 * XXX	uncache if not in use.
1317	 */
1318	return (vm_object_set_attributes_common(object,
1319						     may_cache,
1320						     copy_strategy,
1321						     temporary,
1322						     silent_overwrite,
1323						     advisory_pageout));
1324}
1325
1326kern_return_t
1327memory_object_get_attributes(
1328        memory_object_control_t	control,
1329        memory_object_flavor_t 	flavor,
1330	memory_object_info_t	attributes,	/* pointer to OUT array */
1331	mach_msg_type_number_t	*count)		/* IN/OUT */
1332{
1333	kern_return_t 		ret = KERN_SUCCESS;
1334	vm_object_t		object;
1335
1336	object = memory_object_control_to_vm_object(control);
1337	if (object == VM_OBJECT_NULL)
1338		return (KERN_INVALID_ARGUMENT);
1339
1340        vm_object_lock(object);
1341
1342	switch (flavor) {
1343	    case OLD_MEMORY_OBJECT_BEHAVIOR_INFO:
1344	    {
1345		old_memory_object_behave_info_t	behave;
1346
1347		if (*count < OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT) {
1348			ret = KERN_INVALID_ARGUMENT;
1349			break;
1350		}
1351
1352		behave = (old_memory_object_behave_info_t) attributes;
1353		behave->copy_strategy = object->copy_strategy;
1354		behave->temporary = object->temporary;
1355#if notyet	/* remove when vm_msync complies and clean in place fini */
1356                behave->invalidate = object->invalidate;
1357#else
1358		behave->invalidate = FALSE;
1359#endif
1360
1361		*count = OLD_MEMORY_OBJECT_BEHAVE_INFO_COUNT;
1362		break;
1363	    }
1364
1365	    case MEMORY_OBJECT_BEHAVIOR_INFO:
1366	    {
1367		memory_object_behave_info_t	behave;
1368
1369		if (*count < MEMORY_OBJECT_BEHAVE_INFO_COUNT) {
1370                        ret = KERN_INVALID_ARGUMENT;
1371                        break;
1372                }
1373
1374                behave = (memory_object_behave_info_t) attributes;
1375                behave->copy_strategy = object->copy_strategy;
1376		behave->temporary = object->temporary;
1377#if notyet	/* remove when vm_msync complies and clean in place fini */
1378                behave->invalidate = object->invalidate;
1379#else
1380		behave->invalidate = FALSE;
1381#endif
1382		behave->advisory_pageout = object->advisory_pageout;
1383//		behave->silent_overwrite = object->silent_overwrite;
1384		behave->silent_overwrite = FALSE;
1385                *count = MEMORY_OBJECT_BEHAVE_INFO_COUNT;
1386		break;
1387	    }
1388
1389	    case MEMORY_OBJECT_PERFORMANCE_INFO:
1390	    {
1391		memory_object_perf_info_t	perf;
1392
1393		if (*count < MEMORY_OBJECT_PERF_INFO_COUNT) {
1394			ret = KERN_INVALID_ARGUMENT;
1395			break;
1396		}
1397
1398		perf = (memory_object_perf_info_t) attributes;
1399		perf->cluster_size = PAGE_SIZE;
1400		perf->may_cache = object->can_persist;
1401
1402		*count = MEMORY_OBJECT_PERF_INFO_COUNT;
1403		break;
1404	    }
1405
1406            case OLD_MEMORY_OBJECT_ATTRIBUTE_INFO:
1407            {
1408                old_memory_object_attr_info_t       attr;
1409
1410                if (*count < OLD_MEMORY_OBJECT_ATTR_INFO_COUNT) {
1411                        ret = KERN_INVALID_ARGUMENT;
1412                        break;
1413                }
1414
1415                attr = (old_memory_object_attr_info_t) attributes;
1416        	attr->may_cache = object->can_persist;
1417        	attr->copy_strategy = object->copy_strategy;
1418
1419                *count = OLD_MEMORY_OBJECT_ATTR_INFO_COUNT;
1420                break;
1421            }
1422
1423            case MEMORY_OBJECT_ATTRIBUTE_INFO:
1424            {
1425                memory_object_attr_info_t       attr;
1426
1427                if (*count < MEMORY_OBJECT_ATTR_INFO_COUNT) {
1428                        ret = KERN_INVALID_ARGUMENT;
1429                        break;
1430                }
1431
1432                attr = (memory_object_attr_info_t) attributes;
1433        	attr->copy_strategy = object->copy_strategy;
1434		attr->cluster_size = PAGE_SIZE;
1435        	attr->may_cache_object = object->can_persist;
1436		attr->temporary = object->temporary;
1437
1438                *count = MEMORY_OBJECT_ATTR_INFO_COUNT;
1439                break;
1440            }
1441
1442	    default:
1443		ret = KERN_INVALID_ARGUMENT;
1444		break;
1445	}
1446
1447        vm_object_unlock(object);
1448
1449        return(ret);
1450}
1451
1452
1453kern_return_t
1454memory_object_iopl_request(
1455	ipc_port_t		port,
1456	memory_object_offset_t	offset,
1457	upl_size_t		*upl_size,
1458	upl_t			*upl_ptr,
1459	upl_page_info_array_t	user_page_list,
1460	unsigned int		*page_list_count,
1461	int			*flags)
1462{
1463	vm_object_t		object;
1464	kern_return_t		ret;
1465	int			caller_flags;
1466
1467	caller_flags = *flags;
1468
1469	if (caller_flags & ~UPL_VALID_FLAGS) {
1470		/*
1471		 * For forward compatibility's sake,
1472		 * reject any unknown flag.
1473		 */
1474		return KERN_INVALID_VALUE;
1475	}
1476
1477	if (ip_kotype(port) == IKOT_NAMED_ENTRY) {
1478		vm_named_entry_t	named_entry;
1479
1480		named_entry = (vm_named_entry_t)port->ip_kobject;
1481		/* a few checks to make sure user is obeying rules */
1482		if(*upl_size == 0) {
1483			if(offset >= named_entry->size)
1484				return(KERN_INVALID_RIGHT);
1485			*upl_size = (upl_size_t)(named_entry->size - offset);
1486			if (*upl_size != named_entry->size - offset)
1487				return KERN_INVALID_ARGUMENT;
1488		}
1489		if(caller_flags & UPL_COPYOUT_FROM) {
1490			if((named_entry->protection & VM_PROT_READ)
1491						!= VM_PROT_READ) {
1492				return(KERN_INVALID_RIGHT);
1493			}
1494		} else {
1495			if((named_entry->protection &
1496				(VM_PROT_READ | VM_PROT_WRITE))
1497				!= (VM_PROT_READ | VM_PROT_WRITE)) {
1498				return(KERN_INVALID_RIGHT);
1499			}
1500		}
1501		if(named_entry->size < (offset + *upl_size))
1502			return(KERN_INVALID_ARGUMENT);
1503
1504		/* the callers parameter offset is defined to be the */
1505		/* offset from beginning of named entry offset in object */
1506		offset = offset + named_entry->offset;
1507
1508		if (named_entry->is_sub_map ||
1509		    named_entry->is_copy)
1510			return KERN_INVALID_ARGUMENT;
1511
1512		named_entry_lock(named_entry);
1513
1514		if (named_entry->is_pager) {
1515			object = vm_object_enter(named_entry->backing.pager,
1516					named_entry->offset + named_entry->size,
1517					named_entry->internal,
1518					FALSE,
1519					FALSE);
1520			if (object == VM_OBJECT_NULL) {
1521				named_entry_unlock(named_entry);
1522				return(KERN_INVALID_OBJECT);
1523			}
1524
1525			/* JMM - drop reference on pager here? */
1526
1527			/* create an extra reference for the named entry */
1528			vm_object_lock(object);
1529			vm_object_reference_locked(object);
1530			named_entry->backing.object = object;
1531			named_entry->is_pager = FALSE;
1532			named_entry_unlock(named_entry);
1533
1534			/* wait for object to be ready */
1535			while (!object->pager_ready) {
1536				vm_object_wait(object,
1537						VM_OBJECT_EVENT_PAGER_READY,
1538						THREAD_UNINT);
1539				vm_object_lock(object);
1540			}
1541			vm_object_unlock(object);
1542		} else {
1543			/* This is the case where we are going to map */
1544			/* an already mapped object.  If the object is */
1545			/* not ready it is internal.  An external     */
1546			/* object cannot be mapped until it is ready  */
1547			/* we can therefore avoid the ready check     */
1548			/* in this case.  */
1549			object = named_entry->backing.object;
1550			vm_object_reference(object);
1551			named_entry_unlock(named_entry);
1552		}
1553	} else if (ip_kotype(port) == IKOT_MEM_OBJ_CONTROL) {
1554		memory_object_control_t	control;
1555		control = (memory_object_control_t) port;
1556		if (control == NULL)
1557			return (KERN_INVALID_ARGUMENT);
1558		object = memory_object_control_to_vm_object(control);
1559		if (object == VM_OBJECT_NULL)
1560			return (KERN_INVALID_ARGUMENT);
1561		vm_object_reference(object);
1562	} else {
1563		return KERN_INVALID_ARGUMENT;
1564	}
1565	if (object == VM_OBJECT_NULL)
1566		return (KERN_INVALID_ARGUMENT);
1567
1568	if (!object->private) {
1569		if (*upl_size > (MAX_UPL_TRANSFER*PAGE_SIZE))
1570			*upl_size = (MAX_UPL_TRANSFER*PAGE_SIZE);
1571		if (object->phys_contiguous) {
1572			*flags = UPL_PHYS_CONTIG;
1573		} else {
1574			*flags = 0;
1575		}
1576	} else {
1577		*flags = UPL_DEV_MEMORY | UPL_PHYS_CONTIG;
1578	}
1579
1580	ret = vm_object_iopl_request(object,
1581				     offset,
1582				     *upl_size,
1583				     upl_ptr,
1584				     user_page_list,
1585				     page_list_count,
1586				     caller_flags);
1587	vm_object_deallocate(object);
1588	return ret;
1589}
1590
1591/*
1592 *	Routine:	memory_object_upl_request [interface]
1593 *	Purpose:
1594 *		Cause the population of a portion of a vm_object.
1595 *		Depending on the nature of the request, the pages
1596 *		returned may be contain valid data or be uninitialized.
1597 *
1598 */
1599
1600kern_return_t
1601memory_object_upl_request(
1602	memory_object_control_t	control,
1603	memory_object_offset_t	offset,
1604	upl_size_t		size,
1605	upl_t			*upl_ptr,
1606	upl_page_info_array_t	user_page_list,
1607	unsigned int		*page_list_count,
1608	int			cntrl_flags)
1609{
1610	vm_object_t		object;
1611
1612	object = memory_object_control_to_vm_object(control);
1613	if (object == VM_OBJECT_NULL)
1614		return (KERN_TERMINATED);
1615
1616	return vm_object_upl_request(object,
1617				     offset,
1618				     size,
1619				     upl_ptr,
1620				     user_page_list,
1621				     page_list_count,
1622				     cntrl_flags);
1623}
1624
1625/*
1626 *	Routine:	memory_object_super_upl_request [interface]
1627 *	Purpose:
1628 *		Cause the population of a portion of a vm_object
1629 *		in much the same way as memory_object_upl_request.
1630 *		Depending on the nature of the request, the pages
1631 *		returned may be contain valid data or be uninitialized.
1632 *		However, the region may be expanded up to the super
1633 *		cluster size provided.
1634 */
1635
1636kern_return_t
1637memory_object_super_upl_request(
1638	memory_object_control_t control,
1639	memory_object_offset_t	offset,
1640	upl_size_t		size,
1641	upl_size_t		super_cluster,
1642	upl_t			*upl,
1643	upl_page_info_t		*user_page_list,
1644	unsigned int		*page_list_count,
1645	int			cntrl_flags)
1646{
1647	vm_object_t		object;
1648
1649	object = memory_object_control_to_vm_object(control);
1650	if (object == VM_OBJECT_NULL)
1651		return (KERN_INVALID_ARGUMENT);
1652
1653	return vm_object_super_upl_request(object,
1654					   offset,
1655					   size,
1656					   super_cluster,
1657					   upl,
1658					   user_page_list,
1659					   page_list_count,
1660					   cntrl_flags);
1661}
1662
1663kern_return_t
1664memory_object_cluster_size(memory_object_control_t control, memory_object_offset_t *start,
1665			   vm_size_t *length, uint32_t *io_streaming, memory_object_fault_info_t fault_info)
1666{
1667	vm_object_t		object;
1668
1669	object = memory_object_control_to_vm_object(control);
1670
1671	if (object == VM_OBJECT_NULL || object->paging_offset > *start)
1672		return (KERN_INVALID_ARGUMENT);
1673
1674	*start -= object->paging_offset;
1675
1676	vm_object_cluster_size(object, (vm_object_offset_t *)start, length, (vm_object_fault_info_t)fault_info, io_streaming);
1677
1678	*start += object->paging_offset;
1679
1680	return (KERN_SUCCESS);
1681}
1682
1683
1684int vm_stat_discard_cleared_reply = 0;
1685int vm_stat_discard_cleared_unset = 0;
1686int vm_stat_discard_cleared_too_late = 0;
1687
1688
1689
1690/*
1691 *	Routine:	host_default_memory_manager [interface]
1692 *	Purpose:
1693 *		set/get the default memory manager port and default cluster
1694 *		size.
1695 *
1696 *		If successful, consumes the supplied naked send right.
1697 */
1698kern_return_t
1699host_default_memory_manager(
1700	host_priv_t		host_priv,
1701	memory_object_default_t	*default_manager,
1702	__unused memory_object_cluster_size_t cluster_size)
1703{
1704	memory_object_default_t current_manager;
1705	memory_object_default_t new_manager;
1706	memory_object_default_t returned_manager;
1707	kern_return_t result = KERN_SUCCESS;
1708
1709	if (host_priv == HOST_PRIV_NULL)
1710		return(KERN_INVALID_HOST);
1711
1712	assert(host_priv == &realhost);
1713
1714	new_manager = *default_manager;
1715	lck_mtx_lock(&memory_manager_default_lock);
1716	current_manager = memory_manager_default;
1717	returned_manager = MEMORY_OBJECT_DEFAULT_NULL;
1718
1719	if (new_manager == MEMORY_OBJECT_DEFAULT_NULL) {
1720		/*
1721		 *	Retrieve the current value.
1722		 */
1723		returned_manager = current_manager;
1724		memory_object_default_reference(returned_manager);
1725	} else {
1726
1727		/*
1728		 *	If this is the first non-null manager, start
1729		 *	up the internal pager support.
1730		 */
1731		if (current_manager == MEMORY_OBJECT_DEFAULT_NULL) {
1732			result = vm_pageout_internal_start();
1733			if (result != KERN_SUCCESS)
1734				goto out;
1735		}
1736
1737		/*
1738		 *	Retrieve the current value,
1739		 *	and replace it with the supplied value.
1740		 *	We return the old reference to the caller
1741		 *	but we have to take a reference on the new
1742		 *	one.
1743		 */
1744		returned_manager = current_manager;
1745		memory_manager_default = new_manager;
1746		memory_object_default_reference(new_manager);
1747
1748		/*
1749		 *	In case anyone's been waiting for a memory
1750		 *	manager to be established, wake them up.
1751		 */
1752
1753		thread_wakeup((event_t) &memory_manager_default);
1754
1755		/*
1756		 * Now that we have a default pager for anonymous memory,
1757		 * reactivate all the throttled pages (i.e. dirty pages with
1758		 * no pager).
1759		 */
1760		if (current_manager == MEMORY_OBJECT_DEFAULT_NULL)
1761		{
1762			vm_page_reactivate_all_throttled();
1763		}
1764	}
1765 out:
1766	lck_mtx_unlock(&memory_manager_default_lock);
1767
1768	*default_manager = returned_manager;
1769	return(result);
1770}
1771
1772/*
1773 *	Routine:	memory_manager_default_reference
1774 *	Purpose:
1775 *		Returns a naked send right for the default
1776 *		memory manager.  The returned right is always
1777 *		valid (not IP_NULL or IP_DEAD).
1778 */
1779
1780__private_extern__ memory_object_default_t
1781memory_manager_default_reference(void)
1782{
1783	memory_object_default_t current_manager;
1784
1785	lck_mtx_lock(&memory_manager_default_lock);
1786	current_manager = memory_manager_default;
1787	while (current_manager == MEMORY_OBJECT_DEFAULT_NULL) {
1788		wait_result_t res;
1789
1790		res = lck_mtx_sleep(&memory_manager_default_lock,
1791					LCK_SLEEP_DEFAULT,
1792					(event_t) &memory_manager_default,
1793					THREAD_UNINT);
1794		assert(res == THREAD_AWAKENED);
1795		current_manager = memory_manager_default;
1796	}
1797	memory_object_default_reference(current_manager);
1798	lck_mtx_unlock(&memory_manager_default_lock);
1799
1800	return current_manager;
1801}
1802
1803/*
1804 *	Routine:	memory_manager_default_check
1805 *
1806 *	Purpose:
1807 *		Check whether a default memory manager has been set
1808 *		up yet, or not. Returns KERN_SUCCESS if dmm exists,
1809 *		and KERN_FAILURE if dmm does not exist.
1810 *
1811 *		If there is no default memory manager, log an error,
1812 *		but only the first time.
1813 *
1814 */
1815__private_extern__ kern_return_t
1816memory_manager_default_check(void)
1817{
1818	memory_object_default_t current;
1819
1820	lck_mtx_lock(&memory_manager_default_lock);
1821	current = memory_manager_default;
1822	if (current == MEMORY_OBJECT_DEFAULT_NULL) {
1823		static boolean_t logged;	/* initialized to 0 */
1824		boolean_t	complain = !logged;
1825		logged = TRUE;
1826		lck_mtx_unlock(&memory_manager_default_lock);
1827		if (complain)
1828			printf("Warning: No default memory manager\n");
1829		return(KERN_FAILURE);
1830	} else {
1831		lck_mtx_unlock(&memory_manager_default_lock);
1832		return(KERN_SUCCESS);
1833	}
1834}
1835
1836__private_extern__ void
1837memory_manager_default_init(void)
1838{
1839	memory_manager_default = MEMORY_OBJECT_DEFAULT_NULL;
1840	lck_mtx_init(&memory_manager_default_lock, &vm_object_lck_grp, &vm_object_lck_attr);
1841}
1842
1843
1844
1845/* Allow manipulation of individual page state.  This is actually part of */
1846/* the UPL regimen but takes place on the object rather than on a UPL */
1847
1848kern_return_t
1849memory_object_page_op(
1850	memory_object_control_t	control,
1851	memory_object_offset_t	offset,
1852	int			ops,
1853	ppnum_t			*phys_entry,
1854	int			*flags)
1855{
1856	vm_object_t		object;
1857
1858	object = memory_object_control_to_vm_object(control);
1859	if (object == VM_OBJECT_NULL)
1860		return (KERN_INVALID_ARGUMENT);
1861
1862	return vm_object_page_op(object, offset, ops, phys_entry, flags);
1863}
1864
1865/*
1866 * memory_object_range_op offers performance enhancement over
1867 * memory_object_page_op for page_op functions which do not require page
1868 * level state to be returned from the call.  Page_op was created to provide
1869 * a low-cost alternative to page manipulation via UPLs when only a single
1870 * page was involved.  The range_op call establishes the ability in the _op
1871 * family of functions to work on multiple pages where the lack of page level
1872 * state handling allows the caller to avoid the overhead of the upl structures.
1873 */
1874
1875kern_return_t
1876memory_object_range_op(
1877	memory_object_control_t	control,
1878	memory_object_offset_t	offset_beg,
1879	memory_object_offset_t	offset_end,
1880	int                     ops,
1881	int                     *range)
1882{
1883	vm_object_t		object;
1884
1885	object = memory_object_control_to_vm_object(control);
1886	if (object == VM_OBJECT_NULL)
1887		return (KERN_INVALID_ARGUMENT);
1888
1889	return vm_object_range_op(object,
1890				  offset_beg,
1891				  offset_end,
1892				  ops,
1893				  (uint32_t *) range);
1894}
1895
1896
1897void
1898memory_object_mark_used(
1899        memory_object_control_t	control)
1900{
1901	vm_object_t		object;
1902
1903	if (control == NULL)
1904		return;
1905
1906	object = memory_object_control_to_vm_object(control);
1907
1908	if (object != VM_OBJECT_NULL)
1909		vm_object_cache_remove(object);
1910}
1911
1912
1913void
1914memory_object_mark_unused(
1915	memory_object_control_t	control,
1916	__unused boolean_t	rage)
1917{
1918	vm_object_t		object;
1919
1920	if (control == NULL)
1921		return;
1922
1923	object = memory_object_control_to_vm_object(control);
1924
1925	if (object != VM_OBJECT_NULL)
1926		vm_object_cache_add(object);
1927}
1928
1929
1930kern_return_t
1931memory_object_pages_resident(
1932	memory_object_control_t	control,
1933	boolean_t			*	has_pages_resident)
1934{
1935	vm_object_t		object;
1936
1937	*has_pages_resident = FALSE;
1938
1939	object = memory_object_control_to_vm_object(control);
1940	if (object == VM_OBJECT_NULL)
1941		return (KERN_INVALID_ARGUMENT);
1942
1943	if (object->resident_page_count)
1944		*has_pages_resident = TRUE;
1945
1946	return (KERN_SUCCESS);
1947}
1948
1949kern_return_t
1950memory_object_signed(
1951	memory_object_control_t	control,
1952	boolean_t		is_signed)
1953{
1954	vm_object_t	object;
1955
1956	object = memory_object_control_to_vm_object(control);
1957	if (object == VM_OBJECT_NULL)
1958		return KERN_INVALID_ARGUMENT;
1959
1960	vm_object_lock(object);
1961	object->code_signed = is_signed;
1962	vm_object_unlock(object);
1963
1964	return KERN_SUCCESS;
1965}
1966
1967boolean_t
1968memory_object_is_signed(
1969	memory_object_control_t	control)
1970{
1971	boolean_t	is_signed;
1972	vm_object_t	object;
1973
1974	object = memory_object_control_to_vm_object(control);
1975	if (object == VM_OBJECT_NULL)
1976		return FALSE;
1977
1978	vm_object_lock_shared(object);
1979	is_signed = object->code_signed;
1980	vm_object_unlock(object);
1981
1982	return is_signed;
1983}
1984
1985boolean_t
1986memory_object_is_slid(
1987	memory_object_control_t	control)
1988{
1989	vm_object_t	object = VM_OBJECT_NULL;
1990
1991	object = memory_object_control_to_vm_object(control);
1992	if (object == VM_OBJECT_NULL)
1993		return FALSE;
1994
1995	return object->object_slid;
1996}
1997
1998static zone_t mem_obj_control_zone;
1999
2000__private_extern__ void
2001memory_object_control_bootstrap(void)
2002{
2003	int	i;
2004
2005	i = (vm_size_t) sizeof (struct memory_object_control);
2006	mem_obj_control_zone = zinit (i, 8192*i, 4096, "mem_obj_control");
2007	zone_change(mem_obj_control_zone, Z_CALLERACCT, FALSE);
2008	zone_change(mem_obj_control_zone, Z_NOENCRYPT, TRUE);
2009	return;
2010}
2011
2012__private_extern__ memory_object_control_t
2013memory_object_control_allocate(
2014	vm_object_t		object)
2015{
2016	memory_object_control_t control;
2017
2018	control = (memory_object_control_t)zalloc(mem_obj_control_zone);
2019	if (control != MEMORY_OBJECT_CONTROL_NULL) {
2020		control->moc_object = object;
2021		control->moc_ikot = IKOT_MEM_OBJ_CONTROL; /* fake ip_kotype */
2022	}
2023	return (control);
2024}
2025
2026__private_extern__ void
2027memory_object_control_collapse(
2028	memory_object_control_t control,
2029	vm_object_t		object)
2030{
2031	assert((control->moc_object != VM_OBJECT_NULL) &&
2032	       (control->moc_object != object));
2033	control->moc_object = object;
2034}
2035
2036__private_extern__ vm_object_t
2037memory_object_control_to_vm_object(
2038	memory_object_control_t	control)
2039{
2040	if (control == MEMORY_OBJECT_CONTROL_NULL ||
2041	    control->moc_ikot != IKOT_MEM_OBJ_CONTROL)
2042		return VM_OBJECT_NULL;
2043
2044	return (control->moc_object);
2045}
2046
2047memory_object_control_t
2048convert_port_to_mo_control(
2049	__unused mach_port_t	port)
2050{
2051	return MEMORY_OBJECT_CONTROL_NULL;
2052}
2053
2054
2055mach_port_t
2056convert_mo_control_to_port(
2057	__unused memory_object_control_t	control)
2058{
2059	return MACH_PORT_NULL;
2060}
2061
2062void
2063memory_object_control_reference(
2064	__unused memory_object_control_t	control)
2065{
2066	return;
2067}
2068
2069/*
2070 * We only every issue one of these references, so kill it
2071 * when that gets released (should switch the real reference
2072 * counting in true port-less EMMI).
2073 */
2074void
2075memory_object_control_deallocate(
2076	memory_object_control_t	control)
2077{
2078	zfree(mem_obj_control_zone, control);
2079}
2080
2081void
2082memory_object_control_disable(
2083	memory_object_control_t	control)
2084{
2085	assert(control->moc_object != VM_OBJECT_NULL);
2086	control->moc_object = VM_OBJECT_NULL;
2087}
2088
2089void
2090memory_object_default_reference(
2091	memory_object_default_t dmm)
2092{
2093	ipc_port_make_send(dmm);
2094}
2095
2096void
2097memory_object_default_deallocate(
2098	memory_object_default_t dmm)
2099{
2100	ipc_port_release_send(dmm);
2101}
2102
2103memory_object_t
2104convert_port_to_memory_object(
2105	__unused mach_port_t	port)
2106{
2107	return (MEMORY_OBJECT_NULL);
2108}
2109
2110
2111mach_port_t
2112convert_memory_object_to_port(
2113	__unused memory_object_t	object)
2114{
2115	return (MACH_PORT_NULL);
2116}
2117
2118
2119/* Routine memory_object_reference */
2120void memory_object_reference(
2121	memory_object_t memory_object)
2122{
2123	(memory_object->mo_pager_ops->memory_object_reference)(
2124		memory_object);
2125}
2126
2127/* Routine memory_object_deallocate */
2128void memory_object_deallocate(
2129	memory_object_t memory_object)
2130{
2131	(memory_object->mo_pager_ops->memory_object_deallocate)(
2132		 memory_object);
2133}
2134
2135
2136/* Routine memory_object_init */
2137kern_return_t memory_object_init
2138(
2139	memory_object_t memory_object,
2140	memory_object_control_t memory_control,
2141	memory_object_cluster_size_t memory_object_page_size
2142)
2143{
2144	return (memory_object->mo_pager_ops->memory_object_init)(
2145		memory_object,
2146		memory_control,
2147		memory_object_page_size);
2148}
2149
2150/* Routine memory_object_terminate */
2151kern_return_t memory_object_terminate
2152(
2153	memory_object_t memory_object
2154)
2155{
2156	return (memory_object->mo_pager_ops->memory_object_terminate)(
2157		memory_object);
2158}
2159
2160/* Routine memory_object_data_request */
2161kern_return_t memory_object_data_request
2162(
2163	memory_object_t memory_object,
2164	memory_object_offset_t offset,
2165	memory_object_cluster_size_t length,
2166	vm_prot_t desired_access,
2167	memory_object_fault_info_t fault_info
2168)
2169{
2170	return (memory_object->mo_pager_ops->memory_object_data_request)(
2171		memory_object,
2172		offset,
2173		length,
2174		desired_access,
2175		fault_info);
2176}
2177
2178/* Routine memory_object_data_return */
2179kern_return_t memory_object_data_return
2180(
2181	memory_object_t memory_object,
2182	memory_object_offset_t offset,
2183	memory_object_cluster_size_t size,
2184	memory_object_offset_t *resid_offset,
2185	int	*io_error,
2186	boolean_t dirty,
2187	boolean_t kernel_copy,
2188	int	upl_flags
2189)
2190{
2191	return (memory_object->mo_pager_ops->memory_object_data_return)(
2192		memory_object,
2193		offset,
2194		size,
2195		resid_offset,
2196		io_error,
2197		dirty,
2198		kernel_copy,
2199		upl_flags);
2200}
2201
2202/* Routine memory_object_data_initialize */
2203kern_return_t memory_object_data_initialize
2204(
2205	memory_object_t memory_object,
2206	memory_object_offset_t offset,
2207	memory_object_cluster_size_t size
2208)
2209{
2210	return (memory_object->mo_pager_ops->memory_object_data_initialize)(
2211		memory_object,
2212		offset,
2213		size);
2214}
2215
2216/* Routine memory_object_data_unlock */
2217kern_return_t memory_object_data_unlock
2218(
2219	memory_object_t memory_object,
2220	memory_object_offset_t offset,
2221	memory_object_size_t size,
2222	vm_prot_t desired_access
2223)
2224{
2225	return (memory_object->mo_pager_ops->memory_object_data_unlock)(
2226		memory_object,
2227		offset,
2228		size,
2229		desired_access);
2230}
2231
2232/* Routine memory_object_synchronize */
2233kern_return_t memory_object_synchronize
2234(
2235	memory_object_t memory_object,
2236	memory_object_offset_t offset,
2237	memory_object_size_t size,
2238	vm_sync_t sync_flags
2239)
2240{
2241	return (memory_object->mo_pager_ops->memory_object_synchronize)(
2242		memory_object,
2243		offset,
2244		size,
2245		sync_flags);
2246}
2247
2248
2249/*
2250 * memory_object_map() is called by VM (in vm_map_enter() and its variants)
2251 * each time a "named" VM object gets mapped directly or indirectly
2252 * (copy-on-write mapping).  A "named" VM object has an extra reference held
2253 * by the pager to keep it alive until the pager decides that the
2254 * memory object (and its VM object) can be reclaimed.
2255 * VM calls memory_object_last_unmap() (in vm_object_deallocate()) when all
2256 * the mappings of that memory object have been removed.
2257 *
2258 * For a given VM object, calls to memory_object_map() and memory_object_unmap()
2259 * are serialized (through object->mapping_in_progress), to ensure that the
2260 * pager gets a consistent view of the mapping status of the memory object.
2261 *
2262 * This allows the pager to keep track of how many times a memory object
2263 * has been mapped and with which protections, to decide when it can be
2264 * reclaimed.
2265 */
2266
2267/* Routine memory_object_map */
2268kern_return_t memory_object_map
2269(
2270	memory_object_t memory_object,
2271	vm_prot_t prot
2272)
2273{
2274	return (memory_object->mo_pager_ops->memory_object_map)(
2275		memory_object,
2276		prot);
2277}
2278
2279/* Routine memory_object_last_unmap */
2280kern_return_t memory_object_last_unmap
2281(
2282	memory_object_t memory_object
2283)
2284{
2285	return (memory_object->mo_pager_ops->memory_object_last_unmap)(
2286		memory_object);
2287}
2288
2289/* Routine memory_object_data_reclaim */
2290kern_return_t memory_object_data_reclaim
2291(
2292	memory_object_t memory_object,
2293	boolean_t	reclaim_backing_store
2294)
2295{
2296	if (memory_object->mo_pager_ops->memory_object_data_reclaim == NULL)
2297		return KERN_NOT_SUPPORTED;
2298	return (memory_object->mo_pager_ops->memory_object_data_reclaim)(
2299		memory_object,
2300		reclaim_backing_store);
2301}
2302
2303/* Routine memory_object_create */
2304kern_return_t memory_object_create
2305(
2306	memory_object_default_t default_memory_manager,
2307	vm_size_t new_memory_object_size,
2308	memory_object_t *new_memory_object
2309)
2310{
2311	return default_pager_memory_object_create(default_memory_manager,
2312						  new_memory_object_size,
2313						  new_memory_object);
2314}
2315
2316upl_t
2317convert_port_to_upl(
2318	ipc_port_t	port)
2319{
2320	upl_t upl;
2321
2322	ip_lock(port);
2323	if (!ip_active(port) || (ip_kotype(port) != IKOT_UPL)) {
2324			ip_unlock(port);
2325			return (upl_t)NULL;
2326	}
2327	upl = (upl_t) port->ip_kobject;
2328	ip_unlock(port);
2329	upl_lock(upl);
2330	upl->ref_count+=1;
2331	upl_unlock(upl);
2332	return upl;
2333}
2334
2335mach_port_t
2336convert_upl_to_port(
2337	__unused upl_t		upl)
2338{
2339	return MACH_PORT_NULL;
2340}
2341
2342__private_extern__ void
2343upl_no_senders(
2344	__unused ipc_port_t				port,
2345	__unused mach_port_mscount_t	mscount)
2346{
2347	return;
2348}
2349