VirtualBox

Ignore:
Timestamp:
Nov 14, 2008 2:53:05 PM (16 years ago)
Author:
vboxsync
Message:

Additions/Linux: remove Linux-specific guest R0 HGCM hack and add VBOXGUEST_IOCTL_CALL_TIMEOUT support for Linux

Location:
trunk/src/VBox/Additions/linux/module
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/module/Makefile.kmk

    r14015 r14218  
    5858vboxadd_SOURCES  = \
    5959        vboxmod.c \
    60         cmc.c \
    61         hgcmcall.c
     60        cmc.c
    6261vboxadd_LIBS     = \
    6362        $(VBOX_LIB_VBGL_R0BASE) \
  • trunk/src/VBox/Additions/linux/module/Makefile.module

    r13773 r14218  
    6161OBJS   = \
    6262        cmc.o \
    63         hgcmcall.o \
    6463        vboxmod.o \
    6564        GenericRequest.o \
     
    7069        VMMDev.o \
    7170        r0drv/alloc-r0drv.o \
     71        r0drv/memobj-r0drv.o \
    7272        r0drv/linux/alloc-r0drv-linux.o \
    7373        r0drv/linux/assert-r0drv-linux.o \
     74        r0drv/linux/memobj-r0drv-linux.o \
     75        r0drv/linux/process-r0drv-linux.o \
    7476        r0drv/linux/semevent-r0drv-linux.o \
    7577        r0drv/linux/semfastmutex-r0drv-linux.o \
  • trunk/src/VBox/Additions/linux/module/cmc.c

    r13835 r14218  
    4040}
    4141
     42static DECLVBGL(void)
     43vboxadd_hgcm_callback_timeout (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)
     44{
     45    VBoxDevice *dev = pvData;
     46    wait_event_interruptible_timeout (dev->eventq, pHeader->fu32Flags & VBOX_HGCM_REQ_DONE,
     47                                      msecs_to_jiffies (u32Data));
     48}
     49
    4250DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data)
    4351{
    44     switch (func)
     52    int rc = VINF_SUCCESS;
     53
     54    /* this function can handle cancelled requests */
     55    if (   VBOXGUEST_IOCTL_STRIP_SIZE(func)
     56        == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
     57        rc = VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, 0);
     58    /* this function can handle cancelled requests */
     59    else if (   VBOXGUEST_IOCTL_STRIP_SIZE(func)
     60             == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0)))
     61    {
     62        VBoxGuestHGCMCallInfoTimeout *pCallInfo;
     63        pCallInfo = (VBoxGuestHGCMCallInfoTimeout *) data;
     64        rc = VbglHGCMCall (&pCallInfo->info, vboxadd_hgcm_callback_timeout,
     65                           opaque, pCallInfo->u32Timeout);
     66    }
     67    else switch (func)
    4568    {
    4669        /* this function can NOT handle cancelled requests */
    4770        case VBOXGUEST_IOCTL_HGCM_CONNECT:
    48             return VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, 0);
     71            rc = VbglHGCMConnect (data, vboxadd_hgcm_callback, opaque, 0);
     72            break;
    4973
    5074        /* this function can NOT handle cancelled requests */
    5175        case VBOXGUEST_IOCTL_HGCM_DISCONNECT:
    52             return VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, 0);
     76            rc = VbglHGCMDisconnect (data, vboxadd_hgcm_callback, opaque, 0);
     77            break;
    5378
    54         /* this function can handle cancelled requests */
    5579        default:
    56             if (VBOXGUEST_IOCTL_STRIP_SIZE(func) != VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL(0)))
    57                 return VERR_VBGL_IOCTL_FAILED;
    58             /* fall thru */
    59         case VBOXGUEST_IOCTL_STRIP_SIZE (VBOXGUEST_IOCTL_HGCM_CALL (0)):
    60             return VbglHGCMCall (data, vboxadd_hgcm_callback_interruptible, opaque, 0);
     80            rc = VERR_VBGL_IOCTL_FAILED;
    6181    }
     82    return rc;
    6283}
    6384
  • trunk/src/VBox/Additions/linux/module/files_vboxadd

    r14015 r14218  
    3030    ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \
    3131    ${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \
     32    ${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \
    3233    ${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \
     34    ${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \
    3335    ${PATH_ROOT}/include/iprt/semaphore.h=>include/iprt/semaphore.h \
    3436    ${PATH_ROOT}/include/iprt/spinlock.h=>include/iprt/spinlock.h \
     
    5658    ${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VMMDev.cpp=>VMMDev.c \
    5759    ${PATH_ROOT}/src/VBox/Runtime/include/internal/magics.h=>include/internal/magics.h \
     60    ${PATH_ROOT}/src/VBox/Runtime/include/internal/memobj.h=>include/internal/memobj.h \
    5861    ${PATH_ROOT}/src/VBox/Runtime/include/internal/string.h=>include/internal/string.h \
    5962    ${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>alloc/heapsimple.c \
     
    7376    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
    7477    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
     78    ${PATH_ROOT}/src/VBox/Runtime/r0drv/memobj-r0drv.cpp=>r0drv/memobj-r0drv.c \
    7579    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c=>r0drv/linux/alloc-r0drv-linux.c \
    7680    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/assert-r0drv-linux.c=>r0drv/linux/assert-r0drv-linux.c \
     81    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c=>r0drv/linux/memobj-r0drv-linux.c \
     82    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/process-r0drv-linux.c=>r0drv/linux/process-r0drv-linux.c \
    7783    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c=>r0drv/linux/semevent-r0drv-linux.c \
    7884    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c=>r0drv/linux/semeventmulti-r0drv-linux.c \
     
    8591    ${PATH_ROOT}/src/VBox/Additions/linux/module/vboxmod.c=>vboxmod.c \
    8692    ${PATH_ROOT}/src/VBox/Additions/linux/module/cmc.c=>cmc.c \
    87     ${PATH_ROOT}/src/VBox/Additions/linux/module/hgcmcall.c=>hgcmcall.c \
    8893    ${PATH_ROOT}/src/VBox/Additions/linux/module/vboxmod.h=>vboxmod.h \
    8994    ${PATH_ROOT}/src/VBox/Additions/linux/module/waitcompat.h=>waitcompat.h \
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r13837 r14218  
    287287{
    288288        VBoxGuestHGCMConnectInfo info;
    289         VBoxGuestHGCMDisconnectInfo infoDisconnect;
    290         int rc = 0, rcVBox;
    291 
    292         if (0 != copy_from_user ((void *)&info, (void *)userspace_info, sizeof (info))) {
    293                 LogRelFunc (("VBOXGUEST_IOCTL_HGCM_CONNECT: can not get connection info\n"));
    294                 return -EFAULT;
    295         }
    296         rcVBox = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_CONNECT, &info);
    297         if (RT_FAILURE(rcVBox) || (RT_FAILURE(info.result))) {
    298                 LogRelFunc(("VBOXGUEST_IOCTL_HGCM_CONNECT: hgcm connection failed.  internal ioctl result %Rrc, hgcm result %Rrc\n", rcVBox, info.result));
    299                 rc = RT_FAILURE(rcVBox) ?   -RTErrConvertToErrno(rcVBox)
    300                                           : -RTErrConvertToErrno(info.result);
    301         } else {
    302                 /* Register that the connection is associated with this file pointer. */
    303                 LogRelFunc(("Connected, client ID %u\n", info.u32ClientID));
    304                 rc = vboxadd_register_hgcm_connection(info.u32ClientID, filp);
    305                 if (0 != rc) {
    306                         LogRelFunc(("VBOXGUEST_IOCTL_HGCM_CONNECT: failed to register the HGCM connection\n"));
    307                 } else {
    308                         if (copy_to_user ((void *)userspace_info, (void *)&info,
    309                                           sizeof(info))) {
    310                                 LogRelFunc (("VBOXGUEST_IOCTL_HGCM_CONNECT: failed to return the connection structure\n"));
    311                                 rc = -EFAULT;
    312                         } else {
    313                                 return 0;
    314                         }
    315                         /* Unregister again, as we didn't get as far as informing userspace. */
    316                         vboxadd_unregister_hgcm_connection_no_close(info.u32ClientID);
    317                 }
    318                 /* And disconnect the hgcm connection again, as we told userspace it failed. */
    319                 infoDisconnect.u32ClientID = info.u32ClientID;
    320                 vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT,
    321                                   &infoDisconnect);
     289        int rc = 0;
     290
     291        if (copy_from_user ((void *)&info, (void *)userspace_info,
     292                            sizeof (info)) != 0) {
     293            LogFunc (("VBOXGUEST_IOCTL_HGCM_CONNECT: can not get connection info\n"));
     294            rc = -EFAULT;
     295        }
     296        info.u32ClientID = 0;
     297        if (rc >= 0) {
     298            int vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_CONNECT,
     299                                       &info);
     300            rc = RT_FAILURE(vrc) ?   -RTErrConvertToErrno(vrc)
     301                                   : -RTErrConvertToErrno(info.result);
     302            if (rc < 0)
     303                LogFunc(("hgcm connection failed.  internal ioctl result %Rrc, hgcm result %Rrc\n",
     304                         vrc, info.result));
     305        }
     306        if (rc >= 0) {
     307            /* Register that the connection is associated with this file pointer. */
     308            LogFunc(("Connected, client ID %u\n", info.u32ClientID));
     309            rc = vboxadd_register_hgcm_connection(info.u32ClientID, filp);
     310            if (rc < 0)
     311                LogFunc(("failed to register the HGCM connection\n"));
     312        }
     313        if (   rc >= 0
     314            && copy_to_user ((void *)userspace_info, (void *)&info,
     315                             sizeof(info)) != 0) {
     316            LogFunc (("failed to return the connection structure\n"));
     317            rc = -EFAULT;
     318        }
     319        if (rc < 0)
     320            /* Unregister again, as we didn't get as far as informing userspace. */
     321            vboxadd_unregister_hgcm_connection_no_close(info.u32ClientID);
     322        if (rc < 0 && info.u32ClientID != 0) {
     323            /* Disconnect the hgcm connection again, as we told userspace it failed. */
     324            VBoxGuestHGCMDisconnectInfo infoDisconnect;
     325            infoDisconnect.u32ClientID = info.u32ClientID;
     326            vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT,
     327                             &infoDisconnect);
    322328        }
    323329        return rc;
     
    335341static int vboxadd_hgcm_disconnect(struct file *filp, unsigned long userspace_info)
    336342{
     343        int rc = 0, vrc = VINF_SUCCESS;
     344
    337345        VBoxGuestHGCMDisconnectInfo info;
    338         if (0 != copy_from_user ((void *)&info, (void *)userspace_info, sizeof (info))) {
    339                 LogRelFunc (("VBOXGUEST_IOCTL_HGCM_DISCONNECT: can not get info\n"));
    340                 return -EFAULT;
    341         }
    342         LogRelFunc(("client ID %u\n", info.u32ClientID));
    343         vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT, &info);
    344         if (copy_to_user ((void *)userspace_info, (void *)&info, sizeof(info))) {
     346        if (copy_from_user ((void *)&info, (void *)userspace_info,
     347                            sizeof (info)) != 0) {
     348            LogRelFunc (("VBOXGUEST_IOCTL_HGCM_DISCONNECT: can not get info\n"));
     349            rc = -EFAULT;
     350        }
     351        if (rc >= 0) {
     352            LogRelFunc(("client ID %u\n", info.u32ClientID));
     353            vrc = vboxadd_cmc_call(vboxDev, VBOXGUEST_IOCTL_HGCM_DISCONNECT,
     354                                   &info);
     355            rc = -RTErrConvertToErrno(vrc);
     356        }
     357        if (   rc >= 0
     358            && copy_to_user ((void *)userspace_info, (void *)&info,
     359                             sizeof(info)) != 0) {
    345360                LogRelFunc (("VBOXGUEST_IOCTL_HGCM_DISCONNECT: failed to return the connection structure\n"));
    346                 return -EFAULT;
    347         }
    348         return 0;
     361                rc = -EFAULT;
     362        }
     363        return rc;
     364}
     365
     366/**
     367 * IOCTL handler.  Make an HGCM call.
     368 *
     369 * @returns 0 on success, or a Linux kernel errno value
     370 * @param  userspace_info userspace pointer to the hgcm connection information
     371 *                        (VBoxGuestHGCMConnectInfo structure).  This will be
     372 *                        updated on success.
     373 * @param  u32Size        the size of the userspace structure
     374 */
     375static int vboxadd_hgcm_call(unsigned long userspace_info, uint32_t u32Size)
     376{
     377        VBoxGuestHGCMCallInfo *pInfo = NULL;
     378        int rc = 0;
     379       
     380        pInfo = kmalloc(u32Size, GFP_KERNEL);
     381        if (pInfo == NULL)
     382                rc = -ENOMEM;
     383        if (rc >= 0 &&
     384            0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) {
     385                LogRelFunc (("can not get info from user space\n"));
     386                rc = -EFAULT;
     387        }
     388        if (rc >= 0 &&
     389            sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter) != u32Size) {
     390                LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n",
     391                             sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter),
     392                             u32Size));
     393            rc = -EINVAL;
     394        }
     395        if (rc >= 0) {
     396                int vrc;
     397                LogRelFunc(("client ID %u\n", pInfo->u32ClientID));
     398                vrc = vboxadd_cmc_call(vboxDev,
     399                              VBOXGUEST_IOCTL_HGCM_CALL(u32Size), pInfo);
     400                rc = -RTErrConvertToErrno(vrc);
     401                if (   rc >= 0
     402                    && copy_to_user ((void *)userspace_info, (void *)pInfo,
     403                                     u32Size)) {
     404                        LogRelFunc (("failed to return the information to user space\n"));
     405                        rc = -EFAULT;
     406                }
     407        }
     408        if (pInfo != NULL)
     409            kfree(pInfo);
     410        return rc;
     411}
     412
     413/**
     414 * IOCTL handler.  Make an HGCM call with timeout.
     415 *
     416 * @returns 0 on success, or a Linux kernel errno value
     417 * @param  userspace_info userspace pointer to the hgcm connection information
     418 *                        (VBoxGuestHGCMConnectInfo structure).  This will be
     419 *                        updated on success.
     420 * @param  u32Size        the size of the userspace structure
     421 */
     422static int vboxadd_hgcm_call_timeout(unsigned long userspace_info,
     423                                     uint32_t u32Size)
     424{
     425        VBoxGuestHGCMCallInfoTimeout *pInfo = NULL;
     426        int rc = 0;
     427       
     428        pInfo = kmalloc(u32Size, GFP_KERNEL);
     429        if (pInfo == NULL)
     430                rc = -ENOMEM;
     431        if (rc >= 0 &&
     432            0 != copy_from_user ((void *)pInfo, (void *)userspace_info, u32Size)) {
     433                LogRelFunc (("can not get info from user space\n"));
     434                rc = -EFAULT;
     435        }
     436        if (rc >= 0 &&
     437            sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter) != u32Size) {
     438                LogRelFunc (("bad parameter size, structure says %d, ioctl says %d\n",
     439                             sizeof(*pInfo) + pInfo->info.cParms * sizeof(HGCMFunctionParameter),
     440                             u32Size));
     441            rc = -EINVAL;
     442        }
     443        if (rc >= 0) {
     444                int vrc;
     445                LogRelFunc(("client ID %u\n", pInfo->info.u32ClientID));
     446                vrc = vboxadd_cmc_call(vboxDev,
     447                              VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(u32Size), pInfo);
     448                rc = -RTErrConvertToErrno(vrc);
     449                if (   rc >= 0
     450                    && copy_to_user ((void *)userspace_info, (void *)pInfo,
     451                                     u32Size)) {
     452                        LogRelFunc (("failed to return the information to user space\n"));
     453                        rc = -EFAULT;
     454                }
     455        }
     456        if (pInfo != NULL)
     457            kfree(pInfo);
     458        return rc;
    349459}
    350460
     
    509619                 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd))
    510620        {
    511         /* This IOCTL allows the guest to make an HGCM call from user space.  The
    512            OS-independant part of the Guest Additions already contain code for making an
    513            HGCM call from the guest, but this code assumes that the call is made from the
    514            kernel's address space.  So before calling it, we have to copy all parameters
    515            to the HGCM call from user space to kernel space and reconstruct the structures
    516            passed to the call (which include pointers to other memory) inside the kernel's
    517            address space. */
     621        /* Do the HGCM call using the Vbgl bits */
    518622                IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL", arg);
    519                 rc = vbox_ioctl_hgcm_call(arg, vboxDev);
     623                rc = vboxadd_hgcm_call(arg, _IOC_SIZE(cmd));
    520624                IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL", arg);
     625        }
     626        else if (   VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(0))
     627                 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd))
     628        {
     629        /* Do the HGCM call using the Vbgl bits */
     630                IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT", arg);
     631                rc = vboxadd_hgcm_call_timeout(arg, _IOC_SIZE(cmd));
     632                IOCTL_EXIT("VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT", arg);
    521633        }
    522634        else
  • trunk/src/VBox/Additions/linux/module/vboxmod.h

    r12280 r14218  
    7777DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
    7878
     79#if 0
    7980/**
    8081 * This IOCTL wrapper allows the guest to make an HGCM call from user space.  The
     
    9192extern int vbox_ioctl_hgcm_call(unsigned long arg, VBoxDevice *vboxDev);
    9293
     94/**
     95 * This call is similar to vbox_ioctl_hgcm_call, but for the _TIMEOUT variant
     96 * of the ioctl.
     97 *
     98 * @returns   0 on success or Linux error code on failure
     99 * @param arg      User space pointer to the call data structure
     100 */
     101extern int vbox_ioctl_hgcm_call_timeout(unsigned long arg, VBoxDevice *vboxDev);
     102#endif
     103
    93104#endif /* !VBOXMOD_H */
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