VirtualBox

Changeset 25643 in vbox


Ignore:
Timestamp:
Jan 5, 2010 8:29:27 AM (15 years ago)
Author:
vboxsync
Message:

VMMDev: loading of HGCM saved state does not rely on saved size of structures anymore (xTracker 4500)

Location:
trunk/src/VBox/Devices/VMMDev
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r25374 r25643  
    7878
    7979/** The saved state version. */
    80 #define VMMDEV_SAVED_STATE_VERSION          12
     80#define VMMDEV_SAVED_STATE_VERSION          13
    8181/** The saved state version used by VirtualBox 3.0.
    8282 *  This doesn't have the config part. */
  • trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp

    r25073 r25643  
    7979    struct VBOXHGCMCMD *pPrev;
    8080
    81     /* Size of memory buffer for this command structure, including trailing paHostParms.
    82      * This field simplifies loading of saved state.
    83      */
    84 /** @todo @bugref{4500} - Now that we require states to be portable between
    85  * systems and between 32-bit/64-bit variants of the same OS, this field no
    86  * longer simplifies loading of saved state. :-(  Needs proper fixing... */
    87     uint32_t cbCmd;
    88 /** HACK ALERT! (TEMPORARY)
    89  * Factor to muliply cbCmd by when reading it from a saved state.  */
    90 #define CMD_SIZE_HACK_FACTOR    4
    91 
    9281    /* The type of the command. */
    9382    VBOXHGCMCMDTYPE enmCmdType;
     
    455444}
    456445
    457 static void logRelSavedCmdSizeMismatch (const char *pszFunction, uint32_t cbExpected, uint32_t cbCmdSize)
    458 {
    459     LogRel(("Warning: VMMDev %s command length %d (expected %d)\n",
    460             pszFunction, cbCmdSize, cbExpected));
     446static void vmmdevRestoreSavedCommand(VBOXHGCMCMD *pCmd, VBOXHGCMCMD *pSavedCmd)
     447{
     448    /* Copy relevant saved command information to the new allocated structure. */
     449    pCmd->enmCmdType   = pSavedCmd->enmCmdType;
     450    pCmd->fCancelled   = pSavedCmd->fCancelled;
     451    pCmd->GCPhys       = pSavedCmd->GCPhys;
     452    pCmd->cbSize       = pSavedCmd->cbSize;
     453    pCmd->cLinPtrs     = pSavedCmd->cLinPtrs;
     454    pCmd->cLinPtrPages = pSavedCmd->cLinPtrPages;
     455    pCmd->paLinPtrs    = pSavedCmd->paLinPtrs;
     456   
     457    /* The new allocated command owns the 'paLinPtrs' pointer. */
     458    pSavedCmd->paLinPtrs = NULL;
    461459}
    462460
     
    477475        memcpy(pHGCMConnectCopy, pHGCMConnect, pHGCMConnect->header.header.size);
    478476
    479         pCmd->cbCmd       = cbCmdSize;
    480477        pCmd->paHostParms = NULL;
    481478        pCmd->cLinPtrs = 0;
     
    483480
    484481        /* Only allow the guest to use existing services! */
    485         Assert(pHGCMConnect->loc.type == VMMDevHGCMLoc_LocalHost_Existing);
    486         pHGCMConnect->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
     482        Assert(pHGCMConnectCopy->loc.type == VMMDevHGCMLoc_LocalHost_Existing);
     483        pHGCMConnectCopy->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
    487484
    488485        rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID);
     
    496493}
    497494
    498 static int vmmdevHGCMConnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd)
     495static int vmmdevHGCMConnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS GCPhys, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd, VBOXHGCMCMD **ppCmd)
    499496{
    500497    int rc = VINF_SUCCESS;
    501498
     499    /* Allocate buffer for the new command. */
    502500    uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD) + pHGCMConnect->header.header.size;
    503501
    504 #ifdef CMD_SIZE_HACK_FACTOR /*HACK ALERT!*/
    505     if (pSavedCmd->cbCmd * CMD_SIZE_HACK_FACTOR < cbCmdSize)
    506 #else
    507     if (pSavedCmd->cbCmd < cbCmdSize)
    508 #endif
    509     {
    510         logRelSavedCmdSizeMismatch ("HGCMConnect", pSavedCmd->cbCmd, cbCmdSize);
    511         return VERR_INVALID_PARAMETER;
    512     }
    513 
    514     VMMDevHGCMConnect *pHGCMConnectCopy = (VMMDevHGCMConnect *)(pSavedCmd+1);
    515 
    516     memcpy(pHGCMConnectCopy, pHGCMConnect, pHGCMConnect->header.header.size);
    517 
    518     /* Only allow the guest to use existing services! */
    519     Assert(pHGCMConnect->loc.type == VMMDevHGCMLoc_LocalHost_Existing);
    520     pHGCMConnect->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
    521 
    522     rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pSavedCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID);
    523     if (RT_SUCCESS (rc))
    524     {
    525         *pfHGCMCalled = true;
     502    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (cbCmdSize);
     503
     504    if (pCmd)
     505    {
     506        vmmdevRestoreSavedCommand(pCmd, pSavedCmd);
     507        *ppCmd = pCmd;
     508
     509        VMMDevHGCMConnect *pHGCMConnectCopy = (VMMDevHGCMConnect *)(pCmd+1);
     510
     511        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMConnect->header.header.size, VBOXHGCMCMDTYPE_CONNECT);
     512
     513        memcpy(pHGCMConnectCopy, pHGCMConnect, pHGCMConnect->header.header.size);
     514
     515        /* Only allow the guest to use existing services! */
     516        Assert(pHGCMConnectCopy->loc.type == VMMDevHGCMLoc_LocalHost_Existing);
     517        pHGCMConnectCopy->loc.type = VMMDevHGCMLoc_LocalHost_Existing;
     518
     519        rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID);
     520
     521        if (RT_SUCCESS (rc))
     522        {
     523            *pfHGCMCalled = true;
     524        }
     525    }
     526    else
     527    {
     528        rc = VERR_NO_MEMORY;
    526529    }
    527530
     
    541544        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMDisconnect->header.header.size, VBOXHGCMCMDTYPE_DISCONNECT);
    542545
    543         pCmd->cbCmd       = cbCmdSize;
    544546        pCmd->paHostParms = NULL;
    545547        pCmd->cLinPtrs = 0;
     
    556558}
    557559
    558 static int vmmdevHGCMDisconnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd)
     560static int vmmdevHGCMDisconnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPhys, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd, VBOXHGCMCMD **ppCmd)
    559561{
    560562    int rc = VINF_SUCCESS;
     
    562564    uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD);
    563565
    564 #ifdef CMD_SIZE_HACK_FACTOR  /*HACK ALERT!*/
    565     if (pSavedCmd->cbCmd * CMD_SIZE_HACK_FACTOR < cbCmdSize)
    566 #else
    567     if (pSavedCmd->cbCmd < cbCmdSize)
    568 #endif
    569     {
    570         logRelSavedCmdSizeMismatch ("HGCMConnect", pSavedCmd->cbCmd, cbCmdSize);
    571         return VERR_INVALID_PARAMETER;
    572     }
    573 
    574     rc = pVMMDevState->pHGCMDrv->pfnDisconnect (pVMMDevState->pHGCMDrv, pSavedCmd, pHGCMDisconnect->u32ClientID);
    575     if (RT_SUCCESS (rc))
    576     {
    577         *pfHGCMCalled = true;
     566    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (cbCmdSize);
     567
     568    if (pCmd)
     569    {
     570        vmmdevRestoreSavedCommand(pCmd, pSavedCmd);
     571        *ppCmd = pCmd;
     572
     573        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMDisconnect->header.header.size, VBOXHGCMCMDTYPE_DISCONNECT);
     574
     575        pCmd->paHostParms = NULL;
     576        pCmd->cLinPtrs = 0;
     577        pCmd->paLinPtrs = NULL;
     578
     579        rc = pVMMDevState->pHGCMDrv->pfnDisconnect (pVMMDevState->pHGCMDrv, pCmd, pHGCMDisconnect->u32ClientID);
     580
     581        if (RT_SUCCESS (rc))
     582        {
     583            *pfHGCMCalled = true;
     584        }
     585    }
     586    else
     587    {
     588        rc = VERR_NO_MEMORY;
    578589    }
    579590
     
    727738    memset (pCmd, 0, sizeof (*pCmd));
    728739
    729     pCmd->cbCmd       = cbCmdSize;
    730740    pCmd->paHostParms = NULL;
    731741    pCmd->cLinPtrs    = cLinPtrs;
     
    10871097
    10881098
    1089 static int vmmdevHGCMCallSaved (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, bool f64Bits, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd)
     1099static int vmmdevHGCMCallSaved (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, RTGCPHYS GCPhys, uint32_t cbHGCMCall, bool f64Bits, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd, VBOXHGCMCMD **ppCmd)
    10901100{
    10911101    int rc = VINF_SUCCESS;
     
    11071117     */
    11081118
    1109     pSavedCmd->paHostParms = NULL;
     1119    uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD) + cParms * sizeof (VBOXHGCMSVCPARM);
     1120
     1121    uint32_t i;
     1122
     1123    uint32_t cLinPtrs = 0;
     1124    uint32_t cLinPtrPages  = 0;
     1125
     1126    if (f64Bits)
     1127    {
     1128#ifdef VBOX_WITH_64_BITS_GUESTS
     1129        HGCMFunctionParameter64 *pGuestParm = VMMDEV_HGCM_CALL_PARMS64(pHGCMCall);
     1130#else
     1131        HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
     1132        AssertFailed (); /* This code should not be called in this case */
     1133#endif /* VBOX_WITH_64_BITS_GUESTS */
     1134
     1135        /* Look for pointer parameters, which require a host buffer. */
     1136        for (i = 0; i < cParms && RT_SUCCESS(rc); i++, pGuestParm++)
     1137        {
     1138            switch (pGuestParm->type)
     1139            {
     1140                case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
     1141                case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
     1142                case VMMDevHGCMParmType_LinAddr:     /* In & Out */
     1143                {
     1144                    if (pGuestParm->u.Pointer.size > 0)
     1145                    {
     1146                        /* Only pointers with some actual data are counted. */
     1147                        cbCmdSize += pGuestParm->u.Pointer.size;
     1148
     1149                        cLinPtrs++;
     1150                        /* Take the offset into the current page also into account! */
     1151                        cLinPtrPages += ((pGuestParm->u.Pointer.u.linearAddr & PAGE_OFFSET_MASK)
     1152                                          + pGuestParm->u.Pointer.size + PAGE_SIZE - 1) / PAGE_SIZE;
     1153                    }
     1154
     1155                    Log(("vmmdevHGCMCall: linptr size = %d\n", pGuestParm->u.Pointer.size));
     1156                } break;
     1157
     1158                case VMMDevHGCMParmType_PageList:
     1159                {
     1160                    cbCmdSize += pGuestParm->u.PageList.size;
     1161                    Log(("vmmdevHGCMCall: pagelist size = %d\n", pGuestParm->u.PageList.size));
     1162                } break;
     1163
     1164                case VMMDevHGCMParmType_32bit:
     1165                case VMMDevHGCMParmType_64bit:
     1166                {
     1167                } break;
     1168
     1169                default:
     1170                case VMMDevHGCMParmType_PhysAddr:
     1171                {
     1172                    AssertMsgFailed(("vmmdevHGCMCall: invalid parameter type %x\n", pGuestParm->type));
     1173                    rc = VERR_INVALID_PARAMETER;
     1174                    break;
     1175                }
     1176            }
     1177        }
     1178    }
     1179    else
     1180    {
     1181#ifdef VBOX_WITH_64_BITS_GUESTS
     1182        HGCMFunctionParameter32 *pGuestParm = VMMDEV_HGCM_CALL_PARMS32(pHGCMCall);
     1183#else
     1184        HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
     1185#endif /* VBOX_WITH_64_BITS_GUESTS */
     1186
     1187        /* Look for pointer parameters, which require a host buffer. */
     1188        for (i = 0; i < cParms && RT_SUCCESS(rc); i++, pGuestParm++)
     1189        {
     1190            switch (pGuestParm->type)
     1191            {
     1192                case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
     1193                case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
     1194                case VMMDevHGCMParmType_LinAddr:     /* In & Out */
     1195                {
     1196                    if (pGuestParm->u.Pointer.size > 0)
     1197                    {
     1198                        /* Only pointers with some actual data are counted. */
     1199                        cbCmdSize += pGuestParm->u.Pointer.size;
     1200
     1201                        cLinPtrs++;
     1202                        /* Take the offset into the current page also into account! */
     1203                        cLinPtrPages += ((pGuestParm->u.Pointer.u.linearAddr & PAGE_OFFSET_MASK)
     1204                                          + pGuestParm->u.Pointer.size + PAGE_SIZE - 1) / PAGE_SIZE;
     1205                    }
     1206
     1207                    Log(("vmmdevHGCMCall: linptr size = %d\n", pGuestParm->u.Pointer.size));
     1208                } break;
     1209
     1210                case VMMDevHGCMParmType_PageList:
     1211                {
     1212                    cbCmdSize += pGuestParm->u.PageList.size;
     1213                    Log(("vmmdevHGCMCall: pagelist size = %d\n", pGuestParm->u.PageList.size));
     1214                } break;
     1215
     1216                case VMMDevHGCMParmType_32bit:
     1217                case VMMDevHGCMParmType_64bit:
     1218                {
     1219                } break;
     1220
     1221                default:
     1222                {
     1223                    AssertMsgFailed(("vmmdevHGCMCall: invalid parameter type %x\n", pGuestParm->type));
     1224                    rc = VERR_INVALID_PARAMETER;
     1225                    break;
     1226                }
     1227            }
     1228        }
     1229    }
     1230
     1231    if (RT_FAILURE (rc))
     1232    {
     1233        return rc;
     1234    }
     1235
     1236    if (   pSavedCmd->cLinPtrs     != cLinPtrs
     1237        || pSavedCmd->cLinPtrPages != cLinPtrPages)
     1238    {
     1239        LogRel(("VMMDev: invalid saved command ptrs: %d/%d, pages %d/%d\n",
     1240                pSavedCmd->cLinPtrs, cLinPtrs, pSavedCmd->cLinPtrPages, cLinPtrPages));
     1241        AssertFailed();
     1242        return VERR_INVALID_PARAMETER;
     1243    }
     1244
     1245    PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (cbCmdSize);
     1246
     1247    if (pCmd == NULL)
     1248    {
     1249        return VERR_NO_MEMORY;
     1250    }
     1251
     1252    vmmdevRestoreSavedCommand(pCmd, pSavedCmd);
     1253    *ppCmd = pCmd;
     1254
     1255    vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMCall->header.header.size, VBOXHGCMCMDTYPE_CALL);
    11101256
    11111257    /* Process parameters, changing them to host context pointers for easy
     
    11171263    {
    11181264        /* Compute addresses of host parms array and first memory buffer. */
    1119         VBOXHGCMSVCPARM *pHostParm = (VBOXHGCMSVCPARM *)((uint8_t *)pSavedCmd + sizeof (struct VBOXHGCMCMD));
     1265        VBOXHGCMSVCPARM *pHostParm = (VBOXHGCMSVCPARM *)((uint8_t *)pCmd + sizeof (struct VBOXHGCMCMD));
    11201266
    11211267        uint8_t *pu8Buf = (uint8_t *)pHostParm + cParms * sizeof (VBOXHGCMSVCPARM);
    11221268
    1123         pSavedCmd->paHostParms = pHostParm;
     1269        pCmd->paHostParms = pHostParm;
    11241270
    11251271        uint32_t iParm;
     
    11861332                             if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_Out)
    11871333                             {
    1188                                  if (   iLinPtr >= pSavedCmd->cLinPtrs
    1189                                      || pSavedCmd->paLinPtrs[iLinPtr].iParm != iParm)
     1334                                 if (   iLinPtr >= pCmd->cLinPtrs
     1335                                     || pCmd->paLinPtrs[iLinPtr].iParm != iParm)
    11901336                                 {
    1191                                      logRelLoadStatePointerIndexMismatch (iParm, pSavedCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pSavedCmd->cLinPtrs);
     1337                                     logRelLoadStatePointerIndexMismatch (iParm, pCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pCmd->cLinPtrs);
    11921338                                     rc = VERR_INVALID_PARAMETER;
    11931339                                 }
    11941340                                 else
    11951341                                 {
    1196                                      VBOXHGCMLINPTR *pLinPtr = &pSavedCmd->paLinPtrs[iLinPtr];
     1342                                     VBOXHGCMLINPTR *pLinPtr = &pCmd->paLinPtrs[iLinPtr];
    11971343
    11981344                                     uint32_t iPage;
     
    13661512                             if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_Out)
    13671513                             {
    1368                                  if (   iLinPtr >= pSavedCmd->cLinPtrs
    1369                                      || pSavedCmd->paLinPtrs[iLinPtr].iParm != iParm)
     1514                                 if (   iLinPtr >= pCmd->cLinPtrs
     1515                                     || pCmd->paLinPtrs[iLinPtr].iParm != iParm)
    13701516                                 {
    1371                                      logRelLoadStatePointerIndexMismatch (iParm, pSavedCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pSavedCmd->cLinPtrs);
     1517                                     logRelLoadStatePointerIndexMismatch (iParm, pCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pCmd->cLinPtrs);
    13721518                                     rc = VERR_INVALID_PARAMETER;
    13731519                                 }
    13741520                                 else
    13751521                                 {
    1376                                      VBOXHGCMLINPTR *pLinPtr = &pSavedCmd->paLinPtrs[iLinPtr];
     1522                                     VBOXHGCMLINPTR *pLinPtr = &pCmd->paLinPtrs[iLinPtr];
    13771523
    13781524                                     uint32_t iPage;
     
    14921638    {
    14931639        /* Pass the function call to HGCM connector for actual processing */
    1494         rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pSavedCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pSavedCmd->paHostParms);
     1640        rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pCmd->paHostParms);
    14951641        if (RT_SUCCESS (rc))
    14961642        {
     
    21062252             */
    21072253
    2108             /* Size of entire command. */
    2109 /** @todo @bugref{4500} - Not portable, see other todos. */
    2110             rc = SSMR3PutU32(pSSM, pIter->cbCmd);
    2111             AssertRCReturn(rc, rc);
    2112 
    21132254            /* The type of the command. */
    21142255            rc = SSMR3PutU32(pSSM, (uint32_t)pIter->enmCmdType);
     
    22102351            AssertReturn(pCmd, VERR_NO_MEMORY);
    22112352
     2353            pCmd->enmCmdType = VBOXHGCMCMDTYPE_LOADSTATE; /* This marks the "old" saved command. */
     2354
    22122355            vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, cbSize, VBOXHGCMCMDTYPE_LOADSTATE);
    22132356        }
     
    22362379            LogFlowFunc (("Restoring %RGp size %x bytes\n", GCPhys, cbSize));
    22372380
    2238             /* Size of entire command. */
    2239 /** @todo @bugref{4500} - Not portable, see other todos. */
    2240             rc = SSMR3GetU32(pSSM, &u32);
    2241             AssertRCReturn(rc, rc);
    2242 
    2243             PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (u32 * CMD_SIZE_HACK_FACTOR); /*HACK ALERT!*/
     2381            /* For uVersion <= 12, this was the size of entire command.
     2382             * Now the size is recalculated in vmmdevHGCMLoadStateDone.
     2383             */
     2384            if (uVersion <= 12)
     2385            {
     2386                rc = SSMR3Skip(pSSM, sizeof (uint32_t));
     2387                AssertRCReturn(rc, rc);
     2388            }
     2389
     2390            /* Allocate only VBOXHGCMCMD structure. vmmdevHGCMLoadStateDone will rellocate the command
     2391             * with aditional space for parameters and for pointer/pagelists buffer.
     2392             */
     2393            PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (VBOXHGCMCMD));
    22442394            AssertReturn(pCmd, VERR_NO_MEMORY);
    2245             pCmd->cbCmd = u32;
    22462395
    22472396            /* The type of the command. */
     
    23522501         * New commands will be inserted at the list head, so they will not be seen by
    23532502         * this loop.
     2503         *
     2504         * Note: The list contains only VBOXHGCMCMD structures, place for HGCM parameters
     2505         *       and for data buffers has not been allocated.
     2506         *       Command handlers compute the command size and reallocate it before
     2507         *       resubmitting the command to HGCM services.
     2508         *       New commands will be inserted to the list.
    23542509         */
    23552510        PVBOXHGCMCMD pIter = pVMMDevState->pHGCMCmdList;
    23562511
     2512        pVMMDevState->pHGCMCmdList = NULL; /* Reset the list. Saved commands will be processed and deallocated. */
     2513
    23572514        while (pIter)
    23582515        {
     
    23632520
    23642521            PVBOXHGCMCMD pNext = pIter->pNext;
     2522
     2523            PVBOXHGCMCMD pCmd = NULL; /* Resubmitted command. */
    23652524
    23662525            VMMDevHGCMRequestHeader *requestHeader = (VMMDevHGCMRequestHeader *)RTMemAllocZ (pIter->cbSize);
     
    24102569                                Log(("VMMDevReq_HGCMConnect\n"));
    24112570
    2412                                 requestHeader->header.rc = vmmdevHGCMConnectSaved (pVMMDevState, pHGCMConnect, &fHGCMCalled, pIter);
     2571                                requestHeader->header.rc = vmmdevHGCMConnectSaved (pVMMDevState, pHGCMConnect, pIter->GCPhys, &fHGCMCalled, pIter, &pCmd);
    24132572                            }
    24142573                            break;
     
    24322591
    24332592                                Log(("VMMDevReq_VMMDevHGCMDisconnect\n"));
    2434                                 requestHeader->header.rc = vmmdevHGCMDisconnectSaved (pVMMDevState, pHGCMDisconnect, &fHGCMCalled, pIter);
     2593                                requestHeader->header.rc = vmmdevHGCMDisconnectSaved (pVMMDevState, pHGCMDisconnect, pIter->GCPhys, &fHGCMCalled, pIter, &pCmd);
    24352594                            }
    24362595                            break;
     
    24622621                                bool f64Bits = false;
    24632622#endif /* VBOX_WITH_64_BITS_GUESTS */
    2464                                 requestHeader->header.rc = vmmdevHGCMCallSaved (pVMMDevState, pHGCMCall, requestHeader->header.size, f64Bits, &fHGCMCalled, pIter);
     2623                                requestHeader->header.rc = vmmdevHGCMCallSaved (pVMMDevState, pHGCMCall, pIter->GCPhys, requestHeader->header.size, f64Bits, &fHGCMCalled, pIter, &pCmd);
    24652624                            }
    24662625                            break;
     
    25652724            if (pIter->enmCmdType == VBOXHGCMCMDTYPE_LOADSTATE)
    25662725            {
    2567                 /* Old saved state. Remove the LOADSTATE command. */
     2726                /* Old saved state. */
    25682727
    25692728                /* Write back the request */
     
    25712730                RTMemFree(requestHeader);
    25722731                requestHeader = NULL;
    2573 
    2574                 vmmdevHGCMRemoveCommand (pVMMDevState, pIter);
    2575 
    2576                 if (pIter->paLinPtrs != NULL)
    2577                 {
    2578                      RTMemFree(pIter->paLinPtrs);
    2579                 }
    2580 
    2581                 RTMemFree(pIter);
    25822732            }
    25832733            else
     
    25982748                {
    25992749                   /* HGCM was not called. Deallocate the current command and then notify guest. */
    2600                    vmmdevHGCMRemoveCommand (pVMMDevState, pIter);
    2601 
    2602                    if (pIter->paLinPtrs != NULL)
     2750                   if (pCmd)
    26032751                   {
    2604                         RTMemFree(pIter->paLinPtrs);
     2752                       vmmdevHGCMRemoveCommand (pVMMDevState, pCmd);
     2753
     2754                       if (pCmd->paLinPtrs != NULL)
     2755                       {
     2756                           RTMemFree(pCmd->paLinPtrs);
     2757                       }
     2758
     2759                       RTMemFree(pCmd);
     2760                       pCmd = NULL;
    26052761                   }
    2606 
    2607                    RTMemFree(pIter);
    26082762
    26092763                   VMMDevNotifyGuest (pVMMDevState, VMMDEV_EVENT_HGCM);
     
    26112765            }
    26122766
     2767            /* Deallocate the saved command structure. */
     2768            if (pIter->paLinPtrs != NULL)
     2769            {
     2770                RTMemFree(pIter->paLinPtrs);
     2771            }
     2772
     2773            RTMemFree(pIter);
     2774
    26132775            pIter = pNext;
    26142776        }
Note: See TracChangeset for help on using the changeset viewer.

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