VirtualBox

Changeset 84292 in vbox for trunk


Ignore:
Timestamp:
May 13, 2020 4:06:42 PM (5 years ago)
Author:
vboxsync
Message:

AMD IOMMU: bugref:9654 Asynchronous IOMMU command processing.

File:
1 edited

Legend:

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

    r84291 r84292  
    489489 * This will make a long jump to ring-3 to acquire the lock if necessary.
    490490 */
    491 #define IOMMU_LOCK(a_pDevIns, a_pThis)  \
     491#define IOMMU_LOCK(a_pDevIns)  \
    492492    do { \
    493         NOREF(pThis); \
    494493        int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS); \
    495494        if (RT_LIKELY(rcLock == VINF_SUCCESS)) \
     
    500499
    501500/**
    502  * Acquires the IOMMU PDM lock (no return, only asserts on failure).
     501 * Acquires the IOMMU PDM lock (asserts on failure rather than returning an error).
    503502 * This will make a long jump to ring-3 to acquire the lock if necessary.
    504503 */
    505 #define IOMMU_LOCK_NORET(a_pDevIns, a_pThis)  \
     504#define IOMMU_LOCK_NORET(a_pDevIns)  \
    506505    do { \
    507         NOREF(pThis); \
    508506        int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS); \
    509507        AssertRC(rcLock); \
     
    513511 * Releases the IOMMU PDM lock.
    514512 */
    515 #define IOMMU_UNLOCK(a_pDevIns, a_pThis) \
     513#define IOMMU_UNLOCK(a_pDevIns) \
    516514    do { \
    517515        PDMDevHlpCritSectLeave((a_pDevIns), (a_pDevIns)->CTX_SUFF(pCritSectRo)); \
     
    35453543    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    35463544
    3547     IOMMU_LOCK(pDevIns, pThis);
     3545    IOMMU_ASSERT_LOCKED(pDevIns);
    35483546
    35493547    /* Check if event logging is active and the log has not overflowed. */
     
    35933591        }
    35943592    }
    3595 
    3596     IOMMU_UNLOCK(pDevIns, pThis);
    35973593}
    35983594
     
    36083604static void iommuAmdSetHwError(PPDMDEVINS pDevIns, PCEVT_GENERIC_T pEvent)
    36093605{
     3606    IOMMU_ASSERT_LOCKED(pDevIns);
     3607
    36103608    PIOMMU pThis = PDMDEVINS_2_DATA(pDevIns, PIOMMU);
    3611     IOMMU_LOCK_NORET(pDevIns, pThis);
    36123609    if (pThis->ExtFeat.n.u1HwErrorSup)
    36133610    {
     
    36193616        Assert(pThis->HwEvtHi.n.u4EvtCode == IOMMU_EVT_DEV_TAB_HW_ERROR);
    36203617    }
    3621     IOMMU_UNLOCK(pDevIns, pThis);
    36223618}
    36233619
     
    36393635    pEvtPageTabHwErr->n.u16DevId           = uDevId;
    36403636    pEvtPageTabHwErr->n.u16DomainOrPasidLo = uDomainId;
    3641     //pEvtPageTabHwErr->n.u1GuestOrNested  = 0;
     3637    pEvtPageTabHwErr->n.u1GuestOrNested    = 0;
    36423638    pEvtPageTabHwErr->n.u1Interrupt        = RT_BOOL(enmOp == IOMMUOP_INTR_REQ);
    36433639    pEvtPageTabHwErr->n.u1ReadWrite        = RT_BOOL(enmOp == IOMMUOP_MEM_WRITE);
     
    36563652 * @param   pEvtPageTabHwErr    The page table hardware error event.
    36573653 * @param   enmEvtType          The hardware error event type.
     3654 *
     3655 * @thread  Any.
    36583656 */
    36593657static void iommuAmdRaisePageTabHwErrorEvent(PPDMDEVINS pDevIns, IOMMUOP enmOp, PEVT_PAGE_TAB_HW_ERR_T pEvtPageTabHwErr,
     
    36623660    AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_PAGE_TAB_HW_ERR_T));
    36633661    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtPageTabHwErr;
     3662
     3663    IOMMU_LOCK_NORET(pDevIns);
    36643664
    36653665    iommuAmdSetHwError(pDevIns, (PCEVT_GENERIC_T)pEvent);
     
    36683668        iommuAmdSetPciTargetAbort(pDevIns);
    36693669
     3670    IOMMU_UNLOCK(pDevIns);
     3671
    36703672    Log((IOMMU_LOG_PFX ": Raised PAGE_TAB_HARDWARE_ERROR. uDevId=%#x uDomainId=%#x GCPhysPtEntity=%#RGp enmOp=%u enmType=%u\n",
    36713673         pEvtPageTabHwErr->n.u16DevId, pEvtPageTabHwErr->n.u16DomainOrPasidLo, pEvtPageTabHwErr->n.u64Addr, enmOp, enmEvtType));
     
    36963698 * @param   pEvtCmdHwErr    The command hardware error event.
    36973699 * @param   enmEvtType      The hardware error event type.
     3700 *
     3701 * @thread  Any.
    36983702 */
    36993703static void iommuAmdRaiseCmdHwErrorEvent(PPDMDEVINS pDevIns, PCEVT_CMD_HW_ERR_T pEvtCmdHwErr, EVT_HW_ERR_TYPE_T enmEvtType)
     
    37013705    AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_CMD_HW_ERR_T));
    37023706    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtCmdHwErr;
     3707
     3708    IOMMU_LOCK_NORET(pDevIns);
    37033709
    37043710    iommuAmdSetHwError(pDevIns, (PCEVT_GENERIC_T)pEvent);
    37053711    iommuAmdWriteEvtLogEntry(pDevIns, (PCEVT_GENERIC_T)pEvent);
    37063712    iommuAmdHaltCmdProcessing(pDevIns);
     3713
     3714    IOMMU_UNLOCK(pDevIns);
    37073715
    37083716    Log((IOMMU_LOG_PFX ": Raised COMMAND_HARDWARE_ERROR. GCPhysCmd=%#RGp enmType=%u\n", pEvtCmdHwErr->n.u64Addr, enmEvtType));
     
    37423750 * @param   pEvtDevTabHwErr     The device table hardware error event.
    37433751 * @param   enmEvtType          The hardware error event type.
     3752 *
     3753 * @thread  Any.
    37443754 */
    37453755static void iommuAmdRaiseDevTabHwErrorEvent(PPDMDEVINS pDevIns, IOMMUOP enmOp, PEVT_DEV_TAB_HW_ERROR_T pEvtDevTabHwErr,
     
    37483758    AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_DEV_TAB_HW_ERROR_T));
    37493759    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtDevTabHwErr;
     3760
     3761    IOMMU_LOCK_NORET(pDevIns);
     3762
    37503763    iommuAmdSetHwError(pDevIns, (PCEVT_GENERIC_T)pEvent);
    37513764    iommuAmdWriteEvtLogEntry(pDevIns, (PCEVT_GENERIC_T)pEvent);
    37523765    if (enmOp != IOMMUOP_CMD)
    37533766        iommuAmdSetPciTargetAbort(pDevIns);
     3767
     3768    IOMMU_UNLOCK(pDevIns);
    37543769
    37553770    Log((IOMMU_LOG_PFX ": Raised DEV_TAB_HARDWARE_ERROR. uDevId=%#x GCPhysDte=%#RGp enmOp=%u enmType=%u\n",
     
    37943809 * @param   pEvtIllegalDte  The illegal device table entry event.
    37953810 * @param   enmEvtType      The illegal DTE event type.
     3811 *
     3812 * @thread  Any.
    37963813 */
    37973814static void iommuAmdRaiseIllegalDteEvent(PPDMDEVINS pDevIns, IOMMUOP enmOp, PCEVT_ILLEGAL_DTE_T pEvtIllegalDte,
     
    38003817    AssertCompile(sizeof(EVT_GENERIC_T) == sizeof(EVT_ILLEGAL_DTE_T));
    38013818    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtIllegalDte;
     3819
     3820    IOMMU_LOCK_NORET(pDevIns);
     3821
    38023822    iommuAmdWriteEvtLogEntry(pDevIns, pEvent);
    38033823    if (enmOp != IOMMUOP_CMD)
    38043824        iommuAmdSetPciTargetAbort(pDevIns);
     3825
     3826    IOMMU_UNLOCK(pDevIns);
    38053827
    38063828    Log((IOMMU_LOG_PFX ": Raised ILLEGAL_DTE_EVENT. uDevId=%#x uIova=%#RX64 enmOp=%u enmEvtType=%u\n", pEvtIllegalDte->n.u16DevId,
     
    38683890    PCEVT_GENERIC_T pEvent = (PCEVT_GENERIC_T)pEvtIoPageFault;
    38693891
     3892    IOMMU_LOCK_NORET(pDevIns);
     3893
    38703894    bool fSuppressEvtLogging = false;
    38713895    if (   enmOp == IOMMUOP_MEM_READ
     
    39673991        }
    39683992    }
     3993
     3994    IOMMU_UNLOCK(pDevIns);
    39693995}
    39703996
     
    46304656        if (Status.u64 & IOMMU_STATUS_CMD_BUF_RUNNING)
    46314657        {
    4632             IOMMU_LOCK(pDevIns, pThis);
     4658            IOMMU_LOCK(pDevIns);
    46334659
    46344660            uint32_t const cbCmdBuf = iommuAmdGetBufLength(pThis->CmdBufBaseAddr.n.u4Len);
     
    46484674
    46494675                    /* Process the fetched command. */
    4650                     IOMMU_UNLOCK(pDevIns, pThis);
     4676                    IOMMU_UNLOCK(pDevIns);
    46514677                    rc = iommuAmdR3ProcessCmd(pDevIns, &Cmd);
    4652                     IOMMU_LOCK(pDevIns, pThis);
     4678                    IOMMU_LOCK(pDevIns);
    46534679                    if (RT_SUCCESS(rc))
    46544680                    { /* likely */ }
     
    46654691                    /* Reporting this as a "data error". Maybe target abort is more appropriate? */
    46664692                    EVT_CMD_HW_ERR_T EvtCmdHwErr;
    4667                     iommuAmdInitCmdHwErrorEvent(GCPhysCmd, HWEVTTYPE_DATA_ERROR, & EvtCmdHwErr);
     4693                    iommuAmdInitCmdHwErrorEvent(GCPhysCmd, HWEVTTYPE_DATA_ERROR, &EvtCmdHwErr);
    46684694                    iommuAmdRaiseCmdHwErrorEvent(pDevIns, &EvtCmdHwErr, kHwErrType_PoisonedData);
    46694695                    break;
     
    46714697            }
    46724698
    4673             IOMMU_UNLOCK(pDevIns, pThis);
     4699            IOMMU_UNLOCK(pDevIns);
    46744700        }
    46754701    }
     
    47324758    }
    47334759
    4734     IOMMU_LOCK(pDevIns, pThis);
     4760    IOMMU_LOCK(pDevIns);
    47354761
    47364762    VBOXSTRICTRC rcStrict;
     
    47834809    }
    47844810
    4785     IOMMU_UNLOCK(pDevIns, pThis);
     4811    IOMMU_UNLOCK(pDevIns);
    47864812
    47874813    Log3((IOMMU_LOG_PFX ": PCI config write: %#x -> To %#x (%u) %Rrc\n", u32Value, uAddress, cb, VBOXSTRICTRC_VAL(rcStrict)));
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