Changeset 14218 in vbox for trunk/src/VBox/Additions/linux/module
- Timestamp:
- Nov 14, 2008 2:53:05 PM (16 years ago)
- 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 58 58 vboxadd_SOURCES = \ 59 59 vboxmod.c \ 60 cmc.c \ 61 hgcmcall.c 60 cmc.c 62 61 vboxadd_LIBS = \ 63 62 $(VBOX_LIB_VBGL_R0BASE) \ -
trunk/src/VBox/Additions/linux/module/Makefile.module
r13773 r14218 61 61 OBJS = \ 62 62 cmc.o \ 63 hgcmcall.o \64 63 vboxmod.o \ 65 64 GenericRequest.o \ … … 70 69 VMMDev.o \ 71 70 r0drv/alloc-r0drv.o \ 71 r0drv/memobj-r0drv.o \ 72 72 r0drv/linux/alloc-r0drv-linux.o \ 73 73 r0drv/linux/assert-r0drv-linux.o \ 74 r0drv/linux/memobj-r0drv-linux.o \ 75 r0drv/linux/process-r0drv-linux.o \ 74 76 r0drv/linux/semevent-r0drv-linux.o \ 75 77 r0drv/linux/semfastmutex-r0drv-linux.o \ -
trunk/src/VBox/Additions/linux/module/cmc.c
r13835 r14218 40 40 } 41 41 42 static DECLVBGL(void) 43 vboxadd_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 42 50 DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data) 43 51 { 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) 45 68 { 46 69 /* this function can NOT handle cancelled requests */ 47 70 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; 49 73 50 74 /* this function can NOT handle cancelled requests */ 51 75 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; 53 78 54 /* this function can handle cancelled requests */55 79 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; 61 81 } 82 return rc; 62 83 } 63 84 -
trunk/src/VBox/Additions/linux/module/files_vboxadd
r14015 r14218 30 30 ${PATH_ROOT}/include/iprt/log.h=>include/iprt/log.h \ 31 31 ${PATH_ROOT}/include/iprt/mem.h=>include/iprt/mem.h \ 32 ${PATH_ROOT}/include/iprt/memobj.h=>include/iprt/memobj.h \ 32 33 ${PATH_ROOT}/include/iprt/param.h=>include/iprt/param.h \ 34 ${PATH_ROOT}/include/iprt/process.h=>include/iprt/process.h \ 33 35 ${PATH_ROOT}/include/iprt/semaphore.h=>include/iprt/semaphore.h \ 34 36 ${PATH_ROOT}/include/iprt/spinlock.h=>include/iprt/spinlock.h \ … … 56 58 ${PATH_ROOT}/src/VBox/Additions/common/VBoxGuestLib/VMMDev.cpp=>VMMDev.c \ 57 59 ${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 \ 58 61 ${PATH_ROOT}/src/VBox/Runtime/include/internal/string.h=>include/internal/string.h \ 59 62 ${PATH_ROOT}/src/VBox/Runtime/common/alloc/heapsimple.cpp=>alloc/heapsimple.c \ … … 73 76 ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \ 74 77 ${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 \ 75 79 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c=>r0drv/linux/alloc-r0drv-linux.c \ 76 80 ${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 \ 77 83 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c=>r0drv/linux/semevent-r0drv-linux.c \ 78 84 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c=>r0drv/linux/semeventmulti-r0drv-linux.c \ … … 85 91 ${PATH_ROOT}/src/VBox/Additions/linux/module/vboxmod.c=>vboxmod.c \ 86 92 ${PATH_ROOT}/src/VBox/Additions/linux/module/cmc.c=>cmc.c \ 87 ${PATH_ROOT}/src/VBox/Additions/linux/module/hgcmcall.c=>hgcmcall.c \88 93 ${PATH_ROOT}/src/VBox/Additions/linux/module/vboxmod.h=>vboxmod.h \ 89 94 ${PATH_ROOT}/src/VBox/Additions/linux/module/waitcompat.h=>waitcompat.h \ -
trunk/src/VBox/Additions/linux/module/vboxmod.c
r13837 r14218 287 287 { 288 288 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); 322 328 } 323 329 return rc; … … 335 341 static int vboxadd_hgcm_disconnect(struct file *filp, unsigned long userspace_info) 336 342 { 343 int rc = 0, vrc = VINF_SUCCESS; 344 337 345 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) { 345 360 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 */ 375 static 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 */ 422 static 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; 349 459 } 350 460 … … 509 619 == VBOXGUEST_IOCTL_STRIP_SIZE(cmd)) 510 620 { 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 */ 518 622 IOCTL_ENTRY("VBOXGUEST_IOCTL_HGCM_CALL", arg); 519 rc = vbox _ioctl_hgcm_call(arg, vboxDev);623 rc = vboxadd_hgcm_call(arg, _IOC_SIZE(cmd)); 520 624 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); 521 633 } 522 634 else -
trunk/src/VBox/Additions/linux/module/vboxmod.h
r12280 r14218 77 77 DECLVBGL (int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data); 78 78 79 #if 0 79 80 /** 80 81 * This IOCTL wrapper allows the guest to make an HGCM call from user space. The … … 91 92 extern int vbox_ioctl_hgcm_call(unsigned long arg, VBoxDevice *vboxDev); 92 93 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 */ 101 extern int vbox_ioctl_hgcm_call_timeout(unsigned long arg, VBoxDevice *vboxDev); 102 #endif 103 93 104 #endif /* !VBOXMOD_H */
Note:
See TracChangeset
for help on using the changeset viewer.