VirtualBox

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

Last change on this file since 77807 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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