VirtualBox

Changeset 88494 in vbox for trunk/src


Ignore:
Timestamp:
Apr 13, 2021 3:53:13 PM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 WIP.

File:
1 edited

Legend:

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

    r88481 r88494  
    585585 * This will preserve read-only bits, mask off reserved bits and clear RW1C bits.
    586586 *
     587 * @returns The value that's actually written to the register.
    587588 * @param   pThis   The shared DMAR device state.
    588589 * @param   offReg  The MMIO offset of the register.
    589590 * @param   uReg    The 64-bit value to write.
    590591 */
    591 static void dmarRegWrite64(PDMAR pThis, uint16_t offReg, uint64_t uReg)
     592static uint64_t dmarRegWrite64(PDMAR pThis, uint16_t offReg, uint64_t uReg)
    592593{
    593594    /* Read current value from the 64-bit register. */
     
    604605    /* Write new value to the 64-bit register. */
    605606    dmarRegWriteRaw64(pThis, offReg, uNewReg);
     607    return uNewReg;
    606608}
    607609
     
    611613 * This will preserve read-only bits, mask off reserved bits and clear RW1C bits.
    612614 *
     615 * @returns The value that's actually written to the register.
    613616 * @param   pThis   The shared DMAR device state.
    614617 * @param   offReg  The MMIO offset of the register.
    615618 * @param   uReg    The 32-bit value to write.
    616619 */
    617 static void dmarRegWrite32(PDMAR pThis, uint16_t offReg, uint32_t uReg)
     620static uint32_t dmarRegWrite32(PDMAR pThis, uint16_t offReg, uint32_t uReg)
    618621{
    619622    /* Read current value from the 32-bit register. */
     
    630633    /* Write new value to the 32-bit register. */
    631634    dmarRegWriteRaw32(pThis, offReg, uNewReg);
     635    return uNewReg;
    632636}
    633637
     
    666670    NOREF(fRwMask); NOREF(fRw1cMask);
    667671    return uCurReg;
     672}
     673
     674
     675/**
     676 * Handles writes to IQT_REG.
     677 *
     678 * @returns Strict VBox status code.
     679 * @param   pDevIns     The IOMMU device instance.
     680 * @param   off         The MMIO register offset.
     681 * @param   uIqtReg     The value written to IQT_REG.
     682 */
     683static VBOXSTRICTRC dmarIqtRegWrite(PPDMDEVINS pDevIns, uint16_t off, uint64_t uIqtReg)
     684{
     685    /* We only care about the low dword of VTD_MMIO_OFF_IQT_REG. */
     686    PDMAR pThis = PDMDEVINS_2_DATA(pDevIns, PDMAR);
     687    if (off == VTD_MMIO_OFF_IQT_REG)
     688    {
     689        /* Verify if the queue tail offset is aligned according to the descriptor width in IQA_REG. */
     690        uint16_t const offQueueTail = VTD_IQT_REG_GET_QT(uIqtReg);
     691        uint64_t const uIqaReg      = dmarRegRead64(pThis, VTD_MMIO_OFF_IQA_REG);
     692        uint8_t const  uDw          = RT_BF_GET(uIqaReg, VTD_BF_IQA_REG_DW);
     693        if (   uDw != VTD_IQA_REG_DW_256_BIT
     694            || !(offQueueTail & 0x1f))
     695        {
     696            /** @todo IOMMU: Figure out what to do here, like waking up worker thread or
     697             *        something. */
     698        }
     699        else
     700        {
     701            /* Raise invalidation queue error as queue tail not aligned to 256-bits. */
     702            /** @todo IOMMU: Raise error. */
     703        }
     704    }
     705    return VINF_SUCCESS;
    668706}
    669707
     
    747785    if (DMAR_IS_MMIO_OFF_VALID(offLast))
    748786    {
     787        uint64_t const uRegWritten = cb == 8 ? dmarRegWrite64(pThis, offReg, *(uint64_t *)pv)
     788                                             : dmarRegWrite32(pThis, offReg, *(uint32_t *)pv);
     789        VBOXSTRICTRC rcStrict = VINF_SUCCESS;
    749790        switch (off)
    750791        {
    751             default:
     792            case VTD_MMIO_OFF_IQT_REG:
     793            case VTD_MMIO_OFF_IQT_REG + 4:
    752794            {
    753                 if (cb == 8)
    754                     dmarRegWrite64(pThis, offReg, *(uint64_t *)pv);
    755                 else
    756                     dmarRegWrite32(pThis, offReg, *(uint32_t *)pv);
     795                rcStrict = dmarIqtRegWrite(pDevIns, offReg, uRegWritten);
    757796                break;
    758797            }
    759798        }
    760799
    761         LogFlowFunc(("offReg=%#x\n", offReg));
    762         return VINF_SUCCESS;
     800        LogFlowFunc(("offReg=%#x rc=%Rrc\n", offReg, VBOXSTRICTRC_VAL(rcStrict)));
     801        return rcStrict;
    763802    }
    764803
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