VirtualBox

Changeset 15719 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 22, 2008 4:06:05 PM (16 years ago)
Author:
vboxsync
Message:

Additions/Linux: use jump buffers again for HGCM transfers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r15624 r15719  
    365365}
    366366
     367/** Jump buffer structure for hcgm guest-host data copies. */
     368typedef struct hgcm_jump_buffer
     369{
     370    /** Kernel memory address. */
     371    void *pKernel;
     372    /** User memory address. */
     373    void *pUser;
     374    /** Buffer size. */
     375    size_t cb;
     376} hgcm_jump_buffer;
     377
     378/** Create a jump buffer in kernel space for user space memory. */
     379static int vboxadd_hgcm_alloc_buffer(hgcm_jump_buffer **ppBuf, void *pUser,
     380                                     size_t cb)
     381{
     382    hgcm_jump_buffer *pBuf = NULL;
     383    void *pKernel = NULL;
     384    int rc = 0;
     385    AssertPtrReturn(ppBuf, -EINVAL);
     386    AssertPtrReturn(pUser, -EINVAL);
     387    pBuf = kmalloc(sizeof(*pBuf), GFP_KERNEL);
     388    if (pBuf == NULL)
     389        rc = -ENOMEM;
     390    if (rc >= 0) {
     391        pKernel = kmalloc(cb, GFP_KERNEL);
     392        if (pKernel == NULL)
     393            rc = -ENOMEM;
     394    }
     395    if (   rc >= 0
     396        && copy_from_user(pKernel, pUser, cb) != 0)
     397        rc = -EFAULT;
     398    if (rc >= 0) {
     399        pBuf->pKernel = pKernel;
     400        pBuf->pUser = pUser;
     401        pBuf->cb = cb;
     402        *ppBuf = pBuf;
     403    }
     404    else {
     405        kfree(pBuf);
     406        kfree(pKernel);
     407        LogFunc(("failed, returning %d\n", rc));
     408    }
     409    return rc;
     410}
     411
     412/** Free a kernel space jump buffer for user space memory. */
     413static int vboxadd_hgcm_free_buffer(hgcm_jump_buffer *pBuf)
     414{
     415    int rc = 0;
     416    AssertPtrReturn(pBuf, -EINVAL);
     417    if (copy_to_user(pBuf->pUser, pBuf->pKernel, pBuf->cb) != 0)
     418        rc = -EFAULT;
     419    kfree(pBuf->pKernel);  /* We want to do this whatever the outcome. */
     420    kfree(pBuf);
     421    if (rc < 0)
     422        LogFunc(("failed, returning %d\n", rc));
     423    return rc;
     424}
     425
    367426/** Lock down R3 memory as needed for the HGCM call.  Copied from
    368427 * HGCMInternal.cpp and SysHlp.cpp */
    369 static int vboxadd_lock_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
     428static int vboxadd_buffer_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
    370429{
    371430    uint32_t cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter);
    372     int rc = VINF_SUCCESS;
     431    int rc = 0;
    373432    unsigned iParm;
    374433    HGCMFunctionParameter *pParm;
     
    397456            case VMMDevHGCMParmType_LinAddr:
    398457            {
    399                 RTR3PTR pv = (RTR3PTR)pParm->u.Pointer.u.linearAddr;
     458                void *pv = (void *) pParm->u.Pointer.u.linearAddr;
    400459                uint32_t u32Size = pParm->u.Pointer.size;
    401                 RTR0MEMOBJ MemObj;
    402                 rc = RTR0MemObjLockUser(&MemObj, pv, u32Size, NIL_RTR0PROCESS);
    403                 if (RT_SUCCESS(rc))
     460                hgcm_jump_buffer *MemObj = NULL;
     461                rc = vboxadd_hgcm_alloc_buffer(&MemObj, pv, u32Size);
     462                if (rc >= 0) {
    404463                    ppvCtx[iParm] = MemObj;
    405                 else
    406                     ppvCtx[iParm] = NIL_RTR0MEMOBJ;
     464                    pParm->u.Pointer.u.linearAddr = (uintptr_t)MemObj->pKernel;
     465                } else
     466                    ppvCtx[iParm] = NULL;
    407467                break;
    408468            }
     
    411471                break;
    412472            }
    413             if (RT_FAILURE (rc))
     473            if (rc < 0)
    414474                break;
    415475        }
    416476    }
    417     return -RTErrConvertToErrno (rc);
     477    return rc;
    418478}
    419479
    420480/** Unlock R3 memory after the HGCM call.  Copied from HGCMInternal.cpp and
    421481 * SysHlp.cpp */
    422 static void vboxadd_unlock_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
     482static void vboxadd_unbuffer_hgcm_parms(void **ppvCtx, VBoxGuestHGCMCallInfo *pCallInfo)
    423483{
    424484    unsigned iParm;
     
    434494            if (ppvCtx[iParm] != NULL)
    435495            {
    436                 RTR0MEMOBJ MemObj = (RTR0MEMOBJ)ppvCtx[iParm];
    437                 int rc = RTR0MemObjFree(MemObj, false);
    438                 AssertRC(rc);
     496                hgcm_jump_buffer *MemObj = (hgcm_jump_buffer *)ppvCtx[iParm];
     497#ifdef VBOX_STRICT
     498                int rc = vboxadd_hgcm_free_buffer(MemObj);
     499                Assert(rc >= 0);  /* vboxadd_hgcm_unbuffer_user logs this. */
     500#else
     501                vboxadd_hgcm_free_buffer(MemObj);
     502#endif
    439503            }
    440504        }
     
    477541        if (rc >= 0) {
    478542            haveParms = 1;
    479             rc = vboxadd_lock_hgcm_parms(apvCtx, pInfo);
     543            rc = vboxadd_buffer_hgcm_parms(apvCtx, pInfo);
    480544        }
    481545        if (rc >= 0) {
     
    493557        }
    494558        if (haveParms)
    495             vboxadd_unlock_hgcm_parms(apvCtx, pInfo);
     559            vboxadd_unbuffer_hgcm_parms(apvCtx, pInfo);
    496560        if (pInfo != NULL)
    497561            kfree(pInfo);
     
    533597        if (rc >= 0) {
    534598            haveParms = 1;
    535             rc = vboxadd_lock_hgcm_parms(apvCtx, &pInfo->info);
     599            rc = vboxadd_buffer_hgcm_parms(apvCtx, &pInfo->info);
    536600        }
    537601        if (rc >= 0) {
     
    550614        }
    551615        if (haveParms)
    552             vboxadd_unlock_hgcm_parms(apvCtx, &pInfo->info);
     616            vboxadd_unbuffer_hgcm_parms(apvCtx, &pInfo->info);
    553617        if (pInfo != NULL)
    554618            kfree(pInfo);
     
    13761440 * End:
    13771441 */
    1378 
     1442s
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