- Timestamp:
- Oct 27, 2021 5:55:32 AM (3 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 3 edited
-
Network/DevVirtioNet_1_0.cpp (modified) (19 diffs)
-
VirtIO/VirtioCore.cpp (modified) (8 diffs)
-
VirtIO/VirtioCore.h (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp
r91703 r92091 86 86 /** @} */ 87 87 88 static const VIRTIO_FEATURES_LIST s_aDevSpecificFeatures[] = 89 { 90 { VIRTIONET_F_CSUM, " CSUM Host handles packets with partial checksum.\n" }, 91 { VIRTIONET_F_GUEST_CSUM, " GUEST_CSUM Guest handles packets with partial checksum.\n" }, 92 { VIRTIONET_F_CTRL_GUEST_OFFLOADS, " CTRL_GUEST_OFFLOADS Control channel offloads reconfiguration support.\n" }, 93 { VIRTIONET_F_MAC, " MAC Host has given MAC address.\n" }, 94 { VIRTIONET_F_GUEST_TSO4, " GUEST_TSO4 Guest can receive TSOv4.\n" }, 95 { VIRTIONET_F_GUEST_TSO6, " GUEST_TSO6 Guest can receive TSOv6.\n" }, 96 { VIRTIONET_F_GUEST_ECN, " GUEST_ECN Guest can receive TSO with ECN.\n" }, 97 { VIRTIONET_F_GUEST_UFO, " GUEST_UFO Guest can receive UFO.\n" }, 98 { VIRTIONET_F_HOST_TSO4, " HOST_TSO4 Host can receive TSOv4.\n" }, 99 { VIRTIONET_F_HOST_TSO6, " HOST_TSO6 Host can receive TSOv6.\n" }, 100 { VIRTIONET_F_HOST_ECN, " HOST_ECN Host can receive TSO with ECN.\n" }, 101 { VIRTIONET_F_HOST_UFO, " HOST_UFO Host can receive UFO.\n" }, 102 { VIRTIONET_F_MRG_RXBUF, " MRG_RXBUF Guest can merge receive buffers.\n" }, 103 { VIRTIONET_F_STATUS, " STATUS Configuration status field is available.\n" }, 104 { VIRTIONET_F_CTRL_VQ, " CTRL_VQ Control channel is available.\n" }, 105 { VIRTIONET_F_CTRL_RX, " CTRL_RX Control channel RX mode support.\n" }, 106 { VIRTIONET_F_CTRL_VLAN, " CTRL_VLAN Control channel VLAN filtering.\n" }, 107 { VIRTIONET_F_GUEST_ANNOUNCE, " GUEST_ANNOUNCE Guest can send gratuitous packets.\n" }, 108 { VIRTIONET_F_MQ, " MQ Host supports multiqueue with automatic receive steering.\n" }, 109 { VIRTIONET_F_CTRL_MAC_ADDR, " CTRL_MAC_ADDR Set MAC address through control channel.\n" }, 110 }; 111 112 88 113 #ifdef VIRTIONET_WITH_GSO 89 114 # define VIRTIONET_HOST_FEATURES_GSO \ … … 293 318 /** @} */ 294 319 320 typedef enum VIRTIONETPKTHDRTYPE 321 { 322 kVirtioNetModernPktHdr_1_0 = 0, 323 kVirtioNetLegacyPktHdr = 1, 324 kVirtioNetLegacyPktHdrWithoutMrgRx = 2, 325 kVirtioNetFor32BitHack = 0x7fffffff 326 } VIRTIONETPKTHDRTYPE; 327 295 328 /** 296 329 * device-specific queue info … … 436 469 /** No broadcast mode - Supresses broadcast receive */ 437 470 uint8_t fNoBroadcast; 471 472 /** Type of network pkt header based on guest driver version/features */ 473 VIRTIONETPKTHDRTYPE ePktHdrType; 474 475 /** Size of network pkt header based on guest driver version/features */ 476 uint16_t cbPktHdr; 438 477 439 478 /** True if physical cable is attached in configuration. */ … … 551 590 static int virtioNetR3CreateWorkerThreads(PPDMDEVINS, PVIRTIONET, PVIRTIONETCC); 552 591 553 typedef enum VIRTIONETPKTHDRTYPE554 {555 kVirtioNetModernPktHdr_1_0 = 0,556 kVirtioNetLegacyPktHdr = 1,557 kVirtioNetLegacyPktHdrWithoutMrgRx = 2,558 kVirtioNetFor32BitHack = 0x7fffffff559 } VIRTIONETPKTHDRTYPE;560 561 DECLINLINE(int) virtioNetPktHdrType(PVIRTIOCORE pVirtio, PVIRTIONET pThis)562 {563 if (!virtioCoreIsLegacyMode(pVirtio))564 return kVirtioNetModernPktHdr_1_0;565 else /* legacy mode */566 if (FEATURE_ENABLED(MRG_RXBUF))567 return kVirtioNetLegacyPktHdrWithoutMrgRx;568 return kVirtioNetLegacyPktHdr;569 }570 571 DECLINLINE(size_t) virtioNetCalcPktHdrSize(PVIRTIOCORE pVirtio, PVIRTIONET pThis)572 {573 size_t cbHdr = sizeof(VIRTIONETPKTHDR);574 if (virtioCoreIsLegacyMode(pVirtio) & !FEATURE_ENABLED(MRG_RXBUF))575 cbHdr -= RT_SIZEOFMEMB(VIRTIONETPKTHDR, uNumBuffers);576 return cbHdr;577 }578 579 592 DECLINLINE(const char *) virtioNetThreadStateName(PPDMTHREAD pThread) 580 593 { … … 720 733 } 721 734 722 DECLINLINE(void) virtioNetPrintFeatures(VIRTIONET *pThis, PCDBGFINFOHLP pHlp)723 {724 static struct725 {726 uint64_t fFeatureBit;727 const char *pcszDesc;728 } const s_aFeatures[] =729 {730 { VIRTIONET_F_CSUM, " CSUM Host handles packets with partial checksum.\n" },731 { VIRTIONET_F_GUEST_CSUM, " GUEST_CSUM Guest handles packets with partial checksum.\n" },732 { VIRTIONET_F_CTRL_GUEST_OFFLOADS, " CTRL_GUEST_OFFLOADS Control channel offloads reconfiguration support.\n" },733 { VIRTIONET_F_MAC, " MAC Host has given MAC address.\n" },734 { VIRTIONET_F_GUEST_TSO4, " GUEST_TSO4 Guest can receive TSOv4.\n" },735 { VIRTIONET_F_GUEST_TSO6, " GUEST_TSO6 Guest can receive TSOv6.\n" },736 { VIRTIONET_F_GUEST_ECN, " GUEST_ECN Guest can receive TSO with ECN.\n" },737 { VIRTIONET_F_GUEST_UFO, " GUEST_UFO Guest can receive UFO.\n" },738 { VIRTIONET_F_HOST_TSO4, " HOST_TSO4 Host can receive TSOv4.\n" },739 { VIRTIONET_F_HOST_TSO6, " HOST_TSO6 Host can receive TSOv6.\n" },740 { VIRTIONET_F_HOST_ECN, " HOST_ECN Host can receive TSO with ECN.\n" },741 { VIRTIONET_F_HOST_UFO, " HOST_UFO Host can receive UFO.\n" },742 { VIRTIONET_F_MRG_RXBUF, " MRG_RXBUF Guest can merge receive buffers.\n" },743 { VIRTIONET_F_STATUS, " STATUS Configuration status field is available.\n" },744 { VIRTIONET_F_CTRL_VQ, " CTRL_VQ Control channel is available.\n" },745 { VIRTIONET_F_CTRL_RX, " CTRL_RX Control channel RX mode support.\n" },746 { VIRTIONET_F_CTRL_VLAN, " CTRL_VLAN Control channel VLAN filtering.\n" },747 { VIRTIONET_F_GUEST_ANNOUNCE, " GUEST_ANNOUNCE Guest can send gratuitous packets.\n" },748 { VIRTIONET_F_MQ, " MQ Host supports multiqueue with automatic receive steering.\n" },749 { VIRTIONET_F_CTRL_MAC_ADDR, " CTRL_MAC_ADDR Set MAC address through control channel.\n" }750 };751 752 #define MAXLINE 80753 /* Display as a single buf to prevent interceding log messages */754 uint64_t fFeaturesOfferedMask = VIRTIONET_HOST_FEATURES_OFFERED;755 uint16_t cbBuf = RT_ELEMENTS(s_aFeatures) * 132;756 char *pszBuf = (char *)RTMemAllocZ(cbBuf);757 Assert(pszBuf);758 char *cp = pszBuf;759 for (unsigned i = 0; i < RT_ELEMENTS(s_aFeatures); ++i)760 {761 uint64_t isOffered = fFeaturesOfferedMask & s_aFeatures[i].fFeatureBit;762 uint64_t isNegotiated = pThis->fNegotiatedFeatures & s_aFeatures[i].fFeatureBit;763 cp += RTStrPrintf(cp, cbBuf - (cp - pszBuf), " %s %s %s",764 isOffered ? "+" : "-", isNegotiated ? "x" : " ", s_aFeatures[i].pcszDesc);765 }766 if (pHlp)767 pHlp->pfnPrintf(pHlp, "VirtIO Net Features Configuration\n\n"768 " Offered Accepted Feature Description\n"769 " ------- -------- ------- -----------\n"770 "%s\n", pszBuf);771 #ifdef LOG_ENABLED772 else773 Log3(("VirtIO Net Features Configuration\n\n"774 " Offered Accepted Feature Description\n"775 " ------- -------- ------- -----------\n"776 "%s\n", pszBuf));777 #endif778 RTMemFree(pszBuf);779 }780 735 781 736 #ifdef LOG_ENABLED … … 843 798 if (fAll || fFeatures) 844 799 { 845 virtioCorePrint Features(&pThis->Virtio, pHlp);846 virtioNetPrintFeatures(pThis, pHlp);800 virtioCorePrintDeviceFeatures(&pThis->Virtio, pHlp, s_aDevSpecificFeatures, 801 RT_ELEMENTS(s_aDevSpecificFeatures)); 847 802 pHlp->pfnPrintf(pHlp, "\n"); 848 803 } … … 1584 1539 uint64_t uOffset = 0; 1585 1540 1586 int uPktHdrType = virtioNetPktHdrType(&pThis->Virtio, pThis);1587 1588 1541 while (uOffset < cb) 1589 1542 { … … 1604 1557 * Re-visit if needed */ 1605 1558 1606 size_t cbPktHdr = virtioNetCalcPktHdrSize(&pThis->Virtio, pThis); 1607 1608 AssertMsgReturn(pVirtqBuf->pSgPhysReturn->paSegs[0].cbSeg >= cbPktHdr, 1559 AssertMsgReturn(pVirtqBuf->pSgPhysReturn->paSegs[0].cbSeg >= pThis->cbPktHdr, 1609 1560 ("Out of Memory"), VERR_NO_MEMORY); 1610 1561 … … 1618 1569 { 1619 1570 /* Lead with packet header */ 1620 paVirtSegsToGuest[0].cbSeg = cbPktHdr;1621 paVirtSegsToGuest[0].pvSeg = RTMemAlloc( cbPktHdr);1571 paVirtSegsToGuest[0].cbSeg = pThis->cbPktHdr; 1572 paVirtSegsToGuest[0].pvSeg = RTMemAlloc(pThis->cbPktHdr); 1622 1573 AssertReturn(paVirtSegsToGuest[0].pvSeg, VERR_NO_MEMORY); 1623 cbBufRemaining -= cbPktHdr;1624 1625 memcpy(paVirtSegsToGuest[0].pvSeg, rxPktHdr, cbPktHdr);1626 1627 if ( uPktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx)1574 cbBufRemaining -= pThis->cbPktHdr; 1575 1576 memcpy(paVirtSegsToGuest[0].pvSeg, rxPktHdr, pThis->cbPktHdr); 1577 1578 if (pThis->ePktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx) 1628 1579 { 1629 1580 /* Calculate & cache GCPhys addr of field to update after final value is known */ … … 1672 1623 1673 1624 1674 if ( uPktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx)1625 if (pThis->ePktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx) 1675 1626 { 1676 1627 /* Fix-up pkthdr (in guest phys. memory) with number buffers (descriptors) processed */ … … 2196 2147 static int virtioNetR3ReadHeader(PVIRTIOCORE pVirtio, PVIRTIONET pThis, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PVIRTIONETPKTHDR pPktHdr, size_t cbFrame) 2197 2148 { 2198 size_t cbPktHdr = virtioNetCalcPktHdrSize(pVirtio, pThis); 2199 int rc = virtioCoreGCPhysRead(pVirtio, pDevIns, GCPhys, pPktHdr, cbPktHdr); 2149 int rc = virtioCoreGCPhysRead(pVirtio, pDevIns, GCPhys, pPktHdr, pThis->cbPktHdr); 2200 2150 if (RT_FAILURE(rc)) 2201 2151 return rc; … … 2365 2315 size_t uSize = 0; 2366 2316 2367 size_t cbPktHdr = virtioNetCalcPktHdrSize(pVirtio, pThis); 2368 2369 AssertMsgReturn(paSegsFromGuest[0].cbSeg >= cbPktHdr, 2317 AssertMsgReturn(paSegsFromGuest[0].cbSeg >= pThis->cbPktHdr, 2370 2318 ("Desc chain's first seg has insufficient space for pkt header!\n"), 2371 2319 VERR_INTERNAL_ERROR); 2372 2320 2373 PVIRTIONETPKTHDR pPktHdr = (PVIRTIONETPKTHDR)RTMemAllocZ( cbPktHdr);2321 PVIRTIONETPKTHDR pPktHdr = (PVIRTIONETPKTHDR)RTMemAllocZ(pThis->cbPktHdr); 2374 2322 AssertMsgReturn(pPktHdr, ("Out of Memory\n"), VERR_NO_MEMORY); 2375 2323 … … 2389 2337 uint64_t uOffset; 2390 2338 2391 uSize -= cbPktHdr;2339 uSize -= pThis->cbPktHdr; 2392 2340 rc = virtioNetR3ReadHeader(pVirtio, pThis, pDevIns, paSegsFromGuest[0].GCPhys, pPktHdr, uSize); 2393 2341 if (RT_FAILURE(rc)) 2394 2342 return rc; 2395 virtioCoreGCPhysChainAdvance(pSgPhysSend, cbPktHdr);2343 virtioCoreGCPhysChainAdvance(pSgPhysSend, pThis->cbPktHdr); 2396 2344 2397 2345 PDMNETWORKGSO Gso, *pGso = virtioNetR3SetupGsoCtx(&Gso, pPktHdr); … … 2787 2735 } 2788 2736 2737 2789 2738 /** 2790 2739 * @callback_method_impl{VIRTIOCORER3,pfnStatusChanged} … … 2804 2753 2805 2754 pThis->fNegotiatedFeatures = virtioCoreGetNegotiatedFeatures(pVirtio); 2806 2807 2755 #ifdef LOG_ENABLED 2808 virtioCorePrint Features(pVirtio, NULL);2809 virtioNetPrintFeatures(pThis, NULL);2756 virtioCorePrintDeviceFeatures(&pThis->Virtio, NULL, s_aDevSpecificFeatures, 2757 RT_ELEMENTS(s_aDevSpecificFeatures)); 2810 2758 #endif 2811 2759 … … 2857 2805 } 2858 2806 } 2807 2808 static DECLCALLBACK(void) virtioGuestVersionHandler(PVIRTIOCORE pVirtio, uint32_t fModern) 2809 { 2810 LogFunc(("Guest Driver version is %s\n", fModern ? "modern" : "legacy")); 2811 2812 PVIRTIONET pThis = RT_FROM_MEMBER(pVirtio, VIRTIONET, Virtio); 2813 2814 /* Calculate network packet header type and size based on what we know now */ 2815 pThis->cbPktHdr = sizeof(VIRTIONETPKTHDR); 2816 2817 if (fModern) 2818 pThis->ePktHdrType = kVirtioNetModernPktHdr_1_0; 2819 else if (FEATURE_DISABLED(MRG_RXBUF)) 2820 { 2821 pThis->ePktHdrType = kVirtioNetLegacyPktHdrWithoutMrgRx; 2822 pThis->cbPktHdr -= RT_SIZEOFMEMB(VIRTIONETPKTHDR, uNumBuffers); 2823 } 2824 else /* Legacy guest with MRG_RX feature enabled */ 2825 pThis->ePktHdrType = kVirtioNetLegacyPktHdr; 2826 } 2827 2828 2859 2829 #endif /* IN_RING3 */ 2860 2830 … … 2927 2897 2928 2898 /** 2929 * @interface_method_impl{PDMIBASE,pfnQueryInterface ,2899 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 2930 2900 */ 2931 2901 static DECLCALLBACK(void *) virtioNetR3QueryInterface(struct PDMIBASE *pInterface, const char *pszIID) … … 3045 3015 3046 3016 pThis->virtioNetConfig.uMaxVirtqPairs = VIRTIONET_MAX_QPAIRS; 3047 3017 pThisCC->Virtio.pfnGuestVersionHandler = virtioGuestVersionHandler; 3048 3018 pThisCC->Virtio.pfnVirtqNotified = virtioNetVirtqNotified; 3049 3019 pThisCC->Virtio.pfnStatusChanged = virtioNetR3StatusChg; … … 3125 3095 else if ( rc == VERR_PDM_NO_ATTACHED_DRIVER 3126 3096 || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME) 3097 { 3127 3098 Log(("[%s] No attached driver!\n", pThis->szInst)); 3099 AssertRCReturn(rc, rc); 3100 } 3101 3128 3102 /* 3129 3103 * Status driver -
trunk/src/VBox/Devices/VirtIO/VirtioCore.cpp
r91706 r92091 329 329 #ifdef IN_RING3 330 330 331 /** API Function: See header file*/ 332 void virtioCorePrintFeatures(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp) 333 { 334 static struct 335 { 336 uint64_t fFeatureBit; 337 const char *pcszDesc; 338 } const s_aFeatures[] = 339 { 340 { VIRTIO_F_RING_INDIRECT_DESC, " RING_INDIRECT_DESC Driver can use descriptors with VIRTQ_DESC_F_INDIRECT flag set\n" }, 341 { VIRTIO_F_RING_EVENT_IDX, " RING_EVENT_IDX Enables use_event and avail_event fields described in 2.4.7, 2.4.8\n" }, 342 { VIRTIO_F_VERSION_1, " VERSION Used to detect legacy drivers.\n" }, 343 }; 344 331 void virtioCoreR3FeatureDump(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp, const VIRTIO_FEATURES_LIST *s_aFeatures, int cFeatures, int fBanner) 332 { 345 333 #define MAXLINE 80 346 334 /* Display as a single buf to prevent interceding log messages */ 347 uint16_t cbBuf = RT_ELEMENTS(s_aFeatures)* 132;335 uint16_t cbBuf = cFeatures * 132; 348 336 char *pszBuf = (char *)RTMemAllocZ(cbBuf); 349 337 Assert(pszBuf); 350 338 char *cp = pszBuf; 351 for ( unsigned i = 0; i < RT_ELEMENTS(s_aFeatures); ++i)339 for (int i = 0; i < cFeatures; ++i) 352 340 { 353 341 bool isOffered = RT_BOOL(pVirtio->uDeviceFeatures & s_aFeatures[i].fFeatureBit); … … 356 344 isOffered ? "+" : "-", isNegotiated ? "x" : " ", s_aFeatures[i].pcszDesc); 357 345 } 358 if (pHlp) 359 pHlp->pfnPrintf(pHlp, "VirtIO Core Features Configuration\n\n" 360 " Offered Accepted Feature Description\n" 361 " ------- -------- ------- -----------\n" 362 "%s\n", pszBuf); 346 if (pHlp) { 347 if (fBanner) 348 pHlp->pfnPrintf(pHlp, "VirtIO Features Configuration\n\n" 349 " Offered Accepted Feature Description\n" 350 " ------- -------- ------- -----------\n"); 351 pHlp->pfnPrintf(pHlp, "%s\n", pszBuf); 352 } 363 353 #ifdef LOG_ENABLED 364 354 else 365 Log3(("VirtIO Core Features Configuration\n\n" 366 " Offered Accepted Feature Description\n" 367 " ------- -------- ------- -----------\n" 368 "%s\n", pszBuf)); 355 { 356 if (fBanner) 357 Log(("VirtIO Features Configuration\n\n" 358 " Offered Accepted Feature Description\n" 359 " ------- -------- ------- -----------\n")); 360 Log(("%s\n", pszBuf)); 361 } 369 362 #endif 370 363 RTMemFree(pszBuf); 371 364 } 365 366 /** API Function: See header file*/ 367 void virtioCorePrintDeviceFeatures(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp, 368 const VIRTIO_FEATURES_LIST *s_aDevSpecificFeatures, int cFeatures) { 369 virtioCoreR3FeatureDump(pVirtio, pHlp, s_aCoreFeatures, RT_ELEMENTS(s_aCoreFeatures), 1 /*fBanner */); 370 virtioCoreR3FeatureDump(pVirtio, pHlp, s_aDevSpecificFeatures, cFeatures, 0 /*fBanner */); 371 } 372 372 373 #endif 373 374 … … 1232 1233 memcpy((char *)&pVirtio->uDriverFeatures + sizeof(uint32_t), pv, cb); 1233 1234 if (pVirtio->uDriverFeatures & VIRTIO_F_VERSION_1) 1235 { 1236 #ifdef IN_RING0 1237 return VINF_IOM_R3_MMIO_WRITE; 1238 #endif 1239 #ifdef IN_RING3 1234 1240 pVirtio->fLegacyDriver = 0; 1241 pVirtioCC->pfnGuestVersionHandler(pVirtio, 1 /* fModern */); 1242 #endif 1243 } 1235 1244 VIRTIO_DEV_CONFIG_LOG_ACCESS(uDriverFeatures, VIRTIO_PCI_COMMON_CFG_T, uOffsetOfAccess + sizeof(uint32_t)); 1236 1245 break; … … 1388 1397 1389 1398 RT_NOREF(pvUser); 1390 // LogFunc((" Read from port offset=%RTiop cb=%#x\n", offPort, cb));1391 1399 1392 1400 void *pv = pu32; /* To use existing macros */ … … 2018 2026 for (int uVirtq = 0; uVirtq < VIRTQ_MAX_COUNT; uVirtq++) 2019 2027 { 2020 if (!pVirtio->fLegacyDriver || pVirtio->aVirtqueues[uVirtq].uEnable) 2021 virtioCoreNotifyGuestDriver(pVirtio->pDevInsR3, pVirtio, uVirtq); 2028 if ((!pVirtio->fLegacyDriver && pVirtio->aVirtqueues[uVirtq].uEnable) 2029 | pVirtio->aVirtqueues[uVirtq].GCPhysVirtqDesc) 2030 virtioCoreNotifyGuestDriver(pVirtio->pDevInsR3, pVirtio, uVirtq); 2022 2031 } 2023 2032 break; … … 2050 2059 const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg) 2051 2060 { 2052 2053 2054 2061 /* 2055 2062 * The pVirtio state must be the first member of the shared device instance … … 2066 2073 AssertReturn(pVirtioCC->pfnStatusChanged, VERR_INVALID_POINTER); 2067 2074 AssertReturn(pVirtioCC->pfnVirtqNotified, VERR_INVALID_POINTER); 2075 AssertReturn(pVirtioCC->pfnGuestVersionHandler, VERR_INVALID_POINTER); 2068 2076 AssertReturn(VIRTQ_SIZE > 0 && VIRTQ_SIZE <= 32768, VERR_OUT_OF_RANGE); /* VirtIO specification-defined limit */ 2069 2077 … … 2076 2084 #endif 2077 2085 2086 /* Tell the device-specific code that guest is in legacy mode (for now) */ 2087 pVirtioCC->pfnGuestVersionHandler(pVirtio, false /* fModern */); 2078 2088 2079 2089 /* -
trunk/src/VBox/Devices/VirtIO/VirtioCore.h
r91703 r92091 140 140 } VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS; 141 141 142 /* Virtio Platform Indepdented Reserved Feature Bits (see 1.1 specification section 6) */ 142 143 /* Virtio Platform Independent Reserved Feature Bits (see 1.1 specification section 6) */ 143 144 144 145 #define VIRTIO_F_NOTIFY_ON_EMPTY RT_BIT_64(24) /**< Legacy feature: Force intr if no AVAIL */ 145 146 #define VIRTIO_F_ANY_LAYOUT RT_BIT_64(27) /**< Doc bug: Goes under two names in spec */ 147 #define VIRTIO_F_RING_INDIRECT_DESC RT_BIT_64(28) /**< Doc bug: Goes under two names in spec */ 146 148 #define VIRTIO_F_INDIRECT_DESC RT_BIT_64(28) /**< Allow descs to point to list of descs */ 147 #define VIRTIO_F_RING_ INDIRECT_DESC RT_BIT_64(28) /**< Doc bug: Goes under two names in spec */149 #define VIRTIO_F_RING_EVENT_IDX RT_BIT_64(29) /**< Doc bug: Goes under two names in spec */ 148 150 #define VIRTIO_F_EVENT_IDX RT_BIT_64(29) /**< Allow notification disable for n elems */ 149 #define VIRTIO_F_RING_EVENT_IDX RT_BIT_64(29) /**< Doc bug: Goes under two names in spec */150 151 #define VIRTIO_F_BAD_FEATURE RT_BIT_64(30) /**< QEMU kludge. UNUSED as of >= VirtIO 1.0 */ 151 152 #define VIRTIO_F_VERSION_1 RT_BIT_64(32) /**< Required feature bit for 1.0 devices */ … … 157 158 #define VIRTIO_F_NOTIFICAITON_DATA RT_BIT_64(38) /**< Driver passes extra data (VirtIO 1.1 NYI) */ 158 159 160 typedef struct VIRTIO_FEATURES_LIST 161 { 162 uint64_t fFeatureBit; 163 const char *pcszDesc; 164 } VIRTIO_FEATURES_LIST, *PVIRTIO_FEATURES_LIST; 165 166 static const VIRTIO_FEATURES_LIST s_aCoreFeatures[] = 167 { 168 { VIRTIO_F_RING_INDIRECT_DESC, " RING_INDIRECT_DESC Driver can use descriptors with VIRTQ_DESC_F_INDIRECT flag set\n" }, 169 { VIRTIO_F_RING_EVENT_IDX, " RING_EVENT_IDX Enables use_event and avail_event fields described in 2.4.7, 2.4.8\n" }, 170 { VIRTIO_F_VERSION_1, " VERSION Used to detect legacy drivers.\n" }, 171 }; 172 173 159 174 #define VIRTIO_DEV_INDEPENDENT_FEATURES_OFFERED ( 0 ) /**< TBD: Add VIRTIO_F_INDIRECT_DESC */ 160 175 #define VIRTIO_DEV_INDEPENDENT_LEGACY_FEATURES_OFFERED ( 0 ) /**< Only offered to legacy drivers */ … … 187 202 kvirtIoVmStateChangedFor32BitHack = 0x7fffffff 188 203 } VIRTIOVMSTATECHANGED; 204 205 189 206 190 207 /** @def Virtio Device PCI Capabilities type codes */ … … 229 246 uint8_t fDeviceStatus; /**< RW (driver writes device status, 0=reset) */ 230 247 uint8_t fIsrStatus; /**< RW (driver writes ISR status, 0=reset) */ 231 // uint16_t uMsixConfig; /**< RW (driver sets MSI-X config vector) */ 232 // uint16_t uMsixVector; /**< RW (driver sets MSI-X config vector) */ 248 #ifdef LEGACY_MSIX_SUPPORTED 249 uint16_t uMsixConfig; /**< RW (driver sets MSI-X config vector) */ 250 uint16_t uMsixVector; /**< RW (driver sets MSI-X config vector) */ 251 #endif 233 252 } VIRTIO_LEGACY_PCI_COMMON_CFG_T, *PVIRTIO_LEGACY_PCI_COMMON_CFG_T; 234 253 … … 323 342 uint8_t uISR; /**< Interrupt Status Register. */ 324 343 uint8_t fMsiSupport; /**< Flag set if using MSI instead of ISR */ 325 uint8_t fLegacyDriver; /**< Set if guest driver < VirtIO 1.0 */326 344 uint16_t uVirtqSelect; /**< (MMIO) queue selector GUEST */ 345 uint32_t fLegacyDriver; /**< Set if guest driver < VirtIO 1.0 */ 327 346 328 347 /** @name The locations of the capability structures in PCI config space and the BAR. … … 356 375 #endif 357 376 377 358 378 /** @} */ 359 379 } VIRTIOCORE; … … 368 388 /** @name Callbacks filled by the device before calling virtioCoreR3Init. 369 389 * @{ */ 390 /** 391 * Implementation-specific client callback to report VirtIO version as modern or legacy. 392 * That's the only meaningful distinction in the VirtIO specification. Beyond that 393 * versioning is loosely discernable through feature negotiation. There will be two callbacks, 394 * the first indicates the guest driver is considered legacy VirtIO, as it is critical to 395 * assume that initially. A 2nd callback will occur during feature negotiation 396 * which will indicate the guest is modern, if the guest acknowledges VIRTIO_F_VERSION_1, 397 * feature, or legacy if the feature isn't negotiated. That 2nd callback allows 398 * the device-specific code to configure its behavior in terms of both guest version and features. 399 * 400 * @param pVirtio Pointer to the shared virtio state. 401 * @param fModern True if guest driver identified itself as modern (e.g. VirtIO 1.0 featured) 402 */ 403 DECLCALLBACKMEMBER(void, pfnGuestVersionHandler,(PVIRTIOCORE pVirtio, uint32_t fModern)); 404 370 405 /** 371 406 * Implementation-specific client callback to notify client of significant device status … … 391 426 392 427 /** 393 * Implementation-specific client ballback to access VirtIO Device-specific capabilities428 * Implementation-specific client callback to access VirtIO Device-specific capabilities 394 429 * (other VirtIO capabilities and features are handled in VirtIO implementation) 395 430 * … … 546 581 547 582 /** 548 * Displays the VirtIO spec-related features offered by the core component, 549 * as well as which features have been negotiated and accepted or declined by the guest driver, 550 * providing a summary view of the configuration the device is operating with. 583 * Displays the VirtIO spec-related features offered and their accepted/declined status 584 * by both the VirtIO core and dev-specific device code (which invokes this function). 585 * The result is a comprehensive list of available features the VirtIO specification 586 * defines, which ones were actually offered by the device, and which ones were accepted 587 * by the guest driver, thus providing a legible summary view of the configuration 588 * the device is operating with. 551 589 * 552 590 * @param pVirtio Pointer to the shared virtio state. 553 591 * @param pHlp Pointer to the debug info hlp struct 554 */ 555 void virtioCorePrintFeatures(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp); 592 * @param s_aDevSpecificFeatures 593 * Features specification lists for device-specific implementation 594 * (i.e: net controller, scsi controller ...) 595 * @param cFeatures Number of features in aDevSpecificFeatures 596 */ 597 void virtioCorePrintDeviceFeatures(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp, 598 const VIRTIO_FEATURES_LIST *aDevSpecificFeatures, int cFeatures); 556 599 557 600 /* … … 711 754 * If not, it's presumed to be a VirtIO legacy guest driver. Note that legacy drivers 712 755 * may start using the device prematurely, as opposed to the rigorously sane protocol 713 * prescribed by the "modern" VirtIO spec. Doing so is suggestive ofa legacy driver.714 * Therefore legacy mode is the assumption un proven otherwise.756 * prescribed by the "modern" VirtIO spec. Early access implies a legacy driver. 757 * Therefore legacy mode is the assumption until feature negotiation. 715 758 * 716 759 * @param pVirtio Pointer to the virtio state.
Note:
See TracChangeset
for help on using the changeset viewer.

