VirtualBox

Changeset 89245 in vbox


Ignore:
Timestamp:
May 24, 2021 3:58:34 PM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Address translation, WIP.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/iommu-intel.h

    r89238 r89245  
    151151/** Pointer to a const root entry. */
    152152typedef VTD_ROOT_ENTRY_T const *PCVTD_ROOT_ENTRY_T;
     153
     154/* Root Entry: Qword 0 valid mask. */
     155#define VTD_ROOT_ENTRY_0_VALID_MASK                             (VTD_BF_0_ROOT_ENTRY_P_MASK | VTD_BF_0_ROOT_ENTRY_CTP_MASK)
     156/* Root Entry: Qword 1 valid mask. */
     157#define VTD_ROOT_ENTRY_1_VALID_MASK                             UINT64_C(0)
    153158/** @} */
    154159
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r89238 r89245  
    158158
    159159    /* Address Translation Faults. */
     160    kDmarDiag_Atf_Lrt_1,
     161    kDmarDiag_Atf_Lrt_2,
     162    kDmarDiag_Atf_Lrt_3,
    160163    kDmarDiag_Atf_Rta_1_1,
    161164    kDmarDiag_Atf_Rta_1_2,
     
    214217{
    215218    DMARDIAG_DESC(None                      ),
     219    DMARDIAG_DESC(Atf_Lrt_1                 ),
     220    DMARDIAG_DESC(Atf_Lrt_2                 ),
     221    DMARDIAG_DESC(Atf_Lrt_3                 ),
    216222    DMARDIAG_DESC(Atf_Rta_1_1               ),
    217223    DMARDIAG_DESC(Atf_Rta_1_2               ),
     
    17941800
    17951801/**
     1802 * Reads a root entry from guest memory.
     1803 *
     1804 * @returns VBox status code.
     1805 * @param   pDevIns         The IOMMU device instance.
     1806 * @param   uRtaddrReg      The current RTADDR_REG value.
     1807 * @param   idxRootEntry    The root entry index to read.
     1808 * @param   pRootEntry      Where to store the read root entry.
     1809 */
     1810static int dmarDrReadRootEntry(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, uint8_t idxRootEntry, PVTD_ROOT_ENTRY_T pRootEntry)
     1811{
     1812    size_t const   cbRootEntry     = sizeof(*pRootEntry);
     1813    RTGCPHYS const GCPhysRootEntry = (uRtaddrReg & VTD_BF_RTADDR_REG_RTA_MASK) + (idxRootEntry * cbRootEntry);
     1814    return PDMDevHlpPhysReadMeta(pDevIns, GCPhysRootEntry, pRootEntry, cbRootEntry);
     1815}
     1816
     1817
     1818static int dmarDrReadCtxEntry(PPDMDEVINS pDevIns, RTGCPHYS GCPhysCtxTable, uint8_t idxCtxEntry, PVTD_CONTEXT_ENTRY_T pCtxEntry)
     1819{
     1820    size_t const   cbCtxEntry     = sizeof(*pCtxEntry);
     1821    RTGCPHYS const GCPhysCtxEntry = GCPhysCtxTable + (idxCtxEntry * cbCtxEntry);
     1822    return PDMDevHlpPhysReadMeta(pDevIns, GCPhysCtxEntry, pCtxEntry, cbCtxEntry);
     1823}
     1824
     1825
     1826/**
    17961827 * Handles remapping of DMA address requests in legacy mode.
    17971828 *
     
    18031834static int dmarDrLegacyModeRemapAddr(PPDMDEVINS pDevIns, uint64_t uRtaddrReg, PDMARADDRMAP pAddrRemap)
    18041835{
    1805     RT_NOREF3(pDevIns, uRtaddrReg, pAddrRemap);
    1806     return VERR_NOT_IMPLEMENTED;
     1836    uint8_t const idxRootEntry = RT_HI_U8(pAddrRemap->idDevice);
     1837    VTD_ROOT_ENTRY_T RootEntry;
     1838    int rc = dmarDrReadRootEntry(pDevIns, uRtaddrReg, idxRootEntry, &RootEntry);
     1839    if (RT_SUCCESS(rc))
     1840    {
     1841        uint64_t const uRootEntryQword0 = RootEntry.au64[0];
     1842        uint64_t const uRootEntryQword1 = RootEntry.au64[1];
     1843        bool const fPresent = RT_BF_GET(uRootEntryQword0, VTD_BF_0_ROOT_ENTRY_P);
     1844        if (fPresent)
     1845        {
     1846            if (   !(uRootEntryQword0 & ~VTD_ROOT_ENTRY_0_VALID_MASK)
     1847                && !(uRootEntryQword1 & ~VTD_ROOT_ENTRY_1_VALID_MASK))
     1848            {
     1849                RTGCPHYS const GCPhysCtxTable = RT_BF_GET(uRootEntryQword0, VTD_BF_0_ROOT_ENTRY_CTP);
     1850                uint8_t const idxCtxEntry = RT_LO_U8(pAddrRemap->idDevice);
     1851                VTD_CONTEXT_ENTRY_T CtxEntry;
     1852                rc = dmarDrReadCtxEntry(pDevIns, GCPhysCtxTable, idxCtxEntry, &CtxEntry);
     1853
     1854                /** @todo Handle context entry validation and processing. */
     1855                return VERR_NOT_IMPLEMENTED;
     1856            }
     1857            else
     1858                dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Lrt_3, VTDATFAULT_LRT_3, pAddrRemap->idDevice, pAddrRemap->uDmaAddr,
     1859                                  pAddrRemap->enmReqType);
     1860        }
     1861        else
     1862            dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Lrt_2, VTDATFAULT_LRT_2, pAddrRemap->idDevice, pAddrRemap->uDmaAddr,
     1863                              pAddrRemap->enmReqType);
     1864    }
     1865    else
     1866        dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Lrt_1, VTDATFAULT_LRT_1, pAddrRemap->idDevice, pAddrRemap->uDmaAddr,
     1867                          pAddrRemap->enmReqType);
     1868    return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
    18071869}
    18081870
     
    18281890                      pAddrRemap->enmReqType);
    18291891    return VERR_IOMMU_ADDR_TRANSLATION_FAILED;
    1830 }
    1831 
    1832 
    1833 /**
    1834  * Reads a root entry from guest memory.
    1835  *
    1836  * @returns VBox status code.
    1837  * @param   idDevice        The device ID (bus, device, function).
    1838  * @param   pRootEntry      Where to store the read root entry.
    1839  */
    1840 static 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);
    18451892}
    18461893
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