VirtualBox

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


Ignore:
Timestamp:
Jun 9, 2018 3:11:13 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
122975
Message:

NEM,EM: Generic optimization of I/O port accesses that have to be executed in ring-3. Only NEM uses the feature for now. bugref:9044 bugref:9193

File:
1 edited

Legend:

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

    r72489 r72490  
    819819
    820820/**
     821 * Handle pending ring-3 I/O port write.
     822 *
     823 * This is in response to a VINF_EM_PENDING_R3_IOPORT_WRITE status code returned
     824 * by EMRZSetPendingIoPortWrite() in ring-0 or raw-mode context.
     825 *
     826 * @returns Strict VBox status code.
     827 * @param   pVM     The cross context VM structure.
     828 * @param   pVCpu   The cross context virtual CPU structure.
     829 */
     830VBOXSTRICTRC emR3ExecutePendingIoPortWrite(PVM pVM, PVMCPU pVCpu)
     831{
     832    CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS);
     833
     834    /* Get and clear the pending data. */
     835    RTIOPORT const uPort   = pVCpu->em.s.PendingIoPortAccess.uPort;
     836    uint32_t const uValue  = pVCpu->em.s.PendingIoPortAccess.uValue;
     837    uint8_t  const cbValue = pVCpu->em.s.PendingIoPortAccess.cbValue;
     838    uint8_t  const cbInstr = pVCpu->em.s.PendingIoPortAccess.cbInstr;
     839    pVCpu->em.s.PendingIoPortAccess.cbValue = 0;
     840
     841    /* Assert sanity. */
     842    switch (cbValue)
     843    {
     844        case 1:     Assert(!(cbValue & UINT32_C(0xffffff00))); break;
     845        case 2:     Assert(!(cbValue & UINT32_C(0xffff0000))); break;
     846        case 4:     break;
     847        default:    AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_EM_INTERNAL_ERROR);
     848    }
     849    AssertReturn(cbInstr <= 15 && cbInstr >= 1, VERR_EM_INTERNAL_ERROR);
     850
     851    /* Do the work.*/
     852    VBOXSTRICTRC rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, uValue, cbValue);
     853    LogFlow(("EM/OUT: %#x, %#x LB %u -> %Rrc\n", uPort, uValue, cbValue, VBOXSTRICTRC_VAL(rcStrict) ));
     854    if (IOM_SUCCESS(rcStrict))
     855    {
     856        pVCpu->cpum.GstCtx.rip += cbInstr;
     857        pVCpu->cpum.GstCtx.rflags.Bits.u1RF = 0;
     858    }
     859    return rcStrict;
     860}
     861
     862
     863/**
     864 * Handle pending ring-3 I/O port write.
     865 *
     866 * This is in response to a VINF_EM_PENDING_R3_IOPORT_WRITE status code returned
     867 * by EMRZSetPendingIoPortRead() in ring-0 or raw-mode context.
     868 *
     869 * @returns Strict VBox status code.
     870 * @param   pVM     The cross context VM structure.
     871 * @param   pVCpu   The cross context virtual CPU structure.
     872 */
     873VBOXSTRICTRC emR3ExecutePendingIoPortRead(PVM pVM, PVMCPU pVCpu)
     874{
     875    CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_RAX);
     876
     877    /* Get and clear the pending data. */
     878    RTIOPORT const uPort   = pVCpu->em.s.PendingIoPortAccess.uPort;
     879    uint8_t  const cbValue = pVCpu->em.s.PendingIoPortAccess.cbValue;
     880    uint8_t  const cbInstr = pVCpu->em.s.PendingIoPortAccess.cbInstr;
     881    pVCpu->em.s.PendingIoPortAccess.cbValue = 0;
     882
     883    /* Assert sanity. */
     884    switch (cbValue)
     885    {
     886        case 1:     break;
     887        case 2:     break;
     888        case 4:     break;
     889        default:    AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_EM_INTERNAL_ERROR);
     890    }
     891    AssertReturn(pVCpu->em.s.PendingIoPortAccess.uValue == UINT32_C(0x52454144) /* READ*/, VERR_EM_INTERNAL_ERROR);
     892    AssertReturn(cbInstr <= 15 && cbInstr >= 1, VERR_EM_INTERNAL_ERROR);
     893
     894    /* Do the work.*/
     895    uint32_t uValue = 0;
     896    VBOXSTRICTRC rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &uValue, cbValue);
     897    LogFlow(("EM/IN: %#x LB %u -> %Rrc, %#x\n", uPort, cbValue, VBOXSTRICTRC_VAL(rcStrict), uValue ));
     898    if (IOM_SUCCESS(rcStrict))
     899    {
     900        if (cbValue == 4)
     901            pVCpu->cpum.GstCtx.rax = uValue;
     902        else if (cbValue == 2)
     903            pVCpu->cpum.GstCtx.ax = (uint16_t)uValue;
     904        else
     905            pVCpu->cpum.GstCtx.al = (uint8_t)uValue;
     906        pVCpu->cpum.GstCtx.rip += cbInstr;
     907        pVCpu->cpum.GstCtx.rflags.Bits.u1RF = 0;
     908    }
     909    return rcStrict;
     910}
     911
     912
     913/**
    821914 * Debug loop.
    822915 *
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