VirtualBox

Changeset 60847 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
May 5, 2016 3:24:46 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
107055
Message:

IOM: New way of defer RC+R0 I/O port writes, prepping for MMIO writes.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r60804 r60847  
    15911591        rc = VBOXSTRICTRC_TODO(IEMR3DoPendingAction(pVCpu, rc));
    15921592
     1593    /* IOM has pending work (comitting an I/O or MMIO write). */
     1594    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_IOM))
     1595        rc = VBOXSTRICTRC_TODO(IOMR3ProcessForceFlag(pVM, pVCpu, rc));
     1596
    15931597#ifdef VBOX_WITH_RAW_MODE
    15941598    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION))
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r58909 r60847  
    16461646
    16471647/**
     1648 * Handles the unlikely and probably fatal merge cases.
     1649 *
     1650 * @returns Merged status code.
     1651 * @param   rcStrict        Current EM status code.
     1652 * @param   rcStrictCommit  The IOM I/O or MMIO write commit status to merge
     1653 *                          with @a rcStrict.
     1654 * @param   rcIom           For logging purposes only.
     1655 * @param   pVCpu           The cross context virtual CPU structure of the
     1656 *                          calling EMT.  For logging purposes.
     1657 */
     1658DECL_NO_INLINE(static, VBOXSTRICTRC) iomR3MergeStatusSlow(VBOXSTRICTRC rcStrict, VBOXSTRICTRC rcStrictCommit,
     1659                                                          int rcIom, PVMCPU pVCpu)
     1660{
     1661    if (RT_FAILURE_NP(rcStrict))
     1662        return rcStrict;
     1663
     1664    if (RT_FAILURE_NP(rcStrictCommit))
     1665        return rcStrictCommit;
     1666
     1667    if (rcStrict == rcStrictCommit)
     1668        return rcStrictCommit;
     1669
     1670    AssertLogRelMsgFailed(("rcStrictCommit=%Rrc rcStrict=%Rrc IOPort={%#06x<-%#xx/%u} MMIO={%RGp<-%.*Rhxs} (rcIom=%Rrc)\n",
     1671                           VBOXSTRICTRC_VAL(rcStrictCommit), VBOXSTRICTRC_VAL(rcStrict),
     1672                           pVCpu->iom.s.PendingIOPortWrite.IOPort,
     1673                           pVCpu->iom.s.PendingIOPortWrite.u32Value, pVCpu->iom.s.PendingIOPortWrite.cbValue,
     1674                           pVCpu->iom.s.PendingMmioWrite.GCPhys,
     1675                           pVCpu->iom.s.PendingMmioWrite.cbValue, &pVCpu->iom.s.PendingMmioWrite.abValue[0], rcIom));
     1676    return VERR_IOM_FF_STATUS_IPE;
     1677}
     1678
     1679
     1680/**
     1681 * Helper for IOMR3ProcessForceFlag.
     1682 *
     1683 * @returns Merged status code.
     1684 * @param   rcStrict        Current EM status code.
     1685 * @param   rcStrictCommit  The IOM I/O or MMIO write commit status to merge
     1686 *                          with @a rcStrict.
     1687 * @param   rcIom           Either VINF_IOM_R3_IOPORT_COMMIT_WRITE or
     1688 *                          VINF_IOM_R3_MMIO_COMMIT_WRITE.
     1689 * @param   pVCpu           The cross context virtual CPU structure of the
     1690 *                          calling EMT.
     1691 */
     1692DECLINLINE(VBOXSTRICTRC) iomR3MergeStatus(VBOXSTRICTRC rcStrict, VBOXSTRICTRC rcStrictCommit, int rcIom, PVMCPU pVCpu)
     1693{
     1694    /* Simple. */
     1695    if (RT_LIKELY(rcStrict == rcIom || rcStrict == VINF_EM_RAW_TO_R3 || rcStrict == VINF_SUCCESS))
     1696        return rcStrictCommit;
     1697
     1698    /* EM scheduling status codes. */
     1699    if (RT_LIKELY(   rcStrict >= VINF_EM_FIRST
     1700                  && rcStrict <= VINF_EM_LAST))
     1701    {
     1702        if (RT_LIKELY(   rcStrictCommit >= VINF_EM_FIRST
     1703                      && rcStrictCommit <= VINF_EM_LAST))
     1704            return rcStrict < rcStrictCommit ? rcStrict : rcStrictCommit;
     1705    }
     1706
     1707    /* Unlikely */
     1708    return iomR3MergeStatusSlow(rcStrict, rcStrictCommit, rcIom, pVCpu);
     1709}
     1710
     1711
     1712/**
     1713 * Called by force-flag handling code when VMCPU_FF_IOM is set.
     1714 *
     1715 * @returns Merge between @a rcStrict and what the commit operation returned.
     1716 * @param   pVM         The cross context VM structure.
     1717 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     1718 * @param   rcStrict    The status code returned by ring-0 or raw-mode.
     1719 * @thread  EMT(pVCpu)
     1720 *
     1721 * @remarks The VMCPU_FF_IOM flag is handled before the status codes by EM, so
     1722 *          we're very likely to see @a rcStrict set to
     1723 *          VINF_IOM_R3_IOPORT_COMMIT_WRITE and VINF_IOM_R3_MMIO_COMMIT_WRITE
     1724 *          here.
     1725 */
     1726VMMR3_INT_DECL(VBOXSTRICTRC) IOMR3ProcessForceFlag(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rcStrict)
     1727{
     1728    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_IOM);
     1729    Assert(pVCpu->iom.s.PendingIOPortWrite.cbValue || pVCpu->iom.s.PendingMmioWrite.cbValue);
     1730
     1731    if (pVCpu->iom.s.PendingIOPortWrite.cbValue)
     1732    {
     1733        VBOXSTRICTRC rcStrictCommit = IOMIOPortWrite(pVM, pVCpu, pVCpu->iom.s.PendingIOPortWrite.IOPort,
     1734                                                     pVCpu->iom.s.PendingIOPortWrite.u32Value,
     1735                                                     pVCpu->iom.s.PendingIOPortWrite.cbValue);
     1736        pVCpu->iom.s.PendingIOPortWrite.cbValue = 0;
     1737        rcStrict = iomR3MergeStatus(rcStrict, rcStrictCommit, VINF_IOM_R3_IOPORT_COMMIT_WRITE, pVCpu);
     1738    }
     1739
     1740
     1741    if (pVCpu->iom.s.PendingMmioWrite.cbValue)
     1742    {
     1743        /** @todo Try optimize this some day?  Currently easier and correcter to
     1744         *        involve PGM here since we never know if the MMIO area is still mapped
     1745         *        to the same location as when we wrote to it in RC/R0 context. */
     1746        VBOXSTRICTRC rcStrictCommit = PGMPhysWrite(pVM, pVCpu->iom.s.PendingMmioWrite.GCPhys,
     1747                                                   pVCpu->iom.s.PendingMmioWrite.abValue, pVCpu->iom.s.PendingMmioWrite.cbValue,
     1748                                                   PGMACCESSORIGIN_IOM);
     1749        pVCpu->iom.s.PendingIOPortWrite.cbValue = 0;
     1750        rcStrict = iomR3MergeStatus(rcStrict, rcStrictCommit, VINF_IOM_R3_MMIO_COMMIT_WRITE, pVCpu);
     1751    }
     1752
     1753    return rcStrict;
     1754}
     1755
     1756
     1757/**
    16481758 * Notification from DBGF that the number of active I/O port or MMIO
    16491759 * breakpoints has change.
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r60377 r60847  
    463463    STAM_REG(pVM, &pVM->vmm.s.StatRZRetIORead,              STAMTYPE_COUNTER, "/VMM/RZRet/IORead",              STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_IOPORT_READ returns.");
    464464    STAM_REG(pVM, &pVM->vmm.s.StatRZRetIOWrite,             STAMTYPE_COUNTER, "/VMM/RZRet/IOWrite",             STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_IOPORT_WRITE returns.");
     465    STAM_REG(pVM, &pVM->vmm.s.StatRZRetIOCommitWrite,       STAMTYPE_COUNTER, "/VMM/RZRet/IOCommitWrite",       STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_IOPORT_COMMIT_WRITE returns.");
    465466    STAM_REG(pVM, &pVM->vmm.s.StatRZRetMMIORead,            STAMTYPE_COUNTER, "/VMM/RZRet/MMIORead",            STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_MMIO_READ returns.");
    466467    STAM_REG(pVM, &pVM->vmm.s.StatRZRetMMIOWrite,           STAMTYPE_COUNTER, "/VMM/RZRet/MMIOWrite",           STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_MMIO_WRITE returns.");
     468    STAM_REG(pVM, &pVM->vmm.s.StatRZRetMMIOCommitWrite,     STAMTYPE_COUNTER, "/VMM/RZRet/MMIOCommitWrite",     STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_MMIO_COMMIT_WRITE returns.");
    467469    STAM_REG(pVM, &pVM->vmm.s.StatRZRetMMIOReadWrite,       STAMTYPE_COUNTER, "/VMM/RZRet/MMIOReadWrite",       STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_MMIO_READ_WRITE returns.");
    468470    STAM_REG(pVM, &pVM->vmm.s.StatRZRetMMIOPatchRead,       STAMTYPE_COUNTER, "/VMM/RZRet/MMIOPatchRead",       STAMUNIT_OCCURENCES, "Number of VINF_IOM_HC_MMIO_PATCH_READ returns.");
     
    482484    STAM_REG(pVM, &pVM->vmm.s.StatRZRetPatchIretIRQ,        STAMTYPE_COUNTER, "/VMM/RZRet/PatchIret",           STAMUNIT_OCCURENCES, "Number of VINF_PATM_PENDING_IRQ_AFTER_IRET returns.");
    483485    STAM_REG(pVM, &pVM->vmm.s.StatRZRetRescheduleREM,       STAMTYPE_COUNTER, "/VMM/RZRet/ScheduleREM",         STAMUNIT_OCCURENCES, "Number of VINF_EM_RESCHEDULE_REM returns.");
    484     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3,                STAMTYPE_COUNTER, "/VMM/RZRet/ToR3",                STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    485     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Unknown,         STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Unknown",        STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    486     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3TMVirt,          STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/TMVirt",         STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    487     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3HandyPages,      STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Handy",          STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    488     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3PDMQueues,       STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/PDMQueue",       STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    489     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Rendezvous,      STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Rendezvous",     STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    490     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Timer,           STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Timer",          STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    491     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3DMA,             STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/DMA",            STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
    492     STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3CritSect,        STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/CritSect",       STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
     486    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Total,           STAMTYPE_COUNTER, "/VMM/RZRet/ToR3",                STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns.");
     487    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Unknown,         STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Unknown",        STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns without responsible force flag.");
     488    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3FF,              STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/ToR3",           STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VMCPU_FF_TO_R3.");
     489    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3TMVirt,          STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/TMVirt",         STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VM_FF_TM_VIRTUAL_SYNC.");
     490    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3HandyPages,      STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Handy",          STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VM_FF_PGM_NEED_HANDY_PAGES.");
     491    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3PDMQueues,       STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/PDMQueue",       STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VM_FF_PDM_QUEUES.");
     492    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Rendezvous,      STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Rendezvous",     STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VM_FF_EMT_RENDEZVOUS.");
     493    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Timer,           STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/Timer",          STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VMCPU_FF_TIMER.");
     494    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3DMA,             STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/DMA",            STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VM_FF_PDM_DMA.");
     495    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3CritSect,        STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/CritSect",       STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VMCPU_FF_PDM_CRITSECT.");
     496    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Iem,             STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/IEM",            STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VMCPU_FF_IEM.");
     497    STAM_REG(pVM, &pVM->vmm.s.StatRZRetToR3Iom,             STAMTYPE_COUNTER, "/VMM/RZRet/ToR3/IOM",            STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TO_R3 returns with VMCPU_FF_IOM.");
    493498    STAM_REG(pVM, &pVM->vmm.s.StatRZRetTimerPending,        STAMTYPE_COUNTER, "/VMM/RZRet/TimerPending",        STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_TIMER_PENDING returns.");
    494499    STAM_REG(pVM, &pVM->vmm.s.StatRZRetInterruptPending,    STAMTYPE_COUNTER, "/VMM/RZRet/InterruptPending",    STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_INTERRUPT_PENDING returns.");
     
    28612866        PRINT_FLAG(VMCPU_FF_,BLOCK_NMIS);
    28622867        PRINT_FLAG(VMCPU_FF_,TO_R3);
     2868        PRINT_FLAG(VMCPU_FF_,IOM);
    28632869#ifdef VBOX_WITH_RAW_MODE
    28642870        PRINT_FLAG(VMCPU_FF_,TRPM_SYNC_IDT);
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