VirtualBox

Changeset 88875 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
May 5, 2021 12:55:23 PM (4 years ago)
Author:
vboxsync
Message:

Intel IOMMU: bugref:9967 Interrupt remapping, work-in-progress.

File:
1 edited

Legend:

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

    r88872 r88875  
    170170    kDmarDiag_Ir_Cfi_Blocked,
    171171    kDmarDiag_Ir_Rfi_Intr_Index_Invalid,
     172    kDmarDiag_Ir_Rfi_Irte_Mode_Invalid,
     173    kDmarDiag_Ir_Rfi_Irte_Not_Present,
    172174    kDmarDiag_Ir_Rfi_Irte_Read_Failed,
    173     kDmarDiag_Ir_Rfi_Irte_Not_Present,
    174175    kDmarDiag_Ir_Rfi_Irte_Rsvd,
    175176    kDmarDiag_Ir_Rfi_Irte_Svt_Bus,
     
    208209    DMARDIAG_DESC(Ir_Cfi_Blocked            ),
    209210    DMARDIAG_DESC(Ir_Rfi_Intr_Index_Invalid ),
     211    DMARDIAG_DESC(Ir_Rfi_Irte_Mode_Invalid  ),
     212    DMARDIAG_DESC(Ir_Rfi_Irte_Not_Present   ),
    210213    DMARDIAG_DESC(Ir_Rfi_Irte_Read_Failed   ),
    211     DMARDIAG_DESC(Ir_Rfi_Irte_Not_Present   ),
    212214    DMARDIAG_DESC(Ir_Rfi_Irte_Rsvd          ),
    213215    DMARDIAG_DESC(Ir_Rfi_Irte_Svt_Bus       ),
     
    15331535
    15341536/**
     1537 * Remaps the source MSI to the destination MSI given the IRTE.
     1538 *
     1539 * @param   fExtIntrMode    Whether extended interrupt mode is enabled (i.e
     1540 *                          IRTA_REG.EIME).
     1541 * @param   pMsiIn          The source MSI (currently unused).
     1542 * @param   pMsiOut         Where to store the remapped MSI.
     1543 * @param   pIrte           The IRTE used for the remapping.
     1544 */
     1545static void dmarIrRemapFromIrte(bool fExtIntrMode, PCVTD_IRTE_T pIrte, PCMSIMSG pMsiIn, PMSIMSG pMsiOut)
     1546{
     1547    NOREF(pMsiIn);
     1548    uint64_t const uIrteQword0 = pIrte->au64[0];
     1549
     1550    /*
     1551     * Let's start with a clean slate and preserve unspecified bits if the need arises.
     1552     * For instance, address bits 1:0 is supposed to be "ignored" by remapping hardware,
     1553     * but it's not clear if hardware zeroes out these bits in the remapped MSI or if
     1554     * it copies it from the source MSI.
     1555     */
     1556    RT_ZERO(*pMsiOut);
     1557    pMsiOut->Addr.n.u1DestMode  = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_DM);
     1558    pMsiOut->Addr.n.u1RedirHint = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_RH);
     1559    pMsiOut->Addr.n.u12Addr     = VBOX_MSI_ADDR_BASE >> VBOX_MSI_ADDR_SHIFT;
     1560    if (fExtIntrMode)
     1561    {
     1562        /*
     1563         * Apparently the DMAR stuffs the high 24-bits of the destination ID into the
     1564         * high 24-bits of the upper 32-bits of the message address, see @bugref{9967#c22}.
     1565         */
     1566        uint32_t const idDest = VTD_IRTE_0_GET_X2APIC_DEST_ID(uIrteQword0);
     1567        pMsiOut->Addr.n.u8DestId = idDest & 0xff;
     1568        pMsiOut->Addr.n.u32Rsvd0 = idDest & 0xffffff00;
     1569    }
     1570    else
     1571        pMsiOut->Addr.n.u8DestId = VTD_IRTE_0_GET_XAPIC_DEST_ID(uIrteQword0);
     1572
     1573    pMsiOut->Data.n.u8Vector       = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_V);
     1574    pMsiOut->Data.n.u3DeliveryMode = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_DLM);
     1575    pMsiOut->Data.n.u1Level        = 1;
     1576    pMsiOut->Data.n.u1TriggerMode  = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_TM);
     1577}
     1578
     1579
     1580/**
    15351581 * Handles remapping of interrupts in remappable interrupt format.
    15361582 *
     
    16241670                        if (fSrcValid)
    16251671                        {
    1626                             /** @todo Get the interrupt mode (must not be posted) and then remap. */
    1627                             *pMsiOut = *pMsiIn;      // This is just temporary to shut up the compiler!
    1628                             return VERR_NOT_IMPLEMENTED;
     1672                            uint8_t const fPostedMode = RT_BF_GET(uIrteQword0, VTD_BF_0_IRTE_IM);
     1673                            if (!fPostedMode)
     1674                            {
     1675                                bool const fExtIntrMode = RT_BF_GET(uIrtaReg, VTD_BF_IRTA_REG_EIME);
     1676                                dmarIrRemapFromIrte(fExtIntrMode, &Irte, pMsiIn, pMsiOut);
     1677                                return VINF_SUCCESS;
     1678                            }
     1679                            dmarIrFaultRecordQualified(pDevIns, kDmarDiag_Ir_Rfi_Irte_Mode_Invalid, kIrf_Irte_Present_Rsvd,
     1680                                                       idDevice, idxIntr, &Irte);
    16291681                        }
    16301682                        else
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