VirtualBox

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

Last change on this file since 47660 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.4 KB
Line 
1/* $Id: MMAllPagePool.cpp 44528 2013-02-04 14:27:54Z 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-2012 Oracle Corporation
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
20/*******************************************************************************
21* Header Files *
22*******************************************************************************/
23#define LOG_GROUP LOG_GROUP_MM_POOL
24#include <VBox/vmm/mm.h>
25#include <VBox/vmm/pgm.h>
26#include <VBox/vmm/stam.h>
27#include "MMInternal.h"
28#include <VBox/vmm/vm.h>
29#include <VBox/param.h>
30#include <VBox/err.h>
31#include <VBox/log.h>
32#include <iprt/alloc.h>
33#include <iprt/assert.h>
34#include <iprt/string.h>
35#define USE_INLINE_ASM_BIT_OPS
36#ifdef USE_INLINE_ASM_BIT_OPS
37# include <iprt/asm.h>
38#endif
39
40
41#if !defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) && !defined(IN_RC)
42
43/**
44 * Converts a pool physical address to a linear address.
45 * The specified allocation type must match with the address.
46 *
47 * @returns Physical address.
48 * @returns NULL if not found or eType is not matching.
49 * @param pPool Pointer to the page pool.
50 * @param HCPhys The address to convert.
51 * @thread The Emulation Thread.
52 */
53void *mmPagePoolPhys2Ptr(PMMPAGEPOOL pPool, RTHCPHYS HCPhys)
54{
55#if 0 /** @todo have to fix the debugger, but until then this is going on my nerves. */
56#ifdef IN_RING3
57 VM_ASSERT_EMT(pPool->pVM);
58#endif
59#endif
60
61 /*
62 * Lookup the virtual address.
63 */
64 PMMPPLOOKUPHCPHYS pLookup = (PMMPPLOOKUPHCPHYS)RTAvlHCPhysGet(&pPool->pLookupPhys, HCPhys & X86_PTE_PAE_PG_MASK);
65 if (pLookup)
66 {
67 STAM_COUNTER_INC(&pPool->cToVirtCalls);
68 PSUPPAGE pPhysPage = pLookup->pPhysPage;
69 PMMPAGESUBPOOL pSubPool = (PMMPAGESUBPOOL)pPhysPage->uReserved;
70 unsigned iPage = pPhysPage - pSubPool->paPhysPages;
71 return (char *)pSubPool->pvPages + (HCPhys & PAGE_OFFSET_MASK) + (iPage << PAGE_SHIFT);
72 }
73 return NULL;
74}
75
76
77/**
78 * Convert physical address of a page to a HC virtual address.
79 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
80 * and MMR3PageAllocLow().
81 *
82 * @returns VBox status code.
83 * @param pVM Pointer to the VM.
84 * @param HCPhysPage The physical address of a page.
85 * @param ppvPage Where to store the address corresponding to HCPhysPage.
86 * @thread The Emulation Thread.
87 */
88VMMDECL(int) MMPagePhys2PageEx(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage)
89{
90 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
91 if (!pvPage)
92 {
93 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
94 if (!pvPage)
95 {
96 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
97 AssertMsg(pvPage, ("Invalid HCPhysPage=%RHp specified\n", HCPhysPage));
98 return VERR_INVALID_POINTER;
99 }
100 }
101 *ppvPage = pvPage;
102 return VINF_SUCCESS;
103}
104
105#endif /* !VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */
106#ifdef IN_RING3
107
108/**
109 * Convert physical address of a page to a HC virtual address.
110 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
111 * and MMR3PageAllocLow().
112 *
113 * @returns Pointer to the page at that physical address.
114 * @param pVM Pointer to the VM.
115 * @param HCPhysPage The physical address of a page.
116 * @thread The Emulation Thread.
117 */
118VMMDECL(void *) MMPagePhys2Page(PVM pVM, RTHCPHYS HCPhysPage)
119{
120 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
121 if (!pvPage)
122 {
123 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
124 if (!pvPage)
125 {
126 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
127 AssertMsg(pvPage, ("Invalid HCPhysPage=%RHp specified\n", HCPhysPage));
128 }
129 }
130 return pvPage;
131}
132
133
134/**
135 * Try convert physical address of a page to a HC virtual address.
136 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
137 * and MMR3PageAllocLow().
138 *
139 * @returns VBox status code.
140 * @param pVM Pointer to the VM.
141 * @param HCPhysPage The physical address of a page.
142 * @param ppvPage Where to store the address corresponding to HCPhysPage.
143 * @thread The Emulation Thread.
144 */
145VMMDECL(int) MMPagePhys2PageTry(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage)
146{
147 void *pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePool), HCPhysPage);
148 if (!pvPage)
149 {
150 pvPage = mmPagePoolPhys2Ptr(pVM->mm.s.CTX_SUFF(pPagePoolLow), HCPhysPage);
151 if (!pvPage)
152 return VERR_INVALID_POINTER;
153 }
154 *ppvPage = pvPage;
155 return VINF_SUCCESS;
156}
157
158
159/**
160 * Converts a pool address to a physical address.
161 * The specified allocation type must match with the address.
162 *
163 * @returns Physical address.
164 * @returns NIL_RTHCPHYS if not found or eType is not matching.
165 * @param pPool Pointer to the page pool.
166 * @param pv The address to convert.
167 * @thread The Emulation Thread.
168 */
169RTHCPHYS mmPagePoolPtr2Phys(PMMPAGEPOOL pPool, void *pv)
170{
171#ifdef IN_RING3
172 VM_ASSERT_EMT(pPool->pVM);
173#endif
174 /*
175 * Lookup the virtual address.
176 */
177 PMMPPLOOKUPHCPTR pLookup = (PMMPPLOOKUPHCPTR)RTAvlPVGetBestFit(&pPool->pLookupVirt, pv, false);
178 if (pLookup)
179 {
180 unsigned iPage = ((char *)pv - (char *)pLookup->pSubPool->pvPages) >> PAGE_SHIFT;
181 if (iPage < pLookup->pSubPool->cPages)
182 {
183 /*
184 * Convert the virtual address to a physical address.
185 */
186 STAM_COUNTER_INC(&pPool->cToPhysCalls);
187 AssertMsg( pLookup->pSubPool->paPhysPages[iPage].Phys
188 && !(pLookup->pSubPool->paPhysPages[iPage].Phys & PAGE_OFFSET_MASK),
189 ("Phys=%#x\n", pLookup->pSubPool->paPhysPages[iPage].Phys));
190 AssertMsg((uintptr_t)pLookup->pSubPool == pLookup->pSubPool->paPhysPages[iPage].uReserved,
191 ("pSubPool=%p uReserved=%p\n", pLookup->pSubPool, pLookup->pSubPool->paPhysPages[iPage].uReserved));
192 return pLookup->pSubPool->paPhysPages[iPage].Phys + ((uintptr_t)pv & PAGE_OFFSET_MASK);
193 }
194 }
195 return NIL_RTHCPHYS;
196}
197
198
199/**
200 * Convert a page in the page pool to a HC physical address.
201 * This works for pages allocated by MMR3PageAlloc(), MMR3PageAllocPhys()
202 * and MMR3PageAllocLow().
203 *
204 * @returns Physical address for the specified page table.
205 * @param pVM Pointer to the VM.
206 * @param pvPage Page which physical address we query.
207 * @thread The Emulation Thread.
208 */
209VMMDECL(RTHCPHYS) MMPage2Phys(PVM pVM, void *pvPage)
210{
211 RTHCPHYS HCPhys = mmPagePoolPtr2Phys(pVM->mm.s.CTX_SUFF(pPagePool), pvPage);
212 if (HCPhys == NIL_RTHCPHYS)
213 {
214 HCPhys = mmPagePoolPtr2Phys(pVM->mm.s.CTX_SUFF(pPagePoolLow), pvPage);
215 if (HCPhys == NIL_RTHCPHYS)
216 {
217 STAM_COUNTER_INC(&pVM->mm.s.CTX_SUFF(pPagePool)->cErrors);
218 AssertMsgFailed(("Invalid pvPage=%p specified\n", pvPage));
219 }
220 }
221 return HCPhys;
222}
223
224
225#endif /* IN_RING3 */
226
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