VirtualBox

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


Ignore:
Timestamp:
May 20, 2021 2:05:41 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144542
Message:

Intel IOMMU: bugref:9967 Address translation, WIP.

File:
1 edited

Legend:

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

    r89195 r89201  
    661661 *
    662662 * @returns @c true if qualified, @c false otherwise.
    663  * @param   enmIrFault  The interrupt remapping fault condition.
    664  */
    665 static bool vtdIrFaultIsQualified(VTD_IR_FAULT_T enmIrFault)
    666 {
    667     switch (enmIrFault)
    668     {
    669         case kIrf_Irte_Not_Present:
    670         case kIrf_Irte_Present_Rsvd:
    671         case kIrf_Irte_Present_Invalid:
    672         case kIrf_Pid_Read_Failed:
    673         case kIrf_Pid_Rsvd:
     663 * @param   enmIntrFault    The interrupt remapping fault condition.
     664 */
     665static bool vtdIrFaultIsQualified(VTDINTRFAULT enmIntrFault)
     666{
     667    switch (enmIntrFault)
     668    {
     669        case VTDINTRFAULT_IRTE_NOT_PRESENT:
     670        case VTDINTRFAULT_IRTE_PRESENT_RSVD:
     671        case VTDINTRFAULT_IRTE_PRESENT_INVALID:
     672        case VTDINTRFAULT_PID_READ_FAILED:
     673        case VTDINTRFAULT_PID_RSVD:
    674674            return true;
    675675        default:
     
    12391239 * Records an interrupt request fault.
    12401240 *
    1241  * @param   pDevIns     The IOMMU device instance.
    1242  * @param   enmDiag     The diagnostic reason.
    1243  * @param   enmIrFault  The interrupt fault reason.
    1244  * @param   idDevice    The device ID (bus, device, function).
    1245  * @param   idxIntr     The interrupt index.
    1246  */
    1247 static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IR_FAULT_T enmIrFault, uint16_t idDevice,
     1241 * @param   pDevIns         The IOMMU device instance.
     1242 * @param   enmDiag         The diagnostic reason.
     1243 * @param   enmIntrFault    The interrupt fault reason.
     1244 * @param   idDevice        The device ID (bus, device, function).
     1245 * @param   idxIntr         The interrupt index.
     1246 */
     1247static void dmarIrFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice,
    12481248                              uint16_t idxIntr)
    12491249{
     
    12631263        /* Update the fault recording registers with the fault information. */
    12641264        uint64_t const uFrcdHi = RT_BF_MAKE(VTD_BF_1_FRCD_REG_SID, idDevice)
    1265                                | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR,  enmIrFault)
     1265                               | RT_BF_MAKE(VTD_BF_1_FRCD_REG_FR,  enmIntrFault)
    12661266                               | RT_BF_MAKE(VTD_BF_1_FRCD_REG_F,   1);
    12671267        uint64_t const uFrcdLo = (uint64_t)idxIntr << 48;
     
    12861286 * in the IRTE.
    12871287 *
    1288  * @param   pDevIns     The IOMMU device instance.
    1289  * @param   enmDiag     The diagnostic reason.
    1290  * @param   enmIrFault  The interrupt fault reason.
    1291  * @param   idDevice    The device ID (bus, device, function).
    1292  * @param   idxIntr     The interrupt index.
    1293  * @param   pIrte       The IRTE that caused this fault.
    1294  */
    1295 static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IR_FAULT_T enmIrFault, uint16_t idDevice,
     1288 * @param   pDevIns         The IOMMU device instance.
     1289 * @param   enmDiag         The diagnostic reason.
     1290 * @param   enmIntrFault    The interrupt fault reason.
     1291 * @param   idDevice        The device ID (bus, device, function).
     1292 * @param   idxIntr         The interrupt index.
     1293 * @param   pIrte           The IRTE that caused this fault.
     1294 */
     1295static void dmarIrFaultRecordQualified(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDINTRFAULT enmIntrFault, uint16_t idDevice,
    12961296                                       uint16_t idxIntr, PCVTD_IRTE_T pIrte)
    12971297{
    1298     Assert(vtdIrFaultIsQualified(enmIrFault));
     1298    Assert(vtdIrFaultIsQualified(enmIntrFault));
    12991299    Assert(pIrte);
    13001300    if (!(pIrte->au64[0] & VTD_BF_0_IRTE_FPD_MASK))
    1301         return dmarIrFaultRecord(pDevIns, enmDiag, enmIrFault, idDevice, idxIntr);
     1301        return dmarIrFaultRecord(pDevIns, enmDiag, enmIntrFault, idDevice, idxIntr);
    13021302}
    13031303
     
    13101310 * @param   enmDiag     The diagnostic reason.
    13111311 */
    1312 static void dmarIqeFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTD_IQEI_T enmIqei)
     1312static void dmarIqeFaultRecord(PPDMDEVINS pDevIns, DMARDIAG enmDiag, VTDIQEI enmIqei)
    13131313{
    13141314    PDMAR    pThis   = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     
    15391539        /* Hardware treats bit 4 as RsvdZ in this situation, so clear it. */
    15401540        dmarRegChangeRaw32(pThis, offReg, ~RT_BIT(4), 0 /* fOrMask */);
    1541         dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, kIqei_QueueTailNotAligned);
     1541        dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_NotAligned, VTDIQEI_QUEUE_TAIL_MISALIGNED);
    15421542    }
    15431543    return VINF_SUCCESS;
     
    15701570        { /* likely */ }
    15711571        else
    1572             dmarIqeFaultRecord(pDevIns, kDmarDiag_IqaReg_Dw_256_Invalid, kIqei_InvalidDescriptorWidth);
     1572            dmarIqeFaultRecord(pDevIns, kDmarDiag_IqaReg_Dw_256_Invalid, VTDIQEI_INVALID_DESCRIPTOR_WIDTH);
    15731573    }
    15741574    /* else: 128-bit descriptor width is validated lazily, see explanation in dmarR3InvQueueProcessRequests. */
     
    17011701
    17021702    DMAR_LOCK(pDevIns, pThisCC);
    1703     uint32_t const uGstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_GSTS_REG);
     1703    uint32_t const uGstsReg   = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_GSTS_REG);
     1704    uint64_t const uRtaddrReg = pThis->uRtaddrReg;
    17041705    DMAR_UNLOCK(pDevIns, pThisCC);
     1706
    17051707
    17061708    if (uGstsReg & VTD_BF_GSTS_REG_TES_MASK)
     
    17101712        else
    17111713            STAM_COUNTER_INC(&pThis->CTX_SUFF_Z(StatMemWrite));
     1714
     1715        uint8_t const fTtm = RT_BF_GET(uRtaddrReg, VTD_BF_RTADDR_REG_TTM);
     1716        switch (fTtm)
     1717        {
     1718            case VTD_TTM_LEGACY_MODE:
     1719            case VTD_TTM_ABORT_DMA_MODE:
     1720            {
     1721                if (pThis->fExtCapReg & VTD_BF_ECAP_REG_ADMS_MASK)
     1722                {
     1723
     1724                }
     1725            }
     1726        }
    17121727
    17131728        return VERR_NOT_IMPLEMENTED;
     
    18841899                                return VINF_SUCCESS;
    18851900                            }
    1886                             dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid, kIrf_Irte_Present_Rsvd,
    1887                                                        idDevice, idxIntr, &Irte);
     1901                            dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid,
     1902                                                       VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr, &Irte);
    18881903                        }
    18891904                        else
    1890                             dmarIrFaultRecordQualified(pDevIns, enmIrDiag, kIrf_Irte_Present_Rsvd, idDevice, idxIntr, &Irte);
     1905                            dmarIrFaultRecordQualified(pDevIns, enmIrDiag, VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice, idxIntr,
     1906                                                       &Irte);
    18911907                    }
    18921908                    else
    1893                         dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, kIrf_Irte_Present_Rsvd, idDevice,
     1909                        dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Rsvd, VTDINTRFAULT_IRTE_PRESENT_RSVD, idDevice,
    18941910                                                   idxIntr, &Irte);
    18951911                }
    18961912                else
    1897                     dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, kIrf_Irte_Not_Present, idDevice,
    1898                                                idxIntr, &Irte);
     1913                    dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Not_Present, VTDINTRFAULT_IRTE_NOT_PRESENT,
     1914                                               idDevice, idxIntr, &Irte);
    18991915            }
    19001916            else
    1901                 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, kIrf_Irte_Read_Failed, idDevice, idxIntr);
     1917                dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Irte_Read_Failed, VTDINTRFAULT_IRTE_READ_FAILED, idDevice, idxIntr);
    19021918        }
    19031919        else
    1904             dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, kIrf_Intr_Index_Invalid, idDevice, idxIntr);
     1920            dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Intr_Index_Invalid, VTDINTRFAULT_INTR_INDEX_INVALID, idDevice, idxIntr);
    19051921    }
    19061922    else
    1907         dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, kIrf_Remappable_Intr_Rsvd, idDevice, 0 /* idxIntr */);
     1923        dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Rfi_Rsvd, VTDINTRFAULT_REMAPPABLE_INTR_RSVD, idDevice, 0 /* idxIntr */);
    19081924    return VERR_IOMMU_INTR_REMAP_DENIED;
    19091925}
     
    19491965                || !(uGstsReg & VTD_BF_GSTS_REG_CFIS_MASK))
    19501966            {
    1951                 dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Cfi_Blocked, kIrf_Cfi_Blocked, idDevice, 0 /* idxIntr */);
     1967                dmarIrFaultRecord(pDevIns, kDmarDiag_Ir_Cfi_Blocked, VTDINTRFAULT_CFI_BLOCKED, idDevice, 0 /* idxIntr */);
    19521968                return VERR_IOMMU_INTR_REMAP_DENIED;
    19531969            }
     
    21472163    { /* likely */ }
    21482164    else
    2149         DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_IqaReg_Dw_128_Invalid, kIqei_InvalidDescriptorWidth);
     2165        DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_IqaReg_Dw_128_Invalid, VTDIQEI_INVALID_DESCRIPTOR_WIDTH);
    21502166#endif
    21512167
     
    21692185                { /* likely */  }
    21702186                else
    2171                     DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_Invalid, kIqei_InvalidDescriptorType);
     2187                    DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_Invalid, VTDIQEI_INVALID_DESCRIPTOR_TYPE);
    21722188
    21732189                /* Validate reserved bits. */
     
    21792195                { /* likely */ }
    21802196                else
    2181                     DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_0_1_Rsvd, kIqei_RsvdFieldViolation);
     2197                    DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_0_1_Rsvd, VTDIQEI_RSVD_FIELD_VIOLATION);
    21822198
    21832199                if (fDw == VTD_IQA_REG_DW_256_BIT)
     
    21872203                    { /* likely */ }
    21882204                    else
    2189                         DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_2_3_Rsvd, kIqei_RsvdFieldViolation);
     2205                        DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Inv_Wait_Dsc_2_3_Rsvd, VTDIQEI_RSVD_FIELD_VIOLATION);
    21902206                }
    21912207
     
    22242240                /* Stop processing further requests. */
    22252241                LogFunc(("Invalid descriptor type: %#x\n", fDscType));
    2226                 DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Dsc_Type_Invalid, kIqei_InvalidDescriptorType);
     2242                DMAR_IQE_FAULT_RECORD_RET(kDmarDiag_Iqei_Dsc_Type_Invalid, VTDIQEI_INVALID_DESCRIPTOR_TYPE);
    22272243            }
    22282244        }
     
    23662382                    }
    23672383                    else
    2368                         dmarIqeFaultRecord(pDevIns, kDmarDiag_IqaReg_Dsc_Fetch_Error, kIqei_FetchDescriptorError);
     2384                        dmarIqeFaultRecord(pDevIns, kDmarDiag_IqaReg_Dsc_Fetch_Error, VTDIQEI_FETCH_DESCRIPTOR_ERR);
    23692385                }
    23702386                else
    23712387                {
    23722388                    if (fTtm == VTD_TTM_RSVD)
    2373                         dmarIqeFaultRecord(pDevIns, kDmarDiag_Iqei_Ttm_Rsvd, kIqei_InvalidTtm);
     2389                        dmarIqeFaultRecord(pDevIns, kDmarDiag_Iqei_Ttm_Rsvd, VTDIQEI_INVALID_TTM);
    23742390                    else
    23752391                    {
    23762392                        Assert(offQueueTail >= cbQueue);
    2377                         dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_Invalid, kIqei_InvalidTailPointer);
     2393                        dmarIqeFaultRecord(pDevIns, kDmarDiag_IqtReg_Qt_Invalid, VTDIQEI_INVALID_TAIL_PTR);
    23782394                    }
    23792395                }
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