VirtualBox

Changeset 88257 in vbox for trunk/src


Ignore:
Timestamp:
Mar 23, 2021 10:54:19 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
143460
Message:

Intel IOMMU: bugref:9967 Move implementation-specifics out of iommu-intel.h. WIP.

File:
1 edited

Legend:

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

    r88225 r88257  
    4545 * used as it asserts for correctness when compiling on certain compilers). */
    4646#define VTD_HI_U32(a)       (uint32_t)((a) >> 32)
     47
     48/** @def VTD_ASSERT_MMIO_ACCESS
     49 * Asserts MMIO access' offset and size are valid or returns appropriate error
     50 * code suitable for returning from MMIO access handlers. */
     51#define VTD_ASSERT_MMIO_ACCESS_RET(a_off, a_cb) \
     52    do { \
     53         AssertReturn(!(off & 3), VINF_IOM_MMIO_UNUSED_FF); \
     54         AssertReturn(cb == 4 || cb == 8, VINF_IOM_MMIO_UNUSED_FF); \
     55    } while (0);
     56
     57/** @def VTD_IS_MMIO_OFF_VALID
     58 * Returns @c true if the MMIO offset is valid, or @c false otherwise. */
     59#define VTD_IS_MMIO_OFF_VALID(a_off)                (   (a_off) < VTD_MMIO_GROUP_0_OFF_END \
     60                                                     || (a_off) - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE)
     61
     62/** The number of fault recording registers our implementation supports.
     63 *  Normal guest operation shouldn't trigger faults anyway, so we only support the
     64 *  minimum number of registers (which is 1).
     65 *
     66 *  See Intel VT-d spec. 10.4.2 "Capability Register" (CAP_REG::NFR). */
     67#define VTD_FRCD_REG_COUNT                          UINT32_C(1)
     68
     69/** Offset of first register in group 0. */
     70#define VTD_MMIO_GROUP_0_OFF_FIRST                  VTD_MMIO_OFF_VER_REG
     71/** Offset of last register in group 0 (inclusive). */
     72#define VTD_MMIO_GROUP_0_OFF_LAST                   VTD_MMIO_OFF_MTRR_PHYSMASK9_REG
     73/** Last valid offset in group 0 (exclusive). */
     74#define VTD_MMIO_GROUP_0_OFF_END                    (VTD_MMIO_GROUP_0_OFF_LAST + 8 /* sizeof MTRR_PHYSMASK9_REG */)
     75/** Size of the group 0 (in bytes). */
     76#define VTD_MMIO_GROUP_0_SIZE                       (VTD_MMIO_GROUP_0_OFF_END - VTD_MMIO_GROUP_0_OFF_FIRST)
     77
     78#define VTD_MMIO_OFF_IVA_REG                        0xe40   /**< Implementation-specific MMIO offset of IVA_REG. */
     79#define VTD_MMIO_OFF_IOTLB_REG                      0xe48   /**< Implementation-specific MMIO offset of IOTLB_REG. */
     80#define VTD_MMIO_OFF_FRCD_LO_REG                    0xe60   /**< Implementation-specific MMIO offset of FRCD_LO_REG. */
     81#define VTD_MMIO_OFF_FRCD_HI_REG                    0xe68   /**< Implementation-specific MMIO offset of FRCD_HI_REG. */
     82AssertCompile(!(VTD_MMIO_OFF_FRCD_LO_REG & 0xf));
     83
     84/** Offset of first register in group 1. */
     85#define VTD_MMIO_GROUP_1_OFF_FIRST                  VTD_MMIO_OFF_VCCAP_REG
     86/** Offset of last register in group 1 (inclusive). */
     87#define VTD_MMIO_GROUP_1_OFF_LAST                   VTD_MMIO_OFF_FRCD_LO_REG + 8 * VTD_FRCD_REG_COUNT
     88/** Last valid offset in group 1 (exclusive). */
     89#define VTD_MMIO_GROUP_1_OFF_END                    (VTD_MMIO_GROUP_1_OFF_LAST + 8 /* sizeof FRCD_HI_REG */)
     90/** Size of the group 1 (in bytes). */
     91#define VTD_MMIO_GROUP_1_SIZE                       (VTD_MMIO_GROUP_1_OFF_END - VTD_MMIO_GROUP_1_OFF_FIRST)
    4792
    4893/** Release log prefix string. */
     
    318363static const uint32_t g_au32RwMasks1[] =
    319364{
    320     /* Offset  Register                  Low                                 High */
    321     /* 0xe00   VCCAP_REG             */  VTD_LO_U32(VTD_VCCAP_REG_RW_MASK),  VTD_HI_U32(VTD_VCCAP_REG_RW_MASK),
    322     /* 0xe08   Reserved              */  0,                                  0,
    323     /* 0xe10   VCMD_REG              */  0,                                  0, /* RO as we don't support VCS. */
    324     /* 0xe18   Reserved              */  0,                                  0,
    325     /* 0xe20   VCRSP_REG             */  0,                                  0, /* RO as we don't support VCS. */
     365    /* Offset  Register                  Low                                    High */
     366    /* 0xe00   VCCAP_REG             */  VTD_LO_U32(VTD_VCCAP_REG_RW_MASK),     VTD_HI_U32(VTD_VCCAP_REG_RW_MASK),
     367    /* 0xe08   Reserved              */  0,                                     0,
     368    /* 0xe10   VCMD_REG              */  0,                                     0, /* RO as we don't support VCS. */
     369    /* 0xe18   VCMDRSVD_REG          */  0,                                     0,
     370    /* 0xe20   VCRSP_REG             */  0,                                     0, /* RO as we don't support VCS. */
     371    /* 0xe28   VCRSPRSVD_REG         */  0,                                     0,
     372    /* 0xe30   Reserved              */  0,                                     0,
     373    /* 0xe38   Reserved              */  0,                                     0,
     374    /* 0xe40   IVA_REG               */  VTD_LO_U32(VTD_IVA_REG_RW_MASK),       VTD_HI_U32(VTD_IVA_REG_RW_MASK),
     375    /* 0xe48   IOTLB_REG             */  VTD_LO_U32(VTD_IOTLB_REG_RW_MASK),     VTD_HI_U32(VTD_IOTLB_REG_RW_MASK),
     376    /* 0xe50   Reserved              */  0,                                     0,
     377    /* 0xe58   Reserved              */  0,                                     0,
     378    /* 0xe60   FRCD_REG_LO           */  VTD_LO_U32(VTD_FRCD_REG_LO_RW_MASK),   VTD_HI_U32(VTD_FRCD_REG_LO_RW_MASK),
     379    /* 0xe68   FRCD_REG_HI           */  VTD_LO_U32(VTD_FRCD_REG_HI_RW_MASK),   VTD_HI_U32(VTD_FRCD_REG_HI_RW_MASK),
    326380};
    327381AssertCompile(sizeof(g_au32RwMasks1) == VTD_MMIO_GROUP_1_SIZE);
     382AssertCompile((VTD_MMIO_OFF_FRCD_LO_REG - VTD_MMIO_GROUP_1_OFF_FIRST) + VTD_FRCD_REG_COUNT * 2 * sizeof(uint64_t) );
    328383
    329384/**
     
    332387static const uint32_t g_au32Rw1cMasks1[] =
    333388{
    334     /* Offset  Register                  Low  High */
    335     /* 0xe00   VCCAP_REG             */  0,   0,
    336     /* 0xe08   Reserved              */  0,   0,
    337     /* 0xe10   VCMD_REG              */  0,   0,
    338     /* 0xe18   Reserved              */  0,   0,
    339     /* 0xe20   VCRSP_REG             */  0,   0,
     389    /* Offset  Register                  Low                                    High */
     390    /* 0xe00   VCCAP_REG             */  0,                                     0,
     391    /* 0xe08   Reserved              */  0,                                     0,
     392    /* 0xe10   VCMD_REG              */  0,                                     0,
     393    /* 0xe18   VCMDRSVD_REG          */  0,                                     0,
     394    /* 0xe20   VCRSP_REG             */  0,                                     0,
     395    /* 0xe28   VCRSPRSVD_REG         */  0,                                     0,
     396    /* 0xe30   Reserved              */  0,                                     0,
     397    /* 0xe38   Reserved              */  0,                                     0,
     398    /* 0xe40   IVA_REG               */  0,                                     0,
     399    /* 0xe48   IOTLB_REG             */  0,                                     0,
     400    /* 0xe50   Reserved              */  0,                                     0,
     401    /* 0xe58   Reserved              */  0,                                     0,
     402    /* 0xe60   FRCD_REG_LO           */  VTD_LO_U32(VTD_FRCD_REG_LO_RW1C_MASK), VTD_HI_U32(VTD_FRCD_REG_LO_RW1C_MASK),
     403    /* 0xe68   FRCD_REG_HI           */  VTD_LO_U32(VTD_FRCD_REG_HI_RW1C_MASK), VTD_HI_U32(VTD_FRCD_REG_HI_RW1C_MASK),
    340404};
    341405AssertCompile(sizeof(g_au32Rw1cMasks1) == VTD_MMIO_GROUP_1_SIZE);
     
    356420 * @param   pThis       The shared IOMMU device state.
    357421 * @param   offReg      The MMIO offset of the register.
    358  * @param   cbReg       The size of the access being made (for bounds check).
     422 * @param   cbReg       The size of the access being made.
    359423 * @param   pIdxGroup   Where to store the index of the register group the register
    360424 *                      belongs to.
     
    362426DECLINLINE(uint8_t *) iommuIntelRegGetGroup(PIOMMU pThis, uint16_t offReg, uint8_t cbReg, uint8_t *pIdxGroup)
    363427{
     428    uint16_t const offLast = offReg + cbReg - 1;
     429
    364430    AssertCompile(VTD_MMIO_GROUP_0_OFF_FIRST == 0);
    365     AssertMsg(   offReg + cbReg <= VTD_MMIO_GROUP_0_OFF_END
    366               || (offReg >= VTD_MMIO_GROUP_1_OFF_FIRST && offReg + cbReg <= VTD_MMIO_GROUP_1_OFF_END), ("%#x\n", offReg));
     431    AssertMsg(   offLast < VTD_MMIO_GROUP_0_OFF_END
     432              || offLast - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE, ("off=%#x cb=%u\n", offReg, cbReg));
    367433    NOREF(cbReg);
    368434
    369435    uint8_t *apbRegs[] = { &pThis->abRegs0[0], &pThis->abRegs1[0] };
    370     *pIdxGroup = !(offReg < VTD_MMIO_GROUP_0_OFF_END);
     436    *pIdxGroup = !(offLast < VTD_MMIO_GROUP_0_OFF_END);
    371437    return apbRegs[*pIdxGroup];
    372438}
     
    600666static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
    601667{
    602     RT_NOREF5(pDevIns, pvUser, off, pv, cb);
    603     return VERR_NOT_IMPLEMENTED;
    604 }
    605 
    606 
    607 /**
    608  * @callback_method_impl{FNIOMMMIONEWREAD}
    609  */
    610 static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
    611 {
    612668    RT_NOREF1(pvUser);
    613 
    614     AssertReturn(!(off & 3), VINF_IOM_MMIO_UNUSED_FF);
    615     AssertReturn(cb == 4 || cb == 8, VINF_IOM_MMIO_UNUSED_FF);
     669    VTD_ASSERT_MMIO_ACCESS_RET(off, cb);
    616670
    617671    PIOMMU         pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    618672    uint16_t const offReg  = off;
    619673    uint16_t const offLast = offReg + cb - 1;
    620     if (   offLast < VTD_MMIO_GROUP_0_OFF_END
    621         || offLast - VTD_MMIO_GROUP_1_OFF_FIRST < VTD_MMIO_GROUP_1_SIZE)
     674    if (VTD_IS_MMIO_OFF_VALID(offLast))
     675    {
     676        switch (off)
     677        {
     678            default:
     679            {
     680                if (cb == 8)
     681                    iommuIntelRegWrite64(pThis, offReg, *(uint64_t *)pv);
     682                else
     683                    iommuIntelRegWrite32(pThis, offReg, *(uint32_t *)pv);
     684                break;
     685            }
     686        }
     687        return VINF_SUCCESS;
     688    }
     689    return VINF_IOM_MMIO_UNUSED_FF;
     690}
     691
     692
     693/**
     694 * @callback_method_impl{FNIOMMMIONEWREAD}
     695 */
     696static DECLCALLBACK(VBOXSTRICTRC) iommuIntelMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
     697{
     698    RT_NOREF1(pvUser);
     699    VTD_ASSERT_MMIO_ACCESS_RET(off, cb);
     700
     701    PIOMMU         pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     702    uint16_t const offReg  = off;
     703    uint16_t const offLast = offReg + cb - 1;
     704    if (VTD_IS_MMIO_OFF_VALID(offLast))
    622705    {
    623706        if (cb == 8)
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