VirtualBox

Changeset 89238 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
May 24, 2021 1:53:16 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144581
Message:

Intel IOMMU: bugref:9967 Address translation, WIP.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r89236 r89238  
    395395    DMAREVENTTYPE_FAULT
    396396} DMAREVENTTYPE;
     397
     398
     399/**
     400 * DMA address map.
     401 * This structure holds information about a DMA address translation.
     402 */
     403typedef struct DMARADDRMAP
     404{
     405    /** The device ID (bus, device, function). */
     406    uint16_t        idDevice;
     407    uint16_t        uPadding0;
     408    /** The DMA remapping operation request type. */
     409    VTDREQTYPE      enmReqType;
     410    /** The DMA address being accessed. */
     411    uint64_t        uDmaAddr;
     412    /** The size of the DMA access (in bytes). */
     413    size_t          cbDma;
     414    /** The translated system-physical address (HPA). */
     415    RTGCPHYS        GCPhysSpa;
     416    /** The size of the contiguous translated region (in bytes). */
     417    size_t          cbContiguous;
     418} DMARADDRMAP;
     419/** Pointer to a DMA address map. */
     420typedef DMARADDRMAP *PDMARADDRMAP;
     421/** Pointer to a const DMA address map. */
     422typedef DMARADDRMAP const *PCDMARADDRMAP;
    397423
    398424
     
    681707
    682708/**
    683  * Returns whether the interrupt remapping fault is qualified or not.
     709 * Returns whether the interrupt remapping (IR) fault is qualified or not.
    684710 *
    685711 * @returns @c true if qualified, @c false otherwise.
     
    13001326 * Records an interrupt request fault.
    13011327 *
    1302  * @param   pDevIns         The IOMMU device instance.
    1303  * @param   enmDiag         The diagnostic reason.
    1304  * @param   enmIrFault    The interrupt fault reason.
    1305  * @param   idDevice        The device ID (bus, device, function).
    1306  * @param   idxIntr         The interrupt index.
     1328 * @param   pDevIns     The IOMMU device instance.
     1329 * @param   enmDiag     The diagnostic reason.
     1330 * @param   enmIrFault  The interrupt fault reason.
     1331 * @param   idDevice    The device ID (bus, device, function).
     1332 * @param   idxIntr     The interrupt index.
    13071333 */
    13081334static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice, uint16_t idxIntr)
     
    13221348 * in the IRTE.
    13231349 *
    1324  * @param   pDevIns         The IOMMU device instance.
    1325  * @param   enmDiag         The diagnostic reason.
    1326  * @param   enmIrFault    The interrupt fault reason.
    1327  * @param   idDevice        The device ID (bus, device, function).
    1328  * @param   idxIntr         The interrupt index.
    1329  * @param   pIrte           The IRTE that caused this fault.
     1350 * @param   pDevIns     The IOMMU device instance.
     1351 * @param   enmDiag     The diagnostic reason.
     1352 * @param   enmIrFault  The interrupt fault reason.
     1353 * @param   idDevice    The device ID (bus, device, function).
     1354 * @param   idxIntr     The interrupt index.
     1355 * @param   pIrte       The IRTE that caused this fault.
    13301356 */
    13311357static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIRFAULT enmIrFault, uint16_t idDevice,
     
    17521778
    17531779/**
    1754  * Performs a PCI target abort for a DMA remapping operation.
     1780 * Performs a PCI target abort for a DMA remapping (DR) operation.
    17551781 *
    17561782 * @param   pDevIns     The IOMMU device instance.
     
    17681794
    17691795/**
    1770  * Validates the table translation mode for a DMA remapping operation.
    1771  *
    1772  * @returns @c true if the TTM is valid, @c false otherwise.
     1796 * Handles remapping of DMA address requests in legacy mode.
     1797 *
     1798 * @returns VBox status code.
    17731799 * @param   pDevIns         The IOMMU device instance.
    17741800 * @param   uRtaddrReg      The current RTADDR_REG value.
     1801 * @param   pAddrRemap      The DMA address remap info.
     1802 */
     1803static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRMAP pAddrRemap)
     1804{
     1805    RT_NOREF3(pDevIns, uRtaddrReg, pAddrRemap);
     1806    return VERR_NOT_IMPLEMENTED;
     1807}
     1808
     1809
     1810/**
     1811 * Handles remapping of DMA address requests in scalable mode.
     1812 *
     1813 * @returns VBox status code.
     1814 * @param   pDevIns         The IOMMU device instance.
     1815 * @param   uRtaddrReg      The current RTADDR_REG value.
     1816 * @param   pAddrRemap      The DMA address remap info.
     1817 */
     1818static int dmarDrScalableModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRMAP pAddrRemap)
     1819{
     1820    PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     1821    if (pThis->fExtCapReg & VTD_BF_ECAP_REG_SMTS_MASK)
     1822    {
     1823        RT_NOREF1(uRtaddrReg);
     1824        return VERR_NOT_IMPLEMENTED;
     1825    }
     1826
     1827    dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_3, VTDATFAULT_RTA_1_3, pAddrRemap->idDevice, pAddrRemap->uDmaAddr,
     1828                      pAddrRemap->enmReqType);
     1829    return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
     1830}
     1831
     1832
     1833/**
     1834 * Reads a root entry from guest memory.
     1835 *
     1836 * @returns VBox status code.
    17751837 * @param   idDevice        The device ID (bus, device, function).
    1776  * @param   uIova           The I/O virtual address being accessed.
    1777  * @param   enmReqType      The type of the request (for fault recording).
    1778  */
    1779 static bool dmarDrIsTtmValid(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, uint16_t idDevice, uint64_t uIova, VTDREQTYPE enmReqType)
    1780 {
    1781     bool fValid = true;
    1782     PCDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PCDMAR);
    1783     uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
    1784     switch (fTtm)
    1785     {
    1786         case VTD_TTM_LEGACY_MODE:
    1787             break;
    1788 
    1789         case VTD_TTM_SCALABLE_MODE:
    1790         {
    1791             if (pThis->fExtCapReg & VTD_BF_ECAP_REG_SMTS_MASK)
    1792                 break;
    1793             dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_3, VTDATFAULT_RTA_1_3, idDevice, uIova, enmReqType);
    1794             fValid = false;
    1795             break;
    1796         }
    1797 
    1798         case VTD_TTM_ABORT_DMA_MODE:
    1799         {
    1800             if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK)
    1801                 dmarDrTargetAbort(pDevIns);
    1802             else
    1803                 dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_1, VTDATFAULT_RTA_1_1, idDevice, uIova, enmReqType);
    1804             fValid = false;
    1805             break;
    1806         }
    1807 
    1808         default:
    1809         {
    1810             dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_2, VTDATFAULT_RTA_1_2, idDevice, uIova, enmReqType);
    1811             fValid = false;
    1812             break;
    1813         }
    1814     }
    1815     return fValid;
     1838 * @param   pRootEntry      Where to store the read root entry.
     1839 */
     1840static int dmarDrReadRootEntry(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, uint8_t idxEntry, PVTD_ROOT_ENTRY_T pRootEntry)
     1841{
     1842    size_t const   cbEntry     = sizeof(*pRootEntry);
     1843    RTGCPHYS const GCPhysEntry = (uRtaddrReg & VTD_BF_RTADDR_REG_RTA_MASK) + (idxEntry * cbEntry);
     1844    return PDMDevHlpPhysReadMeta(pDevIns, GCPhysEntry, pRootEntry, cbEntry);
    18161845}
    18171846
     
    18851914        }
    18861915
    1887         bool const fTtmValid = dmarDrIsTtmValid(pDevIns, uRtaddrReg, idDevice, uIova, enmReqType);
    1888         if (!fTtmValid)
    1889             return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
    1890 
    1891         return VERR_NOT_IMPLEMENTED;
     1916        DMARADDRMAP AddrRemap;
     1917        AddrRemap.idDevice     = idDevice;
     1918        AddrRemap.enmReqType   = enmReqType;
     1919        AddrRemap.uDmaAddr     = uIova;
     1920        AddrRemap.cbDma        = cbIova;
     1921        AddrRemap.GCPhysSpa    = NIL_RTGCPHYS;
     1922        AddrRemap.cbContiguous = 0;
     1923
     1924        int rc;
     1925        uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
     1926        switch (fTtm)
     1927        {
     1928            case VTD_TTM_LEGACY_MODE:
     1929            {
     1930                rc = dmarDrLegacyModeRemapAddr(pDevIns, uRtaddrReg, &AddrRemap);
     1931                break;
     1932            }
     1933
     1934            case VTD_TTM_SCALABLE_MODE:
     1935            {
     1936                rc = dmarDrScalableModeRemapAddr(pDevIns, uRtaddrReg, &AddrRemap);
     1937                break;
     1938            }
     1939
     1940            case VTD_TTM_ABORT_DMA_MODE:
     1941            {
     1942                rc = VERR_IOMMU_ADDR_TRANSLATION_FAILED;
     1943                if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK)
     1944                    dmarDrTargetAbort(pDevIns);
     1945                else
     1946                    dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_1, VTDATFAULT_RTA_1_1, idDevice, uIova, enmReqType);
     1947                break;
     1948            }
     1949
     1950            default:
     1951            {
     1952                rc = VERR_IOMMU_ADDR_TRANSLATION_FAILED;
     1953                dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Rta_1_2, VTDATFAULT_RTA_1_2, idDevice, uIova, enmReqType);
     1954                break;
     1955            }
     1956        }
     1957
     1958        *pcbContiguous = AddrRemap.cbContiguous;
     1959        *pGCPhysSpa    = AddrRemap.GCPhysSpa;
     1960        return rc;
    18921961    }
    18931962
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