VirtualBox

Changeset 98063 in vbox


Ignore:
Timestamp:
Jan 12, 2023 3:01:04 PM (23 months ago)
Author:
vboxsync
Message:

Devices/Virtio,Devices/DevVirtioNet_1_0: Additional fixes for the virtio-net device implementation, don't reset the shadow index counters in the virtq structure when it is being attached because the guest might have used the queues before setting the DRIVER_OK flag (FreeBSD's legacy virtio-net driver included up to version 12.3 and pfSense 2.6.0). Also add a device reset callback to properly reset the device state, avoiding the RX code to work on stale data overwriting random guest memory. Some style fixes, ticketref:21201

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/user_ChangeLogImpl.xml

    r98060 r98063  
    8282
    8383      <listitem>
    84        <para></para>
     84       <para>virtio-net: Follow up fixes for FreeBSD 12.3 and pfSense 2.6.0 (bug #21201)</para>
    8585      </listitem>
    8686
  • trunk/src/VBox/Devices/Network/DevVirtioNet_1_0.cpp

    r97824 r98063  
    10611061    PVIRTIONET pThis = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
    10621062
    1063     Log10Func(("[%s] uOffset: %d, cb: %d: %.*Rhxs\n", pThis->szInst, uOffset, cb, RT_MAX(cb, 8) , pv));
     1063    Log10Func(("[%s] uOffset: %u, cb: %u: %.*Rhxs\n", pThis->szInst, uOffset, cb, cb, pv));
    10641064    RT_NOREF(pThis);
    10651065    return virtioNetR3DevCfgAccess(PDMDEVINS_2_DATA(pDevIns, PVIRTIONET), uOffset, (void *)pv, cb, true /*fWrite*/);
     
    31803180         * Dispatch to the handler for the queue this worker is set up to drive
    31813181         */
    3182          if (pVirtq->fCtlVirtq)
    3183          {
    3184              Log10Func(("[%s] %s worker woken. Fetching desc chain\n", pThis->szInst, pVirtq->szName));
     3182        if (pVirtq->fCtlVirtq)
     3183        {
     3184            Log10Func(("[%s] %s worker woken. Fetching desc chain\n", pThis->szInst, pVirtq->szName));
    31853185#ifdef VIRTIO_VBUF_ON_STACK
    31863186            VIRTQBUF_T VirtqBuf;
     
    31883188            int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pVirtq->uIdx, pVirtqBuf, true);
    31893189#else /* !VIRTIO_VBUF_ON_STACK */
    3190              PVIRTQBUF pVirtqBuf = NULL;
    3191              int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pVirtq->uIdx, &pVirtqBuf, true);
     3190            PVIRTQBUF pVirtqBuf = NULL;
     3191            int rc = virtioCoreR3VirtqAvailBufGet(pDevIns, &pThis->Virtio, pVirtq->uIdx, &pVirtqBuf, true);
    31923192#endif /* !VIRTIO_VBUF_ON_STACK */
    3193              if (rc == VERR_NOT_AVAILABLE)
    3194              {
     3193            if (rc == VERR_NOT_AVAILABLE)
     3194            {
    31953195                Log10Func(("[%s] %s worker woken. Nothing found in queue\n", pThis->szInst, pVirtq->szName));
    31963196                continue;
    3197              }
    3198              virtioNetR3Ctrl(pDevIns, pThis, pThisCC, pVirtqBuf);
     3197            }
     3198            virtioNetR3Ctrl(pDevIns, pThis, pThisCC, pVirtqBuf);
    31993199#ifndef VIRTIO_VBUF_ON_STACK
    3200              virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
     3200            virtioCoreR3VirtqBufRelease(&pThis->Virtio, pVirtqBuf);
    32013201#endif /* !VIRTIO_VBUF_ON_STACK */
    3202          }
    3203          else /* Must be Tx queue */
    3204          {
    3205              Log10Func(("[%s] %s worker woken. Virtq has data to transmit\n",  pThis->szInst, pVirtq->szName));
    3206              virtioNetR3TransmitPkts(pDevIns, pThis, pThisCC, pVirtq, false /* fOnWorkerThread */);
    3207          }
    3208          /* Note: Surprise! Rx queues aren't handled by local worker threads. Instead, the PDM network leaf driver
    3209           * invokes PDMINETWORKDOWN.pfnWaitReceiveAvail() callback, which waits until woken by virtioNetVirtqNotified()
    3210           * indicating that guest IN buffers have been added to Rx virt queue.
    3211           */
     3202        }
     3203        else /* Must be Tx queue */
     3204        {
     3205            Log10Func(("[%s] %s worker woken. Virtq has data to transmit\n",  pThis->szInst, pVirtq->szName));
     3206            virtioNetR3TransmitPkts(pDevIns, pThis, pThisCC, pVirtq, false /* fOnWorkerThread */);
     3207        }
     3208        /* Note: Surprise! Rx queues aren't handled by local worker threads. Instead, the PDM network leaf driver
     3209         * invokes PDMINETWORKDOWN.pfnWaitReceiveAvail() callback, which waits until woken by virtioNetVirtqNotified()
     3210         * indicating that guest IN buffers have been added to Rx virt queue.
     3211         */
    32123212    }
    32133213    Log10(("[%s] %s worker thread exiting\n", pThis->szInst, pVirtq->szName));
     
    32543254                virtioCoreVirtqEnableNotify(&pThis->Virtio, pVirtq->uIdx, true /* fEnable */);
    32553255        }
     3256
     3257        virtioNetWakeupRxBufWaiter(pThisCC->pDevIns);
    32563258    }
    32573259    else
     
    33763378    PDMIBASE_RETURN_INTERFACE(pszIID, PDMILEDPORTS,      &pThisCC->ILeds);
    33773379    return NULL;
     3380}
     3381
     3382/**
     3383 * @interface_method_impl{PDMDEVREGR3,pfnReset}
     3384 */
     3385static DECLCALLBACK(void) virtioNetR3Reset(PPDMDEVINS pDevIns)
     3386{
     3387    PVIRTIONET   pThis   = PDMDEVINS_2_DATA(pDevIns, PVIRTIONET);
     3388    PVIRTIONETCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
     3389
     3390    virtioCoreR3ResetDevice(pDevIns, &pThis->Virtio, &pThisCC->Virtio);
    33783391}
    33793392
     
    37023715    /* .pfnMemSetup = */            NULL,
    37033716    /* .pfnPowerOn = */             NULL,
    3704     /* .pfnReset = */               NULL,
     3717    /* .pfnReset = */               virtioNetR3Reset,
    37053718    /* .pfnSuspend = */             virtioNetWakeupRxBufWaiter,
    37063719    /* .pfnResume = */              NULL,
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.cpp

    r97530 r98063  
    590590    PVIRTQUEUE pVirtq = &pVirtio->aVirtqueues[uVirtq];
    591591    pVirtq->uVirtq = uVirtq;
    592     pVirtq->uAvailIdxShadow = 0;
    593     pVirtq->uUsedIdxShadow  = 0;
    594592    pVirtq->fUsedRingEvent = false;
    595593    pVirtq->fAttached = true;
     
    10141012                    ("Guest driver not in ready state.\n"), VERR_INVALID_STATE);
    10151013
    1016     Log6Func(("    Copying device data to %s, [desc:%u used ring:%u]\n",
     1014    Log6Func(("    Copying device data to %s, [desc:%u -> used ring:%u]\n",
    10171015              VIRTQNAME(pVirtio, uVirtq), pVirtqBuf->uHeadIdx, pVirtq->uUsedIdxShadow));
    10181016
     
    11611159            ("Guest driver not in ready state.\n"), VERR_INVALID_STATE);
    11621160
    1163     Log6Func(("    Sync %s used ring (%u idx)\n",
     1161    Log6Func(("    Sync %s used ring (%u -> idx)\n",
    11641162                        pVirtq->szName, pVirtq->uUsedIdxShadow));
    11651163
     
    13531351    pVirtioCC->pfnStatusChanged(pVirtio, pVirtioCC, 0 /* fDriverOk */);
    13541352    virtioResetDevice(pDevIns, pVirtio);
     1353}
     1354
     1355DECLHIDDEN(void) virtioCoreR3ResetDevice(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, PVIRTIOCORECC pVirtioCC)
     1356{
     1357    virtioGuestR3WasReset(pDevIns, pVirtio, pVirtioCC);
    13551358}
    13561359#endif /* IN_RING3 */
  • trunk/src/VBox/Devices/VirtIO/VirtioCore.h

    r96407 r98063  
    549549
    550550/**
     551 * Resets the device state upon a VM reset for instance.
     552 *
     553 * @returns nothing.
     554 * @param   pVirtio     Pointer to the virtio state.
     555 *
     556 * @note Calls back into the upper device when the status changes.
     557 */
     558DECLHIDDEN(void) virtioCoreR3ResetDevice(PPDMDEVINS pDevIns, PVIRTIOCORE pVirtio, PVIRTIOCORECC pVirtioCC);
     559
     560/**
    551561 * 'Attaches' host device-specific implementation's queue state to host VirtIO core
    552562 * virtqueue management infrastructure, informing the virtio core of the name of the
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