Changeset 81300 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Oct 17, 2019 5:51:54 AM (5 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r81231 r81300 263 263 /* Device-readable section */ 264 264 265 struct REQ_CMD_HDR cmdHdr;265 struct REQ_CMD_HDR ReqHdr; 266 266 uint8_t uCdb[1]; /**< cdb */ 267 267 … … 550 550 PVIRTIOSCSITARGET pTarget; /**< Target */ 551 551 uint16_t qIdx; /**< Index of queue this request arrived on */ 552 uint32_t cbPiOut; /**< Size of T10 pi in buffer */ 553 uint8_t *pbPiOut; /**< Address of pi out buffer */ 554 uint8_t *pbDataOut; /**< dataout */ 552 PVIRTIO_DESC_CHAIN_T pDescChain; /**< Prepared desc chain pulled from virtq avail ring */ 553 uint32_t cbDataIn; /**< size of dataout buffer */ 555 554 uint32_t cbDataOut; /**< size of dataout buffer */ 556 uint32_t cbPiIn; /**< Size of T10 pi buffer */ 557 uint8_t *pbPiIn; /**< Address of pi in buffer */ 558 uint32_t cbDataIn; /**< Size of datain buffer */ 559 uint8_t *pbDataIn; /**< datain */ 555 uint16_t uDataInOff; /**< Fixed size of respHdr + sense (precede datain) */ 556 uint16_t uDataOutOff; /**< Fixed size of respHdr + sense (precede datain) */ 560 557 uint32_t cbSense; /**< Size of sense buffer */ 561 558 size_t uSenseLen; /**< Receives # bytes written into sense buffer */ … … 563 560 PDMMEDIAEXIOREQSCSITXDIR enmTxDir; /**< Receives transfer direction of I/O req */ 564 561 uint8_t uStatus; /**< SCSI status code */ 565 PVIRTIO_DESC_CHAIN_T pDescChain; /**< Prepared desc chain pulled from virtq avail ring */566 562 } VIRTIOSCSIREQ; 567 563 … … 687 683 } 688 684 #endif 689 690 /**691 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf}692 */693 static DECLCALLBACK(int) virtioScsiIoReqCopyFromBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,694 void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf, size_t cbCopy)695 {696 RT_NOREF2(hIoReq, pInterface);697 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;698 699 AssertReturn(pReq->pbDataIn700 && offDst + cbCopy <= pReq->cbDataIn701 && cbCopy <= pSgBuf->cbSegLeft, VERR_INVALID_PARAMETER);702 703 RTSgBufCopyToBuf(pSgBuf, pReq->pbDataIn + offDst, cbCopy);704 705 return VINF_SUCCESS;706 }707 708 /**709 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyToBuf}710 */711 static DECLCALLBACK(int) virtioScsiIoReqCopyToBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq,712 void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf, size_t cbCopy)713 {714 RT_NOREF2(hIoReq, pInterface);715 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc;716 717 AssertReturn(pReq->pbDataOut718 && offSrc + cbCopy <= pReq->cbDataOut719 && cbCopy <= pSgBuf->cbSegLeft, VERR_INVALID_PARAMETER);720 721 RTSgBufCopyFromBuf(pSgBuf, pReq->pbDataOut + offSrc, cbCopy);722 723 return VINF_SUCCESS;724 }725 685 726 686 static int virtioScsiSendEvent(PVIRTIOSCSI pThis, uint16_t uTarget, uint32_t uEventType, uint32_t uReason) … … 798 758 { 799 759 RTMemFree(pReq->pbSense); 800 RTMemFree(pReq->pbPiIn);801 RTMemFree(pReq->pbDataIn);802 760 pTarget->pDrvMediaEx->pfnIoReqFree(pTarget->pDrvMediaEx, pReq->hIoReq); 803 761 } … … 876 834 AssertRC(rc); 877 835 836 /* Masking used to deal with datatype size differences between APIs */ 878 837 Assert(!(cbXfer & 0xffffffff00000000)); 879 838 uint32_t cbXfer32 = cbXfer & 0xffffffff; 880 881 839 struct REQ_RESP_HDR respHdr = { 0 }; 882 840 respHdr.uSenseLen = pReq->pbSense[2] == SCSI_SENSE_NONE ? 0 : (uint32_t)pReq->uSenseLen; … … 972 930 { 973 931 LogFunc(("cbDataIn = %u, cbDataOut = %u (cbIn = %u, cbOut = %u)\n", 974 pReq->cbDataIn, pReq->cbDataOut, pReq->pDescChain->cbPhys Dst, pReq->pDescChain->cbVirtSrc));932 pReq->cbDataIn, pReq->cbDataOut, pReq->pDescChain->cbPhysReturn, pReq->pDescChain->cbPhysSend)); 975 933 LogFunc(("xfer = %lu, residual = %u\n", cbXfer, cbResidual)); 976 934 const char *pszTxDirText = virtioGetTxDirText(pReq->enmTxDir); … … 984 942 LogFunc(("Sense: %s\n", SCSISenseText(pReq->pbSense[2]))); 985 943 LogFunc(("Sense Ext3: %s\n", SCSISenseExtText(pReq->pbSense[12], pReq->pbSense[13]))); 986 }987 988 if (LogIs12Enabled())989 {990 uint32_t cb = RT_MIN(cbXfer32, 256);991 if (VIRTIO_IN_DIRECTION(pReq->enmTxDir))992 {993 if (!isBufZero(pReq->pbDataIn, cb))994 {995 Log(("datain[showing the first %d of %d total bytes xferred]:\n", cb, cbXfer32));996 VIRTIO_HEX_DUMP(RTLOGGRPFLAGS_LEVEL_12, pReq->pbDataIn, cb, 0, 0);997 }998 else999 Log12Func(("First %d bytes transfered in this req are 0 --\n", cb));1000 }1001 else1002 if (VIRTIO_OUT_DIRECTION(pReq->enmTxDir))1003 {1004 if (!isBufZero(pReq->pbDataOut, cb))1005 {1006 Log(("dataout[showing the first %d of %d total bytes xferred]:\n", cb, cbXfer32));1007 VIRTIO_HEX_DUMP(RTLOGGRPFLAGS_LEVEL_12, pReq->pbDataOut, cb, 0, 0);1008 }1009 else1010 Log12Func(("First %d bytes transfered in this req are 0 --\n", cb));1011 }1012 944 } 1013 945 … … 1032 964 Assert(pReq->pbSense != NULL); 1033 965 966 /* req datain bytes already in guest phys mem. via virtioScsiIoReqCopyFromBuf() */ 967 1034 968 RTSGSEG aReqSegs[4]; 1035 969 aReqSegs[cSegs].pvSeg = &respHdr; … … 1039 973 aReqSegs[cSegs++].cbSeg = pReq->cbSense; /* VirtIO 1.0 spec 5.6.4/5.6.6.1 */ 1040 974 1041 if (pReq->cbPiIn)1042 {1043 aReqSegs[cSegs].pvSeg = pReq->pbPiIn;1044 aReqSegs[cSegs++].cbSeg = pReq->cbPiIn;1045 }1046 if (pReq->cbDataIn)1047 {1048 aReqSegs[cSegs].pvSeg = pReq->pbDataIn;1049 aReqSegs[cSegs++].cbSeg = cbXfer;1050 }1051 975 RTSGBUF reqSegBuf; 1052 976 RTSgBufInit(&reqSegBuf, aReqSegs, cSegs); 1053 977 1054 978 size_t cbReqSgBuf = RTSgBufCalcTotalLength(&reqSegBuf); 1055 AssertMsgReturn(cbReqSgBuf <= pReq->pDescChain->cbPhys Dst,979 AssertMsgReturn(cbReqSgBuf <= pReq->pDescChain->cbPhysReturn, 1056 980 ("Guest expected less req data (space needed: %d, avail: %d)\n", 1057 cbReqSgBuf, pReq->pDescChain->cbPhys Dst),981 cbReqSgBuf, pReq->pDescChain->cbPhysReturn), 1058 982 VERR_BUFFER_OVERFLOW); 983 1059 984 1060 985 virtioQueuePut(pThis->hVirtio, pReq->qIdx, &reqSegBuf, pReq->pDescChain, true /* fFence TBD */); … … 1073 998 } 1074 999 1000 /** 1001 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyFromBuf} 1002 * 1003 * Copy virtual memory from VSCSI layer to guest physical memory 1004 */ 1005 static DECLCALLBACK(int) virtioScsiIoReqCopyFromBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 1006 void *pvIoReqAlloc, uint32_t offDst, PRTSGBUF pSgBuf, size_t cbCopy) 1007 { 1008 RT_NOREF(hIoReq, cbCopy); 1009 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1010 PVIRTIOSCSI pThis = pTarget->pVirtioScsi; 1011 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 1012 1013 AssertReturn(pReq->pDescChain, VERR_INVALID_PARAMETER); 1014 1015 if (!pReq->cbDataIn) 1016 return VINF_SUCCESS; 1017 1018 PRTSGBUF pSgPhysReturn = pReq->pDescChain->pSgPhysReturn; 1019 RTSgBufAdvance(pSgPhysReturn, offDst); 1020 1021 size_t cbCopied = 0; 1022 size_t cbRemain = pReq->cbDataIn; 1023 1024 if (!pSgPhysReturn->idxSeg && pSgPhysReturn->cbSegLeft == pSgPhysReturn->paSegs[0].cbSeg) 1025 { 1026 Log(("Do advance\n")); 1027 RTSgBufAdvance(pSgPhysReturn, pReq->uDataInOff); 1028 } 1029 1030 while (cbRemain) 1031 { 1032 PCRTSGSEG paSeg = &pSgPhysReturn->paSegs[pSgPhysReturn->idxSeg]; 1033 uint64_t dstSgStart = (uint64_t)paSeg->pvSeg; 1034 uint64_t dstSgLen = (uint64_t)paSeg->cbSeg; 1035 uint64_t dstSgCur = (uint64_t)pSgPhysReturn->pvSegCur; 1036 cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, dstSgLen - (dstSgCur - dstSgStart)); 1037 PDMDevHlpPhysWrite(pThis->CTX_SUFF(pDevIns), 1038 (RTGCPHYS)pSgPhysReturn->pvSegCur, pSgBuf->pvSegCur, cbCopied); 1039 RTSgBufAdvance(pSgBuf, cbCopied); 1040 RTSgBufAdvance(pSgPhysReturn, cbCopied); 1041 cbRemain -= cbCopied; 1042 } 1043 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); /* needed? */ 1044 1045 Log2Func((".... Copied %lu bytes from %lu byte guest buffer, residual=%lu\n", 1046 cbCopy, pReq->pDescChain->cbPhysReturn, pReq->pDescChain->cbPhysReturn - cbCopy)); 1047 1048 return VINF_SUCCESS; 1049 } 1050 1051 /** 1052 * @interface_method_impl{PDMIMEDIAEXPORT,pfnIoReqCopyToBuf} 1053 * 1054 * Copy guest physical memory to VSCSI layer virtual memory 1055 */ 1056 static DECLCALLBACK(int) virtioScsiIoReqCopyToBuf(PPDMIMEDIAEXPORT pInterface, PDMMEDIAEXIOREQ hIoReq, 1057 void *pvIoReqAlloc, uint32_t offSrc, PRTSGBUF pSgBuf, size_t cbCopy) 1058 { 1059 1060 RT_NOREF(hIoReq, cbCopy); 1061 PVIRTIOSCSITARGET pTarget = RT_FROM_MEMBER(pInterface, VIRTIOSCSITARGET, IMediaExPort); 1062 PVIRTIOSCSI pThis = pTarget->pVirtioScsi; 1063 PVIRTIOSCSIREQ pReq = (PVIRTIOSCSIREQ)pvIoReqAlloc; 1064 1065 if (!pReq->cbDataOut) 1066 return VINF_SUCCESS; 1067 1068 PRTSGBUF pSgPhysSend = pReq->pDescChain->pSgPhysSend; 1069 RTSgBufAdvance(pSgPhysSend, offSrc); 1070 1071 size_t cbCopied = 0; 1072 size_t cbRemain = pReq->cbDataOut; 1073 while (cbRemain) 1074 { 1075 PCRTSGSEG paSeg = &pSgPhysSend->paSegs[pSgPhysSend->idxSeg]; 1076 uint64_t srcSgStart = (uint64_t)paSeg->pvSeg; 1077 uint64_t srcSgLen = (uint64_t)paSeg->cbSeg; 1078 uint64_t srcSgCur = (uint64_t)pSgPhysSend->pvSegCur; 1079 cbCopied = RT_MIN((uint64_t)pSgBuf->cbSegLeft, srcSgLen - (srcSgCur - srcSgStart)); 1080 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 1081 (RTGCPHYS)pSgPhysSend->pvSegCur, pSgBuf->pvSegCur, cbCopied); 1082 RTSgBufAdvance(pSgBuf, cbCopied); 1083 RTSgBufAdvance(pSgPhysSend, cbCopied); 1084 cbRemain -= cbCopied; 1085 } 1086 1087 Log2Func((".... Copied %lu bytes to %lu byte guest buffer, residual=%lu\n", 1088 cbCopy, pReq->pDescChain->cbPhysReturn, pReq->pDescChain->cbPhysReturn - cbCopy)); 1089 1090 return VINF_SUCCESS; 1091 } 1092 1075 1093 static int virtioScsiReqSubmit(PVIRTIOSCSI pThis, uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1076 1094 { 1095 AssertReturn(pDescChain->cbPhysSend, VERR_INVALID_PARAMETER); 1096 1077 1097 ASMAtomicIncU32(&pThis->cActiveReqs); 1078 1098 1079 PVIRTIOSCSI_REQ_CMD_T pVirtqReq = (PVIRTIOSCSI_REQ_CMD_T)pDescChain->pVirtSrc; 1080 1081 uint8_t uTarget = pVirtqReq->cmdHdr.uVirtioLun[1]; 1082 uint32_t uScsiLun = (pVirtqReq->cmdHdr.uVirtioLun[2] << 8 | pVirtqReq->cmdHdr.uVirtioLun[3]) & 0x3fff; 1099 /* Extract command header and CDB from guest physical memory */ 1100 1101 uint16_t cbReqHdr = sizeof(struct REQ_CMD_HDR) + pThis->virtioScsiConfig.uCdbSize; 1102 PVIRTIOSCSI_REQ_CMD_T pVirtqReq = (PVIRTIOSCSI_REQ_CMD_T)RTMemAlloc(cbReqHdr); 1103 AssertReturn(pVirtqReq, VERR_NO_MEMORY); 1104 uint8_t *pb = (uint8_t *)pVirtqReq; 1105 for (size_t cb = RT_MIN(pDescChain->cbPhysSend, cbReqHdr); cb; ) 1106 { 1107 size_t cbSeg = cb; 1108 RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg); 1109 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg); 1110 pb += cbSeg; 1111 cb -= cbSeg; 1112 } 1113 1114 uint8_t uTarget = pVirtqReq->ReqHdr.uVirtioLun[1]; 1115 uint32_t uScsiLun = (pVirtqReq->ReqHdr.uVirtioLun[2] << 8 | pVirtqReq->ReqHdr.uVirtioLun[3]) & 0x3fff; 1083 1116 PVIRTIOSCSITARGET pTarget = &pThis->paTargetInstances[uTarget]; 1084 1117 … … 1088 1121 pThis->virtioScsiConfig.uCdbSize), pVirtqReq->uCdb)); 1089 1122 1090 Log3Func((" id: %RX64, attr: %x, prio: %d, crn: %x\n",1091 pVirtqReq-> cmdHdr.uId, pVirtqReq->cmdHdr.uTaskAttr, pVirtqReq->cmdHdr.uPrio, pVirtqReq->cmdHdr.uCrn));1123 Log3Func(("cmd id: %RX64, attr: %x, prio: %d, crn: %x\n", 1124 pVirtqReq->ReqHdr.uId, pVirtqReq->ReqHdr.uTaskAttr, pVirtqReq->ReqHdr.uPrio, pVirtqReq->ReqHdr.uCrn)); 1092 1125 1093 1126 /* 1094 1127 * Calculate request offsets 1095 1128 */ 1096 uint32_t cbPiIn = 0, cbPiOut = 0, cbPiHdr = 0; 1097 off_t piOutOff = 0; 1098 1099 if (pThis->fHasT10pi) 1100 { 1101 cbPiIn = pVirtqReq->piHdr.uPiBytesOut; 1102 cbPiOut = pVirtqReq->piHdr.uPiBytesIn; 1103 cbPiHdr = sizeof(REQ_CMD_PI) + cbPiOut; 1104 piOutOff = sizeof(REQ_CMD_HDR) + pThis->virtioScsiConfig.uCdbSize + sizeof(REQ_CMD_PI); 1105 } 1106 1107 off_t uDataOutOff = sizeof(REQ_CMD_HDR) + pThis->virtioScsiConfig.uCdbSize + cbPiHdr; 1108 off_t uDataInOff = sizeof(REQ_RESP_HDR) + pThis->virtioScsiConfig.uSenseSize + cbPiIn; 1109 uint8_t *pbDataOut = (uint8_t *)((uint64_t)pVirtqReq + uDataOutOff); 1110 uint32_t cbDataOut = pDescChain->cbVirtSrc - uDataOutOff; 1111 uint32_t cbDataIn = pDescChain->cbPhysDst - uDataInOff; 1112 1129 off_t uDataOutOff = sizeof(REQ_CMD_HDR) + pThis->virtioScsiConfig.uCdbSize; 1130 off_t uDataInOff = sizeof(REQ_RESP_HDR) + pThis->virtioScsiConfig.uSenseSize; 1131 uint32_t cbDataOut = pDescChain->cbPhysSend - uDataOutOff; 1132 uint32_t cbDataIn = pDescChain->cbPhysReturn - uDataInOff; 1113 1133 /** 1114 1134 * Handle submission errors … … 1172 1192 * Have underlying driver allocate a req of size set during initialization of this device. 1173 1193 */ 1174 PDMMEDIAEXIOREQ 1175 PVIRTIOSCSIREQ 1176 PPDMIMEDIAEX 1194 PDMMEDIAEXIOREQ hIoReq = NULL; 1195 PVIRTIOSCSIREQ pReq; 1196 PPDMIMEDIAEX pIMediaEx = pTarget->pDrvMediaEx; 1177 1197 1178 1198 int rc = pIMediaEx->pfnIoReqAlloc(pIMediaEx, &hIoReq, (void **)&pReq, 0 /* uIoReqId */, … … 1181 1201 AssertMsgRCReturn(rc, ("Failed to allocate I/O request, rc=%Rrc\n", rc), rc); 1182 1202 1183 /* 1184 * Prepare req's parameters for submission 1185 */ 1186 if (pThis->fHasT10pi) 1187 { 1188 pReq->cbPiOut = cbPiOut; 1189 pReq->pbPiOut = (uint8_t *)((uint64_t)pVirtqReq + piOutOff); 1190 pReq->cbPiIn = cbPiIn; 1191 pReq->pbPiIn = (uint8_t *)RTMemAlloc(cbPiIn); 1192 AssertMsgReturn(pReq->pbPiIn, ("Out of memory allocating pi_in buffer"), VERR_NO_MEMORY); 1193 } 1194 1195 pReq->hIoReq = hIoReq; 1196 pReq->pTarget = pTarget; 1197 pReq->qIdx = qIdx; 1198 pReq->cbDataOut = cbDataOut; 1199 pReq->pbDataOut = cbDataOut ? pbDataOut : 0; 1200 pReq->pDescChain = pDescChain; 1201 pReq->cbSense = pThis->virtioScsiConfig.uSenseSize; 1202 pReq->pbSense = (uint8_t *)RTMemAlloc(pReq->cbSense); 1203 pReq->hIoReq = hIoReq; 1204 pReq->pTarget = pTarget; 1205 pReq->qIdx = qIdx; 1206 pReq->cbDataIn = cbDataIn; 1207 pReq->cbDataOut = cbDataOut; 1208 pReq->pDescChain = pDescChain; 1209 pReq->uDataInOff = uDataInOff; 1210 pReq->uDataOutOff = uDataOutOff; 1211 1212 pReq->cbSense = pThis->virtioScsiConfig.uSenseSize; 1213 pReq->pbSense = (uint8_t *)RTMemAlloc(pReq->cbSense); 1203 1214 AssertMsgReturn(pReq->pbSense, ("Out of memory allocating sense buffer"), VERR_NO_MEMORY); 1204 1215 1205 if (cbDataIn) 1206 { 1207 pReq->cbDataIn = cbDataIn; 1208 pReq->pbDataIn = (uint8_t *)RTMemAlloc(cbDataIn); 1209 AssertMsgReturn(pReq->pbDataIn, ("Out of memory allocating datain buffer"), VERR_NO_MEMORY); 1210 } 1211 1216 /* Note: DrvSCSI allocates one virtual memory buffer for input and output phases of the request */ 1212 1217 rc = pIMediaEx->pfnIoReqSendScsiCmd(pIMediaEx, pReq->hIoReq, uScsiLun, 1213 1218 pVirtqReq->uCdb, (size_t)pThis->virtioScsiConfig.uCdbSize, … … 1256 1261 uint8_t uResponse = VIRTIOSCSI_S_OK; 1257 1262 1258 PVIRTIOSCSI_CTRL_T pScsiCtrl = (PVIRTIOSCSI_CTRL_T)pDescChain->pVirtSrc; 1263 PVIRTIOSCSI_CTRL_T pScsiCtrl = (PVIRTIOSCSI_CTRL_T)RTMemAlloc(sizeof(PVIRTIOSCSI_CTRL_T)); 1264 1265 uint8_t *pb = (uint8_t *)pScsiCtrl; 1266 for (size_t cb = RT_MIN(pDescChain->cbPhysSend, sizeof(PVIRTIOSCSI_CTRL_T)); cb; ) 1267 { 1268 size_t cbSeg = cb; 1269 RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg); 1270 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), GCPhys, pb, cbSeg); 1271 pb += cbSeg; 1272 cb -= cbSeg; 1273 } 1259 1274 1260 1275 /* … … 1900 1915 const void *pv, uint32_t cb, bool fWrite) 1901 1916 { 1902 int rc = VINF_SUCCESS; 1917 1918 AssertReturn(!pv || cb >= sizeof(uint32_t), fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00); 1919 1903 1920 if (MATCH_SCSI_CONFIG(uNumQueues)) 1904 1921 SCSI_CONFIG_ACCESSOR_READONLY(uNumQueues); … … 1933 1950 { 1934 1951 LogFunc(("Bad access by guest to virtio_scsi_config: uoff=%d, cb=%d\n", uOffset, cb)); 1935 r c = VERR_ACCESS_DENIED;1936 } 1937 return rc;1952 return fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00; 1953 } 1954 return VINF_SUCCESS; 1938 1955 } 1939 1956 -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r81231 r81300 188 188 } while (desc.fFlags & VIRTQ_DESC_F_NEXT); 189 189 190 191 190 PRTSGBUF pSgPhysIn = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); 192 191 AssertReturn(pSgPhysIn, VERR_NO_MEMORY); … … 194 193 RTSgBufInit(pSgPhysIn, (PCRTSGSEG)paSegsIn, cSegsIn); 195 194 196 void *pVirtOut = RTMemAlloc(cbOut); 197 AssertReturn(pVirtOut, VERR_NO_MEMORY); 198 199 /* If there's any guest → device data in phys. memory pulled 200 * from queue, copy it into virtual memory to return to caller */ 201 202 if (cSegsOut) 203 { 204 uint8_t *outSgVirt = (uint8_t *)pVirtOut; 205 RTSGBUF outSgPhys; 206 RTSgBufInit(&outSgPhys, (PCRTSGSEG)paSegsOut, cSegsOut); 207 for (size_t cb = cbOut; cb;) 208 { 209 size_t cbSeg = cb; 210 RTGCPHYS GCPhys = (RTGCPHYS)RTSgBufGetNextSegment(&outSgPhys, &cbSeg); 211 PDMDevHlpPhysRead(((PVIRTIOSTATE)hVirtio)->CTX_SUFF(pDevIns), GCPhys, outSgVirt, cbSeg); 212 outSgVirt = ((uint8_t *)outSgVirt) + cbSeg; 213 cb -= cbSeg; 214 } 215 RTMemFree(paSegsOut); 216 } 195 PRTSGBUF pSgPhysOut = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); 196 AssertReturn(pSgPhysOut, VERR_NO_MEMORY); 197 198 RTSgBufInit(pSgPhysOut, (PCRTSGSEG)paSegsOut, cSegsOut); 217 199 218 200 PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T)); … … 220 202 221 203 pDescChain->uHeadIdx = uHeadIdx; 222 pDescChain->cb VirtSrc= cbOut;223 pDescChain->p VirtSrc = pVirtOut;224 pDescChain->cbPhys Dst= cbIn;225 pDescChain->pSgPhys Dst= pSgPhysIn;204 pDescChain->cbPhysSend = cbOut; 205 pDescChain->pSgPhysSend = pSgPhysOut; 206 pDescChain->cbPhysReturn = cbIn; 207 pDescChain->pSgPhysReturn = pSgPhysIn; 226 208 *ppDescChain = pDescChain; 227 209 … … 240 222 PVIRTIOSTATE pVirtio = (PVIRTIOSTATE)hVirtio; 241 223 PVIRTQSTATE pVirtq = &pVirtio->virtqState[qIdx]; 242 PRTSGBUF pSgPhysReturn = pDescChain->pSgPhysDst; 224 PRTSGBUF pSgPhysReturn = pDescChain->pSgPhysReturn; 225 243 226 244 227 AssertMsgReturn(DRIVER_OK(pVirtio) /*&& pVirtio->uQueueEnable[qIdx]*/, … … 251 234 252 235 /* 253 * Copy virtual memory s/g buffer containing data to return to the guest 254 * to phys. memory described by (IN direction ) s/g buffer of the descriptor chain 255 * (pulled from avail ring of queue), essentially giving result back to the guest driver. 256 */ 236 * Copy s/g buf (virtual memory) to guest phys mem (IN direction). This virtual memory 237 * block will be small (fixed portion of response header + sense buffer area or 238 * control commands or error return values)... The bulk of req data xfers to phys mem 239 * is handled by client */ 240 257 241 size_t cbCopy = 0; 258 242 size_t cbRemain = RTSgBufCalcTotalLength(pSgVirtReturn); 243 RTSgBufReset(pSgPhysReturn); /* Reset ptr because req data may have already been written */ 259 244 while (cbRemain) 260 245 { … … 272 257 273 258 if (fFence) 274 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 259 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); /* needed? */ 275 260 276 261 /** If this write-ahead crosses threshold where the driver wants to get an event flag it */ … … 287 272 (uint32_t)(cbCopy & 0xffffffff)); 288 273 289 Log2Func((".... Copied % ul bytes to %ul byte buffer, residual=%ul\n",290 cbCopy, pDescChain->cbPhys Dst, pDescChain->cbPhysDst- cbCopy));274 Log2Func((".... Copied %lu bytes to %lu byte buffer, residual=%lu\n", 275 cbCopy, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy)); 291 276 292 277 Log6Func(("Write ahead used_idx=%d, %s used_idx=%d\n", … … 561 546 { 562 547 if (fWrite) /* Guest WRITE pCommonCfg>uDeviceFeatures */ 548 { 563 549 LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n")); 550 return VINF_SUCCESS; 551 } 564 552 else /* Guest READ pCommonCfg->uDeviceFeatures */ 565 553 { … … 581 569 LogFunc(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n", 582 570 pVirtio->uDeviceFeaturesSelect)); 583 return V ERR_ACCESS_DENIED;571 return VINF_IOM_MMIO_UNUSED_00; 584 572 } 585 573 } … … 604 592 LogFunc(("Guest wrote uDriverFeatures with out of range selector (%d), returning 0\n", 605 593 pVirtio->uDriverFeaturesSelect)); 606 return V ERR_ACCESS_DENIED;594 return VINF_SUCCESS; 607 595 } 608 596 } … … 626 614 LogFunc(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n", 627 615 pVirtio->uDriverFeaturesSelect)); 628 return V ERR_ACCESS_DENIED;616 return VINF_IOM_MMIO_UNUSED_00; 629 617 } 630 618 } … … 635 623 { 636 624 Log2Func(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n")); 637 return V ERR_ACCESS_DENIED;625 return VINF_SUCCESS; 638 626 } 639 627 else … … 712 700 Log2Func(("Bad guest %s access to virtio_pci_common_cfg: uOffset=%d, cb=%d\n", 713 701 fWrite ? "write" : "read ", uOffset, cb)); 714 r c = VERR_ACCESS_DENIED;702 return fWrite ? VINF_SUCCESS : VINF_IOM_MMIO_UNUSED_00; 715 703 } 716 704 return rc; … … 770 758 { 771 759 uint32_t uOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg; 772 virtioCommonCfgAccessed(pVirtio, false /* fWrite */, uOffset, cb, (void const *)pv);760 rc = virtioCommonCfgAccessed(pVirtio, false /* fWrite */, uOffset, cb, (void const *)pv); 773 761 } 774 762 else … … 784 772 " pVirtio=%#p GCPhysAddr=%RGp cb=%u\n", 785 773 pVirtio, GCPhysAddr, cb)); 774 return VINF_IOM_MMIO_UNUSED_00; 786 775 } 787 776 return rc; … … 802 791 RT_NOREF(pvUser); 803 792 PVIRTIOSTATE pVirtio = *PDMINS_2_DATA(pDevIns, PVIRTIOSTATE *); 804 int rc = VINF_SUCCESS;805 793 806 794 MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap, fDevSpecific); … … 815 803 * Pass this MMIO write access back to the client to handle 816 804 */ 817 rc =pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uOffset, pv, cb);805 (void)pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uOffset, pv, cb); 818 806 } 819 807 else … … 821 809 { 822 810 uint32_t uOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg; 823 virtioCommonCfgAccessed(pVirtio, true /* fWrite */, uOffset, cb, pv);811 (void)virtioCommonCfgAccessed(pVirtio, true /* fWrite */, uOffset, cb, pv); 824 812 } 825 813 else … … 847 835 pVirtio, GCPhysAddr, pv, cb, pv, cb)); 848 836 } 849 return rc;837 return VINF_SUCCESS; 850 838 } 851 839 -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h
r81122 r81300 65 65 typedef struct VIRTIO_DESC_CHAIN 66 66 { 67 uint32_t uHeadIdx; /**< Head idx of associated desc chain */68 uint32_t cb VirtSrc; /**< Size of virt source buffer*/69 void *pVirtSrc; /**< Virt mem buf holding out data from guest*/70 uint32_t cbPhys Dst;/**< Total size of dst buffer */71 PRTSGBUF pSgPhys Dst;/**< Phys S/G buf to store result for guest */67 uint32_t uHeadIdx; /**< Head idx of associated desc chain */ 68 uint32_t cbPhysSend; /**< Total size of src buffer */ 69 PRTSGBUF pSgPhysSend; /**< Phys S/G/ buf for data from guest */ 70 uint32_t cbPhysReturn; /**< Total size of dst buffer */ 71 PRTSGBUF pSgPhysReturn; /**< Phys S/G buf to store result for guest */ 72 72 } VIRTIO_DESC_CHAIN_T, *PVIRTIO_DESC_CHAIN_T, **PPVIRTIO_DESC_CHAIN_T; 73 73
Note:
See TracChangeset
for help on using the changeset viewer.