Changeset 102593 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Dec 13, 2023 10:41:23 PM (15 months ago)
- svn:sync-xref-src-repo-rev:
- 160746
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r102587 r102593 1586 1586 * Used by TB code when it wants to raise a \#GP(0). 1587 1587 */ 1588 IEM_DECL_NATIVE_HLP_DEF(int, iemNativeHlpExecRaiseGp0,(PVMCPUCC pVCpu, uint8_t idxInstr)) 1589 { 1590 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING 1591 pVCpu->iem.s.idxTbCurInstr = idxInstr; 1592 #else 1593 RT_NOREF(idxInstr); 1594 #endif 1588 IEM_DECL_NATIVE_HLP_DEF(int, iemNativeHlpExecRaiseGp0,(PVMCPUCC pVCpu)) 1589 { 1595 1590 iemRaiseGeneralProtectionFault0Jmp(pVCpu); 1596 1591 #ifndef _MSC_VER … … 4501 4496 iemNativeEmitCheckGprCanonicalMaybeRaiseGp0(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxAddrReg, uint8_t idxInstr) 4502 4497 { 4503 RT_NOREF(idxInstr);4504 4505 4498 /* 4506 4499 * Make sure we don't have any outstanding guest register writes as we may … … 4508 4501 */ 4509 4502 off = iemNativeRegFlushPendingWrites(pReNative, off); 4503 4504 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING 4505 off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr)); 4506 #else 4507 RT_NOREF(idxInstr); 4508 #endif 4510 4509 4511 4510 #ifdef RT_ARCH_AMD64 … … 4521 4520 off = iemNativeEmitAddGpr32Imm(pReNative, off, iTmpReg, (int32_t)0x8000); 4522 4521 off = iemNativeEmitShiftGprRight(pReNative, off, iTmpReg, 16); 4523 4524 # ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING4525 4522 off = iemNativeEmitJnzToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0); 4526 # else4527 uint32_t const offFixup = off;4528 off = iemNativeEmitJzToFixed(pReNative, off, 0);4529 off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);4530 off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);4531 iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);4532 # endif4533 4523 4534 4524 iemNativeRegFreeTmp(pReNative, iTmpReg); … … 4542 4532 * add x1, x0, x1 4543 4533 * cmp xzr, x1, lsr 48 4544 * and either:4545 4534 * b.ne .Lraisexcpt 4546 * or:4547 * b.eq .Lnoexcept4548 * movz x1, #instruction-number4549 * b .Lraisexcpt4550 * .Lnoexcept:4551 4535 */ 4552 4536 uint8_t const iTmpReg = iemNativeRegAllocTmp(pReNative, &off); … … 4555 4539 off = iemNativeEmitAddTwoGprs(pReNative, off, iTmpReg, idxAddrReg); 4556 4540 off = iemNativeEmitCmpArm64(pReNative, off, ARMV8_A64_REG_XZR, idxAddrReg, true /*f64Bit*/, 48 /*cShift*/, kArmv8A64InstrShift_Lsr); 4557 4558 # ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING4559 4541 off = iemNativeEmitJnzToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0); 4560 # else4561 uint32_t const offFixup = off;4562 off = iemNativeEmitJzToFixed(pReNative, off, 0);4563 off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);4564 off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);4565 iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);4566 # endif4567 4542 4568 4543 iemNativeRegFreeTmp(pReNative, iTmpReg); … … 4598 4573 off = iemNativeRegFlushPendingWrites(pReNative, off); 4599 4574 4575 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING 4576 off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr)); 4577 #else 4578 RT_NOREF(idxInstr); 4579 #endif 4580 4600 4581 /** @todo implement expand down/whatnot checking */ 4601 4582 AssertStmt(idxSegReg == X86_SREG_CS, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_CASE_NOT_IMPLEMENTED_1)); … … 4606 4587 4607 4588 off = iemNativeEmitCmpGpr32WithGpr(pReNative, off, idxAddrReg, iTmpLimReg); 4608 4609 #ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING4610 4589 off = iemNativeEmitJaToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0); 4611 RT_NOREF(idxInstr);4612 #else4613 uint32_t const offFixup = off;4614 off = iemNativeEmitJbeToFixed(pReNative, off, 0);4615 off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, idxInstr);4616 off = iemNativeEmitJmpToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0);4617 iemNativeFixupFixedJump(pReNative, offFixup, off /*offTarget*/);4618 #endif4619 4590 4620 4591 iemNativeRegFreeTmp(pReNative, iTmpLimReg); … … 4808 4779 iemNativeLabelDefine(pReNative, idxLabel, off); 4809 4780 4810 /* iemNativeHlpExecRaiseGp0(PVMCPUCC pVCpu , uint8_t idxInstr) */4781 /* iemNativeHlpExecRaiseGp0(PVMCPUCC pVCpu) */ 4811 4782 off = iemNativeEmitLoadGprFromGpr(pReNative, off, IEMNATIVE_CALL_ARG0_GREG, IEMNATIVE_REG_FIXED_PVMCPU); 4812 #ifndef IEMNATIVE_WITH_INSTRUCTION_COUNTING4813 off = iemNativeEmitLoadGpr8Imm(pReNative, off, IEMNATIVE_CALL_ARG1_GREG, 0);4814 #endif4815 4783 off = iemNativeEmitCallImm(pReNative, off, (uintptr_t)iemNativeHlpExecRaiseGp0); 4816 4784 … … 11076 11044 11077 11045 11046 /** 11047 * Macro that emits the 16/32-bit CS.LIM check. 11048 */ 11049 #define BODY_CHECK_CS_LIM(a_cbInstr) \ 11050 off = iemNativeEmitBltInCheckCsLim(pReNative, off, (a_cbInstr), pCallEntry->idxInstr) 11051 11052 DECL_FORCE_INLINE(uint32_t) 11053 iemNativeEmitBltInCheckCsLim(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cbInstr, uint8_t idxInstr) 11054 { 11055 Assert(cbInstr > 0); 11056 Assert(cbInstr < 16); 11057 11058 /* Before we start, update the instruction number in case we raise an exception. */ 11059 #ifdef IEMNATIVE_WITH_INSTRUCTION_COUNTING 11060 off = iemNativeEmitStoreImmToVCpuU8(pReNative, off, idxInstr, RT_UOFFSETOF(VMCPUCC, iem.s.idxTbCurInstr)); 11061 #else 11062 RT_NOREF(idxInstr); 11063 #endif 11064 11065 /* 11066 * We need CS.LIM and RIP here. When cbInstr is larger than 1, we also need 11067 * a temporary register for calculating the last address of the instruction. 11068 * 11069 * The calculation and comparisons are 32-bit. We ASSUME that the incoming 11070 * RIP isn't totally invalid, i.e. that any jump/call/ret/iret instruction 11071 * that last updated EIP here checked it already, and that we're therefore 11072 * safe in the 32-bit wrap-around scenario to only check that the last byte 11073 * is within CS.LIM. In the case of instruction-by-instruction advancing 11074 * up to a EIP wrap-around, we know that CS.LIM is 4G-1 because the limit 11075 * must be using 4KB granularity and the previous instruction was fine. 11076 */ 11077 uint8_t const idxRegPc = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, 11078 kIemNativeGstRegUse_ReadOnly); 11079 uint8_t const idxRegCsLim = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_SEG_LIMIT(X86_SREG_CS), 11080 kIemNativeGstRegUse_ReadOnly); 11081 #ifdef RT_ARCH_AMD64 11082 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8+1); 11083 #elif defined(RT_ARCH_ARM64) 11084 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 11085 #else 11086 # error "Port me" 11087 #endif 11088 11089 if (cbInstr != 1) 11090 { 11091 uint8_t const idxRegTmp = iemNativeRegAllocTmp(pReNative, &off); 11092 11093 /* 11094 * 1. idxRegTmp = idxRegPc + cbInstr; 11095 * 2. if idxRegTmp > idxRegCsLim then raise #GP(0). 11096 */ 11097 #ifdef RT_ARCH_AMD64 11098 /* 1. lea tmp32, [Pc + cbInstr - 1] */ 11099 if (idxRegTmp >= 8 || idxRegPc >= 8) 11100 pbCodeBuf[off++] = (idxRegTmp < 8 ? 0 : X86_OP_REX_R) | (idxRegPc < 8 ? 0 : X86_OP_REX_B); 11101 pbCodeBuf[off++] = 0x8d; 11102 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, idxRegTmp & 7, idxRegPc & 7); 11103 if ((idxRegPc & 7) == X86_GREG_xSP) 11104 pbCodeBuf[off++] = X86_SIB_MAKE(idxRegPc & 7, 4 /*no index*/, 0); 11105 pbCodeBuf[off++] = cbInstr - 1; 11106 11107 /* 2. cmp tmp32(r), CsLim(r/m). */ 11108 if (idxRegTmp >= 8 || idxRegCsLim >= 8) 11109 pbCodeBuf[off++] = (idxRegTmp < 8 ? 0 : X86_OP_REX_R) | (idxRegCsLim < 8 ? 0 : X86_OP_REX_B); 11110 pbCodeBuf[off++] = 0x3b; 11111 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegTmp & 7, idxRegCsLim & 7); 11112 11113 #elif defined(RT_ARCH_ARM64) 11114 /* 1. add tmp32, Pc, #cbInstr-1 */ 11115 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, idxRegTmp, idxRegPc, cbInstr - 1, false /*f64Bit*/); 11116 /* 2. cmp tmp32, CsLim */ 11117 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR, idxRegTmp, idxRegCsLim, 11118 false /*f64Bit*/, true /*fSetFlags*/); 11119 11120 #endif 11121 iemNativeRegFreeTmp(pReNative, idxRegTmp); 11122 } 11123 else 11124 { 11125 /* 11126 * Here we can skip step 1 and compare PC and CS.LIM directly. 11127 */ 11128 #ifdef RT_ARCH_AMD64 11129 /* 2. cmp eip(r), CsLim(r/m). */ 11130 if (idxRegPc >= 8 || idxRegCsLim >= 8) 11131 pbCodeBuf[off++] = (idxRegPc < 8 ? 0 : X86_OP_REX_R) | (idxRegCsLim < 8 ? 0 : X86_OP_REX_B); 11132 pbCodeBuf[off++] = 0x3b; 11133 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegPc & 7, idxRegCsLim & 7); 11134 11135 #elif defined(RT_ARCH_ARM64) 11136 /* 2. cmp Pc, CsLim */ 11137 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR, idxRegPc, idxRegCsLim, 11138 false /*f64Bit*/, true /*fSetFlags*/); 11139 11140 #endif 11141 } 11142 11143 /* 3. Jump if greater. */ 11144 off = iemNativeEmitJaToNewLabel(pReNative, off, kIemNativeLabelType_RaiseGp0); 11145 11146 iemNativeRegFreeTmp(pReNative, idxRegCsLim); 11147 iemNativeRegFreeTmp(pReNative, idxRegPc); 11148 return off; 11149 } 11150 11151 #ifdef BODY_CHECK_CS_LIM 11152 /** 11153 * Built-in function that checks the EIP/IP + uParam0 is within CS.LIM, 11154 * raising a \#GP(0) if this isn't the case. 11155 */ 11156 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLim) 11157 { 11158 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11159 BODY_CHECK_CS_LIM(cbInstr); 11160 return off; 11161 } 11162 #endif 11163 11164 11165 #if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_CS_LIM) 11166 /** 11167 * Built-in function for re-checking opcodes and CS.LIM after an instruction 11168 * that may have modified them. 11169 */ 11170 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodes) 11171 { 11172 PCIEMTB const pTb = pVCpu->iem.s.pCurTbR3; 11173 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11174 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11175 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11176 BODY_CHECK_CS_LIM(cbInstr); 11177 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11178 return off; 11179 } 11180 #endif 11181 11182 11183 #if defined(BODY_CHECK_OPCODES) 11184 /** 11185 * Built-in function for re-checking opcodes after an instruction that may have 11186 * modified them. 11187 */ 11188 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodes) 11189 { 11190 PCIEMTB const pTb = pReNative->pTbOrg; 11191 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11192 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11193 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11194 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11195 return off; 11196 } 11197 #endif 11198 11199 11200 #if defined(BODY_CHECK_OPCODES) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11201 /** 11202 * Built-in function for re-checking opcodes and considering the need for CS.LIM 11203 * checking after an instruction that may have modified them. 11204 */ 11205 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesConsiderCsLim) 11206 { 11207 PCIEMTB const pTb = pReNative->pTbOrg; 11208 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11209 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11210 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11211 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11212 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11213 return off; 11214 } 11215 #endif 11216 11217 11218 /* 11219 * Post-branching checkers. 11220 */ 11221 11222 #if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH) && defined(BODY_CHECK_CS_LIM) 11223 /** 11224 * Built-in function for checking CS.LIM, checking the PC and checking opcodes 11225 * after conditional branching within the same page. 11226 * 11227 * @see iemThreadedFunc_BltIn_CheckPcAndOpcodes 11228 */ 11229 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndPcAndOpcodes) 11230 { 11231 PCIEMTB const pTb = pReNative->pTbOrg; 11232 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11233 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11234 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11235 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11236 BODY_CHECK_CS_LIM(cbInstr); 11237 BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr); 11238 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11239 //LogFunc(("okay\n")); 11240 return off; 11241 } 11242 #endif 11243 11244 11245 #if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH) 11246 /** 11247 * Built-in function for checking the PC and checking opcodes after conditional 11248 * branching within the same page. 11249 * 11250 * @see iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes 11251 */ 11252 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckPcAndOpcodes) 11253 { 11254 PCIEMTB const pTb = pReNative->pTbOrg; 11255 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11256 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11257 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11258 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11259 BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr); 11260 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11261 //LogFunc(("okay\n")); 11262 return off; 11263 } 11264 #endif 11265 11266 11267 #if defined(BODY_CHECK_OPCODES) && defined(BODY_CHECK_PC_AFTER_BRANCH) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11268 /** 11269 * Built-in function for checking the PC and checking opcodes and considering 11270 * the need for CS.LIM checking after conditional branching within the same 11271 * page. 11272 * 11273 * @see iemThreadedFunc_BltIn_CheckCsLimAndPcAndOpcodes 11274 */ 11275 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckPcAndOpcodesConsiderCsLim) 11276 { 11277 PCIEMTB const pTb = pReNative->pTbOrg; 11278 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11279 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11280 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11281 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11282 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11283 BODY_CHECK_PC_AFTER_BRANCH(pTb, idxRange, cbInstr); 11284 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11285 //LogFunc(("okay\n")); 11286 return off; 11287 } 11288 #endif 11289 11290 11291 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH) && defined(BODY_CHECK_CS_LIM) 11292 /** 11293 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when 11294 * transitioning to a different code page. 11295 * 11296 * The code page transition can either be natural over onto the next page (with 11297 * the instruction starting at page offset zero) or by means of branching. 11298 * 11299 * @see iemThreadedFunc_BltIn_CheckOpcodesLoadingTlb 11300 */ 11301 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb) 11302 { 11303 PCIEMTB const pTb = pReNative->pTbOrg; 11304 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11305 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11306 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11307 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11308 BODY_CHECK_CS_LIM(cbInstr); 11309 BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr); 11310 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11311 //LogFunc(("okay\n")); 11312 return off; 11313 } 11314 #endif 11315 11316 11317 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH) 11318 /** 11319 * Built-in function for loading TLB and checking opcodes when transitioning to 11320 * a different code page. 11321 * 11322 * The code page transition can either be natural over onto the next page (with 11323 * the instruction starting at page offset zero) or by means of branching. 11324 * 11325 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb 11326 */ 11327 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlb) 11328 { 11329 PCIEMTB const pTb = pReNative->pTbOrg; 11330 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11331 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11332 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11333 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11334 BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr); 11335 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11336 //LogFunc(("okay\n")); 11337 return off; 11338 } 11339 #endif 11340 11341 11342 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_AFTER_BRANCH) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11343 /** 11344 * Built-in function for loading TLB and checking opcodes and considering the 11345 * need for CS.LIM checking when transitioning to a different code page. 11346 * 11347 * The code page transition can either be natural over onto the next page (with 11348 * the instruction starting at page offset zero) or by means of branching. 11349 * 11350 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb 11351 */ 11352 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim) 11353 { 11354 PCIEMTB const pTb = pReNative->pTbOrg; 11355 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11356 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11357 uint32_t const offRange = (uint32_t)pCallEntry->auParams[2]; 11358 //LogFunc(("idxRange=%u @ %#x LB %#x: offPhysPage=%#x LB %#x\n", idxRange, offRange, cbInstr, pTb->aRanges[idxRange].offPhysPage, pTb->aRanges[idxRange].cbOpcodes)); 11359 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11360 BODY_LOAD_TLB_AFTER_BRANCH(pTb, idxRange, cbInstr); 11361 BODY_CHECK_OPCODES(pTb, idxRange, offRange, cbInstr); 11362 //LogFunc(("okay\n")); 11363 return off; 11364 } 11365 #endif 11366 11367 11368 11369 /* 11370 * Natural page crossing checkers. 11371 */ 11372 11373 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM) 11374 /** 11375 * Built-in function for checking CS.LIM, loading TLB and checking opcodes on 11376 * both pages when transitioning to a different code page. 11377 * 11378 * This is used when the previous instruction requires revalidation of opcodes 11379 * bytes and the current instruction stries a page boundrary with opcode bytes 11380 * in both the old and new page. 11381 * 11382 * @see iemThreadedFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb 11383 */ 11384 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb) 11385 { 11386 PCIEMTB const pTb = pReNative->pTbOrg; 11387 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11388 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11389 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11390 uint32_t const offRange1 = (uint32_t)pCallEntry->auParams[2]; 11391 uint32_t const idxRange2 = idxRange1 + 1; 11392 BODY_CHECK_CS_LIM(cbInstr); 11393 BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr); 11394 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11395 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11396 return off; 11397 } 11398 #endif 11399 11400 11401 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) 11402 /** 11403 * Built-in function for loading TLB and checking opcodes on both pages when 11404 * transitioning to a different code page. 11405 * 11406 * This is used when the previous instruction requires revalidation of opcodes 11407 * bytes and the current instruction stries a page boundrary with opcode bytes 11408 * in both the old and new page. 11409 * 11410 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb 11411 */ 11412 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb) 11413 { 11414 PCIEMTB const pTb = pReNative->pTbOrg; 11415 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11416 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11417 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11418 uint32_t const offRange1 = (uint32_t)pCallEntry->auParams[2]; 11419 uint32_t const idxRange2 = idxRange1 + 1; 11420 BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr); 11421 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11422 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11423 return off; 11424 } 11425 #endif 11426 11427 11428 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11429 /** 11430 * Built-in function for loading TLB and checking opcodes on both pages and 11431 * considering the need for CS.LIM checking when transitioning to a different 11432 * code page. 11433 * 11434 * This is used when the previous instruction requires revalidation of opcodes 11435 * bytes and the current instruction stries a page boundrary with opcode bytes 11436 * in both the old and new page. 11437 * 11438 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb 11439 */ 11440 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim) 11441 { 11442 PCIEMTB const pTb = pReNative->pTbOrg; 11443 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11444 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11445 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11446 uint32_t const offRange1 = (uint32_t)pCallEntry->auParams[2]; 11447 uint32_t const idxRange2 = idxRange1 + 1; 11448 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11449 BODY_CHECK_OPCODES(pTb, idxRange1, offRange1, cbInstr); 11450 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11451 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11452 return off; 11453 } 11454 #endif 11455 11456 11457 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM) 11458 /** 11459 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when 11460 * advancing naturally to a different code page. 11461 * 11462 * Only opcodes on the new page is checked. 11463 * 11464 * @see iemThreadedFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb 11465 */ 11466 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb) 11467 { 11468 PCIEMTB const pTb = pReNative->pTbOrg; 11469 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11470 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11471 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11472 //uint32_t const offRange1 = (uint32_t)uParam2; 11473 uint32_t const idxRange2 = idxRange1 + 1; 11474 BODY_CHECK_CS_LIM(cbInstr); 11475 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11476 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11477 return off; 11478 } 11479 #endif 11480 11481 11482 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) 11483 /** 11484 * Built-in function for loading TLB and checking opcodes when advancing 11485 * naturally to a different code page. 11486 * 11487 * Only opcodes on the new page is checked. 11488 * 11489 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb 11490 */ 11491 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb) 11492 { 11493 PCIEMTB const pTb = pReNative->pTbOrg; 11494 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11495 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11496 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11497 //uint32_t const offRange1 = (uint32_t)pCallEntry->auParams[2]; 11498 uint32_t const idxRange2 = idxRange1 + 1; 11499 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11500 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11501 return off; 11502 } 11503 #endif 11504 11505 11506 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11507 /** 11508 * Built-in function for loading TLB and checking opcodes and considering the 11509 * need for CS.LIM checking when advancing naturally to a different code page. 11510 * 11511 * Only opcodes on the new page is checked. 11512 * 11513 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb 11514 */ 11515 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim) 11516 { 11517 PCIEMTB const pTb = pReNative->pTbOrg; 11518 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11519 uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32); 11520 uint32_t const idxRange1 = (uint32_t)pCallEntry->auParams[1]; 11521 //uint32_t const offRange1 = (uint32_t)pCallEntry->auParams[2]; 11522 uint32_t const idxRange2 = idxRange1 + 1; 11523 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11524 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, cbStartPage, idxRange2, cbInstr); 11525 BODY_CHECK_OPCODES(pTb, idxRange2, 0, cbInstr); 11526 return off; 11527 } 11528 #endif 11529 11530 11531 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CHECK_CS_LIM) 11532 /** 11533 * Built-in function for checking CS.LIM, loading TLB and checking opcodes when 11534 * advancing naturally to a different code page with first instr at byte 0. 11535 * 11536 * @see iemThreadedFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb 11537 */ 11538 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb) 11539 { 11540 PCIEMTB const pTb = pReNative->pTbOrg; 11541 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11542 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11543 BODY_CHECK_CS_LIM(cbInstr); 11544 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr); 11545 //Assert(pVCpu->iem.s.offCurInstrStart == 0); 11546 BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr); 11547 return off; 11548 } 11549 #endif 11550 11551 11552 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) 11553 /** 11554 * Built-in function for loading TLB and checking opcodes when advancing 11555 * naturally to a different code page with first instr at byte 0. 11556 * 11557 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb 11558 */ 11559 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb) 11560 { 11561 PCIEMTB const pTb = pReNative->pTbOrg; 11562 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11563 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11564 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr); 11565 //Assert(pVCpu->iem.s.offCurInstrStart == 0); 11566 BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr); 11567 return off; 11568 } 11569 #endif 11570 11571 11572 #if defined(BODY_CHECK_OPCODES) && defined(BODY_LOAD_TLB_FOR_NEW_PAGE) && defined(BODY_CONSIDER_CS_LIM_CHECKING) 11573 /** 11574 * Built-in function for loading TLB and checking opcodes and considering the 11575 * need for CS.LIM checking when advancing naturally to a different code page 11576 * with first instr at byte 0. 11577 * 11578 * @see iemThreadedFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb 11579 */ 11580 static IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim) 11581 { 11582 PCIEMTB const pTb = pReNative->pTbOrg; 11583 uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0]; 11584 uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1]; 11585 BODY_CONSIDER_CS_LIM_CHECKING(pTb, cbInstr); 11586 BODY_LOAD_TLB_FOR_NEW_PAGE(pTb, 0, idxRange, cbInstr); 11587 //Assert(pVCpu->iem.s.offCurInstrStart == 0); 11588 BODY_CHECK_OPCODES(pTb, idxRange, 0, cbInstr); 11589 return off; 11590 } 11591 #endif 11592 11078 11593 11079 11594 /********************************************************************************************************************************* … … 11421 11936 break; 11422 11937 case kIemNativeLabelType_TlbMiss: 11423 pszName = " CheckIrq_TlbMiss";11938 pszName = "TlbMiss"; 11424 11939 fNumbered = true; 11425 11940 break; 11426 11941 case kIemNativeLabelType_TlbDone: 11427 pszName = " CheckIrq_TlbDone";11942 pszName = "TlbDone"; 11428 11943 fNumbered = true; 11429 11944 break; -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
r102585 r102593 1964 1964 ( 'CheckMode', 1, True ), 1965 1965 ( 'CheckHwInstrBps', 0, False ), 1966 ( 'CheckCsLim', 1, False),1966 ( 'CheckCsLim', 1, True ), 1967 1967 1968 1968 ( 'CheckCsLimAndOpcodes', 3, False ),
Note:
See TracChangeset
for help on using the changeset viewer.