Changeset 27023 in vbox for trunk/src/VBox/Additions/common/VBoxGuest
- Timestamp:
- Mar 4, 2010 1:32:45 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 58333
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r26999 r27023 48 48 #endif 49 49 50 const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 50 51 51 52 … … 259 260 { 260 261 VMMDevReportGuestInfo *pReq; 261 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo); 262 int rc; 263 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo); 262 264 if (RT_SUCCESS(rc)) 263 265 { … … 274 276 } 275 277 278 /** 279 * Inflate the balloon by one chunk represented by an R0 memory object. 280 * 281 * @returns IPRT status code. 282 * @param pMemObj Pointer to the R0 memory object. 283 * @param pReq The pre-allocated request for performing the VMMDev call. 284 */ 285 static int vboxGuestBalloonInflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq) 286 { 287 uint32_t iPage; 288 int rc; 289 290 for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++) 291 { 292 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage); 293 pReq->aPhysPage[iPage] = phys; 294 } 295 296 /* Protect this memory from being accessed. Doesn't work on every platform and probably 297 * doesn't work for R3-provided memory, therefore ignore the return value. Unprotect 298 * done when object is freed. */ 299 rc = RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE); 300 NOREF(rc); 301 302 pReq->fInflate = true; 303 pReq->header.size = cbChangeMemBalloonReq; 304 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 305 306 return VbglGRPerform(&pReq->header); 307 } 308 309 /** 310 * Deflate the balloon by one chunk represented by an R0 memory object. 311 * 312 * @returns IPRT status code. 313 * @param pMemObj Pointer to the R0 memory object. 314 * The memory object will be freed afterwards. 315 * @param pReq The pre-allocated request for performing the VMMDev call. 316 */ 317 static int vboxGuestBalloonDeflate(PRTR0MEMOBJ pMemObj, VMMDevChangeMemBalloon *pReq) 318 { 319 uint32_t iPage; 320 int rc; 321 322 for (iPage = 0; iPage < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; iPage++) 323 { 324 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, iPage); 325 pReq->aPhysPage[iPage] = phys; 326 } 327 328 pReq->fInflate = false; 329 pReq->header.size = cbChangeMemBalloonReq; 330 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 331 332 rc = VbglGRPerform(&pReq->header); 333 if (RT_FAILURE(rc)) 334 return rc; 335 336 rc = RTR0MemObjFree(*pMemObj, true); 337 if (RT_FAILURE(rc)) 338 return rc; 339 340 *pMemObj = NIL_RTR0MEMOBJ; 341 return VINF_SUCCESS; 342 } 343 276 344 277 345 /** … … 279 347 * 280 348 * @returns VBox status code. 281 * @param pDevExt The device extension282 * @param u32BalloonSizeThe new size of the balloon in chunks of 1MB.283 */ 284 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t u32BalloonSize)349 * @param pDevExt The device extension 350 * @param cBalloonChunks The new size of the balloon in chunks of 1MB. 351 */ 352 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks) 285 353 { 286 354 int rc = VINF_SUCCESS; … … 289 357 { 290 358 VMMDevChangeMemBalloon *pReq; 291 uint32_t i, j; 292 const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 293 294 if (u32BalloonSize > pDevExt->MemBalloon.cMaxChunks) 359 uint32_t i; 360 361 if (cBalloonChunks > pDevExt->MemBalloon.cMaxChunks) 295 362 { 296 363 AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n", 297 u32BalloonSize, pDevExt->MemBalloon.cMaxChunks));364 cBalloonChunks, pDevExt->MemBalloon.cMaxChunks)); 298 365 return VERR_INVALID_PARAMETER; 299 366 } 300 367 301 if ( u32BalloonSize== pDevExt->MemBalloon.cMaxChunks)368 if (cBalloonChunks == pDevExt->MemBalloon.cMaxChunks) 302 369 return VINF_SUCCESS; /* nothing to do */ 303 370 304 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbReq, VMMDevReq_ChangeMemBalloon); 371 if ( cBalloonChunks > pDevExt->MemBalloon.cChunks 372 && !pDevExt->MemBalloon.paMemObj) 373 { 374 pDevExt->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks); 375 if (!pDevExt->MemBalloon.paMemObj) 376 { 377 LogRel(("VBoxGuestSetBalloonSizeKernel: no memory for paMemObj!\n")); 378 return VERR_NO_MEMORY; 379 } 380 } 381 382 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon); 305 383 if (RT_FAILURE(rc)) 306 384 return rc; 307 385 308 if ( u32BalloonSize> pDevExt->MemBalloon.cChunks)386 if (cBalloonChunks > pDevExt->MemBalloon.cChunks) 309 387 { 310 388 /* inflate */ 311 for (i = pDevExt->MemBalloon.cChunks; i < u32BalloonSize; i++)389 for (i = pDevExt->MemBalloon.cChunks; i < cBalloonChunks; i++) 312 390 { 313 391 rc = RTR0MemObjAllocPhysNC(&pDevExt->MemBalloon.paMemObj[i], 314 VMMDEV_MEMORY_BALLOON_CHUNK_ PAGES * PAGE_SIZE, NIL_RTHCPHYS);392 VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, NIL_RTHCPHYS); 315 393 if (RT_UNLIKELY(rc == VERR_NOT_SUPPORTED)) 316 394 { 395 /* not supported -- fall back to the R3-allocated memory */ 317 396 pDevExt->MemBalloon.fUseKernelAPI = false; 318 397 break; … … 329 408 } 330 409 331 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i]; 332 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 333 { 334 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j); 335 pReq->aPhysPage[j] = phys; 336 } 337 338 pReq->header.size = cbReq; 339 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 340 pReq->fInflate = true; 341 342 rc = VbglGRPerform(&pReq->header); 410 rc = vboxGuestBalloonInflate(&pDevExt->MemBalloon.paMemObj[i], pReq); 343 411 if (RT_FAILURE(rc)) 344 412 { 345 Log(("vboxGuestSetBalloonSize(inflate): VbglGRPerformfailed, rc=%Rrc!\n", rc));413 Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc)); 346 414 break; 347 415 } … … 352 420 { 353 421 /* deflate */ 354 for (i = pDevExt->MemBalloon.cChunks; i > u32BalloonSize; i--)422 for (i = pDevExt->MemBalloon.cChunks; i-- > cBalloonChunks;) 355 423 { 356 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i]; 357 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 358 { 359 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j); 360 pReq->aPhysPage[j] = phys; 361 } 362 363 pReq->header.size = cbReq; 364 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 365 pReq->fInflate = false; 366 367 rc = VbglGRPerform(&pReq->header); 424 rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq); 368 425 if (RT_FAILURE(rc)) 369 426 { 370 Log(("vboxGuestSetBalloonSize(deflate): VbglGRPerformfailed, rc=%Rrc!\n", rc));427 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); 371 428 break; 372 429 } 373 374 rc = RTR0MemObjFree(pDevExt->MemBalloon.paMemObj[i], true);375 if (RT_FAILURE(rc))376 {377 Log(("vboxGuestSetBalloonSize(deflate): RTR0MemObjFree() failed, rc=%Rrc!\n", rc));378 break;379 }380 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;381 430 pDevExt->MemBalloon.cChunks--; 382 431 } … … 405 454 VMMDevChangeMemBalloon *pReq; 406 455 int rc = VINF_SUCCESS; 407 uint32_t i, j; 408 const size_t cbReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 456 uint32_t i; 409 457 PRTR0MEMOBJ pMemObj = NULL; 410 458 411 if ( fInflate 412 && pSession->MemBalloon.cChunks > pSession->MemBalloon.cMaxChunks - 1) 413 { 414 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n", 415 pSession->MemBalloon.cChunks, pSession->MemBalloon.cMaxChunks)); 416 return VERR_INVALID_PARAMETER; 417 } 418 else if ( !fInflate 419 && pSession->MemBalloon.cChunks == 0) 420 { 421 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n")); 422 return VERR_INVALID_PARAMETER; 459 if (fInflate) 460 { 461 if (pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1) 462 { 463 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n", 464 pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks)); 465 return VERR_INVALID_PARAMETER; 466 } 467 468 if (!pSession->MemBalloon.paMemObj) 469 { 470 pSession->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks); 471 if (!pSession->MemBalloon.paMemObj) 472 { 473 LogRel(("VBoxGuestSetBalloonSizeFromUser: no memory for paMemObj!\n")); 474 return VERR_NO_MEMORY; 475 } 476 for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++) 477 pSession->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ; 478 } 479 } 480 else 481 { 482 if (pSession->MemBalloon.cChunks == 0) 483 { 484 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n")); 485 return VERR_INVALID_PARAMETER; 486 } 423 487 } 424 488 … … 426 490 * Enumerate all memory objects and check if the object is already registered. 427 491 */ 428 for (i = 0; i < p Session->MemBalloon.cMaxChunks; i++)492 for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++) 429 493 { 430 494 if ( fInflate 431 && !p Session->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ432 && !pMemObj)495 && !pMemObj 496 && pSession->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ) 433 497 pMemObj = &pSession->MemBalloon.paMemObj[i]; /* found free object pointer */ 434 498 if (RTR0MemObjAddressR3(pSession->MemBalloon.paMemObj[i]) == u64ChunkAddr) … … 448 512 } 449 513 450 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cb Req, VMMDevReq_ChangeMemBalloon);514 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon); 451 515 if (RT_FAILURE(rc)) 452 516 return rc; … … 456 520 if (fInflate) 457 521 { 458 rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_ PAGES * PAGE_SIZE,522 rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, 459 523 RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS); 460 524 if (RT_SUCCESS(rc)) 461 525 { 462 RTR0MEMOBJ MemObj = pDevExt->MemBalloon.paMemObj[i]; 463 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 464 { 465 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(MemObj, j); 466 pReq->aPhysPage[j] = phys; 467 } 468 469 pReq->header.size = cbReq; 470 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 471 pReq->fInflate = true; 472 473 rc = VbglGRPerform(&pReq->header); 526 rc = vboxGuestBalloonInflate(pMemObj, pReq); 474 527 if (RT_FAILURE(rc)) 475 528 { 476 Log(("vboxGuestSetBalloonSize(inflate): VbglGRPerformfailed, rc=%Rrc!\n", rc));529 Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc)); 477 530 break; 478 531 } … … 482 535 else 483 536 { 484 /* deflate */ 485 for (j = 0; j < VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; j++) 486 { 487 RTHCPHYS phys = RTR0MemObjGetPagePhysAddr(*pMemObj, j); 488 pReq->aPhysPage[j] = phys; 489 } 490 491 pReq->header.size = cbReq; 492 pReq->cPages = VMMDEV_MEMORY_BALLOON_CHUNK_PAGES; 493 pReq->fInflate = false; 494 495 rc = VbglGRPerform(&pReq->header); 537 rc = vboxGuestBalloonDeflate(pMemObj, pReq); 496 538 if (RT_FAILURE(rc)) 497 539 { 498 Log(("vboxGuestSetBalloonSize(deflate): VbglGRPerformfailed, rc=%Rrc!\n", rc));540 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); 499 541 break; 500 542 } 501 502 rc = RTR0MemObjFree(*pMemObj, true);503 if (RT_FAILURE(rc))504 {505 Log(("vboxGuestSetBalloonSize(deflate): RTR0MemObjFree() failed, rc=%Rrc!\n", rc));506 break;507 }508 *pMemObj = NIL_RTR0MEMOBJ;509 543 pSession->MemBalloon.cChunks--; 510 544 } … … 517 551 518 552 /** 553 * Cleanup the memory balloon of a session. 554 */ 555 static void vboxGuestCloseSessionMemBalloon(PVBOXGUESTSESSION pSession) 556 { 557 if (pSession->MemBalloon.paMemObj) 558 { 559 VMMDevChangeMemBalloon *pReq; 560 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon); 561 if (RT_SUCCESS(rc)) 562 { 563 uint32_t i; 564 for (i = pSession->MemBalloon.cChunks; i-- > 0;) 565 { 566 rc = vboxGuestBalloonDeflate(&pSession->MemBalloon.paMemObj[i], pReq); 567 if (RT_FAILURE(rc)) 568 { 569 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); 570 break; 571 } 572 pSession->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ; 573 pSession->MemBalloon.cChunks--; 574 } 575 VbglGRFree(&pReq->header); 576 } 577 RTMemFree(pSession->MemBalloon.paMemObj); 578 pSession->MemBalloon.paMemObj = NULL; 579 } 580 } 581 582 583 /** 519 584 * Init the variables for memory ballooning 520 585 * … … 525 590 pDevExt->MemBalloon.cChunks = 0; 526 591 pDevExt->MemBalloon.cMaxChunks = 0; 527 //#ifdef RT_OS_LINUX528 //pDevExt->MemBalloon.fUseKernelAPI = true;529 //#else592 #ifdef RT_OS_LINUX 593 pDevExt->MemBalloon.fUseKernelAPI = true; 594 #else 530 595 pDevExt->MemBalloon.fUseKernelAPI = false; 531 //#endif596 #endif 532 597 pDevExt->MemBalloon.paMemObj = NULL; 533 598 } … … 775 840 int VBoxGuestCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession) 776 841 { 777 unsigned i;778 842 PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)RTMemAllocZ(sizeof(*pSession)); 779 843 if (RT_UNLIKELY(!pSession)) … … 856 920 pSession->Process = NIL_RTPROCESS; 857 921 pSession->R0Process = NIL_RTR0PROCESS; 922 vboxGuestCloseSessionMemBalloon(pSession); 858 923 RTMemFree(pSession); 859 924 } … … 1047 1112 Log(("VBoxGuestCommonIOCtlFast: iFunction=%#x pDevExt=%p pSession=%p\n", iFunction, pDevExt, pSession)); 1048 1113 1114 NOREF(iFunction); 1115 NOREF(pDevExt); 1116 NOREF(pSession); 1049 1117 return VERR_NOT_SUPPORTED; 1050 1118 } 1051 1119 1052 1120 1053 1121 /** 1122 * Return the VMM device port. 1123 * 1124 * returns IPRT status code. 1125 * @param pDevExt The device extension. 1126 * @param pInfo The request info. 1127 * @param pcbDataReturned (out) contains the number of bytes to return. 1128 */ 1054 1129 static int VBoxGuestCommonIOCtl_GetVMMDevPort(PVBOXGUESTDEVEXT pDevExt, VBoxGuestPortInfo *pInfo, size_t *pcbDataReturned) 1055 1130 { … … 1746 1821 */ 1747 1822 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, 1748 uint32_t *memBalloonSize, size_t *pcbDataReturned)1823 VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned) 1749 1824 { 1750 1825 VMMDevGetMemBalloonChangeRequest *pReq; … … 1764 1839 } 1765 1840 1766 if ( pReq->u32BalloonSize != 0 1767 && !pDevExt->MemBalloon.paMemObj) 1768 { 1769 pDevExt->MemBalloon.cMaxChunks = pReq->u32PhysMemSize; 1770 pDevExt->MemBalloon.paMemObj = (RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pReq->u32PhysMemSize); 1771 } 1772 1773 rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->u32BalloonSize); 1774 /* ignore out of memory failures */ 1841 pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks; 1842 1843 rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->cBalloonChunks); 1844 /* Ignore out of memory failures */ 1775 1845 if (rc == VERR_NO_MEMORY) 1776 1846 rc = VINF_SUCCESS; 1777 1847 1778 /* Balloon size in MB */ 1779 *memBalloonSize = pReq->u32BalloonSize; 1848 /* Return values */ 1849 pInfo->cBalloonChunks = pReq->cBalloonChunks; 1850 pInfo->fHandleInR3 = false; 1851 if (rc == VERR_NO_PHYS_MEMORY) 1852 { 1853 pInfo->fHandleInR3 = true; 1854 rc = VINF_SUCCESS; 1855 } 1856 1780 1857 if (pcbDataReturned) 1781 *pcbDataReturned = sizeof( *memBalloonSize);1858 *pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo); 1782 1859 1783 1860 return rc; … … 1809 1886 static int VBoxGuestCommonIOCtl_Log(const char *pch, size_t cbData, size_t *pcbDataReturned) 1810 1887 { 1888 NOREF(pch); 1889 NOREF(cbData); 1811 1890 Log(("%.*s", cbData, pch)); 1812 1891 if (pcbDataReturned) … … 1977 2056 1978 2057 case VBOXGUEST_IOCTL_CHECK_BALLOON: 1979 CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof( uint32_t));1980 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, ( uint32_t*)pvData, pcbDataReturned);2058 CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(VBoxGuestCheckBalloonInfo)); 2059 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned); 1981 2060 break; 1982 2061
Note:
See TracChangeset
for help on using the changeset viewer.