xref: /illumos-gate/usr/src/uts/i86pc/os/hold_page.c (revision 6eaf49db)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/hold_page.h>
28 
29 #if defined(__xpv)
30 #include <sys/hypervisor.h>
31 #endif
32 
33 int
plat_hold_page(pfn_t pfn,int lock,page_t ** pp_ret)34 plat_hold_page(pfn_t pfn, int lock, page_t **pp_ret)
35 {
36 	page_t *pp = page_numtopp_nolock(pfn);
37 
38 	if (pp == NULL)
39 		return (PLAT_HOLD_FAIL);
40 
41 #if !defined(__xpv)
42 	/*
43 	 * Pages are locked SE_SHARED because some hypervisors
44 	 * like xVM ESX reclaim Guest OS memory by locking
45 	 * it SE_EXCL so we want to leave these pages alone.
46 	 */
47 	if (lock == PLAT_HOLD_LOCK) {
48 		ASSERT(pp_ret != NULL);
49 		if (page_trylock(pp, SE_SHARED) == 0)
50 			return (PLAT_HOLD_FAIL);
51 	}
52 #else	/* __xpv */
53 	if (lock == PLAT_HOLD_LOCK) {
54 		ASSERT(pp_ret != NULL);
55 		if (page_trylock(pp, SE_EXCL) == 0)
56 			return (PLAT_HOLD_FAIL);
57 	}
58 
59 	if (mfn_list[pfn] == MFN_INVALID) {
60 		/* We failed - release the lock if we grabbed it earlier */
61 		if (lock == PLAT_HOLD_LOCK) {
62 			page_unlock(pp);
63 		}
64 		return (PLAT_HOLD_FAIL);
65 	}
66 #endif	/* __xpv */
67 
68 	if (lock == PLAT_HOLD_LOCK)
69 		*pp_ret = pp;
70 
71 	return (PLAT_HOLD_OK);
72 }
73 
74 void
plat_release_page(page_t * pp)75 plat_release_page(page_t *pp)
76 {
77 	ASSERT((pp != NULL) && PAGE_LOCKED(pp));
78 	page_unlock(pp);
79 }
80