VirtualBox

Ignore:
Timestamp:
May 12, 2010 3:11:09 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
61539
Message:

Shared paging updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMSharedPage.cpp

    r29411 r29424  
    3535#include <iprt/mem.h>
    3636
    37 
    38 #ifdef VBOX_WITH_PAGE_SHARING
    39 /**
    40  * Rendezvous callback that will be called once.
    41  *
    42  * @returns VBox strict status code.
    43  * @param   pVM                 VM handle.
    44  * @param   pVCpu               The VMCPU handle for the calling EMT.
    45  * @param   pvUser              PGMMREGISTERSHAREDMODULEREQ
    46  */
    47 static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
    48 {
    49     PGMMREGISTERSHAREDMODULEREQ pReq = (PGMMREGISTERSHAREDMODULEREQ)pvUser;
    50 
    51     return VMMR3CallR0(pVM, VMMR0_DO_PGM_CHECK_SHARED_MODULE, 0, &pReq->Hdr);
    52 }
    53 
    54 /**
    55  * Shared module registration helper (called on the way out).
    56  *
    57  * @param   pVM         The VM handle.
    58  * @param   pReq        Registration request info
    59  */
    60 static DECLCALLBACK(void) pgmR3SharedModuleRegisterHelper(PVM pVM, PGMMREGISTERSHAREDMODULEREQ pReq)
    61 {
    62     int rc;
    63    
    64     rc = GMMR3RegisterSharedModule(pVM, pReq);
    65     Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SHARED_MODULE_COLLISION || rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED);
    66     if (rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED)
    67     {
    68         PVMCPU   pVCpu = VMMGetCpu(pVM);
    69         unsigned cFlushedPages = 0;
    70 
    71         /** todo count copy-on-write actions in the trap handler so we don't have to check everything all the time! */
    72 
    73         /* Count the number of shared pages that were changed (copy-on-write). */
    74         for (unsigned i = 0; i < pReq->cRegions; i++)
    75         {
    76             Assert((pReq->aRegions[i].cbRegion & 0xfff) == 0);
    77             Assert((pReq->aRegions[i].GCRegionAddr & 0xfff) == 0);
    78 
    79             RTGCPTR GCRegion  = pReq->aRegions[i].GCRegionAddr;
    80             uint32_t cbRegion = pReq->aRegions[i].cbRegion & ~0xfff;
    81 
    82             while (cbRegion)
    83             {
    84                 RTGCPHYS GCPhys;
    85                 uint64_t fFlags;
    86 
    87                 rc = PGMGstGetPage(pVCpu, GCRegion, &fFlags, &GCPhys);
    88                 if (    rc == VINF_SUCCESS
    89                     &&  !(fFlags & X86_PTE_RW))
    90                 {
    91                     PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
    92                     if (    pPage
    93                         &&  !PGM_PAGE_IS_SHARED(pPage))
    94                     {
    95                         cFlushedPages++;
    96                     }
    97                 }
    98 
    99                 GCRegion += PAGE_SIZE;
    100                 cbRegion -= PAGE_SIZE;
    101             }
    102         }
    103 
    104         if (cFlushedPages > 32)
    105             rc = VINF_SUCCESS;  /* force recheck below */
    106     }
    107     /* Full (re)check needed? */
    108     if (rc == VINF_SUCCESS)
    109     {
    110         pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    111         pReq->Hdr.cbReq = RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[pReq->cRegions]);
    112 
    113         /* We must stall other VCPUs as we'd otherwise have to send IPI flush commands for every single change we make. */
    114         rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3SharedModuleRegRendezvous, pReq);
    115         AssertRC(rc);
    116     }
    117     RTMemFree(pReq);
    118     return;
    119 }
    120 #endif
    12137
    12238/**
     
    16177    }
    16278
    163     /* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */
    164     return VMR3ReqCallNoWait(pVM, VMMGetCpuId(pVM), (PFNRT)pgmR3SharedModuleRegisterHelper, 2, pVM, pReq);
     79    int rc = GMMR3RegisterSharedModule(pVM, pReq);
     80    RTMemFree(pReq);
     81    Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SHARED_MODULE_COLLISION || rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED);
     82    if (RT_FAILURE(rc))
     83        return rc;
     84    return VINF_SUCCESS;
    16585#else
    16686    return VERR_NOT_IMPLEMENTED;
    16787#endif
    16888}
    169 
    170 
    171 #ifdef VBOX_WITH_PAGE_SHARING
    172 /**
    173  * Shared module unregistration helper (called on the way out).
    174  *
    175  * @param   pVM         The VM handle.
    176  * @param   pReq        Unregistration request info
    177  */
    178 static DECLCALLBACK(void) pgmR3SharedModuleUnregisterHelper(PVM pVM, PGMMREGISTERSHAREDMODULEREQ pReq)
    179 {
    180     int rc;
    181    
    182     rc = GMMR3UnregisterSharedModule(pVM, pReq);
    183     RTMemFree(pReq);
    184     return;
    185 }
    186 #endif
    18789
    18890/**
     
    212114        ||  RTStrCopy(pReq->szVersion, sizeof(pReq->szVersion), pszVersion) != VINF_SUCCESS)
    213115    {
     116        RTMemFree(pReq);
    214117        return VERR_BUFFER_OVERFLOW;
    215118    }
    216     /* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */
    217     return VMR3ReqCallNoWait(pVM, VMMGetCpuId(pVM), (PFNRT)pgmR3SharedModuleUnregisterHelper, 2, pVM, pReq);
     119    int rc = GMMR3UnregisterSharedModule(pVM, pReq);
     120    RTMemFree(pReq);
     121    return rc;
    218122#else
    219123    return VERR_NOT_IMPLEMENTED;
    220124#endif
    221125}
     126
     127#ifdef VBOX_WITH_PAGE_SHARING
     128/**
     129 * Rendezvous callback that will be called once.
     130 *
     131 * @returns VBox strict status code.
     132 * @param   pVM                 VM handle.
     133 * @param   pVCpu               The VMCPU handle for the calling EMT.
     134 * @param   pvUser              Not used;
     135 */
     136static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
     137{
     138    return GMMR3CheckSharedModules(pVM);
     139}
     140
     141/**
     142 * Shared module unregistration helper (called on the way out).
     143 *
     144 * @param   pVM         The VM handle.
     145 */
     146static DECLCALLBACK(void) pgmR3CheckSharedModulesHelper(PVM pVM)
     147{   
     148    /* We must stall other VCPUs as we'd otherwise have to send IPI flush commands for every single change we make. */
     149    int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3SharedModuleRegRendezvous, NULL);
     150    AssertRC(rc);
     151}
     152#endif
     153
     154/**
     155 * Check all registered modules for changes.
     156 *
     157 * @returns VBox status code.
     158 * @param   pVM                 VM handle
     159 */
     160VMMR3DECL(int) PGMR3SharedModuleCheckAll(PVM pVM)
     161{
     162#ifdef VBOX_WITH_PAGE_SHARING
     163    /* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */
     164    return VMR3ReqCallNoWait(pVM, VMMGetCpuId(pVM), (PFNRT)pgmR3CheckSharedModulesHelper, 1, pVM);
     165#else
     166    return VERR_NOT_IMPLEMENTED;
     167#endif
     168}
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