- Timestamp:
- Apr 5, 2020 7:24:56 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r83566 r83567 765 765 * @param pRespHdr Response header 766 766 * @param pbSense Pointer to sense buffer or NULL if none. 767 * @param cbSenseCfg The configured sense buffer size. 767 768 * 768 * @returns V Box status code.769 * @returns VINF_SUCCESS 769 770 */ 770 771 static int virtioScsiR3ReqErr(PPDMDEVINS pDevIns, PVIRTIOSCSI pThis, PVIRTIOSCSICC pThisCC, uint16_t qIdx, 771 PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense) 772 { 773 /** @todo r=bird: There is too much allocating here and we'll leak stuff if 774 * we're low on memory and one of the RTMemAllocZ calls fail! */ 775 uint8_t *pabSenseBuf = (uint8_t *)RTMemAllocZ(pThis->virtioScsiConfig.uSenseSize); 776 AssertReturn(pabSenseBuf, VERR_NO_MEMORY); 777 772 PVIRTIO_DESC_CHAIN_T pDescChain, REQ_RESP_HDR_T *pRespHdr, uint8_t *pbSense, 773 uint32_t cbSenseCfg) 774 { 778 775 Log2Func((" status: %s response: %s\n", 779 776 SCSIStatusText(pRespHdr->uStatus), virtioGetReqRespText(pRespHdr->uResponse))); 780 777 781 PRTSGBUF pReqSegBuf = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); 782 AssertReturn(pReqSegBuf, VERR_NO_MEMORY); 783 784 PRTSGSEG paReqSegs = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 2); 785 AssertReturn(paReqSegs, VERR_NO_MEMORY); 786 787 paReqSegs[0].cbSeg = sizeof(*pRespHdr); 788 paReqSegs[0].pvSeg = pRespHdr; 789 paReqSegs[1].cbSeg = pThis->virtioScsiConfig.uSenseSize; 790 paReqSegs[1].pvSeg = pabSenseBuf; 791 778 RTSGSEG aReqSegs[2]; 779 780 /* Segment #1: Request header*/ 781 aReqSegs[0].pvSeg = pRespHdr; 782 aReqSegs[0].cbSeg = sizeof(*pRespHdr); 783 784 /* Segment #2: Sense data. */ 785 uint8_t abSenseBuf[VIRTIOSCSI_SENSE_SIZE_MAX]; 786 AssertCompile(VIRTIOSCSI_SENSE_SIZE_MAX <= 4096); 787 Assert(cbSenseCfg <= sizeof(abSenseBuf)); 788 789 RT_ZERO(abSenseBuf); 792 790 if (pbSense && pRespHdr->cbSenseLen) 793 memcpy( pabSenseBuf, pbSense, pRespHdr->cbSenseLen);791 memcpy(abSenseBuf, pbSense, RT_MIN(pRespHdr->cbSenseLen, sizeof(abSenseBuf))); 794 792 else 795 793 pRespHdr->cbSenseLen = 0; 796 794 797 /* Copy segment data to malloc'd memory to avoid stack out-of-scope errors sanitizer doesn't detect */ 798 /** @todo r=bird: The above comment makes zero sense as the memory is freed 799 * before we return, so there cannot be any trouble with out-of-scope 800 * stuff here. */ 801 for (int i = 0; i < 2; i++) 802 { 803 void *pv = paReqSegs[i].pvSeg; 804 paReqSegs[i].pvSeg = RTMemDup(pv, paReqSegs[i].cbSeg); 805 AssertReturn(paReqSegs[i].pvSeg, VERR_NO_MEMORY); 806 } 807 808 RTSgBufInit(pReqSegBuf, paReqSegs, 2); 795 aReqSegs[1].pvSeg = abSenseBuf; 796 aReqSegs[1].cbSeg = cbSenseCfg; 797 798 /* Init S/G buffer. */ 799 RTSGBUF ReqSgBuf; 800 RTSgBufInit(&ReqSgBuf, aReqSegs, RT_ELEMENTS(aReqSegs)); 809 801 810 802 if (pThis->fResetting) 811 803 pRespHdr->uResponse = VIRTIOSCSI_S_RESET; 812 804 813 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, pReqSegBuf, pDescChain, true /* fFence */);805 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &ReqSgBuf, pDescChain, true /* fFence */); 814 806 virtioCoreQueueSync(pDevIns, &pThis->Virtio, qIdx); 815 816 for (int i = 0; i < 2; i++)817 RTMemFree(paReqSegs[i].pvSeg);818 819 RTMemFree(paReqSegs);820 RTMemFree(pReqSegBuf);821 RTMemFree(pabSenseBuf);822 807 823 808 if (!ASMAtomicDecU32(&pThis->cActiveReqs) && pThisCC->fQuiescing) … … 948 933 respHdr.uResidual = pReq->cbDataIn; 949 934 950 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense); 935 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, pReq->qIdx, pReq->pDescChain, &respHdr, abSense, 936 RT_MIN(pThis->virtioScsiConfig.uSenseSize, VIRTIOSCSI_SENSE_SIZE_MAX)); 951 937 } 952 938 else … … 1198 1184 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1199 1185 respHdr.uResidual = cbDataIn + cbDataOut; 1200 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , NULL);1186 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense); 1201 1187 return VINF_SUCCESS; 1202 1188 } … … 1217 1203 respHdr.uResponse = VIRTIOSCSI_S_BAD_TARGET; 1218 1204 respHdr.uResidual = cbDataOut + cbDataIn; 1219 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense );1205 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1220 1206 return VINF_SUCCESS; 1221 1207 … … 1234 1220 respHdr.uResponse = VIRTIOSCSI_S_OK; 1235 1221 respHdr.uResidual = cbDataOut + cbDataIn; 1236 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense );1222 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1237 1223 return VINF_SUCCESS; 1238 1224 } … … 1247 1233 respHdr.uResponse = VIRTIOSCSI_S_RESET; 1248 1234 respHdr.uResidual = cbDataIn + cbDataOut; 1249 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL );1235 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, NULL, cbSense); 1250 1236 return VINF_SUCCESS; 1251 1237 } … … 1265 1251 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1266 1252 respHdr.uResidual = cbDataIn + cbDataOut; 1267 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr , abSense);1253 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1268 1254 return VINF_SUCCESS; 1269 1255 } … … 1329 1315 respHdr.uResponse = VIRTIOSCSI_S_FAILURE; 1330 1316 respHdr.uResidual = cbDataIn + cbDataOut; 1331 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense );1317 virtioScsiR3ReqErr(pDevIns, pThis, pThisCC, qIdx, pDescChain, &respHdr, abSense, cbSense); 1332 1318 virtioScsiR3FreeReq(pTarget, pReq); 1333 1319 }
Note:
See TracChangeset
for help on using the changeset viewer.