VirtualBox

Ignore:
Timestamp:
Jul 10, 2009 4:38:37 PM (15 years ago)
Author:
vboxsync
Message:

VbglR0HGCMInternal.cpp: Less wasteful bounce buffering, some bugfixes, logging.

File:
1 edited

Legend:

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

    r21464 r21487  
    4646#endif
    4747
    48 
    49 
    50 /* These functions can be only used by VBoxGuest. */
    51 
    52 DECLVBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
    53                                          VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData,
    54                                          uint32_t u32AsyncData)
    55 {
    56     VMMDevHGCMConnect *pHGCMConnect;
    57     int rc;
    58 
    59     if (!pConnectInfo || !pAsyncCallback)
    60         return VERR_INVALID_PARAMETER;
    61 
    62     pHGCMConnect = NULL;
    63 
    64     /* Allocate request */
    65     rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
    66 
    67     if (RT_SUCCESS(rc))
    68     {
    69         /* Initialize request memory */
    70         pHGCMConnect->header.fu32Flags = 0;
    71 
    72         memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
    73         pHGCMConnect->u32ClientID = 0;
    74 
    75         /* Issue request */
    76         rc = VbglGRPerform (&pHGCMConnect->header.header);
    77 
    78         if (RT_SUCCESS(rc))
    79         {
    80             /* Check if host decides to process the request asynchronously. */
    81             if (rc == VINF_HGCM_ASYNC_EXECUTE)
    82             {
    83                 /* Wait for request completion interrupt notification from host */
    84                 pAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
    85             }
    86 
    87             pConnectInfo->result = pHGCMConnect->header.result;
    88 
    89             if (RT_SUCCESS (pConnectInfo->result))
    90                 pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
    91         }
    92 
    93         VbglGRFree (&pHGCMConnect->header.header);
    94     }
    95 
    96     return rc;
    97 }
    98 
    99 
    100 DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
    101                                               VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
    102 {
    103     VMMDevHGCMDisconnect *pHGCMDisconnect;
    104     int rc;
    105 
    106     if (!pDisconnectInfo || !pAsyncCallback)
    107         return VERR_INVALID_PARAMETER;
    108 
    109     pHGCMDisconnect = NULL;
    110 
    111     /* Allocate request */
    112     rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
    113 
    114     if (RT_SUCCESS(rc))
    115     {
    116         /* Initialize request memory */
    117         pHGCMDisconnect->header.fu32Flags = 0;
    118 
    119         pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
    120 
    121         /* Issue request */
    122         rc = VbglGRPerform (&pHGCMDisconnect->header.header);
    123 
    124         if (RT_SUCCESS(rc))
    125         {
    126             /* Check if host decides to process the request asynchronously. */
    127             if (rc == VINF_HGCM_ASYNC_EXECUTE)
    128             {
    129                 /* Wait for request completion interrupt notification from host */
    130                 pAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
    131             }
    132 
    133             pDisconnectInfo->result = pHGCMDisconnect->header.result;
    134         }
    135 
    136         VbglGRFree (&pHGCMDisconnect->header.header);
    137     }
    138 
    139     return rc;
    140 }
    141 
    142 #if 0 /* new code using page list and whatnot. */
    143 
     48/*******************************************************************************
     49*   Structures and Typedefs                                                    *
     50*******************************************************************************/
    14451/**
    14552 * Lock info structure used by VbglR0HGCMInternalCall and its helpers.
     
    15259        uint32_t    iParm;
    15360        RTR0MEMOBJ  hObj;
     61#ifdef USE_BOUNCH_BUFFERS
     62        void       *pvSmallBuf;
     63#endif
    15464    } aLockBufs[10];
    15565};
     66
     67
     68
     69/* These functions can be only used by VBoxGuest. */
     70
     71DECLVBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
     72                                         VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData,
     73                                         uint32_t u32AsyncData)
     74{
     75    VMMDevHGCMConnect *pHGCMConnect;
     76    int rc;
     77
     78    if (!pConnectInfo || !pAsyncCallback)
     79        return VERR_INVALID_PARAMETER;
     80
     81    pHGCMConnect = NULL;
     82
     83    /* Allocate request */
     84    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
     85
     86    if (RT_SUCCESS(rc))
     87    {
     88        /* Initialize request memory */
     89        pHGCMConnect->header.fu32Flags = 0;
     90
     91        memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
     92        pHGCMConnect->u32ClientID = 0;
     93
     94        /* Issue request */
     95        rc = VbglGRPerform (&pHGCMConnect->header.header);
     96
     97        if (RT_SUCCESS(rc))
     98        {
     99            /* Check if host decides to process the request asynchronously. */
     100            if (rc == VINF_HGCM_ASYNC_EXECUTE)
     101            {
     102                /* Wait for request completion interrupt notification from host */
     103                pAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
     104            }
     105
     106            pConnectInfo->result = pHGCMConnect->header.result;
     107
     108            if (RT_SUCCESS (pConnectInfo->result))
     109                pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
     110        }
     111
     112        VbglGRFree (&pHGCMConnect->header.header);
     113    }
     114
     115    return rc;
     116}
     117
     118
     119DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
     120                                              VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
     121{
     122    VMMDevHGCMDisconnect *pHGCMDisconnect;
     123    int rc;
     124
     125    if (!pDisconnectInfo || !pAsyncCallback)
     126        return VERR_INVALID_PARAMETER;
     127
     128    pHGCMDisconnect = NULL;
     129
     130    /* Allocate request */
     131    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
     132
     133    if (RT_SUCCESS(rc))
     134    {
     135        /* Initialize request memory */
     136        pHGCMDisconnect->header.fu32Flags = 0;
     137
     138        pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
     139
     140        /* Issue request */
     141        rc = VbglGRPerform (&pHGCMDisconnect->header.header);
     142
     143        if (RT_SUCCESS(rc))
     144        {
     145            /* Check if host decides to process the request asynchronously. */
     146            if (rc == VINF_HGCM_ASYNC_EXECUTE)
     147            {
     148                /* Wait for request completion interrupt notification from host */
     149                pAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
     150            }
     151
     152            pDisconnectInfo->result = pHGCMDisconnect->header.result;
     153        }
     154
     155        VbglGRFree (&pHGCMDisconnect->header.header);
     156    }
     157
     158    return rc;
     159}
     160
     161#if 0 /* new code using page list and whatnot. */
    156162
    157163/**
     
    172178    uint32_t    cParms = pCallInfo->cParms;
    173179    uint32_t    iParm;
     180    uint32_t    cb;
    174181
    175182    /*
    176183     * Lock down the any linear buffers so we can get their addresses
    177184     * and figure out how much extra storage we need for page lists.
     185     *
     186     * Note! With kernel mode users we can be assertive. For user mode users
     187     *       we should just (debug) log it and fail without any fanfare.
    178188     */
    179189    *pcbExtra = 0;
     
    184194        {
    185195            case VMMDevHGCMParmType_32bit:
     196                Log4(("GstHGCMCall: parm=%u type=32bit: %#010x\n", iParm, pSrcParm->u.value32));
     197                break;
     198
    186199            case VMMDevHGCMParmType_64bit:
     200                Log4(("GstHGCMCall: parm=%u type=64bit: %#018x\n", iParm, pSrcParm->u.value64));
    187201                break;
    188202
     
    190204                if (fIsUser)
    191205                    return VERR_INVALID_PARAMETER;
    192                 if (pSrcParm->u.PageList.size)
    193                 {
    194                     HGCMPageListInfo *pPgLst;
    195 
    196                     if (pSrcParm->u.Pointer.size > VBGLR0_MAX_HGCM_KERNEL_PARM)
    197                         return VERR_OUT_OF_RANGE;
    198                     AssertReturn(   pSrcParm->u.PageList.offset >= pCallInfo->cParms * sizeof(HGCMFunctionParameter)
    199                                  && pSrcParm->u.PageList.offset < cbCallInfo - sizeof(HGCMPageListInfo), VERR_INVALID_PARAMETER);
    200                     pPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + pSrcParm->u.PageList.offset);
    201                     AssertReturn(RT_OFFSETOF(HGCMPageListInfo, aPages[pPgLst->cPages]) + pSrcParm->u.PageList.offset <= cbCallInfo, VERR_INVALID_PARAMETER);
    202                     AssertReturn(pPgLst->offFirstPage < PAGE_SIZE, VERR_INVALID_PARAMETER);
    203                     AssertReturn(pPgLst->flags > VBOX_HGCM_F_PARM_DIRECTION_NONE && pPgLst->flags <= VBOX_HGCM_F_PARM_DIRECTION_BOTH, VERR_INVALID_PARAMETER);
     206                cb = pSrcParm->u.PageList.size;
     207                if (cb)
     208                {
     209                    uint32_t            off = pSrcParm->u.PageList.offset;
     210                    HGCMPageListInfo   *pPgLst;
     211                    uint32_t            cPages;
     212                    uint32_t            u32;
     213
     214                    AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM), VERR_OUT_OF_RANGE);
     215                    AssertMsgReturn(   off >= pCallInfo->cParms * sizeof(HGCMFunctionParameter)
     216                                    && off < cbCallInfo - sizeof(HGCMPageListInfo),
     217                                    ("offset=%#x cParms=%#x cbCallInfo=%#x\n", off, pCallInfo->cParms, cbCallInfo),
     218                                    VERR_INVALID_PARAMETER);
     219
     220                    pPgLst = (HGCMPageListInfo *)((uint8_t *)pCallInfo + off);
     221                    cPages = pPgLst->cPages;
     222                    u32    = RT_OFFSETOF(HGCMPageListInfo, aPages[cPages]) + off;
     223                    AssertMsgReturn(u32 <= cbCallInfo,
     224                                    ("u32=%#x (cPages=%#x offset=%#x) cbCallInfo=%#x\n", u32, cPages, off, cbCallInfo),
     225                                    VERR_INVALID_PARAMETER);
     226                    AssertMsgReturn(pPgLst->offFirstPage < PAGE_SIZE, ("#x\n", pPgLst->offFirstPage), VERR_INVALID_PARAMETER);
     227                    u32 = RT_ALIGN_32(pPgLst->offFirstPage + cb, PAGE_SIZE) >> PAGE_SHIFT;
     228                    AssertMsgReturn(cPages == u32, ("cPages=%#x u32=%#x\n", cPages, u32), VERR_INVALID_PARAMETER);
     229                    AssertMsgReturn(pPgLst->flags > VBOX_HGCM_F_PARM_DIRECTION_NONE && pPgLst->flags <= VBOX_HGCM_F_PARM_DIRECTION_BOTH,
     230                                    ("%#x\n", pPgLst->flags),
     231                                    VERR_INVALID_PARAMETER);
     232                    Log4(("GstHGCMCall: parm=%u type=pglst: cb=%#010x cPgs=%u offPg0=%#x flags=%#x\n", iParm, cb, cPages, pPgLst->offFirstPage, pPgLst->flags));
     233                    u32 = cPages;
     234                    while (u32-- > 0)
     235                    {
     236                        Log4(("GstHGCMCall:   pg#%u=%RHp\n", u32, pPgLst->aPages[u32]));
     237                        AssertMsgReturn(!(pPgLst->aPages[u32] & (PAGE_OFFSET_MASK | UINT64_C(0xfff0000000000000))),
     238                                        ("pg#%u=%RHp\n", u32, pPgLst->aPages[u32]),
     239                                        VERR_INVALID_PARAMETER);
     240                    }
    204241
    205242                    *pcbExtra += RT_OFFSETOF(HGCMPageListInfo, aPages[pPgLst->cPages]);
    206243                }
     244                else
     245                    Log4(("GstHGCMCall: parm=%u type=pglst: cb=0\n", iParm));
    207246                break;
    208247
     
    214253                if (!VBGLR0_CAN_USE_PHYS_PAGE_LIST())
    215254                {
    216                     if (pSrcParm->u.Pointer.size > VBGLR0_MAX_HGCM_KERNEL_PARM)
    217                         return VERR_OUT_OF_RANGE;
     255                    cb = pSrcParm->u.Pointer.size;
     256                    AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM), VERR_OUT_OF_RANGE);
     257                    if (cb != 0)
     258                        Log4(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p\n", iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr));
     259                    else
     260                        Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
    218261                    break;
    219262                }
     
    223266            case VMMDevHGCMParmType_LinAddr_Out:
    224267            case VMMDevHGCMParmType_LinAddr:
    225                 if (pSrcParm->u.Pointer.size > (fIsUser ? VBGLR0_MAX_HGCM_USER_PARM : VBGLR0_MAX_HGCM_KERNEL_PARM))
    226                     return VERR_OUT_OF_RANGE;
    227                 if (pSrcParm->u.Pointer.size != 0)
    228                 {
    229                     RTR0MEMOBJ hObj;
    230                     int rc;
    231 
    232                     AssertReturn(pParmInfo->cLockBufs < RT_ELEMENTS(pParmInfo->aLockBufs), VERR_INVALID_PARAMETER);
     268                cb = pSrcParm->u.Pointer.size;
     269                if (cb != 0)
     270                {
     271#ifdef USE_BOUNCH_BUFFERS
     272                    void       *pvSmallBuf = NULL;
     273#endif
     274                    uint32_t    iLockBuf   = pParmInfo->cLockBufs;
     275                    RTR0MEMOBJ  hObj;
     276                    int         rc;
     277
     278                    AssertReturn(iLockBuf < RT_ELEMENTS(pParmInfo->aLockBufs), VERR_INVALID_PARAMETER);
    233279                    if (!fIsUser)
    234                         rc = RTR0MemObjLockKernel(&hObj,
    235                                                   (void *)pSrcParm->u.Pointer.u.linearAddr,
    236                                                   pSrcParm->u.Pointer.size);
     280                    {
     281                        AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_KERNEL_PARM, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_KERNEL_PARM), VERR_OUT_OF_RANGE);
     282                        rc = RTR0MemObjLockKernel(&hObj, (void *)pSrcParm->u.Pointer.u.linearAddr, cb);
     283                        if (RT_FAILURE(rc))
     284                        {
     285                            Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockKernel(,%p,%#x) -> %Rrc\n",
     286                                 pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
     287                            return rc;
     288                        }
     289                        Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked kernel -> %p\n", iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
     290                    }
    237291                    else
    238292                    {
     293                        if (cb > VBGLR0_MAX_HGCM_USER_PARM)
     294                        {
     295                            Log(("GstHGCMCall: id=%#x fn=%u parm=%u pv=%p cb=%#x > %#x -> out of range\n",
     296                                 pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, VBGLR0_MAX_HGCM_USER_PARM));
     297                            return VERR_OUT_OF_RANGE;
     298                        }
     299
     300#ifndef USE_BOUNCH_BUFFERS
     301                        rc = RTR0MemObjLockUser(&hObj, (RTR3PTR)pSrcParm->u.Pointer.u.linearAddr, cb, NIL_RTR0PROCESS);
     302                        if (RT_FAILURE(rc))
     303                        {
     304                            Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemObjLockUser(,%p,%#x,nil) -> %Rrc\n",
     305                                 pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
     306                            return rc;
     307                        }
     308                        Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p locked user -> %p\n", iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
     309
     310#else  /* USE_BOUNCH_BUFFERS */
     311                        /*
     312                         * This is a bit massive, but we don't want to waste a
     313                         * whole page for a 3 byte string buffer (guest props).
     314                         *
     315                         * The threshold is ASSUMING sizeof(RTMEMHDR) == 16 and
     316                         * the system is using some power of two allocator.
     317                         */
     318                        /** @todo A more efficient strategy would be to combine buffers. However it
     319                         *        is probably going to be more massive than the current code, so
     320                         *        it can wait till later.   */
     321                        bool fCopyIn = pSrcParm->type != VMMDevHGCMParmType_LinAddr_Out
     322                                    && pSrcParm->type != VMMDevHGCMParmType_LinAddr_Locked_Out;
     323                        if (cb <= PAGE_SIZE / 2 - 16)
     324                        {
     325                            pvSmallBuf = fCopyIn ? RTMemTmpAlloc(cb) : RTMemTmpAllocZ(cb);
     326                            if (RT_UNLIKELY(!pvSmallBuf))
     327                                return VERR_NO_MEMORY;
     328                            if (fCopyIn)
     329                            {
     330                                rc = RTR0MemUserCopyFrom(pvSmallBuf, pSrcParm->u.Pointer.u.linearAddr, cb);
     331                                if (RT_FAILURE(rc))
     332                                {
     333                                    RTMemTmpFree(pvSmallBuf);
     334                                    Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
     335                                         pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
     336                                    return rc;
     337                                }
     338                            }
     339                            rc = RTR0MemObjLockKernel(&hObj, pvSmallBuf, cb);
     340                            if (RT_FAILURE(rc))
     341                            {
     342                                RTMemTmpFree(pvSmallBuf);
     343                                Log(("GstHGCMCall: RTR0MemObjLockKernel failed for small buffer: rc=%Rrc pvSmallBuf=%p cb=%#x\n", rc, pvSmallBuf, cb));
     344                                return rc;
     345                            }
     346                            Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p small buffer %p -> %p\n", iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, pvSmallBuf, hObj));
     347                        }
     348                        else
     349                        {
     350                            rc = RTR0MemObjAllocPage(&hObj, cb, false /*fExecutable*/);
     351                            if (RT_FAILURE(rc))
     352                                return rc;
     353                            if (!fCopyIn)
     354                                memset(RTR0MemObjAddress(hObj), '\0', cb);
     355                            else
     356                            {
     357                                rc = RTR0MemUserCopyFrom(RTR0MemObjAddress(hObj), pSrcParm->u.Pointer.u.linearAddr, cb);
     358                                if (RT_FAILURE(rc))
     359                                {
     360                                    RTR0MemObjFree(hObj, false /*fFreeMappings*/);
     361                                    Log(("GstHGCMCall: id=%#x fn=%u parm=%u RTR0MemUserCopyFrom(,%p,%#x) -> %Rrc\n",
     362                                         pCallInfo->u32ClientID, pCallInfo->u32Function, iParm, pSrcParm->u.Pointer.u.linearAddr, cb, rc));
     363                                    return rc;
     364                                }
     365                            }
     366                            Log3(("GstHGCMCall: parm=%u type=%#x: cb=%#010x pv=%p big buffer -> %p\n", iParm, pSrcParm->type, cb, pSrcParm->u.Pointer.u.linearAddr, hObj));
     367                        }
     368#endif /* USE_BOUNCH_BUFFERS */
     369                    }
     370
     371                    pParmInfo->aLockBufs[iLockBuf].iParm      = iParm;
     372                    pParmInfo->aLockBufs[iLockBuf].hObj       = hObj;
    239373#ifdef USE_BOUNCH_BUFFERS
    240                         rc = RTR0MemObjAllocPage(&hObj,
    241                                                  pSrcParm->u.Pointer.size,
    242                                                  false /*fExecutable*/);
    243                         if (    RT_SUCCESS(rc)
    244                             &&  pSrcParm->type != VMMDevHGCMParmType_LinAddr_Out
    245                             &&  pSrcParm->type != VMMDevHGCMParmType_LinAddr_Locked_Out)
    246                         {
    247                             rc = RTR0MemUserCopyFrom(RTR0MemObjAddress(hObj),
    248                                                      pSrcParm->u.Pointer.u.linearAddr,
    249                                                      pSrcParm->u.Pointer.size + 2);
    250                             if (RT_FAILURE(rc))
    251                                 RTR0MemObjFree(hObj, false /*fFreeMappings*/);
    252                         }
    253 #else
    254                         rc = RTR0MemObjLockUser(&hObj,
    255                                                 (RTR3PTR)pSrcParm->u.Pointer.u.linearAddr,
    256                                                 pSrcParm->u.Pointer.size,
    257                                                 NIL_RTR0PROCESS);
     374                    pParmInfo->aLockBufs[iLockBuf].pvSmallBuf = pvSmallBuf;
    258375#endif
    259                     }
    260                     if (RT_FAILURE(rc))
    261                         return rc;
    262 
    263                     pParmInfo->aLockBufs[pParmInfo->cLockBufs].iParm = iParm;
    264                     pParmInfo->aLockBufs[pParmInfo->cLockBufs].hObj  = hObj;
    265                     pParmInfo->cLockBufs++;
     376                    pParmInfo->cLockBufs = iLockBuf + 1;
    266377
    267378                    if (VBGLR0_CAN_USE_PHYS_PAGE_LIST())
     
    271382                    }
    272383                }
     384                else
     385                    Log4(("GstHGCMCall: parm=%u type=%#x: cb=0\n", iParm, pSrcParm->type));
    273386                break;
    274387
     
    315428        case VMMDevHGCMParmType_LinAddr_In:
    316429        case VMMDevHGCMParmType_LinAddr_Locked_In:
    317             return VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
     430            return VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
    318431
    319432        case VMMDevHGCMParmType_LinAddr_Out:
    320433        case VMMDevHGCMParmType_LinAddr_Locked_Out:
    321             return VBOX_HGCM_F_PARM_DIRECTION_TO_HOST;
     434            return VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
    322435
    323436        default: AssertFailed();
     
    411524                if (pSrcParm->u.Pointer.size != 0)
    412525                {
    413                     RTR0MEMOBJ hObj = pParmInfo->aLockBufs[iLockBuf].hObj;
     526#ifdef USE_BOUNCH_BUFFERS
     527                    void      *pvSmallBuf = pParmInfo->aLockBufs[iLockBuf].pvSmallBuf;
     528#endif
     529                    RTR0MEMOBJ hObj       = pParmInfo->aLockBufs[iLockBuf].hObj;
    414530                    Assert(iParm == pParmInfo->aLockBufs[iLockBuf].iParm);
    415531
     
    426542#ifdef USE_BOUNCH_BUFFERS
    427543                        if (fIsUser)
    428                             pDstPgLst->offFirstPage = 0;
     544                            pDstPgLst->offFirstPage = (uintptr_t)pvSmallBuf & PAGE_OFFSET_MASK;
    429545                        else
    430546#endif
     
    445561#ifdef USE_BOUNCH_BUFFERS
    446562                        if (fIsUser)
    447                             pDstParm->u.Pointer.u.linearAddr = (uintptr_t)RTR0MemObjAddress(hObj);
     563                            pDstParm->u.Pointer.u.linearAddr = pvSmallBuf
     564                                                             ? (uintptr_t)pvSmallBuf
     565                                                             : (uintptr_t)RTR0MemObjAddress(hObj);
    448566                        else
    449567#endif
     
    523641        }
    524642    }
     643
     644    Log(("GstHGCMCall: rc=%Rrc result=%Rrc fu32Flags=%#x\n", rc, pHGCMCall->header.result, pHGCMCall->header.fu32Flags));
    525645    return rc;
    526646}
     
    597717                if (fIsUser)
    598718                {
    599                     if (    pSrcParm->u.Pointer.size != 0
    600                         &&  pDstParm->u.Pointer.size != 0)
     719                    size_t cbOut = RT_MIN(pSrcParm->u.Pointer.size, pDstParm->u.Pointer.size);
     720                    if (cbOut)
    601721                    {
    602722                        Assert(pParmInfo->aLockBufs[iLockBuf].iParm == iParm);
    603723                        int rc2 = RTR0MemUserCopyTo((RTR3PTR)pDstParm->u.Pointer.u.linearAddr,
    604                                                     RTR0MemObjAddress(pParmInfo->aLockBufs[iLockBuf].hObj),
    605                                                     RT_MIN(pSrcParm->u.Pointer.size, pDstParm->u.Pointer.size));
     724                                                    pParmInfo->aLockBufs[iLockBuf].pvSmallBuf
     725                                                    ? pParmInfo->aLockBufs[iLockBuf].pvSmallBuf
     726                                                    : RTR0MemObjAddress(pParmInfo->aLockBufs[iLockBuf].hObj),
     727                                                    cbOut);
    606728                        if (RT_FAILURE(rc2))
    607729                            return rc2;
     
    648770                 VERR_INVALID_PARAMETER);
    649771
    650     Log (("VbglR0HGCMInternalCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d, fFlags=%#x\n",
    651           pCallInfo->cParms, pCallInfo->u32Function, fFlags));
     772    Log(("GstHGCMCall: u32ClientID=%#x u32Function=%u cParms=%u cbCallInfo=%#x fFlags=%#x\n",
     773         pCallInfo->u32ClientID, pCallInfo->u32ClientID, pCallInfo->u32Function, pCallInfo->cParms, cbCallInfo, fFlags));
    652774
    653775    /*
    654      * Preprocess the parameters, locking/buffering stuff.
     776     * Validate, lock and buffer the parameters for the call.
     777     * This will calculate the amount of extra space for physical page list.
    655778     */
    656779    rc = vbglR0HGCMInternalPreprocessCall(pCallInfo, cbCallInfo, fIsUser, &ParmInfo, &cbExtra);
     
    685808
    686809    /*
    687      * Copy back buffered data and release buffers & locks.
     810     * Release locks and free bounce buffers.
    688811     */
    689812    if (ParmInfo.cLockBufs)
    690813        while (ParmInfo.cLockBufs-- > 0)
     814        {
    691815            RTR0MemObjFree(ParmInfo.aLockBufs[ParmInfo.cLockBufs].hObj, false /*fFreeMappings*/);
     816#ifdef USE_BOUNCH_BUFFERS
     817            RTMemTmpFree(ParmInfo.aLockBufs[ParmInfo.cLockBufs].pvSmallBuf);
     818#endif
     819        }
    692820
    693821    return rc;
     
    814942                    VERR_INVALID_PARAMETER);
    815943
    816     Log (("VbglR0HGCMInternalCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d, fFlags=%#x\n",
     944    Log (("GstHGCMCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d, fFlags=%#x\n",
    817945          pCallInfo->cParms, pCallInfo->u32Function, fFlags));
    818946
     
    838966    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMCall, sizeof (VMMDevHGCMCall) + cbParms, VMMDevReq_HGCMCall);
    839967
    840     Log (("VbglR0HGCMInternalCall: Allocated gr %p, rc = %Rrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
     968    Log (("GstHGCMCall: Allocated gr %p, rc = %Rrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
    841969
    842970    if (RT_SUCCESS(rc))
     
    10141142                    VERR_INVALID_PARAMETER);
    10151143
    1016     Log (("VbglR0HGCMInternalCall32: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d, fFlags=%#x\n",
     1144    Log (("GstHGCMCall32: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d, fFlags=%#x\n",
    10171145          pCallInfo->cParms, pCallInfo->u32Function, fFlags));
    10181146
     
    10381166    rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMCall, sizeof (VMMDevHGCMCall) + cbParms, VMMDevReq_HGCMCall32);
    10391167
    1040     Log (("VbglR0HGCMInternalCall32: Allocated gr %p, rc = %Rrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
     1168    Log (("GstHGCMCall32: Allocated gr %p, rc = %Rrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
    10411169
    10421170    if (RT_SUCCESS(rc))
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