- Timestamp:
- Apr 5, 2020 9:53:37 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
r83570 r83571 737 737 RTSgBufInit(pReqSegBuf, paReqSegs, 1); 738 738 739 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, pReqSegBuf, pDescChain, true );739 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, EVENTQ_IDX, pReqSegBuf, pDescChain, true /*fFence*/); 740 740 virtioCoreQueueSync(pDevIns, &pThis->Virtio, EVENTQ_IDX); 741 741 … … 1319 1319 uint16_t qIdx, PVIRTIO_DESC_CHAIN_T pDescChain) 1320 1320 { 1321 uint8_t bResponse = VIRTIOSCSI_S_OK;1322 uint8_t cSegs = 0;1323 1324 1321 AssertReturn(pDescChain->cbPhysSend >= RT_MIN(sizeof(VIRTIOSCSI_CTRL_AN_T), 1325 1322 sizeof(VIRTIOSCSI_CTRL_TMF_T)), 0); … … 1328 1325 * Allocate buffer and read in the control command 1329 1326 */ 1330 PVIRTIO_SCSI_CTRL_UNION_T pScsiCtrlUnion = (PVIRTIO_SCSI_CTRL_UNION_T)RTMemAllocZ(sizeof(VIRTIO_SCSI_CTRL_UNION_T));1331 AssertPtrReturn(pScsiCtrlUnion, VERR_NO_MEMORY /*ignored*/);1332 1333 uint8_t *pb = pScsiCtrlUnion->ab;1334 for (size_t cb = RT_MIN(pDescChain->cbPhysSend, sizeof(VIRTIO_SCSI_CTRL_UNION_T)); cb; )1335 { 1336 size_t cbSeg = cb ;1327 VIRTIO_SCSI_CTRL_UNION_T ScsiCtrlUnion; 1328 RT_ZERO(ScsiCtrlUnion); 1329 1330 size_t const cbCtrl = RT_MIN(pDescChain->cbPhysSend, sizeof(VIRTIO_SCSI_CTRL_UNION_T)); 1331 for (size_t offCtrl = 0; offCtrl < cbCtrl; ) 1332 { 1333 size_t cbSeg = cbCtrl - offCtrl; 1337 1334 RTGCPHYS GCPhys = virtioCoreSgBufGetNextSegment(pDescChain->pSgPhysSend, &cbSeg); 1338 PDMDevHlpPCIPhysRead(pDevIns, GCPhys, pb, cbSeg); 1339 pb += cbSeg; 1340 cb -= cbSeg; 1341 } 1342 1343 /** @todo r=bird: Memory leak here. */ 1344 AssertReturn( (pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_TMF 1335 PDMDevHlpPCIPhysRead(pDevIns, GCPhys, &ScsiCtrlUnion.ab[offCtrl], cbSeg); 1336 offCtrl += cbSeg; 1337 } 1338 1339 AssertReturn( (ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_TMF 1345 1340 && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_TMF_T)) 1346 || ( ( pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_AN_QUERY 1347 || pScsiCtrlUnion->scsiCtrl.uType == VIRTIOSCSI_T_AN_SUBSCRIBE) 1348 && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_AN_T)), 0); 1349 1350 /** @todo r=bird: This segment handling is unnecessary. A stack array should 1351 * suffice. The stack variable w/ initializer + memcpy into paReqSegs 1352 * done in the switch below is also weird + suboptimal. */ 1353 PRTSGSEG paReqSegs = (PRTSGSEG)RTMemAllocZ(sizeof(RTSGSEG) * 2); 1354 AssertReturn(paReqSegs, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here. */ 1355 1356 switch (pScsiCtrlUnion->scsiCtrl.uType) 1341 || ( ( ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_AN_QUERY 1342 || ScsiCtrlUnion.scsiCtrl.uType == VIRTIOSCSI_T_AN_SUBSCRIBE) 1343 && pDescChain->cbPhysSend >= sizeof(VIRTIOSCSI_CTRL_AN_T)), 1344 0 /** @todo r=bird: what kind of status is '0' here? */); 1345 1346 union 1347 { 1348 uint32_t fSupportedEvents; 1349 } uData; 1350 uint8_t bResponse = VIRTIOSCSI_S_OK; 1351 uint8_t cSegs; 1352 RTSGSEG aReqSegs[2]; 1353 switch (ScsiCtrlUnion.scsiCtrl.uType) 1357 1354 { 1358 1355 case VIRTIOSCSI_T_TMF: /* Task Management Functions */ 1359 1356 { 1360 uint8_t uTarget = pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[1];1361 uint32_t uScsiLun = (pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[2] << 81362 | pScsiCtrlUnion->scsiCtrlTmf.abScsiLun[3]) & 0x3fff;1357 uint8_t uTarget = ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[1]; 1358 uint32_t uScsiLun = RT_MAKE_U16(ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[3], 1359 ScsiCtrlUnion.scsiCtrlTmf.abScsiLun[2]) & 0x3fff; 1363 1360 Log2Func(("[%s] (Target: %d LUN: %d) Task Mgt Function: %s\n", 1364 VIRTQNAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText( pScsiCtrlUnion->scsiCtrlTmf.uSubtype)));1361 VIRTQNAME(qIdx), uTarget, uScsiLun, virtioGetTMFTypeText(ScsiCtrlUnion.scsiCtrlTmf.uSubtype))); 1365 1362 1366 1363 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) … … 1370 1367 bResponse = VIRTIOSCSI_S_INCORRECT_LUN; 1371 1368 else 1372 switch ( pScsiCtrlUnion->scsiCtrlTmf.uSubtype)1369 switch (ScsiCtrlUnion.scsiCtrlTmf.uSubtype) 1373 1370 { 1374 1371 case VIRTIOSCSI_T_TMF_ABORT_TASK: … … 1400 1397 bResponse = VIRTIOSCSI_S_FAILURE; 1401 1398 } 1402 1403 RTSGSEG aSegs[] = { { &bResponse, sizeof(bResponse) } }; 1404 memcpy(paReqSegs, aSegs, sizeof(aSegs)); 1405 cSegs = RT_ELEMENTS(aSegs); 1399 cSegs = 0; /* only bResponse */ 1406 1400 break; 1407 1401 } 1408 1402 case VIRTIOSCSI_T_AN_QUERY: /* Guest SCSI driver is querying supported async event notifications */ 1409 1403 { 1410 1411 PVIRTIOSCSI_CTRL_AN_T pScsiCtrlAnQuery = &pScsiCtrlUnion->scsiCtrlAsyncNotify; 1404 PVIRTIOSCSI_CTRL_AN_T const pScsiCtrlAnQuery = &ScsiCtrlUnion.scsiCtrlAsyncNotify; 1412 1405 1413 1406 uint8_t uTarget = pScsiCtrlAnQuery->abScsiLun[1]; 1414 uint32_t uScsiLun = (pScsiCtrlAnQuery->abScsiLun[2] << 8 | pScsiCtrlAnQuery->abScsiLun[3]) & 0x3fff;1407 uint32_t uScsiLun = RT_MAKE_U16(pScsiCtrlAnQuery->abScsiLun[3], pScsiCtrlAnQuery->abScsiLun[2]) & 0x3fff; 1415 1408 1416 1409 if (uTarget >= pThis->cTargets || !pThisCC->paTargetInstances[uTarget].fPresent) … … 1431 1424 } 1432 1425 #endif 1433 uint32_t fSupportedEvents = SUPPORTED_EVENTS; 1434 RTSGSEG aSegs[] = { { &fSupportedEvents, sizeof(fSupportedEvents) }, 1435 { &bResponse, sizeof(bResponse) } }; 1436 memcpy(paReqSegs, aSegs, sizeof(aSegs)); 1437 cSegs = RT_ELEMENTS(aSegs); 1426 uData.fSupportedEvents = SUPPORTED_EVENTS; 1427 aReqSegs[0].pvSeg = &uData.fSupportedEvents; 1428 aReqSegs[0].cbSeg = sizeof(uData.fSupportedEvents); 1429 cSegs = 1; 1438 1430 break; 1439 1431 } 1440 1432 case VIRTIOSCSI_T_AN_SUBSCRIBE: /* Guest SCSI driver is subscribing to async event notification(s) */ 1441 1433 { 1442 PVIRTIOSCSI_CTRL_AN_T pScsiCtrlAnSubscribe = &pScsiCtrlUnion->scsiCtrlAsyncNotify;1434 PVIRTIOSCSI_CTRL_AN_T const pScsiCtrlAnSubscribe = &ScsiCtrlUnion.scsiCtrlAsyncNotify; 1443 1435 1444 1436 if (pScsiCtrlAnSubscribe->fEventsRequested & ~SUBSCRIBABLE_EVENTS) … … 1447 1439 1448 1440 uint8_t uTarget = pScsiCtrlAnSubscribe->abScsiLun[1]; 1449 uint32_t uScsiLun = (pScsiCtrlAnSubscribe->abScsiLun[2] << 8 1450 | pScsiCtrlAnSubscribe->abScsiLun[3]) & 0x3fff; 1441 uint32_t uScsiLun = RT_MAKE_U16(pScsiCtrlAnSubscribe->abScsiLun[3], pScsiCtrlAnSubscribe->abScsiLun[2]) & 0x3fff; 1451 1442 1452 1443 #ifdef LOG_ENABLED … … 1470 1461 } 1471 1462 1472 RTSGSEG aSegs[] = { { &pThis->fAsyncEvtsEnabled, sizeof(pThis->fAsyncEvtsEnabled) }, 1473 { &bResponse, sizeof(bResponse) } }; 1474 memcpy(paReqSegs, aSegs, sizeof(aSegs)); 1475 cSegs = RT_ELEMENTS(aSegs); 1463 aReqSegs[0].pvSeg = &pThis->fAsyncEvtsEnabled; 1464 aReqSegs[0].cbSeg = sizeof(pThis->fAsyncEvtsEnabled); 1465 cSegs = 1; 1476 1466 break; 1477 1467 } 1478 1468 default: 1479 1469 { 1480 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(qIdx), pScsiCtrlUnion->scsiCtrl.uType));1470 LogFunc(("Unknown control type extracted from %s: %u\n", VIRTQNAME(qIdx), ScsiCtrlUnion.scsiCtrl.uType)); 1481 1471 1482 1472 bResponse = VIRTIOSCSI_S_FAILURE; 1483 RTSGSEG aSegs[] = { { &bResponse, sizeof(bResponse) } }; 1484 memcpy(paReqSegs, aSegs, sizeof(aSegs)); 1485 cSegs = RT_ELEMENTS(aSegs); 1473 cSegs = 0; /* only bResponse */ 1474 break; 1486 1475 } 1487 1476 } 1477 1478 /* Add the response code: */ 1479 aReqSegs[cSegs].pvSeg = &bResponse; 1480 aReqSegs[cSegs].cbSeg = sizeof(bResponse); 1481 cSegs++; 1482 Assert(cSegs <= RT_ELEMENTS(aReqSegs)); 1483 1488 1484 LogFunc(("Response code: %s\n", virtioGetReqRespText(bResponse))); 1489 1485 1490 PRTSGBUF pReqSegBuf = (PRTSGBUF)RTMemAllocZ(sizeof(RTSGBUF)); 1491 AssertReturn(pReqSegBuf, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here. */ 1492 1493 /* Copy segment data to malloc'd memory to avoid stack out-of-scope errors sanitizer doesn't detect */ 1494 /** @todo r=bird: The above comment makes zero sense as the memory is freed 1495 * before we return, so there cannot be any trouble with out-of-scope 1496 * stuff here. */ 1497 for (int i = 0; i < cSegs; i++) 1498 { 1499 void *pv = paReqSegs[i].pvSeg; 1500 paReqSegs[i].pvSeg = RTMemDup(pv, paReqSegs[i].cbSeg); 1501 AssertReturn(paReqSegs[i].pvSeg, VERR_NO_MEMORY); /** @todo r=bird: Memory leak here. */ 1502 } 1503 1504 RTSgBufInit(pReqSegBuf, paReqSegs, cSegs); 1505 1506 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, pReqSegBuf, pDescChain, true); 1486 RTSGBUF ReqSgBuf; 1487 RTSgBufInit(&ReqSgBuf, aReqSegs, cSegs); 1488 1489 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, qIdx, &ReqSgBuf, pDescChain, true /*fFence*/); 1507 1490 virtioCoreQueueSync(pDevIns, &pThis->Virtio, qIdx); 1508 1509 for (int i = 0; i < cSegs; i++)1510 RTMemFree(paReqSegs[i].pvSeg);1511 1512 RTMemFree(paReqSegs);1513 RTMemFree(pReqSegBuf);1514 /** @todo r=bird: Leaking pScsiCtrlUnion here! */1515 1491 1516 1492 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.