VirtualBox

Changeset 19182 in vbox


Ignore:
Timestamp:
Apr 24, 2009 6:37:47 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
46494
Message:

DBGFAddr: Three new APIs for address conversion that takes threading into account.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/dbgf.h

    r18927 r19182  
    128128VMMR3DECL(void) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
    129129VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress);
     130VMMR3DECL(int)  DBGFR3AddrToPhys(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
     131VMMR3DECL(int)  DBGFR3AddrToHostPhys(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
     132VMMR3DECL(int)  DBGFR3AddrToVolatileR3Ptr(PVMCPU pVCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
    130133
    131134
  • trunk/src/VBox/VMM/DBGFAddr.cpp

    r18927 r19182  
    2626#define LOG_GROUP LOG_GROUP_DBGF
    2727#include <VBox/dbgf.h>
     28#include <VBox/pgm.h>
    2829#include <VBox/selm.h>
     30#include <VBox/mm.h>
    2931#include "DBGFInternal.h"
    3032#include <VBox/vm.h>
    31 #include <VBox/mm.h>
     33#include <VBox/param.h>
    3234#include <VBox/err.h>
    3335#include <VBox/log.h>
     
    162164}
    163165
     166
     167/**
     168 * Called on the EMT for the VCpu.
     169 *
     170 * @returns VBox status code.
     171 * @param   pVCpu           The virtual CPU handle.
     172 * @param   pAddress        The address.
     173 * @param   pGCPhys         Where to return the physical address.
     174 */
     175static DECLCALLBACK(int) dbgfR3AddrToPhysOnVCpu(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
     176{
     177    VMCPU_ASSERT_EMT(pVCpu);
     178    /* This is just a wrapper because we cannot pass FlatPtr thru VMR3ReqCall directly. */
     179    return PGMGstGetPage(pVCpu, pAddress->FlatPtr, NULL, pGCPhys);
     180}
     181
     182
     183/**
     184 * Converts an address to a guest physical address.
     185 *
     186 * @returns VBox status code.
     187 * @retval  VINF_SUCCESS
     188 * @retval  VERR_INVALID_PARAMETER if the address is invalid.
     189 * @retval  VERR_INVALID_STATE if the VM is being terminated or if the virtual
     190 *          CPU handle is invalid.
     191 * @retval  VERR_NOT_SUPPORTED is the type of address cannot be converted.
     192 * @retval  VERR_PAGE_NOT_PRESENT
     193 * @retval  VERR_PAGE_TABLE_NOT_PRESENT
     194 * @retval  VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT
     195 * @retval  VERR_PAGE_MAP_LEVEL4_NOT_PRESENT
     196 *
     197 * @param   pVCpu           The virtual CPU handle.
     198 * @param   pAddress        The address.
     199 * @param   pGCPhys         Where to return the physical address.
     200 */
     201VMMR3DECL(int)  DBGFR3AddrToPhys(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys)
     202{
     203    /*
     204     * Parameter validation.
     205     */
     206    AssertPtr(pGCPhys);
     207    *pGCPhys = NIL_RTGCPHYS;
     208    AssertPtr(pAddress);
     209    AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER);
     210    VMCPU_ASSERT_VALID_EXT_RETURN(pVCpu->pVMR3, VERR_INVALID_STATE);
     211
     212    /*
     213     * Convert by address type.
     214     */
     215    int rc;
     216    if (pAddress->fFlags & DBGFADDRESS_FLAGS_HMA)
     217        rc = VERR_NOT_SUPPORTED;
     218    else if (pAddress->fFlags & DBGFADDRESS_FLAGS_PHYS)
     219    {
     220        *pGCPhys = pAddress->FlatPtr;
     221        rc = VINF_SUCCESS;
     222    }
     223    else if (VMCPU_IS_EMT(pVCpu))
     224        rc = dbgfR3AddrToPhysOnVCpu(pVCpu, pAddress, pGCPhys);
     225    else
     226    {
     227        PVMREQ pReq = NULL;
     228        rc = VMR3ReqCall(pVCpu->pVMR3, VMREQDEST_FROM_VMCPU(pVCpu), &pReq, RT_INDEFINITE_WAIT,
     229                         (PFNRT)dbgfR3AddrToPhysOnVCpu, 3, pVCpu, pAddress, pGCPhys);
     230        if (RT_SUCCESS(rc))
     231        {
     232            rc = pReq->iStatus;
     233            VMR3ReqFree(pReq);
     234        }
     235    }
     236    return rc;
     237}
     238
     239
     240/**
     241 * Converts an address to a host physical address.
     242 *
     243 * @returns VBox status code.
     244 * @retval  VINF_SUCCESS
     245 * @retval  VERR_INVALID_PARAMETER if the address is invalid.
     246 * @retval  VERR_INVALID_STATE if the VM is being terminated or if the virtual
     247 *          CPU handle is invalid.
     248 * @retval  VERR_NOT_SUPPORTED is the type of address cannot be converted.
     249 * @retval  VERR_PAGE_NOT_PRESENT
     250 * @retval  VERR_PAGE_TABLE_NOT_PRESENT
     251 * @retval  VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT
     252 * @retval  VERR_PAGE_MAP_LEVEL4_NOT_PRESENT
     253 * @retval  VERR_PGM_PHYS_PAGE_RESERVED
     254 * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS
     255 *
     256 * @param   pVCpu           The virtual CPU handle.
     257 * @param   pAddress        The address.
     258 * @param   pHCPhys         Where to return the physical address.
     259 */
     260VMMR3DECL(int)  DBGFR3AddrToHostPhys(PVMCPU pVCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys)
     261{
     262    /*
     263     * Parameter validation.
     264     */
     265    AssertPtr(pHCPhys);
     266    *pHCPhys = NIL_RTHCPHYS;
     267    AssertPtr(pAddress);
     268    AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER);
     269    VMCPU_ASSERT_VALID_EXT_RETURN(pVCpu->pVMR3, VERR_INVALID_STATE);
     270
     271    /*
     272     * Convert it if we can.
     273     */
     274    int rc;
     275    if (pAddress->fFlags & DBGFADDRESS_FLAGS_HMA)
     276        rc = VERR_NOT_SUPPORTED; /** @todo implement this */
     277    else
     278    {
     279        RTGCPHYS GCPhys;
     280        rc = DBGFR3AddrToPhys(pVCpu, pAddress, &GCPhys);
     281        if (RT_SUCCESS(rc))
     282            rc = PGMPhysGCPhys2HCPhys(pVCpu->pVMR3, pAddress->FlatPtr, pHCPhys);
     283    }
     284    return rc;
     285}
     286
     287
     288/**
     289 * Called on the EMT for the VCpu.
     290 *
     291 * @returns VBox status code.
     292 * @param   pVCpu           The virtual CPU handle.
     293 * @param   pAddress        The address.
     294 * @param   fReadOnly       Whether returning a read-only page is fine or not.
     295 * @param   ppvR3Ptr        Where to return the address.
     296 */
     297static DECLCALLBACK(int) dbgfR3AddrToVolatileR3PtrOnVCpu(PVMCPU pVCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr)
     298{
     299    VMCPU_ASSERT_EMT(pVCpu);
     300
     301    int rc;
     302    PVM pVM = pVCpu->CTX_SUFF(pVM);
     303    if (pAddress->fFlags & DBGFADDRESS_FLAGS_HMA)
     304    {
     305        rc = VERR_NOT_SUPPORTED; /** @todo create some dedicated errors for this stuff. */
     306        /** @todo this may assert, create a debug version of this which doesn't. */
     307        if (MMHyperIsInsideArea(pVM, pAddress->FlatPtr))
     308        {
     309            void *pv = MMHyperRCToCC(pVM, (RTRCPTR)pAddress->FlatPtr);
     310            if (pv)
     311            {
     312                *ppvR3Ptr = pv;
     313                rc = VINF_SUCCESS;
     314            }
     315        }
     316    }
     317    else
     318    {
     319        /*
     320         * This is a tad ugly, but it gets the job done.
     321         */
     322        PGMPAGEMAPLOCK Lock;
     323        if (pAddress->fFlags & DBGFADDRESS_FLAGS_PHYS)
     324        {
     325            if (fReadOnly)
     326                rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, pAddress->FlatPtr, (void const **)ppvR3Ptr, &Lock);
     327            else
     328                rc = PGMPhysGCPhys2CCPtr(pVM, pAddress->FlatPtr, ppvR3Ptr, &Lock);
     329        }
     330        else
     331        {
     332            if (fReadOnly)
     333                rc = PGMPhysGCPtr2CCPtrReadOnly(pVCpu, pAddress->FlatPtr, (void const **)ppvR3Ptr, &Lock);
     334            else
     335                rc = PGMPhysGCPtr2CCPtr(pVCpu, pAddress->FlatPtr, ppvR3Ptr, &Lock);
     336        }
     337        if (RT_SUCCESS(rc))
     338            PGMPhysReleasePageMappingLock(pVM, &Lock);
     339    }
     340    return rc;
     341}
     342
     343
     344
     345
     346/**
     347 * Converts an address to a volatile host virtual address.
     348 *
     349 * @returns VBox status code.
     350 * @retval  VINF_SUCCESS
     351 * @retval  VERR_INVALID_PARAMETER if the address is invalid.
     352 * @retval  VERR_INVALID_STATE if the VM is being terminated or if the virtual
     353 *          CPU handle is invalid.
     354 * @retval  VERR_NOT_SUPPORTED is the type of address cannot be converted.
     355 * @retval  VERR_PAGE_NOT_PRESENT
     356 * @retval  VERR_PAGE_TABLE_NOT_PRESENT
     357 * @retval  VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT
     358 * @retval  VERR_PAGE_MAP_LEVEL4_NOT_PRESENT
     359 * @retval  VERR_PGM_PHYS_PAGE_RESERVED
     360 * @retval  VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS
     361 *
     362 * @param   pVCpu           The virtual CPU handle.
     363 * @param   pAddress        The address.
     364 * @param   fReadOnly       Whether returning a read-only page is fine or not.
     365 *                          If set to thru the page may have to be made writable
     366 *                          before we return.
     367 * @param   ppvR3Ptr        Where to return the address.
     368 */
     369VMMR3DECL(int)  DBGFR3AddrToVolatileR3Ptr(PVMCPU pVCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr)
     370{
     371    /*
     372     * Parameter validation.
     373     */
     374    AssertPtr(ppvR3Ptr);
     375    *ppvR3Ptr = NULL;
     376    AssertPtr(pAddress);
     377    AssertReturn(DBGFADDRESS_IS_VALID(pAddress), VERR_INVALID_PARAMETER);
     378    VMCPU_ASSERT_VALID_EXT_RETURN(pVCpu->pVMR3, VERR_INVALID_STATE);
     379
     380    /*
     381     * Convert it.
     382     */
     383    int rc;
     384    if (VMCPU_IS_EMT(pVCpu))
     385        rc = dbgfR3AddrToVolatileR3PtrOnVCpu(pVCpu, pAddress, fReadOnly, ppvR3Ptr);
     386    else
     387    {
     388        PVMREQ pReq = NULL;
     389        rc = VMR3ReqCall(pVCpu->pVMR3, VMREQDEST_FROM_VMCPU(pVCpu), &pReq, RT_INDEFINITE_WAIT,
     390                         (PFNRT)dbgfR3AddrToVolatileR3PtrOnVCpu, 4, pVCpu, pAddress, fReadOnly, ppvR3Ptr);
     391        if (RT_SUCCESS(rc))
     392        {
     393            rc = pReq->iStatus;
     394            VMR3ReqFree(pReq);
     395        }
     396    }
     397
     398    return rc;
     399}
     400
Note: See TracChangeset for help on using the changeset viewer.

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