Changeset 21506 in vbox
- Timestamp:
- Jul 10, 2009 11:54:26 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 49956
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxGuestLib.h
r21461 r21506 166 166 * completion IRQ is required. 167 167 * 168 * @param pvData VBoxGuest pointer to be passed to callback. 169 * @param u32Data VBoxGuest 32 bit value to be passed to callback. 170 */ 171 172 typedef DECLVBGL(void) VBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); 168 * @returns VINF_SUCCESS, VERR_INTERRUPT or VERR_TIMEOUT. 169 * @param pvData VBoxGuest pointer to be passed to callback. 170 * @param u32Data VBoxGuest 32 bit value to be passed to callback. 171 */ 172 typedef DECLVBGL(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data); 173 /** Pointer to a FNVBGLHGCMCALLBACK. */ 174 typedef FNVBGLHGCMCALLBACK *PFNVBGLHGCMCALLBACK; 173 175 174 176 /** … … 178 180 * @note This function can NOT handle cancelled requests! 179 181 * 180 * @param pConnectInfoThe request data.181 * @param pAsyncCallback Required pointer to function that is calledwhen182 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest183 * implements waiting for an IRQ in this function.184 * @param pvAsyncDataAn arbitrary VBoxGuest pointer to be passed to callback.185 * @param u32AsyncDataAn arbitrary VBoxGuest 32 bit value to be passed to callback.186 * 187 * @return VBox status code.182 * @param pConnectInfo The request data. 183 * @param pfnAsyncCallback Required pointer to function that is calledwhen 184 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 185 * implements waiting for an IRQ in this function. 186 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 187 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback. 188 * 189 * @return VBox status code. 188 190 */ 189 191 190 192 DECLR0VBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo, 191 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);193 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 192 194 193 195 … … 198 200 * @note This function can NOT handle cancelled requests! 199 201 * 200 * @param pDisconnectInfo The request data. 201 * @param pAsyncCallback Required pointer to function that is called when 202 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 203 * implements waiting for an IRQ in this function. 204 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 205 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback. 206 * 207 * @return VBox status code. 202 * @param pDisconnectInfo The request data. 203 * @param pfnAsyncCallback Required pointer to function that is called when 204 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 205 * implements waiting for an IRQ in this function. 206 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 207 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to 208 * callback. 209 * 210 * @return VBox status code. 208 211 */ 209 212 210 213 DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo, 211 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);214 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 212 215 213 216 /** Call a HGCM service. … … 215 218 * @note This function can deal with cancelled requests. 216 219 * 217 * @param pCallInfoThe request data.218 * @param fFlagsFlags, see VBGLR0_HGCMCALL_F_XXX.219 * @param pAsyncCallbackRequired pointer to function that is called when220 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest221 * implements waiting for an IRQ in this function.222 * @param pvAsyncDataAn arbitrary VBoxGuest pointer to be passed to callback.223 * @param u32AsyncDataAn arbitrary VBoxGuest 32 bit value to be passed to callback.220 * @param pCallInfo The request data. 221 * @param fFlags Flags, see VBGLR0_HGCMCALL_F_XXX. 222 * @param pfnAsyncCallback Required pointer to function that is called when 223 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 224 * implements waiting for an IRQ in this function. 225 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 226 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback. 224 227 * 225 228 * @return VBox status code. 226 229 */ 227 230 DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags, 228 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);231 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 229 232 230 233 /** Call a HGCM service. (32 bits packet structure in a 64 bits guest) … … 232 235 * @note This function can deal with cancelled requests. 233 236 * 234 * @param pCallInfoThe request data.235 * @param fFlagsFlags, see VBGLR0_HGCMCALL_F_XXX.236 * @param pAsyncCallbackRequired pointer to function that is called when237 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest238 * implements waiting for an IRQ in this function.239 * @param pvAsyncDataAn arbitrary VBoxGuest pointer to be passed to callback.240 * @param u32AsyncDataAn arbitrary VBoxGuest 32 bit value to be passed to callback.241 * 242 * @return VBox status code.237 * @param pCallInfo The request data. 238 * @param fFlags Flags, see VBGLR0_HGCMCALL_F_XXX. 239 * @param pfnAsyncCallback Required pointer to function that is called when 240 * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest 241 * implements waiting for an IRQ in this function. 242 * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback. 243 * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback. 244 * 245 * @return VBox status code. 243 246 */ 244 247 DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags, 245 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);248 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData); 246 249 247 250 /** @name VbglR0HGCMInternalCall flags -
trunk/include/VBox/VMMDev.h
r21488 r21506 151 151 #endif /* VBOX_WITH_64_BITS_GUESTS */ 152 152 VMMDevReq_HGCMCancel = 64, 153 VMMDevReq_HGCMCancel2 = 65, 153 154 #endif 154 155 VMMDevReq_VideoAccelEnable = 70, … … 953 954 * @{ 954 955 */ 955 # define VBOX_HGCM_REQ_DONE (0x1) 956 # define VBOX_HGCM_REQ_DONE RT_BIT_32(VBOX_HGCM_REQ_DONE_BIT) 957 # define VBOX_HGCM_REQ_DONE_BIT 0 956 958 # define VBOX_HGCM_REQ_CANCELLED (0x2) 957 959 /** @} */ … … 1332 1334 } VMMDevHGCMCancel; 1333 1335 AssertCompileSize(VMMDevHGCMCancel, 32); 1336 1337 /** 1338 * HGCM cancel request structure, version 2. 1339 * 1340 * Used by VMMDevReq_HGCMCancel2. 1341 * 1342 * VINF_SUCCESS when cancelled. 1343 * VERR_NOT_FOUND if the specified request cannot be found. 1344 * VERR_INVALID_PARAMETER if the address is invalid valid. 1345 */ 1346 typedef struct 1347 { 1348 /** Header. */ 1349 VMMDevRequestHeader header; 1350 /** The physical address of the request to cancel. */ 1351 RTGCPHYS32 physReqToCancel; 1352 } VMMDevHGCMCancel2; 1353 AssertCompileSize(VMMDevHGCMCancel2, 24+4); 1334 1354 1335 1355 #endif /* VBOX_WITH_HGCM */ -
trunk/src/VBox/Additions/WINNT/VBoxGuest/VBoxGuest.cpp
r21456 r21506 454 454 } 455 455 456 DECLVBGL( void) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data)456 DECLVBGL(int) VBoxHGCMCallback (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 457 457 { 458 458 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData; … … 460 460 dprintf(("VBoxHGCMCallback\n")); 461 461 VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, false, UserMode); 462 } 463 464 DECLVBGL(void) VBoxHGCMCallbackKernelMode (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 462 return VINF_SUCCESS; 463 } 464 465 DECLVBGL(int) VBoxHGCMCallbackKernelMode (VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data) 465 466 { 466 467 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvData; … … 468 469 dprintf(("VBoxHGCMCallback\n")); 469 470 VBoxHGCMCallbackWorker (pHeader, pDevExt, u32Data, false, KernelMode); 471 return VINF_SUCCESS; 470 472 } 471 473 -
trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
r21498 r21506 46 46 *******************************************************************************/ 47 47 #ifdef VBOX_WITH_HGCM 48 static DECLCALLBACK( void) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User);48 static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdrNonVolatile, void *pvUser, uint32_t u32User); 49 49 #endif 50 50 … … 1049 1049 1050 1050 /** Worker for VBoxGuestHGCMAsyncWaitCallback*. */ 1051 static voidVBoxGuestHGCMAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile *pHdr, PVBOXGUESTDEVEXT pDevExt,1051 static int VBoxGuestHGCMAsyncWaitCallbackWorker(VMMDevHGCMRequestHeader volatile *pHdr, PVBOXGUESTDEVEXT pDevExt, 1052 1052 bool fInterruptible, uint32_t cMillies) 1053 1053 { … … 1068 1068 { 1069 1069 RTSpinlockReleaseNoInts(pDevExt->EventSpinlock, &Tmp); 1070 return ;1070 return VINF_SUCCESS; 1071 1071 } 1072 1072 RTSpinlockReleaseNoInts(pDevExt->EventSpinlock, &Tmp); … … 1076 1076 break; 1077 1077 if (fInterruptible) 1078 return ;1078 return VERR_INTERRUPTED; 1079 1079 RTThreadSleep(1); 1080 1080 } … … 1092 1092 VBoxGuestWaitFreeLocked(pDevExt, pWait); 1093 1093 RTSpinlockReleaseNoInts(pDevExt->EventSpinlock, &Tmp); 1094 return ;1094 return VINF_SUCCESS; 1095 1095 } 1096 1096 VBoxGuestWaitAppend(&pDevExt->HGCMWaitList, pWait); … … 1102 1102 else 1103 1103 rc = RTSemEventMultiWait(pWait->Event, cMillies); 1104 1105 /* 1106 * This shouldn't ever return failure... 1104 if (rc == VERR_SEM_DESTROYED) 1105 return rc; 1106 1107 /* 1107 1108 * Unlink, free and return. 1108 1109 */ 1109 if (rc == VERR_SEM_DESTROYED) 1110 return; 1111 if (RT_FAILURE(rc)) 1110 if ( RT_FAILURE(rc) 1111 && rc != VERR_TIMEOUT 1112 && ( !fInterruptible 1113 || rc != VERR_INTERRUPTED)) 1112 1114 LogRel(("VBoxGuestHGCMAsyncWaitCallback: wait failed! %Rrc\n", rc)); 1113 1115 … … 1116 1118 VBoxGuestWaitFreeLocked(pDevExt, pWait); 1117 1119 RTSpinlockReleaseNoInts(pDevExt->EventSpinlock, &Tmp); 1120 return rc; 1118 1121 } 1119 1122 … … 1124 1127 * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent. 1125 1128 */ 1126 static DECLCALLBACK( void) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User)1129 static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallback(VMMDevHGCMRequestHeader *pHdr, void *pvUser, uint32_t u32User) 1127 1130 { 1128 1131 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser; 1129 1132 Log(("VBoxGuestHGCMAsyncWaitCallback: requestType=%d\n", pHdr->header.requestType)); 1130 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr,1131 pDevExt,1132 false /* fInterruptible */,1133 u32User /* cMillies */);1133 return VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, 1134 pDevExt, 1135 false /* fInterruptible */, 1136 u32User /* cMillies */); 1134 1137 } 1135 1138 … … 1140 1143 * It operates in a manner similar to VBoxGuestCommonIOCtl_WaitEvent. 1141 1144 */ 1142 static DECLCALLBACK( void) VBoxGuestHGCMAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr,1145 static DECLCALLBACK(int) VBoxGuestHGCMAsyncWaitCallbackInterruptible(VMMDevHGCMRequestHeader *pHdr, 1143 1146 void *pvUser, uint32_t u32User) 1144 1147 { 1145 1148 PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pvUser; 1146 1149 Log(("VBoxGuestHGCMAsyncWaitCallbackInterruptible: requestType=%d\n", pHdr->header.requestType)); 1147 VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, 1148 pDevExt, 1149 true /* fInterruptible */, 1150 u32User /* cMillies */ ); 1150 return VBoxGuestHGCMAsyncWaitCallbackWorker((VMMDevHGCMRequestHeader volatile *)pHdr, 1151 pDevExt, 1152 true /* fInterruptible */, 1153 u32User /* cMillies */ ); 1154 1151 1155 } 1152 1156 -
trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile
r21337 r21506 92 92 r0drv/linux/spinlock-r0drv-linux.o \ 93 93 r0drv/linux/thread-r0drv-linux.o \ 94 r0drv/linux/time-r0drv-linux.o \ 94 95 r0drv/linux/RTLogWriteDebugger-r0drv-linux.o \ 95 96 common/err/RTErrConvertFromErrno.o \ -
trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
r21337 r21506 125 125 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h=>r0drv/linux/the-linux-kernel.h \ 126 126 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c=>r0drv/linux/thread-r0drv-linux.c \ 127 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \ 127 128 ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c=>r0drv/linux/RTLogWriteDebugger-r0drv-linux.c \ 128 129 ${PATH_ROOT}/src/VBox/Runtime/VBox/log-vbox.cpp=>VBox/log-vbox.c \ … … 134 135 FILES_VBOXGUEST_BIN=" \ 135 136 " 137 -
trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp
r21489 r21506 28 28 #include "VBGLInternal.h" 29 29 #include <iprt/alloca.h> 30 #include <iprt/asm.h> 30 31 #include <iprt/assert.h> 31 32 #include <iprt/mem.h> 32 33 #include <iprt/memobj.h> 33 34 #include <iprt/string.h> 35 #include <iprt/thread.h> 36 #include <iprt/time.h> 37 34 38 35 39 /******************************************************************************* … … 46 50 #endif 47 51 52 48 53 /******************************************************************************* 49 54 * Structures and Typedefs * … … 70 75 71 76 DECLVBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo, 72 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, 73 uint32_t u32AsyncData) 77 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData) 74 78 { 75 79 VMMDevHGCMConnect *pHGCMConnect; 76 80 int rc; 77 81 78 if (!pConnectInfo || !p AsyncCallback)82 if (!pConnectInfo || !pfnAsyncCallback) 79 83 return VERR_INVALID_PARAMETER; 80 84 … … 101 105 { 102 106 /* Wait for request completion interrupt notification from host */ 103 p AsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);107 pfnAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData); 104 108 } 105 109 … … 118 122 119 123 DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo, 120 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)124 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData) 121 125 { 122 126 VMMDevHGCMDisconnect *pHGCMDisconnect; 123 127 int rc; 124 128 125 if (!pDisconnectInfo || !p AsyncCallback)129 if (!pDisconnectInfo || !pfnAsyncCallback) 126 130 return VERR_INVALID_PARAMETER; 127 131 … … 147 151 { 148 152 /* Wait for request completion interrupt notification from host */ 149 p AsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);153 pfnAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData); 150 154 } 151 155 … … 609 613 * @param pvAsyncData Argument for the callback. 610 614 * @param u32AsyncData Argument for the callback. 615 * @param pfLeakIt Where to return the leak it / free it, 616 * indicator. Cancellation fun. 611 617 */ 612 static int vbglR0HGCMInternalDoCall(VMMDevHGCMCall *pHGCMCall, VBGLHGCMCALLBACK *pfnAsyncCallback,613 void *pvAsyncData, uint32_t u32AsyncData )618 static int vbglR0HGCMInternalDoCall(VMMDevHGCMCall *pHGCMCall, PFNVBGLHGCMCALLBACK pfnAsyncCallback, 619 void *pvAsyncData, uint32_t u32AsyncData, bool *pfLeakIt) 614 620 { 615 621 int rc; … … 634 640 * if so, we wait for it to complete using the caller supplied callback. 635 641 */ 636 if ( RT_SUCCESS(rc)637 &&rc == VINF_HGCM_ASYNC_EXECUTE)642 *pfLeakIt = false; 643 if (rc == VINF_HGCM_ASYNC_EXECUTE) 638 644 { 639 645 Log(("Processing HGCM call asynchronously\n")); 640 /** @todo timeout vs. interrupted. */ 641 pfnAsyncCallback(&pHGCMCall->header, pvAsyncData, u32AsyncData); 642 643 /* 644 * If the request isn't completed by the time the callback returns 645 * we will have to try cancel it. 646 */ 647 if (!(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)) 646 rc = pfnAsyncCallback(&pHGCMCall->header, pvAsyncData, u32AsyncData); 647 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 648 648 { 649 /** @todo use a new request for this! See @bugref{4052}. */ 650 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 651 pHGCMCall->header.header.requestType = VMMDevReq_HGCMCancel; 652 VbglGRPerform(&pHGCMCall->header.header); 653 rc = VERR_INTERRUPTED; 649 Assert(!(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED)); 650 rc = VINF_SUCCESS; 654 651 } 655 } 656 657 Log(("GstHGCMCall: rc=%Rrc result=%Rrc fu32Flags=%#x\n", rc, pHGCMCall->header.result, pHGCMCall->header.fu32Flags)); 652 else 653 { 654 /* 655 * The request didn't complete in time or the call was interrupted, 656 * the RC from the callback indicates which. Try cancel the request. 657 * 658 * This is a bit messy because we're racing request completion. Sorry. 659 */ 660 /** @todo It would be nice if we could use the waiter callback to do further 661 * waiting in case of a completion race. If it wasn't for WINNT having its own 662 * version of all that stuff, I would've done it already. */ 663 VMMDevHGCMCancel2 *pCancelReq; 664 int rc2 = VbglGRAlloc((VMMDevRequestHeader **)&pCancelReq, sizeof(*pCancelReq), VMMDevReq_HGCMCancel2); 665 if (RT_SUCCESS(rc2)) 666 { 667 pCancelReq->physReqToCancel = VbglPhysHeapGetPhysAddr(pHGCMCall); 668 rc2 = VbglGRPerform(&pCancelReq->header); 669 VbglGRFree(&pCancelReq->header); 670 } 671 #if 1 /** @todo ADDVER: Remove this on next minor version change. */ 672 if (rc2 == VERR_NOT_IMPLEMENTED) 673 { 674 /* host is too old, or we're out of heap. */ 675 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 676 pHGCMCall->header.header.requestType = VMMDevReq_HGCMCancel; 677 rc2 = VbglGRPerform(&pHGCMCall->header.header); 678 if (rc2 == VERR_INVALID_PARAMETER) 679 rc2 = VERR_NOT_FOUND; 680 else if (RT_SUCCESS(rc)) 681 RTThreadSleep(1); 682 } 683 #endif 684 if (RT_SUCCESS(rc)) rc = VERR_INTERRUPTED; /** @todo weed this out from the WINNT VBoxGuest code. */ 685 if (RT_SUCCESS(rc2)) 686 { 687 Log(("vbglR0HGCMInternalDoCall: successfully cancelled\n")); 688 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED; 689 } 690 else 691 { 692 /* 693 * Wait for a bit while the host (hopefully) completes it. 694 */ 695 uint64_t u64Start = RTTimeSystemMilliTS(); 696 uint32_t cMilliesToWait = rc2 == VERR_NOT_FOUND || rc2 == VERR_SEM_DESTROYED ? 500 : 2000; 697 uint64_t cElapsed = 0; 698 if (rc2 != VERR_NOT_FOUND) 699 LogRel(("vbglR0HGCMInternalDoCall: Failed to cancel the HGCM call on %Rrc: rc2=%Rrc\n", rc, rc2)); 700 else 701 Log(("vbglR0HGCMInternalDoCall: Cancel race rc=%Rrc rc2=%Rrc\n", rc, rc2)); 702 703 do 704 { 705 ASMCompilerBarrier(); /* paranoia */ 706 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 707 break; 708 RTThreadSleep(1); 709 cElapsed = RTTimeSystemMilliTS() - u64Start; 710 } while (cElapsed < cMilliesToWait); 711 712 ASMCompilerBarrier(); /* paranoia^2 */ 713 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE) 714 rc = VINF_SUCCESS; 715 else 716 { 717 LogRel(("vbglR0HGCMInternalDoCall: Leaking %u bytes. Pending call to %u with %u parms. (rc2=%Rrc)\n", 718 pHGCMCall->header.header.size, pHGCMCall->u32Function, pHGCMCall->cParms, rc2)); 719 *pfLeakIt = true; 720 } 721 Log(("vbglR0HGCMInternalDoCall: Cancel race ended with rc=%Rrc (rc2=%Rrc) after %llu ms\n", rc, rc2, cElapsed)); 722 } 723 } 724 } 725 726 Log(("GstHGCMCall: rc=%Rrc result=%Rrc fu32Flags=%#x fLeakIt=%d\n", 727 rc, pHGCMCall->header.result, pHGCMCall->header.fu32Flags, *pfLeakIt)); 658 728 return rc; 659 729 } … … 767 837 768 838 DECLR0VBGL(int) VbglR0HGCMInternalCall(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags, 769 VBGLHGCMCALLBACK *pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)839 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData) 770 840 { 771 841 bool fIsUser = (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER; … … 806 876 if (RT_SUCCESS(rc)) 807 877 { 878 bool fLeakIt; 808 879 vbglR0HGCMInternalInitCall(pHGCMCall, pCallInfo, cbCallInfo, fIsUser, &ParmInfo); 809 880 … … 811 882 * Perform the call. 812 883 */ 813 rc = vbglR0HGCMInternalDoCall(pHGCMCall, pfnAsyncCallback, pvAsyncData, u32AsyncData );884 rc = vbglR0HGCMInternalDoCall(pHGCMCall, pfnAsyncCallback, pvAsyncData, u32AsyncData, &fLeakIt); 814 885 if (RT_SUCCESS(rc)) 815 886 { … … 820 891 } 821 892 822 VbglGRFree(&pHGCMCall->header.header); 893 if (!fLeakIt) 894 VbglGRFree(&pHGCMCall->header.header); 823 895 } 824 896 } … … 842 914 #if ARCH_BITS == 64 843 915 DECLR0VBGL(int) VbglR0HGCMInternalCall32(VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags, 844 VBGLHGCMCALLBACK *pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)916 PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData) 845 917 { 846 918 VBoxGuestHGCMCallInfo *pCallInfo64; … … 858 930 || pCallInfo->cParms > VBOX_HGCM_MAX_PARMS 859 931 || !(fFlags & ~VBGLR0_HGCMCALL_F_MODE_MASK), 860 ("pCallInfo=%p p AsyncCallback=%p fFlags=%#x\n", pCallInfo, pfnAsyncCallback, fFlags),932 ("pCallInfo=%p pfnAsyncCallback=%p fFlags=%#x\n", pCallInfo, pfnAsyncCallback, fFlags), 861 933 VERR_INVALID_PARAMETER); 862 934 AssertReturn( cbCallInfo >= sizeof(VBoxGuestHGCMCallInfo) -
trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
r21460 r21506 1137 1137 } 1138 1138 1139 case VMMDevReq_HGCMCancel2: 1140 { 1141 if (pRequestHeader->size != sizeof(VMMDevHGCMCancel2)) 1142 { 1143 AssertMsgFailed(("VMMDevReq_HGCMCancel structure has invalid size!\n")); 1144 pRequestHeader->rc = VERR_INVALID_PARAMETER; 1145 } 1146 else if (!pThis->pHGCMDrv) 1147 { 1148 Log(("VMMDevReq_HGCMCancel HGCM Connector is NULL!\n")); 1149 pRequestHeader->rc = VERR_NOT_SUPPORTED; 1150 } 1151 else 1152 { 1153 VMMDevHGCMCancel2 *pHGCMCancel2 = (VMMDevHGCMCancel2 *)pRequestHeader; 1154 1155 Log(("VMMDevReq_VMMDevHGCMCancel\n")); 1156 pRequestHeader->rc = vmmdevHGCMCancel2 (pThis, pHGCMCancel2->physReqToCancel); 1157 } 1158 break; 1159 } 1160 1139 1161 case VMMDevReq_VideoAccelEnable: 1140 1162 { … … 1587 1609 else 1588 1610 { 1589 VMMDevReqLogString *pReqLogString = (VMMDevReqLogString*)pRequestHeader; 1590 #undef LOG_GROUP 1591 #define LOG_GROUP LOG_GROUP_DEV_VMM_BACKDOOR 1592 // Log(("Guest Log: %s", pReqLogString->szString)); 1593 Log(("DEBUG LOG: %s", pReqLogString->szString)); 1594 1595 #undef LOG_GROUP 1596 #define LOG_GROUP LOG_GROUP_DEV_VMM 1611 VMMDevReqLogString *pReqLogString = (VMMDevReqLogString *)pRequestHeader; 1612 LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP_DEV_VMM_BACKDOOR, 1613 ("DEBUG LOG: %s", pReqLogString->szString)); 1597 1614 pRequestHeader->rc = VINF_SUCCESS; 1598 1615 } -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
r21458 r21506 199 199 200 200 201 static PVBOXHGCMCMD vmmdevHGCMFindCommand (VMMDevState *pVMMDevState, RTGCPHYS GCPhys) 202 { 203 PVBOXHGCMCMD pCmd = NULL; 204 205 int rc = vmmdevHGCMCmdListLock (pVMMDevState); 206 207 if (RT_SUCCESS (rc)) 208 { 209 pCmd = pVMMDevState->pHGCMCmdList; 210 211 while (pCmd) 212 { 213 if (pCmd->GCPhys == GCPhys) 214 { 215 break; 216 } 217 pCmd = pCmd->pNext; 218 } 219 220 vmmdevHGCMCmdListUnlock (pVMMDevState); 221 } 222 223 LogFlowFunc(("%p\n", pCmd)); 224 return pCmd; 201 /** 202 * Find a HGCM command by its physical address. 203 * 204 * The caller is responsible for taking the command list lock before calling 205 * this function. 206 * 207 * @returns Pointer to the command on success, NULL otherwise. 208 * @param pThis The VMMDev instance data. 209 * @param GCPhys The physical address of the command we're looking 210 * for. 211 */ 212 DECLINLINE(PVBOXHGCMCMD) vmmdevHGCMFindCommandLocked (VMMDevState *pThis, RTGCPHYS GCPhys) 213 { 214 for (PVBOXHGCMCMD pCmd = pThis->pHGCMCmdList; 215 pCmd; 216 pCmd = pCmd->pNext) 217 { 218 if (pCmd->GCPhys == GCPhys) 219 return pCmd; 220 } 221 return NULL; 225 222 } 226 227 223 228 224 static int vmmdevHGCMSaveLinPtr (PPDMDEVINS pDevIns, … … 1005 1001 1006 1002 /* Pass the function call to HGCM connector for actual processing */ 1007 rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pCmd->paHostParms); 1003 rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pCmd, pHGCMCall->u32ClientID, 1004 pHGCMCall->u32Function, cParms, pCmd->paHostParms); 1008 1005 } 1009 1006 else … … 1448 1445 } 1449 1446 1450 /* @thread EMT */ 1447 /** 1448 * VMMDevReq_HGCMCancel worker. 1449 * 1450 * @thread EMT 1451 */ 1451 1452 int vmmdevHGCMCancel (VMMDevState *pVMMDevState, VMMDevHGCMCancel *pHGCMCancel, RTGCPHYS GCPhys) 1452 1453 { 1453 int rc = VINF_SUCCESS;1454 1455 1454 NOREF(pHGCMCancel); 1456 1457 Log(("vmmdevHGCMCancel\n")); 1458 1459 /* Find the command in the list. */ 1460 PVBOXHGCMCMD pCmd = vmmdevHGCMFindCommand (pVMMDevState, GCPhys); 1461 1455 int rc = vmmdevHGCMCancel2(pVMMDevState, GCPhys); 1456 return rc == VERR_NOT_FOUND ? VERR_INVALID_PARAMETER : rc; 1457 } 1458 1459 /** 1460 * VMMDevReq_HGCMCancel2 worker. 1461 * 1462 * @retval VINF_SUCCESS on success. 1463 * @retval VERR_NOT_FOUND if the request was not found. 1464 * @retval VERR_INVALID_PARAMETER if the request address is invalid. 1465 * 1466 * @param pThis The VMMDev instance data. 1467 * @param GCPhys The address of the request that should be cancelled. 1468 * 1469 * @thread EMT 1470 */ 1471 int vmmdevHGCMCancel2 (VMMDevState *pThis, RTGCPHYS GCPhys) 1472 { 1473 if ( GCPhys == 0 1474 || GCPhys == NIL_RTGCPHYS 1475 || GCPhys == NIL_RTGCPHYS32) 1476 { 1477 Log(("vmmdevHGCMCancel2: GCPhys=%#x\n", GCPhys)); 1478 return VERR_INVALID_PARAMETER; 1479 } 1480 1481 /* 1482 * Locate the command and cancel it while under the protection of 1483 * the lock. hgcmCompletedWorker makes assumptions about this. 1484 */ 1485 int rc = vmmdevHGCMCmdListLock (pThis); 1486 AssertRCReturn(rc, rc); 1487 1488 PVBOXHGCMCMD pCmd = vmmdevHGCMFindCommandLocked (pThis, GCPhys); 1462 1489 if (pCmd) 1463 1490 { 1464 1491 pCmd->fCancelled = true; 1492 Log(("vmmdevHGCMCancel2: Cancelled pCmd=%p / GCPhys=%#x\n", pCmd, GCPhys)); 1465 1493 } 1466 1494 else 1467 { 1468 rc = VERR_INVALID_PARAMETER; 1469 } 1470 1495 rc = VERR_NOT_FOUND; 1496 1497 vmmdevHGCMCmdListUnlock (pThis); 1471 1498 return rc; 1472 1499 } … … 1529 1556 } 1530 1557 1531 /* Check whether the command has been already cancelled by the guest. 1532 * If it was cancelled, then the data must not be written back to the 1533 * guest RAM. 1558 /* 1559 * The cancellation protocol requires us to remove the command here 1560 * and then check the flag. Cancelled commands must not be written 1561 * back to guest memory. 1534 1562 */ 1563 vmmdevHGCMRemoveCommand (pVMMDevState, pCmd); 1564 1535 1565 if (pCmd->fCancelled) 1536 1566 { 1537 /* Just remove the command from the internal list, so the memory can be freed. */1538 1567 LogFlowFunc(("A cancelled command %p\n", pCmd)); 1539 vmmdevHGCMRemoveCommand (pVMMDevState, pCmd);1540 1568 } 1541 1569 else … … 1557 1585 { 1558 1586 pHeader = (VMMDevHGCMRequestHeader *)RTMemAlloc (pCmd->cbSize); 1559 Assert(pHeader);1560 1587 if (pHeader == NULL) 1561 1588 { 1562 LogRel(("VMMDev: Failed to allocate % dbytes for HGCM request completion!!!\n", pCmd->cbSize));1563 1564 /* Do some cleanup. The command have to be excluded from list of active commands anyway. */1565 vmmdevHGCMRemoveCommand (pVMMDevState,pCmd);1589 LogRel(("VMMDev: Failed to allocate %u bytes for HGCM request completion!!!\n", pCmd->cbSize)); 1590 1591 /* Free it. The command have to be excluded from list of active commands anyway. */ 1592 RTMemFree (pCmd); 1566 1593 return; 1567 1594 } … … 1578 1605 * didn't have to mess around with PDMDevHlpPhysRead/Write. We're 1579 1606 * reading the header 3 times now and writing the request back twice. */ 1607 1580 1608 PDMCritSectEnter(&pVMMDevState->CritSect, VERR_SEM_BUSY); 1581 1609 PDMCritSectLeave(&pVMMDevState->CritSect); … … 1635 1663 { 1636 1664 /* Use the saved page list to write data back to the guest RAM. */ 1637 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr, pCmd->paLinPtrs); 1665 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, 1666 size, iLinPtr, pCmd->paLinPtrs); 1638 1667 AssertReleaseRC(rc); 1639 1668 } … … 1916 1945 /* Write back the request */ 1917 1946 PDMDevHlpPhysWrite(pVMMDevState->pDevIns, pCmd->GCPhys, pHeader, pCmd->cbSize); 1918 1919 /* The command has been completely processed and can be removed from the list. */1920 vmmdevHGCMRemoveCommand (pVMMDevState, pCmd);1921 1947 1922 1948 /* Now, when the command was removed from the internal list, notify the guest. */ -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h
r21456 r21506 30 30 DECLCALLBACK(int) vmmdevHGCMCall (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, uint32_t cbHGCMCall, RTGCPHYS GCPtr, bool f64Bits); 31 31 DECLCALLBACK(int) vmmdevHGCMCancel (VMMDevState *pVMMDevState, VMMDevHGCMCancel *pHGCMCancel, RTGCPHYS GCPtr); 32 DECLCALLBACK(int) vmmdevHGCMCancel2 (VMMDevState *pVMMDevState, RTGCPHYS GCPtr); 32 33 33 34 DECLCALLBACK(void) hgcmCompleted (PPDMIHGCMPORT pInterface, int32_t result, PVBOXHGCMCMD pCmdPtr);
Note:
See TracChangeset
for help on using the changeset viewer.