- Timestamp:
- Mar 5, 2010 3:49:11 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
r27054 r27106 48 48 #endif 49 49 50 const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 50 51 /******************************************************************************* 52 * Global Variables * 53 *******************************************************************************/ 54 static const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]); 55 51 56 52 57 … … 260 265 { 261 266 VMMDevReportGuestInfo *pReq; 262 int rc; 263 rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo); 267 int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(*pReq), VMMDevReq_ReportGuestInfo); 264 268 if (RT_SUCCESS(rc)) 265 269 { … … 298 302 * doesn't work for R3-provided memory, therefore ignore the return value. Unprotect 299 303 * done when object is freed. */ 300 rc = RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE); 301 NOREF(rc); 304 RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_NONE); 302 305 303 306 pReq->fInflate = true; … … 313 316 314 317 /** 315 * Deflate the balloon by one chunk represented by an R0memory object.318 * Deflate the balloon by one chunk - info the host and free the memory object. 316 319 * 317 320 * @returns IPRT status code. … … 342 345 } 343 346 347 /* undo previous protec call, ignore rc for reasons stated there. */ 348 RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE); 349 /*RTR0MemObjProtect(*pMemObj, 0, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, RTMEM_PROT_READ | RTMEM_PROT_WRITE | RTMEM_PROT_EXEC); - probably not safe... */ 350 344 351 rc = RTR0MemObjFree(*pMemObj, true); 345 352 if (RT_FAILURE(rc)) 353 { 354 LogRel(("vboxGuestBalloonDeflate: RTR0MemObjFree(%p,true) -> %Rrc; this is *BAD*!\n", *pMemObj, rc)); 346 355 return rc; 356 } 347 357 348 358 *pMemObj = NIL_RTR0MEMOBJ; … … 355 365 * 356 366 * @returns VBox status code. 357 * @param pDevExt The device extension 367 * @param pDevExt The device extension. 358 368 * @param cBalloonChunks The new size of the balloon in chunks of 1MB. 359 369 */ … … 369 379 if (cBalloonChunks > pDevExt->MemBalloon.cMaxChunks) 370 380 { 371 AssertMsgFailed(("vboxGuestSetBalloonSize illegal balloon size %d (max=%d)\n",372 381 LogRel(("vboxGuestSetBalloonSizeKernel: illegal balloon size %u (max=%u)\n", 382 cBalloonChunks, pDevExt->MemBalloon.cMaxChunks)); 373 383 return VERR_INVALID_PARAMETER; 374 384 } … … 380 390 && !pDevExt->MemBalloon.paMemObj) 381 391 { 382 pDevExt->MemBalloon.paMemObj = ( RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);392 pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks); 383 393 if (!pDevExt->MemBalloon.paMemObj) 384 394 { … … 399 409 rc = RTR0MemObjAllocPhysNC(&pDevExt->MemBalloon.paMemObj[i], 400 410 VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, NIL_RTHCPHYS); 401 if (RT_UNLIKELY(rc == VERR_NOT_SUPPORTED))402 {403 /* not supported -- fall back to the R3-allocated memory */404 pDevExt->MemBalloon.fUseKernelAPI = false;405 Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n"));406 break;407 }408 if (RT_UNLIKELY(rc == VERR_NO_MEMORY))409 {410 /* cannot allocate more memory => don't try further, just stop here */411 break;412 }413 411 if (RT_FAILURE(rc)) 414 412 { 415 /* XXX what else can fail? */ 413 if (rc == VERR_NOT_SUPPORTED) 414 { 415 /* not supported -- fall back to the R3-allocated memory */ 416 pDevExt->MemBalloon.fUseKernelAPI = false; 417 Assert(pDevExt->MemBalloon.cChunks == 0); 418 Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n")); 419 } 420 /* else if (rc == VERR_NO_MEMORY): cannot allocate more memory => don't try further, just stop here */ 421 /* else: XXX what else can fail? VERR_MEMOBJ_INIT_FAILED for instance. just stop. */ 416 422 break; 417 423 } … … 421 427 { 422 428 Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc)); 429 RTR0MemObjFree(pDevExt->MemBalloon.paMemObj[i], true); 430 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ; 423 431 break; 424 432 } … … 457 465 /** 458 466 * Inflate/deflate the balloon by one chunk. 467 * 468 * @returns VBox status code. 469 * @param pDevExt The device extension. 470 * @param pSession The session. 471 * @param u64ChunkAddr The address of the chunk to add to / remove from the 472 * balloon. 473 * @param fInflate Inflate if true, deflate if false. 459 474 */ 460 475 static int vboxGuestSetBalloonSizeFromUser(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, … … 468 483 if (fInflate) 469 484 { 470 if (pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1) 471 { 472 AssertMsgFailed(("vboxGuestSetBalloonSize: cannot inflate balloon, already have (max=%d)\n", 473 pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks)); 485 if ( pSession->MemBalloon.cChunks > pDevExt->MemBalloon.cMaxChunks - 1 486 || pDevExt->MemBalloon.cMaxChunks == 0 /* If called without first querying. */) 487 { 488 LogRel(("vboxGuestSetBalloonSize: cannot inflate balloon, already have %u chunks (max=%u)\n", 489 pSession->MemBalloon.cChunks, pDevExt->MemBalloon.cMaxChunks)); 474 490 return VERR_INVALID_PARAMETER; 475 491 } … … 477 493 if (!pSession->MemBalloon.paMemObj) 478 494 { 479 pSession->MemBalloon.paMemObj = ( RTR0MEMOBJ*)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);495 pSession->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAlloc(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks); 480 496 if (!pSession->MemBalloon.paMemObj) 481 497 { … … 517 533 if (fInflate) 518 534 return VERR_NO_MEMORY; /* no free object pointer found -- should not happen */ 519 else 520 return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */ 535 return VERR_NOT_FOUND; /* cannot free this memory as it wasn't provided before */ 521 536 } 522 537 … … 525 540 return rc; 526 541 527 do 528 { 529 if (fInflate) 530 { 531 rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, 532 RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS); 542 if (fInflate) 543 { 544 rc = RTR0MemObjLockUser(pMemObj, u64ChunkAddr, VMMDEV_MEMORY_BALLOON_CHUNK_SIZE, 545 RTMEM_PROT_READ | RTMEM_PROT_WRITE, NIL_RTR0PROCESS); 546 if (RT_SUCCESS(rc)) 547 { 548 rc = vboxGuestBalloonInflate(pMemObj, pReq); 533 549 if (RT_SUCCESS(rc)) 550 pSession->MemBalloon.cChunks++; 551 else 534 552 { 535 rc = vboxGuestBalloonInflate(pMemObj, pReq); 536 if (RT_FAILURE(rc)) 537 { 538 Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc)); 539 break; 540 } 541 pSession->MemBalloon.cChunks++; 553 Log(("vboxGuestSetBalloonSize(inflate): failed, rc=%Rrc!\n", rc)); 554 RTR0MemObjFree(*pMemObj, true); 555 *pMemObj = NIL_RTR0MEMOBJ; 542 556 } 543 557 } 558 } 559 else 560 { 561 rc = vboxGuestBalloonDeflate(pMemObj, pReq); 562 if (RT_SUCCESS(rc)) 563 pSession->MemBalloon.cChunks--; 544 564 else 545 { 546 rc = vboxGuestBalloonDeflate(pMemObj, pReq); 547 if (RT_FAILURE(rc)) 548 { 549 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); 550 break; 551 } 552 pSession->MemBalloon.cChunks--; 553 } 554 } while (0); 565 Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc)); 566 } 555 567 556 568 VbglGRFree(&pReq->header); … … 599 611 pDevExt->MemBalloon.cChunks = 0; 600 612 pDevExt->MemBalloon.cMaxChunks = 0; 601 #if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)602 613 pDevExt->MemBalloon.fUseKernelAPI = true; 603 #else604 pDevExt->MemBalloon.fUseKernelAPI = false;605 #endif606 614 pDevExt->MemBalloon.paMemObj = NULL; 607 615 } … … 1760 1768 * @returns VBox status code. Unlike the other HGCM IOCtls this will combine 1761 1769 * the VbglHGCMConnect/Disconnect return code with the Info.result. 1770 * 1771 * @param pDevExt The device extension. 1772 * @param pu32ClientId The client id. 1773 * @param pcbDataReturned Where to store the amount of returned data. Can 1774 * be NULL. 1762 1775 */ 1763 1776 static int VBoxGuestCommonIOCtl_HGCMClipboardReConnect(PVBOXGUESTDEVEXT pDevExt, uint32_t *pu32ClientId, size_t *pcbDataReturned) … … 1823 1836 1824 1837 /** 1825 * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3. Ask the host for the size 1826 * of the balloon and try to set it accordingly. If this fails, return with 1827 * VERR_NO_PHYS_MEMORY and userland has to provide the memory. 1838 * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3. 1839 * 1840 * Ask the host for the size of the balloon and try to set it accordingly. If 1841 * this fails, return with VERR_NO_PHYS_MEMORY and userland has to provide the 1842 * memory. 1828 1843 * 1829 1844 * @returns VBox status code. 1845 * 1846 * @param pDevExt The device extension. 1847 * @param pInfo The output buffer. 1848 * @param pcbDataReturned Where to store the amount of returned data. Can 1849 * be NULL. 1830 1850 */ 1831 1851 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, … … 1838 1858 return rc; 1839 1859 1860 /** @todo r=bird: The following needs to be serialized as there is no one 1861 * saying mr. evil user cannot start more than one VBoxService. */ 1862 1840 1863 /* This is a response to that event. Setting this bit means that we request the value 1841 1864 * from the host and change the guest memory balloon according to this value. */ … … 1849 1872 } 1850 1873 1874 Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0); 1851 1875 pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks; 1852 1876 … … 1874 1898 1875 1899 /** 1876 * 1900 * Handle a request for changing the memory balloon. 1901 * 1902 * @returns VBox status code. 1903 * 1904 * @param pDevExt The device extention. 1905 * @param pSession The session. 1906 * @param pInfo The change request structure (input). 1907 * @param pcbDataReturned Where to store the amount of returned data. Can 1908 * be NULL. 1877 1909 */ 1878 1910 static int VBoxGuestCommonIOCtl_ChangeMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, 1879 1911 VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned) 1880 1912 { 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. */ 1881 1922 int rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate); 1882 1923 if (pcbDataReturned) -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
r26999 r27106 82 82 typedef struct VBOXGUESTMEMBALLOON 83 83 { 84 /** The current number of chunks in the balloon */84 /** The current number of chunks in the balloon. */ 85 85 uint32_t cChunks; 86 86 /** The maximum number of chunks in the balloon (typically the amount of guest 87 * memory / chunksize) */87 * memory / chunksize). */ 88 88 uint32_t cMaxChunks; 89 89 /** This is true if we are using RTR0MemObjAllocPhysNC() / RTR0MemObjGetPagePhysAddr() 90 * and false otherwise */90 * and false otherwise. */ 91 91 bool fUseKernelAPI; 92 /* The pointer to the array of memory objects holding the chunks of the balloon */ 93 RTR0MEMOBJ *paMemObj; 92 /** The pointer to the array of memory objects holding the chunks of the 93 * balloon. This array is cMaxChunks in size when present. */ 94 PRTR0MEMOBJ paMemObj; 94 95 } VBOXGUESTMEMBALLOON; 96 /** Pointer to a memory balloon. */ 95 97 typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON; 96 98 … … 140 142 uint32_t u32ClipboardClientId; 141 143 142 /* Memory balloon information for RTR0MemObjAllocPhysNC(). */144 /** Memory balloon information for RTR0MemObjAllocPhysNC(). */ 143 145 VBOXGUESTMEMBALLOON MemBalloon; 144 146
Note:
See TracChangeset
for help on using the changeset viewer.