VirtualBox

Changeset 87691 in vbox


Ignore:
Timestamp:
Feb 10, 2021 4:20:11 PM (4 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Replace IOMMU device lock with the PDM lock and use a separate lock for the IOTLB/DTE cache.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmdev.h

    r87477 r87691  
    14921492    /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
    14931493    uint32_t                u32Version;
     1494
     1495    /**
     1496     * Acquires the PDM lock.
     1497     *
     1498     * @returns VINF_SUCCESS on success.
     1499     * @returns rc if we failed to acquire the lock.
     1500     * @param   pDevIns     The PCI device instance.
     1501     * @param   rc          What to return if we fail to acquire the lock.
     1502     */
     1503    DECLR0CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
     1504
     1505    /**
     1506     * Releases the PDM lock.
     1507     *
     1508     * @param   pDevIns         The PCI device instance.
     1509     */
     1510    DECLR0CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
     1511
    14941512    /** Just a safety precaution. */
    14951513    uint32_t                u32TheEnd;
     
    15011519
    15021520/** Current PDMIOMMUHLPR0 version number. */
    1503 #define PDM_IOMMUHLPR0_VERSION                      PDM_VERSION_MAKE(0xff13, 1, 0)
     1521#define PDM_IOMMUHLPR0_VERSION                      PDM_VERSION_MAKE(0xff13, 2, 0)
    15041522
    15051523
     
    15111529    /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
    15121530    uint32_t                u32Version;
     1531
     1532    /**
     1533     * Acquires the PDM lock.
     1534     *
     1535     * @returns VINF_SUCCESS on success.
     1536     * @returns rc if we failed to acquire the lock.
     1537     * @param   pDevIns     The PCI device instance.
     1538     * @param   rc          What to return if we fail to acquire the lock.
     1539     */
     1540    DECLRCCALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
     1541
     1542    /**
     1543     * Releases the PDM lock.
     1544     *
     1545     * @param   pDevIns         The PCI device instance.
     1546     */
     1547    DECLRCCALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
     1548
    15131549    /** Just a safety precaution. */
    15141550    uint32_t                u32TheEnd;
     
    15201556
    15211557/** Current PDMIOMMUHLPRC version number. */
    1522 #define PDM_IOMMUHLPRC_VERSION                      PDM_VERSION_MAKE(0xff14, 1, 0)
     1558#define PDM_IOMMUHLPRC_VERSION                      PDM_VERSION_MAKE(0xff14, 2, 0)
    15231559
    15241560
     
    15301566    /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
    15311567    uint32_t                u32Version;
     1568
     1569    /**
     1570     * Acquires the PDM lock.
     1571     *
     1572     * @returns VINF_SUCCESS on success.
     1573     * @returns rc if we failed to acquire the lock.
     1574     * @param   pDevIns     The PCI device instance.
     1575     * @param   rc          What to return if we fail to acquire the lock.
     1576     */
     1577    DECLR3CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
     1578
     1579    /**
     1580     * Releases the PDM lock.
     1581     *
     1582     * @param   pDevIns         The PCI device instance.
     1583     */
     1584    DECLR3CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
     1585
    15321586    /** Just a safety precaution. */
    15331587    uint32_t                u32TheEnd;
     
    15391593
    15401594/** Current PDMIOMMUHLPR3 version number. */
    1541 #define PDM_IOMMUHLPR3_VERSION                      PDM_VERSION_MAKE(0xff15, 1, 0)
     1595#define PDM_IOMMUHLPR3_VERSION                      PDM_VERSION_MAKE(0xff15, 2, 0)
    15421596
    15431597
  • trunk/src/VBox/Devices/Bus/DevIommuAmd.cpp

    r87671 r87691  
    7777# define IOMMU_IOTLB_KEY_MAKE(a_DomainId, a_uIova)  (  ((uint64_t)(a_DomainId) << IOMMU_IOTLB_DOMAIN_ID_SHIFT) \
    7878                                                     | (((a_uIova) >> X86_PAGE_4K_SHIFT) & IOMMU_IOTLB_IOVA_MASK))
     79
     80/** Acquires the cache lock. */
     81# define IOMMU_LOCK_CACHE(a_pDevIns, a_pThis) \
     82    do { \
     83        int const rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSectCache, VERR_SEM_BUSY); \
     84        if (rcLock == VINF_SUCCESS) \
     85        { /* likely */ } \
     86        else \
     87        { \
     88            AssertRC(rcLock); \
     89            return rcLock; \
     90        } \
     91    } while (0)
     92
     93/** Acquires the cache lock (asserts on failure). */
     94# define IOMMU_LOCK_CACHE_NORET(a_pDevIns, a_pThis) \
     95    do { \
     96        int const rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSectCache, VERR_SEM_BUSY); \
     97        AssertRC(rcLock); \
     98    } while (0)
     99
     100/** Releases the cache lock.  */
     101# define IOMMU_UNLOCK_CACHE(a_pDevIns, a_pThis)     PDMDevHlpCritSectLeave((a_pDevIns), &(a_pThis)->CritSectCache)
    79102#endif
    80103
     
    131154#define IOMMU_GET_PAGE_OFF_MASK(a_cShift)           (~(UINT64_C(0xffffffffffffffff) << (a_cShift)))
    132155
    133 
    134 /*********************************************************************************************************************************
    135 *   Structures and Typedefs                                                                                                      *
    136 *********************************************************************************************************************************/
    137 /**
    138  * Acquires the IOMMU PDM lock.
    139  * This will make a long jump to ring-3 to acquire the lock if necessary.
    140  */
    141 #define IOMMU_LOCK(a_pDevIns)  \
     156/** Acquires the PDM lock. */
     157#define IOMMU_LOCK(a_pDevIns, a_pThisCC)  \
    142158    do { \
    143         int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS); \
     159        int const rcLock = (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), VERR_SEM_BUSY); \
    144160        if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
    145161        { /* likely */ } \
     
    148164    } while (0)
    149165
    150 /**
    151  * Acquires the IOMMU PDM lock (asserts on failure rather than returning an error).
    152  * This will make a long jump to ring-3 to acquire the lock if necessary.
    153  */
    154 #define IOMMU_LOCK_NORET(a_pDevIns)  \
     166/** Acquires the PDM lock (asserts on failure). */
     167#define IOMMU_LOCK_NORET(a_pDevIns, a_pThisCC)  \
    155168    do { \
    156         int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS); \
     169        int const rcLock = (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnLock((a_pDevIns), VERR_SEM_BUSY); \
    157170        AssertRC(rcLock); \
    158171    } while (0)
    159172
    160 /**
    161  * Releases the IOMMU PDM lock.
    162  */
    163 #define IOMMU_UNLOCK(a_pDevIns) \
    164     do { \
    165         PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo)); \
    166     } while (0)
    167 
    168 /**
    169  * Asserts that the critsect is owned by this thread.
    170  */
    171 #define IOMMU_ASSERT_LOCKED(a_pDevIns) \
    172     do { \
    173         Assert(PDMDevHlpCritSectIsOwner((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))); \
    174     }  while (0)
    175 
    176 /**
    177  * Asserts that the critsect is not owned by this thread.
    178  */
    179 #define IOMMU_ASSERT_NOT_LOCKED(a_pDevIns) \
    180     do { \
    181         Assert(!PDMDevHlpCritSectIsOwner((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo))); \
    182     }  while (0)
    183 
     173/** Releases the PDM lock.   */
     174# define IOMMU_UNLOCK(a_pDevIns, a_pThisCC)         (a_pThisCC)->CTX_SUFF(pIommuHlp)->pfnUnlock((a_pDevIns))
     175
     176/** Asserts that the lock is owned by this thread. */
     177#define IOMMU_ASSERT_LOCKED(a_pDevIns)              do { } while (0)
     178
     179/** Asserts that the lock isn't owned by this thread. */
     180#define IOMMU_ASSERT_NOT_LOCKED(a_pDevIns)          do { } while (0)
     181
     182
     183/*********************************************************************************************************************************
     184*   Structures and Typedefs                                                                                                      *
     185*********************************************************************************************************************************/
    184186/**
    185187 * IOMMU operation (transaction).
     
    284286
    285287#ifdef IOMMU_WITH_IOTLBE_CACHE
     288    /** The critsect that protects the cache from concurrent access. */
     289    PDMCRITSECT                 CritSectCache;
    286290    /** L1 Cache - Maps [DeviceId] to [DomainId]. */
    287291    PIODEVICE                   paDevices;
     
    486490    PPDMDEVINSR3                pDevInsR3;
    487491    /** The IOMMU helpers. */
    488     PCPDMIOMMUHLPR3             pIommuHlpR3;
     492    R3PTRTYPE(PCPDMIOMMUHLPR3)  pIommuHlpR3;
    489493    /** The command thread handle. */
    490494    R3PTRTYPE(PPDMTHREAD)       pCmdThread;
     
    501505    PPDMDEVINSR0                pDevInsR0;
    502506    /** The IOMMU helpers. */
    503     PCPDMIOMMUHLPR0             pIommuHlpR0;
     507    R0PTRTYPE(PCPDMIOMMUHLPR0)  pIommuHlpR0;
    504508} IOMMUR0;
    505509/** Pointer to the ring-0 IOMMU device state. */
     
    512516{
    513517    /** Device instance. */
    514     PPDMDEVINSR0                pDevInsRC;
     518    PPDMDEVINSRC                pDevInsRC;
    515519    /** The IOMMU helpers. */
    516     PCPDMIOMMUHLPRC             pIommuHlpRC;
     520    RCPTRTYPE(PCPDMIOMMUHLPRC)  pIommuHlpRC;
    517521} IOMMURC;
    518522/** Pointer to the raw-mode IOMMU device state. */
     
    10281032{
    10291033    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    1030     IOMMU_ASSERT_LOCKED(pDevIns);
     1034    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    10311035
    10321036    if (pThis->cCachedIotlbes > 0)
     
    10391043        RTListInit(&pThis->LstLruIotlbe);
    10401044    }
     1045
     1046    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    10411047}
    10421048
     
    10461052 * domain ID from the cache.
    10471053 *
    1048  * @param   pThis           The IOMMU device state.
     1054 * @param   pDevIns         The IOMMU instance data.
    10491055 * @param   uDomainId       The domain ID.
    10501056 * @param   uIova           The I/O virtual address to invalidate.
    10511057 * @param   cbInvalidate    The size of the invalidation (must be 4K aligned).
    10521058 */
    1053 static void iommuAmdIotlbRemoveRange(PIOMMU pThis, uint16_t uDomainId, uint64_t uIova, size_t cbInvalidate)
     1059static void iommuAmdIotlbRemoveRange(PPDMDEVINS pDevIns, uint16_t uDomainId, uint64_t uIova, size_t cbInvalidate)
    10541060{
    10551061    /* Validate. */
     
    10581064    Assert(cbInvalidate >= X86_PAGE_4K_SIZE);
    10591065
     1066    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     1067    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
     1068
    10601069    do
    10611070    {
     
    10701079        cbInvalidate -= X86_PAGE_4K_SIZE;
    10711080    } while (cbInvalidate > 0);
     1081
     1082    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    10721083}
    10731084
     
    10761087 * Removes all IOTLB entries for the specified domain ID.
    10771088 *
    1078  * @param   pThis       The IOMMU device state.
     1089 * @param   pDevIns     The IOMMU instance data.
    10791090 * @param   uDomainId   The domain ID.
    10801091 */
    1081 static void iommuAmdIotlbRemoveDomainId(PIOMMU pThis, uint16_t uDomainId)
     1092static void iommuAmdIotlbRemoveDomainId(PPDMDEVINS pDevIns, uint16_t uDomainId)
    10821093{
    10831094    /*
     
    10871098     * so they will eventually get evicted and re-cycled as the cache gets re-populated.
    10881099     */
     1100    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     1101    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
     1102
    10891103    IOTLBEFLUSHARG Args;
    10901104    Args.pIommu    = pThis;
    10911105    Args.uDomainId = uDomainId;
    10921106    RTAvlU64DoWithAll(&pThis->TreeIotlbe, true /* fFromLeft */, iommuAmdIotlbEntryRemoveDomainId, &Args);
     1107
     1108    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    10931109}
    10941110
     
    11111127    Assert(!(cbAccess & X86_PAGE_4K_OFFSET_MASK));
    11121128    Assert(cbAccess >= X86_PAGE_4K_SIZE);
    1113     IOMMU_ASSERT_LOCKED(pDevIns);
    11141129
    11151130    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     
    11241139    size_t cPages = cbAccess / X86_PAGE_4K_SIZE;
    11251140    cPages = RT_MIN(cPages, IOMMU_IOTLBE_MAX);
     1141
     1142    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    11261143    do
    11271144    {
     
    11311148        --cPages;
    11321149    } while (cPages > 0);
     1150    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    11331151}
    11341152
     
    11481166{
    11491167    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    1150     IOMMU_ASSERT_LOCKED(pDevIns);
     1168    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    11511169
    11521170    if (fOrMask & IOMMU_DEV_F_PRESENT)
     
    11611179        pThis->paDevices[uDevId].uDomainId = 0;
    11621180    }
     1181
     1182    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    11631183}
    11641184
     
    11741194{
    11751195    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    1176     IOMMU_ASSERT_LOCKED(pDevIns);
     1196    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    11771197
    11781198    if (fDevIoFlags & IOMMU_DEV_F_PRESENT)
    11791199        pThis->paDevices[uDevId].fFlags |= fDevIoFlags;
     1200
     1201    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    11801202}
    11811203
     
    11891211{
    11901212    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    1191     IOMMU_ASSERT_LOCKED(pDevIns);
     1213    IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    11921214
    11931215    size_t const cbDevices = sizeof(IODEVICE) * IOMMU_DTE_CACHE_MAX;
    11941216    RT_BZERO(pThis->paDevices, cbDevices);
     1217
     1218    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    11951219}
    11961220#endif  /* IOMMU_WITH_IOTLBE_CACHE */
     
    12471271 *
    12481272 * @param   pDevIns     The IOMMU device instance.
     1273 *
     1274 * @remarks The IOMMU lock must be held.
    12491275 */
    12501276static void iommuAmdCmdThreadWakeUpIfNeeded(PPDMDEVINS pDevIns)
     
    24872513 *
    24882514 * @thread  Any.
     2515 * @remarks The IOMMU lock must be held while calling this function.
    24892516 */
    24902517static int iommuAmdEvtLogEntryWrite(PPDMDEVINS pDevIns, PCEVT_GENERIC_T pEvent)
    24912518{
    2492     PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    2493 
    2494     IOMMU_ASSERT_LOCKED(pDevIns);
     2519    PIOMMU   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     2520    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     2521
     2522    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    24952523
    24962524    /* Check if event logging is active and the log has not overflowed. */
     
    25402568        }
    25412569    }
     2570
     2571    IOMMU_UNLOCK(pDevIns, pThisCC);
    25422572
    25432573    return VINF_SUCCESS;
     
    26122642    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtPageTabHwErr;
    26132643
    2614     IOMMU_LOCK_NORET(pDevIns);
     2644    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     2645    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    26152646
    26162647    iommuAmdHwErrorSet(pDevIns, (PCEVT_GENERIC_T)pEvent);
     
    26192650        iommuAmdSetPciTargetAbort(pDevIns);
    26202651
    2621     IOMMU_UNLOCK(pDevIns);
     2652    IOMMU_UNLOCK(pDevIns, pThisCC);
    26222653
    26232654    LogFunc(("Raised PAGE_TAB_HARDWARE_ERROR. uDevId=%#x uDomainId=%#x GCPhysPtEntity=%#RGp enmOp=%u u2Type=%u\n",
     
    26572688    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    26582689
    2659     IOMMU_LOCK_NORET(pDevIns);
     2690    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     2691    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    26602692
    26612693    iommuAmdHwErrorSet(pDevIns, (PCEVT_GENERIC_T)pEvent);
     
    26632695    ASMAtomicAndU64(&pThis->Status.u64, ~IOMMU_STATUS_CMD_BUF_RUNNING);
    26642696
    2665     IOMMU_UNLOCK(pDevIns);
     2697    IOMMU_UNLOCK(pDevIns, pThisCC);
    26662698
    26672699    LogFunc(("Raised COMMAND_HARDWARE_ERROR. GCPhysCmd=%#RGp u2Type=%u\n", pEvtCmdHwErr->n.u64Addr, pEvtCmdHwErr->n.u2Type));
     
    27082740    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtDevTabHwErr;
    27092741
    2710     IOMMU_LOCK_NORET(pDevIns);
     2742    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     2743    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    27112744
    27122745    iommuAmdHwErrorSet(pDevIns, (PCEVT_GENERIC_T)pEvent);
     
    27152748        iommuAmdSetPciTargetAbort(pDevIns);
    27162749
    2717     IOMMU_UNLOCK(pDevIns);
     2750    IOMMU_UNLOCK(pDevIns, pThisCC);
    27182751
    27192752    LogFunc(("Raised DEV_TAB_HARDWARE_ERROR. uDevId=%#x GCPhysDte=%#RGp enmOp=%u u2Type=%u\n", pEvtDevTabHwErr->n.u16DevId,
     
    27512784    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    27522785
    2753     IOMMU_LOCK_NORET(pDevIns);
    2754 
    27552786    iommuAmdEvtLogEntryWrite(pDevIns, pEvent);
    27562787    ASMAtomicAndU64(&pThis->Status.u64, ~IOMMU_STATUS_CMD_BUF_RUNNING);
    2757 
    2758     IOMMU_UNLOCK(pDevIns);
    27592788
    27602789    LogFunc(("Raised ILLEGAL_COMMAND_ERROR. Addr=%#RGp\n", pEvtIllegalCmd->n.u64Addr));
     
    28072836    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtIllegalDte;
    28082837
    2809     IOMMU_LOCK_NORET(pDevIns);
    2810 
    28112838    iommuAmdEvtLogEntryWrite(pDevIns, pEvent);
    28122839    if (enmOp != IOMMUOP_CMD)
    28132840        iommuAmdSetPciTargetAbort(pDevIns);
    2814 
    2815     IOMMU_UNLOCK(pDevIns);
    28162841
    28172842    LogFunc(("Raised ILLEGAL_DTE_EVENT. uDevId=%#x uIova=%#RX64 enmOp=%u enmEvtType=%u\n", pEvtIllegalDte->n.u16DevId,
     
    28842909#endif
    28852910
    2886     IOMMU_LOCK_NORET(pDevIns);
    2887 
    28882911    bool fSuppressEvtLogging = false;
    28892912    if (   enmOp == IOMMUOP_MEM_READ
     
    29953018    }
    29963019
    2997     IOMMU_UNLOCK(pDevIns);
    2998 
    29993020#undef IOMMU_DTE_CACHE_SET_PF_RAISED
    30003021}
     
    30353056static int iommuAmdDteRead(PPDMDEVINS pDevIns, uint16_t uDevId, IOMMUOP enmOp, PDTE_T pDte)
    30363057{
    3037     PCIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3038 
    3039     IOMMU_LOCK(pDevIns);
     3058    PCIOMMU  pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     3059    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     3060
     3061    IOMMU_LOCK(pDevIns, pThisCC);
    30403062
    30413063    /* Figure out which device table segment is being accessed. */
     
    30553077    uint32_t const cbDevTabSeg  = (pThis->aDevTabBaseAddrs[idxSeg].n.u9Size + 1) << X86_PAGE_4K_SHIFT;
    30563078
    3057     IOMMU_UNLOCK(pDevIns);
     3079    IOMMU_UNLOCK(pDevIns, pThisCC);
    30583080
    30593081    if (offDte + sizeof(DTE_T) <= cbDevTabSeg)
     
    34813503                    {
    34823504                        /* Update that addresses requires translation (cumulative permissions of DTE and I/O page tables). */
    3483                         IOMMU_LOCK(pDevIns);
    34843505                        iommuAmdDteCacheUpdate(pDevIns, uDevId, &Dte, IOMMU_DEV_F_PRESENT | IOMMU_DEV_F_ADDR_TRANSLATE);
    34853506
     
    34873508                        iommuAmdIotlbUpdate(pDevIns, Dte.n.u16DomainId, uIova & X86_PAGE_4K_BASE_MASK, cbPages,
    34883509                                            GCPhysSpa & X86_PAGE_4K_BASE_MASK, WalkResultPrev.fPerm);
    3489                         IOMMU_UNLOCK(pDevIns);
    34903510                    }
    34913511#endif
     
    35033523#if defined(IN_RING3) && defined(IOMMU_WITH_IOTLBE_CACHE)
    35043524                    /* Update that addresses permissions of DTE apply (but omit address translation). */
    3505                     IOMMU_LOCK(pDevIns);
    35063525                    iommuAmdDteCacheUpdate(pDevIns, uDevId, &Dte, IOMMU_DEV_F_PRESENT | IOMMU_DEV_F_IO_PERM);
    3507                     IOMMU_UNLOCK(pDevIns);
    35083526#endif
    35093527                }
     
    35373555#if defined(IN_RING3) && defined(IOMMU_WITH_IOTLBE_CACHE)
    35383556            /* Update that addresses don't require translation (nor permission checks) but a DTE is present. */
    3539             IOMMU_LOCK(pDevIns);
    35403557            iommuAmdDteCacheUpdate(pDevIns, uDevId, &Dte, IOMMU_DEV_F_PRESENT);
    3541             IOMMU_UNLOCK(pDevIns);
    35423558#endif
    35433559        }
     
    35843600{
    35853601    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3586 
    3587     IOMMU_LOCK(pDevIns);
     3602    IOMMU_LOCK_CACHE(pDevIns, pThis);
    35883603
    35893604    /* Lookup the device from the level 1 cache. */
     
    37023717    }
    37033718
    3704     IOMMU_UNLOCK(pDevIns);
     3719    IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    37053720    return rc;
    37063721}
     
    37873802        if (rc == VERR_IOMMU_ADDR_ACCESS_DENIED)
    37883803            return VERR_IOMMU_ADDR_ACCESS_DENIED;
    3789         Assert(rc == VERR_NOT_FOUND);
     3804        AssertMsg(rc == VERR_NOT_FOUND, ("Cache lokoup failed: %Rrc\n", rc));
    37903805        STAM_COUNTER_INC(&pThis->StatIotlbeCacheMiss);
    37913806        /** @todo r=ramshankar: WARNING! when implementing continuing of lookups because
     
    42604275static int iommuAmdR3CmdProcess(PPDMDEVINS pDevIns, PCCMD_GENERIC_T pCmd, RTGCPHYS GCPhysCmd, PEVT_GENERIC_T pEvtError)
    42614276{
    4262     IOMMU_ASSERT_NOT_LOCKED(pDevIns);
    4263 
    4264     PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     4277    PIOMMU   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     4278    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     4279
    42654280    STAM_COUNTER_INC(&pThis->StatCmd);
    42664281
     
    42964311                if (pCmdComWait->n.u1Interrupt)
    42974312                {
    4298                     IOMMU_LOCK(pDevIns);
     4313                    IOMMU_LOCK(pDevIns, pThisCC);
    42994314                    ASMAtomicOrU64(&pThis->Status.u64, IOMMU_STATUS_COMPLETION_WAIT_INTR);
    43004315                    IOMMU_CTRL_T const Ctrl = iommuAmdGetCtrl(pThis);
    43014316                    bool const fRaiseInt = Ctrl.n.u1CompWaitIntrEn;
    4302                     IOMMU_UNLOCK(pDevIns);
     4317                    IOMMU_UNLOCK(pDevIns, pThisCC);
    43034318
    43044319                    if (fRaiseInt)
     
    43224337                && !(pCmdInvDte->au64[1] & ~IOMMU_CMD_INV_DTE_QWORD_1_VALID_MASK))
    43234338            {
    4324                 IOMMU_LOCK(pDevIns);
    43254339                iommuAmdDteCacheUpdate(pDevIns, pCmdInvDte->n.u16DevId, NULL /* pDte */, 0 /* fFlags */);
    4326                 IOMMU_UNLOCK(pDevIns);
    43274340                return VINF_SUCCESS;
    43284341            }
     
    43714384                }
    43724385
    4373                 IOMMU_LOCK(pDevIns);
    4374 
    43754386                /*
    43764387                 * Validate invalidation size.
     
    43834394                    /* Remove the range of I/O virtual addresses requesting to be invalidated. */
    43844395                    size_t const cbAccess = RT_BIT_64(cShift);
    4385                     iommuAmdIotlbRemoveRange(pThis, uDomainId, uIova, cbAccess);
     4396                    iommuAmdIotlbRemoveRange(pDevIns, uDomainId, uIova, cbAccess);
    43864397                }
    43874398                else
     
    43914402                     * In such situations we must remove all ranges for the specified domain ID.
    43924403                     */
    4393                     iommuAmdIotlbRemoveDomainId(pThis, uDomainId);
     4404                    iommuAmdIotlbRemoveDomainId(pDevIns, uDomainId);
    43944405                }
    43954406
    4396                 IOMMU_UNLOCK(pDevIns);
    43974407                return VINF_SUCCESS;
    43984408            }
     
    44614471                    && !(pCmdInvAll->au64[1] & ~IOMMU_CMD_INV_IOMMU_ALL_QWORD_1_VALID_MASK))
    44624472                {
    4463                     IOMMU_LOCK(pDevIns);
    44644473                    iommuAmdDteCacheRemoveAll(pDevIns);
    44654474                    iommuAmdIotlbRemoveAll(pDevIns);
    4466                     IOMMU_UNLOCK(pDevIns);
    44674475                    return VINF_SUCCESS;
    44684476                }
     
    44944502static DECLCALLBACK(int) iommuAmdR3CmdThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
    44954503{
    4496     PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     4504    PIOMMU   pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     4505    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
    44974506
    44984507    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     
    45364545         *        save on host memory a bit, we could (once PGM has the necessary APIs)
    45374546         *        lock the page mappings page mappings and access them directly. */
    4538         IOMMU_LOCK(pDevIns);
     4547        IOMMU_LOCK(pDevIns, pThisCC);
    45394548
    45404549        IOMMU_STATUS_T const Status = iommuAmdGetStatus(pThis);
     
    45624571
    45634572                    /* Allow IOMMU to do other work while we process commands. */
    4564                     IOMMU_UNLOCK(pDevIns);
     4573                    IOMMU_UNLOCK(pDevIns, pThisCC);
    45654574
    45664575                    /* Process the fetched commands. */
     
    45984607                    iommuAmdCmdHwErrorEventRaise(pDevIns, &EvtCmdHwErr);
    45994608
    4600                     IOMMU_UNLOCK(pDevIns);
     4609                    IOMMU_UNLOCK(pDevIns, pThisCC);
    46014610                }
    46024611            }
    46034612            else
    4604                 IOMMU_UNLOCK(pDevIns);
     4613                IOMMU_UNLOCK(pDevIns, pThisCC);
    46054614        }
    46064615        else
    4607             IOMMU_UNLOCK(pDevIns);
     4616            IOMMU_UNLOCK(pDevIns, pThisCC);
    46084617    }
    46094618
     
    46684677    }
    46694678
    4670     IOMMU_LOCK(pDevIns);
     4679    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
     4680    IOMMU_LOCK(pDevIns, pThisCC);
    46714681
    46724682    VBOXSTRICTRC rcStrict = VERR_IOMMU_IPE_3;
     
    47484758    }
    47494759
    4750     IOMMU_UNLOCK(pDevIns);
     4760    IOMMU_UNLOCK(pDevIns, pThisCC);
    47514761
    47524762    Log3Func(("uAddress=%#x (cb=%u) with %#x. rc=%Rrc\n", uAddress, cb, u32Value, VBOXSTRICTRC_VAL(rcStrict)));
     
    54005410        {
    54015411            DTE_T Dte;
    5402             IOMMU_LOCK_NORET(pDevIns);
    54035412            rc = iommuAmdDteRead(pDevIns, uDevId, IOMMUOP_TRANSLATE_REQ,  &Dte);
    5404             IOMMU_UNLOCK(pDevIns);
    54055413            if (RT_SUCCESS(rc))
    54065414            {
     
    54375445            Args.pHlp      = pHlp;
    54385446            Args.uDomainId = uDomainId;
    5439             IOMMU_LOCK_NORET(pDevIns);
     5447
     5448            IOMMU_LOCK_CACHE_NORET(pDevIns, pThis);
    54405449            RTAvlU64DoWithAll(&pThis->TreeIotlbe, true /* fFromLeft */, iommuAmdR3IotlbEntryInfo, &Args);
    5441             IOMMU_UNLOCK(pDevIns);
     5450            IOMMU_UNLOCK_CACHE(pDevIns, pThis);
    54425451        }
    54435452        else
     
    55625571     */
    55635572    PIOMMU     pThis   = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     5573    PIOMMUCC   pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
    55645574    PPDMPCIDEV pPciDev = pDevIns->apPciDevs[0];
    55655575    PDMPCIDEV_ASSERT_VALID(pDevIns, pPciDev);
    55665576
    5567     IOMMU_LOCK_NORET(pDevIns);
     5577    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    55685578
    55695579    LogFlowFunc(("\n"));
     
    56385648    PDMPciDevSetCommand(pPciDev, VBOX_PCI_COMMAND_MASTER);
    56395649
    5640     IOMMU_UNLOCK(pDevIns);
     5650    IOMMU_UNLOCK(pDevIns, pThisCC);
     5651
     5652#ifdef IOMMU_WITH_IOTLBE_CACHE
     5653    iommuAmdDteCacheRemoveAll(pDevIns);
     5654    iommuAmdIotlbRemoveAll(pDevIns);
     5655#endif
    56415656}
    56425657
     
    56485663{
    56495664    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
    5650     PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     5665    PIOMMU    pThis  = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
     5666    PIOMMUCC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PIOMMUCC);
    56515667    LogFlowFunc(("\n"));
    56525668
    5653     IOMMU_LOCK_NORET(pDevIns);
     5669    IOMMU_LOCK_NORET(pDevIns, pThisCC);
    56545670
    56555671    /* Close the command thread semaphore. */
     
    56715687    if (pThis->paIotlbes)
    56725688    {
    5673         iommuAmdIotlbRemoveAll(pDevIns);
    56745689        PDMDevHlpMMHeapFree(pDevIns, pThis->paIotlbes);
    56755690        pThis->paIotlbes = NULL;
     
    56775692#endif
    56785693
    5679     IOMMU_UNLOCK(pDevIns);
     5694    IOMMU_UNLOCK(pDevIns, pThisCC);
    56805695    return VINF_SUCCESS;
    56815696}
     
    57205735
    57215736    /*
     5737     * We will use PDM's critical section (via helpers) for the IOMMU device.
     5738     */
     5739    rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     5740    AssertRCReturn(rc, rc);
     5741
     5742    /*
    57225743     * Initialize read-only PCI configuration space.
    57235744     */
     
    59155936
    59165937#ifdef IOMMU_WITH_IOTLBE_CACHE
     5938    /*
     5939     * Initialize the critsect of the cache.
     5940     */
     5941    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSectCache, RT_SRC_POS, "IOMMUCache-#%u", pDevIns->iInstance);
     5942    AssertLogRelRCReturn(rc, rc);
     5943
    59175944    /*
    59185945     * Allocate the level 1 cache (device ID to domain ID mapping).
     
    60366063    pThisCC->CTX_SUFF(pDevIns) = pDevIns;
    60376064
     6065    /* We will use PDM's critical section (via helpers) for the IOMMU device. */
     6066    int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     6067    AssertRCReturn(rc, rc);
     6068
    60386069    /* Set up the MMIO RZ handlers. */
    6039     int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, iommuAmdMmioWrite, iommuAmdMmioRead, NULL /* pvUser */);
     6070    rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, iommuAmdMmioWrite, iommuAmdMmioRead, NULL /* pvUser */);
    60406071    AssertRCReturn(rc, rc);
    60416072
     
    60516082    rc = PDMDevHlpIommuSetUpContext(pDevIns, &IommuReg, &pThisCC->CTX_SUFF(pIommuHlp));
    60526083    AssertRCReturn(rc, rc);
    6053 
     6084    AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp), VERR_IOMMU_IPE_1);
     6085    AssertReturn(pThisCC->CTX_SUFF(pIommuHlp)->u32Version == CTX_SUFF(PDM_IOMMUHLP)_VERSION, VERR_VERSION_MISMATCH);
     6086    AssertReturn(pThisCC->CTX_SUFF(pIommuHlp)->u32TheEnd  == CTX_SUFF(PDM_IOMMUHLP)_VERSION, VERR_VERSION_MISMATCH);
     6087    AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnLock,   VERR_INVALID_POINTER);
     6088    AssertPtrReturn(pThisCC->CTX_SUFF(pIommuHlp)->pfnUnlock, VERR_INVALID_POINTER);
    60546089    return VINF_SUCCESS;
    60556090}
  • trunk/src/VBox/VMM/VMMR0/PDMR0DevHlp.cpp

    r87478 r87691  
    16651665 */
    16661666
     1667/** @interface_method_impl{PDMIOMMUHLPR0,pfnLock} */
     1668static DECLCALLBACK(int) pdmR0IommuHlp_Lock(PPDMDEVINS pDevIns, int rc)
     1669{
     1670    PDMDEV_ASSERT_DEVINS(pDevIns);
     1671    return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
     1672}
     1673
     1674
     1675/** @interface_method_impl{PDMIOMMUHLPR0,pfnUnlock} */
     1676static DECLCALLBACK(void) pdmR0IommuHlp_Unlock(PPDMDEVINS pDevIns)
     1677{
     1678    PDMDEV_ASSERT_DEVINS(pDevIns);
     1679    pdmUnlock(pDevIns->Internal.s.pGVM);
     1680}
     1681
     1682
    16671683/**
    16681684 * The Ring-0 IOMMU Helper Callbacks.
     
    16711687{
    16721688    PDM_IOMMUHLPR0_VERSION,
     1689    pdmR0IommuHlp_Lock,
     1690    pdmR0IommuHlp_Unlock,
    16731691    PDM_IOMMUHLPR0_VERSION, /* the end */
    16741692};
  • trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp

    r87477 r87691  
    260260
    261261
     262/** @name Ring-3 IOMMU Helpers
     263 * @{
     264 */
     265
     266/** @interface_method_impl{PDMIOMMUHLPR3,pfnLock} */
     267static DECLCALLBACK(int) pdmR3IommuHlp_Lock(PPDMDEVINS pDevIns, int rc)
     268{
     269    PDMDEV_ASSERT_DEVINS(pDevIns);
     270    LogFlowFunc(("caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     271    return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
     272}
     273
     274
     275/** @interface_method_impl{PDMIOMMUHLPR3,pfnUnlock} */
     276static DECLCALLBACK(void) pdmR3IommuHlp_Unlock(PPDMDEVINS pDevIns)
     277{
     278    PDMDEV_ASSERT_DEVINS(pDevIns);
     279    LogFlowFunc(("caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
     280    pdmUnlock(pDevIns->Internal.s.pVMR3);
     281}
     282
     283
    262284/**
    263285 * IOMMU Device Helpers.
     
    266288{
    267289    PDM_IOMMUHLPR3_VERSION,
     290    pdmR3IommuHlp_Lock,
     291    pdmR3IommuHlp_Unlock,
    268292    PDM_IOMMUHLPR3_VERSION /* the end */
    269293};
     294
     295/** @} */
    270296
    271297
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