VirtualBox

Ignore:
Timestamp:
Oct 2, 2020 5:58:42 AM (4 years ago)
Author:
vboxsync
Message:

Fixed problem with host crashing with DevVirtioNet_1_0.cpp R3 virtual address access from R0 when SMAP kernel parameter is enabled

File:
1 edited

Legend:

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

    r85608 r86405  
    304304typedef struct VIRTIONETVIRTQ
    305305{
    306     struct VIRTIONETWORKER         *pWorker;                    /**< Pointer to R0 worker struct                    */
    307     struct VIRTIONETWORKERR3       *pWorkerR3;                  /**< Pointer to R3 worker struct                    */
    308306    uint16_t                       uIdx;                        /**< Index of this queue                            */
    309307    uint16_t                       align;
     
    321319{
    322320    SUPSEMEVENT                     hEvtProcess;                /**< handle of associated sleep/wake-up semaphore   */
    323     PVIRTIONETVIRTQ                 pVirtq;                     /**< pointer to queue                               */
    324321    uint16_t                        uIdx;                       /**< Index of this worker                           */
    325322    bool volatile                   fSleeping;                  /**< Flags whether worker thread is sleeping or not */
     
    337334{
    338335    R3PTRTYPE(PPDMTHREAD)           pThread;                    /**< pointer to worker thread's handle              */
    339     PVIRTIONETVIRTQ                 pVirtq;                     /**< pointer to queue                               */
    340336    uint16_t                        uIdx;                       /**< Index of this worker                           */
    341337    uint16_t                        pad;
     
    603599}
    604600
     601
     602
    605603/**
    606604 * @callback_method_impl{VIRTIOCORER0,pfnVirtqNotified}
     
    612610
    613611    PVIRTIONETVIRTQ  pVirtq  = &pThis->aVirtqs[uVirtqNbr];
    614     PVIRTIONETWORKER pWorker = pVirtq->pWorker;
     612    PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr];
    615613
    616614#if defined (IN_RING3) && defined (LOG_ENABLED)
     615
    617616     RTLogFlush(NULL);
     617
    618618#endif
    619619
     
    624624        if (cBufsAvailable)
    625625        {
    626             Log10Func(("%s %u empty bufs added to %s by guest (notifying leaf device)\n",
    627                        pThis->szInst, cBufsAvailable, pVirtq->szName));
     626            VIRTIOLOGLEVEL10("%s %u empty bufs added to %s by guest (notifying leaf device)\n",
     627                       pThis->szInst, cBufsAvailable, pVirtq->szName);
    628628            virtioNetWakeupRxBufWaiter(pDevIns);
    629629        }
    630630        else
    631             LogRel(("%s \n\n***WARNING: %s notified but no empty bufs added by guest! (skip notifying of leaf device)\n\n",
    632                     pThis->szInst, pVirtq->szName));
     631            VIRTIOLOGLEVEL10("%s \n\n***WARNING: %s notified but no empty bufs added by guest! (skip notifying of leaf device)\n\n",
     632                    pThis->szInst, pVirtq->szName);
    633633    }
    634634    else if (IS_TX_VIRTQ(uVirtqNbr) || IS_CTRL_VIRTQ(uVirtqNbr))
     
    639639            if (ASMAtomicReadBool(&pWorker->fSleeping))
    640640            {
    641                 Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName));
     641                VIRTIOLOGLEVEL10("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName);
     642
    642643                int rc = PDMDevHlpSUPSemEventSignal(pDevIns, pWorker->hEvtProcess);
    643644                AssertRC(rc);
     
    645646            else
    646647            {
    647                 Log10Func(("%s %s has available buffers - worker already awake\n", pThis->szInst, pVirtq->szName));
     648                VIRTIOLOGLEVEL10("%s %s has available buffers - worker already awake\n", pThis->szInst, pVirtq->szName);
    648649            }
    649650        }
    650651        else
    651652        {
    652             Log10Func(("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName));
     653            VIRTIOLOGLEVEL10("%s %s has available buffers - waking worker.\n", pThis->szInst, pVirtq->szName);
    653654        }
    654655    }
     
    838839            if (pVirtq->fHasWorker)
    839840            {
    840                 PVIRTIONETWORKER   pWorker   = pVirtq->pWorker;
    841                 PVIRTIONETWORKERR3 pWorkerR3 = pVirtq->pWorkerR3;
     841                PVIRTIONETWORKER   pWorker   = &pThis->aWorkers[uVirtqNbr];
     842                PVIRTIONETWORKERR3 pWorkerR3 = &pThisCC->aWorkers[uVirtqNbr];
     843
     844                Assert((pWorker->uIdx == pVirtq->uIdx));
     845                Assert((pWorkerR3->uIdx == pVirtq->uIdx));
    842846
    843847                if (pWorker->fAssigned)
     
    11341138    {
    11351139        PVIRTIONETWORKER pWorker = &pThis->aWorkers[uIdxWorker];
    1136         PVIRTIONETVIRTQ  pVirtq  = pWorker->pVirtq;
     1140        PVIRTIONETVIRTQ  pVirtq  = &pThis->aVirtqs[uIdxWorker];
    11371141        if (pVirtq->fAttachedToVirtioCore)
    11381142        {
     
    25892593}
    25902594
    2591 static int virtioNetR3CreateOneWorkerThread(PPDMDEVINS pDevIns, PVIRTIONET pThis, uint16_t uIdxWorker,
     2595static int virtioNetR3CreateOneWorkerThread(PPDMDEVINS pDevIns, PVIRTIONET pThis,
    25922596                                            PVIRTIONETWORKER pWorker, PVIRTIONETWORKERR3 pWorkerR3,
    25932597                                            PVIRTIONETVIRTQ pVirtq)
     
    25972601
    25982602    int rc = PDMDevHlpSUPSemEventCreate(pDevIns, &pWorker->hEvtProcess);
     2603    LogFunc(("PDMDevHlpSUPSemEventCreate(pDevIns, &pWorker->hEvtProcess=%p)", &pWorker->hEvtProcess));
     2604    LogFunc(("pWorker->hEvtProcess = %x\n", pWorker->hEvtProcess));
    25992605
    26002606    if (RT_FAILURE(rc))
     
    26112617                                   N_("Error creating thread for Virtual Virtq %s\n"), pVirtq->uIdx);
    26122618
    2613     pWorker->pVirtq    = pWorkerR3->pVirtq   = pVirtq;
    2614     pWorker->uIdx      = pWorkerR3->uIdx     = uIdxWorker;
    2615     pVirtq->pWorker    = pWorker;
    2616     pVirtq->pWorkerR3  = pWorkerR3;
    26172619    pWorker->fAssigned = true;  /* Because worker's state held in fixed-size array w/empty slots */
    26182620
     
    26252627{
    26262628
    2627 #define CTRLWIDX 0 /* First worker is for the control queue */
    26282629
    26292630    Log10Func(("%s\n", pThis->szInst));
    26302631
    26312632    PVIRTIONETVIRTQ pCtlVirtq = &pThis->aVirtqs[CTRLQIDX];
    2632     int rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, CTRLQIDX /* uIdxWorker */,
    2633                                               &pThis->aWorkers[CTRLWIDX], &pThisCC->aWorkers[CTRLWIDX], pCtlVirtq);
     2633    int rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis,
     2634                                              &pThis->aWorkers[CTRLQIDX], &pThisCC->aWorkers[CTRLQIDX], pCtlVirtq);
    26342635    AssertRCReturn(rc, rc);
    26352636
    26362637    pCtlVirtq->fHasWorker = true;
    26372638
    2638     uint16_t uIdxWorker = CTRLWIDX + 1;
    2639     for (uint16_t uVirtqPair = pThis->cInitializedVirtqPairs; uVirtqPair < pThis->cVirtqPairs; uVirtqPair++, uIdxWorker++)
     2639    for (uint16_t uVirtqPair = pThis->cInitializedVirtqPairs; uVirtqPair < pThis->cVirtqPairs; uVirtqPair++)
    26402640    {
    26412641        PVIRTIONETVIRTQ pTxVirtq = &pThis->aVirtqs[TXQIDX(uVirtqPair)];
    26422642        PVIRTIONETVIRTQ pRxVirtq = &pThis->aVirtqs[RXQIDX(uVirtqPair)];
    26432643
    2644         rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, uIdxWorker, &pThis->aWorkers[uIdxWorker],
    2645                                               &pThisCC->aWorkers[uIdxWorker], pTxVirtq);
     2644        rc = virtioNetR3CreateOneWorkerThread(pDevIns, pThis, &pThis->aWorkers[TXQIDX(uVirtqPair)],
     2645                                                              &pThisCC->aWorkers[TXQIDX(uVirtqPair)], pTxVirtq);
    26462646        AssertRCReturn(rc, rc);
    26472647
     
    26652665    PVIRTIONETCC       pThisCC   = PDMDEVINS_2_DATA_CC(pDevIns, PVIRTIONETCC);
    26662666    PVIRTIONETWORKER   pWorker   = (PVIRTIONETWORKER)pThread->pvUser;
    2667     PVIRTIONETVIRTQ    pVirtq    = pWorker->pVirtq;
     2667    PVIRTIONETVIRTQ    pVirtq    = &pThis->aVirtqs[pWorker->uIdx];
     2668    uint16_t           uIdx      = pWorker->uIdx;
     2669
     2670    ASMAtomicWriteBool(&pWorker->fSleeping, false);
     2671
     2672    Assert(pWorker->uIdx == pVirtq->uIdx);
    26682673
    26692674    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
    26702675        return VINF_SUCCESS;
    26712676
    2672     LogFunc(("%s worker thread started for %s\n", pThis->szInst, pVirtq->szName));
     2677    LogFunc(("%s worker thread idx=%d started for %s (virtq idx=%d)\n", pThis->szInst,  pWorker->uIdx, pVirtq->szName, pVirtq->uIdx));
    26732678
    26742679    /** @todo Race w/guest enabling/disabling guest notifications cyclically.
    26752680              See BugRef #8651, Comment #82 */
    2676     virtioCoreVirtqEnableNotify(&pThis->Virtio, pVirtq->uIdx, true /* fEnable */);
     2681    virtioCoreVirtqEnableNotify(&pThis->Virtio, uIdx, true /* fEnable */);
    26772682
    26782683    while (   pThread->enmState != PDMTHREADSTATE_TERMINATING
    26792684           && pThread->enmState != PDMTHREADSTATE_TERMINATED)
    26802685    {
    2681         if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio, pVirtq->uIdx))
     2686        if (IS_VIRTQ_EMPTY(pDevIns, &pThis->Virtio,  pVirtq->uIdx))
    26822687        {
    26832688            /* Atomic interlocks avoid missing alarm while going to sleep & notifier waking the awoken */
    26842689            ASMAtomicWriteBool(&pWorker->fSleeping, true);
     2690
    26852691            bool fNotificationSent = ASMAtomicXchgBool(&pWorker->fNotified, false);
    26862692            if (!fNotificationSent)
     
    26882694                Log10Func(("%s %s worker sleeping...\n\n", pThis->szInst, pVirtq->szName));
    26892695                Assert(ASMAtomicReadBool(&pWorker->fSleeping));
     2696
    26902697                int rc = PDMDevHlpSUPSemEventWaitNoResume(pDevIns, pWorker->hEvtProcess, RT_INDEFINITE_WAIT);
    26912698                STAM_COUNTER_INC(&pThis->StatTransmitByThread);
     
    26982705            }
    26992706            ASMAtomicWriteBool(&pWorker->fSleeping, false);
     2707
    27002708        }
    27012709
     
    27602768        {
    27612769            PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr];
    2762             pVirtq->uIdx = uVirtqNbr;
     2770            PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr];
     2771
     2772            Assert(pWorker->uIdx == uVirtqNbr);
     2773            Assert(pVirtq->uIdx == pWorker->uIdx);
     2774
    27632775            (void) virtioCoreR3VirtqAttach(&pThis->Virtio, pVirtq->uIdx, pVirtq->szName);
    27642776            pVirtq->fAttachedToVirtioCore = true;
     
    30323044    virtioNetR3SetVirtqNames(pThis);
    30333045    pThis->aVirtqs[CTRLQIDX].fCtlVirtq = true;
     3046    for (unsigned uVirtqNbr = 0; uVirtqNbr < pThis->cVirtVirtqs; uVirtqNbr++)
     3047    {
     3048        PVIRTIONETVIRTQ pVirtq = &pThis->aVirtqs[uVirtqNbr];
     3049        PVIRTIONETWORKER pWorker = &pThis->aWorkers[uVirtqNbr];
     3050        PVIRTIONETWORKERR3 pWorkerR3 = &pThisCC->aWorkers[uVirtqNbr];
     3051        pVirtq->uIdx = uVirtqNbr;
     3052        pWorker->uIdx = uVirtqNbr;
     3053        pWorkerR3->uIdx = uVirtqNbr;
     3054    }
    30343055
    30353056    /*
     
    30393060    if (RT_FAILURE(rc))
    30403061        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to create worker threads"));
     3062
    30413063
    30423064    /*
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