Changeset 83165 in vbox
- Timestamp:
- Feb 26, 2020 8:47:09 PM (5 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r83153 r83165 77 77 #define VIRTQNAME(idxQueue) (pThis->aszVirtqNames[idxQueue]) 78 78 #define CBVIRTQNAME(idxQueue) RTStrNLen(VIRTQNAME(idxQueue), sizeof(VIRTQNAME(idxQueue))) 79 #define FEATURE_ENABLED(feature) ( pThis->fNegotiatedFeatures & VIRTIONET_F_##feature)79 #define FEATURE_ENABLED(feature) (!!(pThis->fNegotiatedFeatures & VIRTIONET_F_##feature)) 80 80 #define FEATURE_DISABLED(feature) (!FEATURE_ENABLED(feature)) 81 81 #define FEATURE_OFFERED(feature) VIRTIONET_HOST_FEATURES_OFFERED & VIRTIONET_F_##feature … … 209 209 /* Device operation: Net header packet (VirtIO 1.0, 5.1.6) */ 210 210 #pragma pack(1) 211 struct virtio_net_ hdr {211 struct virtio_net_pkt_hdr { 212 212 uint8_t uFlags; /**< flags */ 213 213 uint8_t uGsoType; /**< gso_type */ … … 219 219 }; 220 220 #pragma pack() 221 typedef virtio_net_ hdr VIRTIONET_PKT_HDR_T, *PVIRTIONET_PKT_HDR_T;221 typedef virtio_net_pkt_hdr VIRTIONET_PKT_HDR_T, *PVIRTIONET_PKT_HDR_T; 222 222 AssertCompileSize(VIRTIONET_PKT_HDR_T, 12); 223 223 … … 1354 1354 RT_NOREF(pThisCC); 1355 1355 1356 LogFunc(("%s (%RTmac) \n", INSTANCE(pThis), pvBuf));1356 LogFunc(("%s (%RTmac) pGso %s\n", INSTANCE(pThis), pvBuf, pGso ? "present" : "not present")); 1357 1357 VIRTIONET_PKT_HDR_T rxPktHdr; 1358 1358 … … 1402 1402 uint32_t cDescs = 0; 1403 1403 1404 uint8_t fAddPktHdr = true; 1405 uint32_t uOffset = 0; 1406 1407 while (uOffset < cb) 1408 { 1404 uint8_t fAddPktHdr = !!FEATURE_ENABLED(MRG_RXBUF); 1405 1406 uint32_t uOffset; 1407 for (uOffset = 0; uOffset < cb; ) 1408 { 1409 /* Pull the next empty Guest Rx buffer from the queue */ 1410 1409 1411 PVIRTIO_DESC_CHAIN_T pDescChain; 1410 1412 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), &pDescChain, true); … … 1418 1420 VERR_INTERNAL_ERROR); 1419 1421 1420 /* Unlikely that len of 1st seg of guest Rx (IN) buf is less than sizeof(virtio_net_ hdr) == 12.1422 /* Unlikely that len of 1st seg of guest Rx (IN) buf is less than sizeof(virtio_net_pkt_hdr) == 12. 1421 1423 * Assert it to reduce complexity. Robust solution would entail finding seg idx and offset of 1422 1424 * virtio_net_header.num_buffers (to update field *after* hdr & pkts copied to gcPhys) */ … … 1426 1428 VERR_INTERNAL_ERROR); 1427 1429 1428 uint32_t cbDescChainLeft = pDescChain->cbPhys Send;1429 1430 uint16_t cSegs = 0;1431 if (fAddPktHdr)1430 uint32_t cbDescChainLeft = pDescChain->cbPhysReturn; 1431 1432 /* Fill the Guest Rx buffer with data received from the interface */ 1433 for (uint16_t cSegs = 0; uOffset < cb && cbDescChainLeft; cSegs++) 1432 1434 { 1433 LogFunc(("Add pkthdr\n")); 1434 /* Lead with packet header */ 1435 paVirtSegsToGuest[cSegs].cbSeg = sizeof(VIRTIONET_PKT_HDR_T); 1436 paVirtSegsToGuest[cSegs].pvSeg = RTMemAlloc(sizeof(VIRTIONET_PKT_HDR_T)); 1437 AssertReturn(paVirtSegsToGuest[0].pvSeg, VERR_NO_MEMORY); 1438 1439 cbDescChainLeft -= sizeof(VIRTIONET_PKT_HDR_T); 1440 1441 memcpy(paVirtSegsToGuest[cSegs].pvSeg, &rxPktHdr, sizeof(VIRTIONET_PKT_HDR_T)); 1442 1443 /* Calculate & cache the field we will need to update later in gcPhys memory */ 1444 gcPhysPktHdrNumBuffers = pDescChain->pSgPhysReturn->paSegs[0].gcPhys 1445 + RT_UOFFSETOF(VIRTIONET_PKT_HDR_T, uNumBuffers); 1446 1447 fAddPktHdr = false; 1435 if (fAddPktHdr) 1436 { 1437 /* Lead with packet header */ 1438 paVirtSegsToGuest[0].cbSeg = sizeof(VIRTIONET_PKT_HDR_T); 1439 paVirtSegsToGuest[0].pvSeg = RTMemAlloc(sizeof(VIRTIONET_PKT_HDR_T)); 1440 AssertReturn(paVirtSegsToGuest[0].pvSeg, VERR_NO_MEMORY); 1441 cbDescChainLeft -= sizeof(VIRTIONET_PKT_HDR_T); 1442 1443 memcpy(paVirtSegsToGuest[0].pvSeg, &rxPktHdr, sizeof(VIRTIONET_PKT_HDR_T)); 1444 1445 /* Calculate & cache the field we will need to update later in gcPhys memory */ 1446 gcPhysPktHdrNumBuffers = pDescChain->pSgPhysReturn->paSegs[0].gcPhys 1447 + RT_UOFFSETOF(VIRTIONET_PKT_HDR_T, uNumBuffers); 1448 fAddPktHdr = false; 1449 cSegs++; 1450 } 1451 if (cSegs >= cSegsAllocated) 1452 { 1453 cSegsAllocated <<= 1; /* double the allocation size */ 1454 paVirtSegsToGuest = (PRTSGSEG)RTMemRealloc(paVirtSegsToGuest, sizeof(RTSGSEG) * cSegsAllocated); 1455 AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY); 1456 } 1457 1458 /* Append remaining Rx pkt or as much current desc chain has room for */ 1459 uint32_t cbCropped = RT_MIN(cb, cbDescChainLeft); 1460 paVirtSegsToGuest[cSegs].cbSeg = cbCropped; 1461 paVirtSegsToGuest[cSegs].pvSeg = ((uint8_t *)pvBuf) + uOffset; 1462 cbDescChainLeft -= cbCropped; 1463 uOffset += cbCropped; 1464 cDescs++; 1465 RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs + 1); 1466 Log7Func(("Send Rx pkt to guest...\n")); 1467 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), 1468 pVirtSegBufToGuest, pDescChain, true); 1469 1470 if (FEATURE_DISABLED(MRG_RXBUF)) 1471 break; 1448 1472 } 1449 if (cSegs++ >= cSegsAllocated)1450 {1451 cSegsAllocated <<= 1; /* double the allocation size */1452 paVirtSegsToGuest = (PRTSGSEG)RTMemRealloc(paVirtSegsToGuest, sizeof(RTSGSEG) * cSegsAllocated);1453 AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY);1454 }1455 LogFunc(("Add new post-hdr segment\n"));1456 1457 /* Append remaining Rx pkt or as much current desc chain has room for */1458 uint32_t cbLim = RT_MIN(cb, cbDescChainLeft);1459 paVirtSegsToGuest[cSegs].cbSeg = cbLim;1460 paVirtSegsToGuest[cSegs++].pvSeg = ((uint8_t *)pvBuf) + uOffset;1461 uOffset += cbLim;1462 cDescs++;1463 1464 RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs);1465 //if (pThis->fLog)1466 // RT_BREAKPOINT();1467 Log7Func(("Send Rx pkt to guest...\n"));1468 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue),1469 pVirtSegBufToGuest, pDescChain, true);1470 1471 if (FEATURE_DISABLED(MRG_RXBUF))1472 break;1473 1473 } 1474 1474 … … 1481 1481 1482 1482 virtioCoreQueueSync(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue)); 1483 1484 // for (int i = 0; i < cSegs; i++)1485 // RTMemFree(paVirtSegsToGuest[i].pvSeg);1486 1483 1487 1484 RTMemFree(paVirtSegsToGuest); … … 2447 2444 pThisCC->fQuiescing = false; 2448 2445 pThis->fNegotiatedFeatures = virtioCoreGetAcceptedFeatures(pVirtio); 2446 2449 2447 for (unsigned idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue++) 2450 2448 { -
trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp
r83058 r83165 556 556 if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK) 557 557 return virtqIsEmpty(pDevIns, pVirtio, idxQueue); 558 LogFunc(("VirtIO not ready: Returning 'true' for queue empty\n")); 558 559 return true; 559 560 } … … 582 583 uint16_t uDescIdx = uHeadIdx; 583 584 584 Log 3Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtq->szVirtqName, uHeadIdx));585 Log6Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtq->szVirtqName, uHeadIdx)); 585 586 RT_NOREF(pVirtq); 586 587 … … 618 619 if (desc.fFlags & VIRTQ_DESC_F_WRITE) 619 620 { 620 Log 3Func(("%s IN desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsIn, desc.GCPhysBuf, desc.cb));621 Log6Func(("%s IN desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsIn, desc.GCPhysBuf, desc.cb)); 621 622 cbIn += desc.cb; 622 623 pSeg = &(paSegsIn[cSegsIn++]); … … 624 625 else 625 626 { 626 Log 3Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsOut, desc.GCPhysBuf, desc.cb));627 Log6Func(("%s OUT desc_idx=%u seg=%u addr=%RGp cb=%u\n", VIRTQNAME(pVirtio, idxQueue), uDescIdx, cSegsOut, desc.GCPhysBuf, desc.cb)); 627 628 cbOut += desc.cb; 628 629 pSeg = &(paSegsOut[cSegsOut++]); … … 635 636 } while (desc.fFlags & VIRTQ_DESC_F_NEXT); 636 637 637 PVIRTIOSGBUF pSgPhysIn = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF));638 AssertReturn(pSgPhysIn, VERR_NO_MEMORY);639 640 virtioCoreSgBufInit(pSgPhysIn, paSegsIn, cSegsIn);641 642 PVIRTIOSGBUF pSgPhysOut = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF));643 AssertReturn(pSgPhysOut, VERR_NO_MEMORY);644 645 virtioCoreSgBufInit(pSgPhysOut, paSegsOut, cSegsOut);646 647 638 PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T)); 648 639 AssertReturn(pDescChain, VERR_NO_MEMORY); 649 640 650 641 pDescChain->uHeadIdx = uHeadIdx; 651 pDescChain->cbPhysSend = cbOut;652 pDescChain->pSgPhysSend = pSgPhysOut;653 pDescChain->cbPhysReturn = cbIn;654 pDescChain->pSgPhysReturn = pSgPhysIn;655 642 *ppDescChain = pDescChain; 656 643 657 Log3Func(("%s -- segs OUT: %u (%u bytes) IN: %u (%u bytes) --\n", pVirtq->szVirtqName, cSegsOut, cbOut, cSegsIn, cbIn)); 644 if (cSegsIn) 645 { 646 PVIRTIOSGBUF pSgPhysIn = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF)); 647 AssertReturn(pSgPhysIn, VERR_NO_MEMORY); 648 649 virtioCoreSgBufInit(pSgPhysIn, paSegsIn, cSegsIn); 650 pDescChain->pSgPhysReturn = pSgPhysIn; 651 pDescChain->cbPhysReturn = cbIn; 652 } 653 654 if (cSegsOut) 655 { 656 PVIRTIOSGBUF pSgPhysOut = (PVIRTIOSGBUF)RTMemAllocZ(sizeof(VIRTIOSGBUF)); 657 AssertReturn(pSgPhysOut, VERR_NO_MEMORY); 658 659 virtioCoreSgBufInit(pSgPhysOut, paSegsOut, cSegsOut); 660 pDescChain->pSgPhysSend = pSgPhysOut; 661 pDescChain->cbPhysSend = cbOut; 662 } 663 664 665 Log6Func(("%s -- segs OUT: %u (%u bytes) IN: %u (%u bytes) --\n", pVirtq->szVirtqName, cSegsOut, cbOut, cSegsIn, cbIn)); 658 666 659 667 return VINF_SUCCESS; … … 859 867 ("Guest driver not in ready state.\n"), VERR_INVALID_STATE); 860 868 861 Log 3Func(("Copying client data to %s, desc chain (head desc_idx %d)\n",869 Log6Func(("Copying client data to %s, desc chain (head desc_idx %d)\n", 862 870 VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue))); 863 871 … … 868 876 * is handled by client */ 869 877 870 size_t cbCopy = 0 ;878 size_t cbCopy = 0, cbTotal, cbRemain; 871 879 872 880 if (pSgVirtReturn) 873 881 { 874 size_t cbRemain= RTSgBufCalcTotalLength(pSgVirtReturn);882 cbRemain = cbTotal = RTSgBufCalcTotalLength(pSgVirtReturn); 875 883 virtioCoreSgBufReset(pSgPhysReturn); /* Reset ptr because req data may have already been written */ 876 884 while (cbRemain) … … 904 912 virtioWriteUsedElem(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)cbCopy); 905 913 906 Log 3Func((".... Copied %zu bytes to %u byte buffer, residual=%zu\n",907 cb Copy, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy));914 Log6Func((".... Copied %zu bytes in %d segs to %u byte buffer, residual=%zu\n", 915 cbTotal - cbRemain, pSgVirtReturn->cSegs, pDescChain->cbPhysReturn, pDescChain->cbPhysReturn - cbCopy)); 908 916 909 917 Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n", 910 918 pVirtq->uUsedIdx, VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue))); 911 919 912 RTMemFree((void *)pDescChain->pSgPhysSend->paSegs); 913 RTMemFree(pDescChain->pSgPhysSend); 914 RTMemFree((void *)pSgPhysReturn->paSegs); 915 RTMemFree(pSgPhysReturn); 920 if (pDescChain->pSgPhysSend) 921 { 922 RTMemFree((void *)pDescChain->pSgPhysSend->paSegs); 923 RTMemFree(pDescChain->pSgPhysSend); 924 } 925 if (pDescChain->pSgPhysReturn) 926 { 927 RTMemFree((void *)pSgPhysReturn->paSegs); 928 RTMemFree(pSgPhysReturn); 929 } 916 930 RTMemFree(pDescChain); 917 931
Note:
See TracChangeset
for help on using the changeset viewer.