VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/MMAllPagePool.cpp@ 14155

Last change on this file since 14155 was 14155, checked in by vboxsync, 16 years ago

#1865: MM - dealt with the last R3R0PTRTYPEs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1/* $Id: MMAllPagePool.cpp 14155 2008-11-12 23:55:08Z vboxsync $ */
2/** @file
3 * MM - Memory Manager - Page Pool.
4 *
5 * @remarks This file is NOT built for the raw-mode context.
6 */
7
8/*
9 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_MM_POOL
28#include <VBox/mm.h>
29#include <VBox/pgm.h>
30#include <VBox/stam.h>
31#include "MMInternal.h"
32#include <VBox/vm.h>
33#include <VBox/param.h>
34#include <VBox/err.h>
35#include <VBox/log.h>
36#include <iprt/alloc.h>
37#include <iprt/assert.h>
38#include <iprt/string.h>
39#define USE_INLINE_ASM_BIT_OPS
40#ifdef USE_INLINE_ASM_BIT_OPS
41# include <iprt/asm.h>
42#endif
43
44
45
46#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE_R0
47
48/**
49 * Converts a pool physical address to a linear address.
50 * The specified allocation type must match with the address.
51 *
52 * @returns Physical address.
53 * @returns NULL if not found or eType is not matching.
54 * @param pPool Pointer to the page pool.
55 * @param HCPhys The address to convert.
56 * @thread The Emulation Thread.
57 */
58void *mmPagePoolPhys2Ptr(PMMPAGEPOOL pPool, RTHCPHYS HCPhys)
59{
60#if 0 /** @todo have to fix the debugger, but until then this is going on my nerves. */
61#ifdef IN_RING3
62 VM_ASSERT_EMT(pPool->pVM);
63#endif
64#endif
65
66 /*
67 * Lookup the virtual address.
68 */
69 PMMPPLOOKUPHCPHYS pLookup = (PMMPPLOOKUPHCPHYS)RTAvlHCPhysGet(&pPool->pLookupPhys, HCPhys & X86_PTE_PAE_PG_MASK);
70 if (pLookup)
71 {
72 STAM_COUNTER_INC(&pPool->cToVirtCalls);
73 PSUPPAGE pPhysPage = pLookup->pPhysPage;
74 PMMPAGESUBPOOL pSubPool = (PMMPAGESUBPOOL)pPhysPage->uReserved;
75 unsigned iPage = pPhysPage - pSubPool->paPhysPages;
76 return (char *)pSubPool->pvPages + (HCPhys & PAGE_OFFSET_MASK) + (iPage << PAGE_SHIFT);
77 }
78 return NULL;
79}
80
81
82/**
83 * Convert physical address of a page to a HC virtual address.
84 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
85 * and MMR3PageAllocLow().
86 *
87 * @returns VBox status code.
88 * @param pVM VM handle.
89 * @param HCPhysPage The physical address of a page.
90 * @param ppvPage Where to store the address corresponding to HCPhysPage.
91 * @thread The Emulation Thread.
92 */
93VMMDECL(int) MMPagePhys2PageEx(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage)
94{
95 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
96 if (!pvPage)
97 {
98 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
99 if (!pvPage)
100 {
101 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
102 AssertMsg(pvPage, ("Invalid HCPhysPage=%RHp specified\n", HCPhysPage));
103 return VERR_INVALID_POINTER;
104 }
105 }
106 *ppvPage = pvPage;
107 return VINF_SUCCESS;
108}
109
110#endif /* !VBOX_WITH_2X_4GB_ADDR_SPACE_R0 */
111#ifdef IN_RING3
112
113/**
114 * Convert physical address of a page to a HC virtual address.
115 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
116 * and MMR3PageAllocLow().
117 *
118 * @returns Pointer to the page at that physical address.
119 * @param pVM VM handle.
120 * @param HCPhysPage The physical address of a page.
121 * @thread The Emulation Thread.
122 */
123VMMDECL(void *) MMPagePhys2Page(PVM pVM, RTHCPHYS HCPhysPage)
124{
125 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
126 if (!pvPage)
127 {
128 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
129 if (!pvPage)
130 {
131 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
132 AssertMsg(pvPage, ("Invalid HCPhysPage=%RHp specified\n", HCPhysPage));
133 }
134 }
135 return pvPage;
136}
137
138
139/**
140 * Try convert physical address of a page to a HC virtual address.
141 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
142 * and MMR3PageAllocLow().
143 *
144 * @returns VBox status code.
145 * @param pVM VM handle.
146 * @param HCPhysPage The physical address of a page.
147 * @param ppvPage Where to store the address corresponding to HCPhysPage.
148 * @thread The Emulation Thread.
149 */
150VMMDECL(int) MMPagePhys2PageTry(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage)
151{
152 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
153 if (!pvPage)
154 {
155 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
156 if (!pvPage)
157 return VERR_INVALID_POINTER;
158 }
159 *ppvPage = pvPage;
160 return VINF_SUCCESS;
161}
162
163
164/**
165 * Converts a pool address to a physical address.
166 * The specified allocation type must match with the address.
167 *
168 * @returns Physical address.
169 * @returns NIL_RTHCPHYS if not found or eType is not matching.
170 * @param pPool Pointer to the page pool.
171 * @param pv The address to convert.
172 * @thread The Emulation Thread.
173 */
174RTHCPHYS mmPagePoolPtr2Phys(PMMPAGEPOOL pPool, void *pv)
175{
176#ifdef IN_RING3
177 VM_ASSERT_EMT(pPool->pVM);
178#endif
179 /*
180 * Lookup the virtual address.
181 */
182 PMMPPLOOKUPHCPTR pLookup = (PMMPPLOOKUPHCPTR)RTAvlPVGetBestFit(&pPool->pLookupVirt, pv, false);
183 if (pLookup)
184 {
185 unsigned iPage = ((char *)pv - (char *)pLookup->pSubPool->pvPages) >> PAGE_SHIFT;
186 if (iPage < pLookup->pSubPool->cPages)
187 {
188 /*
189 * Convert the virtual address to a physical address.
190 */
191 STAM_COUNTER_INC(&pPool->cToPhysCalls);
192 AssertMsg( pLookup->pSubPool->paPhysPages[iPage].Phys
193 && !(pLookup->pSubPool->paPhysPages[iPage].Phys & PAGE_OFFSET_MASK),
194 ("Phys=%#x\n", pLookup->pSubPool->paPhysPages[iPage].Phys));
195 AssertMsg((uintptr_t)pLookup->pSubPool == pLookup->pSubPool->paPhysPages[iPage].uReserved,
196 ("pSubPool=%p uReserved=%p\n", pLookup->pSubPool, pLookup->pSubPool->paPhysPages[iPage].uReserved));
197 return pLookup->pSubPool->paPhysPages[iPage].Phys + ((uintptr_t)pv & PAGE_OFFSET_MASK);
198 }
199 }
200 return NIL_RTHCPHYS;
201}
202
203
204/**
205 * Convert a page in the page pool to a HC physical address.
206 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
207 * and MMR3PageAllocLow().
208 *
209 * @returns Physical address for the specified page table.
210 * @param pVM VM handle.
211 * @param pvPage Page which physical address we query.
212 * @thread The Emulation Thread.
213 */
214VMMDECL(RTHCPHYS) MMPage2Phys(PVM pVM, void *pvPage)
215{
216 RTHCPHYS HCPhys = mmPagePoolPtr2Phys(pVM->mm.s.CTX_SUFF(pPagePool), pvPage);
217 if (HCPhys == NIL_RTHCPHYS)
218 {
219 HCPhys = mmPagePoolPtr2Phys(pVM->mm.s.CTX_SUFF(pPagePoolLow), pvPage);
220 if (HCPhys == NIL_RTHCPHYS)
221 {
222 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
223 AssertMsgFailed(("Invalid pvPage=%p specified\n", pvPage));
224 }
225 }
226 return HCPhys;
227}
228
229
230#endif /* IN_RING3 */
231
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette