xref: /onnv-gate/usr/src/uts/i86pc/os/hold_page.c (revision 8706:87b8c2f25cf2)
13446Smrj /*
23446Smrj  * CDDL HEADER START
33446Smrj  *
43446Smrj  * The contents of this file are subject to the terms of the
53446Smrj  * Common Development and Distribution License (the "License").
63446Smrj  * You may not use this file except in compliance with the License.
73446Smrj  *
83446Smrj  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93446Smrj  * or http://www.opensolaris.org/os/licensing.
103446Smrj  * See the License for the specific language governing permissions
113446Smrj  * and limitations under the License.
123446Smrj  *
133446Smrj  * When distributing Covered Code, include this CDDL HEADER in each
143446Smrj  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153446Smrj  * If applicable, add the following below this CDDL HEADER, with the
163446Smrj  * fields enclosed by brackets "[]" replaced with your own identifying
173446Smrj  * information: Portions Copyright [yyyy] [name of copyright owner]
183446Smrj  *
193446Smrj  * CDDL HEADER END
203446Smrj  */
213446Smrj 
223446Smrj /*
23*8706SStan.Studzinski@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
243446Smrj  * Use is subject to license terms.
253446Smrj  */
263446Smrj 
273446Smrj #include <sys/hold_page.h>
283446Smrj 
295084Sjohnlev #if defined(__xpv)
305084Sjohnlev #include <sys/hypervisor.h>
315084Sjohnlev #endif
325084Sjohnlev 
333446Smrj int
plat_hold_page(pfn_t pfn,int lock,page_t ** pp_ret)343446Smrj plat_hold_page(pfn_t pfn, int lock, page_t **pp_ret)
353446Smrj {
365084Sjohnlev 	page_t *pp = page_numtopp_nolock(pfn);
375084Sjohnlev 
385084Sjohnlev 	if (pp == NULL)
395084Sjohnlev 		return (PLAT_HOLD_FAIL);
405084Sjohnlev 
41*8706SStan.Studzinski@Sun.COM #if !defined(__xpv)
42*8706SStan.Studzinski@Sun.COM 	/*
43*8706SStan.Studzinski@Sun.COM 	 * Pages are locked SE_SHARED because some hypervisors
44*8706SStan.Studzinski@Sun.COM 	 * like xVM ESX reclaim Guest OS memory by locking
45*8706SStan.Studzinski@Sun.COM 	 * it SE_EXCL so we want to leave these pages alone.
46*8706SStan.Studzinski@Sun.COM 	 */
47*8706SStan.Studzinski@Sun.COM 	if (lock == PLAT_HOLD_LOCK) {
48*8706SStan.Studzinski@Sun.COM 		ASSERT(pp_ret != NULL);
49*8706SStan.Studzinski@Sun.COM 		if (page_trylock(pp, SE_SHARED) == 0)
50*8706SStan.Studzinski@Sun.COM 			return (PLAT_HOLD_FAIL);
51*8706SStan.Studzinski@Sun.COM 	}
52*8706SStan.Studzinski@Sun.COM #else	/* __xpv */
535084Sjohnlev 	if (lock == PLAT_HOLD_LOCK) {
545084Sjohnlev 		ASSERT(pp_ret != NULL);
555084Sjohnlev 		if (page_trylock(pp, SE_EXCL) == 0)
565084Sjohnlev 			return (PLAT_HOLD_FAIL);
575084Sjohnlev 	}
585084Sjohnlev 
595084Sjohnlev 	if (mfn_list[pfn] == MFN_INVALID) {
605084Sjohnlev 		/* We failed - release the lock if we grabbed it earlier */
615084Sjohnlev 		if (lock == PLAT_HOLD_LOCK) {
625084Sjohnlev 			page_unlock(pp);
635084Sjohnlev 		}
645084Sjohnlev 		return (PLAT_HOLD_FAIL);
655084Sjohnlev 	}
66*8706SStan.Studzinski@Sun.COM #endif	/* __xpv */
67*8706SStan.Studzinski@Sun.COM 
685084Sjohnlev 	if (lock == PLAT_HOLD_LOCK)
695084Sjohnlev 		*pp_ret = pp;
705084Sjohnlev 
713446Smrj 	return (PLAT_HOLD_OK);
723446Smrj }
733446Smrj 
743446Smrj void
plat_release_page(page_t * pp)753446Smrj plat_release_page(page_t *pp)
763446Smrj {
775084Sjohnlev 	ASSERT((pp != NULL) && PAGE_LOCKED(pp));
785084Sjohnlev 	page_unlock(pp);
793446Smrj }
80