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