Changeset 75547 in vbox
- Timestamp:
- Nov 18, 2018 4:50:34 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxGuest.h
r72627 r75547 52 52 * 53 53 * - I/O controls for user and/or kernel mode starts at 0. 54 * - IDC specific requests descends from 127.54 * - IDC specific requests descends from 63. 55 55 * - Bits 7 and 6 are currently reserved for future hacks. 56 56 * … … 285 285 /** @} */ 286 286 287 288 287 #ifdef VBOX_WITH_HGCM 288 289 289 /** @name VBGL_IOCTL_HGCM_CONNECT 290 290 * Connect to a HGCM service. … … 344 344 /** @name VBGL_IOCTL_HGCM_CALL, VBGL_IOCTL_HGCM_CALL_WITH_USER_DATA 345 345 * 346 * Make a call to a HGCM service sure. There are several variations here.346 * Make a call to a HGCM service. There are several variations here. 347 347 * 348 348 * The VBGL_IOCTL_HGCM_CALL_WITH_USER_DATA variation is for other drivers (like … … 360 360 # define VBGL_IOCTL_HGCM_CALL_WITH_USER_DATA(a_cb) VBGL_IOCTL_CODE_SIZE(8, (a_cb)) 361 361 /** @} */ 362 363 364 /** @name VBGL_IOCTL_IDC_HGCM_FAST_CALL 365 * 366 * Variant of VBGL_IOCTL_HGCM_CALL for drivers that submits the request as-is to 367 * the host and handles the waiting, the caller does all the rest. 368 * 369 * @note ring-0 only. 370 * @note Size is not encoded in the I/O control code. 371 * @{ 372 */ 373 #define VBGL_IOCTL_IDC_HGCM_FAST_CALL VBGL_IOCTL_CODE_SIZE(62, sizeof(VBGLIOCIDCHGCMFASTCALL)) 374 #define VBGL_IOCTL_IDC_HGCM_FAST_CALL_SIZE(a_cb) (a_cb) 375 #define VBGL_IOCTL_IDC_HGCM_FAST_CALL_SIZE_IN(a_cb) (a_cb) 376 #define VBGL_IOCTL_IDC_HGCM_FAST_CALL_SIZE_OUT(a_cb) (a_cb) 377 #pragma pack(4) /* Want it to fit nicely with the 44 byte VMMDevHGCMCall and optimally align 64-bit parameters structures. */ 378 typedef struct VBGLIOCIDCHGCMFASTCALL 379 { 380 /** The header. */ 381 VBGLREQHDR Hdr; 382 /** The physical address of the following VMMDevHGCMCall structure. */ 383 RTGCPHYS32 GCPhysReq; 384 /** Set if interruptible. */ 385 bool fInterruptible; 386 /** Reserved. */ 387 uint8_t abReserved0[3]; 388 uint64_t uTimestamp[2]; 389 uint8_t abReserved1[4]; 390 /* After this structure follows a VMMDevHGCMCall strcuture (44 bytes), then 391 zero or more HGCMFunctionParameter structures (12 or 16 bytes), and finally 392 page lists and embedded buffers. */ 393 } VBGLIOCIDCHGCMFASTCALL, RT_FAR *PVBGLIOCIDCHGCMFASTCALL; 394 #pragma pack() 395 AssertCompileSize(VBGLIOCIDCHGCMFASTCALL, /* 24 + 4 + 1 + 3 + 2*8 + 4 = 0x34 (52) = */ 0x34); 396 397 /** 398 * Macro for initializing VBGLIOCIDCHGCMFASTCALL and the following 399 * VMMDevHGCMCall structures. 400 * 401 * @param a_pHdr The request header to initialize. 402 * @param a_HdrPhys The 32-bit physical address corresponding to @a a_pHdr. 403 * @param a_pCall Pointer to the VMMDevHGCMCall structure. 404 * @param a_idClient The HGCM client ID. 405 * @param a_uFunction The HGCM function number. 406 * @param a_cParms The number of parameters following @a a_pCall. 407 * @param a_cbReq The size of the whole request. 408 */ 409 #define VBGLIOCIDCHGCMFASTCALL_INIT(a_pHdr, a_HdrPhys, a_pCall, a_idClient, a_uFunction, a_cParms, a_cbReq) \ 410 do { \ 411 Assert((uintptr_t)(a_pHdr) + sizeof(VBGLIOCIDCHGCMFASTCALL) == (uintptr_t)(a_pCall)); \ 412 VBGLREQHDR_INIT_EX(&(a_pHdr)->Hdr, a_cbReq, a_cbReq); \ 413 pReq->Hdr.GCPhysReq = (a_HdrPhys) + sizeof(VBGLIOCIDCHGCMFASTCALL); \ 414 pReq->Hdr.fInterruptible = false; \ 415 \ 416 (a_pCall)->header.header.size = (a_cbReq) - sizeof(VBGLIOCIDCHGCMFASTCALL); \ 417 (a_pCall)->header.header.version = VBGLREQHDR_VERSION; \ 418 (a_pCall)->header.header.requestType= (ARCH_BITS == 32 ? VMMDevReq_HGCMCall32 : VMMDevReq_HGCMCall64); \ 419 (a_pCall)->header.header.rc = VERR_INTERNAL_ERROR; \ 420 (a_pCall)->header.header.reserved1 = 0; \ 421 (a_pCall)->header.header.fRequestor = VMMDEV_REQUESTOR_KERNEL | VMMDEV_REQUESTOR_USR_DRV_OTHER \ 422 | VMMDEV_REQUESTOR_CON_DONT_KNOW | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN; \ 423 (a_pCall)->header.fu32Flags = 0; \ 424 (a_pCall)->header.result = VERR_INTERNAL_ERROR; \ 425 (a_pCall)->u32ClientID = (a_idClient); \ 426 (a_pCall)->u32Function = (a_uFunction); \ 427 (a_pCall)->cParms = (a_cParms); \ 428 } while (0) 429 430 431 /** @} */ 432 362 433 #endif /* VBOX_WITH_HGCM */ 363 434 … … 798 869 * 799 870 * @note ring-0 only. 871 * @{ 800 872 */ 801 873 #define VBGL_IOCTL_IDC_CONNECT VBGL_IOCTL_CODE_SIZE(63, VBGL_IOCTL_IDC_CONNECT_SIZE) … … 859 931 * 860 932 * @note ring-0 only. 933 * @{ 861 934 */ 862 935 #define VBGL_IOCTL_IDC_DISCONNECT VBGL_IOCTL_CODE_SIZE(62, VBGL_IOCTL_IDC_DISCONNECT_SIZE) -
trunk/include/VBox/VBoxGuestLib.h
r75407 r75547 212 212 # ifdef VBOX_WITH_HGCM 213 213 struct VBGLIOCHGCMCALL; 214 struct VBGLIOCIDCHGCMFASTCALL; 214 215 215 216 # ifdef VBGL_VBOXGUEST … … 325 326 # else /* !VBGL_VBOXGUEST */ 326 327 328 #ifndef VBGL_VBOXGUEST 329 /** @internal */ 330 typedef struct VBGLHGCMHANDLEDATA 331 { 332 uint32_t fAllocated; 333 VBGLIDCHANDLE IdcHandle; 334 } VBGLHGCMHANDLEDATA; 335 #else 327 336 struct VBGLHGCMHANDLEDATA; 337 #endif 338 328 339 typedef struct VBGLHGCMHANDLEDATA *VBGLHGCMHANDLE; 329 340 … … 382 393 * @return VBox status code. 383 394 */ 384 DECLR0VBGL(int) VbglR0HGCMCallRaw(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL *pData, uint32_t cbData);395 DECLR0VBGL(int) VbglR0HGCMCallRaw(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL *pData, uint32_t cbData); 385 396 386 397 /** … … 394 405 * or the HGCM status code (pData->Hdr.rc). 395 406 */ 396 DECLR0VBGL(int) VbglR0HGCMCall(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL *pData, uint32_t cbData);407 DECLR0VBGL(int) VbglR0HGCMCall(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL *pData, uint32_t cbData); 397 408 398 409 /** … … 406 417 * @return VBox status code. 407 418 */ 408 DECLR0VBGL(int) VbglR0HGCMCallUserDataRaw(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL*pData, uint32_t cbData); 419 DECLR0VBGL(int) VbglR0HGCMCallUserDataRaw(VBGLHGCMHANDLE handle, struct VBGLIOCHGCMCALL *pData, uint32_t cbData); 420 421 /** 422 * Call to a service, w/o any repacking and buffer locking in VBoxGuest, 423 * returning the only request related status code (not HGCM). 424 * 425 * The driver only submits the request and waits for completion, nothing else. 426 * 427 * @param hHandle The connection handle. 428 * @param pCallReq The call request. Will be passed directly to the host. 429 * @param cbCallReq The size of the whole call request. 430 * 431 * @return VBox status code. 432 * 433 * @remarks The result of the HGCM call is found in 434 * @a pCallReq->HgcmCallReq.header.result on a successful return. The 435 * @a pCallReq->Hdr.rc and @a pCallReq->HgcmCallReq.header.header.rc 436 * fields are the same as the return value and can safely be ignored. 437 */ 438 DECLR0VBGL(int) VbglR0HGCMFastCall(VBGLHGCMHANDLE hHandle, struct VBGLIOCIDCHGCMFASTCALL *pCallReq, uint32_t cbCallReq); 409 439 410 440 /** @} */ -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r73097 r75547 2729 2729 * Some more validations. 2730 2730 */ 2731 if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */ 2731 if (RT_LIKELY(pInfo->cParms <= VMMDEV_MAX_HGCM_PARMS)) /* (Just make sure it doesn't overflow the next check.) */ 2732 { /* likely */} 2733 else 2732 2734 { 2733 2735 LogRel(("VBOXGUEST_IOCTL_HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms)); … … 2742 2744 #endif 2743 2745 cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter); 2744 if (cbData < cbActual) 2746 if (RT_LIKELY(cbData >= cbActual)) 2747 { /* likely */} 2748 else 2745 2749 { 2746 2750 LogRel(("VBOXGUEST_IOCTL_HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n", … … 2758 2762 break; 2759 2763 RTSpinlockRelease(pDevExt->SessionSpinlock); 2760 if (RT_UNLIKELY(i >= RT_ELEMENTS(pSession->aHGCMClientIds))) 2764 if (RT_LIKELY(i < RT_ELEMENTS(pSession->aHGCMClientIds))) 2765 { /* likely */} 2766 else 2761 2767 { 2762 2768 LogRelMax(32, ("VBOXGUEST_IOCTL_HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId)); … … 2818 2824 } 2819 2825 2826 2827 /** 2828 * Handles a fast HGCM call from another driver. 2829 * 2830 * The driver has provided a fully assembled HGCM call request and all we need 2831 * to do is send it to the host and do the wait processing. 2832 * 2833 * @returns VBox status code of the request submission part. 2834 * @param pDevExt The device extension. 2835 * @param pCallReq The call request. 2836 */ 2837 static int vgdrvIoCtl_HGCMFastCall(PVBOXGUESTDEVEXT pDevExt, VBGLIOCIDCHGCMFASTCALL volatile *pCallReq) 2838 { 2839 VMMDevHGCMCall volatile *pHgcmCall = (VMMDevHGCMCall volatile *)(pCallReq + 1); 2840 int rc; 2841 2842 /* 2843 * Check out the physical address. 2844 */ 2845 Assert((pCallReq->GCPhysReq & PAGE_OFFSET_MASK) == ((uintptr_t)pHgcmCall & PAGE_OFFSET_MASK)); 2846 2847 AssertReturn(!pCallReq->fInterruptible, VERR_NOT_IMPLEMENTED); 2848 2849 /* 2850 * Submit the request. 2851 */ 2852 Log(("vgdrvIoCtl_HGCMFastCall -> host\n")); 2853 ASMOutU32(pDevExt->IOPortBase + VMMDEV_PORT_OFF_REQUEST, (uint32_t)pCallReq->GCPhysReq); 2854 2855 /* Make the compiler aware that the host has changed memory. */ 2856 ASMCompilerBarrier(); 2857 2858 pCallReq->Hdr.rc = rc = pHgcmCall->header.header.rc; 2859 Log(("vgdrvIoCtl_HGCMFastCall -> %Rrc (header rc=%Rrc)\n", rc, pHgcmCall->header.result)); 2860 2861 /* 2862 * The host is likely to engage in asynchronous execution of HGCM, unless it fails. 2863 */ 2864 if (rc == VINF_HGCM_ASYNC_EXECUTE) 2865 { 2866 rc = vgdrvHgcmAsyncWaitCallbackWorker(&pHgcmCall->header, pDevExt, false /* fInterruptible */, RT_INDEFINITE_WAIT); 2867 if (pHgcmCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 2868 { 2869 Assert(!(pHgcmCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED)); 2870 rc = VINF_SUCCESS; 2871 } 2872 else 2873 { 2874 /* 2875 * Timeout and interrupt scenarios are messy and requires 2876 * cancelation, so implement later. 2877 */ 2878 AssertReleaseMsgFailed(("rc=%Rrc\n", rc)); 2879 } 2880 } 2881 else 2882 Assert((pHgcmCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) || RT_FAILURE_NP(rc)); 2883 2884 Log(("vgdrvIoCtl_HGCMFastCall: rc=%Rrc result=%Rrc fu32Flags=%#x\n", rc, pHgcmCall->header.result, pHgcmCall->header.fu32Flags)); 2885 return rc; 2886 2887 } 2820 2888 2821 2889 #endif /* VBOX_WITH_HGCM */ … … 4060 4128 } 4061 4129 #ifdef VBOX_WITH_HGCM 4130 else if (iFunction == VBGL_IOCTL_IDC_HGCM_FAST_CALL) /* (is variable size, but we don't bother encoding it) */ 4131 { 4132 REQ_CHECK_RING0("VBGL_IOCTL_IDC_HGCM_FAST_CALL"); 4133 REQ_CHECK_EXPR(VBGL_IOCTL_IDC_HGCM_FAST_CALL, cbReq >= sizeof(VBGLIOCIDCHGCMFASTCALL) + sizeof(VMMDevHGCMCall)); 4134 vgdrvIoCtl_HGCMFastCall(pDevExt, (VBGLIOCIDCHGCMFASTCALL volatile *)pReqHdr); 4135 } 4062 4136 else if ( iFunctionStripped == VBGL_IOCTL_CODE_STRIPPED(VBGL_IOCTL_HGCM_CALL(0)) 4063 4137 # if ARCH_BITS == 64 -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibHGCM.cpp
r72627 r75547 231 231 } 232 232 233 234 DECLR0VBGL(int) VbglR0HGCMFastCall(VBGLHGCMHANDLE hHandle, PVBGLIOCIDCHGCMFASTCALL pCallReq, uint32_t cbCallReq) 235 { 236 /* pCallReq->Hdr.rc and pCallReq->HgcmCallReq.header.header.rc; are not used by this IDC. */ 237 return VbglR0IdcCallRaw(&hHandle->IdcHandle, VBGL_IOCTL_IDC_HGCM_FAST_CALL, &pCallReq->Hdr, cbCallReq); 238 } 239 -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibInternal.h
r72627 r75547 107 107 typedef struct _VBGLPHYSHEAPCHUNK VBGLPHYSHEAPCHUNK; 108 108 109 #ifndef VBGL_VBOXGUEST110 struct VBGLHGCMHANDLEDATA111 {112 uint32_t fAllocated;113 VBGLIDCHANDLE IdcHandle;114 };115 #endif116 117 109 enum VbglLibStatus 118 110 {
Note:
See TracChangeset
for help on using the changeset viewer.