VirtualBox

Changeset 88558 in vbox


Ignore:
Timestamp:
Apr 16, 2021 7:39:31 AM (3 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 WIP.

Location:
trunk
Files:
2 edited

Legend:

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

    r88521 r88558  
    10161016/** RW: Read/write mask. */
    10171017#define VTD_RTADDR_REG_RW_MASK                                  UINT64_C(0xfffffffffffffc00)
     1018
     1019/** RTADDR_REG.TTM: Legacy mode. */
     1020#define VTD_TTM_LEGACY_MODE                                     0
     1021/** RTADDR_REG.TTM: Scalable mode. */
     1022#define VTD_TTM_SCALABLE_MODE                                   1
     1023/** RTADDR_REG.TTM: Reserved. */
     1024#define VTD_TTM_RSVD                                            2
     1025/** RTADDR_REG.TTM: Abort DMA mode. */
     1026#define VTD_TTM_ABORT_DMA_MODE                                  3
    10181027/** @} */
    10191028
  • trunk/src/VBox/Devices/Bus/DevIommuIntel.cpp

    r88549 r88558  
    110110*********************************************************************************************************************************/
    111111/**
     112 * DMAR error diagnostics.
     113 *
     114 * @note Members of this enum are used as array indices, so no gaps are allowed.
     115 *       Please update g_apsz when you add new fields to this enum.
     116 */
     117typedef enum
     118{
     119    kDmarDiag_None = 0,
     120    kDmarDiag_IqtReg_Qt_NotAligned,
     121    /* Last member for determining array index limit. */
     122    kDmarDiag_End
     123} DMARDIAG;
     124AssertCompileSize(DMARDIAG, 4);
     125
     126/** DMAR diagnostic enum description expansion. */
     127#define DMARDIAG_DESC(a_Def, a_Desc)                #a_Def " - " #a_Desc
     128
     129/** DMAR diagnostics description. */
     130static const char *const g_apszDmarDiagDesc[] =
     131{
     132    DMARDIAG_DESC(kNone,                            "None"                ),
     133    DMARDIAG_DESC(kDmarDiag_IqtReg_Qt_NotAligned,   "IqtReg_Qt_NotAligned")
     134    /* kDmarDiag_End */
     135};
     136AssertCompile(RT_ELEMENTS(g_apszDmarDiagDesc) == kDmarDiag_End);
     137#undef DMARDIAG_DESC
     138
     139/**
    112140 * The shared DMAR device state.
    113141 */
     
    132160    uint8_t                     uVerReg;
    133161    /** Alignment. */
    134     uint8_t                     abPadding[7];
     162    uint8_t                     abPadding[3];
     163    /** Error diagnostic. */
     164    DMARDIAG                    enmDiag;
    135165    /** Copy of CAP_REG. */
    136166    uint64_t                    fCap;
     
    550580 * @param   uReg        The 64-bit value to write.
    551581 */
    552 DECLINLINE(void) dmarRegWriteRaw64(PDMAR pThis, uint16_t offReg, uint64_t uReg)
     582static void dmarRegWriteRaw64(PDMAR pThis, uint16_t offReg, uint64_t uReg)
    553583{
    554584    uint8_t idxGroup;
     
    566596 * @param   uReg        The 32-bit value to write.
    567597 */
    568 DECLINLINE(void) dmarRegWriteRaw32(PDMAR pThis, uint16_t offReg, uint32_t uReg)
     598static void dmarRegWriteRaw32(PDMAR pThis, uint16_t offReg, uint32_t uReg)
    569599{
    570600    uint8_t idxGroup;
     
    584614 * @param   pfRw1cMask  Where to store the RW1C mask corresponding to this register.
    585615 */
    586 DECLINLINE(void) dmarRegReadRaw64(PCDMAR pThis, uint16_t offReg, uint64_t *puReg, uint64_t *pfRwMask, uint64_t *pfRw1cMask)
     616static void dmarRegReadRaw64(PCDMAR pThis, uint16_t offReg, uint64_t *puReg, uint64_t *pfRwMask, uint64_t *pfRw1cMask)
    587617{
    588618    uint8_t idxGroup;
     
    606636 * @param   pfRw1cMask  Where to store the RW1C mask corresponding to this register.
    607637 */
    608 DECLINLINE(void) dmarRegReadRaw32(PCDMAR pThis, uint16_t offReg, uint32_t *puReg, uint32_t *pfRwMask, uint32_t *pfRw1cMask)
     638static void dmarRegReadRaw32(PCDMAR pThis, uint16_t offReg, uint32_t *puReg, uint32_t *pfRwMask, uint32_t *pfRw1cMask)
    609639{
    610640    uint8_t idxGroup;
     
    712742
    713743/**
     744 * Gets the table translation mode from the RTADDR_REG.
     745 *
     746 * @returns The table translation mode.
     747 * @param   pThis   The shared DMAR device state.
     748 */
     749static uint8_t dmarRtAddrRegGetTtm(PCDMAR pThis)
     750{
     751    uint64_t const uRtAddrReg = dmarRegRead64(pThis, VTD_MMIO_OFF_RTADDR_REG);
     752    return RT_BF_GET(uRtAddrReg, VTD_BF_RTADDR_REG_TTM);
     753}
     754
     755
     756/**
     757 * Handles writes to CCMD_REG.
     758 *
     759 * @returns Strict VBox status code.
     760 * @param   pDevIns     The IOMMU device instance.
     761 * @param   off         The MMIO register offset.
     762 * @param   cb          The size of the MMIO access (in bytes).
     763 * @param   uCcmdReg    The value written to CCMD_REG.
     764 */
     765static VBOXSTRICTRC dmarCcmdRegWrite(PPDMDEVINS pDevIns, uint16_t off, uint8_t cb, uint64_t uCcmdReg)
     766{
     767    /* We only care about responding to high 32-bits writes, low 32-bits are data. */
     768    if (off + cb > VTD_MMIO_OFF_CCMD_REG + 4)
     769    {
     770        /* Check if we need to invalidate the context-context. */
     771        bool const fIcc = RT_BF_GET(uCcmdReg, VTD_BF_CCMD_REG_ICC);
     772        if (fIcc)
     773        {
     774            PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     775            uint8_t const uMajorVersion = RT_BF_GET(pThis->uVerReg, VTD_BF_VER_REG_MAX);
     776            if (uMajorVersion < 6)
     777            {
     778                /** @todo Verify queued-invalidation is not enabled.
     779                 *  See Intel spec. 6.5.1 "Register-based Invalidation Interface" */
     780
     781                /* Verify table translation mode is legacy. */
     782                uint8_t const fTtm = dmarRtAddrRegGetTtm(pThis);
     783                if (fTtm == VTD_TTM_LEGACY_MODE)
     784                {
     785                    /** @todo Invalidate. */
     786                    return VINF_SUCCESS;
     787                }
     788            }
     789
     790            /** @todo Raise error. */
     791        }
     792    }
     793    return VINF_SUCCESS;
     794}
     795
     796
     797/**
    714798 * Handles writes to IQT_REG.
    715799 *
     
    721805static VBOXSTRICTRC dmarIqtRegWrite(PPDMDEVINS pDevIns, uint16_t off, uint64_t uIqtReg)
    722806{
    723     /* We only care about the low 32-bits. */
     807    /* We only care about the low 32-bits, high 32-bits are reserved. */
    724808    if (off == VTD_MMIO_OFF_IQT_REG)
    725809    {
     
    732816            || !(offQueueTail & 0x1f))
    733817        {
    734             /** @todo IOMMU: Figure out what to do here, like waking up worker thread or
     818            /** @todo Figure out what to do here, like waking up worker thread or
    735819             *        something. */
    736820        }
     
    738822        {
    739823            /* Raise invalidation queue error as queue tail not aligned to 256-bits. */
    740             /** @todo IOMMU: Raise error. */
     824            /** @todo Raise error. */
    741825        }
    742826    }
     
    832916            {
    833917                rcStrict = dmarIqtRegWrite(pDevIns, offReg, uRegWritten);
     918                break;
     919            }
     920
     921            case VTD_MMIO_OFF_CCMD_REG:
     922            case VTD_MMIO_OFF_CCMD_REG + 4:
     923            {
     924                rcStrict = dmarCcmdRegWrite(pDevIns, offReg, cb, uRegWritten);
    834925                break;
    835926            }
     
    10941185    PDMPciDevSetSubSystemVendorId(pPciDev, DMAR_PCI_VENDOR_ID);         /* Intel */
    10951186
    1096     /** @todo VTD: Chipset spec says PCI Express Capability Id. Relevant for us? */
     1187    /** @todo Chipset spec says PCI Express Capability Id. Relevant for us? */
    10971188    PDMPciDevSetStatus(pPciDev,            0);
    10981189    PDMPciDevSetCapabilityList(pPciDev,    0);
    10991190
    1100     /** @todo VTD: VTBAR at 0x180? */
     1191    /** @todo VTBAR at 0x180? */
    11011192
    11021193    /*
     
    11061197    AssertLogRelRCReturn(rc, rc);
    11071198
    1108     /** @todo VTD: Register MSI but what's the MSI capability offset? */
     1199    /** @todo Register MSI but what's the MSI capability offset? */
    11091200#if 0
    11101201    /*
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