Changeset 90264 in vbox
- Timestamp:
- Jul 20, 2021 7:37:24 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145803
- Location:
- trunk/src/VBox/Devices/VMMDev
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r87767 r90264 104 104 #include <iprt/buildconfig.h> 105 105 #include <iprt/string.h> 106 #include <iprt/system.h> 106 107 #include <iprt/time.h> 107 108 #ifndef IN_RC … … 4413 4414 * Everything HGCM. 4414 4415 */ 4415 vmmdevR3HgcmDestroy(pDevIns, pThisCC);4416 vmmdevR3HgcmDestroy(pDevIns, PDMDEVINS_2_DATA(pDevIns, PVMMDEV), pThisCC); 4416 4417 #endif 4417 4418 … … 4563 4564 "TestingEnabled|" 4564 4565 "TestingMMIO|" 4565 "TestintXmlOutputFile" 4566 "TestintXmlOutputFile|" 4567 "HGCMHeapBudgetDefault|" 4568 "HGCMHeapBudgetLegacy|" 4569 "HGCMHeapBudgetVBoxGuest|" 4570 "HGCMHeapBudgetOtherDrv|" 4571 "HGCMHeapBudgetRoot|" 4572 "HGCMHeapBudgetSystem|" 4573 "HGCMHeapBudgetReserved1|" 4574 "HGCMHeapBudgetUser|" 4575 "HGCMHeapBudgetGuest" 4566 4576 , 4567 4577 ""); … … 4642 4652 #endif 4643 4653 4654 #ifdef VBOX_WITH_HGCM 4655 /* 4656 * Heap budgets for HGCM requestor categories. Take the available host 4657 * memory as a rough hint of how much we can handle. 4658 */ 4659 /** @todo If we reduced the number of categories here, we could alot more to 4660 * each... */ 4661 uint64_t cbDefaultBudget = 0; 4662 if (RT_FAILURE(RTSystemQueryTotalRam(&cbDefaultBudget))) 4663 cbDefaultBudget = 16 * _1G64; 4664 LogFunc(("RTSystemQueryTotalRam -> %'RU64 (%RX64)\n", cbDefaultBudget, cbDefaultBudget)); 4665 # if ARCH_BITS == 32 4666 cbDefaultBudget = RT_MIN(cbDefaultBudget, _512M); 4667 # endif 4668 cbDefaultBudget /= 8; /* One eighth of physical memory ... */ 4669 cbDefaultBudget /= RT_ELEMENTS(pThisCC->aHgcmAcc); /* over 8 accounting categories. (8GiB -> 64MiB) */ 4670 cbDefaultBudget = RT_MIN(cbDefaultBudget, _512M); /* max 512MiB */ 4671 cbDefaultBudget = RT_MAX(cbDefaultBudget, _32M); /* min 32MiB */ 4672 rc = pHlp->pfnCFGMQueryU64Def(pCfg, "HGCMHeapBudgetDefault", &cbDefaultBudget, cbDefaultBudget); 4673 if (RT_FAILURE(rc)) 4674 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed querying \"HGCMHeapBudgetDefault\" as a 64-bit unsigned integer")); 4675 4676 LogRel(("VMMDev: cbDefaultBudget: %'RU64 (%RX64)\n", cbDefaultBudget, cbDefaultBudget)); 4677 static const struct { const char *pszName; unsigned idx; } s_aCfgHeapBudget[] = 4678 { 4679 { "HGCMHeapBudgetLegacy", VMMDEV_REQUESTOR_USR_NOT_GIVEN }, 4680 { "HGCMHeapBudgetVBoxGuest", VMMDEV_REQUESTOR_USR_DRV }, 4681 { "HGCMHeapBudgetOtherDrv", VMMDEV_REQUESTOR_USR_DRV_OTHER }, 4682 { "HGCMHeapBudgetRoot", VMMDEV_REQUESTOR_USR_ROOT }, 4683 { "HGCMHeapBudgetSystem", VMMDEV_REQUESTOR_USR_SYSTEM }, 4684 { "HGCMHeapBudgetReserved1", VMMDEV_REQUESTOR_USR_RESERVED1 }, 4685 { "HGCMHeapBudgetUser", VMMDEV_REQUESTOR_USR_USER }, 4686 { "HGCMHeapBudgetGuest", VMMDEV_REQUESTOR_USR_GUEST }, 4687 }; 4688 AssertCompile(RT_ELEMENTS(s_aCfgHeapBudget) == RT_ELEMENTS(pThisCC->aHgcmAcc)); 4689 for (uintptr_t i = 0; i < RT_ELEMENTS(s_aCfgHeapBudget); i++) 4690 { 4691 uintptr_t const idx = s_aCfgHeapBudget[i].idx; 4692 rc = pHlp->pfnCFGMQueryU64Def(pCfg, s_aCfgHeapBudget[i].pszName, 4693 &pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig, cbDefaultBudget); 4694 if (RT_FAILURE(rc)) 4695 return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, 4696 N_("Configuration error: Failed querying \"%s\" as a 64-bit unsigned integer"), 4697 s_aCfgHeapBudget[i].pszName); 4698 pThisCC->aHgcmAcc[idx].cbHeapBudget = pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig; 4699 if (pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig != cbDefaultBudget) 4700 LogRel(("VMMDev: %s: %'RU64 (%#RX64)\n", s_aCfgHeapBudget[i].pszName, 4701 pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig, pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig)); 4702 4703 const char * const pszCatName = &s_aCfgHeapBudget[i].pszName[sizeof("HGCMHeapBudget") - 1]; 4704 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aHgcmAcc[idx].cbHeapBudget, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, 4705 STAMUNIT_BYTES, "Currently available budget", "HGCM-%s/BudgetAvailable", pszCatName); 4706 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig, STAMTYPE_U64, STAMVISIBILITY_ALWAYS, 4707 STAMUNIT_BYTES, "Configured budget", "HGCM-%s/BudgetConfig", pszCatName); 4708 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aHgcmAcc[idx].cbHeapTotal, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, 4709 STAMUNIT_BYTES, "Total heap usage", "HGCM-%s/cbHeapTotal", pszCatName); 4710 PDMDevHlpSTAMRegisterF(pDevIns, &pThisCC->aHgcmAcc[idx].cTotalMessages, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, 4711 STAMUNIT_COUNT, "Total messages", "HGCM-%s/cTotalMessages", pszCatName); 4712 } 4713 #endif 4714 4715 /* 4716 * <missing comment> 4717 */ 4644 4718 pThis->cbGuestRAM = MMR3PhysGetRamSize(PDMDevHlpGetVM(pDevIns)); 4645 4719 -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
r83558 r90264 182 182 PGMPAGEMAPLOCK ReqMapLock; 183 183 184 /** The accounting index (into VMMDEVR3::aHgcmAcc). */ 185 uint8_t idxHeapAcc; 186 uint8_t abPadding[3]; 187 /** The heap cost of this command. */ 188 uint32_t cbHeapCost; 189 184 190 /** The STAM_GET_TS() value when the request arrived. */ 185 191 uint64_t tsArrival; … … 231 237 typedef struct VBOXHGCMCMDCACHED 232 238 { 233 VBOXHGCMCMD Core; /**< 1 12*/239 VBOXHGCMCMD Core; /**< 120 */ 234 240 VBOXHGCMGUESTPARM aGuestParms[6]; /**< 40 * 6 = 240 */ 235 241 VBOXHGCMSVCPARM aHostParms[6]; /**< 24 * 6 = 144 */ 236 } VBOXHGCMCMDCACHED; /**< 1 12+240+144 = 496*/237 AssertCompile(sizeof(VBOXHGCMCMD) <= 1 12);242 } VBOXHGCMCMDCACHED; /**< 120+240+144 = 504 */ 243 AssertCompile(sizeof(VBOXHGCMCMD) <= 120); 238 244 AssertCompile(sizeof(VBOXHGCMGUESTPARM) <= 40); 239 245 AssertCompile(sizeof(VBOXHGCMSVCPARM) <= 24); 240 246 AssertCompile(sizeof(VBOXHGCMCMDCACHED) <= 512); 241 247 AssertCompile(sizeof(VBOXHGCMCMDCACHED) > sizeof(VBOXHGCMCMD) + sizeof(HGCMServiceLocation)); 248 249 250 /********************************************************************************************************************************* 251 * Internal Functions * 252 *********************************************************************************************************************************/ 253 DECLINLINE(void *) vmmdevR3HgcmCallMemAllocZ(PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd, size_t cbRequested); 254 242 255 243 256 … … 268 281 uint32_t cbRequest, uint32_t cParms, uint32_t fRequestor) 269 282 { 283 /* For heap accounting. */ 284 uintptr_t const idxHeapAcc = fRequestor != VMMDEV_REQUESTOR_LEGACY 285 ? fRequestor & VMMDEV_REQUESTOR_USR_MASK 286 : VMMDEV_REQUESTOR_USR_NOT_GIVEN; 270 287 #if 1 271 288 /* … … 276 293 if (cParms <= RT_ELEMENTS(pCmdCached->aGuestParms)) 277 294 { 278 int rc = RTMemCacheAllocEx(pThisCC->hHgcmCmdCache, (void **)&pCmdCached); 279 if (RT_SUCCESS(rc)) 280 { 281 RT_ZERO(*pCmdCached); 282 pCmdCached->Core.fMemCache = true; 283 pCmdCached->Core.GCPhys = GCPhys; 284 pCmdCached->Core.cbRequest = cbRequest; 285 pCmdCached->Core.enmCmdType = enmCmdType; 286 pCmdCached->Core.fRequestor = fRequestor; 287 if (enmCmdType == VBOXHGCMCMDTYPE_CALL) 288 { 289 pCmdCached->Core.u.call.cParms = cParms; 290 pCmdCached->Core.u.call.paGuestParms = pCmdCached->aGuestParms; 291 pCmdCached->Core.u.call.paHostParms = pCmdCached->aHostParms; 292 } 293 else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT) 294 pCmdCached->Core.u.connect.pLoc = (HGCMServiceLocation *)(&pCmdCached->Core + 1); 295 296 return &pCmdCached->Core; 295 if (sizeof(*pCmdCached) <= pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget) 296 { 297 int rc = RTMemCacheAllocEx(pThisCC->hHgcmCmdCache, (void **)&pCmdCached); 298 if (RT_SUCCESS(rc)) 299 { 300 RT_ZERO(*pCmdCached); 301 pCmdCached->Core.fMemCache = true; 302 pCmdCached->Core.GCPhys = GCPhys; 303 pCmdCached->Core.cbRequest = cbRequest; 304 pCmdCached->Core.enmCmdType = enmCmdType; 305 pCmdCached->Core.fRequestor = fRequestor; 306 pCmdCached->Core.idxHeapAcc = (uint8_t)idxHeapAcc; 307 pCmdCached->Core.cbHeapCost = sizeof(*pCmdCached); 308 Log5Func(("aHgcmAcc[%zu] %#RX64 -= %#zx (%p)\n", 309 idxHeapAcc, pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget, sizeof(*pCmdCached), &pCmdCached->Core)); 310 pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget -= sizeof(*pCmdCached); 311 312 if (enmCmdType == VBOXHGCMCMDTYPE_CALL) 313 { 314 pCmdCached->Core.u.call.cParms = cParms; 315 pCmdCached->Core.u.call.paGuestParms = pCmdCached->aGuestParms; 316 pCmdCached->Core.u.call.paHostParms = pCmdCached->aHostParms; 317 } 318 else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT) 319 pCmdCached->Core.u.connect.pLoc = (HGCMServiceLocation *)(&pCmdCached->Core + 1); 320 321 Assert(!pCmdCached->Core.pvReqLocked); 322 323 Log3Func(("returns %p (enmCmdType=%d GCPhys=%RGp)\n", &pCmdCached->Core, enmCmdType, GCPhys)); 324 return &pCmdCached->Core; 325 } 297 326 } 327 else 328 LogFunc(("Heap budget overrun: sizeof(*pCmdCached)=%#zx aHgcmAcc[%zu].cbHeapBudget=%#RX64 - enmCmdType=%d\n", 329 sizeof(*pCmdCached), idxHeapAcc, pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget, enmCmdType)); 298 330 return NULL; 299 331 } … … 307 339 const uint32_t cbCmd = sizeof(VBOXHGCMCMD) + cParms * (sizeof(VBOXHGCMGUESTPARM) + sizeof(VBOXHGCMSVCPARM)) 308 340 + (enmCmdType == VBOXHGCMCMDTYPE_CONNECT ? sizeof(HGCMServiceLocation) : 0); 309 310 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ(cbCmd); 311 if (pCmd) 312 { 313 pCmd->enmCmdType = enmCmdType; 314 pCmd->GCPhys = GCPhys; 315 pCmd->cbRequest = cbRequest; 316 pCmd->fRequestor = fRequestor; 317 318 if (enmCmdType == VBOXHGCMCMDTYPE_CALL) 319 { 320 pCmd->u.call.cParms = cParms; 321 if (cParms) 322 { 323 pCmd->u.call.paGuestParms = (VBOXHGCMGUESTPARM *)((uint8_t *)pCmd 324 + sizeof(struct VBOXHGCMCMD)); 325 pCmd->u.call.paHostParms = (VBOXHGCMSVCPARM *)((uint8_t *)pCmd->u.call.paGuestParms 326 + cParms * sizeof(VBOXHGCMGUESTPARM)); 327 } 341 if (cbCmd <= pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget) 342 { 343 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ(cbCmd); 344 if (pCmd) 345 { 346 pCmd->enmCmdType = enmCmdType; 347 pCmd->GCPhys = GCPhys; 348 pCmd->cbRequest = cbRequest; 349 pCmd->fRequestor = fRequestor; 350 pCmd->idxHeapAcc = (uint8_t)idxHeapAcc; 351 pCmd->cbHeapCost = cbCmd; 352 Log5Func(("aHgcmAcc[%zu] %#RX64 -= %#x (%p)\n", idxHeapAcc, pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget, cbCmd, pCmd)); 353 pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget -= cbCmd; 354 355 if (enmCmdType == VBOXHGCMCMDTYPE_CALL) 356 { 357 pCmd->u.call.cParms = cParms; 358 if (cParms) 359 { 360 pCmd->u.call.paGuestParms = (VBOXHGCMGUESTPARM *)((uint8_t *)pCmd 361 + sizeof(struct VBOXHGCMCMD)); 362 pCmd->u.call.paHostParms = (VBOXHGCMSVCPARM *)((uint8_t *)pCmd->u.call.paGuestParms 363 + cParms * sizeof(VBOXHGCMGUESTPARM)); 364 } 365 } 366 else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT) 367 pCmd->u.connect.pLoc = (HGCMServiceLocation *)(pCmd + 1); 328 368 } 329 else if (enmCmdType == VBOXHGCMCMDTYPE_CONNECT) 330 pCmd->u.connect.pLoc = (HGCMServiceLocation *)(pCmd + 1); 331 } 332 return pCmd; 369 Log3Func(("returns %p (enmCmdType=%d GCPhys=%RGp cbCmd=%#x)\n", pCmd, enmCmdType, GCPhys, cbCmd)); 370 return pCmd; 371 } 372 LogFunc(("Heap budget overrun: cbCmd=%#x aHgcmAcc[%zu].cbHeapBudget=%#RX64 - enmCmdType=%d\n", 373 cbCmd, idxHeapAcc, pThisCC->aHgcmAcc[idxHeapAcc].cbHeapBudget, enmCmdType)); 374 return NULL; 333 375 } 334 376 … … 336 378 * 337 379 * @param pDevIns The device instance. 380 * @param pThis The VMMDev shared instance data. 338 381 * @param pThisCC The VMMDev ring-3 instance data. 339 382 * @param pCmd Command to deallocate. 340 383 */ 341 static void vmmdevR3HgcmCmdFree(PPDMDEVINS pDevIns, PVMMDEV CC pThisCC, PVBOXHGCMCMD pCmd)384 static void vmmdevR3HgcmCmdFree(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd) 342 385 { 343 386 if (pCmd) 344 387 { 388 Assert( pCmd->enmCmdType == VBOXHGCMCMDTYPE_CALL 389 || pCmd->enmCmdType == VBOXHGCMCMDTYPE_CONNECT 390 || pCmd->enmCmdType == VBOXHGCMCMDTYPE_DISCONNECT 391 || pCmd->enmCmdType == VBOXHGCMCMDTYPE_LOADSTATE); 345 392 if (pCmd->enmCmdType == VBOXHGCMCMDTYPE_CALL) 346 393 { … … 390 437 } 391 438 439 pCmd->enmCmdType = UINT8_MAX; /* poison */ 440 441 /* Update heap budget. Need the critsect to do this safely. */ 442 Assert(pCmd->cbHeapCost != 0); 443 uintptr_t idx = pCmd->idxHeapAcc; 444 AssertStmt(idx < RT_ELEMENTS(pThisCC->aHgcmAcc), idx %= RT_ELEMENTS(pThisCC->aHgcmAcc)); 445 446 PDMDevHlpCritSectEnter(pDevIns, &pThis->CritSect, VERR_IGNORED); 447 448 Log5Func(("aHgcmAcc[%zu] %#RX64 += %#x (%p)\n", idx, pThisCC->aHgcmAcc[idx].cbHeapBudget, pCmd->cbHeapCost, pCmd)); 449 pThisCC->aHgcmAcc[idx].cbHeapBudget += pCmd->cbHeapCost; 450 AssertMsg(pThisCC->aHgcmAcc[idx].cbHeapBudget <= pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig, 451 ("idx=%d (%d) fRequestor=%#x pCmd=%p: %#RX64 vs %#RX64 -> %#RX64\n", idx, pCmd->idxHeapAcc, pCmd->fRequestor, pCmd, 452 pThisCC->aHgcmAcc[idx].cbHeapBudget, pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig, 453 pThisCC->aHgcmAcc[idx].cbHeapBudget - pThisCC->aHgcmAcc[idx].cbHeapBudgetConfig)); 454 pCmd->cbHeapCost = 0; 455 392 456 #if 1 393 457 if (pCmd->fMemCache) 458 { 394 459 RTMemCacheFree(pThisCC->hHgcmCmdCache, pCmd); 460 PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); /* releasing it after just to be on the safe side. */ 461 } 395 462 else 396 463 #endif 464 { 465 PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); 397 466 RTMemFree(pCmd); 467 } 398 468 } 399 469 } … … 415 485 416 486 RTListPrepend(&pThisCC->listHGCMCmd, &pCmd->node); 487 488 /* stats */ 489 uintptr_t idx = pCmd->idxHeapAcc; 490 AssertStmt(idx < RT_ELEMENTS(pThisCC->aHgcmAcc), idx %= RT_ELEMENTS(pThisCC->aHgcmAcc)); 491 STAM_REL_COUNTER_ADD(&pThisCC->aHgcmAcc[idx].cbHeapTotal, pCmd->cbHeapCost); 492 STAM_REL_COUNTER_INC(&pThisCC->aHgcmAcc[idx].cTotalMessages); 417 493 418 494 /* Automatically enable HGCM events, if there are HGCM commands. */ … … 683 759 * @returns VBox status code that the guest should see. 684 760 * @param pDevIns The device instance. 761 * @param pThisCC The VMMDev ring-3 instance data. 685 762 * @param pCmd Command structure where host parameters needs initialization. 686 763 * @param pbReq The request buffer. 687 764 */ 688 static int vmmdevR3HgcmInitHostParameters(PPDMDEVINS pDevIns, PV BOXHGCMCMD pCmd, uint8_t const *pbReq)765 static int vmmdevR3HgcmInitHostParameters(PPDMDEVINS pDevIns, PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd, uint8_t const *pbReq) 689 766 { 690 767 AssertReturn(pCmd->enmCmdType == VBOXHGCMCMDTYPE_CALL, VERR_INTERNAL_ERROR); … … 728 805 { 729 806 /* Zero memory, the buffer content is potentially copied to the guest. */ 730 void *pv = RTMemAllocZ(cbData);807 void *pv = vmmdevR3HgcmCallMemAllocZ(pThisCC, pCmd, cbData); 731 808 AssertReturn(pv, VERR_NO_MEMORY); 732 809 pHostParm->u.pointer.addr = pv; … … 831 908 } 832 909 910 /** 911 * Heap budget wrapper around RTMemAlloc and RTMemAllocZ. 912 */ 913 static void *vmmdevR3HgcmCallMemAllocEx(PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd, size_t cbRequested, bool fZero) 914 { 915 /* Check against max heap costs for this request. */ 916 Assert(pCmd->cbHeapCost <= VMMDEV_MAX_HGCM_DATA_SIZE); 917 if (cbRequested <= VMMDEV_MAX_HGCM_DATA_SIZE - pCmd->cbHeapCost) 918 { 919 /* Check heap budget (we're under lock). */ 920 uintptr_t idx = pCmd->idxHeapAcc; 921 AssertStmt(idx < RT_ELEMENTS(pThisCC->aHgcmAcc), idx %= RT_ELEMENTS(pThisCC->aHgcmAcc)); 922 if (cbRequested <= pThisCC->aHgcmAcc[idx].cbHeapBudget) 923 { 924 /* Do the actual allocation. */ 925 void *pv = fZero ? RTMemAllocZ(cbRequested) : RTMemAlloc(cbRequested); 926 if (pv) 927 { 928 /* Update the request cost and heap budget. */ 929 Log5Func(("aHgcmAcc[%zu] %#RX64 += %#x (%p)\n", idx, pThisCC->aHgcmAcc[idx].cbHeapBudget, cbRequested, pCmd)); 930 pThisCC->aHgcmAcc[idx].cbHeapBudget -= cbRequested; 931 pCmd->cbHeapCost += (uint32_t)cbRequested; 932 return pv; 933 } 934 LogFunc(("Heap alloc failed: cbRequested=%#zx - enmCmdType=%d\n", cbRequested, pCmd->enmCmdType)); 935 } 936 else 937 LogFunc(("Heap budget overrun: cbRequested=%#zx cbHeapCost=%#x aHgcmAcc[%u].cbHeapBudget=%#RX64 - enmCmdType=%d\n", 938 cbRequested, pCmd->cbHeapCost, pCmd->idxHeapAcc, pThisCC->aHgcmAcc[idx].cbHeapBudget, pCmd->enmCmdType)); 939 } 940 else 941 LogFunc(("Request too big: cbRequested=%#zx cbHeapCost=%#x - enmCmdType=%d\n", 942 cbRequested, pCmd->cbHeapCost, pCmd->enmCmdType)); 943 return NULL; 944 } 945 946 /** 947 * Heap budget wrapper around RTMemAlloc. 948 */ 949 DECLINLINE(void *) vmmdevR3HgcmCallMemAlloc(PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd, size_t cbRequested) 950 { 951 return vmmdevR3HgcmCallMemAllocEx(pThisCC, pCmd, cbRequested, false /*fZero*/); 952 } 953 954 /** 955 * Heap budget wrapper around RTMemAllocZ. 956 */ 957 DECLINLINE(void *) vmmdevR3HgcmCallMemAllocZ(PVMMDEVCC pThisCC, PVBOXHGCMCMD pCmd, size_t cbRequested) 958 { 959 return vmmdevR3HgcmCallMemAllocEx(pThisCC, pCmd, cbRequested, true /*fZero*/); 960 } 961 833 962 /** Copy VMMDevHGCMCall request data from the guest to VBOXHGCMCMD command. 834 963 * … … 864 993 const uint8_t *pu8HGCMParm = (uint8_t *)pHGCMCall + offHGCMParms; 865 994 866 uint32_t cbTotalData = 0;867 995 for (uint32_t i = 0; i < cParms; ++i, pu8HGCMParm += cbHGCMParmStruct) 868 996 { … … 927 1055 LogFunc(("LinAddr guest parameter %RGv, cb %u\n", GCPtr, cbData)); 928 1056 929 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE - cbTotalData, VERR_INVALID_PARAMETER); 930 cbTotalData += cbData; 1057 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE, VERR_INVALID_PARAMETER); 931 1058 932 1059 const uint32_t offFirstPage = cbData > 0 ? GCPtr & PAGE_OFFSET_MASK : 0; … … 944 1071 else 945 1072 { 946 pGuestParm->u.ptr.paPages = (RTGCPHYS *)RTMemAlloc(cPages * sizeof(RTGCPHYS)); 1073 /* (Max 262144 bytes with current limits.) */ 1074 pGuestParm->u.ptr.paPages = (RTGCPHYS *)vmmdevR3HgcmCallMemAlloc(pThisCC, pCmd, 1075 cPages * sizeof(RTGCPHYS)); 947 1076 AssertReturn(pGuestParm->u.ptr.paPages, VERR_NO_MEMORY); 948 1077 } … … 986 1115 LogFunc(("PageList guest parameter cb %u, offset %u\n", cbData, offPageListInfo)); 987 1116 988 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE - cbTotalData, VERR_INVALID_PARAMETER); 989 cbTotalData += cbData; 1117 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE, VERR_INVALID_PARAMETER); 990 1118 991 1119 /** @todo respect zero byte page lists... */ … … 1048 1176 pGuestParm->u.Pages.cPages = (uint16_t)cPages; 1049 1177 pGuestParm->u.Pages.fLocked = false; 1050 pGuestParm->u.Pages.paPgLocks = (PPGMPAGEMAPLOCK)RTMemAllocZ( (sizeof(PGMPAGEMAPLOCK) + sizeof(void *)) 1051 * cPages); 1178 pGuestParm->u.Pages.paPgLocks = (PPGMPAGEMAPLOCK)vmmdevR3HgcmCallMemAllocZ(pThisCC, pCmd, 1179 ( sizeof(PGMPAGEMAPLOCK) 1180 + sizeof(void *)) * cPages); 1052 1181 AssertReturn(pGuestParm->u.Pages.paPgLocks, VERR_NO_MEMORY); 1053 1182 … … 1090 1219 else 1091 1220 { 1092 pGuestParm->u.ptr.paPages = (RTGCPHYS *)RTMemAlloc(pPageListInfo->cPages * sizeof(RTGCPHYS)); 1221 pGuestParm->u.ptr.paPages = (RTGCPHYS *)vmmdevR3HgcmCallMemAlloc(pThisCC, pCmd, 1222 pPageListInfo->cPages * sizeof(RTGCPHYS)); 1093 1223 AssertReturn(pGuestParm->u.ptr.paPages, VERR_NO_MEMORY); 1094 1224 … … 1113 1243 LogFunc(("Embedded guest parameter cb %u, offset %u, flags %#x\n", cbData, offData, fFlags)); 1114 1244 1115 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE - cbTotalData, VERR_INVALID_PARAMETER); 1116 cbTotalData += cbData; 1245 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE, VERR_INVALID_PARAMETER); 1117 1246 1118 1247 /* Check flags and buffer range. */ … … 1197 1326 { 1198 1327 /* Copy guest data to host parameters, so HGCM services can use the data. */ 1199 rc = vmmdevR3HgcmInitHostParameters(pDevIns, p Cmd, (uint8_t const *)pHGCMCall);1328 rc = vmmdevR3HgcmInitHostParameters(pDevIns, pThisCC, pCmd, (uint8_t const *)pHGCMCall); 1200 1329 if (RT_SUCCESS(rc)) 1201 1330 { … … 1255 1384 } 1256 1385 } 1257 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);1386 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 1258 1387 } 1259 1388 return rc; … … 1688 1817 #endif 1689 1818 1690 /* Deallocate the command memory. */1819 /* Deallocate the command memory. Enter the critsect for proper */ 1691 1820 VBOXDD_HGCMCALL_COMPLETED_DONE(pCmd, idFunction, idClient, result); 1692 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);1821 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 1693 1822 1694 1823 #ifndef VBOX_WITHOUT_RELEASE_STATISTICS … … 2004 2133 AssertReturn( pGuestParm->enmType != VMMDevHGCMParmType_Embedded 2005 2134 && pGuestParm->enmType != VMMDevHGCMParmType_ContiguousPageList, VERR_INTERNAL_ERROR_3); 2006 pPtr->paPages = (RTGCPHYS *)RTMemAlloc(pPtr->cPages * sizeof(RTGCPHYS)); 2135 pPtr->paPages = (RTGCPHYS *)vmmdevR3HgcmCallMemAlloc(pThisCC, pCmd, 2136 pPtr->cPages * sizeof(RTGCPHYS)); 2007 2137 AssertStmt(pPtr->paPages, rc = VERR_NO_MEMORY); 2008 2138 } … … 2064 2194 Log(("vmmdevR3HgcmLoadState: Skipping cancelled request: enmCmdType=%d GCPhys=%#RX32 LB %#x\n", 2065 2195 enmCmdType, GCPhys, cbRequest)); 2066 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2196 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2067 2197 } 2068 2198 } … … 2128 2258 AssertRCReturn(rc, rc); 2129 2259 2130 pPtr->paPages = (RTGCPHYS *) RTMemAlloc(pPtr->cPages * sizeof(RTGCPHYS));2260 pPtr->paPages = (RTGCPHYS *)vmmdevR3HgcmCallMemAlloc(pThisCC, pCmd, pPtr->cPages * sizeof(RTGCPHYS)); 2131 2261 AssertReturn(pPtr->paPages, VERR_NO_MEMORY); 2132 2262 … … 2148 2278 Log(("vmmdevR3HgcmLoadState: Skipping cancelled request: enmCmdType=%d GCPhys=%#RX32 LB %#x\n", 2149 2279 enmCmdType, GCPhys, cbRequest)); 2150 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2280 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2151 2281 } 2152 2282 } … … 2255 2385 * @returns VBox status code that the guest should see. 2256 2386 * @param pDevIns The device instance. 2387 * @param pThis The VMMDev shared instance data. 2257 2388 * @param pThisCC The VMMDev ring-3 instance data. 2258 2389 * @param uSavedStateVersion The saved state version the command has been loaded from. … … 2263 2394 * @param ppRestoredCmd Where to store pointer to newly allocated restored command. 2264 2395 */ 2265 static int vmmdevR3HgcmRestoreCall(PPDMDEVINS pDevIns, PVMMDEV CC pThisCC, uint32_t uSavedStateVersion, const VBOXHGCMCMD *pLoadedCmd,2266 VMMDevHGCMCall *pReq, uint32_t cbReq, VMMDevRequestType enmRequestType,2267 V BOXHGCMCMD **ppRestoredCmd)2396 static int vmmdevR3HgcmRestoreCall(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC, uint32_t uSavedStateVersion, 2397 const VBOXHGCMCMD *pLoadedCmd, VMMDevHGCMCall *pReq, uint32_t cbReq, 2398 VMMDevRequestType enmRequestType, VBOXHGCMCMD **ppRestoredCmd) 2268 2399 { 2269 2400 /* Verify the request. */ … … 2315 2446 *ppRestoredCmd = pCmd; 2316 2447 else 2317 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2448 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2318 2449 2319 2450 return rc; … … 2325 2456 * @returns VBox status code that the guest should see. 2326 2457 * @param pDevIns The device instance. 2458 * @param pThis The VMMDev shared instance data. 2327 2459 * @param pThisCC The VMMDev ring-3 instance data. 2328 2460 * @param uSavedStateVersion Saved state version. … … 2332 2464 * @param ppRestoredCmd Where to store pointer to restored command. 2333 2465 */ 2334 static int vmmdevR3HgcmRestoreCommand(PPDMDEVINS pDevIns, PVMMDEV CC pThisCC, uint32_t uSavedStateVersion,2466 static int vmmdevR3HgcmRestoreCommand(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC, uint32_t uSavedStateVersion, 2335 2467 const VBOXHGCMCMD *pLoadedCmd, const VMMDevHGCMRequestHeader *pReqHdr, uint32_t cbReq, 2336 2468 VBOXHGCMCMD **ppRestoredCmd) … … 2365 2497 { 2366 2498 VMMDevHGCMCall *pReq = (VMMDevHGCMCall *)pReqHdr; 2367 rc = vmmdevR3HgcmRestoreCall(pDevIns, pThisCC, uSavedStateVersion, pLoadedCmd, pReq, cbReq, enmRequestType, ppRestoredCmd); 2499 rc = vmmdevR3HgcmRestoreCall(pDevIns, pThis, pThisCC, uSavedStateVersion, pLoadedCmd, 2500 pReq, cbReq, enmRequestType, ppRestoredCmd); 2368 2501 break; 2369 2502 } … … 2425 2558 */ 2426 2559 VMMDevHGCMRequestHeader *pReqHdr = (VMMDevHGCMRequestHeader *)RTMemAlloc(pCmd->cbRequest); 2427 AssertBreakStmt(pReqHdr, vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd); rcFunc = VERR_NO_MEMORY);2560 AssertBreakStmt(pReqHdr, vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); rcFunc = VERR_NO_MEMORY); 2428 2561 2429 2562 PDMDevHlpPhysRead(pDevIns, pCmd->GCPhys, pReqHdr, pCmd->cbRequest); … … 2441 2574 { 2442 2575 PVBOXHGCMCMD pRestoredCmd = NULL; 2443 rcCmd = vmmdevR3HgcmRestoreCommand(pDevIns, pThis CC, pThisCC->uSavedStateVersion, pCmd,2576 rcCmd = vmmdevR3HgcmRestoreCommand(pDevIns, pThis, pThisCC, pThisCC->uSavedStateVersion, pCmd, 2444 2577 pReqHdr, pCmd->cbRequest, &pRestoredCmd); 2445 2578 if (RT_SUCCESS(rcCmd)) 2446 2579 { 2447 2580 Assert(pCmd != pRestoredCmd); /* vmmdevR3HgcmRestoreCommand must allocate restored command. */ 2448 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2581 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2449 2582 pCmd = pRestoredCmd; 2450 2583 } … … 2477 2610 case VBOXHGCMCMDTYPE_CALL: 2478 2611 { 2479 rcCmd = vmmdevR3HgcmInitHostParameters(pDevIns, p Cmd, (uint8_t const *)pReqHdr);2612 rcCmd = vmmdevR3HgcmInitHostParameters(pDevIns, pThisCC, pCmd, (uint8_t const *)pReqHdr); 2480 2613 if (RT_SUCCESS(rcCmd)) 2481 2614 { … … 2520 2653 2521 2654 /* Deallocate the command memory. */ 2522 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2655 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2523 2656 } 2524 2657 … … 2531 2664 { 2532 2665 RTListNodeRemove(&pCmd->node); 2533 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2666 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2534 2667 } 2535 2668 } … … 2543 2676 * 2544 2677 * @param pDevIns The device instance. 2678 * @param pThis The VMMDev shared instance data. 2545 2679 * @param pThisCC The VMMDev ring-3 instance data. 2546 2680 */ 2547 void vmmdevR3HgcmDestroy(PPDMDEVINS pDevIns, PVMMDEV CC pThisCC)2681 void vmmdevR3HgcmDestroy(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC) 2548 2682 { 2549 2683 LogFlowFunc(("\n")); … … 2555 2689 { 2556 2690 vmmdevR3HgcmRemoveCommand(pThisCC, pCmd); 2557 vmmdevR3HgcmCmdFree(pDevIns, pThis CC, pCmd);2691 vmmdevR3HgcmCmdFree(pDevIns, pThis, pThisCC, pCmd); 2558 2692 } 2559 2693 -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h
r82968 r90264 45 45 int vmmdevR3HgcmLoadStateDone(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC); 46 46 47 void vmmdevR3HgcmDestroy(PPDMDEVINS pDevIns, PVMMDEV CC pThisCC);47 void vmmdevR3HgcmDestroy(PPDMDEVINS pDevIns, PVMMDEV pThis, PVMMDEVCC pThisCC); 48 48 int vmmdevR3HgcmInit(PVMMDEVCC pThisCC); 49 49 RT_C_DECLS_END -
trunk/src/VBox/Devices/VMMDev/VMMDevState.h
r82968 r90264 400 400 uint32_t uSavedStateVersion; 401 401 RTMEMCACHE hHgcmCmdCache; 402 /** Accounting by for each requestor VMMDEV_REQUESTOR_USR_XXX group. 403 * Legacy requests ends up with VMMDEV_REQUESTOR_USR_NOT_GIVEN */ 404 struct 405 { 406 /** The configured heap budget. */ 407 uint64_t cbHeapBudgetConfig; 408 /** The currently available heap budget. */ 409 uint64_t cbHeapBudget; 410 /** Total sum of all heap usage. */ 411 STAMCOUNTER cbHeapTotal; 412 /** Total number of message. */ 413 STAMCOUNTER cTotalMessages; 414 } aHgcmAcc[VMMDEV_REQUESTOR_USR_MASK + 1]; 402 415 STAMPROFILE StatHgcmCmdArrival; 403 416 STAMPROFILE StatHgcmCmdCompletion;
Note:
See TracChangeset
for help on using the changeset viewer.