VirtualBox

Ignore:
Timestamp:
Apr 16, 2007 1:20:11 PM (18 years ago)
Author:
vboxsync
Message:

Rewrote the hgcm code in the additions kernel module for improved readibility

Location:
trunk/src/VBox/Additions/linux/module
Files:
3 edited

Legend:

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

    r1825 r2100  
    7373        vboxmod.c=>vboxmod.c \
    7474        cmc.c=>cmc.c \
     75        hgcmcall.c=>hgcmcall.c \
    7576        vboxmod.h=>vboxmod.h \
    7677        waitcompat.h=>waitcompat.h \
     
    8889vboxadd_DEFS     = KBUILD_MODNAME=KBUILD_STR\(vboxadd\) KBUILD_BASENAME=KBUILD_STR\(vboxadd\) MODULE IN_RING0 IN_RT_R0 VBGL_VBOXGUEST EXPORT_SYMTAB VBGL_HGCM VBOX_HGCM
    8990vboxadd_LIBS     = $(PATH_LIB)/RuntimeLnx32GuestR0.a
    90 vboxadd_SOURCES  = vboxmod.c cmc.c
     91vboxadd_SOURCES  = vboxmod.c cmc.c hgcmcall.c
    9192vboxadd_INCS     = $(PATH_ROOT)/src/VBox/Runtime/r0drv/linux
    9293vboxadd_NOINST   = 1
  • trunk/src/VBox/Additions/linux/module/vboxmod.c

    r1667 r2100  
    2727#include "vboxmod.h"
    2828#include "waitcompat.h"
     29#include <VBox/log.h>
    2930
    3031#define VERSION "0.5"
     
    4142                        const char *pszFile, const char *pszFunction)
    4243{
    43     elog ("!!Assertion Failed!!\n"
    44           "Expression: %s\n"
    45           "Location  : %s(%d) %s\n",
    46           pszExpr, pszFile, uLine, pszFunction);
     44    elog("!!Assertion Failed!!\n"
     45         "Expression: %s\n"
     46         "Location  : %s(%d) %s\n",
     47         pszExpr, pszFile, uLine, pszFunction);
     48    Log(("!!Assertion Failed!!\n"
     49         "Expression: %s\n"
     50         "Location  : %s(%d) %s\n",
     51         pszExpr, pszFile, uLine, pszFunction));
    4752}
    4853
     
    5661    vsnprintf(msg, sizeof(msg) - 1, pszFormat, ap);
    5762    msg[sizeof(msg) - 1] = '\0';
    58     ilog ("%s", msg);
     63    elog("%s", msg);
     64    Log(("%s", msg));
    5965    va_end(ap);
    6066}
    6167
     68#if 0  /* We now have real backdoor logging */
    6269/* Backdoor logging function, needed by the runtime */
    6370RTDECL(size_t) RTLogBackdoorPrintf (const char *pszFormat, ...)
     
    7481    return n;
    7582}
     83#endif
    7684
    7785/** device extension structure (we only support one device instance) */
     
    252260        case IOCTL_VBOXGUEST_HGCM_CALL:
    253261        {
    254             VBoxGuestHGCMCallInfo callHeader, *hgcmR3, *hgcmR0;
    255             uint8_t *pu8PointerData;
    256             size_t cbPointerData = 0, offPointerData = 0;
    257             int i, rc;
    258 
    259             compiler_assert(_IOC_SIZE(IOCTL_VBOXGUEST_HGCM_CALL) == sizeof(VBoxGuestHGCMCallInfo));
    260             if (copy_from_user(&callHeader, (void*)arg, _IOC_SIZE(cmd)))
    261             {
    262                 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n");
    263                 return -EFAULT;
    264             }
    265             hgcmR3 = kmalloc(sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter),
    266                                GFP_KERNEL);
    267             if (!hgcmR3)
    268             {
    269                 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n");
    270                 return -ENOMEM;
    271             }
    272             if (copy_from_user(hgcmR3, (void*)arg,
    273                                sizeof(*hgcmR3) +   callHeader.cParms
    274                                                  * sizeof(HGCMFunctionParameter)))
    275             {
    276                 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n");
    277                 kfree(hgcmR3);
    278                 return -EFAULT;
    279             }
    280             hgcmR0 = kmalloc(sizeof(*hgcmR0) + callHeader.cParms * sizeof(HGCMFunctionParameter),
    281                                GFP_KERNEL);
    282             if (!hgcmR0)
    283             {
    284                 elog("IOCTL_VBOXGUEST_HGCM_CALL: cannot allocate memory!\n");
    285                 kfree(hgcmR3);
    286                 return -ENOMEM;
    287             }
    288             hgcmR0->u32ClientID = callHeader.u32ClientID;
    289             hgcmR0->u32Function = callHeader.u32Function;
    290             hgcmR0->cParms = callHeader.cParms;
    291             /* Calculate the total size of pointer space.  Will normally be for a single pointer */
    292             for (i = 0; i < callHeader.cParms; ++i)
    293             {
    294                 switch (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type)
    295                 {
    296                 case VMMDevHGCMParmType_32bit:
    297                 case VMMDevHGCMParmType_64bit:
    298                     break;
    299                 case VMMDevHGCMParmType_LinAddr:
    300                 case VMMDevHGCMParmType_LinAddr_In:
    301                 case VMMDevHGCMParmType_LinAddr_Out:
    302                     cbPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size;
    303                     break;
    304                 default:
    305                     elog("IOCTL_VBOXGUEST_HGCM_CALL: unsupported or unknown parameter type\n");
    306                     kfree(hgcmR3);
    307                     kfree(hgcmR0);
    308                     return -EINVAL;
    309                 }
    310             }
    311             pu8PointerData = kmalloc (cbPointerData, GFP_KERNEL);
    312             /* Reconstruct the pointer parameter data in kernel space */
    313             if (pu8PointerData == NULL)
    314             {
    315                 elog("IOCTL_VBOXGUEST_HGCM_CALL: out of memory allocating %d bytes for pointer data\n",
    316                        cbPointerData);
    317                 kfree(hgcmR3);
    318                 kfree(hgcmR0);
    319                 return -ENOMEM;
    320             }
    321             for (i = 0; i < callHeader.cParms; ++i)
    322             {
    323                 VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].type
    324                     = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type;
    325                 if (   (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr)
    326                     || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type
    327                             == VMMDevHGCMParmType_LinAddr_In))
    328                 {
    329                     /* We are sending data to the host or sending and reading. */
    330                     void *pvR3LinAddr
    331                         = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr;
    332                     if (copy_from_user(&pu8PointerData[offPointerData],
    333                                        pvR3LinAddr,
    334                                        VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size))
    335                     {
    336                         elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_from_user failed!\n");
    337                         rc = -EFAULT;
    338                         goto hgcm_exit;
    339                     }
    340                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr
    341                         = (vmmDevHypPtr)&pu8PointerData[offPointerData];
    342                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size
    343                         = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size;
    344                     offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size;
    345                 }
    346                 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type
    347                              == VMMDevHGCMParmType_LinAddr_Out)
    348                 {
    349                     /* We are reading data from the host */
    350                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr
    351                         = (vmmDevHypPtr)&pu8PointerData[offPointerData];
    352                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size
    353                         = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size;
    354                     offPointerData += VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size;
    355                 }
    356                 else
    357                 {
    358                     /* If it is not a pointer, then it is a 32bit or 64bit value */
    359                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64
    360                         = VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64;
    361                 }
    362             }
    363             /* Internal VBoxGuest IOCTL interface */
    364             rc = vboxadd_cmc_call(vboxDev, IOCTL_VBOXGUEST_HGCM_CALL, hgcmR0);
    365             if (rc != VINF_SUCCESS)
    366             {
    367                 elog("IOCTL_VBOXGUEST_HGCM_CALL: internal ioctl call failed, rc=%d\n", rc);
    368                 /** @todo We need a function to convert VBox error codes back to Linux. */
    369                 rc = -EINVAL;
    370                 goto hgcm_exit;
    371             }
    372             for (i = 0; i < callHeader.cParms; ++i)
    373             {
    374                 if (   (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type == VMMDevHGCMParmType_LinAddr)
    375                     || (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type
    376                             == VMMDevHGCMParmType_LinAddr_Out))
    377                 {
    378                     /* We are sending data to the host or sending and reading. */
    379                     void *pvR3LinAddr
    380                         = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.u.linearAddr;
    381                     void *pvR0LinAddr
    382                         = (void *)VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.u.linearAddr;
    383                     if (copy_to_user(pvR3LinAddr, pvR0LinAddr,
    384                                      VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size))
    385                     {
    386                         elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n");
    387                         rc = -EFAULT;
    388                         goto hgcm_exit;
    389                     }
    390                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.Pointer.size
    391                         = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.Pointer.size;
    392                 }
    393                 else if (VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].type
    394                              != VMMDevHGCMParmType_LinAddr_Out)
    395                 {
    396                     /* If it is not a pointer, then it is a 32bit or 64bit value */
    397                     VBOXGUEST_HGCM_CALL_PARMS(hgcmR3)[i].u.value64
    398                         = VBOXGUEST_HGCM_CALL_PARMS(hgcmR0)[i].u.value64;
    399                 }
    400             }
    401             hgcmR3->result = hgcmR0->result;
    402             if (copy_to_user((void*)arg, hgcmR3,
    403                              sizeof(*hgcmR3) + callHeader.cParms * sizeof(HGCMFunctionParameter)))
    404             {
    405                 elog("IOCTL_VBOXGUEST_HGCM_CALL: copy_to_user failed!\n");
    406                 rc = -EFAULT;
    407                 goto hgcm_exit;
    408             }
    409         hgcm_exit:
    410             kfree(hgcmR3);
    411             kfree(hgcmR0);
    412             kfree(pu8PointerData);
    413             return rc;
     262            /* This IOCTL allows the guest to make an HGCM call from user space.  The
     263               OS-independant part of the Guest Additions already contain code for making an
     264               HGCM call from the guest, but this code assumes that the call is made from the
     265               kernel's address space.  So before calling it, we have to copy all parameters
     266               to the HGCM call from user space to kernel space and reconstruct the structures
     267               passed to the call (which include pointers to other memory) inside the kernel's
     268               address space. */
     269            return vbox_ioctl_hgcm_call(arg, vboxDev);
    414270        }
    415271
    416272        default:
    417273        {
    418             printk(KERN_ERR "vboxadd_ioctl: unknown command: %x\n", cmd);
     274            elog("vboxadd_ioctl: unknown command: %x, IOCTL_VBOXGUEST_HGCM_CALL is %x\n", cmd,
     275                 IOCTL_VBOXGUEST_HGCM_CALL);
     276            Log(("vboxadd_ioctl: unknown command: %x, IOCTL_VBOXGUEST_HGCM_CALL is %x\n", cmd,
     277                 IOCTL_VBOXGUEST_HGCM_CALL));
    419278            return -EINVAL;
    420279        }
  • trunk/src/VBox/Additions/linux/module/vboxmod.h

    r1621 r2100  
    8181DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
    8282
     83/**
     84 * This IOCTL wrapper allows the guest to make an HGCM call from user space.  The
     85 * OS-independant part of the Guest Additions already contain code for making an
     86 * HGCM call from the guest, but this code assumes that the call is made from the
     87 * kernel's address space.  So before calling it, we have to copy all parameters
     88 * to the HGCM call from user space to kernel space and reconstruct the structures
     89 * passed to the call (which include pointers to other memory) inside the kernel's
     90 * address space.
     91 *
     92 * @returns   0 on success or Linux error code on failure
     93 * @param arg User space pointer to the call data structure
     94 */
     95extern int vbox_ioctl_hgcm_call(unsigned long arg, VBoxDevice *vboxDev);
     96
    8397#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