Changeset 83186 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Mar 2, 2020 5:50:00 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r83165 r83186 416 416 417 417 bool fLog; 418 418 bool fBp; 419 419 /* Receive-blocking-related fields ***************************************/ 420 420 … … 568 568 } 569 569 570 DECLINLINE(void) virtioNetPrintFeatures(PVIRTIONET pThis, uint32_t fFeatures, const char *pcszText) 570 void virtioNetDumpGcPhysRxBuf(PPDMDEVINS pDevIns, PVIRTIONET_PKT_HDR_T pRxPktHdr, 571 uint16_t cDescs, uint8_t *pvBuf, uint16_t cb, RTGCPHYS gcPhysRxBuf, uint8_t cbRxBuf) 572 { 573 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 574 pRxPktHdr->uNumBuffers = cDescs; 575 LogFunc(("-------------------------------------------------------------------\n")); 576 LogFunc(("rxPktHdr\n" 577 " uFlags ......... %2.2x\n" 578 " uGsoType ....... %2.2x\n" 579 " uHdrLen ........ %4.4x\n" 580 " uGsoSize ....... %4.4x\n" 581 " uChksumStart ... %4.4x\n" 582 " uChksumOffset .. %4.4x\n" 583 " uNumBuffers .... %4.4x\n", 584 pRxPktHdr->uFlags, 585 pRxPktHdr->uGsoType, pRxPktHdr->uHdrLen, pRxPktHdr->uGsoSize, 586 pRxPktHdr->uChksumStart, pRxPktHdr->uChksumOffset, pRxPktHdr->uNumBuffers)); 587 588 virtioCoreHexDump((uint8_t *)pRxPktHdr, sizeof(VIRTIONET_PKT_HDR_T), 0, "Dump of virtual rPktHdr"); 589 virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming"); 590 LogFunc((". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n")); 591 virtioCoreGcPhysHexDump(pDevIns, gcPhysRxBuf, cbRxBuf, 0, "Phys Mem Dump of Rx pkt"); 592 LogFunc(("-------------------------------------------------------------------\n")); 593 } 594 595 DECLINLINE(void) virtioNetPrintFeatures(uint32_t fFeatures, const char *pcszText) 571 596 { 572 597 #ifdef LOG_ENABLED … … 577 602 } const s_aFeatures[] = 578 603 { 579 { VIRTIONET_F_CSUM, " Host handles packets with partial checksum." },580 { VIRTIONET_F_GUEST_CSUM, " Guest handles packets with partial checksum." },581 { VIRTIONET_F_CTRL_GUEST_OFFLOADS, " Control channel offloads reconfiguration support." },582 { VIRTIONET_F_MAC, " Host has given MAC address." },583 { VIRTIONET_F_GUEST_TSO4, " Guest can receive TSOv4." },584 { VIRTIONET_F_GUEST_TSO6, " Guest can receive TSOv6." },585 { VIRTIONET_F_GUEST_ECN, " Guest can receive TSO with ECN." },586 { VIRTIONET_F_GUEST_UFO, " Guest can receive UFO." },587 { VIRTIONET_F_HOST_TSO4, " Host can receive TSOv4." },588 { VIRTIONET_F_HOST_TSO6, " Host can receive TSOv6." },589 { VIRTIONET_F_HOST_ECN, " Host can receive TSO with ECN." },590 { VIRTIONET_F_HOST_UFO, " Host can receive UFO." },591 { VIRTIONET_F_MRG_RXBUF, " Guest can merge receive buffers." },592 { VIRTIONET_F_STATUS, " Configuration status field is available." },593 { VIRTIONET_F_CTRL_VQ, " Control channel is available." },594 { VIRTIONET_F_CTRL_RX, " Control channel RX mode support." },595 { VIRTIONET_F_CTRL_VLAN, " Control channel VLAN filtering." },596 { VIRTIONET_F_GUEST_ANNOUNCE, " Guest can send gratuitous packets." },597 { VIRTIONET_F_MQ, " Host supports multiqueue with automatic receive steering." },598 { VIRTIONET_F_CTRL_MAC_ADDR, " Set MAC address through control channel." }604 { VIRTIONET_F_CSUM, " CSUM: Host handles packets with partial checksum.\n" }, 605 { VIRTIONET_F_GUEST_CSUM, " GUEST_CSUM: Guest handles packets with partial checksum.\n" }, 606 { VIRTIONET_F_CTRL_GUEST_OFFLOADS, " CTRL_GUEST_OFFLOADS: Control channel offloads reconfiguration support.\n" }, 607 { VIRTIONET_F_MAC, " MAC: Host has given MAC address.\n" }, 608 { VIRTIONET_F_GUEST_TSO4, " GUEST_TSO4: Guest can receive TSOv4.\n" }, 609 { VIRTIONET_F_GUEST_TSO6, " GUEST_TSO6: Guest can receive TSOv6.\n" }, 610 { VIRTIONET_F_GUEST_ECN, " GUEST_ECN: Guest can receive TSO with ECN.\n" }, 611 { VIRTIONET_F_GUEST_UFO, " GUEST_UFO: Guest can receive UFO.\n" }, 612 { VIRTIONET_F_HOST_TSO4, " HOST_TSO4: Host can receive TSOv4.\n" }, 613 { VIRTIONET_F_HOST_TSO6, " HOST_TSO6: Host can receive TSOv6.\n" }, 614 { VIRTIONET_F_HOST_ECN, " HOST_ECN: Host can receive TSO with ECN.\n" }, 615 { VIRTIONET_F_HOST_UFO, " HOST_UFO: Host can receive UFO.\n" }, 616 { VIRTIONET_F_MRG_RXBUF, " MRG_RXBUF: Guest can merge receive buffers.\n" }, 617 { VIRTIONET_F_STATUS, " STATUS: Configuration status field is available.\n" }, 618 { VIRTIONET_F_CTRL_VQ, " CTRL_VQ: Control channel is available.\n" }, 619 { VIRTIONET_F_CTRL_RX, " CTRL_RX: Control channel RX mode support.\n" }, 620 { VIRTIONET_F_CTRL_VLAN, " CTRL_VLAN: Control channel VLAN filtering.\n" }, 621 { VIRTIONET_F_GUEST_ANNOUNCE, " GUEST_ANNOUNCE: Guest can send gratuitous packets.\n" }, 622 { VIRTIONET_F_MQ, " MQ: Host supports multiqueue with automatic receive steering.\n" }, 623 { VIRTIONET_F_CTRL_MAC_ADDR, " CTRL_MAC_ADDR: Set MAC address through control channel.\n" } 599 624 }; 600 625 601 Log3(("%s %s:\n", INSTANCE(pThis), pcszText)); 626 #define MAXLINE 80 627 /* Display as a single buf to prevent interceding log messages */ 628 char *pszBuf = (char *)RTMemAllocZ(RT_ELEMENTS(s_aFeatures) * 80), *cp = pszBuf; 629 Assert(pszBuf); 602 630 for (unsigned i = 0; i < RT_ELEMENTS(s_aFeatures); ++i) 603 { 604 if (s_aFeatures[i].fMask & fFeatures) 605 Log3(("%s --> %s\n", INSTANCE(pThis), s_aFeatures[i].pcszDesc)); 606 } 631 if (s_aFeatures[i].fMask & fFeatures) { 632 int len = RTStrNLen(s_aFeatures[i].pcszDesc, MAXLINE); 633 memcpy(cp, s_aFeatures[i].pcszDesc, len); /* intentionally drop trailing '\0' */ 634 cp += len; 635 } 636 Log3(("%s:\n%s\n", pcszText, pszBuf)); 637 RTMemFree(pszBuf); 638 607 639 #else /* !LOG_ENABLED */ 608 640 RT_NOREF3(pThis, fFeatures, pcszText); … … 1276 1308 return false; 1277 1309 } 1278 1310 /* @todo remove this debug hack that detects ARP from specific ping on development setup - pk */ 1279 1311 uint8_t src[6] = { 0xA8, 0x20, 0x66, 0x57, 0x50, 0x3C }; 1280 1312 uint8_t dst[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; … … 1355 1387 1356 1388 LogFunc(("%s (%RTmac) pGso %s\n", INSTANCE(pThis), pvBuf, pGso ? "present" : "not present")); 1357 VIRTIONET_PKT_HDR_T rxPktHdr ;1389 VIRTIONET_PKT_HDR_T rxPktHdr = { 0 }; 1358 1390 1359 1391 if (pGso) … … 1383 1415 rxPktHdr.uHdrLen = pGso->cbHdrsTotal; 1384 1416 rxPktHdr.uGsoSize = pGso->cbMaxSeg; 1385 rxPktHdr.uChksum Offset = pGso->offHdr2;1417 rxPktHdr.uChksumStart = pGso->offHdr2; 1386 1418 } 1387 1419 else … … 1390 1422 rxPktHdr.uGsoType = VIRTIONET_HDR_GSO_NONE; 1391 1423 } 1392 1393 // virtioNetR3PacketDump(pThis, (const uint8_t *)pvBuf, cb, "<-- Incoming");1394 1424 1395 1425 uint16_t cSegsAllocated = VIRTIONET_PREALLOCATE_RX_SEG_COUNT; … … 1399 1429 AssertReturn(paVirtSegsToGuest, VERR_NO_MEMORY); 1400 1430 1431 1432 uint8_t fAddPktHdr = true; 1401 1433 RTGCPHYS gcPhysPktHdrNumBuffers; 1402 uint32_t cDescs = 0; 1403 1404 uint8_t fAddPktHdr = !!FEATURE_ENABLED(MRG_RXBUF); 1405 1434 uint16_t cDescs; 1406 1435 uint32_t uOffset; 1407 for (uOffset = 0; uOffset < cb; ) 1408 { 1409 /* Pull the next empty Guest Rx buffer from the queue */ 1410 1436 for (cDescs = uOffset = 0; uOffset < cb; ) 1437 { 1411 1438 PVIRTIO_DESC_CHAIN_T pDescChain; 1439 1412 1440 int rc = virtioCoreR3QueueGet(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), &pDescChain, true); 1413 1414 1441 AssertRC(rc == VINF_SUCCESS || rc == VERR_NOT_AVAILABLE); 1415 1442 1416 1443 /** @todo Find a better way to deal with this */ 1417 1418 1444 AssertMsgReturn(rc == VINF_SUCCESS && pDescChain->cbPhysReturn, 1419 1445 ("Not enough Rx buffers in queue to accomodate ethernet packet\n"), … … 1423 1449 * Assert it to reduce complexity. Robust solution would entail finding seg idx and offset of 1424 1450 * virtio_net_header.num_buffers (to update field *after* hdr & pkts copied to gcPhys) */ 1425 1426 1451 AssertMsgReturn(pDescChain->pSgPhysReturn->paSegs[0].cbSeg >= sizeof(VIRTIONET_PKT_HDR_T), 1427 1452 ("Desc chain's first seg has insufficient space for pkt header!\n"), … … 1431 1456 1432 1457 /* Fill the Guest Rx buffer with data received from the interface */ 1433 for (uint16_t cSegs = 0; uOffset < cb && cbDescChainLeft; cSegs++)1458 for (uint16_t cSegs = 0; uOffset < cb && cbDescChainLeft; ) 1434 1459 { 1435 1460 if (fAddPktHdr) … … 1463 1488 uOffset += cbCropped; 1464 1489 cDescs++; 1465 RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs + 1); 1490 cSegs++; 1491 RTSgBufInit(pVirtSegBufToGuest, paVirtSegsToGuest, cSegs); 1466 1492 Log7Func(("Send Rx pkt to guest...\n")); 1467 1493 virtioCoreR3QueuePut(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue), … … 1477 1503 int rc = PDMDevHlpPCIPhysWrite(pDevIns, gcPhysPktHdrNumBuffers, &cDescs, sizeof(cDescs)); 1478 1504 AssertMsgRCReturn(rc, 1479 ("Failure updating descriptor count in pkt hdr in guest physical memory\n"), 1480 rc); 1505 ("Failure updating descriptor count in pkt hdr in guest physical memory\n"), 1506 rc); 1507 1508 /* Dump Rx Pkt after it's been written to guest physical memory via the virtio core API */ 1509 if (pThis->fLog) 1510 { 1511 virtioNetDumpGcPhysRxBuf(pDevIns, &rxPktHdr, cDescs, (uint8_t *)pvBuf, cb, 1512 gcPhysPktHdrNumBuffers - RT_UOFFSETOF(VIRTIONET_PKT_HDR_T, uNumBuffers), 1513 cb + sizeof(VIRTIONET_PKT_HDR_T)); 1514 } 1481 1515 1482 1516 virtioCoreQueueSync(pDevIns, &pThis->Virtio, RXQIDX_QPAIR(idxQueue)); 1483 1517 1518 1519 if (pThis->fLog) { 1520 RTThreadSleep(500); 1521 RT_BREAKPOINT(); 1522 pThis->fBp = false; 1523 } 1484 1524 RTMemFree(paVirtSegsToGuest); 1485 1525 RTMemFree(pVirtSegBufToGuest); … … 1815 1855 { 1816 1856 LogFunc(("%s Ignoring CTRL class VIRTIONET_CTRL_ANNOUNCE. Not configured to handle it\n", INSTANCE(pThis))); 1817 virtioNetPrintFeatures(pThis , pThis->fNegotiatedFeatures, "Features");1857 virtioNetPrintFeatures(pThis->fNegotiatedFeatures, "Features"); 1818 1858 break; 1819 1859 } … … 2173 2213 static DECLCALLBACK(int) virtioNetR3WorkerThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 2174 2214 { 2175 uint16_t const idxQueue 2215 uint16_t const idxQueue = (uint16_t)(uintptr_t)pThread->pvUser; 2176 2216 PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET); 2177 2217 PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC); … … 2438 2478 if (fVirtioReady) 2439 2479 { 2480 pThis->fBp = true; 2440 2481 LogFunc(("%s VirtIO ready\n-----------------------------------------------------------------------------------------\n", 2441 2482 INSTANCE(pThis))); … … 2444 2485 pThisCC->fQuiescing = false; 2445 2486 pThis->fNegotiatedFeatures = virtioCoreGetAcceptedFeatures(pVirtio); 2446 2487 virtioNetPrintFeatures(VIRTIONET_HOST_FEATURES_OFFERED, "Offered Features"); 2488 virtioNetPrintFeatures(pThis->fNegotiatedFeatures, "Negotiated Features"); 2447 2489 for (unsigned idxQueue = 0; idxQueue < pThis->cVirtQueues; idxQueue++) 2448 2490 {
Note:
See TracChangeset
for help on using the changeset viewer.