VirtualBox

Changeset 27967 in vbox for trunk/src


Ignore:
Timestamp:
Apr 2, 2010 8:05:49 PM (15 years ago)
Author:
vboxsync
Message:

VBoxGuest (common): Ballooning review, untested: Don't use VERR_NO_PHYS_MEMORY for flagging ring-3 handling as the status was added with RTR0MemObjAllocPhysNC in mind. Just put the whole balloonning stuff behind a mutex, ring-3 is not thrusted period. Renamed functions and corrected log comments to match the current IOCtl names. Also fixed missing NIL initialization of the spinlock members - my own blunder.

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r27118 r27967  
    55
    66/*
    7  * Copyright (C) 2007-2009 Sun Microsystems, Inc.
     7 * Copyright (C) 2007-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    284284 * Inflate the balloon by one chunk represented by an R0 memory object.
    285285 *
     286 * The caller owns the balloon mutex.
     287 *
    286288 * @returns IPRT status code.
    287289 * @param   pMemObj     Pointer to the R0 memory object.
     
    310312    rc = VbglGRPerform(&pReq->header);
    311313    if (RT_FAILURE(rc))
    312         LogRel(("vboxGuestBalloonInflate: VbglGRPerform failed. rc=%d\n", rc));
     314        LogRel(("vboxGuestBalloonInflate: VbglGRPerform failed. rc=%Rrc\n", rc));
    313315    return rc;
    314316}
     
    317319/**
    318320 * Deflate the balloon by one chunk - info the host and free the memory object.
     321 *
     322 * The caller owns the balloon mutex.
    319323 *
    320324 * @returns IPRT status code.
     
    341345    if (RT_FAILURE(rc))
    342346    {
    343         LogRel(("vboxGuestBalloonDeflate: VbglGRPerform failed. rc=%d\n", rc));
     347        LogRel(("vboxGuestBalloonDeflate: VbglGRPerform failed. rc=%Rrc\n", rc));
    344348        return rc;
    345349    }
     
    363367/**
    364368 * Inflate/deflate the memory balloon and notify the host.
     369 *
     370 * This is a worker used by VBoxGuestCommonIOCtl_CheckMemoryBalloon - it takes
     371 * the mutex.
    365372 *
    366373 * @returns VBox status code.
     
    368375 * @param   pSession        The session.
    369376 * @param   cBalloonChunks  The new size of the balloon in chunks of 1MB.
    370  */
    371 static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t cBalloonChunks)
     377 * @param   pfHandleInR3    Where to return the handle-in-ring3 indicator
     378 *                          (VINF_SUCCESS if set).
     379 */
     380static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBalloonChunks, uint32_t *pfHandleInR3)
    372381{
    373382    int rc = VINF_SUCCESS;
     
    414423                    if (rc == VERR_NOT_SUPPORTED)
    415424                    {
    416                         /* not supported -- fall back to the R3-allocated memory */
     425                        /* not supported -- fall back to the R3-allocated memory. */
     426                        rc = VINF_SUCCESS;
    417427                        pDevExt->MemBalloon.fUseKernelAPI = false;
    418428                        Assert(pDevExt->MemBalloon.cChunks == 0);
    419429                        Log(("VBoxGuestSetBalloonSizeKernel: PhysNC allocs not supported, falling back to R3 allocs.\n"));
    420430                    }
    421                     /* else if (rc == VERR_NO_MEMORY): cannot allocate more memory => don't try further, just stop here */
    422                     /* else: XXX what else can fail?  VERR_MEMOBJ_INIT_FAILED for instance.   just stop. */
     431                    /* else if (rc == VERR_NO_MEMORY || rc == VERR_NO_PHYS_MEMORY):
     432                     *      cannot allocate more memory => don't try further, just stop here */
     433                    /* else: XXX what else can fail?  VERR_MEMOBJ_INIT_FAILED for instance. just stop. */
    423434                    break;
    424435                }
     
    453464    }
    454465
    455     if (!pDevExt->MemBalloon.fUseKernelAPI)
    456     {
    457         /* R3 to allocate memory, then do ioctl(VBOXGUEST_IOCTL_CHANGE_BALLOON)
    458          * and R0 to lock it down and tell the host. */
    459         rc = VERR_NO_PHYS_MEMORY;
    460     }
     466    /*
     467     * Set the handle-in-ring3 indicator.  When set Ring-3 will have to work
     468     * the balloon changes via the other API.
     469     */
     470    *pfHandleInR3 = pDevExt->MemBalloon.fUseKernelAPI ? false : true;
    461471
    462472    return rc;
     
    466476/**
    467477 * Inflate/deflate the balloon by one chunk.
     478 *
     479 * Worker for VBoxGuestCommonIOCtl_ChangeMemoryBalloon - it takes the mutex.
    468480 *
    469481 * @returns VBox status code.
     
    542554    }
    543555
     556    /*
     557     * Try inflate / defalte the balloon as requested.
     558     */
    544559    rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
    545560    if (RT_FAILURE(rc))
     
    580595 * Cleanup the memory balloon of a session.
    581596 *
     597 * Will request the balloon mutex, so it must be valid and the caller must not
     598 * own it already.
     599 *
    582600 * @param   pDevExt     The device extension.
    583  * @param   pDevExt     The session. Can be NULL if no owner check required.
     601 * @param   pDevExt     The session.  Can be NULL at unload.
    584602 */
    585603static void vboxGuestCloseMemBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
    586604{
    587     if (   pSession != (PVBOXGUESTSESSION)NULL
    588         && ASMAtomicReadPtr((void * volatile *)&pDevExt->MemBalloon.pOwner) != pSession)
    589         return;
    590 
    591     if (pDevExt->MemBalloon.paMemObj)
    592     {
    593         VMMDevChangeMemBalloon *pReq;
    594         int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
    595         if (RT_SUCCESS(rc))
    596         {
    597             uint32_t i;
    598             for (i = pDevExt->MemBalloon.cChunks; i-- > 0;)
     605    RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
     606    if (    pDevExt->MemBalloon.pOwner == pSession
     607        ||  pSession == NULL /*unload*/)
     608    {
     609        if (pDevExt->MemBalloon.paMemObj)
     610        {
     611            VMMDevChangeMemBalloon *pReq;
     612            int rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, cbChangeMemBalloonReq, VMMDevReq_ChangeMemBalloon);
     613            if (RT_SUCCESS(rc))
    599614            {
    600                 rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
    601                 if (RT_FAILURE(rc))
     615                uint32_t i;
     616                for (i = pDevExt->MemBalloon.cChunks; i-- > 0;)
    602617                {
    603                     Log(("vboxGuestSetBalloonSize(deflate): failed, rc=%Rrc!\n", rc));
    604                     break;
     618                    rc = vboxGuestBalloonDeflate(&pDevExt->MemBalloon.paMemObj[i], pReq);
     619                    if (RT_FAILURE(rc))
     620                    {
     621                        LogRel(("vboxGuestCloseMemBalloon: Deflate failed with rc=%Rrc.  Will leak %u chunks.\n",
     622                                rc, pDevExt->MemBalloon.cChunks));
     623                        break;
     624                    }
     625                    pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
     626                    pDevExt->MemBalloon.cChunks--;
    605627                }
    606                 pDevExt->MemBalloon.paMemObj[i] = NIL_RTR0MEMOBJ;
    607                 pDevExt->MemBalloon.cChunks--;
     628                VbglGRFree(&pReq->header);
    608629            }
    609             VbglGRFree(&pReq->header);
    610         }
    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.
    621  *
    622  * @param   pDevExt     The device extension
    623  */
    624 static void vboxGuestInitMemBalloon(PVBOXGUESTDEVEXT pDevExt)
    625 {
    626     pDevExt->MemBalloon.cChunks = 0;
    627     pDevExt->MemBalloon.cMaxChunks = 0;
    628     pDevExt->MemBalloon.fUseKernelAPI = true;
    629     pDevExt->MemBalloon.paMemObj = NULL;
    630     ASMAtomicWritePtr((void * volatile *)&pDevExt->MemBalloon.pOwner, NULL);
     630            else
     631                LogRel(("vboxGuestCloseMemBalloon: Failed to allocate VMMDev request buffer (rc=%Rrc).  Will leak %u chunks.\n",
     632                        rc, pDevExt->MemBalloon.cChunks));
     633            RTMemFree(pDevExt->MemBalloon.paMemObj);
     634            pDevExt->MemBalloon.paMemObj = NULL;
     635        }
     636
     637        pDevExt->MemBalloon.pOwner = NULL;
     638    }
     639    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
    631640}
    632641
     
    672681    pDevExt->fFixedEvents = fFixedEvents;
    673682    pDevExt->hGuestMappings = NIL_RTR0MEMOBJ;
     683    pDevExt->EventSpinlock = NIL_RTSPINLOCK;
    674684    pDevExt->pIrqAckEvents = NULL;
    675685    pDevExt->PhysIrqAckEvents = NIL_RTCCPHYS;
     
    683693    pDevExt->FreeList.pTail = NULL;
    684694    pDevExt->f32PendingEvents = 0;
     695    pDevExt->u32MousePosChangedSeq = 0;
     696    pDevExt->SessionSpinlock = NIL_RTSPINLOCK;
    685697    pDevExt->u32ClipboardClientId = 0;
    686     pDevExt->u32MousePosChangedSeq = 0;
     698    pDevExt->MemBalloon.hMtx = NIL_RTSEMFASTMUTEX;
     699    pDevExt->MemBalloon.cChunks = 0;
     700    pDevExt->MemBalloon.cMaxChunks = 0;
     701    pDevExt->MemBalloon.fUseKernelAPI = true;
     702    pDevExt->MemBalloon.paMemObj = NULL;
     703    pDevExt->MemBalloon.pOwner = NULL;
    687704
    688705    /*
     
    707724
    708725    /*
    709      * Create the wait and seesion spinlocks.
     726     * Create the wait and session spinlocks as well as the ballooning mutex.
    710727     */
    711728    rc = RTSpinlockCreate(&pDevExt->EventSpinlock);
     
    714731    if (RT_FAILURE(rc))
    715732    {
    716         LogRel(("VBoxGuestInitDevExt: failed to spinlock, rc=%d!\n", rc));
     733        LogRel(("VBoxGuestInitDevExt: failed to create spinlock, rc=%Rrc!\n", rc));
    717734        if (pDevExt->EventSpinlock != NIL_RTSPINLOCK)
    718735            RTSpinlockDestroy(pDevExt->EventSpinlock);
     736        return rc;
     737    }
     738
     739    rc = RTSemFastMutexCreate(&pDevExt->MemBalloon.hMtx);
     740    if (RT_FAILURE(rc))
     741    {
     742        LogRel(("VBoxGuestInitDevExt: failed to create mutex, rc=%Rrc!\n", rc));
     743        RTSpinlockDestroy(pDevExt->SessionSpinlock);
     744        RTSpinlockDestroy(pDevExt->EventSpinlock);
    719745        return rc;
    720746    }
     
    748774                    {
    749775                        vboxGuestInitFixateGuestMappings(pDevExt);
    750                         vboxGuestInitMemBalloon(pDevExt);
    751776                        Log(("VBoxGuestInitDevExt: returns success\n"));
    752777                        return VINF_SUCCESS;
    753778                    }
    754                     else
    755                         LogRel(("VBoxGuestInitDevExt: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
     779
     780                    LogRel(("VBoxGuestInitDevExt: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
    756781                }
    757782                else
     
    771796        LogRel(("VBoxGuestInitDevExt: VbglInit failed, rc=%Rrc\n", rc));
    772797
     798    rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
    773799    rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
    774800    rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock); AssertRC(rc2);
     
    816842
    817843    /*
    818      * Unfix the guest mappings, filter all events and clear
    819      * all capabilities.
     844     * Clean up the bits that involves the host first.
    820845     */
    821846    vboxGuestTermUnfixGuestMappings(pDevExt);
    822     VBoxGuestSetGuestCapabilities(0, UINT32_MAX);
    823     vboxGuestSetFilterMask(pDevExt, 0);
     847    VBoxGuestSetGuestCapabilities(0, UINT32_MAX);       /* clears all capabilities */
     848    vboxGuestSetFilterMask(pDevExt, 0);                 /* filter all events */
    824849    vboxGuestCloseMemBalloon(pDevExt, (PVBOXGUESTSESSION)NULL);
    825850
    826851    /*
    827      * Cleanup resources.
     852     * Cleanup all the other resources.
    828853     */
    829854    rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
    830855    rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock); AssertRC(rc2);
     856    rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
    831857
    832858    VBoxGuestDeleteWaitList(&pDevExt->WaitList);
     
    10901116    if (RT_FAILURE(rc))
    10911117    {
    1092         Log(("VBoxGuestSetGuestCapabilities: failed to allocate %u (%#x) bytes to cache the request. rc=%d!!\n",
     1118        Log(("VBoxGuestSetGuestCapabilities: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
    10931119             sizeof(*pReq), sizeof(*pReq), rc));
    10941120        return rc;
     
    13831409    if (RT_FAILURE(rc))
    13841410    {
    1385         Log(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc %d!!\n",
     1411        Log(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid header: size %#x, expected >= %#x (hdr); type=%#x; rc=%Rrc!!\n",
    13861412             cbData, cbReq, enmType, rc));
    13871413        return rc;
     
    13991425    if (RT_FAILURE(rc))
    14001426    {
    1401         Log(("VBoxGuestCommonIOCtl: VMMREQUEST: failed to allocate %u (%#x) bytes to cache the request. rc=%d!!\n",
     1427        Log(("VBoxGuestCommonIOCtl: VMMREQUEST: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
    14021428             cbReq, cbReq, rc));
    14031429        return rc;
     
    14381464    if (RT_FAILURE(rc))
    14391465    {
    1440         Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: failed to allocate %u (%#x) bytes to cache the request. rc=%d!!\n",
     1466        Log(("VBoxGuestCommonIOCtl: CTL_FILTER_MASK: failed to allocate %u (%#x) bytes to cache the request. rc=%Rrc!!\n",
    14411467             sizeof(*pReq), sizeof(*pReq), rc));
    14421468        return rc;
     
    18351861 * Handle VBOXGUEST_IOCTL_CHECK_BALLOON from R3.
    18361862 *
    1837  * Ask the host for the size of the balloon and try to set it accordingly. If
    1838  * this fails, return with VERR_NO_PHYS_MEMORY and userland has to provide the
    1839  * memory.
     1863 * Ask the host for the size of the balloon and try to set it accordingly.  If
     1864 * this approach fails because it's not supported, return with fHandleInR3 set
     1865 * and let the user land supply memory we can lock via the other ioctl.
    18401866 *
    18411867 * @returns VBox status code.
     
    18471873 *                              be NULL.
    18481874 */
    1849 static int VBoxGuestCommonIOCtl_QueryMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
     1875static int VBoxGuestCommonIOCtl_CheckMemoryBalloon(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
    18501876                                                   VBoxGuestCheckBalloonInfo *pInfo, size_t *pcbDataReturned)
    18511877{
    18521878    VMMDevGetMemBalloonChangeRequest *pReq;
    1853     PVBOXGUESTSESSION pOwner;
    18541879    int rc;
    18551880
    1856     Log(("VBoxGuestCommonIOCtl: QUERYMEMORYBALLOON\n"));
    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);
    1864     if (RT_FAILURE(rc))
    1865         return rc;
    1866 
    1867     /* This is a response to that event. Setting this bit means that we request the value
    1868      * from the host and change the guest memory balloon according to this value. */
    1869     pReq->eventAck = VMMDEV_EVENT_BALLOON_CHANGE_REQUEST;
    1870     rc = VbglGRPerform(&pReq->header);
    1871     if (RT_FAILURE(rc))
    1872     {
    1873         LogRel(("VBoxGuestCommonIOCtl: QUERYMEMORYBALLOON: VbglGRPerform failed. rc=%d\n", rc));
    1874         VbglGRFree(&pReq->header);
    1875         return rc;
    1876     }
    1877 
    1878     Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0);
    1879     pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks;
    1880 
    1881     rc = vboxGuestSetBalloonSizeKernel(pDevExt, pSession, pReq->cBalloonChunks);
    1882     /* Ignore out of memory failures */
    1883     if (rc == VERR_NO_MEMORY)
    1884         rc = VINF_SUCCESS;
    1885 
    1886     /* Return values */
    1887     pInfo->cBalloonChunks = pReq->cBalloonChunks;
    1888     pInfo->fHandleInR3 = false;
    1889     if (rc == VERR_NO_PHYS_MEMORY)
    1890     {
    1891         pInfo->fHandleInR3 = true;
    1892         rc = VINF_SUCCESS;
    1893     }
    1894 
    1895     VbglGRFree(&pReq->header);
    1896 
    1897     if (pcbDataReturned)
    1898         *pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo);
    1899 
    1900     Log(("VBoxGuestCommonIOCtl: QUERYMEMORYBALLOON returns %d\n", rc));
     1881    Log(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON\n"));
     1882    rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
     1883    AssertRCReturn(rc, rc);
     1884
     1885    /*
     1886     * The first user trying to query/change the balloon becomes the
     1887     * owner and owns it until the session is closed (vboxGuestCloseMemBalloon).
     1888     */
     1889    if (   pDevExt->MemBalloon.pOwner != pSession
     1890        && pDevExt->MemBalloon.pOwner == NULL)
     1891        pDevExt->MemBalloon.pOwner = pSession;
     1892
     1893    if (pDevExt->MemBalloon.pOwner == pSession)
     1894    {
     1895        rc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof(VMMDevGetMemBalloonChangeRequest), VMMDevReq_GetMemBalloonChangeRequest);
     1896        if (RT_SUCCESS(rc))
     1897        {
     1898            /*
     1899             * This is a response to that event. Setting this bit means that
     1900             * we request the value from the host and change the guest memory
     1901             * balloon according to this value.
     1902             */
     1903            pReq->eventAck = VMMDEV_EVENT_BALLOON_CHANGE_REQUEST;
     1904            rc = VbglGRPerform(&pReq->header);
     1905            if (RT_SUCCESS(rc))
     1906            {
     1907                Assert(pDevExt->MemBalloon.cMaxChunks == pReq->cPhysMemChunks || pDevExt->MemBalloon.cMaxChunks == 0);
     1908                pDevExt->MemBalloon.cMaxChunks = pReq->cPhysMemChunks;
     1909
     1910                pInfo->cBalloonChunks = pReq->cBalloonChunks;
     1911                pInfo->fHandleInR3    = false;
     1912
     1913                rc = vboxGuestSetBalloonSizeKernel(pDevExt, pReq->cBalloonChunks, &pInfo->fHandleInR3);
     1914                /* Ignore various out of memory failures. */
     1915                if (   rc == VERR_NO_MEMORY
     1916                    || rc == VERR_NO_PHYS_MEMORY
     1917                    || rc == VERR_NO_CONT_MEMORY)
     1918                    rc = VINF_SUCCESS;
     1919
     1920                if (pcbDataReturned)
     1921                    *pcbDataReturned = sizeof(VBoxGuestCheckBalloonInfo);
     1922            }
     1923            else
     1924                LogRel(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON: VbglGRPerform failed. rc=%Rrc\n", rc));
     1925            VbglGRFree(&pReq->header);
     1926        }
     1927    }
     1928    else
     1929        rc = VERR_PERMISSION_DENIED;
     1930
     1931    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
     1932    Log(("VBoxGuestCommonIOCtl: CHECK_MEMORY_BALLOON returns %Rrc\n", rc));
    19011933    return rc;
    19021934}
     
    19171949                                                    VBoxGuestChangeBalloonInfo *pInfo, size_t *pcbDataReturned)
    19181950{
    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);
    1932     if (pcbDataReturned)
    1933         *pcbDataReturned = 0;
     1951    int rc = RTSemFastMutexRequest(pDevExt->MemBalloon.hMtx);
     1952    AssertRCReturn(rc, rc);
     1953
     1954    if (!pDevExt->MemBalloon.fUseKernelAPI)
     1955    {
     1956        /*
     1957         * The first user trying to query/change the balloon becomes the
     1958         * owner and owns it until the session is closed (vboxGuestCloseMemBalloon).
     1959         */
     1960        if (   pDevExt->MemBalloon.pOwner != pSession
     1961            && pDevExt->MemBalloon.pOwner == NULL)
     1962            pDevExt->MemBalloon.pOwner = pSession;
     1963
     1964        if (pDevExt->MemBalloon.pOwner == pSession)
     1965        {
     1966            rc = vboxGuestSetBalloonSizeFromUser(pDevExt, pSession, pInfo->u64ChunkAddr, pInfo->fInflate);
     1967            if (pcbDataReturned)
     1968                *pcbDataReturned = 0;
     1969        }
     1970        else
     1971            rc = VERR_PERMISSION_DENIED;
     1972    }
     1973    else
     1974        rc = VERR_PERMISSION_DENIED;
     1975
     1976    RTSemFastMutexRelease(pDevExt->MemBalloon.hMtx);
    19341977    return rc;
    19351978}
     
    21182161            case VBOXGUEST_IOCTL_CHECK_BALLOON:
    21192162                CHECKRET_MIN_SIZE("CHECK_MEMORY_BALLOON", sizeof(VBoxGuestCheckBalloonInfo));
    2120                 rc = VBoxGuestCommonIOCtl_QueryMemoryBalloon(pDevExt, pSession, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);
     2163                rc = VBoxGuestCommonIOCtl_CheckMemoryBalloon(pDevExt, pSession, (VBoxGuestCheckBalloonInfo *)pvData, pcbDataReturned);
    21212164                break;
    21222165
     
    22382281        }
    22392282        else /* something is serious wrong... */
    2240             Log(("VBoxGuestCommonISR: acknowledge events failed rc=%d (events=%#x)!!\n",
     2283            Log(("VBoxGuestCommonISR: acknowledge events failed rc=%Rrc (events=%#x)!!\n",
    22412284                 pReq->header.rc, pReq->events));
    22422285    }
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h

    r27118 r27967  
    8282typedef struct VBOXGUESTMEMBALLOON
    8383{
     84    /** Mutext protecting the members below from concurrent access.. */
     85    RTSEMFASTMUTEX              hMtx;
    8486    /** The current number of chunks in the balloon. */
    8587    uint32_t                    cChunks;
     
    9092     * and false otherwise. */
    9193    bool                        fUseKernelAPI;
    92     /** The owner of the balloon which is the first process using the balloon API. */
    93     PVBOXGUESTSESSION volatile  pOwner;
     94    /** The current owner of the balloon.
     95     * This is automatically assigned to the first session using the ballooning
     96     * API and first released when the session closes. */
     97    PVBOXGUESTSESSION           pOwner;
    9498    /** The pointer to the array of memory objects holding the chunks of the
    9599     *  balloon.  This array is cMaxChunks in size when present. */
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