- Timestamp:
- Aug 9, 2012 8:03:21 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/iem.h
r41799 r42704 43 43 VMMDECL(VBOXSTRICTRC) IEMExecOneWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC, 44 44 const void *pvOpcodeBytes, size_t cbOpcodeBytes); 45 VMMDECL(VBOXSTRICTRC) IEMExecOneBypassEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten); 46 VMMDECL(VBOXSTRICTRC) IEMExecOneBypassWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC, 47 const void *pvOpcodeBytes, size_t cbOpcodeBytes); 45 48 VMMDECL(VBOXSTRICTRC) IEMExecLots(PVMCPU pVCpu); 46 49 VMM_INT_DECL(VBOXSTRICTRC) IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2); -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r42676 r42704 173 173 * Defined Constants And Macros * 174 174 *******************************************************************************/ 175 /** @def IEM_LOG_MEMORY_ACCESS 176 * Can be used to log memory accesses when debugging problematic guest behavior. */ 177 #if 0 178 # define IEM_LOG_MEMORY_ACCESS 179 #endif 180 175 181 /** @name IEM status codes. 176 182 * … … 709 715 * 710 716 * @param pIemCpu The per CPU IEM state. 711 */ 712 DECLINLINE(void) iemInitDecoder(PIEMCPU pIemCpu) 717 * @param fBypassHandlers Whether to bypass access handlers. 718 */ 719 DECLINLINE(void) iemInitDecoder(PIEMCPU pIemCpu, bool fBypassHandlers) 713 720 { 714 721 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); … … 754 761 pIemCpu->iNextMapping = 0; 755 762 pIemCpu->rcPassUp = VINF_SUCCESS; 763 pIemCpu->fBypassHandlers = fBypassHandlers; 764 756 765 } 757 766 … … 762 771 * @returns Strict VBox status code. 763 772 * @param pIemCpu The IEM state. 764 */ 765 static VBOXSTRICTRC iemInitDecoderAndPrefetchOpcodes(PIEMCPU pIemCpu) 773 * @param fBypassHandlers Whether to bypass access handlers. 774 */ 775 static VBOXSTRICTRC iemInitDecoderAndPrefetchOpcodes(PIEMCPU pIemCpu, bool fBypassHandlers) 766 776 { 767 777 #ifdef IEM_VERIFICATION_MODE 768 778 uint8_t const cbOldOpcodes = pIemCpu->cbOpcode; 769 779 #endif 770 iemInitDecoder(pIemCpu );780 iemInitDecoder(pIemCpu, fBypassHandlers); 771 781 772 782 /* … … 796 806 } 797 807 808 #if defined(IN_RC) && defined(VBOX_WITH_RAW_MODE) 809 /* Allow interpretation of patch manager code blocks since they can for 810 instance throw #PFs for perfectly good reasons. */ 811 if ( (pCtx->cs.Sel & X86_SEL_RPL) == 1 812 && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), GCPtrPC)) 813 { 814 uint32_t cbLeftOnPage = PAGE_SIZE - (GCPtrPC & PAGE_OFFSET_MASK); 815 if (cbToTryRead > cbLeftOnPage) 816 cbToTryRead = cbLeftOnPage; 817 if (cbToTryRead > sizeof(pIemCpu->abOpcode)) 818 cbToTryRead = sizeof(pIemCpu->abOpcode); 819 memcpy(pIemCpu->abOpcode, (void const *)(uintptr_t)GCPtrPC, cbToTryRead); 820 pIemCpu->cbOpcode = cbToTryRead; 821 return VINF_SUCCESS; 822 } 823 #endif 824 798 825 RTGCPHYS GCPhys; 799 826 uint64_t fFlags; … … 801 828 if (RT_FAILURE(rc)) 802 829 { 803 #if defined(IN_RC) && defined(VBOX_WITH_RAW_MODE)804 /* Allow interpretation of patch manager code blocks since they can for805 instance throw #PFs for perfectly good reasons. */806 if ( (pCtx->cs.Sel & X86_SEL_RPL) == 1807 && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), GCPtrPC))808 {809 uint32_t cbLeftOnPage = PAGE_SIZE - (GCPtrPC & PAGE_OFFSET_MASK);810 if (cbToTryRead > cbLeftOnPage)811 cbToTryRead = cbLeftOnPage;812 if (cbToTryRead > sizeof(pIemCpu->abOpcode))813 cbToTryRead = sizeof(pIemCpu->abOpcode);814 memcpy(pIemCpu->abOpcode, (void const *)(uintptr_t)GCPtrPC, cbToTryRead);815 pIemCpu->cbOpcode = cbToTryRead;816 return VINF_SUCCESS;817 }818 #endif819 830 Log(("iemInitDecoderAndPrefetchOpcodes: %RGv - rc=%Rrc\n", GCPtrPC, rc)); 820 831 return iemRaisePageFault(pIemCpu, GCPtrPC, IEM_ACCESS_INSTRUCTION, rc); … … 863 874 /** @todo PATM: Read original, unpatched bytes? EMAll.cpp doesn't seem to be 864 875 * doing that. */ 865 if (!pIemCpu->fBy PassHandlers)876 if (!pIemCpu->fBypassHandlers) 866 877 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, pIemCpu->abOpcode, cbToTryRead); 867 878 else … … 870 881 { 871 882 /** @todo status code handling */ 872 Log(("iemInitDecoderAndPrefetchOpcodes: %RGv - read error - rc=%Rrc (!!)\n", GCPtrPC, rc)); 883 Log(("iemInitDecoderAndPrefetchOpcodes: %RGv/%RGp LB %#x - read error - rc=%Rrc (!!)\n", 884 GCPtrPC, GCPhys, rc, cbToTryRead)); 873 885 return rc; 874 886 } … … 953 965 cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode; 954 966 Assert(cbToTryRead >= cbMin - cbLeft); 955 if (!pIemCpu->fBy PassHandlers)967 if (!pIemCpu->fBypassHandlers) 956 968 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhys, &pIemCpu->abOpcode[pIemCpu->cbOpcode], cbToTryRead); 957 969 else … … 1771 1783 return VINF_SUCCESS; 1772 1784 } 1785 1786 1787 /** 1788 * Gets the correct EFLAGS regardless of whether PATM stores parts of them or 1789 * not. 1790 * 1791 * @param a_pIemCpu The IEM per CPU data. 1792 * @param a_pCtx The CPU context. 1793 */ 1794 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 1795 # define IEMMISC_GET_EFL(a_pIemCpu, a_pCtx) \ 1796 ( IEM_VERIFICATION_ENABLED(a_pIemCpu) \ 1797 ? (a_pCtx)->eflags.u \ 1798 : CPUMRawGetEFlags(IEMCPU_TO_VMCPU(a_pIemCpu)) ) 1799 #else 1800 # define IEMMISC_GET_EFL(a_pIemCpu, a_pCtx) \ 1801 ( (a_pCtx)->eflags.u ) 1802 #endif 1803 1804 /** 1805 * Updates the EFLAGS in the correct manner wrt. PATM. 1806 * 1807 * @param a_pIemCpu The IEM per CPU data. 1808 * @param a_pCtx The CPU context. 1809 */ 1810 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 1811 # define IEMMISC_SET_EFL(a_pIemCpu, a_pCtx, a_fEfl) \ 1812 do { \ 1813 if (IEM_VERIFICATION_ENABLED(a_pIemCpu)) \ 1814 (a_pCtx)->eflags.u = (a_fEfl); \ 1815 else \ 1816 CPUMRawSetEFlags(IEMCPU_TO_VMCPU(a_pIemCpu), a_fEfl); \ 1817 } while (0) 1818 #else 1819 # define IEMMISC_SET_EFL(a_pIemCpu, a_pCtx, a_fEfl) \ 1820 do { \ 1821 (a_pCtx)->eflags.u = (a_fEfl); \ 1822 } while (0) 1823 #endif 1773 1824 1774 1825 … … 1937 1988 return rcStrict; 1938 1989 1939 pu16Frame[2] = (uint16_t)pCtx->eflags.u; 1990 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 1991 pu16Frame[2] = (uint16_t)fEfl; 1940 1992 pu16Frame[1] = (uint16_t)pCtx->cs.Sel; 1941 1993 pu16Frame[0] = pCtx->ip + cbInstr; … … 1954 2006 /** @todo do we load attribs and limit as well? Should we check against limit like far jump? */ 1955 2007 pCtx->rip = Idte.off; 1956 pCtx->eflags.Bits.u1IF = 0; 2008 fEfl &= ~X86_EFL_IF; 2009 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl); 1957 2010 1958 2011 /** @todo do we actually do this in real mode? */ … … 2134 2187 * This in turns means validating the new SS and ESP... 2135 2188 */ 2189 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 2136 2190 uint8_t const uNewCpl = DescCS.Legacy.Gen.u4Type & X86_SEL_TYPE_CONF 2137 2191 ? pIemCpu->uCpl : DescCS.Legacy.Gen.u2Dpl; … … 2182 2236 ? pCtx->eip + cbInstr : pCtx->eip; 2183 2237 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl; 2184 uStackFrame.pu32[2] = pCtx->eflags.u;2238 uStackFrame.pu32[2] = fEfl; 2185 2239 uStackFrame.pu32[3] = pCtx->esp; 2186 2240 uStackFrame.pu32[4] = pCtx->ss.Sel; … … 2239 2293 ? pCtx->eip + cbInstr : pCtx->eip; 2240 2294 uStackFrame.pu32[1] = (pCtx->cs.Sel & ~X86_SEL_RPL) | pIemCpu->uCpl; 2241 uStackFrame.pu32[2] = pCtx->eflags.u;2295 uStackFrame.pu32[2] = fEfl; 2242 2296 rcStrict = iemMemCommitAndUnmap(pIemCpu, pvStackFrame, IEM_ACCESS_STACK_W); /* don't use the commit here */ 2243 2297 if (rcStrict != VINF_SUCCESS) … … 2268 2322 2269 2323 pCtx->rip = uNewEip; 2270 pCtx->rflags.u &= ~fEflToClear; 2324 fEfl &= ~fEflToClear; 2325 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl); 2271 2326 2272 2327 if (fFlags & IEM_XCPT_FLAGS_CR2) … … 4428 4483 4429 4484 /** 4485 * Updates the IEMCPU::cbWritten counter if applicable. 4486 * 4487 * @param pIemCpu The IEM per CPU data. 4488 * @param fAccess The access being accounted for. 4489 * @param cbMem The access size. 4490 */ 4491 DECL_FORCE_INLINE(void) iemMemUpdateWrittenCounter(PIEMCPU pIemCpu, uint32_t fAccess, size_t cbMem) 4492 { 4493 if ( (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_STACK | IEM_ACCESS_TYPE_WRITE) 4494 || (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_DATA | IEM_ACCESS_TYPE_WRITE) ) 4495 pIemCpu->cbWritten += (uint32_t)cbMem; 4496 } 4497 4498 4499 /** 4430 4500 * Checks if the given segment can be written to, raise the appropriate 4431 4501 * exception if not. … … 4662 4732 return VERR_PGM_PHYS_TLB_CATCH_ALL; 4663 4733 #endif 4734 #ifdef IEM_LOG_MEMORY_ACCESS 4735 return VERR_PGM_PHYS_TLB_CATCH_ALL; 4736 #endif 4664 4737 4665 4738 /** @todo This API may require some improving later. A private deal with PGM … … 4670 4743 GCPhysMem, 4671 4744 RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE), 4672 pIemCpu->fBy PassHandlers,4745 pIemCpu->fBypassHandlers, 4673 4746 ppvMem, 4674 4747 pLock); … … 4772 4845 uint16_t const cbSecond = pIemCpu->aMemBbMappings[iMemMap].cbSecond; 4773 4846 uint8_t const *pbBuf = &pIemCpu->aBounceBuffers[iMemMap].ab[0]; 4774 if (!pIemCpu->fBy PassHandlers)4847 if (!pIemCpu->fBypassHandlers) 4775 4848 { 4776 4849 rc = PGMPhysWrite(IEMCPU_TO_VM(pIemCpu), … … 4800 4873 /** @todo status code handling */ 4801 4874 Log(("iemMemBounceBufferCommitAndUnmap: %s GCPhysFirst=%RGp/%#x GCPhysSecond=%RGp/%#x %Rrc (!!)\n", 4802 pIemCpu->fBy PassHandlers ? "PGMPhysWrite" : "PGMPhysSimpleWriteGCPhys",4875 pIemCpu->fBypassHandlers ? "PGMPhysWrite" : "PGMPhysSimpleWriteGCPhys", 4803 4876 pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst, cbFirst, 4804 4877 pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond, cbSecond, rc)); … … 4842 4915 } 4843 4916 #endif 4917 #ifdef IEM_LOG_MEMORY_ACCESS 4918 if (rc == VINF_SUCCESS) 4919 { 4920 Log(("IEM Wrote %RGp: %.*Rhxs\n", pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst, 4921 RT_MAX(RT_MIN(pIemCpu->aMemBbMappings[iMemMap].cbFirst, 64), 1), &pIemCpu->aBounceBuffers[iMemMap].ab[0])); 4922 if (pIemCpu->aMemBbMappings[iMemMap].cbSecond) 4923 Log(("IEM Wrote %RGp: %.*Rhxs [2nd page]\n", pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond, 4924 RT_MIN(pIemCpu->aMemBbMappings[iMemMap].cbSecond, 64), 4925 &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst])); 4926 } 4927 #endif 4844 4928 4845 4929 /* … … 4884 4968 { 4885 4969 int rc; 4886 if (!pIemCpu->fBy PassHandlers)4970 if (!pIemCpu->fBypassHandlers) 4887 4971 { 4888 4972 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbFirstPage); … … 4968 5052 pIemCpu->cActiveMappings++; 4969 5053 5054 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem); 4970 5055 *ppvMem = pbBuf; 4971 5056 return VINF_SUCCESS; … … 5003 5088 { 5004 5089 int rc; 5005 if (!pIemCpu->fBy PassHandlers)5090 if (!pIemCpu->fBypassHandlers) 5006 5091 rc = PGMPhysRead(IEMCPU_TO_VM(pIemCpu), GCPhysFirst, pbBuf, cbMem); 5007 5092 else … … 5011 5096 /** @todo status code handling */ 5012 5097 Log(("iemMemBounceBufferMapPhys: %s GCPhysFirst=%RGp rc=%Rrc (!!)\n", 5013 pIemCpu->fBy PassHandlers ? "PGMPhysRead" : "PGMPhysSimpleReadGCPhys", GCPhysFirst, rc));5098 pIemCpu->fBypassHandlers ? "PGMPhysRead" : "PGMPhysSimpleReadGCPhys", GCPhysFirst, rc)); 5014 5099 return rc; 5015 5100 } … … 5056 5141 pIemCpu->cActiveMappings++; 5057 5142 5143 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem); 5058 5144 *ppvMem = pbBuf; 5059 5145 return VINF_SUCCESS; … … 5135 5221 pIemCpu->cActiveMappings++; 5136 5222 5137 if ( (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_STACK | IEM_ACCESS_TYPE_WRITE) 5138 || (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_DATA | IEM_ACCESS_TYPE_WRITE) ) 5139 pIemCpu->cbWritten += (uint32_t)cbMem; 5223 iemMemUpdateWrittenCounter(pIemCpu, fAccess, cbMem); 5140 5224 *ppvMem = pvMem; 5141 5225 return VINF_SUCCESS; … … 6324 6408 #define IEM_MC_FETCH_TR_U32(a_u32Dst) (a_u32Dst) = (pIemCpu)->CTX_SUFF(pCtx)->tr.Sel 6325 6409 #define IEM_MC_FETCH_TR_U64(a_u64Dst) (a_u64Dst) = (pIemCpu)->CTX_SUFF(pCtx)->tr.Sel 6410 /** @note Not for IOPL or IF testing or modification. */ 6326 6411 #define IEM_MC_FETCH_EFLAGS(a_EFlags) (a_EFlags) = (pIemCpu)->CTX_SUFF(pCtx)->eflags.u 6327 6412 #define IEM_MC_FETCH_EFLAGS_U8(a_EFlags) (a_EFlags) = (uint8_t)(pIemCpu)->CTX_SUFF(pCtx)->eflags.u … … 6348 6433 #define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = (uint32_t *)iemGRegRef(pIemCpu, (a_iGReg)) 6349 6434 #define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = (uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) 6435 /** @note Not for IOPL or IF testing or modification. */ 6350 6436 #define IEM_MC_REF_EFLAGS(a_pEFlags) (a_pEFlags) = &(pIemCpu)->CTX_SUFF(pCtx)->eflags.u 6351 6437 … … 6423 6509 6424 6510 6511 /** @note Not for IOPL or IF modification. */ 6425 6512 #define IEM_MC_SET_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u |= (a_fBit); } while (0) 6513 /** @note Not for IOPL or IF modification. */ 6426 6514 #define IEM_MC_CLEAR_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u &= ~(a_fBit); } while (0) 6515 /** @note Not for IOPL or IF modification. */ 6427 6516 #define IEM_MC_FLIP_EFL_BIT(a_fBit) do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u ^= (a_fBit); } while (0) 6428 6517 … … 6875 6964 CPUMSetChangedFlags(IEMCPU_TO_VMCPU(pIemCpu), CPUM_CHANGED_FPU_REM) 6876 6965 6966 /** @note Not for IOPL or IF testing. */ 6877 6967 #define IEM_MC_IF_EFL_BIT_SET(a_fBit) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) { 6968 /** @note Not for IOPL or IF testing. */ 6878 6969 #define IEM_MC_IF_EFL_BIT_NOT_SET(a_fBit) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit))) { 6970 /** @note Not for IOPL or IF testing. */ 6879 6971 #define IEM_MC_IF_EFL_ANY_BITS_SET(a_fBits) if (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits)) { 6972 /** @note Not for IOPL or IF testing. */ 6880 6973 #define IEM_MC_IF_EFL_NO_BITS_SET(a_fBits) if (!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBits))) { 6974 /** @note Not for IOPL or IF testing. */ 6881 6975 #define IEM_MC_IF_EFL_BITS_NE(a_fBit1, a_fBit2) \ 6882 6976 if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \ 6883 6977 != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) { 6978 /** @note Not for IOPL or IF testing. */ 6884 6979 #define IEM_MC_IF_EFL_BITS_EQ(a_fBit1, a_fBit2) \ 6885 6980 if ( !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \ 6886 6981 == !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) { 6982 /** @note Not for IOPL or IF testing. */ 6887 6983 #define IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE(a_fBit, a_fBit1, a_fBit2) \ 6888 6984 if ( (pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \ 6889 6985 || !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit1)) \ 6890 6986 != !!(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit2)) ) { 6987 /** @note Not for IOPL or IF testing. */ 6891 6988 #define IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ(a_fBit, a_fBit1, a_fBit2) \ 6892 6989 if ( !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & (a_fBit)) \ … … 6896 6993 #define IEM_MC_IF_ECX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->ecx != 0) { 6897 6994 #define IEM_MC_IF_RCX_IS_NZ() if (pIemCpu->CTX_SUFF(pCtx)->rcx != 0) { 6995 /** @note Not for IOPL or IF testing. */ 6898 6996 #define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \ 6899 6997 if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \ 6900 6998 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) { 6999 /** @note Not for IOPL or IF testing. */ 6901 7000 #define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \ 6902 7001 if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \ 6903 7002 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) { 7003 /** @note Not for IOPL or IF testing. */ 6904 7004 #define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_SET(a_fBit) \ 6905 7005 if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \ 6906 7006 && (pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) { 7007 /** @note Not for IOPL or IF testing. */ 6907 7008 #define IEM_MC_IF_CX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \ 6908 7009 if ( pIemCpu->CTX_SUFF(pCtx)->cx != 0 \ 6909 7010 && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) { 7011 /** @note Not for IOPL or IF testing. */ 6910 7012 #define IEM_MC_IF_ECX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \ 6911 7013 if ( pIemCpu->CTX_SUFF(pCtx)->ecx != 0 \ 6912 7014 && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) { 7015 /** @note Not for IOPL or IF testing. */ 6913 7016 #define IEM_MC_IF_RCX_IS_NZ_AND_EFL_BIT_NOT_SET(a_fBit) \ 6914 7017 if ( pIemCpu->CTX_SUFF(pCtx)->rcx != 0 \ … … 8150 8253 * @param pVCpu The current virtual CPU. 8151 8254 * @param pIemCpu The IEM per CPU data. 8152 */ 8153 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu) 8255 * @param fExecuteInhibit If set, execute the instruction following CLI, 8256 * POP SS and MOV SS,GR. 8257 */ 8258 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit) 8154 8259 { 8155 8260 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b); … … 8163 8268 /* Execute the next instruction as well if a cli, pop ss or 8164 8269 mov ss, Gr has just completed successfully. */ 8165 if ( rcStrict == VINF_SUCCESS 8270 if ( fExecuteInhibit 8271 && rcStrict == VINF_SUCCESS 8166 8272 && VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 8167 8273 && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip ) 8168 8274 { 8169 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu );8275 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers); 8170 8276 if (rcStrict == VINF_SUCCESS) 8171 8277 { … … 8282 8388 * Do the decoding and emulation. 8283 8389 */ 8284 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu );8390 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false); 8285 8391 if (rcStrict == VINF_SUCCESS) 8286 rcStrict = iemExecOneInner(pVCpu, pIemCpu );8392 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true); 8287 8393 8288 8394 #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3) … … 8305 8411 AssertReturn(CPUMCTX2CORE(pCtx) == pCtxCore, VERR_IEM_IPE_3); 8306 8412 8307 iemInitDecoder(pIemCpu );8413 iemInitDecoder(pIemCpu, false); 8308 8414 uint32_t const cbOldWritten = pIemCpu->cbWritten; 8309 8415 8310 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu );8416 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false); 8311 8417 if (rcStrict == VINF_SUCCESS) 8312 8418 { 8313 rcStrict = iemExecOneInner(pVCpu, pIemCpu );8419 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true); 8314 8420 if (pcbWritten) 8315 8421 *pcbWritten = pIemCpu->cbWritten - cbOldWritten; … … 8330 8436 && pCtx->rip == OpcodeBytesPC) 8331 8437 { 8332 iemInitDecoder(pIemCpu );8438 iemInitDecoder(pIemCpu, false); 8333 8439 pIemCpu->cbOpcode = (uint8_t)RT_MIN(cbOpcodeBytes, sizeof(pIemCpu->abOpcode)); 8334 8440 memcpy(pIemCpu->abOpcode, pvOpcodeBytes, pIemCpu->cbOpcode); … … 8336 8442 } 8337 8443 else 8338 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu );8444 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, false); 8339 8445 if (rcStrict == VINF_SUCCESS) 8340 8446 { 8341 rcStrict = iemExecOneInner(pVCpu, pIemCpu); 8342 } 8447 rcStrict = iemExecOneInner(pVCpu, pIemCpu, true); 8448 } 8449 return rcStrict; 8450 } 8451 8452 8453 VMMDECL(VBOXSTRICTRC) IEMExecOneBypassEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten) 8454 { 8455 PIEMCPU pIemCpu = &pVCpu->iem.s; 8456 PCPUMCTX pCtx = pVCpu->iem.s.CTX_SUFF(pCtx); 8457 AssertReturn(CPUMCTX2CORE(pCtx) == pCtxCore, VERR_IEM_IPE_3); 8458 8459 iemInitDecoder(pIemCpu, true); 8460 uint32_t const cbOldWritten = pIemCpu->cbWritten; 8461 8462 VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, true); 8463 if (rcStrict == VINF_SUCCESS) 8464 { 8465 rcStrict = iemExecOneInner(pVCpu, pIemCpu, false); 8466 if (pcbWritten) 8467 *pcbWritten = pIemCpu->cbWritten - cbOldWritten; 8468 } 8469 return rcStrict; 8470 } 8471 8472 8473 VMMDECL(VBOXSTRICTRC) IEMExecOneBypassWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC, 8474 const void *pvOpcodeBytes, size_t cbOpcodeBytes) 8475 { 8476 PIEMCPU pIemCpu = &pVCpu->iem.s; 8477 PCPUMCTX pCtx = pVCpu->iem.s.CTX_SUFF(pCtx); 8478 AssertReturn(CPUMCTX2CORE(pCtx) == pCtxCore, VERR_IEM_IPE_3); 8479 8480 VBOXSTRICTRC rcStrict; 8481 if ( cbOpcodeBytes 8482 && pCtx->rip == OpcodeBytesPC) 8483 { 8484 iemInitDecoder(pIemCpu, true); 8485 pIemCpu->cbOpcode = (uint8_t)RT_MIN(cbOpcodeBytes, sizeof(pIemCpu->abOpcode)); 8486 memcpy(pIemCpu->abOpcode, pvOpcodeBytes, pIemCpu->cbOpcode); 8487 rcStrict = VINF_SUCCESS; 8488 } 8489 else 8490 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, true); 8491 if (rcStrict == VINF_SUCCESS) 8492 rcStrict = iemExecOneInner(pVCpu, pIemCpu, false); 8343 8493 return rcStrict; 8344 8494 } … … 8367 8517 VMM_INT_DECL(VBOXSTRICTRC) IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2) 8368 8518 { 8369 iemInitDecoder(&pVCpu->iem.s );8519 iemInitDecoder(&pVCpu->iem.s, false); 8370 8520 8371 8521 uint32_t fFlags; -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r42677 r42704 35 35 DECLINLINE(VBOXSTRICTRC) iemHlpCheckPortIOPermission(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint16_t u16Port, uint8_t cbOperand) 36 36 { 37 X86EFLAGS Efl; 38 Efl.u = IEMMISC_GET_EFL(pIemCpu, pCtx); 37 39 if ( (pCtx->cr0 & X86_CR0_PE) 38 && ( pIemCpu->uCpl > pCtx->eflags.Bits.u2IOPL39 || pCtx->eflags.Bits.u1VM) )40 && ( pIemCpu->uCpl > Efl.Bits.u2IOPL 41 || Efl.Bits.u1VM) ) 40 42 { 41 43 NOREF(u16Port); NOREF(cbOperand); /** @todo I/O port permission bitmap check */ … … 469 471 * doing this in a C implementation). 470 472 */ 471 uint32_t fEfl = pCtx->eflags.u;473 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 472 474 if ( (fEfl & X86_EFL_VM) 473 475 && X86_EFL_GET_IOPL(fEfl) != 3 ) … … 517 519 { 518 520 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 519 uint32_t const fEflOld = pCtx->eflags.u; 521 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu); 522 uint32_t const fEflOld = IEMMISC_GET_EFL(pIemCpu, pCtx); 520 523 VBOXSTRICTRC rcStrict; 521 524 uint32_t fEflNew; … … 633 636 */ 634 637 Assert(fEflNew & RT_BIT_32(1)); 635 pCtx->eflags.u = fEflNew;638 IEMMISC_SET_EFL(pIemCpu, pCtx, fEflNew); 636 639 iemRegAddToRip(pIemCpu, cbInstr); 637 640 … … 1912 1915 IEM_CIMPL_DEF_1(iemCImpl_iret_real_v8086, IEMMODE, enmEffOpSize) 1913 1916 { 1914 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 1917 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 1918 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu); 1919 X86EFLAGS Efl; 1920 Efl.u = IEMMISC_GET_EFL(pIemCpu, pCtx); 1915 1921 NOREF(cbInstr); 1916 1922 … … 1945 1951 | X86_EFL_RF /*| X86_EFL_VM*/ | X86_EFL_AC /*|X86_EFL_VIF*/ /*|X86_EFL_VIP*/ 1946 1952 | X86_EFL_ID; 1947 uNewFlags |= pCtx->eflags.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_1);1953 uNewFlags |= Efl.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_1); 1948 1954 } 1949 1955 else … … 1957 1963 uNewFlags &= X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF 1958 1964 | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT; 1959 uNewFlags |= pCtx->eflags.u & (UINT32_C(0xffff0000) | X86_EFL_1);1965 uNewFlags |= Efl.u & (UINT32_C(0xffff0000) | X86_EFL_1); 1960 1966 /** @todo The intel pseudo code does not indicate what happens to 1961 1967 * reserved flags. We just ignore them. */ … … 1974 1980 * V8086 checks and flag adjustments 1975 1981 */ 1976 if ( pCtx->eflags.Bits.u1VM)1977 { 1978 if ( pCtx->eflags.Bits.u2IOPL == 3)1982 if (Efl.Bits.u1VM) 1983 { 1984 if (Efl.Bits.u2IOPL == 3) 1979 1985 { 1980 1986 /* Preserve IOPL and clear RF. */ 1981 uNewFlags &= 1982 uNewFlags |= pCtx->eflags.u & (X86_EFL_IOPL);1987 uNewFlags &= ~(X86_EFL_IOPL | X86_EFL_RF); 1988 uNewFlags |= Efl.u & (X86_EFL_IOPL); 1983 1989 } 1984 1990 else if ( enmEffOpSize == IEMMODE_16BIT 1985 1991 && ( !(uNewFlags & X86_EFL_IF) 1986 || ! pCtx->eflags.Bits.u1VIP )1992 || !Efl.Bits.u1VIP ) 1987 1993 && !(uNewFlags & X86_EFL_TF) ) 1988 1994 { … … 1990 1996 uNewFlags &= ~X86_EFL_VIF; 1991 1997 uNewFlags |= (uNewFlags & X86_EFL_IF) << (19 - 9); 1992 uNewFlags &= 1993 uNewFlags |= pCtx->eflags.u & (X86_EFL_IF | X86_EFL_IOPL);1998 uNewFlags &= ~(X86_EFL_IF | X86_EFL_IOPL | X86_EFL_RF); 1999 uNewFlags |= Efl.u & (X86_EFL_IF | X86_EFL_IOPL); 1994 2000 } 1995 2001 else … … 2010 2016 /** @todo do we load attribs and limit as well? */ 2011 2017 Assert(uNewFlags & X86_EFL_1); 2012 pCtx->eflags.u = uNewFlags;2018 IEMMISC_SET_EFL(pIemCpu, pCtx, uNewFlags); 2013 2019 2014 2020 return VINF_SUCCESS; … … 2345 2351 else if (pIemCpu->uCpl <= pCtx->eflags.Bits.u2IOPL) 2346 2352 fEFlagsMask |= X86_EFL_IF; 2347 pCtx->eflags.u &= ~fEFlagsMask; 2348 pCtx->eflags.u |= fEFlagsMask & uNewFlags; 2353 uint32_t fEFlagsNew = IEMMISC_GET_EFL(pIemCpu, pCtx); 2354 fEFlagsNew &= ~fEFlagsMask; 2355 fEFlagsNew |= uNewFlags & fEFlagsMask; 2356 IEMMISC_SET_EFL(pIemCpu, pCtx, fEFlagsNew); 2349 2357 2350 2358 pIemCpu->uCpl = uNewCs & X86_SEL_RPL; … … 2389 2397 pCtx->rsp = uNewRsp; 2390 2398 2399 X86EFLAGS NewEfl; 2400 NewEfl.u = IEMMISC_GET_EFL(pIemCpu, pCtx); 2391 2401 uint32_t fEFlagsMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF 2392 2402 | X86_EFL_TF | X86_EFL_DF | X86_EFL_OF | X86_EFL_NT; … … 2395 2405 if (pIemCpu->uCpl == 0) 2396 2406 fEFlagsMask |= X86_EFL_IF | X86_EFL_IOPL | X86_EFL_VIF | X86_EFL_VIP; /* VM is 0 */ 2397 else if (pIemCpu->uCpl <= pCtx->eflags.Bits.u2IOPL)2407 else if (pIemCpu->uCpl <= NewEfl.Bits.u2IOPL) 2398 2408 fEFlagsMask |= X86_EFL_IF; 2399 pCtx->eflags.u &= ~fEFlagsMask; 2400 pCtx->eflags.u |= fEFlagsMask & uNewFlags; 2409 NewEfl.u &= ~fEFlagsMask; 2410 NewEfl.u |= fEFlagsMask & uNewFlags; 2411 IEMMISC_SET_EFL(pIemCpu, pCtx, NewEfl.u); 2401 2412 /* Done! */ 2402 2413 } … … 3277 3288 else 3278 3289 rcStrict = VINF_SUCCESS; 3290 3291 #ifdef IN_RC 3292 /* Return to ring-3 for rescheduling if WP or AM changes. */ 3293 if ( rcStrict == VINF_SUCCESS 3294 && ( (uNewCrX & (X86_CR0_WP | X86_CR0_AM)) 3295 != (uOldCrX & (X86_CR0_WP | X86_CR0_AM))) ) 3296 rcStrict = VINF_EM_RESCHEDULE; 3297 #endif 3279 3298 break; 3280 3299 } … … 3871 3890 * CPL check 3872 3891 */ 3873 if ( (pCtx->cr0 & X86_CR0_PE) 3874 && ( pIemCpu->uCpl > pCtx->eflags.Bits.u2IOPL 3875 || pCtx->eflags.Bits.u1VM) ) 3876 { 3877 /** @todo I/O port permission bitmap check */ 3878 IEM_RETURN_ASPECT_NOT_IMPLEMENTED_LOG(("Implement I/O permission bitmap checks.\n")); 3879 } 3892 VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, cbReg); 3893 if (rcStrict != VINF_SUCCESS) 3894 return rcStrict; 3880 3895 3881 3896 /* … … 3890 3905 default: AssertFailedReturn(VERR_INTERNAL_ERROR_3); 3891 3906 } 3892 VBOXSTRICTRC rcStrict;3893 3907 if (!IEM_VERIFICATION_ENABLED(pIemCpu)) 3894 3908 rcStrict = IOMIOPortWrite(IEMCPU_TO_VM(pIemCpu), u16Port, u32Value, cbReg); … … 3922 3936 IEM_CIMPL_DEF_0(iemCImpl_cli) 3923 3937 { 3924 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3925 3938 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3939 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu); 3940 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 3941 uint32_t const fEflOld = fEfl; 3926 3942 if (pCtx->cr0 & X86_CR0_PE) 3927 3943 { 3928 uint8_t const uIopl = pCtx->eflags.Bits.u2IOPL;3929 if (! pCtx->eflags.Bits.u1VM)3944 uint8_t const uIopl = X86_EFL_GET_IOPL(fEfl); 3945 if (!(fEfl & X86_EFL_VM)) 3930 3946 { 3931 3947 if (pIemCpu->uCpl <= uIopl) 3932 pCtx->eflags.Bits.u1IF = 0;3948 fEfl &= ~X86_EFL_IF; 3933 3949 else if ( pIemCpu->uCpl == 3 3934 3950 && (pCtx->cr4 & X86_CR4_PVI) ) 3935 pCtx->eflags.Bits.u1VIF = 0;3951 fEfl &= ~X86_EFL_VIF; 3936 3952 else 3937 3953 return iemRaiseGeneralProtectionFault0(pIemCpu); … … 3939 3955 /* V8086 */ 3940 3956 else if (uIopl == 3) 3941 pCtx->eflags.Bits.u1IF = 0;3957 fEfl &= ~X86_EFL_IF; 3942 3958 else if ( uIopl < 3 3943 3959 && (pCtx->cr4 & X86_CR4_VME) ) 3944 pCtx->eflags.Bits.u1VIF = 0;3960 fEfl &= ~X86_EFL_VIF; 3945 3961 else 3946 3962 return iemRaiseGeneralProtectionFault0(pIemCpu); … … 3948 3964 /* real mode */ 3949 3965 else 3950 pCtx->eflags.Bits.u1IF = 0; 3966 fEfl &= ~X86_EFL_IF; 3967 3968 /* Commit. */ 3969 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl); 3951 3970 iemRegAddToRip(pIemCpu, cbInstr); 3971 Log2(("CLI: %#x -> %#x\n", fEflOld, fEfl)); NOREF(fEflOld); 3952 3972 return VINF_SUCCESS; 3953 3973 } … … 3959 3979 IEM_CIMPL_DEF_0(iemCImpl_sti) 3960 3980 { 3961 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3981 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3982 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu); 3983 uint32_t fEfl = IEMMISC_GET_EFL(pIemCpu, pCtx); 3984 uint32_t const fEflOld = fEfl; 3962 3985 3963 3986 if (pCtx->cr0 & X86_CR0_PE) 3964 3987 { 3965 uint8_t const uIopl = pCtx->eflags.Bits.u2IOPL;3966 if (! pCtx->eflags.Bits.u1VM)3988 uint8_t const uIopl = X86_EFL_GET_IOPL(fEfl); 3989 if (!(fEfl & X86_EFL_VM)) 3967 3990 { 3968 3991 if (pIemCpu->uCpl <= uIopl) 3969 pCtx->eflags.Bits.u1IF = 1;3992 fEfl |= X86_EFL_IF; 3970 3993 else if ( pIemCpu->uCpl == 3 3971 3994 && (pCtx->cr4 & X86_CR4_PVI) 3972 && ! pCtx->eflags.Bits.u1VIP)3973 pCtx->eflags.Bits.u1VIF = 1;3995 && !(fEfl & X86_EFL_VIP) ) 3996 fEfl |= X86_EFL_VIF; 3974 3997 else 3975 3998 return iemRaiseGeneralProtectionFault0(pIemCpu); … … 3977 4000 /* V8086 */ 3978 4001 else if (uIopl == 3) 3979 pCtx->eflags.Bits.u1IF = 1;4002 fEfl |= X86_EFL_IF; 3980 4003 else if ( uIopl < 3 3981 4004 && (pCtx->cr4 & X86_CR4_VME) 3982 && ! pCtx->eflags.Bits.u1VIP)3983 pCtx->eflags.Bits.u1VIF = 1;4005 && !(fEfl & X86_EFL_VIP) ) 4006 fEfl |= X86_EFL_VIF; 3984 4007 else 3985 4008 return iemRaiseGeneralProtectionFault0(pIemCpu); … … 3987 4010 /* real mode */ 3988 4011 else 3989 pCtx->eflags.Bits.u1IF = 1; 3990 4012 fEfl |= X86_EFL_IF; 4013 4014 /* Commit. */ 4015 IEMMISC_SET_EFL(pIemCpu, pCtx, fEfl); 3991 4016 iemRegAddToRip(pIemCpu, cbInstr); 3992 /** @todo don't do this unconditionally... */ 3993 EMSetInhibitInterruptsPC(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rip); 4017 if (!(fEflOld & X86_EFL_IF) && (fEfl & X86_EFL_IF)) 4018 EMSetInhibitInterruptsPC(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rip); 4019 Log2(("STI: %#x -> %#x\n", fEflOld, fEfl)); 3994 4020 return VINF_SUCCESS; 3995 4021 } -
trunk/src/VBox/VMM/include/IEMInternal.h
r42662 r42704 205 205 206 206 /** Whether to bypass access handlers or not. */ 207 bool fBy PassHandlers;207 bool fBypassHandlers; 208 208 /** Explicit alignment padding. */ 209 209 bool afAlignment0[3];
Note:
See TracChangeset
for help on using the changeset viewer.