Changeset 75548 in vbox
- Timestamp:
- Nov 18, 2018 4:52:14 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VMMDevCoreTypes.h
r72627 r75548 274 274 VMMDevHGCMParmType_LinAddr_Locked_Out = 9, /**< Locked Out (write; host->guest) */ 275 275 VMMDevHGCMParmType_PageList = 10, /**< Physical addresses of locked pages for a buffer. */ 276 VMMDevHGCMParmType_Embedded = 11, /**< Small buffer embedded in request. */ 276 277 VMMDevHGCMParmType_SizeHack = 0x7fffffff 277 278 } HGCMFunctionParameterType; … … 304 305 struct 305 306 { 306 uint32_t size; /**< Size of the buffer described by the page list. */307 uint32_t offset; /**< Relative to the request header, valid if size != 0. */307 uint32_t size; /**< Size of the buffer described by the page list. */ 308 uint32_t offset; /**< Relative to the request header of a HGCMPageListInfo structure, valid if size != 0. */ 308 309 } PageList; 310 struct 311 { 312 uint32_t fFlags : 8; /**< VBOX_HGCM_F_PARM_*. */ 313 uint32_t offData : 24; /**< Relative to the request header, valid if cb != 0. */ 314 uint32_t cbData; /**< The buffer size. */ 315 } Embedded; 309 316 } u; 310 317 # ifdef __cplusplus … … 380 387 uint32_t offset; /**< Relative to the request header, valid if size != 0. */ 381 388 } PageList; 389 struct 390 { 391 uint32_t fFlags : 8; /**< VBOX_HGCM_F_PARM_*. */ 392 uint32_t offData : 24; /**< Relative to the request header, valid if cb != 0. */ 393 uint32_t cbData; /**< The buffer size. */ 394 } Embedded; 382 395 } u; 383 396 # ifdef __cplusplus … … 468 481 uint32_t offset; /**< Relative to the request header, valid if size != 0. */ 469 482 } PageList; 483 struct 484 { 485 uint32_t fFlags : 8; /**< VBOX_HGCM_F_PARM_*. */ 486 uint32_t offData : 24; /**< Relative to the request header (must be a valid offset even if cbData is zero). */ 487 uint32_t cbData; /**< The buffer size. */ 488 } Embedded; 470 489 } u; 471 490 # ifdef __cplusplus -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibHGCMInternal.cpp
r75126 r75548 56 56 /** The max parameter buffer size for a kernel request. */ 57 57 #define VBGLR0_MAX_HGCM_KERNEL_PARM (16*_1M) 58 /** The max embedded buffer size. */ 59 #define VBGLR0_MAX_HGCM_EMBEDDED_BUFFER _64K 60 58 61 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) 59 62 /** Linux needs to use bounce buffers since RTR0MemObjLockUser has unwanted … … 258 261 Log4(("GstHGCMCall: parm=%u type=pglst: cb=0\n", iParm)); 259 262 break; 263 264 case VMMDevHGCMParmType_Embedded: 265 if (fIsUser) /// @todo relax this. 266 return VERR_INVALID_PARAMETER; 267 cb = pSrcParm->u.Embedded.cbData; 268 if (cb) 269 { 270 uint32_t off = pSrcParm->u.Embedded.offData; 271 AssertMsgReturn(cb <= VBGLR0_MAX_HGCM_EMBEDDED_BUFFER, ("%#x > %#x\n", cb, VBGLR0_MAX_HGCM_EMBEDDED_BUFFER), 272 VERR_INVALID_PARAMETER); 273 AssertMsgReturn(cb <= cbCallInfo - cParms * sizeof(HGCMFunctionParameter), 274 ("cb=%#x cParms=%#x cbCallInfo=%3x\n", cb, cParms, cbCallInfo), 275 VERR_INVALID_PARAMETER); 276 AssertMsgReturn( off >= cParms * sizeof(HGCMFunctionParameter) 277 && off <= cbCallInfo - cb, 278 ("offData=%#x cParms=%#x cbCallInfo=%#x\n", off, cParms, cbCallInfo), 279 VERR_INVALID_PARAMETER); 280 AssertMsgReturn(VBOX_HGCM_F_PARM_ARE_VALID(pSrcParm->u.Embedded.fFlags), 281 ("%#x\n", pSrcParm->u.Embedded.fFlags), VERR_INVALID_PARAMETER); 282 283 *pcbExtra += RT_ALIGN_32(cb, 8); 284 } 285 else 286 Log4(("GstHGCMCall: parm=%u type=embed: cb=0\n", iParm)); 287 break; 288 260 289 261 290 case VMMDevHGCMParmType_LinAddr_Locked_In: … … 543 572 } 544 573 else 545 pDstParm->u.PageList.offset = 0; 546 break; 574 pDstParm->u.PageList.offset = 0; /** @todo will fail on the host side now */ 575 break; 576 577 case VMMDevHGCMParmType_Embedded: 578 { 579 uint32_t const cb = pSrcParm->u.Embedded.cbData; 580 pDstParm->type = VMMDevHGCMParmType_Embedded; 581 pDstParm->u.Embedded.cbData = cb; 582 pDstParm->u.Embedded.offData = offExtra; 583 if (cb > 0) 584 { 585 uint8_t *pbDst = (uint8_t *)pHGCMCall + offExtra; 586 if (pSrcParm->u.Embedded.fFlags & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST) 587 { 588 memcpy(pbDst, (uint8_t const *)pCallInfo + pSrcParm->u.Embedded.offData, cb); 589 if (RT_ALIGN(cb, 8) != cb) 590 memset(pbDst + cb, 0, RT_ALIGN(cb, 8) - cb); 591 } 592 else 593 RT_BZERO(pbDst, RT_ALIGN(cb, 8)); 594 offExtra += RT_ALIGN(cb, 8); 595 } 596 break; 597 } 547 598 548 599 case VMMDevHGCMParmType_LinAddr_Locked_In: … … 762 813 * @returns rc, unless RTR0MemUserCopyTo fails. 763 814 * @param pCallInfo Call info structure to update. 815 * @param cbCallInfo The size of the client request. 764 816 * @param pHGCMCall HGCM call request. 817 * @param cbHGCMCall The size of the HGCM call request. 765 818 * @param pParmInfo Parameter locking/buffering info. 766 819 * @param fIsUser Is it a user (true) or kernel request. … … 768 821 * preserve informational status codes. 769 822 */ 770 static int vbglR0HGCMInternalCopyBackResult(PVBGLIOCHGCMCALL pCallInfo, VMMDevHGCMCall const *pHGCMCall, 823 static int vbglR0HGCMInternalCopyBackResult(PVBGLIOCHGCMCALL pCallInfo, uint32_t cbCallInfo, 824 VMMDevHGCMCall const *pHGCMCall, uint32_t cbHGCMCall, 771 825 struct VbglR0ParmInfo *pParmInfo, bool fIsUser, int rc) 772 826 { … … 791 845 * Copy back parameters. 792 846 */ 847 /** @todo This is assuming user data (pDstParm) is buffered. Not true 848 * on OS/2, though I'm not sure we care... */ 793 849 for (iParm = 0; iParm < cParms; iParm++, pSrcParm++, pDstParm++) 794 850 { … … 803 859 pDstParm->u.PageList.size = pSrcParm->u.PageList.size; 804 860 break; 861 862 case VMMDevHGCMParmType_Embedded: 863 { 864 uint32_t cb; 865 pDstParm->u.Embedded.cbData = cb = pSrcParm->u.Embedded.cbData; 866 if ( cb > 0 867 && (pDstParm->u.Embedded.fFlags & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST)) 868 { 869 uint32_t const offDst = pDstParm->u.Embedded.offData; 870 uint32_t const offSrc = pDstParm->u.Embedded.offData; 871 AssertReturn(offDst < cbCallInfo, VERR_INTERNAL_ERROR_2); 872 AssertReturn(offDst >= sizeof(*pCallInfo) + cParms * sizeof(*pDstParm), VERR_INTERNAL_ERROR_2); 873 AssertReturn(cb <= cbCallInfo - offDst , VERR_INTERNAL_ERROR_2); 874 AssertReturn(offSrc < cbCallInfo, VERR_INTERNAL_ERROR_2); 875 AssertReturn(offSrc >= sizeof(*pHGCMCall) + cParms * sizeof(*pSrcParm), VERR_INTERNAL_ERROR_2); 876 AssertReturn(cb <= cbHGCMCall - offSrc, VERR_INTERNAL_ERROR_2); 877 878 memcpy((uint8_t *)pCallInfo + offDst, (uint8_t const *)pHGCMCall + offSrc, cb); 879 } 880 break; 881 } 805 882 806 883 case VMMDevHGCMParmType_LinAddr_Locked_In: … … 902 979 */ 903 980 VMMDevHGCMCall *pHGCMCall; 904 rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pHGCMCall, 905 sizeof(VMMDevHGCMCall) + pCallInfo->cParms * sizeof(HGCMFunctionParameter) + cbExtra, 906 VMMDevReq_HGCMCall); 981 uint32_t const cbHGCMCall = sizeof(VMMDevHGCMCall) + pCallInfo->cParms * sizeof(HGCMFunctionParameter) + cbExtra; 982 rc = VbglR0GRAlloc((VMMDevRequestHeader **)&pHGCMCall, cbHGCMCall, VMMDevReq_HGCMCall); 907 983 if (RT_SUCCESS(rc)) 908 984 { … … 919 995 * Copy back the result (parameters and buffers that changed). 920 996 */ 921 rc = vbglR0HGCMInternalCopyBackResult(pCallInfo, pHGCMCall, &ParmInfo, fIsUser, rc);997 rc = vbglR0HGCMInternalCopyBackResult(pCallInfo, cbCallInfo, pHGCMCall, cbHGCMCall, &ParmInfo, fIsUser, rc); 922 998 } 923 999 else -
trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
r75538 r75548 621 621 * @param pThis The VMMDev instance data. 622 622 * @param pCmd Command structure where host parameters needs initialization. 623 */ 624 static int vmmdevHGCMInitHostParameters(PVMMDEV pThis, PVBOXHGCMCMD pCmd) 623 * @param pbReq The request buffer. 624 */ 625 static int vmmdevHGCMInitHostParameters(PVMMDEV pThis, PVBOXHGCMCMD pCmd, uint8_t const *pbReq) 625 626 { 626 627 AssertReturn(pCmd->enmCmdType == VBOXHGCMCMDTYPE_CALL, VERR_INTERNAL_ERROR); … … 653 654 case VMMDevHGCMParmType_LinAddr: 654 655 case VMMDevHGCMParmType_PageList: 656 case VMMDevHGCMParmType_Embedded: 655 657 { 656 658 const uint32_t cbData = pGuestParm->u.ptr.cbData; … … 668 670 if (pGuestParm->u.ptr.fu32Direction & VBOX_HGCM_F_PARM_DIRECTION_TO_HOST) 669 671 { 670 int rc = vmmdevHGCMGuestBufferRead(pThis->pDevIns, pv, cbData, &pGuestParm->u.ptr); 671 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc); 672 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 672 if (pGuestParm->enmType != VMMDevHGCMParmType_Embedded) 673 { 674 int rc = vmmdevHGCMGuestBufferRead(pThis->pDevIns, pv, cbData, &pGuestParm->u.ptr); 675 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc); 676 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 677 } 678 else 679 { 680 memcpy(pv, &pbReq[pGuestParm->u.ptr.offFirstPage], cbData); 681 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 682 } 673 683 } 674 684 } … … 889 899 cbTotalData += cbData; 890 900 901 /** @todo respect zero byte page lists... */ 891 902 /* Check that the page list info is within the request. */ 892 903 ASSERT_GUEST_RETURN( offPageListInfo >= offExtra … … 935 946 } 936 947 948 case VMMDevHGCMParmType_Embedded: 949 { 950 #ifdef VBOX_WITH_64_BITS_GUESTS 951 AssertCompileMembersSameSizeAndOffset(HGCMFunctionParameter64, u.Embedded.cbData, HGCMFunctionParameter32, u.Embedded.cbData); 952 uint32_t const cbData = ((HGCMFunctionParameter64 *)pu8HGCMParm)->u.Embedded.cbData; 953 uint32_t const offData = ((HGCMFunctionParameter64 *)pu8HGCMParm)->u.Embedded.offData; 954 uint32_t const fFlags = ((HGCMFunctionParameter64 *)pu8HGCMParm)->u.Embedded.fFlags; 955 #else 956 uint32_t const cbData = ((HGCMFunctionParameter *)pu8HGCMParm)->u.Embedded.cbData; 957 uint32_t const offData = ((HGCMFunctionParameter *)pu8HGCMParm)->u.Embedded.offData; 958 uint32_t const fFlags = ((HGCMFunctionParameter *)pu8HGCMParm)->u.Embedded.fFlags; 959 #endif 960 LogFunc(("Embedded guest parameter cb %u, offset %u, flags %#x\n", cbData, offData, fFlags)); 961 962 ASSERT_GUEST_RETURN(cbData <= VMMDEV_MAX_HGCM_DATA_SIZE - cbTotalData, VERR_INVALID_PARAMETER); 963 cbTotalData += cbData; 964 965 /* Check flags and buffer range. */ 966 ASSERT_GUEST_MSG_RETURN(VBOX_HGCM_F_PARM_ARE_VALID(fFlags), ("%#x\n", fFlags), VERR_INVALID_FLAGS); 967 ASSERT_GUEST_MSG_RETURN( offData >= offExtra 968 && offData <= cbHGCMCall 969 && cbData <= cbHGCMCall - offData, 970 ("offData=%#x cbData=%#x cbHGCMCall=%#x offExtra=%#x\n", offData, cbData, cbHGCMCall, offExtra), 971 VERR_INVALID_PARAMETER); 972 RT_UNTRUSTED_VALIDATED_FENCE(); 973 974 /* We use part of the ptr member. */ 975 pGuestParm->u.ptr.fu32Direction = fFlags; 976 pGuestParm->u.ptr.cbData = cbData; 977 pGuestParm->u.ptr.offFirstPage = offData; 978 pGuestParm->u.ptr.GCPhysSinglePage = pCmd->GCPhys + offData; 979 pGuestParm->u.ptr.cPages = 1; 980 pGuestParm->u.ptr.paPages = &pGuestParm->u.ptr.GCPhysSinglePage; 981 break; 982 } 983 937 984 default: 938 985 ASSERT_GUEST_FAILED_RETURN(VERR_INVALID_PARAMETER); … … 995 1042 { 996 1043 /* Copy guest data to host parameters, so HGCM services can use the data. */ 997 rc = vmmdevHGCMInitHostParameters(pThis, pCmd );1044 rc = vmmdevHGCMInitHostParameters(pThis, pCmd, (uint8_t const *)pHGCMCall); 998 1045 if (RT_SUCCESS(rc)) 999 1046 { … … 1003 1050 vmmdevHGCMAddCommand(pThis, pCmd); 1004 1051 1052 #if 1 1053 if ( pCmd->u.call.u32Function == 9 1054 && pCmd->u.call.cParms == 5) 1055 { 1056 vmmdevHGCMRemoveCommand(pThis, pCmd); 1057 1058 if (pCmd->pvReqLocked) 1059 { 1060 VMMDevHGCMRequestHeader volatile *pHeader = (VMMDevHGCMRequestHeader volatile *)pCmd->pvReqLocked; 1061 pHeader->header.rc = VINF_SUCCESS; 1062 pHeader->result = VINF_SUCCESS; 1063 pHeader->fu32Flags |= VBOX_HGCM_REQ_DONE; 1064 } 1065 else 1066 { 1067 VMMDevHGCMRequestHeader *pHeader = (VMMDevHGCMRequestHeader *)pHGCMCall; 1068 pHeader->header.rc = VINF_SUCCESS; 1069 pHeader->result = VINF_SUCCESS; 1070 pHeader->fu32Flags |= VBOX_HGCM_REQ_DONE; 1071 PDMDevHlpPhysWrite(pThis->pDevIns, GCPhys, pHeader, sizeof(*pHeader)); 1072 } 1073 vmmdevHGCMCmdFree(pThis, pCmd); 1074 return VINF_HGCM_ASYNC_EXECUTE; /* ignored, but avoids assertions. */ 1075 } 1076 #endif 1077 1005 1078 rc = pThis->pHGCMDrv->pfnCall(pThis->pHGCMDrv, pCmd, 1006 1079 pCmd->u.call.u32ClientID, pCmd->u.call.u32Function, 1007 1080 pCmd->u.call.cParms, pCmd->u.call.paHostParms, tsArrival); 1008 if (RT_SUCCESS(rc)) 1081 1082 if (rc == VINF_HGCM_ASYNC_EXECUTE) 1009 1083 { 1010 Assert(rc == VINF_HGCM_ASYNC_EXECUTE);1011 1012 1084 /* 1013 1085 * Done. Just update statistics and return. … … 1139 1211 uint32_t cbSrc = pHostParm->u.pointer.size; 1140 1212 rc = vmmdevHGCMGuestBufferWrite(pThis->pDevIns, pPtr, pvSrc, cbSrc); 1213 } 1214 break; 1215 } 1216 1217 case VMMDevHGCMParmType_Embedded: 1218 { 1219 const VBOXHGCMPARMPTR * const pPtr = &pGuestParm->u.ptr; 1220 if ( pPtr->cbData > 0 1221 && (pPtr->fu32Direction & VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST)) 1222 { 1223 const void *pvSrc = pHostParm->u.pointer.addr; 1224 uint32_t cbSrc = pHostParm->u.pointer.size; 1225 if (pCmd->pvReqLocked) 1226 memcpy((uint8_t *)pCmd->pvReqLocked + pPtr->offFirstPage, pvSrc, cbSrc); 1227 else 1228 rc = PDMDevHlpPhysWrite(pThis->pDevIns, pGuestParm->u.ptr.GCPhysSinglePage, pvSrc, cbSrc); 1141 1229 } 1142 1230 break; … … 1487 1575 || pGuestParm->enmType == VMMDevHGCMParmType_LinAddr_Out 1488 1576 || pGuestParm->enmType == VMMDevHGCMParmType_LinAddr 1489 || pGuestParm->enmType == VMMDevHGCMParmType_PageList) 1577 || pGuestParm->enmType == VMMDevHGCMParmType_PageList 1578 || pGuestParm->enmType == VMMDevHGCMParmType_Embedded) 1490 1579 { 1491 1580 const VBOXHGCMPARMPTR * const pPtr = &pGuestParm->u.ptr; … … 1619 1708 || pGuestParm->enmType == VMMDevHGCMParmType_LinAddr_Out 1620 1709 || pGuestParm->enmType == VMMDevHGCMParmType_LinAddr 1621 || pGuestParm->enmType == VMMDevHGCMParmType_PageList) 1710 || pGuestParm->enmType == VMMDevHGCMParmType_PageList 1711 || pGuestParm->enmType == VMMDevHGCMParmType_Embedded) 1622 1712 { 1623 1713 VBOXHGCMPARMPTR * const pPtr = &pGuestParm->u.ptr; … … 1628 1718 if (RT_SUCCESS(rc)) 1629 1719 { 1630 pPtr->paPages = (RTGCPHYS *)RTMemAlloc(pPtr->cPages * sizeof(RTGCPHYS)); 1631 AssertStmt(pPtr->paPages, rc = VERR_NO_MEMORY); 1720 if (pPtr->cPages == 1) 1721 pPtr->paPages = &pPtr->GCPhysSinglePage; 1722 else 1723 { 1724 AssertReturn(pGuestParm->enmType != VMMDevHGCMParmType_Embedded, VERR_INTERNAL_ERROR_3); 1725 pPtr->paPages = (RTGCPHYS *)RTMemAlloc(pPtr->cPages * sizeof(RTGCPHYS)); 1726 AssertStmt(pPtr->paPages, rc = VERR_NO_MEMORY); 1727 } 1632 1728 1633 1729 if (RT_SUCCESS(rc)) … … 2092 2188 case VBOXHGCMCMDTYPE_CALL: 2093 2189 { 2094 rcCmd = vmmdevHGCMInitHostParameters(pThis, pCmd );2190 rcCmd = vmmdevHGCMInitHostParameters(pThis, pCmd, (uint8_t const *)pReqHdr); 2095 2191 if (RT_SUCCESS(rcCmd)) 2096 2192 {
Note:
See TracChangeset
for help on using the changeset viewer.