VirtualBox

Changeset 86088 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Sep 11, 2020 9:33:38 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
140320
Message:

AMD IOMMU: bugref:9654 Add debugger info helper for dumping DTE given a device ID.

File:
1 edited

Legend:

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

    r86087 r86088  
    19911991    RTGCPHYS const GCPhysDte    = GCPhysDevTab + offDte;
    19921992
    1993     LogFlowFunc(("idxSegsEn=%#x GCPhysDevTab=%#RGp offDte=%#x GCPhysDte=%#RGp\n", idxSegsEn, GCPhysDevTab, offDte, GCPhysDte));
    1994 
    19951993    Assert(!(GCPhysDevTab & X86_PAGE_4K_OFFSET_MASK));
    19961994    int rc = PDMDevHlpPCIPhysRead(pDevIns, GCPhysDte, pDte, sizeof(*pDte));
     
    20042002        return VERR_IOMMU_IPE_1;
    20052003    }
    2006 
    20072004
    20082005    return rc;
     
    20432040         *        the DTE) return the state computed so far and raises an I/O page fault. So
    20442041         *        returning an invalid translation rather than skipping translation. */
    2045         LogFunc(("Translation valid bit not set -> IOPF"));
     2042        LogFunc(("Translation valid bit not set -> IOPF\n"));
    20462043        EVT_IO_PAGE_FAULT_T EvtIoPageFault;
    20472044        iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, uIova, false /* fPresent */, false /* fRsvdNotZero */,
     
    21512148        else
    21522149        {
    2153             LogFunc(("Page table entry not present -> IOPF"));
     2150            LogFunc(("Page table entry not present -> IOPF\n"));
    21542151            EVT_IO_PAGE_FAULT_T EvtIoPageFault;
    21552152            iommuAmdInitIoPageFaultEvent(uDevId, pDte->n.u16DomainId, uIova, false /* fPresent */, false /* fRsvdNotZero */,
     
    32013198        {
    32023199            pHlp->pfnPrintf(pHlp, "    Size                                    = %#x (%u bytes)\n", DevTabBar.n.u9Size,
    3203                             IOMMU_GET_DEV_TAB_SIZE(DevTabBar.n.u9Size));
     3200                            IOMMU_GET_DEV_TAB_LEN(DevTabBar));
    32043201            pHlp->pfnPrintf(pHlp, "    Base address                            = %#RX64\n", DevTabBar.n.u40Base << X86_PAGE_4K_SHIFT);
    32053202        }
     
    37343731
    37353732
    3736 static void iommuAmdR3DbgInfoDte(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, PCDTE_T pDte, const char *pszPrefix)
    3737 {
    3738     RT_NOREF(pDevIns);
    3739     pHlp->pfnPrintf(pHlp, " %sValid               = %RTbool\n", pszPrefix, pDte->n.u1Valid);
    3740     pHlp->pfnPrintf(pHlp, " %sInterrupt Map Valid = %RTbool\n", pszPrefix, pDte->n.u1IntrMapValid);
    3741 }
    3742 
    3743 
     3733/**
     3734 * Dumps the DTE via the info callback helper.
     3735 *
     3736 * @param   pHlp        The info helper.
     3737 * @param   pDte        The device table entry.
     3738 * @param   pszPrefix   The string prefix.
     3739 */
     3740static void iommuAmdR3DbgInfoDteWorker(PCDBGFINFOHLP pHlp, PCDTE_T pDte, const char *pszPrefix)
     3741{
     3742    AssertReturnVoid(pHlp);
     3743    AssertReturnVoid(pDte);
     3744    AssertReturnVoid(pszPrefix);
     3745
     3746    pHlp->pfnPrintf(pHlp, "%sValid                      = %RTbool\n", pszPrefix, pDte->n.u1Valid);
     3747    pHlp->pfnPrintf(pHlp, "%sTranslation Valid          = %RTbool\n", pszPrefix, pDte->n.u1TranslationValid);
     3748    pHlp->pfnPrintf(pHlp, "%sHost Access Dirty          = %#x\n",     pszPrefix, pDte->n.u2Had);
     3749    pHlp->pfnPrintf(pHlp, "%sPaging Mode                = %u\n",      pszPrefix, pDte->n.u3Mode);
     3750    pHlp->pfnPrintf(pHlp, "%sPage Table Root Ptr        = %#RX64 (addr=%#RGp)\n", pszPrefix, pDte->n.u40PageTableRootPtrLo,
     3751                    pDte->n.u40PageTableRootPtrLo << 12);
     3752    pHlp->pfnPrintf(pHlp, "%sPPR enable                 = %RTbool\n", pszPrefix, pDte->n.u1Ppr);
     3753    pHlp->pfnPrintf(pHlp, "%sGuest PPR Resp w/ PASID    = %RTbool\n", pszPrefix, pDte->n.u1GstPprRespPasid);
     3754    pHlp->pfnPrintf(pHlp, "%sGuest I/O Prot Valid       = %RTbool\n", pszPrefix, pDte->n.u1GstIoValid);
     3755    pHlp->pfnPrintf(pHlp, "%sGuest Translation Valid    = %RTbool\n", pszPrefix, pDte->n.u1GstTranslateValid);
     3756    pHlp->pfnPrintf(pHlp, "%sGuest Levels Translated    = %#x\n",     pszPrefix, pDte->n.u2GstMode);
     3757    pHlp->pfnPrintf(pHlp, "%sGuest Root Page Table Ptr  = %#x %#x %#x (addr=%#RGp)\n", pszPrefix,
     3758                    pDte->n.u3GstCr3TableRootPtrLo, pDte->n.u16GstCr3TableRootPtrMid, pDte->n.u21GstCr3TableRootPtrHi,
     3759                      (pDte->n.u21GstCr3TableRootPtrHi  << 31)
     3760                    | (pDte->n.u16GstCr3TableRootPtrMid << 15)
     3761                    | (pDte->n.u3GstCr3TableRootPtrLo   << 12));
     3762    pHlp->pfnPrintf(pHlp, "%sI/O Read                   = %s\n",      pszPrefix, pDte->n.u1IoRead ? "allowed" : "denied");
     3763    pHlp->pfnPrintf(pHlp, "%sI/O Write                  = %s\n",      pszPrefix, pDte->n.u1IoWrite ? "allowed" : "denied");
     3764    pHlp->pfnPrintf(pHlp, "%sReserved (MBZ)             = %#x\n",     pszPrefix, pDte->n.u1Rsvd0);
     3765    pHlp->pfnPrintf(pHlp, "%sDomain ID                  = %u (%#x)\n", pszPrefix, pDte->n.u16DomainId, pDte->n.u16DomainId);
     3766    pHlp->pfnPrintf(pHlp, "%sIOTLB Enable               = %RTbool\n", pszPrefix, pDte->n.u1IoTlbEnable);
     3767    pHlp->pfnPrintf(pHlp, "%sSuppress I/O PFs           = %RTbool\n", pszPrefix, pDte->n.u1SuppressPfEvents);
     3768    pHlp->pfnPrintf(pHlp, "%sSuppress all I/O PFs       = %RTbool\n", pszPrefix, pDte->n.u1SuppressAllPfEvents);
     3769    pHlp->pfnPrintf(pHlp, "%sPort I/O Control           = %#x\n",     pszPrefix, pDte->n.u2IoCtl);
     3770    pHlp->pfnPrintf(pHlp, "%sIOTLB Cache Hint           = %s\n",      pszPrefix, pDte->n.u1Cache ? "no caching" : "cache");
     3771    pHlp->pfnPrintf(pHlp, "%sSnoop Disable              = %RTbool\n", pszPrefix, pDte->n.u1SnoopDisable);
     3772    pHlp->pfnPrintf(pHlp, "%sAllow Exclusion            = %RTbool\n", pszPrefix, pDte->n.u1AllowExclusion);
     3773    pHlp->pfnPrintf(pHlp, "%sSysMgt Message Enable      = %RTbool\n", pszPrefix, pDte->n.u2SysMgt);
     3774    pHlp->pfnPrintf(pHlp, "\n");
     3775
     3776    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);
     3782    }
     3783    else
     3784        pHlp->pfnPrintf(pHlp, "%sInterrupt Table Length     = %#x (invalid)\n", pszPrefix, pDte->n.u4IntrTableLength);
     3785    pHlp->pfnPrintf(pHlp, "%sIgnore Unmapped Interrupts = %RTbool\n", pszPrefix, pDte->n.u1IgnoreUnmappedIntrs);
     3786    pHlp->pfnPrintf(pHlp, "%sInterrupt Table Root Ptr   = %#RX64 (addr=%#RGp)\n", pszPrefix,
     3787                    pDte->n.u46IntrTableRootPtr, pDte->au64[2] & IOMMU_DTE_IRTE_ROOT_PTR_MASK);
     3788    pHlp->pfnPrintf(pHlp, "%sReserved (MBZ)             = %#x\n",     pszPrefix, pDte->n.u4Rsvd0);
     3789    pHlp->pfnPrintf(pHlp, "%sINIT passthru              = %RTbool\n", pszPrefix, pDte->n.u1InitPassthru);
     3790    pHlp->pfnPrintf(pHlp, "%sExtInt passthru            = %RTbool\n", pszPrefix, pDte->n.u1ExtIntPassthru);
     3791    pHlp->pfnPrintf(pHlp, "%sNMI passthru               = %RTbool\n", pszPrefix, pDte->n.u1NmiPassthru);
     3792    pHlp->pfnPrintf(pHlp, "%sReserved (MBZ)             = %#x\n",     pszPrefix, pDte->n.u1Rsvd2);
     3793    pHlp->pfnPrintf(pHlp, "%sInterrupt Control          = %#x\n",     pszPrefix, pDte->n.u2IntrCtrl);
     3794    pHlp->pfnPrintf(pHlp, "%sLINT0 passthru             = %RTbool\n", pszPrefix, pDte->n.u1Lint0Passthru);
     3795    pHlp->pfnPrintf(pHlp, "%sLINT1 passthru             = %RTbool\n", pszPrefix, pDte->n.u1Lint1Passthru);
     3796    pHlp->pfnPrintf(pHlp, "%sReserved (MBZ)             = %#x\n",     pszPrefix, pDte->n.u32Rsvd0);
     3797    pHlp->pfnPrintf(pHlp, "%sReserved (MBZ)             = %#x\n",     pszPrefix, pDte->n.u22Rsvd0);
     3798    pHlp->pfnPrintf(pHlp, "%sAttribute Override Valid   = %RTbool\n", pszPrefix, pDte->n.u1AttrOverride);
     3799    pHlp->pfnPrintf(pHlp, "%sMode0FC                    = %#x\n",     pszPrefix, pDte->n.u1Mode0FC);
     3800    pHlp->pfnPrintf(pHlp, "%sSnoop Attribute            = %#x\n",     pszPrefix, pDte->n.u8SnoopAttr);
     3801}
     3802
     3803
     3804/**
     3805 * @callback_method_impl{FNDBGFHANDLERDEV}
     3806 */
     3807static DECLCALLBACK(void) iommuAmdR3DbgInfoDte(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     3808{
     3809    if (pszArgs)
     3810    {
     3811        uint16_t uDevId = 0;
     3812        int rc = RTStrToUInt16Full(pszArgs, 0 /* uBase */, &uDevId);
     3813        if (RT_SUCCESS(rc))
     3814        {
     3815            DTE_T Dte;
     3816            rc = iommuAmdReadDte(pDevIns, uDevId, IOMMUOP_TRANSLATE_REQ,  &Dte);
     3817            if (RT_SUCCESS(rc))
     3818            {
     3819                iommuAmdR3DbgInfoDteWorker(pHlp, &Dte, " ");
     3820                return;
     3821            }
     3822
     3823            pHlp->pfnPrintf(pHlp, "Failed to read DTE for device ID %u (%#x). rc=%Rrc\n", uDevId, uDevId, rc);
     3824        }
     3825        else
     3826            pHlp->pfnPrintf(pHlp, "Failed to parse a valid 16-bit device ID. rc=%Rrc\n", rc);
     3827    }
     3828    else
     3829        pHlp->pfnPrintf(pHlp, "Missing device ID.\n");
     3830}
     3831
     3832
     3833#if 0
    37443834/**
    37453835 * @callback_method_impl{FNDBGFHANDLERDEV}
     
    37733863        if (GCPhysDevTab)
    37743864        {
    3775             uint32_t const cbDevTab = IOMMU_GET_DEV_TAB_SIZE(DevTabBar.n.u9Size);
     3865            uint32_t const cbDevTab = IOMMU_GET_DEV_TAB_LEN(DevTabBar);
    37763866            uint32_t const cDtes    = cbDevTab / sizeof(DTE_T);
    37773867            pHlp->pfnPrintf(pHlp, " Table %u (base=%#RGp size=%u bytes entries=%u):\n", i, GCPhysDevTab, cbDevTab, cDtes);
     
    37903880                        {
    37913881                            pHlp->pfnPrintf(pHlp, " DTE %u:\n", idxDte);
    3792                             iommuAmdR3DbgInfoDte(pDevIns, pHlp, pDte, " ");
     3882                            iommuAmdR3DbgInfoDteWorker(pHlp, pDte, " ");
    37933883                        }
    37943884                    }
     
    38103900        }
    38113901    }
    3812 
    3813 }
    3814 
     3902}
     3903#endif
    38153904
    38163905/**
     
    41144203     * Register debugger info items.
    41154204     */
    4116     PDMDevHlpDBGFInfoRegister(pDevIns, "iommu",        "Display IOMMU state.", iommuAmdR3DbgInfo);
     4205    PDMDevHlpDBGFInfoRegister(pDevIns, "iommu",    "Display IOMMU state.", iommuAmdR3DbgInfo);
     4206    PDMDevHlpDBGFInfoRegister(pDevIns, "iommudte", "Display the DTE for a device. Arguments: DeviceID.", iommuAmdR3DbgInfoDte);
     4207#if 0
    41174208    PDMDevHlpDBGFInfoRegister(pDevIns, "iommudevtabs", "Display IOMMU device tables.", iommuAmdR3DbgInfoDevTabs);
     4209#endif
    41184210
    41194211# ifdef VBOX_WITH_STATISTICS
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