~ubuntu-branches/ubuntu/gutsy/virtualbox-ose/gutsy

« back to all changes in this revision

Viewing changes to src/VBox/VMM/VMMAll/MMAllPagePool.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2007-09-08 16:44:58 UTC
  • Revision ID: james.westby@ubuntu.com-20070908164458-wao29470vqtr8ksy
Tags: upstream-1.5.0-dfsg2
ImportĀ upstreamĀ versionĀ 1.5.0-dfsg2

Show diffs side-by-side

added added

removed removed

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