VirtualBox

Changeset 92091 in vbox for trunk


Ignore:
Timestamp:
Oct 27, 2021 5:55:32 AM (3 years ago)
Author:
vboxsync
Message:

Optimize how legacy/modern driver is determined to avoid polling, and eliminate code duplication for feature logging

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

Legend:

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

    r91703 r92091  
    8686/** @} */
    8787
     88static 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
    88113#ifdef VIRTIONET_WITH_GSO
    89114# define VIRTIONET_HOST_FEATURES_GSO    \
     
    293318/** @} */
    294319
     320typedef enum VIRTIONETPKTHDRTYPE
     321{
     322    kVirtioNetModernPktHdr_1_0          = 0,
     323    kVirtioNetLegacyPktHdr              = 1,
     324    kVirtioNetLegacyPktHdrWithoutMrgRx  = 2,
     325    kVirtioNetFor32BitHack              = 0x7fffffff
     326} VIRTIONETPKTHDRTYPE;
     327
    295328/**
    296329 * device-specific queue info
     
    436469    /** No broadcast mode - Supresses broadcast receive */
    437470    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;
    438477
    439478    /** True if physical cable is attached in configuration. */
     
    551590static int virtioNetR3CreateWorkerThreads(PPDMDEVINS, PVIRTIONET, PVIRTIONETCC);
    552591
    553 typedef enum VIRTIONETPKTHDRTYPE
    554 {
    555     kVirtioNetModernPktHdr_1_0          = 0,
    556     kVirtioNetLegacyPktHdr              = 1,
    557     kVirtioNetLegacyPktHdrWithoutMrgRx  = 2,
    558     kVirtioNetFor32BitHack              = 0x7fffffff
    559 } 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 
    579592DECLINLINE(const char *) virtioNetThreadStateName(PPDMTHREAD pThread)
    580593{
     
    720733}
    721734
    722 DECLINLINE(void) virtioNetPrintFeatures(VIRTIONET *pThis, PCDBGFINFOHLP pHlp)
    723 {
    724     static struct
    725     {
    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 80
    753     /* 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_ENABLED
    772     else
    773         Log3(("VirtIO Net Features Configuration\n\n"
    774               "    Offered  Accepted  Feature              Description\n"
    775               "    -------  --------  -------              -----------\n"
    776               "%s\n", pszBuf));
    777 #endif
    778     RTMemFree(pszBuf);
    779 }
    780735
    781736#ifdef LOG_ENABLED
     
    843798    if (fAll || fFeatures)
    844799    {
    845         virtioCorePrintFeatures(&pThis->Virtio, pHlp);
    846         virtioNetPrintFeatures(pThis, pHlp);
     800        virtioCorePrintDeviceFeatures(&pThis->Virtio, pHlp, s_aDevSpecificFeatures,
     801            RT_ELEMENTS(s_aDevSpecificFeatures));
    847802        pHlp->pfnPrintf(pHlp, "\n");
    848803    }
     
    15841539    uint64_t uOffset = 0;
    15851540
    1586     int uPktHdrType = virtioNetPktHdrType(&pThis->Virtio,  pThis);
    1587 
    15881541    while (uOffset < cb)
    15891542    {
     
    16041557         * Re-visit if needed */
    16051558
    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,
    16091560                            ("Out of Memory"), VERR_NO_MEMORY);
    16101561
     
    16181569            {
    16191570                /* 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);
    16221573                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)
    16281579                {
    16291580                    /* Calculate & cache GCPhys addr of field to update after final value is known */
     
    16721623
    16731624
    1674     if (uPktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx)
     1625    if (pThis->ePktHdrType != kVirtioNetLegacyPktHdrWithoutMrgRx)
    16751626    {
    16761627        /* Fix-up pkthdr (in guest phys. memory) with number buffers (descriptors) processed */
     
    21962147static int virtioNetR3ReadHeader(PVIRTIOCORE pVirtio, PVIRTIONET pThis, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, PVIRTIONETPKTHDR pPktHdr, size_t cbFrame)
    21972148{
    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);
    22002150    if (RT_FAILURE(rc))
    22012151        return rc;
     
    23652315        size_t uSize = 0;
    23662316
    2367         size_t cbPktHdr = virtioNetCalcPktHdrSize(pVirtio, pThis);
    2368 
    2369         AssertMsgReturn(paSegsFromGuest[0].cbSeg >= cbPktHdr,
     2317        AssertMsgReturn(paSegsFromGuest[0].cbSeg >= pThis->cbPktHdr,
    23702318                        ("Desc chain's first seg has insufficient space for pkt header!\n"),
    23712319                        VERR_INTERNAL_ERROR);
    23722320
    2373         PVIRTIONETPKTHDR pPktHdr = (PVIRTIONETPKTHDR)RTMemAllocZ(cbPktHdr);
     2321        PVIRTIONETPKTHDR pPktHdr = (PVIRTIONETPKTHDR)RTMemAllocZ(pThis->cbPktHdr);
    23742322        AssertMsgReturn(pPktHdr, ("Out of Memory\n"), VERR_NO_MEMORY);
    23752323
     
    23892337            uint64_t uOffset;
    23902338
    2391             uSize -= cbPktHdr;
     2339            uSize -= pThis->cbPktHdr;
    23922340            rc = virtioNetR3ReadHeader(pVirtio, pThis, pDevIns, paSegsFromGuest[0].GCPhys, pPktHdr, uSize);
    23932341            if (RT_FAILURE(rc))
    23942342                return rc;
    2395             virtioCoreGCPhysChainAdvance(pSgPhysSend, cbPktHdr);
     2343            virtioCoreGCPhysChainAdvance(pSgPhysSend, pThis->cbPktHdr);
    23962344
    23972345            PDMNETWORKGSO  Gso, *pGso = virtioNetR3SetupGsoCtx(&Gso, pPktHdr);
     
    27872735}
    27882736
     2737
    27892738/**
    27902739 * @callback_method_impl{VIRTIOCORER3,pfnStatusChanged}
     
    28042753
    28052754        pThis->fNegotiatedFeatures = virtioCoreGetNegotiatedFeatures(pVirtio);
    2806 
    28072755#ifdef LOG_ENABLED
    2808         virtioCorePrintFeatures(pVirtio, NULL);
    2809         virtioNetPrintFeatures(pThis, NULL);
     2756        virtioCorePrintDeviceFeatures(&pThis->Virtio, NULL, s_aDevSpecificFeatures,
     2757            RT_ELEMENTS(s_aDevSpecificFeatures));
    28102758#endif
    28112759
     
    28572805    }
    28582806}
     2807
     2808static 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
    28592829#endif /* IN_RING3 */
    28602830
     
    29272897
    29282898/**
    2929  * @interface_method_impl{PDMIBASE,pfnQueryInterface,
     2899 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
    29302900 */
    29312901static DECLCALLBACK(void *) virtioNetR3QueryInterface(struct PDMIBASE *pInterface, const char *pszIID)
     
    30453015
    30463016    pThis->virtioNetConfig.uMaxVirtqPairs   = VIRTIONET_MAX_QPAIRS;
    3047 
     3017    pThisCC->Virtio.pfnGuestVersionHandler  = virtioGuestVersionHandler;
    30483018    pThisCC->Virtio.pfnVirtqNotified        = virtioNetVirtqNotified;
    30493019    pThisCC->Virtio.pfnStatusChanged        = virtioNetR3StatusChg;
     
    31253095    else if (   rc == VERR_PDM_NO_ATTACHED_DRIVER
    31263096             || rc == VERR_PDM_CFG_MISSING_DRIVER_NAME)
     3097    {
    31273098                    Log(("[%s] No attached driver!\n", pThis->szInst));
     3099                    AssertRCReturn(rc, rc);
     3100    }
     3101
    31283102    /*
    31293103     * Status driver
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.cpp

    r91706 r92091  
    329329#ifdef IN_RING3
    330330
    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 
     331void virtioCoreR3FeatureDump(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp, const VIRTIO_FEATURES_LIST *s_aFeatures, int cFeatures, int fBanner)
     332{
    345333#define MAXLINE 80
    346334    /* 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;
    348336    char *pszBuf = (char *)RTMemAllocZ(cbBuf);
    349337    Assert(pszBuf);
    350338    char *cp = pszBuf;
    351     for (unsigned i = 0; i < RT_ELEMENTS(s_aFeatures); ++i)
     339    for (int i = 0; i < cFeatures; ++i)
    352340    {
    353341        bool isOffered    = RT_BOOL(pVirtio->uDeviceFeatures & s_aFeatures[i].fFeatureBit);
     
    356344                          isOffered ? "+" : "-", isNegotiated ? "x" : " ", s_aFeatures[i].pcszDesc);
    357345    }
    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    }
    363353#ifdef LOG_ENABLED
    364354    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    }
    369362#endif
    370363    RTMemFree(pszBuf);
    371364}
     365
     366/** API Function: See header file*/
     367void  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
    372373#endif
    373374
     
    12321233                    memcpy((char *)&pVirtio->uDriverFeatures + sizeof(uint32_t), pv, cb);
    12331234                    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
    12341240                        pVirtio->fLegacyDriver = 0;
     1241                        pVirtioCC->pfnGuestVersionHandler(pVirtio, 1 /* fModern */);
     1242#endif
     1243                    }
    12351244                    VIRTIO_DEV_CONFIG_LOG_ACCESS(uDriverFeatures, VIRTIO_PCI_COMMON_CFG_T, uOffsetOfAccess + sizeof(uint32_t));
    12361245                    break;
     
    13881397
    13891398    RT_NOREF(pvUser);
    1390 //    LogFunc((" Read from port offset=%RTiop cb=%#x\n",  offPort, cb));
    13911399
    13921400    void *pv = pu32; /* To use existing macros */
     
    20182026            for (int uVirtq = 0; uVirtq < VIRTQ_MAX_COUNT; uVirtq++)
    20192027            {
    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);
    20222031            }
    20232032            break;
     
    20502059                     const char *pcszInstance, uint64_t fDevSpecificFeatures, void *pvDevSpecificCfg, uint16_t cbDevSpecificCfg)
    20512060{
    2052 
    2053 
    20542061    /*
    20552062     * The pVirtio state must be the first member of the shared device instance
     
    20662073    AssertReturn(pVirtioCC->pfnStatusChanged, VERR_INVALID_POINTER);
    20672074    AssertReturn(pVirtioCC->pfnVirtqNotified, VERR_INVALID_POINTER);
     2075    AssertReturn(pVirtioCC->pfnGuestVersionHandler,  VERR_INVALID_POINTER);
    20682076    AssertReturn(VIRTQ_SIZE > 0 && VIRTQ_SIZE <= 32768,  VERR_OUT_OF_RANGE); /* VirtIO specification-defined limit */
    20692077
     
    20762084#endif
    20772085
     2086    /* Tell the device-specific code that guest is in legacy mode (for now) */
     2087    pVirtioCC->pfnGuestVersionHandler(pVirtio, false /* fModern */);
    20782088
    20792089    /*
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.h

    r91703 r92091  
    140140} VIRTIOPCIPARAMS, *PVIRTIOPCIPARAMS;
    141141
    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) */
    143144
    144145#define VIRTIO_F_NOTIFY_ON_EMPTY            RT_BIT_64(24)        /**< Legacy feature: Force intr if no AVAIL    */
    145146#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     */
    146148#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     */
    148150#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     */
    150151#define VIRTIO_F_BAD_FEATURE                RT_BIT_64(30)        /**< QEMU kludge.  UNUSED as of >= VirtIO 1.0  */
    151152#define VIRTIO_F_VERSION_1                  RT_BIT_64(32)        /**< Required feature bit for 1.0 devices      */
     
    157158#define VIRTIO_F_NOTIFICAITON_DATA          RT_BIT_64(38)        /**< Driver passes extra data (VirtIO 1.1 NYI) */
    158159
     160typedef struct VIRTIO_FEATURES_LIST
     161{
     162    uint64_t fFeatureBit;
     163    const char *pcszDesc;
     164} VIRTIO_FEATURES_LIST, *PVIRTIO_FEATURES_LIST;
     165
     166static 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
    159174#define VIRTIO_DEV_INDEPENDENT_FEATURES_OFFERED ( 0 )            /**< TBD: Add VIRTIO_F_INDIRECT_DESC           */
    160175#define VIRTIO_DEV_INDEPENDENT_LEGACY_FEATURES_OFFERED ( 0 )     /**< Only offered to legacy drivers            */
     
    187202    kvirtIoVmStateChangedFor32BitHack = 0x7fffffff
    188203} VIRTIOVMSTATECHANGED;
     204
     205
    189206
    190207/** @def Virtio Device PCI Capabilities type codes */
     
    229246    uint8_t   fDeviceStatus;                                     /**< RW (driver writes device status, 0=reset) */
    230247    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
    233252} VIRTIO_LEGACY_PCI_COMMON_CFG_T, *PVIRTIO_LEGACY_PCI_COMMON_CFG_T;
    234253
     
    323342    uint8_t                     uISR;                             /**< Interrupt Status Register.                */
    324343    uint8_t                     fMsiSupport;                      /**< Flag set if using MSI instead of ISR      */
    325     uint8_t                     fLegacyDriver;                    /**< Set if guest driver < VirtIO 1.0          */
    326344    uint16_t                    uVirtqSelect;                     /**< (MMIO) queue selector               GUEST */
     345    uint32_t                    fLegacyDriver;                    /**< Set if guest driver < VirtIO 1.0          */
    327346
    328347    /** @name The locations of the capability structures in PCI config space and the BAR.
     
    356375#endif
    357376
     377
    358378    /** @} */
    359379} VIRTIOCORE;
     
    368388    /** @name Callbacks filled by the device before calling virtioCoreR3Init.
    369389     * @{  */
     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
    370405    /**
    371406     * Implementation-specific client callback to notify client of significant device status
     
    391426
    392427    /**
    393      * Implementation-specific client ballback to access VirtIO Device-specific capabilities
     428     * Implementation-specific client callback to access VirtIO Device-specific capabilities
    394429     * (other VirtIO capabilities and features are handled in VirtIO implementation)
    395430     *
     
    546581
    547582/**
    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.
    551589 *
    552590 * @param   pVirtio     Pointer to the shared virtio state.
    553591 * @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 */
     597void  virtioCorePrintDeviceFeatures(VIRTIOCORE *pVirtio, PCDBGFINFOHLP pHlp,
     598    const VIRTIO_FEATURES_LIST *aDevSpecificFeatures, int cFeatures);
    556599
    557600/*
     
    711754 * If not, it's presumed to be a VirtIO legacy guest driver. Note that legacy drivers
    712755 * may start using the device prematurely, as opposed to the rigorously sane protocol
    713  * prescribed by the "modern" VirtIO spec. Doing so is suggestive of a 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.
    715758 *
    716759 * @param   pVirtio      Pointer to the virtio state.
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