VirtualBox

Changeset 88694 in vbox


Ignore:
Timestamp:
Apr 24, 2021 6:07:05 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144011
Message:

Intel IOMMU: bugref:9967 Queued-invalidation WIP.

Location:
trunk
Files:
2 edited

Legend:

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

    r88627 r88694  
    13581358
    13591359/** IQH_REG.QH: Gets the queue head. */
    1360 #define VTD_IQT_REG_GET_QH(a)                                   ((a) & (VTD_BF_IQH_REG_QH_MASK | VTD_BF_IQH_REG_RSVD_3_0_MASK))
     1360#define VTD_IQH_REG_GET_QH(a)                                   ((a) & (VTD_BF_IQH_REG_QH_MASK | VTD_BF_IQH_REG_RSVD_3_0_MASK))
    13611361/** @} */
    13621362
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r88682 r88694  
    5050    } while (0)
    5151
    52 /** Checks whether the MMIO offset is valid. */
     52/** Checks if the MMIO offset is valid. */
    5353#define DMAR_IS_MMIO_OFF_VALID(a_off)               (   (a_off) < DMAR_MMIO_GROUP_0_OFF_END \
    5454                                                     || (a_off) - DMAR_MMIO_GROUP_1_OFF_FIRST < DMAR_MMIO_GROUP_1_SIZE)
     
    855855
    856856/**
    857  * Checks whether the invalidation-queue is empty.
     857 * Checks if the invalidation-queue is empty.
    858858 *
    859859 * @returns @c true if empty, @c false otherwise.
     
    862862static bool dmarInvQueueIsEmpty(PCDMAR pThis)
    863863{
    864     uint64_t const uIqtReg      = dmarRegRead64(pThis, VTD_MMIO_OFF_IQT_REG);
    865     uint32_t const offQueueTail = VTD_IQT_REG_GET_QT(uIqtReg);
    866 
    867     uint64_t const uIqhReg      = dmarRegRead64(pThis, VTD_MMIO_OFF_IQH_REG);
    868     uint32_t const offQueueHead = VTD_IQT_REG_GET_QH(uIqhReg);
    869 
    870     return offQueueTail == offQueueHead;
    871 }
    872 
    873 
    874 /**
    875  * Checks whether the invalidation-queue is capable of processing requests.
     864    uint64_t const uIqtReg = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_IQT_REG);
     865    uint64_t const uIqhReg = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_IQH_REG);
     866
     867    uint32_t const offQt = VTD_IQT_REG_GET_QT(uIqtReg);
     868    uint32_t const offQh = VTD_IQH_REG_GET_QH(uIqhReg);
     869    return offQt == offQh;
     870}
     871
     872
     873/**
     874 * Checks if the invalidation-queue is capable of processing requests.
    876875 *
    877876 * @returns @c true if the invalidation-queue can process requests, @c false
     
    882881{
    883882    /* Check if queued-invalidation is enabled. */
    884     uint32_t const uGstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG);
     883    uint32_t const uGstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_GSTS_REG);
    885884    if (uGstsReg & VTD_BF_GSTS_REG_QIES_MASK)
    886885    {
    887886        /* Check if there are no invalidation-queue or timeout errors. */
    888         uint32_t const uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG);
     887        uint32_t const uFstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FSTS_REG);
    889888        if (!(uFstsReg & (VTD_BF_FSTS_REG_IQE_MASK | VTD_BF_FSTS_REG_ITE_MASK)))
    890889            return true;
     
    928927#ifdef RT_STRICT
    929928    {
    930         uint32_t const uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG);
     929        uint32_t const uFstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FSTS_REG);
    931930        uint32_t const fFaultMask = VTD_BF_FSTS_REG_PPF_MASK | VTD_BF_FSTS_REG_PFO_MASK
    932931                               /* | VTD_BF_FSTS_REG_APF_MASK | VTD_BF_FSTS_REG_AFO_MASK */    /* AFL not supported */
     
    937936#endif
    938937
    939     uint32_t uFectlReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FECTL_REG);
     938    uint32_t uFectlReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FECTL_REG);
    940939    if (!(uFectlReg & VTD_BF_FECTL_REG_IM_MASK))
    941940    {
    942941        /* Software has unmasked the interrupt, raise it. */
    943942        MSIMSG Msi;
    944         Msi.Addr.u64 = RT_MAKE_U64(dmarRegRead32(pThis, VTD_MMIO_OFF_FEADDR_REG),
    945                                    dmarRegRead32(pThis, VTD_MMIO_OFF_FEUADDR_REG));
    946         Msi.Data.u32 = dmarRegRead32(pThis, VTD_MMIO_OFF_FEDATA_REG);
     943        Msi.Addr.u64 = RT_MAKE_U64(dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FEADDR_REG),
     944                                   dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FEUADDR_REG));
     945        Msi.Data.u32 = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FEDATA_REG);
    947946
    948947        /** @todo Assert Msi.Addr is in the MSR_IA32_APICBASE_ADDR range and ensure on
     
    953952        /* Clear interrupt pending bit. */
    954953        uFectlReg &= ~VTD_BF_FECTL_REG_IP_MASK;
    955         dmarRegWrite32(pThis, VTD_MMIO_OFF_FECTL_REG, uFectlReg);
     954        dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_FECTL_REG, uFectlReg);
    956955    }
    957956    else
     
    959958        /* Interrupt is masked, set the interrupt pending bit. */
    960959        uFectlReg |= VTD_BF_FECTL_REG_IP_MASK;
    961         dmarRegWrite32(pThis, VTD_MMIO_OFF_FECTL_REG, uFectlReg);
     960        dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_FECTL_REG, uFectlReg);
    962961    }
    963962}
     
    966965#if 0
    967966/**
    968  * Checks whether a primary fault can be recorded.
     967 * Checks if a primary fault can be recorded.
    969968 *
    970969 * @returns @c true if the fault can be recorded, @c false otherwise.
     
    973972static bool dmarPrimaryFaultCanRecord(PDMAR pThis)
    974973{
    975     uint32_t uFstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_FSTS_REG);
     974    uint32_t uFstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_FSTS_REG);
    976975    if (uFstsReg & VTD_BF_FSTS_REG_PFO_MASK)
    977976        return false;
     
    985984     */
    986985    AssertCompile(DMAR_FRCD_REG_COUNT == 1);
    987     uint64_t const uFrcdRegHi = dmarRegRead64(pThis, DMAR_MMIO_OFF_FRCD_HI_REG);
     986    uint64_t const uFrcdRegHi = dmarRegReadRaw64(pThis, DMAR_MMIO_OFF_FRCD_HI_REG);
    988987    if (uFrcdRegHi & VTD_BF_1_FRCD_REG_F_MASK)
    989988    {
     
    10131012    DMAR_ASSERT_LOCK_IS_OWNER(pDevIns, pThisCC);
    10141013
    1015     /* Always update the latest diagnostic reason. */
     1014    /* Update the diagnostic reason. */
    10161015    pThis->enmDiag = enmDiag;
    10171016
     
    10381037{
    10391038    PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
    1040     uint32_t const uGstsReg = dmarRegRead32(pThis, VTD_MMIO_OFF_GSTS_REG);
     1039    uint32_t const uGstsReg = dmarRegReadRaw32(pThis, VTD_MMIO_OFF_GSTS_REG);
    10411040    uint32_t const fChanged = uGstsReg ^ uGcmdReg;
    1042     if (pThis->fExtCap & VTD_BF_ECAP_REG_QI_MASK)
    1043     {
    1044         if (fChanged & VTD_BF_GCMD_REG_QIE_MASK)
     1041
     1042    Assert(pThis->fExtCap & VTD_BF_ECAP_REG_QI_MASK);
     1043    if (fChanged & VTD_BF_GCMD_REG_QIE_MASK)
     1044    {
     1045        if (uGcmdReg & VTD_BF_GCMD_REG_QIE_MASK)
    10451046        {
    1046             if (uGcmdReg & VTD_BF_GCMD_REG_QIE_MASK)
    1047             {
    1048                 /* Enable the invalidation-queue. */
    1049                 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */,
    1050                                    VTD_BF_GSTS_REG_QIES_MASK /* fOrMask */);
    1051                 dmarInvQueueThreadWakeUpIfNeeded(pDevIns);
    1052             }
    1053             else
    1054             {
    1055                 /* Disable the invalidation-queue and reset the queue head offset. */
    1056                 dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_QIES_MASK /* fAndMask */, 0 /* fOrMask */);
    1057                 dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_IQH_REG, 0);
    1058             }
     1047            /* Enable the invalidation-queue. */
     1048            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, UINT32_MAX /* fAndMask */, VTD_BF_GSTS_REG_QIES_MASK /* fOrMask */);
     1049            dmarInvQueueThreadWakeUpIfNeeded(pDevIns);
    10591050        }
    1060     }
    1061 
    1062     /** @todo Rest of the bits? */
     1051        else
     1052        {
     1053            /* Disable the invalidation-queue. */
     1054            dmarRegChangeRaw32(pThis, VTD_MMIO_OFF_GSTS_REG, ~VTD_BF_GSTS_REG_QIES_MASK /* fAndMask */, 0 /* fOrMask */);
     1055            dmarRegWriteRaw32(pThis, VTD_MMIO_OFF_IQH_REG, 0);
     1056        }
     1057    }
     1058
     1059    /** @todo Rest of the bits. */
    10631060
    10641061    return VINF_SUCCESS;
     
    11221119
    11231120    uint32_t const offQt   = VTD_IQT_REG_GET_QT(uIqtReg);
    1124     uint64_t const uIqaReg = dmarRegRead64(pThis, VTD_MMIO_OFF_IQA_REG);
     1121    uint64_t const uIqaReg = dmarRegReadRaw64(pThis, VTD_MMIO_OFF_IQA_REG);
    11251122    uint8_t const  fDw     = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_DW);
    11261123
     
    14871484                    | RT_BF_MAKE(VTD_BF_CAP_REG_PI,      0)     /* Posted Interrupts not supported. */
    14881485                    | RT_BF_MAKE(VTD_BF_CAP_REG_FL5LP,   fFlts & fFl5lp)
    1489                     | RT_BF_MAKE(VTD_BF_CAP_REG_ESIRTPS, 0)     /* Whether we invalidate interrupt cache on SIRTP flow. */
    1490                     | RT_BF_MAKE(VTD_BF_CAP_REG_ESRTPS,  0);    /* Whether we invalidate translation cache on SRTP flow. */
     1486                    | RT_BF_MAKE(VTD_BF_CAP_REG_ESIRTPS, 0)     /* If we invalidate interrupt cache on SIRTP flow. */
     1487                    | RT_BF_MAKE(VTD_BF_CAP_REG_ESRTPS,  0);    /* If we invalidate translation cache on SRTP flow. */
    14911488        dmarRegWriteRaw64(pThis, VTD_MMIO_OFF_CAP_REG, pThis->fCap);
    14921489    }
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