Changeset 40453 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Mar 13, 2012 6:38:06 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76810
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r40451 r40453 26 26 #include <VBox/vmm/csam.h> 27 27 #include <VBox/vmm/pgm.h> 28 #ifdef VBOX_WITH_IEM 29 # include <VBox/vmm/iem.h> 30 #endif 28 31 #include <VBox/vmm/iom.h> 29 32 #include <VBox/vmm/stam.h> … … 488 491 LogFlow(("EMInterpretInstruction %RGv fault %RGv\n", (RTGCPTR)pRegFrame->rip, pvFault)); 489 492 #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; 498 498 return rc; 499 499 #else … … 545 545 LogFlow(("EMInterpretInstructionEx %RGv fault %RGv\n", (RTGCPTR)pRegFrame->rip, pvFault)); 546 546 #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; 555 552 return rc; 556 553 #else … … 609 606 RTGCPTR pvFault, EMCODETYPE enmCodeType) 610 607 { 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 612 617 uint32_t cbIgnored; 613 618 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);615 619 if (RT_SUCCESS(rc)) 616 {617 620 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 else621 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,InterpretFailed));622 621 return rc; 623 } 624 622 #endif 623 } 624 625 #if defined(IN_RC) /*&& defined(VBOX_WITH_PATM)*/ 626 627 DECLINLINE(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 */ 645 VMMDECL(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 */ 625 691 #ifndef VBOX_WITH_IEM 626 692 … … 1925 1991 return VERR_EM_INTERPRETER; 1926 1992 #endif 1927 }1928 #endif /* IN_RC */1929 1930 1931 #ifdef IN_RC1932 /**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_RING01971 CPUMRawSetEFlags(pVCpu, pRegFrame, eflags);1972 #endif1973 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;1983 1993 } 1984 1994 #endif /* IN_RC */ -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r40381 r40453 7918 7918 } 7919 7919 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 */ 7928 DECLINLINE(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 */ 7943 DECLINLINE(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 */ 7961 VMM_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.