VirtualBox

Changeset 89256 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
May 25, 2021 7:04:48 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144599
Message:

Intel IOMMU: bugref:9967 Address translation, WIP.

File:
1 edited

Legend:

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

    r89247 r89256  
    135135#define DMAR_VER_MINOR                              0
    136136
     137/** Number of domain supported (0=16, 1=64, 2=256, 3=1K, 4=4K, 5=16K, 6=64K,
     138 *  7=Reserved). */
     139#define DMAR_ND                                     6
     140
    137141/** Release log prefix string. */
    138142#define DMAR_LOG_PFX                                "Intel-IOMMU"
     
    158162
    159163    /* Address Translation Faults. */
     164    kDmarDiag_Atf_Lct_1,
     165    kDmarDiag_Atf_Lct_2,
     166    kDmarDiag_Atf_Lct_3,
     167    kDmarDiag_Atf_Lct_4_1,
     168    kDmarDiag_Atf_Lct_4_2,
     169    kDmarDiag_Atf_Lct_4_3,
    160170    kDmarDiag_Atf_Lrt_1,
    161171    kDmarDiag_Atf_Lrt_2,
     
    217227{
    218228    DMARDIAG_DESC(None                      ),
     229    DMARDIAG_DESC(Atf_Lct_1                 ),
     230    DMARDIAG_DESC(Atf_Lct_2                 ),
     231    DMARDIAG_DESC(Atf_Lct_3                 ),
     232    DMARDIAG_DESC(Atf_Lct_4_1               ),
     233    DMARDIAG_DESC(Atf_Lct_4_2               ),
     234    DMARDIAG_DESC(Atf_Lct_4_3               ),
    219235    DMARDIAG_DESC(Atf_Lrt_1                 ),
    220236    DMARDIAG_DESC(Atf_Lrt_2                 ),
     
    672688AssertCompile(sizeof(g_apbRw1cMasks) == sizeof(g_apbRwMasks));
    673689
     690/** Array of valid domain-ID bits. */
     691static uint16_t const g_auNdMask[] = { 0xf, 0x3f, 0xff, 0x3ff, 0xfff, 0x3fff, 0xffff, 0 };
     692AssertCompile(RT_ELEMENTS(g_auNdMask) >= DMAR_ND);
     693
    674694
    675695#ifndef VBOX_DEVICE_STRUCT_TESTCASE
     
    14271447    dmarAtFaultRecordEx(pDevIns, enmDiag, enmAtFault, idDevice, uFaultAddr, enmReqType, 0 /* uAddrType */,
    14281448                          false /* fHasPasid */, 0 /* uPasid */, 0 /* fReqAttr */);
     1449}
     1450
     1451
     1452/**
     1453 * Records a qualified address translation fault.
     1454 *
     1455 * Qualified faults are those that can be suppressed by software using the FPD bit
     1456 * in the contex entry, scalable-mode context entry etc.
     1457 *
     1458 * This is to be used when Device-TLB, and PASIDs are not supported or for requests
     1459 * where the device-TLB and PASID is not relevant/present.
     1460 *
     1461 * @param   pDevIns             The IOMMU device instance.
     1462 * @param   enmDiag             The diagnostic reason.
     1463 * @param   enmAtFault          The address translation fault reason.
     1464 * @param   idDevice            The device ID (bus, device, function).
     1465 * @param   uFaultAddr          The page address of the faulted request.
     1466 * @param   enmReqType          The type of the faulted request.
     1467 * @param   uPagingEntryQw0     The first qword of the paging entry.
     1468 */
     1469static void dmarAtFaultQualifiedRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDATFAULT enmAtFault, uint16_t idDevice,
     1470                                       uint64_t uFaultAddr, VTDREQTYPE enmReqType, uint64_t uPagingEntryQw0)
     1471{
     1472    AssertCompile(    VTD_BF_0_CONTEXT_ENTRY_FPD_MASK       == 0x2
     1473                   && VTD_BF_0_SM_CONTEXT_ENTRY_FPD_MASK    == 0x2
     1474                   && VTD_BF_0_SM_CONTEXT_ENTRY_FPD_MASK    == 0x2
     1475                   && VTD_BF_SM_PASID_DIR_ENTRY_FPD_MASK    == 0x2
     1476                   && VTD_BF_0_SM_PASID_TBL_ENTRY_FPD_MASK  == 0x2);
     1477    if (!(uPagingEntryQw0 & VTD_BF_0_CONTEXT_ENTRY_FPD_MASK))
     1478        dmarAtFaultRecordEx(pDevIns, enmDiag, enmAtFault, idDevice, uFaultAddr, enmReqType, 0 /* uAddrType */,
     1479                            false /* fHasPasid */, 0 /* uPasid */, 0 /* fReqAttr */);
    14291480}
    14301481
     
    18501901        uint64_t const uRootEntryQword0 = RootEntry.au64[0];
    18511902        uint64_t const uRootEntryQword1 = RootEntry.au64[1];
    1852         bool const fPresent = RT_BF_GET(uRootEntryQword0, VTD_BF_0_ROOT_ENTRY_P);
    1853         if (fPresent)
     1903        bool const fRootEntryPresent = RT_BF_GET(uRootEntryQword0, VTD_BF_0_ROOT_ENTRY_P);
     1904        if (fRootEntryPresent)
    18541905        {
    18551906            if (   !(uRootEntryQword0 & ~VTD_ROOT_ENTRY_0_VALID_MASK)
     
    18601911                VTD_CONTEXT_ENTRY_T CtxEntry;
    18611912                rc = dmarDrReadCtxEntry(pDevIns, GCPhysCtxTable, idxCtxEntry, &CtxEntry);
    1862 
    1863                 /** @todo Handle context entry validation and processing. */
    1864                 return VERR_NOT_IMPLEMENTED;
     1913                if (RT_SUCCESS(rc))
     1914                {
     1915                    uint64_t const uCtxEntryQword0 = CtxEntry.au64[0];
     1916                    uint64_t const uCtxEntryQword1 = CtxEntry.au64[1];
     1917                    bool const fCtxEntryPresent = RT_BF_GET(uCtxEntryQword0, VTD_BF_0_CONTEXT_ENTRY_P);
     1918                    if (fCtxEntryPresent)
     1919                    {
     1920                        if (   !(uCtxEntryQword0 & ~VTD_CONTEXT_ENTRY_0_VALID_MASK)
     1921                            && !(uCtxEntryQword1 & ~VTD_CONTEXT_ENTRY_1_VALID_MASK))
     1922                        {
     1923                            /** @todo Handle context entry validation and processing. */
     1924                            return VERR_NOT_IMPLEMENTED;
     1925                        }
     1926                        else
     1927                            dmarAtFaultQualifiedRecord(pDevIns, kDmarDiag_Atf_Lct_1, VTDATFAULT_LCT_3, pAddrRemap->idDevice,
     1928                                                       pAddrRemap->uDmaAddr, pAddrRemap->enmReqType, uCtxEntryQword0);
     1929                    }
     1930                    else
     1931                        dmarAtFaultQualifiedRecord(pDevIns, kDmarDiag_Atf_Lct_1, VTDATFAULT_LCT_2, pAddrRemap->idDevice,
     1932                                                   pAddrRemap->uDmaAddr, pAddrRemap->enmReqType, uCtxEntryQword0);
     1933                }
     1934                else
     1935                    dmarAtFaultRecord(pDevIns, kDmarDiag_Atf_Lct_1, VTDATFAULT_LCT_1, pAddrRemap->idDevice, pAddrRemap->uDmaAddr,
     1936                                      pAddrRemap->enmReqType);
    18651937            }
    18661938            else
     
    30493121                                         : X86_PAGE_2M_SHIFT)
    30503122                               - X86_PAGE_4K_SHIFT;
    3051         uint8_t const fNd      = 2;                                /* Number of domains supported (0=16, 1=64, 2=256, 3=1K, 4=4K,
    3052                                                                       5=16K, 6=64K, 7=Reserved). */
     3123        uint8_t const fNd      = DMAR_ND;                          /* Number of domains supported. */
    30533124        uint8_t const fPsi     = 1;                                /* Page selective invalidation. */
    30543125        uint8_t const uMgaw    = cGstPhysAddrBits - 1;             /* Maximum guest address width. */
     
    30573128        uint8_t const fEsrtps  = 1;                                /* Enhanced SRTPS (auto invalidate cache on SRTP). */
    30583129        uint8_t const fEsirtps = 1;                                /* Enhanced SIRTPS (auto invalidate cache on SIRTP). */
     3130        AssertCompile(DMAR_ND <= 6);
    30593131
    30603132        pThis->fCapReg = RT_BF_MAKE(VTD_BF_CAP_REG_ND,      fNd)
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