VirtualBox

Changeset 83165 in vbox


Ignore:
Timestamp:
Feb 26, 2020 8:47:09 PM (5 years ago)
Author:
vboxsync
Message:

Network/DevVirtioNet.cpp Found some issues after going back and studying the initial port of the code, and got ping to work, so integrating that. More to test.

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp

    r83153 r83165  
    7777#define VIRTQNAME(idxQueue)           (pThis->aszVirtqNames[idxQueue])
    7878#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))
    8080#define FEATURE_DISABLED(feature) (!FEATURE_ENABLED(feature))
    8181#define FEATURE_OFFERED(feature)  VIRTIONET_HOST_FEATURES_OFFERED & VIRTIONET_F_##feature
     
    209209/* Device operation: Net header packet (VirtIO 1.0, 5.1.6) */
    210210#pragma pack(1)
    211 struct virtio_net_hdr {
     211struct virtio_net_pkt_hdr {
    212212    uint8_t  uFlags;                                           /**< flags                                           */
    213213    uint8_t  uGsoType;                                         /**< gso_type                                        */
     
    219219};
    220220#pragma pack()
    221 typedef virtio_net_hdr VIRTIONET_PKT_HDR_T, *PVIRTIONET_PKT_HDR_T;
     221typedef virtio_net_pkt_hdr VIRTIONET_PKT_HDR_T, *PVIRTIONET_PKT_HDR_T;
    222222AssertCompileSize(VIRTIONET_PKT_HDR_T, 12);
    223223
     
    13541354    RT_NOREF(pThisCC);
    13551355
    1356     LogFunc(("%s (%RTmac)\n", INSTANCE(pThis), pvBuf));
     1356    LogFunc(("%s (%RTmac) pGso %s\n", INSTANCE(pThis), pvBuf, pGso ? "present" : "not present"));
    13571357    VIRTIONET_PKT_HDR_T rxPktHdr;
    13581358
     
    14021402    uint32_t cDescs = 0;
    14031403
    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
    14091411        PVIRTIO_DESC_CHAIN_T pDescChain;
    14101412        int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), &pDescChain, true);
     
    14181420                        VERR_INTERNAL_ERROR);
    14191421
    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.
    14211423         * Assert it to reduce complexity. Robust solution would entail finding seg idx and offset of
    14221424         * virtio_net_header.num_buffers (to update field *after* hdr & pkts copied to gcPhys) */
     
    14261428                        VERR_INTERNAL_ERROR);
    14271429
    1428         uint32_t cbDescChainLeft = pDescChain->cbPhysSend;
    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++)
    14321434        {
    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;
    14481472        }
    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;
    14731473    }
    14741474
     
    14811481
    14821482    virtioCoreQueueSync(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue));
    1483 
    1484 //    for (int i = 0; i < cSegs; i++)
    1485 //        RTMemFree(paVirtSegsToGuest[i].pvSeg);
    14861483
    14871484    RTMemFree(paVirtSegsToGuest);
     
    24472444        pThisCC->fQuiescing  = false;
    24482445        pThis->fNegotiatedFeatures = virtioCoreGetAcceptedFeatures(pVirtio);
     2446
    24492447        for (unsigned idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue++)
    24502448        {
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r83058 r83165  
    556556    if (pVirtio->uDeviceStatus & VIRTIO_STATUS_DRIVER_OK)
    557557        return virtqIsEmpty(pDevIns, pVirtio, idxQueue);
     558    LogFunc(("VirtIO not ready: Returning 'true' for queue empty\n"));
    558559    return true;
    559560}
     
    582583    uint16_t uDescIdx = uHeadIdx;
    583584
    584     Log3Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtq->szVirtqName, uHeadIdx));
     585    Log6Func(("%s DESC CHAIN: (head) desc_idx=%u\n", pVirtq->szVirtqName, uHeadIdx));
    585586    RT_NOREF(pVirtq);
    586587
     
    618619        if (desc.fFlags & VIRTQ_DESC_F_WRITE)
    619620        {
    620             Log3Func(("%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));
    621622            cbIn += desc.cb;
    622623            pSeg = &(paSegsIn[cSegsIn++]);
     
    624625        else
    625626        {
    626             Log3Func(("%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));
    627628            cbOut += desc.cb;
    628629            pSeg = &(paSegsOut[cSegsOut++]);
     
    635636    } while (desc.fFlags & VIRTQ_DESC_F_NEXT);
    636637
    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 
    647638    PVIRTIO_DESC_CHAIN_T pDescChain = (PVIRTIO_DESC_CHAIN_T)RTMemAllocZ(sizeof(VIRTIO_DESC_CHAIN_T));
    648639    AssertReturn(pDescChain, VERR_NO_MEMORY);
    649640
    650641    pDescChain->uHeadIdx      = uHeadIdx;
    651     pDescChain->cbPhysSend    = cbOut;
    652     pDescChain->pSgPhysSend   = pSgPhysOut;
    653     pDescChain->cbPhysReturn  = cbIn;
    654     pDescChain->pSgPhysReturn = pSgPhysIn;
    655642    *ppDescChain = pDescChain;
    656643
    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));
    658666
    659667    return VINF_SUCCESS;
     
    859867                    ("Guest driver not in ready state.\n"), VERR_INVALID_STATE);
    860868
    861     Log3Func(("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",
    862870              VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));
    863871
     
    868876     * is handled by client */
    869877
    870     size_t cbCopy = 0;
     878    size_t cbCopy = 0, cbTotal, cbRemain;
    871879
    872880    if (pSgVirtReturn)
    873881    {
    874         size_t cbRemain = RTSgBufCalcTotalLength(pSgVirtReturn);
     882        cbRemain = cbTotal = RTSgBufCalcTotalLength(pSgVirtReturn);
    875883        virtioCoreSgBufReset(pSgPhysReturn); /* Reset ptr because req data may have already been written */
    876884        while (cbRemain)
     
    904912    virtioWriteUsedElem(pDevIns, pVirtio, idxQueue, pVirtq->uUsedIdx++, pDescChain->uHeadIdx, (uint32_t)cbCopy);
    905913
    906     Log3Func((".... Copied %zu bytes to %u byte buffer, residual=%zu\n",
    907               cbCopy, 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));
    908916
    909917    Log6Func(("Write ahead used_idx=%u, %s used_idx=%u\n",
    910918              pVirtq->uUsedIdx, VIRTQNAME(pVirtio, idxQueue), virtioReadUsedRingIdx(pDevIns, pVirtio, idxQueue)));
    911919
    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    }
    916930    RTMemFree(pDescChain);
    917931
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette