VirtualBox

Changeset 70050 in vbox


Ignore:
Timestamp:
Dec 10, 2017 5:28:20 PM (7 years ago)
Author:
vboxsync
Message:

Devices/OHCI: Don't touch others member of the endpoint descriptor when writing the head pointer HeadP and embedded flags back to the guest as it might corrupt data updated by the guest inbetween. This can result in TDs not being recognized later on because the linked list contains old data again. Some cleanups for the caching to make it more contained and less spread out over the code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/USB/DevOHCI.cpp

    r69954 r70050  
    13051305}
    13061306
    1307 static void physReadStatsPrint(PCOHCIPHYSREADSTATS p)
     1307static void physReadStatsPrint(POHCIPHYSREADSTATS p)
    13081308{
    13091309    p->ed.cMinReadsPerPage = RT_MIN(p->ed.cMinReadsPerPage, p->ed.cReadsLastPage);
     
    14011401}
    14021402
    1403 static void ohciR3ReadEdCached(POHCI pThis, uint32_t EdAddr, POHCIED pEd)
    1404 {
    1405     ohciR3PhysReadCacheRead(pThis, pThis->pCacheED, EdAddr, pEd, sizeof(*pEd));
    1406 }
    1407 
    1408 static void ohciR3ReadTdCached(POHCI pThis, uint32_t TdAddr, POHCITD pTd)
    1409 {
    1410     ohciR3PhysReadCacheRead(pThis, pThis->pCacheTD, TdAddr, pTd, sizeof(*pTd));
    1411 }
    1412 
    1413 
    14141403/**
    14151404 * Update any cached ED data with the given endpoint descriptor at the given address.
     
    14221411DECLINLINE(void) ohciR3CacheEdUpdate(POHCI pThis, RTGCPHYS32 EdAddr, PCOHCIED pEd)
    14231412{
    1424     ohciR3PhysCacheUpdate(pThis->pCacheED, EdAddr, pEd, sizeof(*pEd));
     1413    ohciR3PhysCacheUpdate(pThis->pCacheED, EdAddr + RT_OFFSETOF(OHCIED, HeadP), &pEd->HeadP, sizeof(uint32_t));
    14251414}
    14261415
     
    14501439    physReadStatsUpdateDesc(&g_PhysReadState.all, EdAddr);
    14511440# endif
     1441#ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
     1442    ohciR3PhysReadCacheRead(pThis, pThis->pCacheED, EdAddr, pEd, sizeof(*pEd));
     1443#else
    14521444    ohciR3GetDWords(pThis, EdAddr, (uint32_t *)pEd, sizeof(*pEd) >> 2);
     1445#endif
    14531446}
    14541447
     
    14621455    physReadStatsUpdateDesc(&g_PhysReadState.all, TdAddr);
    14631456# endif
     1457#ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
     1458    ohciR3PhysReadCacheRead(pThis, pThis->pCacheTD, TdAddr, pTd, sizeof(*pTd));
     1459#else
    14641460    ohciR3GetDWords(pThis, TdAddr, (uint32_t *)pTd, sizeof(*pTd) >> 2);
     1461#endif
    14651462# ifdef LOG_ENABLED
    14661463    if (LogIs3Enabled())
     
    15721569# endif
    15731570
    1574     ohciR3PutDWords(pThis, EdAddr, (uint32_t *)pEd, sizeof(*pEd) >> 2);
     1571    ohciR3PutDWords(pThis, EdAddr + RT_OFFSETOF(OHCIED, HeadP), &pEd->HeadP, 1);
    15751572#ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    15761573    ohciR3CacheEdUpdate(pThis, EdAddr, pEd);
     
    24172414    }
    24182415}
     2416
     2417
     2418/**
     2419 * Lock the given OHCI controller instance.
     2420 *
     2421 * @returns nothing.
     2422 * @param   pThis               The OHCI controller instance to lock.
     2423 */
     2424DECLINLINE(void) ohciR3Lock(POHCI pThis)
     2425{
     2426    RTCritSectEnter(&pThis->CritSect);
     2427
     2428# ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
     2429    /* Clear all caches here to avoid reading stale data from previous lock holders. */
     2430    ohciR3PhysReadCacheClear(pThis->pCacheED);
     2431    ohciR3PhysReadCacheClear(pThis->pCacheTD);
     2432# endif
     2433}
     2434
     2435
     2436/**
     2437 * Unlocks the given OHCI controller instance.
     2438 *
     2439 * @returns nothing.
     2440 * @param   pThis               The OHCI controller instance to unlock.
     2441 */
     2442DECLINLINE(void) ohciR3Unlock(POHCI pThis)
     2443{
     2444# ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
     2445    /*
     2446     * Clear all caches here to avoid leaving stale data behind (paranoia^2,
     2447     * already done in ohciR3Lock).
     2448     */
     2449    ohciR3PhysReadCacheClear(pThis->pCacheED);
     2450    ohciR3PhysReadCacheClear(pThis->pCacheTD);
     2451# endif
     2452
     2453    RTCritSectLeave(&pThis->CritSect);
     2454}
     2455
    24192456
    24202457/**
     
    27242761             pUrb->pszDesc, pUrb->pHci->EdAddr, pUrb->pHci->cTds, pUrb->paTds[0].TdAddr));
    27252762
    2726     RTCritSectEnter(&pThis->CritSect);
     2763    ohciR3Lock(pThis);
    27272764    pThis->fIdle = false;   /* Mark as active */
    27282765
     
    27482785             pUrb->pszDesc, pUrb->pHci->EdAddr, pUrb->pHci->cTds, pUrb->paTds[0].TdAddr, cFmAge));
    27492786        STAM_COUNTER_INC(&pThis->StatDroppedUrbs);
    2750         RTCritSectLeave(&pThis->CritSect);
     2787        ohciR3Unlock(pThis);
    27512788        return;
    27522789    }
     
    27682805        NOREF(fHasBeenCanceled);
    27692806        STAM_COUNTER_INC(&pThis->StatDroppedUrbs);
    2770         RTCritSectLeave(&pThis->CritSect);
     2807        ohciR3Unlock(pThis);
    27712808        return;
    27722809    }
     
    27832820    /* finally write back the endpoint descriptor. */
    27842821    ohciR3WriteEd(pThis, pUrb->pHci->EdAddr, &Ed);
    2785 
    2786     RTCritSectLeave(&pThis->CritSect);
     2822    ohciR3Unlock(pThis);
    27872823}
    27882824
     
    28182854    }
    28192855
    2820     RTCritSectEnter(&pThis->CritSect);
    2821 
     2856    ohciR3Lock(pThis);
    28222857    bool fRetire = false;
    28232858    /*
     
    28532888    }
    28542889
    2855     RTCritSectLeave(&pThis->CritSect);
     2890    ohciR3Unlock(pThis);
    28562891    return fRetire;
    28572892}
     
    29372972         pUrb->pszDesc, TdAddr, EdAddr, pUrb->cbData));
    29382973
    2939     RTCritSectLeave(&pThis->CritSect);
     2974    ohciR3Unlock(pThis);
    29402975    int rc = VUSBIRhSubmitUrb(pThis->RootHub.pIRhConn, pUrb, &pThis->RootHub.Led);
    2941     RTCritSectEnter(&pThis->CritSect);
     2976    ohciR3Lock(pThis);
    29422977    if (RT_SUCCESS(rc))
    29432978        return true;
     
    29973032
    29983033    /* read the head */
    2999 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3000     ohciR3ReadTdCached(pThis, TdAddr, &Head.Td);
    3001 # else
    30023034    ohciR3ReadTd(pThis, TdAddr, &Head.Td);
    3003 # endif
    30043035    ohciR3BufInit(&Head.Buf, Head.Td.cbp, Head.Td.be);
    30053036    Head.TdAddr = TdAddr;
     
    30193050        pCur->pNext = NULL;
    30203051        pCur->TdAddr = pTail->Td.NextTD & ED_PTR_MASK;
    3021 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3022         ohciR3ReadTdCached(pThis, pCur->TdAddr, &pCur->Td);
    3023 # else
    30243052        ohciR3ReadTd(pThis, pCur->TdAddr, &pCur->Td);
    3025 # endif
    30263053        ohciR3BufInit(&pCur->Buf, pCur->Td.cbp, pCur->Td.be);
    30273054
     
    31143141    Log(("%s: ohciR3ServiceTdMultiple: submitting cbData=%#x EdAddr=%#010x cTds=%d TdAddr0=%#010x\n",
    31153142         pUrb->pszDesc, pUrb->cbData, EdAddr, cTds, TdAddr));
    3116     RTCritSectLeave(&pThis->CritSect);
     3143    ohciR3Unlock(pThis);
    31173144    int rc = VUSBIRhSubmitUrb(pThis->RootHub.pIRhConn, pUrb, &pThis->RootHub.Led);
    3118     RTCritSectEnter(&pThis->CritSect);
     3145    ohciR3Lock(pThis);
    31193146    if (RT_SUCCESS(rc))
    31203147        return true;
     
    33413368    Log(("%s: ohciR3ServiceIsochronousTd: submitting cbData=%#x cIsocPkts=%d EdAddr=%#010x TdAddr=%#010x SF=%#x (%#x)\n",
    33423369         pUrb->pszDesc, pUrb->cbData, pUrb->cIsocPkts, EdAddr, ITdAddr, pITd->HwInfo & ITD_HWINFO_SF, pThis->HcFmNumber));
    3343     RTCritSectLeave(&pThis->CritSect);
     3370    ohciR3Unlock(pThis);
    33443371    int rc = VUSBIRhSubmitUrb(pThis->RootHub.pIRhConn, pUrb, &pThis->RootHub.Led);
    3345     RTCritSectEnter(&pThis->CritSect);
     3372    ohciR3Lock(pThis);
    33463373    if (RT_SUCCESS(rc))
    33473374        return true;
     
    35293556    {
    35303557        OHCIED Ed;
    3531 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3532         ohciR3ReadEdCached(pThis, EdAddr, &Ed);
    3533 # else
    35343558        ohciR3ReadEd(pThis, EdAddr, &Ed);
    3535 # endif
    35363559        Assert(!(Ed.hwinfo & ED_HWINFO_ISO)); /* the guest is screwing us */
    35373560        if (ohciR3IsEdReady(&Ed))
     
    36273650    {
    36283651        OHCIED Ed;
    3629 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3630         ohciR3ReadEdCached(pThis, EdAddr, &Ed);
    3631 # else
     3652
    36323653        ohciR3ReadEd(pThis, EdAddr, &Ed);
    3633 # endif
    36343654        Assert(!(Ed.hwinfo & ED_HWINFO_ISO)); /* the guest is screwing us */
    36353655        if (ohciR3IsEdPresent(&Ed))
     
    37483768    {
    37493769        OHCIED Ed;
    3750 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3751         ohciR3ReadEdCached(pThis, EdAddr, &Ed);
    3752 # else
     3770
    37533771        ohciR3ReadEd(pThis, EdAddr, &Ed);
    3754 # endif
    3755 
    37563772        if (ohciR3IsEdReady(&Ed))
    37573773        {
     
    39163932            OHCIED Ed;
    39173933            OHCITD Td;
    3918 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3919             ohciR3ReadEdCached(pThis, EdAddr, &Ed);
    3920 # else
     3934
    39213935            ohciR3ReadEd(pThis, EdAddr, &Ed);
    3922 # endif
    39233936            uint32_t TdAddr = Ed.HeadP & ED_PTR_MASK;
    39243937            uint32_t TailP  = Ed.TailP & ED_PTR_MASK;
     
    39323945                do
    39333946                {
    3934 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    3935                     ohciR3ReadTdCached(pThis, TdAddr, &Td);
    3936 # else
    39373947                    ohciR3ReadTd(pThis, TdAddr, &Td);
    3938 # endif
    39393948                    j = ohciR3InFlightFind(pThis, TdAddr);
    39403949                    if (j > -1)
     
    40994108    POHCI pThis = VUSBIROOTHUBPORT_2_OHCI(pInterface);
    41004109
    4101     RTCritSectEnter(&pThis->CritSect);
     4110    ohciR3Lock(pThis);
    41024111
    41034112    /* Reset idle detection flag */
     
    41064115# ifdef VBOX_WITH_OHCI_PHYS_READ_STATS
    41074116    physReadStatsReset(&g_PhysReadState);
    4108 # endif
    4109 
    4110 # ifdef VBOX_WITH_OHCI_PHYS_READ_CACHE
    4111     ohciR3PhysReadCacheClear(pThis->pCacheED);
    4112     ohciR3PhysReadCacheClear(pThis->pCacheTD);
    41134117# endif
    41144118
     
    41284132# endif
    41294133
    4130     RTCritSectLeave(&pThis->CritSect);
    4131 
     4134    ohciR3Unlock(pThis);
    41324135    return pThis->fIdle;
    41334136}
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