Changeset 20731 in vbox
- Timestamp:
- Jun 19, 2009 5:24:41 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 48847
- Location:
- trunk/src/VBox/Devices/VMMDev
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/VMMDev/VBoxDev.cpp
r19654 r20731 2024 2024 2025 2025 2026 #define VMMDEV_SSM_VERSION 82026 #define VMMDEV_SSM_VERSION 9 2027 2027 2028 2028 /** … … 2107 2107 2108 2108 #ifdef VBOX_WITH_HGCM 2109 vmmdevHGCMLoadState (pThis, pSSMHandle );2109 vmmdevHGCMLoadState (pThis, pSSMHandle, u32Version); 2110 2110 #endif /* VBOX_WITH_HGCM */ 2111 2111 -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
r20024 r20731 37 37 typedef enum _VBOXHGCMCMDTYPE 38 38 { 39 VBOXHGCMCMDTYPE_LOADSTATE ,39 VBOXHGCMCMDTYPE_LOADSTATE = 0, 40 40 VBOXHGCMCMDTYPE_CONNECT, 41 41 VBOXHGCMCMDTYPE_DISCONNECT, … … 48 48 { 49 49 /* Index of the parameter. */ 50 int iParm;50 uint32_t iParm; 51 51 52 52 /* Offset in the first physical page of the region. */ … … 70 70 struct VBOXHGCMCMD *pPrev; 71 71 72 /* Size of memory buffer for this command structure, including trailing paHostParms. 73 * This field simplifies loading of saved state. 74 */ 75 uint32_t cbCmd; 76 72 77 /* The type of the command. */ 73 78 VBOXHGCMCMDTYPE enmCmdType; … … 82 87 uint32_t cbSize; 83 88 84 /* Pointer to converted host parameters in case of a Call request. */ 89 /* Pointer to converted host parameters in case of a Call request. 90 * Parameters follow this structure in the same memory block. 91 */ 85 92 VBOXHGCMSVCPARM *paHostParms; 86 93 87 94 /* Linear pointer parameters information. */ 88 95 int cLinPtrs; 96 97 /* How many pages for all linptrs of this command. 98 * Only valid if cLinPtrs > 0. This field simplifies loading of saved state. 99 */ 100 int cLinPtrPages; 89 101 90 102 /* Pointer to descriptions of linear pointers. */ … … 126 138 pVMMDevState->pHGCMCmdList = pCmd; 127 139 128 pCmd->enmCmdType = enmCmdType; 140 if (enmCmdType != VBOXHGCMCMDTYPE_LOADSTATE) 141 { 142 /* Loaded commands already have the right type. */ 143 pCmd->enmCmdType = enmCmdType; 144 } 129 145 pCmd->GCPhys = GCPhys; 130 146 pCmd->cbSize = cbSize; … … 322 338 } 323 339 340 static void logRelSavedCmdSizeMismatch (const char *pszFunction, uint32_t cbExpected, uint32_t cbCmdSize) 341 { 342 LogRel(("Warning: VMMDev %s command length %d (expected %d)\n", 343 pszFunction, cbCmdSize, cbExpected)); 344 } 345 324 346 int vmmdevHGCMConnect (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, RTGCPHYS GCPhys) 325 347 { 326 348 int rc = VINF_SUCCESS; 327 349 328 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD) + pHGCMConnect->header.header.size); 350 uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD) + pHGCMConnect->header.header.size; 351 352 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (cbCmdSize); 329 353 330 354 if (pCmd) … … 336 360 memcpy(pHGCMConnectCopy, pHGCMConnect, pHGCMConnect->header.header.size); 337 361 362 pCmd->cbCmd = cbCmdSize; 338 363 pCmd->paHostParms = NULL; 339 364 pCmd->cLinPtrs = 0; … … 354 379 } 355 380 381 static int vmmdevHGCMConnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMConnect *pHGCMConnect, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd) 382 { 383 int rc = VINF_SUCCESS; 384 385 uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD) + pHGCMConnect->header.header.size; 386 387 if (pSavedCmd->cbCmd < cbCmdSize) 388 { 389 logRelSavedCmdSizeMismatch ("HGCMConnect", pSavedCmd->cbCmd, cbCmdSize); 390 return VERR_INVALID_PARAMETER; 391 } 392 393 VMMDevHGCMConnect *pHGCMConnectCopy = (VMMDevHGCMConnect *)(pSavedCmd+1); 394 395 memcpy(pHGCMConnectCopy, pHGCMConnect, pHGCMConnect->header.header.size); 396 397 /* Only allow the guest to use existing services! */ 398 Assert(pHGCMConnect->loc.type == VMMDevHGCMLoc_LocalHost_Existing); 399 pHGCMConnect->loc.type = VMMDevHGCMLoc_LocalHost_Existing; 400 401 rc = pVMMDevState->pHGCMDrv->pfnConnect (pVMMDevState->pHGCMDrv, pSavedCmd, &pHGCMConnectCopy->loc, &pHGCMConnectCopy->u32ClientID); 402 if (RT_SUCCESS (rc)) 403 { 404 *pfHGCMCalled = true; 405 } 406 407 return rc; 408 } 409 356 410 int vmmdevHGCMDisconnect (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, RTGCPHYS GCPhys) 357 411 { 358 412 int rc = VINF_SUCCESS; 359 413 360 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD)); 414 uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD); 415 416 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (cbCmdSize); 361 417 362 418 if (pCmd) … … 364 420 vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, pHGCMDisconnect->header.header.size, VBOXHGCMCMDTYPE_DISCONNECT); 365 421 422 pCmd->cbCmd = cbCmdSize; 366 423 pCmd->paHostParms = NULL; 367 424 pCmd->cLinPtrs = 0; … … 373 430 { 374 431 rc = VERR_NO_MEMORY; 432 } 433 434 return rc; 435 } 436 437 static int vmmdevHGCMDisconnectSaved (VMMDevState *pVMMDevState, VMMDevHGCMDisconnect *pHGCMDisconnect, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd) 438 { 439 int rc = VINF_SUCCESS; 440 441 uint32_t cbCmdSize = sizeof (struct VBOXHGCMCMD); 442 443 if (pSavedCmd->cbCmd < cbCmdSize) 444 { 445 logRelSavedCmdSizeMismatch ("HGCMConnect", pSavedCmd->cbCmd, cbCmdSize); 446 return VERR_INVALID_PARAMETER; 447 } 448 449 rc = pVMMDevState->pHGCMDrv->pfnDisconnect (pVMMDevState->pHGCMDrv, pSavedCmd, pHGCMDisconnect->u32ClientID); 450 if (RT_SUCCESS (rc)) 451 { 452 *pfHGCMCalled = true; 375 453 } 376 454 … … 424 502 case VMMDevHGCMParmType_LinAddr: /* In & Out */ 425 503 { 426 cbCmdSize += pGuestParm->u.Pointer.size; 427 428 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 504 if (pGuestParm->u.Pointer.size > 0) 429 505 { 506 /* Only pointers with some actual data are counted. */ 507 cbCmdSize += pGuestParm->u.Pointer.size; 508 430 509 cLinPtrs++; 431 510 /* Take the offset into the current page also into account! */ … … 469 548 case VMMDevHGCMParmType_LinAddr: /* In & Out */ 470 549 { 471 cbCmdSize += pGuestParm->u.Pointer.size; 472 473 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 550 if (pGuestParm->u.Pointer.size > 0) 474 551 { 552 /* Only pointers with some actual data are counted. */ 553 cbCmdSize += pGuestParm->u.Pointer.size; 554 475 555 cLinPtrs++; 476 556 /* Take the offset into the current page also into account! */ … … 512 592 memset (pCmd, 0, sizeof (*pCmd)); 513 593 594 pCmd->cbCmd = cbCmdSize; 514 595 pCmd->paHostParms = NULL; 515 596 pCmd->cLinPtrs = cLinPtrs; 597 pCmd->cLinPtrPages = cLinPtrPages; 516 598 517 599 if (cLinPtrs > 0) … … 632 714 pcBuf += size; 633 715 634 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 635 { 636 /* Remember the guest physical pages that belong to the virtual address 637 * region. 638 */ 639 rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr++, pCmd->paLinPtrs, &pPages); 640 } 716 /* Remember the guest physical pages that belong to the virtual address region. 717 * Do it for all linear pointers because load state will require In pointer info too. 718 */ 719 rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr, pCmd->paLinPtrs, &pPages); 720 721 iLinPtr++; 641 722 } 642 723 } … … 734 815 pcBuf += size; 735 816 736 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 737 { 738 /* Remember the guest physical pages that belong to the virtual address 739 * region. 740 */ 741 rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr++, pCmd->paLinPtrs, &pPages); 742 } 817 /* Remember the guest physical pages that belong to the virtual address region. 818 * Do it for all linear pointers because load state will require In pointer info too. 819 */ 820 rc = vmmdevHGCMSaveLinPtr (pVMMDevState->pDevIns, i, linearAddr, size, iLinPtr, pCmd->paLinPtrs, &pPages); 821 822 iLinPtr++; 743 823 } 744 824 } … … 771 851 772 852 RTMemFree (pCmd); 853 } 854 855 return rc; 856 } 857 858 static void logRelLoadStatePointerIndexMismatch (uint32_t iParm, uint32_t iSavedParm, int iLinPtr, int cLinPtrs) 859 { 860 LogRel(("Warning: VMMDev load state: a pointer parameter index mismatch %d (expected %d) (%d/%d)\n", 861 (int)iParm, (int)iSavedParm, iLinPtr, cLinPtrs)); 862 } 863 864 static void logRelLoadStateBufferSizeMismatch (uint32_t size, uint32_t iPage, uint32_t cPages) 865 { 866 LogRel(("Warning: VMMDev load state: buffer size mismatch: size %d, page %d/%d\n", 867 (int)size, (int)iPage, (int)cPages)); 868 } 869 870 871 static int vmmdevHGCMCallSaved (VMMDevState *pVMMDevState, VMMDevHGCMCall *pHGCMCall, bool f64Bits, bool *pfHGCMCalled, VBOXHGCMCMD *pSavedCmd) 872 { 873 int rc = VINF_SUCCESS; 874 875 Log(("vmmdevHGCMCallSaved: client id = %d, function = %d, %s bit\n", pHGCMCall->u32ClientID, pHGCMCall->u32Function, f64Bits? "64": "32")); 876 877 /* Compute size and allocate memory block to hold: 878 * struct VBOXHGCMCMD 879 * VBOXHGCMSVCPARM[cParms] 880 * memory buffers for pointer parameters. 881 */ 882 883 uint32_t cParms = pHGCMCall->cParms; 884 885 Log(("vmmdevHGCMCall: cParms = %d\n", cParms)); 886 887 /* 888 * Compute size of required memory buffer. 889 */ 890 891 pSavedCmd->paHostParms = NULL; 892 893 /* Process parameters, changing them to host context pointers for easy 894 * processing by connector. Guest must insure that the pointed data is actually 895 * in the guest RAM and remains locked there for entire request processing. 896 */ 897 898 if (cParms != 0) 899 { 900 /* Compute addresses of host parms array and first memory buffer. */ 901 VBOXHGCMSVCPARM *pHostParm = (VBOXHGCMSVCPARM *)((uint8_t *)pSavedCmd + sizeof (struct VBOXHGCMCMD)); 902 903 uint8_t *pu8Buf = (uint8_t *)pHostParm + cParms * sizeof (VBOXHGCMSVCPARM); 904 905 pSavedCmd->paHostParms = pHostParm; 906 907 uint32_t iParm; 908 int iLinPtr = 0; 909 910 if (f64Bits) 911 { 912 #ifdef VBOX_WITH_64_BITS_GUESTS 913 HGCMFunctionParameter64 *pGuestParm = VMMDEV_HGCM_CALL_PARMS64(pHGCMCall); 914 #else 915 HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall); 916 AssertFailed (); /* This code should not be called in this case */ 917 #endif /* VBOX_WITH_64_BITS_GUESTS */ 918 919 for (iParm = 0; iParm < cParms && RT_SUCCESS(rc); iParm++, pGuestParm++, pHostParm++) 920 { 921 switch (pGuestParm->type) 922 { 923 case VMMDevHGCMParmType_32bit: 924 { 925 uint32_t u32 = pGuestParm->u.value32; 926 927 pHostParm->type = VBOX_HGCM_SVC_PARM_32BIT; 928 pHostParm->u.uint32 = u32; 929 930 Log(("vmmdevHGCMCall: uint32 guest parameter %u\n", u32)); 931 break; 932 } 933 934 case VMMDevHGCMParmType_64bit: 935 { 936 uint64_t u64 = pGuestParm->u.value64; 937 938 pHostParm->type = VBOX_HGCM_SVC_PARM_64BIT; 939 pHostParm->u.uint64 = u64; 940 941 Log(("vmmdevHGCMCall: uint64 guest parameter %llu\n", u64)); 942 break; 943 } 944 945 case VMMDevHGCMParmType_PhysAddr: 946 { 947 uint32_t size = pGuestParm->u.Pointer.size; 948 #ifdef LOG_ENABLED 949 RTGCPHYS physAddr = pGuestParm->u.Pointer.u.physAddr; 950 #endif 951 952 pHostParm->type = VBOX_HGCM_SVC_PARM_PTR; 953 pHostParm->u.pointer.size = size; 954 955 AssertFailed(); 956 /* rc = PDMDevHlpPhys2HCVirt (pVMMDevState->pDevIns, physAddr, size, &pHostParm->u.pointer.addr); */ 957 958 Log(("vmmdevHGCMCall: PhysAddr guest parameter %RGp\n", physAddr)); 959 break; 960 } 961 962 case VMMDevHGCMParmType_LinAddr_In: /* In (read) */ 963 case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */ 964 case VMMDevHGCMParmType_LinAddr: /* In & Out */ 965 { 966 uint32_t size = pGuestParm->u.Pointer.size; 967 968 pHostParm->type = VBOX_HGCM_SVC_PARM_PTR; 969 pHostParm->u.pointer.size = size; 970 971 /* Copy guest data to an allocated buffer, so 972 * services can use the data. 973 */ 974 975 if (size == 0) 976 { 977 pHostParm->u.pointer.addr = NULL; 978 } 979 else 980 { 981 /* The saved command already have the page list in pCmd->paLinPtrs. 982 * Read data from guest pages. 983 */ 984 /* Don't overdo it */ 985 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_Out) 986 { 987 if ( iLinPtr >= pSavedCmd->cLinPtrs 988 || pSavedCmd->paLinPtrs[iLinPtr].iParm != iParm) 989 { 990 logRelLoadStatePointerIndexMismatch (iParm, pSavedCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pSavedCmd->cLinPtrs); 991 rc = VERR_INVALID_PARAMETER; 992 } 993 else 994 { 995 VBOXHGCMLINPTR *pLinPtr = &pSavedCmd->paLinPtrs[iLinPtr]; 996 997 uint32_t iPage; 998 uint32_t offPage = pLinPtr->offFirstPage; 999 size_t cbRemaining = size; 1000 uint8_t *pu8Dst = pu8Buf; 1001 for (iPage = 0; iPage < pLinPtr->cPages; iPage++) 1002 { 1003 if (cbRemaining == 0) 1004 { 1005 logRelLoadStateBufferSizeMismatch (size, iPage, pLinPtr->cPages); 1006 break; 1007 } 1008 1009 size_t cbChunk = PAGE_SIZE - offPage; 1010 1011 if (cbChunk > cbRemaining) 1012 { 1013 cbChunk = cbRemaining; 1014 } 1015 1016 rc = PDMDevHlpPhysRead(pVMMDevState->pDevIns, 1017 pLinPtr->paPages[iPage] + offPage, 1018 pu8Dst, cbChunk); 1019 1020 AssertRCBreak(rc); 1021 1022 offPage = 0; /* A next page is read from 0 offset. */ 1023 cbRemaining -= cbChunk; 1024 pu8Dst += cbChunk; 1025 } 1026 } 1027 } 1028 else 1029 rc = VINF_SUCCESS; 1030 1031 if (RT_SUCCESS(rc)) 1032 { 1033 pHostParm->u.pointer.addr = pu8Buf; 1034 pu8Buf += size; 1035 1036 iLinPtr++; 1037 } 1038 } 1039 1040 Log(("vmmdevHGCMCall: LinAddr guest parameter %RGv, rc = %Rrc\n", 1041 pGuestParm->u.Pointer.u.linearAddr, rc)); 1042 break; 1043 } 1044 1045 /* just to shut up gcc */ 1046 default: 1047 break; 1048 } 1049 } 1050 } 1051 else 1052 { 1053 #ifdef VBOX_WITH_64_BITS_GUESTS 1054 HGCMFunctionParameter32 *pGuestParm = VMMDEV_HGCM_CALL_PARMS32(pHGCMCall); 1055 #else 1056 HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall); 1057 #endif /* VBOX_WITH_64_BITS_GUESTS */ 1058 1059 for (iParm = 0; iParm < cParms && RT_SUCCESS(rc); iParm++, pGuestParm++, pHostParm++) 1060 { 1061 switch (pGuestParm->type) 1062 { 1063 case VMMDevHGCMParmType_32bit: 1064 { 1065 uint32_t u32 = pGuestParm->u.value32; 1066 1067 pHostParm->type = VBOX_HGCM_SVC_PARM_32BIT; 1068 pHostParm->u.uint32 = u32; 1069 1070 Log(("vmmdevHGCMCall: uint32 guest parameter %u\n", u32)); 1071 break; 1072 } 1073 1074 case VMMDevHGCMParmType_64bit: 1075 { 1076 uint64_t u64 = pGuestParm->u.value64; 1077 1078 pHostParm->type = VBOX_HGCM_SVC_PARM_64BIT; 1079 pHostParm->u.uint64 = u64; 1080 1081 Log(("vmmdevHGCMCall: uint64 guest parameter %llu\n", u64)); 1082 break; 1083 } 1084 1085 case VMMDevHGCMParmType_PhysAddr: 1086 { 1087 uint32_t size = pGuestParm->u.Pointer.size; 1088 #ifdef LOG_ENABLED 1089 RTGCPHYS physAddr = pGuestParm->u.Pointer.u.physAddr; 1090 #endif 1091 1092 pHostParm->type = VBOX_HGCM_SVC_PARM_PTR; 1093 pHostParm->u.pointer.size = size; 1094 1095 AssertFailed(); 1096 /* rc = PDMDevHlpPhys2HCVirt (pVMMDevState->pDevIns, physAddr, size, &pHostParm->u.pointer.addr); */ 1097 1098 Log(("vmmdevHGCMCall: PhysAddr guest parameter %RGp\n", physAddr)); 1099 break; 1100 } 1101 1102 case VMMDevHGCMParmType_LinAddr_In: /* In (read) */ 1103 case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */ 1104 case VMMDevHGCMParmType_LinAddr: /* In & Out */ 1105 { 1106 uint32_t size = pGuestParm->u.Pointer.size; 1107 1108 pHostParm->type = VBOX_HGCM_SVC_PARM_PTR; 1109 pHostParm->u.pointer.size = size; 1110 1111 /* Copy guest data to an allocated buffer, so 1112 * services can use the data. 1113 */ 1114 1115 if (size == 0) 1116 { 1117 pHostParm->u.pointer.addr = NULL; 1118 } 1119 else 1120 { 1121 /* The saved command already have the page list in pCmd->paLinPtrs. 1122 * Read data from guest pages. 1123 */ 1124 /* Don't overdo it */ 1125 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_Out) 1126 { 1127 if ( iLinPtr >= pSavedCmd->cLinPtrs 1128 || pSavedCmd->paLinPtrs[iLinPtr].iParm != iParm) 1129 { 1130 logRelLoadStatePointerIndexMismatch (iParm, pSavedCmd->paLinPtrs[iLinPtr].iParm, iLinPtr, pSavedCmd->cLinPtrs); 1131 rc = VERR_INVALID_PARAMETER; 1132 } 1133 else 1134 { 1135 VBOXHGCMLINPTR *pLinPtr = &pSavedCmd->paLinPtrs[iLinPtr]; 1136 1137 uint32_t iPage; 1138 uint32_t offPage = pLinPtr->offFirstPage; 1139 size_t cbRemaining = size; 1140 uint8_t *pu8Dst = pu8Buf; 1141 for (iPage = 0; iPage < pLinPtr->cPages; iPage++) 1142 { 1143 if (cbRemaining == 0) 1144 { 1145 logRelLoadStateBufferSizeMismatch (size, iPage, pLinPtr->cPages); 1146 break; 1147 } 1148 1149 size_t cbChunk = PAGE_SIZE - offPage; 1150 1151 if (cbChunk > cbRemaining) 1152 { 1153 cbChunk = cbRemaining; 1154 } 1155 1156 rc = PDMDevHlpPhysRead(pVMMDevState->pDevIns, 1157 pLinPtr->paPages[iPage] + offPage, 1158 pu8Dst, cbChunk); 1159 1160 AssertRCBreak(rc); 1161 1162 offPage = 0; /* A next page is read from 0 offset. */ 1163 cbRemaining -= cbChunk; 1164 pu8Dst += cbChunk; 1165 } 1166 } 1167 } 1168 else 1169 rc = VINF_SUCCESS; 1170 1171 if (RT_SUCCESS(rc)) 1172 { 1173 pHostParm->u.pointer.addr = pu8Buf; 1174 pu8Buf += size; 1175 1176 iLinPtr++; 1177 } 1178 } 1179 1180 Log(("vmmdevHGCMCall: LinAddr guest parameter %RGv, rc = %Rrc\n", 1181 pGuestParm->u.Pointer.u.linearAddr, rc)); 1182 break; 1183 } 1184 1185 /* just to shut up gcc */ 1186 default: 1187 break; 1188 } 1189 } 1190 } 1191 } 1192 1193 if (RT_SUCCESS (rc)) 1194 { 1195 /* Pass the function call to HGCM connector for actual processing */ 1196 rc = pVMMDevState->pHGCMDrv->pfnCall (pVMMDevState->pHGCMDrv, pSavedCmd, pHGCMCall->u32ClientID, pHGCMCall->u32Function, cParms, pSavedCmd->paHostParms); 1197 if (RT_SUCCESS (rc)) 1198 { 1199 *pfHGCMCalled = true; 1200 } 773 1201 } 774 1202 … … 950 1378 uint32_t size = pGuestParm->u.Pointer.size; 951 1379 952 if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)1380 if (size > 0) 953 1381 { 954 /* Use the saved page list. */ 955 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs); 956 AssertReleaseRC(rc); 1382 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 1383 { 1384 /* Use the saved page list to write data back to the guest RAM. */ 1385 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr, pCmd->paLinPtrs); 1386 AssertReleaseRC(rc); 1387 } 1388 1389 /* All linptrs with size > 0 were saved. Advance the index to the next linptr. */ 1390 iLinPtr++; 957 1391 } 958 1392 } break; … … 1007 1441 uint32_t size = pGuestParm->u.Pointer.size; 1008 1442 1009 if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)1443 if (size > 0) 1010 1444 { 1011 /* Use the saved page list. */ 1012 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs); 1013 AssertReleaseRC(rc); 1445 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 1446 { 1447 /* Use the saved page list to write data back to the guest RAM. */ 1448 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr, pCmd->paLinPtrs); 1449 AssertReleaseRC(rc); 1450 } 1451 1452 /* All linptrs with size > 0 were saved. Advance the index to the next linptr. */ 1453 iLinPtr++; 1014 1454 } 1015 1455 } break; … … 1064 1504 uint32_t size = pGuestParm->u.Pointer.size; 1065 1505 1066 if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)1506 if (size > 0) 1067 1507 { 1068 /* Use the saved page list. */ 1069 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs); 1070 AssertReleaseRC(rc); 1508 if (pGuestParm->type != VMMDevHGCMParmType_LinAddr_In) 1509 { 1510 /* Use the saved page list to write data back to the guest RAM. */ 1511 rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr, pCmd->paLinPtrs); 1512 AssertReleaseRC(rc); 1513 } 1514 1515 /* All linptrs with size > 0 were saved. Advance the index to the next linptr. */ 1516 iLinPtr++; 1071 1517 } 1072 1518 } break; … … 1179 1625 PVBOXHGCMCMD pNext = pIter->pNext; 1180 1626 1181 LogFlowFunc (("Saving %RGp\n", pIter->GCPhys)); 1627 LogFlowFunc (("Saving %RGp, size %d\n", pIter->GCPhys, pIter->cbSize)); 1628 1629 /* GC physical address of the guest request. */ 1182 1630 rc = SSMR3PutGCPhys(pSSM, pIter->GCPhys); 1183 1631 AssertRCReturn(rc, rc); 1184 1632 1633 /* Request packet size */ 1185 1634 rc = SSMR3PutU32(pSSM, pIter->cbSize); 1186 1635 AssertRCReturn(rc, rc); 1187 1636 1637 /* 1638 * Version 9+: save complete information about commands. 1639 */ 1640 1641 /* Size of entire command. */ 1642 rc = SSMR3PutU32(pSSM, pIter->cbCmd); 1643 AssertRCReturn(rc, rc); 1644 1645 /* The type of the command. */ 1646 rc = SSMR3PutU32(pSSM, (uint32_t)pIter->enmCmdType); 1647 AssertRCReturn(rc, rc); 1648 1649 /* Whether the command was cancelled by the guest. */ 1650 rc = SSMR3PutBool(pSSM, pIter->fCancelled); 1651 AssertRCReturn(rc, rc); 1652 1653 /* Linear pointer parameters information. How many pointers. Always 0 if not a call command. */ 1654 rc = SSMR3PutU32(pSSM, (uint32_t)pIter->cLinPtrs); 1655 AssertRCReturn(rc, rc); 1656 1657 if (pIter->cLinPtrs > 0) 1658 { 1659 /* How many pages for all linptrs in this command. */ 1660 rc = SSMR3PutU32(pSSM, (uint32_t)pIter->cLinPtrPages); 1661 AssertRCReturn(rc, rc); 1662 } 1663 1664 int i; 1665 for (i = 0; i < pIter->cLinPtrs; i++) 1666 { 1667 /* Pointer to descriptions of linear pointers. */ 1668 VBOXHGCMLINPTR *pLinPtr = &pIter->paLinPtrs[i]; 1669 1670 /* Index of the parameter. */ 1671 rc = SSMR3PutU32(pSSM, (uint32_t)pLinPtr->iParm); 1672 AssertRCReturn(rc, rc); 1673 1674 /* Offset in the first physical page of the region. */ 1675 rc = SSMR3PutU32(pSSM, pLinPtr->offFirstPage); 1676 AssertRCReturn(rc, rc); 1677 1678 /* How many pages. */ 1679 rc = SSMR3PutU32(pSSM, pLinPtr->cPages); 1680 AssertRCReturn(rc, rc); 1681 1682 uint32_t iPage; 1683 for (iPage = 0; iPage < pLinPtr->cPages; iPage++) 1684 { 1685 /* Array of the GC physical addresses for these pages. 1686 * It is assumed that the physical address of the locked resident 1687 * guest page does not change. 1688 */ 1689 rc = SSMR3PutGCPhys(pSSM, pLinPtr->paPages[iPage]); 1690 AssertRCReturn(rc, rc); 1691 } 1692 } 1693 1694 /* A reserved field, will allow to extend saved data for a command. */ 1695 rc = SSMR3PutU32(pSSM, 0); 1696 AssertRCReturn(rc, rc); 1697 1188 1698 vmmdevHGCMRemoveCommand (pVMMDevState, pIter); 1189 1699 … … 1192 1702 } 1193 1703 1704 /* A reserved field, will allow to extend saved data for VMMDevHGCM. */ 1705 rc = SSMR3PutU32(pSSM, 0); 1706 AssertRCReturn(rc, rc); 1707 1194 1708 return rc; 1195 1709 } 1196 1710 1197 1711 /* @thread EMT */ 1198 int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM )1712 int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM, uint32_t u32Version) 1199 1713 { 1200 1714 int rc = VINF_SUCCESS; … … 1209 1723 LogFlowFunc(("cCmds = %d\n", cCmds)); 1210 1724 1211 while (cCmds--) 1212 { 1213 RTGCPHYS GCPhys; 1214 uint32_t cbSize; 1215 1216 rc = SSMR3GetGCPhys(pSSM, &GCPhys); 1725 if ( SSM_VERSION_MAJOR(u32Version) == 0 1726 && SSM_VERSION_MINOR(u32Version) < 9) 1727 { 1728 /* Only the guest physical address is saved. */ 1729 while (cCmds--) 1730 { 1731 RTGCPHYS GCPhys; 1732 uint32_t cbSize; 1733 1734 rc = SSMR3GetGCPhys(pSSM, &GCPhys); 1735 AssertRCReturn(rc, rc); 1736 1737 rc = SSMR3GetU32(pSSM, &cbSize); 1738 AssertRCReturn(rc, rc); 1739 1740 LogFlowFunc (("Restoring %RGp size %x bytes\n", GCPhys, cbSize)); 1741 1742 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD)); 1743 AssertReturn(pCmd, VERR_NO_MEMORY); 1744 1745 vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, cbSize, VBOXHGCMCMDTYPE_LOADSTATE); 1746 } 1747 } 1748 else 1749 { 1750 /* 1751 * Version 9+: Load complete information about commands. 1752 */ 1753 uint32_t u32; 1754 bool f; 1755 1756 while (cCmds--) 1757 { 1758 RTGCPHYS GCPhys; 1759 uint32_t cbSize; 1760 1761 /* GC physical address of the guest request. */ 1762 rc = SSMR3GetGCPhys(pSSM, &GCPhys); 1763 AssertRCReturn(rc, rc); 1764 1765 /* The request packet size */ 1766 rc = SSMR3GetU32(pSSM, &cbSize); 1767 AssertRCReturn(rc, rc); 1768 1769 LogFlowFunc (("Restoring %RGp size %x bytes\n", GCPhys, cbSize)); 1770 1771 /* Size of entire command. */ 1772 rc = SSMR3GetU32(pSSM, &u32); 1773 AssertRCReturn(rc, rc); 1774 1775 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (u32); 1776 AssertReturn(pCmd, VERR_NO_MEMORY); 1777 pCmd->cbCmd = u32; 1778 1779 /* The type of the command. */ 1780 rc = SSMR3GetU32(pSSM, &u32); 1781 AssertRCReturn(rc, rc); 1782 pCmd->enmCmdType = (VBOXHGCMCMDTYPE)u32; 1783 1784 /* Whether the command was cancelled by the guest. */ 1785 rc = SSMR3GetBool(pSSM, &f); 1786 AssertRCReturn(rc, rc); 1787 pCmd->fCancelled = f; 1788 1789 /* Linear pointer parameters information. How many pointers. Always 0 if not a call command. */ 1790 rc = SSMR3GetU32(pSSM, &u32); 1791 AssertRCReturn(rc, rc); 1792 pCmd->cLinPtrs = u32; 1793 1794 if (pCmd->cLinPtrs > 0) 1795 { 1796 /* How many pages for all linptrs in this command. */ 1797 rc = SSMR3GetU32(pSSM, &u32); 1798 AssertRCReturn(rc, rc); 1799 pCmd->cLinPtrPages = u32; 1800 1801 pCmd->paLinPtrs = (VBOXHGCMLINPTR *)RTMemAllocZ ( sizeof (VBOXHGCMLINPTR) * pCmd->cLinPtrs 1802 + sizeof (RTGCPHYS) * pCmd->cLinPtrPages); 1803 AssertReturn(pCmd->paLinPtrs, VERR_NO_MEMORY); 1804 1805 RTGCPHYS *pPages = (RTGCPHYS *)((uint8_t *)pCmd->paLinPtrs + sizeof (VBOXHGCMLINPTR) * pCmd->cLinPtrs); 1806 int cPages = 0; 1807 1808 int i; 1809 for (i = 0; i < pCmd->cLinPtrs; i++) 1810 { 1811 /* Pointer to descriptions of linear pointers. */ 1812 VBOXHGCMLINPTR *pLinPtr = &pCmd->paLinPtrs[i]; 1813 1814 pLinPtr->paPages = pPages; 1815 1816 /* Index of the parameter. */ 1817 rc = SSMR3GetU32(pSSM, &u32); 1818 AssertRCReturn(rc, rc); 1819 pLinPtr->iParm = u32; 1820 1821 /* Offset in the first physical page of the region. */ 1822 rc = SSMR3GetU32(pSSM, &u32); 1823 AssertRCReturn(rc, rc); 1824 pLinPtr->offFirstPage = u32; 1825 1826 /* How many pages. */ 1827 rc = SSMR3GetU32(pSSM, &u32); 1828 AssertRCReturn(rc, rc); 1829 pLinPtr->cPages = u32; 1830 1831 uint32_t iPage; 1832 for (iPage = 0; iPage < pLinPtr->cPages; iPage++) 1833 { 1834 /* Array of the GC physical addresses for these pages. 1835 * It is assumed that the physical address of the locked resident 1836 * guest page does not change. 1837 */ 1838 RTGCPHYS GCPhysPage; 1839 rc = SSMR3GetGCPhys(pSSM, &GCPhysPage); 1840 AssertRCReturn(rc, rc); 1841 1842 /* Verify that the number of loaded pages is valid. */ 1843 cPages++; 1844 if (cPages > pCmd->cLinPtrPages) 1845 { 1846 LogRel(("VMMDevHGCM load state failure: cPages %d, expected %d, ptr %d/%d\n", 1847 cPages, pCmd->cLinPtrPages, i, pCmd->cLinPtrs)); 1848 return VERR_SSM_UNEXPECTED_DATA; 1849 } 1850 1851 *pPages++ = GCPhysPage; 1852 } 1853 } 1854 } 1855 1856 /* A reserved field, will allow to extend saved data for a command. */ 1857 rc = SSMR3GetU32(pSSM, &u32); 1858 AssertRCReturn(rc, rc); 1859 1860 vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, cbSize, VBOXHGCMCMDTYPE_LOADSTATE); 1861 } 1862 1863 /* A reserved field, will allow to extend saved data for VMMDevHGCM. */ 1864 rc = SSMR3GetU32(pSSM, &u32); 1217 1865 AssertRCReturn(rc, rc); 1218 1219 rc = SSMR3GetU32(pSSM, &cbSize);1220 AssertRCReturn(rc, rc);1221 1222 LogFlowFunc (("Restoring %RGp size %x bytes\n", GCPhys, cbSize));1223 1224 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)RTMemAllocZ (sizeof (struct VBOXHGCMCMD));1225 AssertReturn(pCmd, VERR_NO_MEMORY);1226 1227 vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPhys, cbSize, VBOXHGCMCMDTYPE_LOADSTATE);1228 1866 } 1229 1867 … … 1243 1881 if (RT_SUCCESS (rc)) 1244 1882 { 1883 /* Start from the current list head and commands loaded from saved state. 1884 * New commands will be inserted at the list head, so they will not be seen by 1885 * this loop. 1886 */ 1245 1887 PVBOXHGCMCMD pIter = pVMMDevState->pHGCMCmdList; 1246 1888 1247 1889 while (pIter) 1248 1890 { 1891 /* This will remove the command from the list if resubmitting fails. */ 1892 bool fHGCMCalled = false; 1893 1249 1894 LogFlowFunc (("pIter %p\n", pIter)); 1250 1895 1251 1896 PVBOXHGCMCMD pNext = pIter->pNext; 1252 1897 1253 VMMDev RequestHeader *requestHeader = (VMMDevRequestHeader *)RTMemAllocZ (pIter->cbSize);1898 VMMDevHGCMRequestHeader *requestHeader = (VMMDevHGCMRequestHeader *)RTMemAllocZ (pIter->cbSize); 1254 1899 Assert(requestHeader); 1255 1900 if (requestHeader == NULL) 1256 1901 return VERR_NO_MEMORY; 1257 1902 1258 PDMDevHlpPhysRead(pDevIns, (RTGCPHYS)pIter->GCPhys, requestHeader, pIter->cbSize);1903 PDMDevHlpPhysRead(pDevIns, pIter->GCPhys, requestHeader, pIter->cbSize); 1259 1904 1260 1905 /* the structure size must be greater or equal to the header size */ 1261 if (requestHeader-> size < sizeof(VMMDevRequestHeader))1906 if (requestHeader->header.size < sizeof(VMMDevHGCMRequestHeader)) 1262 1907 { 1263 Log(("VMMDev request header size too small! size = %d\n", requestHeader-> size));1908 Log(("VMMDev request header size too small! size = %d\n", requestHeader->header.size)); 1264 1909 } 1265 1910 else 1266 1911 { 1267 1912 /* check the version of the header structure */ 1268 if (requestHeader-> version != VMMDEV_REQUEST_HEADER_VERSION)1913 if (requestHeader->header.version != VMMDEV_REQUEST_HEADER_VERSION) 1269 1914 { 1270 Log(("VMMDev: guest header version (0x%08X) differs from ours (0x%08X)\n", requestHeader-> version, VMMDEV_REQUEST_HEADER_VERSION));1915 Log(("VMMDev: guest header version (0x%08X) differs from ours (0x%08X)\n", requestHeader->header.version, VMMDEV_REQUEST_HEADER_VERSION)); 1271 1916 } 1272 1917 else 1273 1918 { 1274 Log(("VMMDev request issued: %d\n", requestHeader->requestType)); 1275 1276 switch (requestHeader->requestType) 1919 Log(("VMMDev request issued: %d, command type %d\n", requestHeader->header.requestType, pIter->enmCmdType)); 1920 1921 /* Use the saved command type. Even if the guest has changed the memory already, 1922 * HGCM should see the same command as it was before saving state. 1923 */ 1924 switch (pIter->enmCmdType) 1277 1925 { 1278 case V MMDevReq_HGCMConnect:1926 case VBOXHGCMCMDTYPE_CONNECT: 1279 1927 { 1280 if (requestHeader-> size < sizeof(VMMDevHGCMConnect))1928 if (requestHeader->header.size < sizeof(VMMDevHGCMConnect)) 1281 1929 { 1282 1930 AssertMsgFailed(("VMMDevReq_HGCMConnect structure has invalid size!\n")); 1283 requestHeader-> rc = VERR_INVALID_PARAMETER;1931 requestHeader->header.rc = VERR_INVALID_PARAMETER; 1284 1932 } 1285 1933 else if (!pVMMDevState->pHGCMDrv) 1286 1934 { 1287 1935 Log(("VMMDevReq_HGCMConnect HGCM Connector is NULL!\n")); 1288 requestHeader-> rc = VERR_NOT_SUPPORTED;1936 requestHeader->header.rc = VERR_NOT_SUPPORTED; 1289 1937 } 1290 1938 else … … 1294 1942 Log(("VMMDevReq_HGCMConnect\n")); 1295 1943 1296 requestHeader-> rc = vmmdevHGCMConnect (pVMMDevState, pHGCMConnect, pIter->GCPhys);1944 requestHeader->header.rc = vmmdevHGCMConnectSaved (pVMMDevState, pHGCMConnect, &fHGCMCalled, pIter); 1297 1945 } 1298 1946 break; 1299 1947 } 1300 1948 1301 case V MMDevReq_HGCMDisconnect:1949 case VBOXHGCMCMDTYPE_DISCONNECT: 1302 1950 { 1303 if (requestHeader-> size < sizeof(VMMDevHGCMDisconnect))1951 if (requestHeader->header.size < sizeof(VMMDevHGCMDisconnect)) 1304 1952 { 1305 1953 AssertMsgFailed(("VMMDevReq_HGCMDisconnect structure has invalid size!\n")); 1306 requestHeader-> rc = VERR_INVALID_PARAMETER;1954 requestHeader->header.rc = VERR_INVALID_PARAMETER; 1307 1955 } 1308 1956 else if (!pVMMDevState->pHGCMDrv) 1309 1957 { 1310 1958 Log(("VMMDevReq_HGCMDisconnect HGCM Connector is NULL!\n")); 1311 requestHeader-> rc = VERR_NOT_SUPPORTED;1959 requestHeader->header.rc = VERR_NOT_SUPPORTED; 1312 1960 } 1313 1961 else … … 1316 1964 1317 1965 Log(("VMMDevReq_VMMDevHGCMDisconnect\n")); 1318 requestHeader-> rc = vmmdevHGCMDisconnect (pVMMDevState, pHGCMDisconnect, pIter->GCPhys);1966 requestHeader->header.rc = vmmdevHGCMDisconnectSaved (pVMMDevState, pHGCMDisconnect, &fHGCMCalled, pIter); 1319 1967 } 1320 1968 break; 1321 1969 } 1322 1970 1323 #ifdef VBOX_WITH_64_BITS_GUESTS 1324 case VMMDevReq_HGCMCall64: 1325 case VMMDevReq_HGCMCall32: 1326 #else 1327 case VMMDevReq_HGCMCall: 1328 #endif /* VBOX_WITH_64_BITS_GUESTS */ 1971 case VBOXHGCMCMDTYPE_CALL: 1329 1972 { 1330 if (requestHeader-> size < sizeof(VMMDevHGCMCall))1973 if (requestHeader->header.size < sizeof(VMMDevHGCMCall)) 1331 1974 { 1332 1975 AssertMsgFailed(("VMMDevReq_HGCMCall structure has invalid size!\n")); 1333 requestHeader-> rc = VERR_INVALID_PARAMETER;1976 requestHeader->header.rc = VERR_INVALID_PARAMETER; 1334 1977 } 1335 1978 else if (!pVMMDevState->pHGCMDrv) 1336 1979 { 1337 1980 Log(("VMMDevReq_HGCMCall HGCM Connector is NULL!\n")); 1338 requestHeader-> rc = VERR_NOT_SUPPORTED;1981 requestHeader->header.rc = VERR_NOT_SUPPORTED; 1339 1982 } 1340 1983 else … … 1344 1987 Log(("VMMDevReq_HGCMCall: sizeof (VMMDevHGCMRequest) = %04X\n", sizeof (VMMDevHGCMCall))); 1345 1988 1346 Log(("%.*Rhxd\n", requestHeader-> size, requestHeader));1989 Log(("%.*Rhxd\n", requestHeader->header.size, requestHeader)); 1347 1990 1348 1991 #ifdef VBOX_WITH_64_BITS_GUESTS 1349 bool f64Bits = (requestHeader-> requestType == VMMDevReq_HGCMCall64);1992 bool f64Bits = (requestHeader->header.requestType == VMMDevReq_HGCMCall64); 1350 1993 #else 1351 1994 bool f64Bits = false; 1352 1995 #endif /* VBOX_WITH_64_BITS_GUESTS */ 1353 requestHeader-> rc = vmmdevHGCMCall (pVMMDevState, pHGCMCall, pIter->GCPhys, f64Bits);1996 requestHeader->header.rc = vmmdevHGCMCallSaved (pVMMDevState, pHGCMCall, f64Bits, &fHGCMCalled, pIter); 1354 1997 } 1355 1998 break; 1356 1999 } 2000 case VBOXHGCMCMDTYPE_LOADSTATE: 2001 { 2002 /* Old saved state. */ 2003 switch (requestHeader->header.requestType) 2004 { 2005 case VMMDevReq_HGCMConnect: 2006 { 2007 if (requestHeader->header.size < sizeof(VMMDevHGCMConnect)) 2008 { 2009 AssertMsgFailed(("VMMDevReq_HGCMConnect structure has invalid size!\n")); 2010 requestHeader->header.rc = VERR_INVALID_PARAMETER; 2011 } 2012 else if (!pVMMDevState->pHGCMDrv) 2013 { 2014 Log(("VMMDevReq_HGCMConnect HGCM Connector is NULL!\n")); 2015 requestHeader->header.rc = VERR_NOT_SUPPORTED; 2016 } 2017 else 2018 { 2019 VMMDevHGCMConnect *pHGCMConnect = (VMMDevHGCMConnect *)requestHeader; 2020 2021 Log(("VMMDevReq_HGCMConnect\n")); 2022 2023 requestHeader->header.rc = vmmdevHGCMConnect (pVMMDevState, pHGCMConnect, pIter->GCPhys); 2024 } 2025 break; 2026 } 2027 2028 case VMMDevReq_HGCMDisconnect: 2029 { 2030 if (requestHeader->header.size < sizeof(VMMDevHGCMDisconnect)) 2031 { 2032 AssertMsgFailed(("VMMDevReq_HGCMDisconnect structure has invalid size!\n")); 2033 requestHeader->header.rc = VERR_INVALID_PARAMETER; 2034 } 2035 else if (!pVMMDevState->pHGCMDrv) 2036 { 2037 Log(("VMMDevReq_HGCMDisconnect HGCM Connector is NULL!\n")); 2038 requestHeader->header.rc = VERR_NOT_SUPPORTED; 2039 } 2040 else 2041 { 2042 VMMDevHGCMDisconnect *pHGCMDisconnect = (VMMDevHGCMDisconnect *)requestHeader; 2043 2044 Log(("VMMDevReq_VMMDevHGCMDisconnect\n")); 2045 requestHeader->header.rc = vmmdevHGCMDisconnect (pVMMDevState, pHGCMDisconnect, pIter->GCPhys); 2046 } 2047 break; 2048 } 2049 2050 #ifdef VBOX_WITH_64_BITS_GUESTS 2051 case VMMDevReq_HGCMCall64: 2052 case VMMDevReq_HGCMCall32: 2053 #else 2054 case VMMDevReq_HGCMCall: 2055 #endif /* VBOX_WITH_64_BITS_GUESTS */ 2056 { 2057 if (requestHeader->header.size < sizeof(VMMDevHGCMCall)) 2058 { 2059 AssertMsgFailed(("VMMDevReq_HGCMCall structure has invalid size!\n")); 2060 requestHeader->header.rc = VERR_INVALID_PARAMETER; 2061 } 2062 else if (!pVMMDevState->pHGCMDrv) 2063 { 2064 Log(("VMMDevReq_HGCMCall HGCM Connector is NULL!\n")); 2065 requestHeader->header.rc = VERR_NOT_SUPPORTED; 2066 } 2067 else 2068 { 2069 VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)requestHeader; 2070 2071 Log(("VMMDevReq_HGCMCall: sizeof (VMMDevHGCMRequest) = %04X\n", sizeof (VMMDevHGCMCall))); 2072 2073 Log(("%.*Rhxd\n", requestHeader->header.size, requestHeader)); 2074 2075 #ifdef VBOX_WITH_64_BITS_GUESTS 2076 bool f64Bits = (requestHeader->header.requestType == VMMDevReq_HGCMCall64); 2077 #else 2078 bool f64Bits = false; 2079 #endif /* VBOX_WITH_64_BITS_GUESTS */ 2080 requestHeader->header.rc = vmmdevHGCMCall (pVMMDevState, pHGCMCall, pIter->GCPhys, f64Bits); 2081 } 2082 break; 2083 } 2084 default: 2085 AssertMsgFailed(("Unknown request type %x during LoadState\n", requestHeader->header.requestType)); 2086 LogRel(("VMMDEV: Ignoring unknown request type %x during LoadState\n", requestHeader->header.requestType)); 2087 } 2088 } break; 2089 1357 2090 default: 1358 AssertMsgFailed(("Unknown request type %x during LoadState\n", requestHeader-> requestType));1359 LogRel(("VMMDEV: Ignoring unknown request type %x during LoadState\n", requestHeader-> requestType));2091 AssertMsgFailed(("Unknown request type %x during LoadState\n", requestHeader->header.requestType)); 2092 LogRel(("VMMDEV: Ignoring unknown request type %x during LoadState\n", requestHeader->header.requestType)); 1360 2093 } 1361 2094 } 1362 2095 } 1363 2096 1364 /* Write back the request */ 1365 PDMDevHlpPhysWrite(pDevIns, pIter->GCPhys, requestHeader, pIter->cbSize); 1366 RTMemFree(requestHeader); 1367 1368 vmmdevHGCMRemoveCommand (pVMMDevState, pIter); 1369 RTMemFree(pIter); 2097 if (pIter->enmCmdType == VBOXHGCMCMDTYPE_LOADSTATE) 2098 { 2099 /* Old saved state. Remove the LOADSTATE command. */ 2100 2101 /* Write back the request */ 2102 PDMDevHlpPhysWrite(pDevIns, pIter->GCPhys, requestHeader, pIter->cbSize); 2103 RTMemFree(requestHeader); 2104 requestHeader = NULL; 2105 2106 vmmdevHGCMRemoveCommand (pVMMDevState, pIter); 2107 2108 if (pIter->paLinPtrs != NULL) 2109 { 2110 RTMemFree(pIter->paLinPtrs); 2111 } 2112 2113 RTMemFree(pIter); 2114 } 2115 else 2116 { 2117 if (!fHGCMCalled) 2118 { 2119 /* HGCM was not called. Return the error to the guest. Guest may try to repeat the call. */ 2120 requestHeader->header.rc = VERR_TRY_AGAIN; 2121 requestHeader->fu32Flags |= VBOX_HGCM_REQ_DONE; 2122 } 2123 2124 /* Write back the request */ 2125 PDMDevHlpPhysWrite(pDevIns, pIter->GCPhys, requestHeader, pIter->cbSize); 2126 RTMemFree(requestHeader); 2127 requestHeader = NULL; 2128 2129 if (!fHGCMCalled) 2130 { 2131 /* HGCM was not called. Deallocate the current command and then notify guest. */ 2132 vmmdevHGCMRemoveCommand (pVMMDevState, pIter); 2133 2134 if (pIter->paLinPtrs != NULL) 2135 { 2136 RTMemFree(pIter->paLinPtrs); 2137 } 2138 2139 RTMemFree(pIter); 2140 2141 VMMDevNotifyGuest (pVMMDevState, VMMDEV_EVENT_HGCM); 2142 } 2143 } 2144 1370 2145 pIter = pNext; 1371 2146 } -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.h
r20374 r20731 39 39 40 40 int vmmdevHGCMSaveState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM); 41 int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM );41 int vmmdevHGCMLoadState(VMMDevState *pVMMDevState, PSSMHANDLE pSSM, uint32_t u32Version); 42 42 int vmmdevHGCMLoadStateDone(VMMDevState *pVMMDevState, PSSMHANDLE pSSM); 43 43 RT_C_DECLS_END
Note:
See TracChangeset
for help on using the changeset viewer.