- Timestamp:
- Jul 4, 2016 3:32:28 PM (9 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r61968 r62010 4489 4489 } 4490 4490 4491 #ifdef IEM_WITH_SETJMP 4492 /** 4493 * See iemRaiseXcptOrInt. Will not return. 4494 */ 4495 IEM_STATIC DECL_NO_RETURN(void) 4496 iemRaiseXcptOrIntJmp(PIEMCPU pIemCpu, 4497 uint8_t cbInstr, 4498 uint8_t u8Vector, 4499 uint32_t fFlags, 4500 uint16_t uErr, 4501 uint64_t uCr2) 4502 { 4503 VBOXSTRICTRC rcStrict = iemRaiseXcptOrInt(pIemCpu, cbInstr, u8Vector, fFlags, uErr, uCr2); 4504 longjmp(*pIemCpu->CTX_SUFF(pJmpBuf), VBOXSTRICTRC_VAL(rcStrict)); 4505 } 4506 #endif 4507 4491 4508 4492 4509 /** \#DE - 00. */ … … 4603 4620 } 4604 4621 4622 #ifdef IEM_WITH_SETJMP 4623 /** \#GP(0) - 0d. */ 4624 DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseGeneralProtectionFault0Jmp(PIEMCPU pIemCpu) 4625 { 4626 iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0); 4627 } 4628 #endif 4629 4605 4630 4606 4631 /** \#GP(sel) - 0d. */ … … 4627 4652 } 4628 4653 4654 #ifdef IEM_WITH_SETJMP 4655 /** \#GP(sel) - 0d, longjmp. */ 4656 DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorBoundsJmp(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess) 4657 { 4658 NOREF(iSegReg); NOREF(fAccess); 4659 iemRaiseXcptOrIntJmp(pIemCpu, 0, iSegReg == X86_SREG_SS ? X86_XCPT_SS : X86_XCPT_GP, 4660 IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0); 4661 } 4662 #endif 4629 4663 4630 4664 /** \#GP(sel) - 0d. */ … … 4635 4669 } 4636 4670 4671 #ifdef IEM_WITH_SETJMP 4672 /** \#GP(sel) - 0d, longjmp. */ 4673 DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorBoundsBySelectorJmp(PIEMCPU pIemCpu, RTSEL Sel) 4674 { 4675 NOREF(Sel); 4676 iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0); 4677 } 4678 #endif 4679 4637 4680 4638 4681 /** \#GP(sel) - 0d. */ … … 4642 4685 return iemRaiseXcptOrInt(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0); 4643 4686 } 4687 4688 #ifdef IEM_WITH_SETJMP 4689 /** \#GP(sel) - 0d, longjmp. */ 4690 DECL_NO_INLINE(IEM_STATIC, DECL_NO_RETURN(void)) iemRaiseSelectorInvalidAccessJmp(PIEMCPU pIemCpu, uint32_t iSegReg, 4691 uint32_t fAccess) 4692 { 4693 NOREF(iSegReg); NOREF(fAccess); 4694 iemRaiseXcptOrIntJmp(pIemCpu, 0, X86_XCPT_GP, IEM_XCPT_FLAGS_T_CPU_XCPT | IEM_XCPT_FLAGS_ERR, 0, 0); 4695 } 4696 #endif 4644 4697 4645 4698 … … 4947 5000 { 4948 5001 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 4949 PCPUMSELREG pSReg; 4950 switch (iSegReg) 4951 { 4952 case X86_SREG_ES: pSReg = &pCtx->es; break; 4953 case X86_SREG_CS: pSReg = &pCtx->cs; break; 4954 case X86_SREG_SS: pSReg = &pCtx->ss; break; 4955 case X86_SREG_DS: pSReg = &pCtx->ds; break; 4956 case X86_SREG_FS: pSReg = &pCtx->fs; break; 4957 case X86_SREG_GS: pSReg = &pCtx->gs; break; 4958 default: 4959 AssertFailedReturn(NULL); 4960 } 5002 5003 Assert(iSegReg < X86_SREG_COUNT); 5004 AssertCompileAdjacentMembers(CPUMCTX, es, cs); 5005 AssertCompileAdjacentMembers(CPUMCTX, cs, ss); 5006 AssertCompileAdjacentMembers(CPUMCTX, ss, ds); 5007 AssertCompileAdjacentMembers(CPUMCTX, ds, fs); 5008 AssertCompileAdjacentMembers(CPUMCTX, fs, gs); 5009 PCPUMSELREG pSReg = &pCtx->es + iSegReg; 5010 4961 5011 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 4962 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg)) 5012 if (RT_LIKELY(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(IEMCPU_TO_VMCPU(pIemCpu), pSReg))) 5013 { /* likely */ } 5014 else 4963 5015 CPUMGuestLazyLoadHiddenSelectorReg(IEMCPU_TO_VMCPU(pIemCpu), pSReg); 4964 5016 #else … … 7988 8040 7989 8041 #ifdef IEM_WITH_SETJMP 7990 /** 7991 * Fetches a data dword, longjmp on error. 8042 8043 IEM_STATIC RTGCPTR iemMemApplySegmentToReadJmp(PIEMCPU pIemCpu, uint8_t iSegReg, size_t cbMem, RTGCPTR GCPtrMem) 8044 { 8045 Assert(cbMem >= 1); 8046 Assert(iSegReg < X86_SREG_COUNT); 8047 8048 /* 8049 * 64-bit mode is simpler. 8050 */ 8051 if (pIemCpu->enmCpuMode == IEMMODE_64BIT) 8052 { 8053 if (iSegReg >= X86_SREG_FS) 8054 { 8055 PCPUMSELREGHID pSel = iemSRegGetHid(pIemCpu, iSegReg); 8056 GCPtrMem += pSel->u64Base; 8057 } 8058 8059 if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1))) 8060 return GCPtrMem; 8061 } 8062 /* 8063 * 16-bit and 32-bit segmentation. 8064 */ 8065 else 8066 { 8067 PCPUMSELREGHID pSel = iemSRegGetHid(pIemCpu, iSegReg); 8068 if ( (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_DOWN)) 8069 == X86DESCATTR_P /* data, expand up */ 8070 || (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) 8071 == (X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ) /* code, read-only */ ) 8072 { 8073 /* expand up */ 8074 uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem; 8075 if (RT_LIKELY( GCPtrLast32 > pSel->u32Limit 8076 && GCPtrLast32 > (uint32_t)GCPtrMem)) 8077 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base; 8078 } 8079 else if ( (pSel->Attr.u & (X86DESCATTR_P | X86DESCATTR_UNUSABLE | X86_SEL_TYPE_CODE | X86_SEL_TYPE_DOWN)) 8080 == (X86DESCATTR_P | X86_SEL_TYPE_DOWN) /* data, expand down */ ) 8081 { 8082 /* expand down */ 8083 uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem; 8084 if (RT_LIKELY( (uint32_t)GCPtrMem > pSel->u32Limit 8085 && GCPtrLast32 <= (pSel->Attr.n.u1DefBig ? UINT32_MAX : UINT32_C(0xffff)) 8086 && GCPtrLast32 > (uint32_t)GCPtrMem)) 8087 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base; 8088 } 8089 else 8090 iemRaiseSelectorInvalidAccessJmp(pIemCpu, iSegReg, IEM_ACCESS_DATA_R); 8091 iemRaiseSelectorBoundsJmp(pIemCpu, iSegReg, IEM_ACCESS_DATA_R); 8092 } 8093 iemRaiseGeneralProtectionFault0Jmp(pIemCpu); 8094 } 8095 8096 8097 /** 8098 * Fetches a data dword, longjmp on error, fallback/safe version. 7992 8099 * 7993 8100 * @returns The dword … … 7997 8104 * @param GCPtrMem The address of the guest memory. 7998 8105 */ 7999 DECL_NO_INLINE(IEM_STATIC, uint32_t) iemMemFetchDataU32Jmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) 8000 { 8001 /* The lazy approach for now... */ 8106 IEM_STATIC uint32_t iemMemFetchDataU32SafeJmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) 8107 { 8002 8108 uint32_t const *pu32Src = (uint32_t const *)iemMemMapJmp(pIemCpu, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R); 8003 8109 uint32_t const u32Ret = *pu32Src; 8004 8110 iemMemCommitAndUnmapJmp(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R); 8005 8111 return u32Ret; 8112 } 8113 8114 8115 /** 8116 * Fetches a data dword, longjmp on error. 8117 * 8118 * @returns The dword 8119 * @param pIemCpu The IEM per CPU data. 8120 * @param iSegReg The index of the segment register to use for 8121 * this access. The base and limits are checked. 8122 * @param GCPtrMem The address of the guest memory. 8123 */ 8124 DECL_NO_INLINE(IEM_STATIC, uint32_t) iemMemFetchDataU32Jmp(PIEMCPU pIemCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) 8125 { 8126 # ifdef IEM_WITH_DATA_TLB 8127 RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pIemCpu, iSegReg, sizeof(uint32_t), GCPtrMem); 8128 if (RT_LIKELY((GCPtrEff & X86_PAGE_OFFSET_MASK) <= X86_PAGE_SIZE - sizeof(uint32_t))) 8129 { 8130 /// @todo more later. 8131 } 8132 8133 return iemMemFetchDataU32SafeJmp(pIemCpu, iSegReg, GCPtrMem); 8134 # else 8135 /* The lazy approach. */ 8136 uint32_t const *pu32Src = (uint32_t const *)iemMemMapJmp(pIemCpu, sizeof(*pu32Src), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R); 8137 uint32_t const u32Ret = *pu32Src; 8138 iemMemCommitAndUnmapJmp(pIemCpu, (void *)pu32Src, IEM_ACCESS_DATA_R); 8139 return u32Ret; 8140 # endif 8006 8141 } 8007 8142 #endif -
trunk/src/VBox/VMM/include/IEMInternal.h
r62000 r62010 319 319 } IEMTLBENTRY; 320 320 AssertCompileSize(IEMTLBENTRY, 32); 321 322 /** @name IEMTLBE_F_XXX - TLB entry flags (IEMTLBENTRY::fFlagsAndPhysRev) 323 * @{ */ 324 #define IEMTLBE_F_PT_NO_EXEC RT_BIT_64(0) /**< Page tables: Not executable. */ 325 #define IEMTLBE_F_PT_NO_WRITE RT_BIT_64(1) /**< Page tables: Not writable. */ 326 #define IEMTLBE_F_PT_NO_USER RT_BIT_64(2) /**< Page tables: Not user accessible (supervisor only). */ 327 #define IEMTLBE_F_PG_NO_WRITE RT_BIT_64(3) /**< Phys page: Not writable (access handler, ROM, whatever). */ 328 #define IEMTLBE_F_PG_NO_READ RT_BIT_64(4) /**< Phys page: Not readable (MMIO / access handler, ROM) */ 329 #define IEMTLBE_F_UNUSED RT_BIT_64(5) /**< Currently unused. */ 330 #define IEMTLBE_F_PT_NO_DIRTY RT_BIT_64(6) /**< Page tables: Not dirty (needs to be made dirty on write). */ 331 #define IEMTLBE_F_NO_MAPPINGR3 RT_BIT_64(7) /**< TLB entry: The IEMTLBENTRY::pMappingR3 member is invalid. */ 332 /** @} */ 321 333 322 334
Note:
See TracChangeset
for help on using the changeset viewer.