VirtualBox

Ignore:
Timestamp:
Nov 18, 2018 4:52:14 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126707
Message:

VMMDev,VBoxGuestR0Lib: Added a new HGCM parameter type that allows embedding small buffers into the request (similar to the page list info structure). Currently only available to kernel code (i.e. shared folders). bugref:9172

File:
1 edited

Legend:

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

    r75126 r75548  
    5656/** The max parameter buffer size for a kernel request. */
    5757#define VBGLR0_MAX_HGCM_KERNEL_PARM     (16*_1M)
     58/** The max embedded buffer size. */
     59#define VBGLR0_MAX_HGCM_EMBEDDED_BUFFER _64K
     60
    5861#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN)
    5962/** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted
     
    258261                    Log4(("GstHGCMCall: parm=%u type=pglst: cb=0\n", iParm));
    259262                break;
     263
     264            case VMMDevHGCMParmType_Embedded:
     265                if (fIsUser) /// @todo relax this.
     266                    return VERR_INVALID_PARAMETER;
     267                cb = pSrcParm->u.Embedded.cbData;
     268                if (cb)
     269                {
     270                    uint32_t off = pSrcParm->u.Embedded.offData;
     271                    AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_EMBEDDED_BUFFER, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_EMBEDDED_BUFFER),
     272                                    VERR_INVALID_PARAMETER);
     273                    AssertMsgReturn(cb <= cbCallInfo - cParms * sizeof(HGCMFunctionParameter),
     274                                    ("cb=%#x cParms=%#x cbCallInfo=%3x\n", cb, cParms, cbCallInfo),
     275                                    VERR_INVALID_PARAMETER);
     276                    AssertMsgReturn(   off >= cParms * sizeof(HGCMFunctionParameter)
     277                                    && off <= cbCallInfo - cb,
     278                                    ("offData=%#x cParms=%#x cbCallInfo=%#x\n", off, cParms, cbCallInfo),
     279                                    VERR_INVALID_PARAMETER);
     280                    AssertMsgReturn(VBOX_HGCM_F_PARM_ARE_VALID(pSrcParm->u.Embedded.fFlags),
     281                                    ("%#x\n", pSrcParm->u.Embedded.fFlags), VERR_INVALID_PARAMETER);
     282
     283                    *pcbExtra += RT_ALIGN_32(cb, 8);
     284                }
     285                else
     286                    Log4(("GstHGCMCall: parm=%u type=embed: cb=0\n", iParm));
     287                break;
     288
    260289
    261290            case VMMDevHGCMParmType_LinAddr_Locked_In:
     
    543572                }
    544573                else
    545                     pDstParm->u.PageList.offset = 0;
    546                 break;
     574                    pDstParm->u.PageList.offset = 0; /** @todo will fail on the host side now */
     575                break;
     576
     577            case VMMDevHGCMParmType_Embedded:
     578            {
     579                uint32_t const cb = pSrcParm->u.Embedded.cbData;
     580                pDstParm->type = VMMDevHGCMParmType_Embedded;
     581                pDstParm->u.Embedded.cbData  = cb;
     582                pDstParm->u.Embedded.offData = offExtra;
     583                if (cb > 0)
     584                {
     585                    uint8_t *pbDst = (uint8_t *)pHGCMCall + offExtra;
     586                    if (pSrcParm->u.Embedded.fFlags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST)
     587                    {
     588                        memcpy(pbDst, (uint8_t const *)pCallInfo + pSrcParm->u.Embedded.offData, cb);
     589                        if (RT_ALIGN(cb, 8) != cb)
     590                            memset(pbDst + cb, 0, RT_ALIGN(cb, 8) - cb);
     591                    }
     592                    else
     593                        RT_BZERO(pbDst, RT_ALIGN(cb, 8));
     594                    offExtra += RT_ALIGN(cb, 8);
     595                }
     596                break;
     597            }
    547598
    548599            case VMMDevHGCMParmType_LinAddr_Locked_In:
     
    762813 * @returns rc, unless RTR0MemUserCopyTo fails.
    763814 * @param   pCallInfo           Call info structure to update.
     815 * @param   cbCallInfo          The size of the client request.
    764816 * @param   pHGCMCall           HGCM call request.
     817 * @param   cbHGCMCall          The size of the HGCM call request.
    765818 * @param   pParmInfo           Parameter locking/buffering info.
    766819 * @param   fIsUser             Is it a user (true) or kernel request.
     
    768821 *                              preserve informational status codes.
    769822 */
    770 static int vbglR0HGCMInternalCopyBackResult(PVBGLIOCHGCMCALL pCallInfo, VMMDevHGCMCall const *pHGCMCall,
     823static int vbglR0HGCMInternalCopyBackResult(PVBGLIOCHGCMCALL pCallInfo, uint32_t cbCallInfo,
     824                                            VMMDevHGCMCall const *pHGCMCall, uint32_t cbHGCMCall,
    771825                                            struct VbglR0ParmInfo *pParmInfo, bool fIsUser, int rc)
    772826{
     
    791845     * Copy back parameters.
    792846     */
     847    /** @todo This is assuming user data (pDstParm) is buffered.  Not true
     848     *        on OS/2, though I'm not sure we care... */
    793849    for (iParm = 0; iParm < cParms; iParm++, pSrcParm++, pDstParm++)
    794850    {
     
    803859                pDstParm->u.PageList.size = pSrcParm->u.PageList.size;
    804860                break;
     861
     862            case VMMDevHGCMParmType_Embedded:
     863            {
     864                uint32_t cb;
     865                pDstParm->u.Embedded.cbData = cb = pSrcParm->u.Embedded.cbData;
     866                if (    cb > 0
     867                    && (pDstParm->u.Embedded.fFlags & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST))
     868                {
     869                    uint32_t const offDst = pDstParm->u.Embedded.offData;
     870                    uint32_t const offSrc = pDstParm->u.Embedded.offData;
     871                    AssertReturn(offDst < cbCallInfo, VERR_INTERNAL_ERROR_2);
     872                    AssertReturn(offDst >= sizeof(*pCallInfo) + cParms * sizeof(*pDstParm), VERR_INTERNAL_ERROR_2);
     873                    AssertReturn(cb <= cbCallInfo - offDst , VERR_INTERNAL_ERROR_2);
     874                    AssertReturn(offSrc < cbCallInfo, VERR_INTERNAL_ERROR_2);
     875                    AssertReturn(offSrc >= sizeof(*pHGCMCall) + cParms * sizeof(*pSrcParm), VERR_INTERNAL_ERROR_2);
     876                    AssertReturn(cb <= cbHGCMCall - offSrc, VERR_INTERNAL_ERROR_2);
     877
     878                    memcpy((uint8_t *)pCallInfo + offDst, (uint8_t const *)pHGCMCall + offSrc, cb);
     879                }
     880                break;
     881            }
    805882
    806883            case VMMDevHGCMParmType_LinAddr_Locked_In:
     
    902979         */
    903980        VMMDevHGCMCall *pHGCMCall;
    904         rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pHGCMCall,
    905                            sizeof(VMMDevHGCMCall) + pCallInfo->cParms * sizeof(HGCMFunctionParameter) + cbExtra,
    906                            VMMDevReq_HGCMCall);
     981        uint32_t const  cbHGCMCall = sizeof(VMMDevHGCMCall) + pCallInfo->cParms * sizeof(HGCMFunctionParameter) + cbExtra;
     982        rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pHGCMCall, cbHGCMCall, VMMDevReq_HGCMCall);
    907983        if (RT_SUCCESS(rc))
    908984        {
     
    919995                 * Copy back the result (parameters and buffers that changed).
    920996                 */
    921                 rc = vbglR0HGCMInternalCopyBackResult(pCallInfo, pHGCMCall, &ParmInfo, fIsUser, rc);
     997                rc = vbglR0HGCMInternalCopyBackResult(pCallInfo, cbCallInfo, pHGCMCall, cbHGCMCall, &ParmInfo, fIsUser, rc);
    922998            }
    923999            else
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette