VirtualBox

Ignore:
Timestamp:
Sep 14, 2020 9:15:29 AM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Bits.

File:
1 edited

Legend:

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

    r86090 r86119  
    24682468                            IOMMUOP enmOp, PIRTE_T pIrte)
    24692469{
     2470    /* Ensure the IRTE length is valid. */
     2471    Assert(pDte->n.u4IntrTableLength < IOMMU_DTE_INTR_TAB_LEN_MAX);
     2472
    24702473    RTGCPHYS const GCPhysIntrTable = pDte->au64[2] & IOMMU_DTE_IRTE_ROOT_PTR_MASK;
     2474    uint16_t const cbIntrTable     = IOMMU_GET_INTR_TAB_LEN(pDte);
    24712475    uint16_t const offIrte         = (uDataIn & IOMMU_MSI_DATA_IRTE_OFFSET_MASK) << IOMMU_IRTE_SIZE_SHIFT;
    24722476    RTGCPHYS const GCPhysIrte      = GCPhysIntrTable + offIrte;
    24732477
    2474     /* Ensure the IRTE offset is within the specified table size. */
    2475     Assert(pDte->n.u4IntrTableLength < 12);
    2476     if (offIrte + sizeof(IRTE_T) <= (1U << pDte->n.u4IntrTableLength) << IOMMU_IRTE_SIZE_SHIFT)
     2478    /* Ensure the IRTE falls completely within the interrupt table. */
     2479    if (offIrte + sizeof(IRTE_T) <= cbIntrTable)
    24772480    { /* likely */ }
    24782481    else
    24792482    {
     2483        LogFunc(("IRTE exceeds table length (GCPhysIntrTable=%#RGp cbIntrTable=%u offIrte=%#x uDataIn=%#x) -> IOPF\n",
     2484                 GCPhysIntrTable, cbIntrTable, offIrte, uDataIn));
     2485
    24802486        EVT_IO_PAGE_FAULT_T EvtIoPageFault;
    24812487        iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, GCPhysIn, false /* fPresent */, false /* fRsvdNotZero */,
     
    26572663                        {
    26582664                            /* Validate the encoded interrupt table length when IntCtl specifies remapping. */
    2659                             uint32_t const uIntTabLen = Dte.n.u4IntrTableLength;
    2660                             if (Dte.n.u4IntrTableLength < 12)
     2665                            uint8_t const uIntrTabLen = Dte.n.u4IntrTableLength;
     2666                            if (uIntrTabLen < IOMMU_DTE_INTR_TAB_LEN_MAX)
    26612667                            {
    26622668                                /*
     
    26742680                            }
    26752681
    2676                             LogFunc(("Invalid interrupt table length %#x -> Illegal DTE\n", uIntTabLen));
     2682                            LogFunc(("Invalid interrupt table length %#x -> Illegal DTE\n", uIntrTabLen));
    26772683                            EVT_ILLEGAL_DTE_T Event;
    26782684                            iommuAmdInitIllegalDteEvent(uDevId, pMsiIn->Addr.u64, false /* fRsvdNotZero */, enmOp, &Event);
     
    31983204        {
    31993205            pHlp->pfnPrintf(pHlp, "    Size                                    = %#x (%u bytes)\n", DevTabBar.n.u9Size,
    3200                             IOMMU_GET_DEV_TAB_LEN(DevTabBar));
     3206                            IOMMU_GET_DEV_TAB_LEN(&DevTabBar));
    32013207            pHlp->pfnPrintf(pHlp, "    Base address                            = %#RX64\n", DevTabBar.n.u40Base << X86_PAGE_4K_SHIFT);
    32023208        }
     
    37753781
    37763782    pHlp->pfnPrintf(pHlp, "%sInterrupt Map Valid        = %RTbool\n", pszPrefix, pDte->n.u1IntrMapValid);
    3777     if (pDte->n.u4IntrTableLength < 12)
    3778     {
    3779         uint32_t const cEntries = 1U << pDte->n.u4IntrTableLength;
    3780         pHlp->pfnPrintf(pHlp, "%sInterrupt Table Length     = %#x (%u entries, %u bytes)\n", pszPrefix,
    3781                         pDte->n.u4IntrTableLength, cEntries, cEntries << IOMMU_IRTE_SIZE_SHIFT);
     3783    uint8_t const uIntrTabLen = pDte->n.u4IntrTableLength;
     3784    if (uIntrTabLen < IOMMU_DTE_INTR_TAB_LEN_MAX)
     3785    {
     3786        uint16_t const cEntries    = IOMMU_GET_INTR_TAB_ENTRIES(pDte);
     3787        uint16_t const cbIntrTable = IOMMU_GET_INTR_TAB_LEN(pDte);
     3788        pHlp->pfnPrintf(pHlp, "%sInterrupt Table Length     = %#x (%u entries, %u bytes)\n", pszPrefix, uIntrTabLen, cEntries,
     3789                        cbIntrTable);
    37823790    }
    37833791    else
    3784         pHlp->pfnPrintf(pHlp, "%sInterrupt Table Length     = %#x (invalid)\n", pszPrefix, pDte->n.u4IntrTableLength);
     3792        pHlp->pfnPrintf(pHlp, "%sInterrupt Table Length     = %#x (invalid!)\n", pszPrefix, uIntrTabLen);
    37853793    pHlp->pfnPrintf(pHlp, "%sIgnore Unmapped Interrupts = %RTbool\n", pszPrefix, pDte->n.u1IgnoreUnmappedIntrs);
    37863794    pHlp->pfnPrintf(pHlp, "%sInterrupt Table Root Ptr   = %#RX64 (addr=%#RGp)\n", pszPrefix,
     
    38633871        if (GCPhysDevTab)
    38643872        {
    3865             uint32_t const cbDevTab = IOMMU_GET_DEV_TAB_LEN(DevTabBar);
     3873            uint32_t const cbDevTab = IOMMU_GET_DEV_TAB_LEN(&DevTabBar);
    38663874            uint32_t const cDtes    = cbDevTab / sizeof(DTE_T);
    38673875            pHlp->pfnPrintf(pHlp, " Table %u (base=%#RGp size=%u bytes entries=%u):\n", i, GCPhysDevTab, cbDevTab, cDtes);
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