Changeset 27118 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Mar 5, 2010 5:41:52 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuest
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r27106 r27118 366 366 * @returns VBox status code. 367 367 * @param pDevExt The device extension. 368 * @param pSession The session. 368 369 * @param cBalloonChunks The new size of the balloon in chunks of 1MB. 369 370 */ 370 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks)371 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t cBalloonChunks) 371 372 { 372 373 int rc = VINF_SUCCESS; … … 483 484 if (fInflate) 484 485 { 485 if ( p Session->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1486 if ( pDevExt->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1 486 487 || pDevExt->MemBalloon.cMaxChunks == 0 /* If called without first querying. */) 487 488 { 488 489 LogRel(("vboxGuestSetBalloonSize: cannot inflate balloon, already have %u chunks (max=%u)\n", 489 p Session->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks));490 pDevExt->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks)); 490 491 return VERR_INVALID_PARAMETER; 491 492 } 492 493 493 if (!p Session->MemBalloon.paMemObj)494 { 495 p Session->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);496 if (!p Session->MemBalloon.paMemObj)494 if (!pDevExt->MemBalloon.paMemObj) 495 { 496 pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks); 497 if (!pDevExt->MemBalloon.paMemObj) 497 498 { 498 499 LogRel(("VBoxGuestSetBalloonSizeFromUser: no memory for paMemObj!\n")); … … 500 501 } 501 502 for (i = 0; i < pDevExt->MemBalloon.cMaxChunks; i++) 502 p Session->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;503 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ; 503 504 } 504 505 } 505 506 else 506 507 { 507 if (p Session->MemBalloon.cChunks == 0)508 if (pDevExt->MemBalloon.cChunks == 0) 508 509 { 509 510 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot decrease balloon, already at size 0\n")); … … 519 520 if ( fInflate 520 521 && !pMemObj 521 && p Session->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ)522 pMemObj = &p Session->MemBalloon.paMemObj[i]; /* found free object pointer */523 if (RTR0MemObjAddressR3(p Session->MemBalloon.paMemObj[i]) == u64ChunkAddr)522 && pDevExt->MemBalloon.paMemObj[i] == NIL_RTR0MEMOBJ) 523 pMemObj = &pDevExt->MemBalloon.paMemObj[i]; /* found free object pointer */ 524 if (RTR0MemObjAddressR3(pDevExt->MemBalloon.paMemObj[i]) == u64ChunkAddr) 524 525 { 525 526 if (fInflate) 526 527 return VERR_ALREADY_EXISTS; /* don't provide the same memory twice */ 527 pMemObj = &p Session->MemBalloon.paMemObj[i];528 pMemObj = &pDevExt->MemBalloon.paMemObj[i]; 528 529 break; 529 530 } … … 532 533 { 533 534 if (fInflate) 534 return VERR_NO_MEMORY; /* no free object pointer found -- should not happen */ 535 return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */ 535 { 536 /* no free object pointer found -- should not happen */ 537 return VERR_NO_MEMORY; 538 } 539 540 /* cannot free this memory as it wasn't provided before */ 541 return VERR_NOT_FOUND; 536 542 } 537 543 … … 548 554 rc = vboxGuestBalloonInflate(pMemObj, pReq); 549 555 if (RT_SUCCESS(rc)) 550 p Session->MemBalloon.cChunks++;556 pDevExt->MemBalloon.cChunks++; 551 557 else 552 558 { … … 561 567 rc = vboxGuestBalloonDeflate(pMemObj, pReq); 562 568 if (RT_SUCCESS(rc)) 563 p Session->MemBalloon.cChunks--;569 pDevExt->MemBalloon.cChunks--; 564 570 else 565 571 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); … … 573 579 /** 574 580 * Cleanup the memory balloon of a session. 575 */ 576 static void vboxGuestCloseSessionMemBalloon(PVBOXGUESTSESSION pSession) 577 { 578 if (pSession->MemBalloon.paMemObj) 581 * 582 * @param pDevExt The device extension. 583 * @param pDevExt The session. Can be NULL if no owner check required. 584 */ 585 static void vboxGuestCloseMemBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession) 586 { 587 if ( pSession != (PVBOXGUESTSESSION)NULL 588 && ASMAtomicReadPtr((void * volatile *)&pDevExt->MemBalloon.pOwner) != pSession) 589 return; 590 591 if (pDevExt->MemBalloon.paMemObj) 579 592 { 580 593 VMMDevChangeMemBalloon *pReq; … … 583 596 { 584 597 uint32_t i; 585 for (i = p Session->MemBalloon.cChunks; i-- > 0;)598 for (i = pDevExt->MemBalloon.cChunks; i-- > 0;) 586 599 { 587 rc = vboxGuestBalloonDeflate(&p Session->MemBalloon.paMemObj[i], pReq);600 rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq); 588 601 if (RT_FAILURE(rc)) 589 602 { … … 591 604 break; 592 605 } 593 p Session->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;594 p Session->MemBalloon.cChunks--;606 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ; 607 pDevExt->MemBalloon.cChunks--; 595 608 } 596 609 VbglGRFree(&pReq->header); 597 610 } 598 RTMemFree(pSession->MemBalloon.paMemObj); 599 pSession->MemBalloon.paMemObj = NULL; 600 } 601 } 602 603 604 /** 605 * Init the variables for memory ballooning 611 RTMemFree(pDevExt->MemBalloon.paMemObj); 612 pDevExt->MemBalloon.paMemObj = NULL; 613 } 614 615 ASMAtomicWritePtr((void * volatile *)&pDevExt->MemBalloon.pOwner, NULL); 616 } 617 618 619 /** 620 * Init the variables for memory ballooning. 606 621 * 607 622 * @param pDevExt The device extension … … 613 628 pDevExt->MemBalloon.fUseKernelAPI = true; 614 629 pDevExt->MemBalloon.paMemObj = NULL; 615 } 616 617 618 /** 619 * Finish memory ballooning, reclaim all memory from the host. 620 * 621 * @param pDevExt The device extension 622 */ 623 static void vboxGuestDoneMemBalloon(PVBOXGUESTDEVEXT pDevExt) 624 { 625 if (pDevExt->MemBalloon.paMemObj) 626 { 627 vboxGuestSetBalloonSizeKernel(pDevExt, 0); 628 RTMemFree(pDevExt->MemBalloon.paMemObj); 629 pDevExt->MemBalloon.paMemObj = NULL; 630 } 630 ASMAtomicWritePtr((void * volatile *)&pDevExt->MemBalloon.pOwner, NULL); 631 631 } 632 632 … … 822 822 VBoxGuestSetGuestCapabilities(0, UINT32_MAX); 823 823 vboxGuestSetFilterMask(pDevExt, 0); 824 vboxGuest DoneMemBalloon(pDevExt);824 vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL); 825 825 826 826 /* … … 867 867 pSession->R0Process = RTR0ProcHandleSelf(); 868 868 pSession->pDevExt = pDevExt; 869 870 pSession->MemBalloon.cChunks = 0;871 pSession->MemBalloon.cMaxChunks = 0;872 869 873 870 *ppSession = pSession; … … 937 934 pSession->Process = NIL_RTPROCESS; 938 935 pSession->R0Process = NIL_RTR0PROCESS; 939 vboxGuestClose SessionMemBalloon(pSession);936 vboxGuestCloseMemBalloon(pDevExt, pSession); 940 937 RTMemFree(pSession); 941 938 } … … 1845 1842 * 1846 1843 * @param pDevExt The device extension. 1844 * @param pSession The session. 1847 1845 * @param pInfo The output buffer. 1848 1846 * @param pcbDataReturned Where to store the amount of returned data. Can 1849 1847 * be NULL. 1850 1848 */ 1851 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, 1849 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 1852 1850 VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned) 1853 1851 { 1854 1852 VMMDevGetMemBalloonChangeRequest *pReq; 1853 PVBOXGUESTSESSION pOwner; 1854 int rc; 1855 1855 1856 Log(("VBoxGuestCommonIOCtl: QUERYMEMORYBALLOON\n")); 1856 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest); 1857 /* the first user trying to query/change the balloon is the owner */ 1858 if ( !ASMAtomicCmpXchgExPtr((void * volatile *)&pDevExt->MemBalloon.pOwner, (const void*) pSession, 1859 (PVBOXGUESTSESSION)NULL, (void**)&pOwner) 1860 && pOwner != pSession) 1861 return VERR_PERMISSION_DENIED; 1862 1863 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest); 1857 1864 if (RT_FAILURE(rc)) 1858 1865 return rc; 1859 1860 /** @todo r=bird: The following needs to be serialized as there is no one1861 * saying mr. evil user cannot start more than one VBoxService. */1862 1866 1863 1867 /* This is a response to that event. Setting this bit means that we request the value … … 1875 1879 pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks; 1876 1880 1877 rc = vboxGuestSetBalloonSizeKernel(pDevExt, p Req->cBalloonChunks);1881 rc = vboxGuestSetBalloonSizeKernel(pDevExt, pSession, pReq->cBalloonChunks); 1878 1882 /* Ignore out of memory failures */ 1879 1883 if (rc == VERR_NO_MEMORY) … … 1888 1892 rc = VINF_SUCCESS; 1889 1893 } 1894 1895 VbglGRFree(&pReq->header); 1890 1896 1891 1897 if (pcbDataReturned) … … 1911 1917 VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned) 1912 1918 { 1913 /** @todo r=bird: Don't allow this if fUseKernelAPI is true. */ 1914 /** @todo r=bird: This needs to be serialized as there is no one saying mr. evil 1915 * user cannot start more than one VBoxService. 1916 * 1917 * Actually, it would be good to drop the VBOXGUESTSESSION::MemBalloon 1918 * and instead add a VBOXGUESTDEVEXT::pMemBallonOwner 1919 * (PVBOXGUESTSESSION). Assign balloon ownership on a first come 1920 * basis, releasing it when the session quits. This could be done 1921 * regardless of the method use for memory allocation. */ 1922 int rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate); 1919 int rc; 1920 PVBOXGUESTSESSION pOwner; 1921 1922 if (pDevExt->MemBalloon.fUseKernelAPI) 1923 return VERR_PERMISSION_DENIED; 1924 1925 /* the first user trying to query/change the balloon is the owner */ 1926 if ( !ASMAtomicCmpXchgExPtr((void * volatile *)&pDevExt->MemBalloon.pOwner, (const void*) pSession, 1927 (PVBOXGUESTSESSION)NULL, (void**)&pOwner) 1928 && pOwner != pSession) 1929 return VERR_PERMISSION_DENIED; 1930 1931 rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate); 1923 1932 if (pcbDataReturned) 1924 1933 *pcbDataReturned = 0; … … 2109 2118 case VBOXGUEST_IOCTL_CHECK_BALLOON: 2110 2119 CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(VBoxGuestCheckBalloonInfo)); 2111 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);2120 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, pSession, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned); 2112 2121 break; 2113 2122 -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r27106 r27118 90 90 * and false otherwise. */ 91 91 bool fUseKernelAPI; 92 /** The owner of the balloon which is the first process using the balloon API. */ 93 PVBOXGUESTSESSION volatile pOwner; 92 94 /** The pointer to the array of memory objects holding the chunks of the 93 95 * balloon. This array is cMaxChunks in size when present. */ … … 186 188 uint32_t volatile u32MousePosChangedSeq; 187 189 188 /* Memory ballooning information if userland provides the balloon memory. */189 VBOXGUESTMEMBALLOON MemBalloon;190 190 } VBOXGUESTSESSION; 191 191
Note:
See TracChangeset
for help on using the changeset viewer.