VirtualBox

Changeset 87371 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Jan 22, 2021 2:42:17 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142356
Message:

AMD IOMMU: bugref:9654 Handle the case where an access might result in non-contiguous physical addresses after address translation via the IOMMU.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp

    r87127 r87371  
    18311831        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    18321832        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1833 
    1834         RTGCPHYS GCPhysOut;
    18351833        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1836         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    1837         if (RT_SUCCESS(rc))
    1838             GCPhys = GCPhysOut;
    1839         else
     1834        int rc = VINF_SUCCESS;
     1835        while (cbRead > 0)
    18401836        {
    1841             Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    1842                  cbRead, rc));
    1843             return rc;
     1837            RTGCPHYS GCPhysOut;
     1838            size_t   cbContig;
     1839            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig);
     1840            if (RT_SUCCESS(rc))
     1841            {
     1842                /** @todo Handle strict return codes from PGMPhysRead. */
     1843                rc = pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags);
     1844                if (RT_SUCCESS(rc))
     1845                {
     1846                    cbRead -= cbContig;
     1847                    pvBuf   = (void *)((uintptr_t)pvBuf + cbContig);
     1848                    GCPhys += cbContig;
     1849                }
     1850                else
     1851                    break;
     1852            }
     1853            else
     1854            {
     1855                AssertMsgFailed(("Here\n"));
     1856                Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     1857                     cbRead, rc));
     1858                break;
     1859            }
    18441860        }
     1861        return rc;
    18451862    }
    18461863#endif
     
    18851902        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    18861903        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1887 
    1888         RTGCPHYS GCPhysOut;
    18891904        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1890         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut);
    1891         if (RT_SUCCESS(rc))
    1892             GCPhys = GCPhysOut;
    1893         else
     1905        int rc = VINF_SUCCESS;
     1906        while (cbWrite > 0)
    18941907        {
    1895             Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    1896                  cbWrite, rc));
    1897             return rc;
     1908            RTGCPHYS GCPhysOut;
     1909            size_t   cbContig;
     1910            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig);
     1911            if (RT_SUCCESS(rc))
     1912            {
     1913                /** @todo Handle strict return codes from PGMPhysWrite. */
     1914                rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags);
     1915                if (RT_SUCCESS(rc))
     1916                {
     1917                    cbWrite -= cbContig;
     1918                    pvBuf    = (const void *)((uintptr_t)pvBuf + cbContig);
     1919                    GCPhys  += cbContig;
     1920                }
     1921                else
     1922                    break;
     1923            }
     1924            else
     1925            {
     1926                Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     1927                     cbWrite, rc));
     1928                break;
     1929            }
    18981930        }
     1931        return rc;
    18991932    }
    19001933#endif
     
    19361969        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    19371970        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1938 
     1971        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    19391972        RTGCPHYS GCPhysOut;
    1940         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1941         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, X86_PAGE_SIZE, PDMIOMMU_MEM_F_WRITE, &GCPhysOut);
     1973        size_t cbContig;
     1974        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys & X86_PAGE_BASE_MASK, X86_PAGE_SIZE, PDMIOMMU_MEM_F_WRITE,
     1975                                      &GCPhysOut, &cbContig);
    19421976        if (RT_SUCCESS(rc))
     1977        {
    19431978            GCPhys = GCPhysOut;
     1979            Assert(cbContig == X86_PAGE_SIZE);
     1980        }
    19441981        else
    19451982        {
     
    19862023        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    19872024        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1988 
     2025        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    19892026        RTGCPHYS GCPhysOut;
    1990         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1991         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, X86_PAGE_SIZE, PDMIOMMU_MEM_F_READ, &GCPhysOut);
     2027        size_t cbContig;
     2028        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys & X86_PAGE_BASE_MASK, X86_PAGE_SIZE, PDMIOMMU_MEM_F_READ,
     2029                                      &GCPhysOut, &cbContig);
    19922030        if (RT_SUCCESS(rc))
     2031        {
    19932032            GCPhys = GCPhysOut;
     2033            Assert(cbContig == X86_PAGE_SIZE);
     2034        }
    19942035        else
    19952036        {
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp

    r86661 r87371  
    429429        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    430430        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    431 
    432         RTGCPHYS GCPhysOut;
    433431        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    434         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    435         if (RT_SUCCESS(rc))
    436             GCPhys = GCPhysOut;
    437         else
     432        int rc = VINF_SUCCESS;
     433        while (cbRead > 0)
    438434        {
    439             Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    440                  cbRead, rc));
    441             return rc;
     435            RTGCPHYS GCPhysOut;
     436            size_t   cbContig;
     437            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut, &cbContig);
     438            if (RT_SUCCESS(rc))
     439            {
     440                /** @todo Handle strict return codes from PGMPhysRead. */
     441                rc = pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhysOut, pvBuf, cbRead, fFlags);
     442                if (RT_SUCCESS(rc))
     443                {
     444                    cbRead -= cbContig;
     445                    pvBuf   = (void *)((uintptr_t)pvBuf + cbContig);
     446                    GCPhys += cbContig;
     447                }
     448                else
     449                    break;
     450            }
     451            else
     452            {
     453                Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     454                     cbRead, rc));
     455                break;
     456            }
    442457        }
    443 
    444         GCPhys = GCPhysOut;
     458        return rc;
    445459    }
    446460#endif
     
    485499        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    486500        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    487 
    488         RTGCPHYS GCPhysOut;
    489501        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    490         int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, & GCPhysOut);
    491         if (RT_SUCCESS(rc))
    492             GCPhys = GCPhysOut;
    493         else
     502        int rc = VINF_SUCCESS;
     503        while (cbWrite > 0)
    494504        {
    495             Log(("pdmR3DevHlp_PCIPhysRead: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    496                  cbWrite, rc));
    497             return rc;
     505            RTGCPHYS GCPhysOut;
     506            size_t   cbContig;
     507            rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig);
     508            if (RT_SUCCESS(rc))
     509            {
     510                /** @todo Handle strict return codes from PGMPhysWrite. */
     511                rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags);
     512                if (RT_SUCCESS(rc))
     513                {
     514                    cbWrite -= cbContig;
     515                    pvBuf    = (const void *)((uintptr_t)pvBuf + cbContig);
     516                    GCPhys  += cbContig;
     517                }
     518                else
     519                    break;
     520            }
     521            else
     522            {
     523                Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
     524                     cbWrite, rc));
     525                break;
     526            }
    498527        }
    499 
    500         GCPhys = GCPhysOut;
     528        return rc;
    501529    }
    502530#endif
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette