VirtualBox

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


Ignore:
Timestamp:
Oct 21, 2020 11:39:04 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
141037
Message:

AMD IOMMU: bugref:9654: Add PDM interfaces for pfnPCIPhysGCPhys2CCPtr[ReadOnly] and merge IOMMU memory read/write interface into memory access interface with a flag.

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

Legend:

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

    r86614 r86661  
    4343#include <iprt/string.h>
    4444#include <iprt/thread.h>
     45#include <iprt/mem.h>
    4546
    4647#include "dtrace/VBoxVMM.h"
     
    18331834        RTGCPHYS GCPhysOut;
    18341835        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1835         int rc = pIommu->pfnMemRead(pDevInsIommu, uDevId, GCPhys, cbRead, &GCPhysOut);
     1836        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    18361837        if (RT_SUCCESS(rc))
    18371838            GCPhys = GCPhysOut;
     
    18871888        RTGCPHYS GCPhysOut;
    18881889        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    1889         int rc = pIommu->pfnMemWrite(pDevInsIommu, uDevId, GCPhys, cbWrite, &GCPhysOut);
     1890        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, &GCPhysOut);
    18901891        if (RT_SUCCESS(rc))
    18911892            GCPhys = GCPhysOut;
     
    19001901
    19011902    return pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, fFlags);
     1903}
     1904
     1905
     1906/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysGCPhys2CCPtr} */
     1907static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     1908                                                         uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
     1909{
     1910    PDMDEV_ASSERT_DEVINS(pDevIns);
     1911    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1912        pPciDev = pDevIns->apPciDevs[0];
     1913    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     1914    PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
     1915
     1916#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     1917    if (PCIDevIsBusmaster(pPciDev))
     1918    { /* likely */ }
     1919    else
     1920    {
     1921        LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp fFlags=%#RX32\n",
     1922                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, fFlags));
     1923        return VERR_PDM_NOT_PCI_BUS_MASTER;
     1924    }
     1925#endif
     1926
     1927#ifdef VBOX_WITH_IOMMU_AMD
     1928    /** @todo IOMMU: Optimize/re-organize things here later. */
     1929    PVM        pVM          = pDevIns->Internal.s.pVMR3;
     1930    PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
     1931    PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
     1932    if (   pDevInsIommu
     1933        && pDevInsIommu != pDevIns)
     1934    {
     1935        size_t const idxBus = pPciDev->Int.s.idxPdmBus;
     1936        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
     1937        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
     1938
     1939        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);
     1942        if (RT_SUCCESS(rc))
     1943            GCPhys = GCPhysOut;
     1944        else
     1945        {
     1946            LogFunc(("IOMMU translation failed. uDevId=%#x GCPhys=%#RGp rc=%Rrc\n", uDevId, GCPhys, rc));
     1947            return rc;
     1948        }
     1949    }
     1950#endif
     1951
     1952    return pDevIns->pHlpR3->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
     1953}
     1954
     1955
     1956/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysGCPhys2CCPtrReadOnly} */
     1957static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
     1958                                                                 uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
     1959{
     1960    PDMDEV_ASSERT_DEVINS(pDevIns);
     1961    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     1962        pPciDev = pDevIns->apPciDevs[0];
     1963    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     1964    PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
     1965
     1966#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     1967    if (PCIDevIsBusmaster(pPciDev))
     1968    { /* likely */ }
     1969    else
     1970    {
     1971        LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp fFlags=%#RX32\n",
     1972                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, fFlags));
     1973        return VERR_PDM_NOT_PCI_BUS_MASTER;
     1974    }
     1975#endif
     1976
     1977#ifdef VBOX_WITH_IOMMU_AMD
     1978    /** @todo IOMMU: Optimize/re-organize things here later. */
     1979    PVM        pVM          = pDevIns->Internal.s.pVMR3;
     1980    PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
     1981    PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
     1982    if (   pDevInsIommu
     1983        && pDevInsIommu != pDevIns)
     1984    {
     1985        size_t const idxBus = pPciDev->Int.s.idxPdmBus;
     1986        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
     1987        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
     1988
     1989        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);
     1992        if (RT_SUCCESS(rc))
     1993            GCPhys = GCPhysOut;
     1994        else
     1995        {
     1996            LogFunc(("IOMMU translation failed. uDevId=%#x GCPhys=%#RGp rc=%Rrc\n", uDevId, GCPhys, rc));
     1997            return rc;
     1998        }
     1999    }
     2000#endif
     2001
     2002    return pDevIns->pHlpR3->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
     2003}
     2004
     2005
     2006/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysBulkGCPhys2CCPtr} */
     2007static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
     2008                                                             PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void **papvPages,
     2009                                                             PPGMPAGEMAPLOCK paLocks)
     2010{
     2011    PDMDEV_ASSERT_DEVINS(pDevIns);
     2012    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     2013        pPciDev = pDevIns->apPciDevs[0];
     2014    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     2015    PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
     2016
     2017#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     2018    if (PCIDevIsBusmaster(pPciDev))
     2019    { /* likely */ }
     2020    else
     2021    {
     2022        LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! cPages=%zu fFlags=%#RX32\n",
     2023                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, cPages, fFlags));
     2024        return VERR_PDM_NOT_PCI_BUS_MASTER;
     2025    }
     2026#endif
     2027
     2028#ifdef VBOX_WITH_IOMMU_AMD
     2029    /** @todo IOMMU: Optimize/re-organize things here later. */
     2030    PVM        pVM          = pDevIns->Internal.s.pVMR3;
     2031    PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
     2032    PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
     2033    if (   pDevInsIommu
     2034        && pDevInsIommu != pDevIns)
     2035    {
     2036        size_t const idxBus = pPciDev->Int.s.idxPdmBus;
     2037        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
     2038        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
     2039
     2040        /* Allocate space of translated addresses. */
     2041        size_t const cbIovas  = cPages * sizeof(uint64_t);
     2042        PRTGCPHYS paGCPhysSpa = (PRTGCPHYS)RTMemAllocZ(cbIovas);
     2043        if (paGCPhysSpa)
     2044        { /* likely */ }
     2045        else
     2046        {
     2047            LogFunc(("caller='%s'/%d: returns %Rrc - Failed to alloc %zu bytes for IOVA addresses\n",
     2048                     pDevIns->pReg->szName, pDevIns->iInstance, VERR_NO_MEMORY, cbIovas));
     2049            return VERR_NO_MEMORY;
     2050        }
     2051
     2052        /* Ask the IOMMU for corresponding translated physical addresses. */
     2053        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
     2054        AssertCompile(sizeof(RTGCPHYS) == sizeof(uint64_t));
     2055        int rc = pIommu->pfnMemBulkAccess(pDevInsIommu, uDevId, cPages, (uint64_t const *)paGCPhysPages, PDMIOMMU_MEM_F_WRITE,
     2056                                          paGCPhysSpa);
     2057        if (RT_SUCCESS(rc))
     2058        {
     2059            /* Perform the bulk mapping but with the translated addresses. */
     2060            rc = pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysSpa, fFlags, papvPages, paLocks);
     2061            if (RT_FAILURE(rc))
     2062                LogFunc(("Bulk mapping of addresses failed. cPages=%zu fFlags=%#x rc=%Rrc\n", rc, cPages, fFlags));
     2063        }
     2064        else
     2065            LogFunc(("IOMMU bulk translation failed. uDevId=%#x cPages=%zu rc=%Rrc\n", uDevId, cPages, rc));
     2066
     2067        /* Free the translated addresses and return result of the address translation or mapping operation. */
     2068        RTMemFree(paGCPhysSpa);
     2069        return rc;
     2070    }
     2071#endif
     2072
     2073    return pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
     2074}
     2075
     2076
     2077/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysBulkGCPhys2CCPtrReadOnly} */
     2078static DECLCALLBACK(int) pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
     2079                                                                     PCRTGCPHYS paGCPhysPages, uint32_t fFlags,
     2080                                                                     const void **papvPages, PPGMPAGEMAPLOCK paLocks)
     2081{
     2082    PDMDEV_ASSERT_DEVINS(pDevIns);
     2083    if (!pPciDev) /* NULL is an alias for the default PCI device. */
     2084        pPciDev = pDevIns->apPciDevs[0];
     2085    AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
     2086    PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
     2087
     2088#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
     2089    if (PCIDevIsBusmaster(pPciDev))
     2090    { /* likely */ }
     2091    else
     2092    {
     2093        LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! cPages=%zu fFlags=%#RX32\n",
     2094                 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, cPages, fFlags));
     2095        return VERR_PDM_NOT_PCI_BUS_MASTER;
     2096    }
     2097#endif
     2098
     2099#ifdef VBOX_WITH_IOMMU_AMD
     2100    /** @todo IOMMU: Optimize/re-organize things here later. */
     2101    PVM        pVM          = pDevIns->Internal.s.pVMR3;
     2102    PPDMIOMMU  pIommu       = &pVM->pdm.s.aIommus[0];
     2103    PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
     2104    if (   pDevInsIommu
     2105        && pDevInsIommu != pDevIns)
     2106    {
     2107        size_t const idxBus = pPciDev->Int.s.idxPdmBus;
     2108        Assert(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
     2109        PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
     2110
     2111        /* Allocate space of translated addresses. */
     2112        size_t const cbIovas  = cPages * sizeof(uint64_t);
     2113        PRTGCPHYS paGCPhysSpa = (PRTGCPHYS)RTMemAllocZ(cbIovas);
     2114        if (paGCPhysSpa)
     2115        { /* likely */ }
     2116        else
     2117        {
     2118            LogFunc(("caller='%s'/%d: returns %Rrc - Failed to alloc %zu bytes for IOVA addresses\n",
     2119                     pDevIns->pReg->szName, pDevIns->iInstance, VERR_NO_MEMORY, cbIovas));
     2120            return VERR_NO_MEMORY;
     2121        }
     2122
     2123        /* Ask the IOMMU for corresponding translated physical addresses. */
     2124        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
     2125        AssertCompile(sizeof(RTGCPHYS) == sizeof(uint64_t));
     2126        int rc = pIommu->pfnMemBulkAccess(pDevInsIommu, uDevId, cPages, (uint64_t const *)paGCPhysPages, PDMIOMMU_MEM_F_READ,
     2127                                          paGCPhysSpa);
     2128        if (RT_SUCCESS(rc))
     2129        {
     2130            /* Perform the bulk mapping but with the translated addresses. */
     2131            rc = pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysSpa, fFlags, papvPages, paLocks);
     2132            if (RT_FAILURE(rc))
     2133                LogFunc(("Bulk mapping of addresses failed. cPages=%zu fFlags=%#x rc=%Rrc\n", rc, cPages, fFlags));
     2134        }
     2135        else
     2136            LogFunc(("IOMMU bulk translation failed. uDevId=%#x cPages=%zu rc=%Rrc\n", uDevId, cPages, rc));
     2137
     2138        /* Free the translated addresses and return result of the address translation or mapping operation. */
     2139        RTMemFree(paGCPhysSpa);
     2140        return rc;
     2141    }
     2142#endif
     2143
     2144    return pDevIns->pHlpR3->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
    19022145}
    19032146
     
    33583601                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32Version, PDM_IOMMUREGR3_VERSION),
    33593602                    VERR_INVALID_PARAMETER);
    3360     AssertPtrReturn(pIommuReg->pfnMemRead, VERR_INVALID_POINTER);
    3361     AssertPtrReturn(pIommuReg->pfnMemWrite, VERR_INVALID_POINTER);
    3362     AssertPtrReturn(pIommuReg->pfnMsiRemap, VERR_INVALID_POINTER);
     3603    AssertPtrReturn(pIommuReg->pfnMemAccess,    VERR_INVALID_POINTER);
     3604    AssertPtrReturn(pIommuReg->pfnMemBulkAccess, VERR_INVALID_POINTER);
     3605    AssertPtrReturn(pIommuReg->pfnMsiRemap,      VERR_INVALID_POINTER);
    33633606    AssertMsgReturn(pIommuReg->u32TheEnd == PDM_IOMMUREGR3_VERSION,
    33643607                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pIommuReg->u32TheEnd, PDM_IOMMUREGR3_VERSION),
     
    33923635     * Init the R3 bits.
    33933636     */
    3394     pIommu->idxIommu    = idxIommu;
    3395     pIommu->pDevInsR3   = pDevIns;
    3396     pIommu->pfnMemRead  = pIommuReg->pfnMemRead;
    3397     pIommu->pfnMemWrite = pIommuReg->pfnMemWrite;
    3398     pIommu->pfnMsiRemap = pIommuReg->pfnMsiRemap;
     3637    pIommu->idxIommu         = idxIommu;
     3638    pIommu->pDevInsR3        = pDevIns;
     3639    pIommu->pfnMemAccess     = pIommuReg->pfnMemAccess;
     3640    pIommu->pfnMemBulkAccess = pIommuReg->pfnMemBulkAccess;
     3641    pIommu->pfnMsiRemap      = pIommuReg->pfnMsiRemap;
    33993642    Log(("PDM: Registered IOMMU device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
    34003643
     
    42204463    pdmR3DevHlp_PCIPhysRead,
    42214464    pdmR3DevHlp_PCIPhysWrite,
     4465    pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
     4466    pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
     4467    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
     4468    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
    42224469    pdmR3DevHlp_PCISetIrq,
    42234470    pdmR3DevHlp_PCISetIrqNoWait,
     
    45654812    pdmR3DevHlpTracing_PCIPhysRead,
    45664813    pdmR3DevHlpTracing_PCIPhysWrite,
     4814    pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
     4815    pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
     4816    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
     4817    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
    45674818    pdmR3DevHlpTracing_PCISetIrq,
    45684819    pdmR3DevHlpTracing_PCISetIrqNoWait,
     
    50675318    pdmR3DevHlp_PCIPhysRead,
    50685319    pdmR3DevHlp_PCIPhysWrite,
     5320    pdmR3DevHlp_PCIPhysGCPhys2CCPtr,
     5321    pdmR3DevHlp_PCIPhysGCPhys2CCPtrReadOnly,
     5322    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtr,
     5323    pdmR3DevHlp_PCIPhysBulkGCPhys2CCPtrReadOnly,
    50695324    pdmR3DevHlp_PCISetIrq,
    50705325    pdmR3DevHlp_PCISetIrqNoWait,
  • trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp

    r86070 r86661  
    432432        RTGCPHYS GCPhysOut;
    433433        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    434         int rc = pIommu->pfnMemRead(pDevInsIommu, uDevId, GCPhys, cbRead, &GCPhysOut);
     434        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbRead, PDMIOMMU_MEM_F_READ, &GCPhysOut);
    435435        if (RT_SUCCESS(rc))
    436436            GCPhys = GCPhysOut;
     
    488488        RTGCPHYS GCPhysOut;
    489489        uint16_t const uDevId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
    490         int rc = pIommu->pfnMemWrite(pDevInsIommu, uDevId, GCPhys, cbWrite, &GCPhysOut);
     490        int rc = pIommu->pfnMemAccess(pDevInsIommu, uDevId, GCPhys, cbWrite, PDMIOMMU_MEM_F_WRITE, & GCPhysOut);
    491491        if (RT_SUCCESS(rc))
    492492            GCPhys = GCPhysOut;
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