VirtualBox

Changeset 40453 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Mar 13, 2012 6:38:06 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
76810
Message:

EM/IEM/PATM: some refactoring.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r40451 r40453  
    2626#include <VBox/vmm/csam.h>
    2727#include <VBox/vmm/pgm.h>
     28#ifdef VBOX_WITH_IEM
     29# include <VBox/vmm/iem.h>
     30#endif
    2831#include <VBox/vmm/iom.h>
    2932#include <VBox/vmm/stam.h>
     
    488491    LogFlow(("EMInterpretInstruction %RGv fault %RGv\n", (RTGCPTR)pRegFrame->rip, pvFault));
    489492#ifdef VBOX_WITH_IEM
    490     int rc = IEMExecOneEx(pVCpu, pRegFrame, IEM_EXEC_ONE_EX_FLAGS_, pcbSize);
    491     if (RT_FAILURE(rc))
    492         switch (rc)
    493         {
    494             case VERR_IEM_ASPECT_NOT_IMPLEMENTED:
    495             case VERR_IEM_INSTR_NOT_IMPLEMENTED:
    496                 return VERR_EM_INTERPRETER;
    497         }
     493    NOREF(pvFault);
     494    VBOXSTRICTRC rc = IEMExecOneEx(pVCpu, pRegFrame, NULL);
     495    if (RT_UNLIKELY(   rc == VERR_IEM_ASPECT_NOT_IMPLEMENTED
     496                    || rc == VERR_IEM_INSTR_NOT_IMPLEMENTED))
     497        return VERR_EM_INTERPRETER;
    498498    return rc;
    499499#else
     
    545545    LogFlow(("EMInterpretInstructionEx %RGv fault %RGv\n", (RTGCPTR)pRegFrame->rip, pvFault));
    546546#ifdef VBOX_WITH_IEM
    547     int rc = IEMExecOneEx(pVCpu, pRegFrame, IEM_EXEC_ONE_EX_FLAGS_, pcbWritten);
    548     if (RT_FAILURE(rc))
    549         switch (rc)
    550         {
    551             case VERR_IEM_ASPECT_NOT_IMPLEMENTED:
    552             case VERR_IEM_INSTR_NOT_IMPLEMENTED:
    553                 return VERR_EM_INTERPRETER;
    554         }
     547    NOREF(pvFault);
     548    VBOXSTRICTRC rc = IEMExecOneEx(pVCpu, pRegFrame, pcbWritten);
     549    if (RT_UNLIKELY(   rc == VERR_IEM_ASPECT_NOT_IMPLEMENTED
     550                    || rc == VERR_IEM_INSTR_NOT_IMPLEMENTED))
     551        return VERR_EM_INTERPRETER;
    555552    return rc;
    556553#else
     
    609606                                                       RTGCPTR pvFault, EMCODETYPE enmCodeType)
    610607{
    611     STAM_PROFILE_START(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,Emulate), a);
     608    LogFlow(("EMInterpretInstructionDisasState %RGv fault %RGv\n", (RTGCPTR)pRegFrame->rip, pvFault));
     609#ifdef VBOX_WITH_IEM
     610    NOREF(pDis); NOREF(pvFault); NOREF(enmCodeType);
     611    VBOXSTRICTRC rc = IEMExecOneEx(pVCpu, pRegFrame, NULL);
     612    if (RT_UNLIKELY(   rc == VERR_IEM_ASPECT_NOT_IMPLEMENTED
     613                    || rc == VERR_IEM_INSTR_NOT_IMPLEMENTED))
     614        return VERR_EM_INTERPRETER;
     615    return rc;
     616#else
    612617    uint32_t cbIgnored;
    613618    VBOXSTRICTRC rc = emInterpretInstructionCPUOuter(pVCpu, pDis, pRegFrame, pvFault, enmCodeType, &cbIgnored);
    614     STAM_PROFILE_STOP(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,Emulate), a);
    615619    if (RT_SUCCESS(rc))
    616     {
    617620        pRegFrame->rip += pDis->opsize; /* Move on to the next instruction. */
    618         STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,InterpretSucceeded));
    619     }
    620     else
    621         STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,InterpretFailed));
    622621    return rc;
    623 }
    624 
     622#endif
     623}
     624
     625#if defined(IN_RC) /*&& defined(VBOX_WITH_PATM)*/
     626
     627DECLINLINE(int) emRCStackRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, uint32_t cb)
     628{
     629    int rc = MMGCRamRead(pVM, pvDst, (void *)(uintptr_t)GCPtrSrc, cb);
     630    if (RT_LIKELY(rc != VERR_ACCESS_DENIED))
     631        return rc;
     632    return PGMPhysInterpretedReadNoHandlers(pVCpu, pCtxCore, pvDst, GCPtrSrc, cb, /*fMayTrap*/ false);
     633}
     634
     635
     636/**
     637 * Interpret IRET (currently only to V86 code) - PATM only.
     638 *
     639 * @returns VBox status code.
     640 * @param   pVM         The VM handle.
     641 * @param   pVCpu       The VMCPU handle.
     642 * @param   pRegFrame   The register frame.
     643 *
     644 */
     645VMMDECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame)
     646{
     647    RTGCUINTPTR pIretStack = (RTGCUINTPTR)pRegFrame->esp;
     648    RTGCUINTPTR eip, cs, esp, ss, eflags, ds, es, fs, gs, uMask;
     649    int         rc;
     650
     651    Assert(!CPUMIsGuestIn64BitCode(pVCpu, pRegFrame));
     652    /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by
     653     *        this function.  Faire that it may guru on us, thus not converted to
     654     *        IEM. */
     655
     656    rc  = emRCStackRead(pVM, pVCpu, pRegFrame, &eip,      (RTGCPTR)pIretStack      , 4);
     657    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &cs,       (RTGCPTR)(pIretStack + 4), 4);
     658    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &eflags,   (RTGCPTR)(pIretStack + 8), 4);
     659    AssertRCReturn(rc, VERR_EM_INTERPRETER);
     660    AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER);
     661
     662    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &esp,      (RTGCPTR)(pIretStack + 12), 4);
     663    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &ss,       (RTGCPTR)(pIretStack + 16), 4);
     664    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &es,       (RTGCPTR)(pIretStack + 20), 4);
     665    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &ds,       (RTGCPTR)(pIretStack + 24), 4);
     666    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &fs,       (RTGCPTR)(pIretStack + 28), 4);
     667    rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &gs,       (RTGCPTR)(pIretStack + 32), 4);
     668    AssertRCReturn(rc, VERR_EM_INTERPRETER);
     669
     670    pRegFrame->eip = eip & 0xffff;
     671    pRegFrame->cs  = cs;
     672
     673    /* Mask away all reserved bits */
     674    uMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM | X86_EFL_AC | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_ID;
     675    eflags &= uMask;
     676
     677    CPUMRawSetEFlags(pVCpu, pRegFrame, eflags);
     678    Assert((pRegFrame->eflags.u32 & (X86_EFL_IF|X86_EFL_IOPL)) == X86_EFL_IF);
     679
     680    pRegFrame->esp = esp;
     681    pRegFrame->ss  = ss;
     682    pRegFrame->ds  = ds;
     683    pRegFrame->es  = es;
     684    pRegFrame->fs  = fs;
     685    pRegFrame->gs  = gs;
     686
     687    return VINF_SUCCESS;
     688}
     689
     690#endif /* IN_RC && VBOX_WITH_PATM */
    625691#ifndef VBOX_WITH_IEM
    626692
     
    19251991    return VERR_EM_INTERPRETER;
    19261992#endif
    1927 }
    1928 #endif /* IN_RC */
    1929 
    1930 
    1931 #ifdef IN_RC
    1932 /**
    1933  * Interpret IRET (currently only to V86 code)
    1934  *
    1935  * @returns VBox status code.
    1936  * @param   pVM         The VM handle.
    1937  * @param   pVCpu       The VMCPU handle.
    1938  * @param   pRegFrame   The register frame.
    1939  *
    1940  */
    1941 VMMDECL(int) EMInterpretIret(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame)
    1942 {
    1943     RTGCUINTPTR pIretStack = (RTGCUINTPTR)pRegFrame->esp;
    1944     RTGCUINTPTR eip, cs, esp, ss, eflags, ds, es, fs, gs, uMask;
    1945     int         rc;
    1946 
    1947     Assert(!CPUMIsGuestIn64BitCode(pVCpu, pRegFrame));
    1948 
    1949     rc  = emRamRead(pVM, pVCpu, pRegFrame, &eip,      (RTGCPTR)pIretStack      , 4);
    1950     rc |= emRamRead(pVM, pVCpu, pRegFrame, &cs,       (RTGCPTR)(pIretStack + 4), 4);
    1951     rc |= emRamRead(pVM, pVCpu, pRegFrame, &eflags,   (RTGCPTR)(pIretStack + 8), 4);
    1952     AssertRCReturn(rc, VERR_EM_INTERPRETER);
    1953     AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER);
    1954 
    1955     rc |= emRamRead(pVM, pVCpu, pRegFrame, &esp,      (RTGCPTR)(pIretStack + 12), 4);
    1956     rc |= emRamRead(pVM, pVCpu, pRegFrame, &ss,       (RTGCPTR)(pIretStack + 16), 4);
    1957     rc |= emRamRead(pVM, pVCpu, pRegFrame, &es,       (RTGCPTR)(pIretStack + 20), 4);
    1958     rc |= emRamRead(pVM, pVCpu, pRegFrame, &ds,       (RTGCPTR)(pIretStack + 24), 4);
    1959     rc |= emRamRead(pVM, pVCpu, pRegFrame, &fs,       (RTGCPTR)(pIretStack + 28), 4);
    1960     rc |= emRamRead(pVM, pVCpu, pRegFrame, &gs,       (RTGCPTR)(pIretStack + 32), 4);
    1961     AssertRCReturn(rc, VERR_EM_INTERPRETER);
    1962 
    1963     pRegFrame->eip = eip & 0xffff;
    1964     pRegFrame->cs  = cs;
    1965 
    1966     /* Mask away all reserved bits */
    1967     uMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM | X86_EFL_AC | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_ID;
    1968     eflags &= uMask;
    1969 
    1970 #ifndef IN_RING0
    1971     CPUMRawSetEFlags(pVCpu, pRegFrame, eflags);
    1972 #endif
    1973     Assert((pRegFrame->eflags.u32 & (X86_EFL_IF|X86_EFL_IOPL)) == X86_EFL_IF);
    1974 
    1975     pRegFrame->esp = esp;
    1976     pRegFrame->ss  = ss;
    1977     pRegFrame->ds  = ds;
    1978     pRegFrame->es  = es;
    1979     pRegFrame->fs  = fs;
    1980     pRegFrame->gs  = gs;
    1981 
    1982     return VINF_SUCCESS;
    19831993}
    19841994#endif /* IN_RC */
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r40381 r40453  
    79187918}
    79197919
     7920
     7921/**
     7922 * Updates the real CPU context structure with the context core (from the trap
     7923 * stack frame) before interpreting any instructions.
     7924 *
     7925 * @param   pCtx        The real CPU context.
     7926 * @param   pCtxCore    The trap stack CPU core context.
     7927 */
     7928DECLINLINE(void) iemCtxCoreToCtx(PCPUMCTX pCtx, PCCPUMCTXCORE pCtxCore)
     7929{
     7930    PCPUMCTXCORE pDst = CPUMCTX2CORE(pCtx);
     7931    if (pDst != pCtxCore)
     7932        *pDst = *pCtxCore;
     7933}
     7934
     7935
     7936/**
     7937 * Updates the context core (from the trap stack frame) with the updated values
     7938 * from the real CPU context structure after instruction emulation.
     7939 *
     7940 * @param   pCtx        The real CPU context.
     7941 * @param   pCtxCore    The trap stack CPU core context.
     7942 */
     7943DECLINLINE(void) iemCtxToCtxCore(PCPUMCTXCORE pCtxCore, PCCPUMCTX pCtx)
     7944{
     7945    PCCPUMCTXCORE pSrc = CPUMCTX2CORE(pCtx);
     7946    if (pSrc != pCtxCore)
     7947        *pCtxCore = *pSrc;
     7948}
     7949
     7950
     7951#if 0 /* The IRET-to-v8086 mode in PATM is very optimistic, so I don't dare do this yet. */
     7952/**
     7953 * Executes a IRET instruction with default operand size.
     7954 *
     7955 * This is for PATM.
     7956 *
     7957 * @returns VBox status code.
     7958 * @param   pVCpu               The current virtual CPU.
     7959 * @param   pCtxCore            The register frame.
     7960 */
     7961VMM_INT_DECL(int) IEMExecInstr_iret(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore)
     7962{
     7963    PIEMCPU  pIemCpu = &pVCpu->iem.s;
     7964    PCPUMCTX pCtx    = pVCpu->iem.s.CTX_SUFF(pCtx);
     7965
     7966    iemCtxCoreToCtx(pCtx, pCtxCore);
     7967    iemInitDecoder(pIemCpu);
     7968    VBOXSTRICTRC rcStrict = iemCImpl_iret(pIemCpu, 1, pIemCpu->enmDefOpSize);
     7969    if (rcStrict == VINF_SUCCESS)
     7970        iemCtxToCtxCore(pCtxCore, pCtx);
     7971    else
     7972        LogFlow(("IEMExecInstr_iret: cs:rip=%04x:%08RX64 ss:rsp=%04x:%08RX64 EFL=%06x - rcStrict=%Rrc\n",
     7973                 pCtx->cs, pCtx->rip, pCtx->ss, pCtx->rsp, pCtx->eflags.u, VBOXSTRICTRC_VAL(rcStrict)));
     7974    return rcStrict;
     7975}
     7976#endif
     7977
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