VirtualBox

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


Ignore:
Timestamp:
Jan 29, 2021 11:43:09 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142499
Message:

AMD IOMMU: bugref:9654 PDM IOMMU code de-duplication and cleanup.

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

Legend:

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

    r87371 r87477  
    18211821
    18221822#ifdef VBOX_WITH_IOMMU_AMD
    1823     /** @todo IOMMU: Optimize/re-organize things here later. */
    1824     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    1825     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    1826     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    1827     if (   pDevInsIommu
    1828         && pDevInsIommu != pDevIns)
    1829     {
    1830         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    1831         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    1832         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1833         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1834         int rc = VINF_SUCCESS;
    1835         while (cbRead > 0)
    1836         {
    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             }
    1860         }
     1823    int rc = pdmIommuMemAccessRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, fFlags);
     1824    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    18611825        return rc;
    1862     }
    18631826#endif
    18641827
     
    18921855
    18931856#ifdef VBOX_WITH_IOMMU_AMD
    1894     /** @todo IOMMU: Optimize/re-organize things here later. */
    1895     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    1896     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    1897     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    1898     if (   pDevInsIommu
    1899         && pDevInsIommu != pDevIns)
    1900     {
    1901         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    1902         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    1903         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1904         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1905         int rc = VINF_SUCCESS;
    1906         while (cbWrite > 0)
    1907         {
    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             }
    1930         }
     1857    int rc = pdmIommuMemAccessWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, fFlags);
     1858    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    19311859        return rc;
    1932     }
    19331860#endif
    19341861
     
    19591886
    19601887#ifdef VBOX_WITH_IOMMU_AMD
    1961     /** @todo IOMMU: Optimize/re-organize things here later. */
    1962     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    1963     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    1964     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    1965     if (   pDevInsIommu
    1966         && pDevInsIommu != pDevIns)
    1967     {
    1968         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    1969         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    1970         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    1971         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1972         RTGCPHYS 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);
    1976         if (RT_SUCCESS(rc))
    1977         {
    1978             GCPhys = GCPhysOut;
    1979             Assert(cbContig == X86_PAGE_SIZE);
    1980         }
    1981         else
    1982         {
    1983             LogFunc(("IOMMU translation failed. uDevId=%#x GCPhys=%#RGp rc=%Rrc\n", uDevId, GCPhys, rc));
    1984             return rc;
    1985         }
    1986     }
     1888    int rc = pdmIommuMemAccessWriteCCPtr(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
     1889    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
     1890        return rc;
    19871891#endif
    19881892
     
    20131917
    20141918#ifdef VBOX_WITH_IOMMU_AMD
    2015     /** @todo IOMMU: Optimize/re-organize things here later. */
    2016     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    2017     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    2018     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    2019     if (   pDevInsIommu
    2020         && pDevInsIommu != pDevIns)
    2021     {
    2022         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    2023         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    2024         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    2025         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    2026         RTGCPHYS 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);
    2030         if (RT_SUCCESS(rc))
    2031         {
    2032             GCPhys = GCPhysOut;
    2033             Assert(cbContig == X86_PAGE_SIZE);
    2034         }
    2035         else
    2036         {
    2037             LogFunc(("IOMMU translation failed. uDevId=%#x GCPhys=%#RGp rc=%Rrc\n", uDevId, GCPhys, rc));
    2038             return rc;
    2039         }
    2040     }
     1919    int rc = pdmIommuMemAccessReadCCPtr(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
     1920    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
     1921        return rc;
    20411922#endif
    20421923
     
    20681949
    20691950#ifdef VBOX_WITH_IOMMU_AMD
    2070     /** @todo IOMMU: Optimize/re-organize things here later. */
    2071     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    2072     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    2073     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    2074     if (   pDevInsIommu
    2075         && pDevInsIommu != pDevIns)
    2076     {
    2077         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    2078         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    2079         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    2080 
    2081         /* Allocate space of translated addresses. */
    2082         size_t const cbIovas  = cPages * sizeof(uint64_t);
    2083         PRTGCPHYS paGCPhysSpa = (PRTGCPHYS)RTMemAllocZ(cbIovas);
    2084         if (paGCPhysSpa)
    2085         { /* likely */ }
    2086         else
    2087         {
    2088             LogFunc(("caller='%s'/%d: returns %Rrc - Failed to alloc %zu bytes for IOVA addresses\n",
    2089                      pDevIns->pReg->szName, pDevIns->iInstance, VERR_NO_MEMORY, cbIovas));
    2090             return VERR_NO_MEMORY;
    2091         }
    2092 
    2093         /* Ask the IOMMU for corresponding translated physical addresses. */
    2094         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    2095         AssertCompile(sizeof(RTGCPHYS) == sizeof(uint64_t));
    2096         int rc = pIommu->pfnMemBulkAccess(pDevInsIommu, uDevId, cPages, (uint64_t const *)paGCPhysPages, PDMIOMMU_MEM_F_WRITE,
    2097                                           paGCPhysSpa);
    2098         if (RT_SUCCESS(rc))
    2099         {
    2100             /* Perform the bulk mapping but with the translated addresses. */
    2101             rc = pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysSpa, fFlags, papvPages, paLocks);
    2102             if (RT_FAILURE(rc))
    2103                 LogFunc(("Bulk mapping of addresses failed. cPages=%zu fFlags=%#x rc=%Rrc\n", rc, cPages, fFlags));
    2104         }
    2105         else
    2106             LogFunc(("IOMMU bulk translation failed. uDevId=%#x cPages=%zu rc=%Rrc\n", uDevId, cPages, rc));
    2107 
    2108         /* Free the translated addresses and return result of the address translation or mapping operation. */
    2109         RTMemFree(paGCPhysSpa);
     1951    int rc = pdmIommuMemAccessBulkWriteCCPtr(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
     1952    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    21101953        return rc;
    2111     }
    21121954#endif
    21131955
     
    21391981
    21401982#ifdef VBOX_WITH_IOMMU_AMD
    2141     /** @todo IOMMU: Optimize/re-organize things here later. */
    2142     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    2143     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    2144     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    2145     if (   pDevInsIommu
    2146         && pDevInsIommu != pDevIns)
    2147     {
    2148         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    2149         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    2150         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    2151 
    2152         /* Allocate space of translated addresses. */
    2153         size_t const cbIovas  = cPages * sizeof(uint64_t);
    2154         PRTGCPHYS paGCPhysSpa = (PRTGCPHYS)RTMemAllocZ(cbIovas);
    2155         if (paGCPhysSpa)
    2156         { /* likely */ }
    2157         else
    2158         {
    2159             LogFunc(("caller='%s'/%d: returns %Rrc - Failed to alloc %zu bytes for IOVA addresses\n",
    2160                      pDevIns->pReg->szName, pDevIns->iInstance, VERR_NO_MEMORY, cbIovas));
    2161             return VERR_NO_MEMORY;
    2162         }
    2163 
    2164         /* Ask the IOMMU for corresponding translated physical addresses. */
    2165         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    2166         AssertCompile(sizeof(RTGCPHYS) == sizeof(uint64_t));
    2167         int rc = pIommu->pfnMemBulkAccess(pDevInsIommu, uDevId, cPages, (uint64_t const *)paGCPhysPages, PDMIOMMU_MEM_F_READ,
    2168                                           paGCPhysSpa);
    2169         if (RT_SUCCESS(rc))
    2170         {
    2171             /* Perform the bulk mapping but with the translated addresses. */
    2172             rc = pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysSpa, fFlags, papvPages, paLocks);
    2173             if (RT_FAILURE(rc))
    2174                 LogFunc(("Bulk mapping of addresses failed. cPages=%zu fFlags=%#x rc=%Rrc\n", rc, cPages, fFlags));
    2175         }
    2176         else
    2177             LogFunc(("IOMMU bulk translation failed. uDevId=%#x cPages=%zu rc=%Rrc\n", uDevId, cPages, rc));
    2178 
    2179         /* Free the translated addresses and return result of the address translation or mapping operation. */
    2180         RTMemFree(paGCPhysSpa);
     1983    int rc = pdmIommuMemAccessBulkReadCCPtr(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
     1984    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    21811985        return rc;
    2182     }
    21831986#endif
    21841987
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp

    r87474 r87477  
    419419
    420420#ifdef VBOX_WITH_IOMMU_AMD
    421     /** @todo IOMMU: Optimize/re-organize things here later. */
    422     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    423     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    424     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    425     if (   pDevInsIommu
    426         && pDevInsIommu != pDevIns)
    427     {
    428         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    429         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    430         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    431         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    432         int rc = VINF_SUCCESS;
    433         while (cbRead > 0)
    434         {
    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                 LogFunc(("IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys, cbRead, rc));
    454                 break;
    455             }
    456         }
     421    int rc = pdmIommuMemAccessRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, fFlags);
     422    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    457423        return rc;
    458     }
    459424#endif
    460425
     
    488453
    489454#ifdef VBOX_WITH_IOMMU_AMD
    490     /** @todo IOMMU: Optimize/re-organize things here later. */
    491     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    492     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    493     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    494     if (   pDevInsIommu
    495         && pDevInsIommu != pDevIns)
    496     {
    497         size_t const idxBus = pPciDev->Int.s.idxPdmBus;
    498         Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
    499         PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
    500         uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    501         int rc = VINF_SUCCESS;
    502         while (cbWrite > 0)
    503         {
    504             RTGCPHYS GCPhysOut;
    505             size_t   cbContig;
    506             rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut, &cbContig);
    507             if (RT_SUCCESS(rc))
    508             {
    509                 /** @todo Handle strict return codes from PGMPhysWrite. */
    510                 rc = pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhysOut, pvBuf, cbContig, fFlags);
    511                 if (RT_SUCCESS(rc))
    512                 {
    513                     cbWrite -= cbContig;
    514                     pvBuf    = (const void *)((uintptr_t)pvBuf + cbContig);
    515                     GCPhys  += cbContig;
    516                 }
    517                 else
    518                     break;
    519             }
    520             else
    521             {
    522                 Log(("pdmR3DevHlp_PCIPhysWrite: IOMMU translation failed. uDevId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDevId, GCPhys,
    523                      cbWrite, rc));
    524                 break;
    525             }
    526         }
     455    int rc = pdmIommuMemAccessWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, fFlags);
     456    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    527457        return rc;
    528     }
    529458#endif
    530459
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r86070 r87477  
    142142
    143143/** @interface_method_impl{PDMIOAPICHLP,pfnIommuMsiRemap} */
    144 static DECLCALLBACK(int) pdmR3IoApicHlp_IommuMsiRemap(PPDMDEVINS pDevIns, uint16_t uDevId, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
     144static DECLCALLBACK(int) pdmR3IoApicHlp_IommuMsiRemap(PPDMDEVINS pDevIns, uint16_t uDeviceId, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
    145145{
    146146    PDMDEV_ASSERT_DEVINS(pDevIns);
     
    149149
    150150#ifdef VBOX_WITH_IOMMU_AMD
    151     /** @todo IOMMU: Optimize/re-organize things here later. */
    152     PVM        pVM          = pDevIns->Internal.s.pVMR3;
    153     PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
    154     PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
    155     if (   pDevInsIommu
    156         && pDevInsIommu != pDevIns)
    157     {
    158         int rc = pIommu->pfnMsiRemap(pDevInsIommu, uDevId, pMsiIn, pMsiOut);
    159         if (RT_SUCCESS(rc))
    160             return rc;
    161 
    162         Log(("pdmR3IoApicHlp_IommuRemapMsi: IOMMU MSI remap failed. uDevId=%#x pMsiIn=(%#RX64, %#RU32) rc=%Rrc\n",
    163              uDevId, pMsiIn->Addr.u64, pMsiIn->Data.u32, rc));
     151    int rc = pdmIommuMsiRemap(pDevIns, uDeviceId, pMsiIn, pMsiOut);
     152    if (RT_SUCCESS(rc) || rc != VERR_IOMMU_NOT_PRESENT)
    164153        return rc;
    165     }
    166154#else
    167     RT_NOREF(pDevIns, uDevId);
     155    RT_NOREF(pDevIns, uDeviceId);
    168156#endif
     157
    169158    *pMsiOut = *pMsiIn;
    170159    return VINF_SUCCESS;
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