VirtualBox

Changeset 88481 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Apr 13, 2021 5:46:02 AM (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

    r88427 r88481  
    455455 * @param   uSagaw  The CAP_REG.SAGAW value.
    456456 */
    457 static uint8_t vtdGetSupGstAddrBits(uint8_t uSagaw)
     457static uint8_t vtdCapRegGetSagawBits(uint8_t uSagaw)
    458458{
    459459    if (RT_LIKELY(uSagaw > 0 && uSagaw < 4))
     
    467467 * address width (MGAW).
    468468 *
    469  * @returns The CAP.SAGAW value.
     469 * @returns The CAP_REG.SAGAW value.
    470470 * @param   uMgaw  The CAP_REG.MGAW value.
    471471 */
    472 static uint8_t vtdGetSupGstAddrWidth(uint8_t uMgaw)
     472static uint8_t vtdCapRegGetSagaw(uint8_t uMgaw)
    473473{
    474474    switch (uMgaw + 1)
     
    783783    {
    784784        if (cb == 8)
     785        {
    785786            *(uint64_t *)pv = dmarRegRead64(pThis, offReg);
     787            LogFlowFunc(("offReg=%#x pv=%#RX64\n", offReg, *(uint64_t *)pv));
     788        }
    786789        else
     790        {
    787791            *(uint32_t *)pv = dmarRegRead32(pThis, offReg);
    788 
    789         LogFlowFunc(("offReg=%#x\n", offReg));
     792            LogFlowFunc(("offReg=%#x pv=%#RX32\n", offReg, *(uint32_t *)pv));
     793        }
     794
    790795        return VINF_SUCCESS;
    791796    }
     
    825830    /* CAP_REG */
    826831    {
    827         uint8_t const fFl1gp = 1;                               /* First-Level 1GB pages support. */
    828         uint8_t const fFl5lp = 1;                               /* First-level 5-level paging support (PML5E). */
    829         uint8_t const fSl2mp = fSlts & 1;                       /* Second-Level 2MB pages support. */
    830         uint8_t const fSl2gp = fSlts & 1;                       /* Second-Level 1GB pages support. */
    831         uint8_t const fSllps = fSl2mp                           /* Second-Level large page Support. */
    832                              | ((fSl2mp & fFl1gp) & RT_BIT(1));
    833         uint8_t const fMamv  = (fSl2gp ?                        /* Maximum address mask value (for second-level invalidations). */
    834                                 X86_PAGE_1G_SHIFT : X86_PAGE_2M_SHIFT) - X86_PAGE_4K_SHIFT;
    835         uint8_t const fNd    = 2;                               /* Number of domains (0=16, 1=64, 2=256, 3=1K, 4=4K, 5=16K, 6=64K,
    836                                                                    7=Reserved). */
    837         uint8_t const fPsi   = 1;                               /* Page selective invalidation. */
    838832        uint8_t cGstPhysAddrBits;
    839833        uint8_t cGstLinearAddrBits;
    840834        PDMDevHlpCpuGetGuestAddrWidths(pDevIns, &cGstPhysAddrBits, &cGstLinearAddrBits);
    841         NOREF(cGstLinearAddrBits);
    842         uint8_t const uMgaw  = cGstPhysAddrBits - 1;            /* Maximum guest address width. */
    843         uint8_t const uSagaw = vtdGetSupGstAddrWidth(uMgaw);    /* Supported adjust guest address width. */
     835
     836        uint8_t const fFl1gp  = 1;                              /* First-Level 1GB pages support. */
     837        uint8_t const fFl5lp  = 1;                              /* First-level 5-level paging support (PML5E). */
     838        uint8_t const fSl2mp  = fSlts & 1;                      /* Second-Level 2MB pages support. */
     839        uint8_t const fSl2gp  = fSlts & 1;                      /* Second-Level 1GB pages support. */
     840        uint8_t const fSllps  = fSl2mp                          /* Second-Level large page Support. */
     841                              | ((fSl2mp & fFl1gp) & RT_BIT(1));
     842        uint8_t const fMamv   = (fSl2gp ?                       /* Maximum address mask value (for second-level invalidations). */
     843                                X86_PAGE_1G_SHIFT : X86_PAGE_2M_SHIFT) - X86_PAGE_4K_SHIFT;
     844        uint8_t const fNd     = 2;                              /* Number of domains (0=16, 1=64, 2=256, 3=1K, 4=4K, 5=16K, 6=64K,
     845                                                                  7=Reserved). */
     846        uint8_t const fPsi    = 1;                              /* Page selective invalidation. */
     847        uint8_t const uMgaw   = cGstPhysAddrBits - 1;           /* Maximum guest address width. */
     848        uint8_t const uSagaw  = vtdCapRegGetSagaw(uMgaw);       /* Supported adjust guest address width. */
     849        uint16_t const offFro = DMAR_MMIO_OFF_FRCD_LO_REG >> 4; /* MMIO offset of FRCD registers. */
    844850
    845851        pThis->fCap = RT_BF_MAKE(VTD_BF_CAP_REG_ND,     fNd)
     
    852858                    | RT_BF_MAKE(VTD_BF_CAP_REG_MGAW,   uMgaw)
    853859                    | RT_BF_MAKE(VTD_BF_CAP_REG_ZLR,    1)      /** @todo Figure out if/how to support zero-length reads. */
    854                     | RT_BF_MAKE(VTD_BF_CAP_REG_FRO,    DMAR_MMIO_OFF_FRCD_LO_REG >> 4)
     860                    | RT_BF_MAKE(VTD_BF_CAP_REG_FRO,    offFro)
    855861                    | RT_BF_MAKE(VTD_BF_CAP_REG_SLLPS,  fSlts & fSllps)
    856862                    | RT_BF_MAKE(VTD_BF_CAP_REG_PSI,    fPsi)
     
    866872    /* ECAP_REG */
    867873    {
    868         uint8_t const  fIr     = 1;                             /* Interrupt remapping support. */
    869         uint8_t const  fMhmv   = 0xf;                           /* Maximum handle mask value. */
    870         uint16_t const offIro  = DMAR_MMIO_OFF_IVA_REG >> 4;    /* MMIO offset of IOTLB registers. */
    871         uint8_t const  fSrs    = 1;                             /* Supervisor request support. */
    872         uint8_t const  fEim    = 1;                             /* Extended interrupt mode.*/
     874        uint8_t const  fQi    = 1;                              /* Queued invalidations. */
     875        uint8_t const  fIr    = !!(DMAR_ACPI_DMAR_FLAGS & ACPI_DMAR_F_INTR_REMAP);  /* Interrupt remapping support. */
     876        uint8_t const  fMhmv  = 0xf;                            /* Maximum handle mask value. */
     877        uint16_t const offIro = DMAR_MMIO_OFF_IVA_REG >> 4;     /* MMIO offset of IOTLB registers. */
     878        uint8_t const  fSrs   = 1;                              /* Supervisor request support. */
     879        uint8_t const  fEim   = 1;                              /* Extended interrupt mode.*/
    873880
    874881        pThis->fExtCap = RT_BF_MAKE(VTD_BF_ECAP_REG_C,      0)  /* Accesses don't snoop CPU cache. */
    875882                       | RT_BF_MAKE(VTD_BF_ECAP_REG_QI,     1)
    876883                       | RT_BF_MAKE(VTD_BF_ECAP_REG_DT,     0)  /* Device-TLBs not supported. */
    877                        | RT_BF_MAKE(VTD_BF_ECAP_REG_IR,     fIr)
     884                       | RT_BF_MAKE(VTD_BF_ECAP_REG_IR,     fQi & fIr)
    878885                       | RT_BF_MAKE(VTD_BF_ECAP_REG_EIM,    fIr & fEim)
    879886                       | RT_BF_MAKE(VTD_BF_ECAP_REG_PT,     fPt)
     
    918925
    919926#ifdef VBOX_STRICT
    920     uint64_t const fExtCap = dmarRegRead64(pThis, VTD_MMIO_OFF_ECAP_REG);
    921     Assert(!RT_BF_GET(fExtCap, VTD_BF_ECAP_REG_PRS));    /* PECTL_REG - Reserved if don't support PRS. */
    922     Assert(!RT_BF_GET(fExtCap, VTD_BF_ECAP_REG_MTS));    /* MTRRCAP_REG - Reserved if we don't support MTS. */
     927    Assert(!RT_BF_GET(pThis->fExtCap, VTD_BF_ECAP_REG_PRS));    /* PECTL_REG - Reserved if don't support PRS. */
     928    Assert(!RT_BF_GET(pThis->fExtCap, VTD_BF_ECAP_REG_MTS));    /* MTRRCAP_REG - Reserved if we don't support MTS. */
    923929#endif
    924930}
     
    10651071    dmarR3RegsInit(pDevIns);
    10661072
    1067     uint8_t const cMaxGstAddrBits = RT_BF_GET(pThis->fCap, VTD_BF_CAP_REG_MGAW) + 1;
    1068     uint8_t const cSupGstAddrBits = vtdGetSupGstAddrBits(RT_BF_GET(pThis->fCap, VTD_BF_CAP_REG_SAGAW));
    1069     LogRel(("%s: CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%u bits)\n", DMAR_LOG_PFX, pThis->fCap, pThis->fExtCap,
    1070             cMaxGstAddrBits, cSupGstAddrBits));
     1073    /*
     1074     * Log some of the features exposed to software.
     1075     */
     1076    uint32_t const uVerReg         = dmarRegRead32(pThis, VTD_MMIO_OFF_VER_REG);
     1077    uint8_t const  cMaxGstAddrBits = RT_BF_GET(pThis->fCap, VTD_BF_CAP_REG_MGAW) + 1;
     1078    uint8_t const  cSupGstAddrBits = vtdCapRegGetSagawBits(RT_BF_GET(pThis->fCap, VTD_BF_CAP_REG_SAGAW));
     1079    uint16_t const offFrcd         = RT_BF_GET(pThis->fCap, VTD_BF_CAP_REG_FRO);
     1080    uint16_t const offIva          = RT_BF_GET(pThis->fExtCap, VTD_BF_ECAP_REG_IRO);
     1081    LogRel(("%s: VER=%u.%u CAP=%#RX64 ECAP=%#RX64 (MGAW=%u bits, SAGAW=%u bits, FRO=%#x, IRO=%#x) mapped at %#RGp\n", DMAR_LOG_PFX,
     1082            RT_BF_GET(uVerReg, VTD_BF_VER_REG_MAX), RT_BF_GET(uVerReg, VTD_BF_VER_REG_MIN),
     1083            pThis->fCap, pThis->fExtCap, cMaxGstAddrBits, cSupGstAddrBits, offFrcd, offIva, DMAR_MMIO_BASE_PHYSADDR));
    10711084    return VINF_SUCCESS;
    10721085}
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