- Timestamp:
- Oct 18, 2022 11:37:50 AM (2 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r97193 r97199 764 764 * @param pVM The cross context VM structure. 765 765 * @param pVCpu The cross context virtual CPU structure. 766 * @param p RegFrame Trap register frame.766 * @param pCtx Pointer to the register context for the CPU. 767 767 * @param pDis The disassembly info for the faulting instruction. 768 768 * @param pvFault The fault address. … … 771 771 * @remark The REP prefix check is left to the caller because of STOSD/W. 772 772 */ 773 DECLINLINE(bool) pgmRZPoolMonitorIsReused(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTX CORE pRegFrame, PDISCPUSTATE pDis, RTGCPTR pvFault,773 DECLINLINE(bool) pgmRZPoolMonitorIsReused(PVMCC pVM, PVMCPUCC pVCpu, PCPUMCTX pCtx, PDISCPUSTATE pDis, RTGCPTR pvFault, 774 774 PPGMPOOLPAGE pPage) 775 775 { … … 784 784 /** @todo could make this general, faulting close to rsp should be a safe reuse heuristic. */ 785 785 if ( HMHasPendingIrq(pVM) 786 && p RegFrame->rsp - pvFault < 32)786 && pCtx->rsp - pvFault < 32) 787 787 { 788 788 /* Fault caused by stack writes while trying to inject an interrupt event. */ 789 Log(("pgmRZPoolMonitorIsReused: reused %RGv for interrupt stack (rsp=%RGv).\n", pvFault, p RegFrame->rsp));789 Log(("pgmRZPoolMonitorIsReused: reused %RGv for interrupt stack (rsp=%RGv).\n", pvFault, pCtx->rsp)); 790 790 return true; 791 791 } 792 792 793 LogFlow(("Reused instr %RGv %d at %RGv param1.fUse=%llx param1.reg=%d\n", p RegFrame->rip, pDis->pCurInstr->uOpcode, pvFault, pDis->Param1.fUse, pDis->Param1.Base.idxGenReg));793 LogFlow(("Reused instr %RGv %d at %RGv param1.fUse=%llx param1.reg=%d\n", pCtx->rip, pDis->pCurInstr->uOpcode, pvFault, pDis->Param1.fUse, pDis->Param1.Base.idxGenReg)); 794 794 795 795 /* Non-supervisor mode write means it's used for something else. */ … … 824 824 case OP_STOSWD: 825 825 if ( pDis->fPrefix == (DISPREFIX_REP|DISPREFIX_REX) 826 && p RegFrame->rcx >= 0x40826 && pCtx->rcx >= 0x40 827 827 ) 828 828 { … … 881 881 * @param pPage The pool page (head). 882 882 * @param pDis The disassembly of the write instruction. 883 * @param p RegFrame The trap register frame.883 * @param pCtx Pointer to the register context for the CPU. 884 884 * @param GCPhysFault The fault address as guest physical address. 885 885 * @param pvFault The fault address. … … 887 887 */ 888 888 static int pgmRZPoolAccessPfHandlerFlush(PVMCC pVM, PVMCPUCC pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis, 889 PCPUMCTX CORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault)889 PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault) 890 890 { 891 891 NOREF(pVM); NOREF(GCPhysFault); … … 901 901 */ 902 902 int rc = VINF_SUCCESS; 903 VBOXSTRICTRC rc2 = EMInterpretInstructionDisasState(pVCpu, pDis, pRegFrame, pvFault, EMCODETYPE_ALL);903 VBOXSTRICTRC rc2 = EMInterpretInstructionDisasState(pVCpu, pDis, CPUMCTX2CORE(pCtx), pvFault, EMCODETYPE_ALL); 904 904 if (rc2 == VINF_SUCCESS) 905 905 { /* do nothing */ } … … 934 934 * @param pPage The pool page (head). 935 935 * @param pDis The disassembly of the write instruction. 936 * @param p RegFrame The trap register frame.936 * @param pCtx Pointer to the register context for the CPU. 937 937 * @param GCPhysFault The fault address as guest physical address. 938 938 * @param pvFault The fault address. 939 939 */ 940 940 DECLINLINE(int) pgmRZPoolAccessPfHandlerSTOSD(PVMCC pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis, 941 PCPUMCTX CORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault)941 PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault) 942 942 { 943 943 unsigned uIncrement = pDis->Param1.cb; … … 945 945 946 946 Assert(pDis->uCpuMode == DISCPUMODE_32BIT || pDis->uCpuMode == DISCPUMODE_64BIT); 947 Assert(p RegFrame->rcx <= 0x20);947 Assert(pCtx->rcx <= 0x20); 948 948 949 949 # ifdef VBOX_STRICT … … 971 971 PVMCPUCC pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM)); 972 972 RTGCUINTPTR pu32 = (RTGCUINTPTR)pvFault; 973 while (p RegFrame->rcx)973 while (pCtx->rcx) 974 974 { 975 975 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, NULL, uIncrement); 976 PGMPhysSimpleWriteGCPhys(pVM, GCPhysFault, &p RegFrame->rax, uIncrement);976 PGMPhysSimpleWriteGCPhys(pVM, GCPhysFault, &pCtx->rax, uIncrement); 977 977 pu32 += uIncrement; 978 978 GCPhysFault += uIncrement; 979 p RegFrame->rdi += uIncrement;980 p RegFrame->rcx--;981 } 982 p RegFrame->rip += pDis->cbInstr;979 pCtx->rdi += uIncrement; 980 pCtx->rcx--; 981 } 982 pCtx->rip += pDis->cbInstr; 983 983 984 984 LogFlow(("pgmRZPoolAccessPfHandlerSTOSD: returns\n")); … … 996 996 * @param pPage The pool page (head). 997 997 * @param pDis The disassembly of the write instruction. 998 * @param p RegFrame The trap register frame.998 * @param pCtx Pointer to the register context for the CPU. 999 999 * @param GCPhysFault The fault address as guest physical address. 1000 1000 * @param pvFault The fault address. … … 1002 1002 */ 1003 1003 DECLINLINE(int) pgmRZPoolAccessPfHandlerSimple(PVMCC pVM, PVMCPUCC pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis, 1004 PCPUMCTX CORE pRegFrame, RTGCPHYS GCPhysFault, RTGCPTR pvFault, bool *pfReused)1004 PCPUMCTX pCtx, RTGCPHYS GCPhysFault, RTGCPTR pvFault, bool *pfReused) 1005 1005 { 1006 1006 Log3(("pgmRZPoolAccessPfHandlerSimple\n")); … … 1036 1036 * Interpret the instruction. 1037 1037 */ 1038 VBOXSTRICTRC rc = EMInterpretInstructionDisasState(pVCpu, pDis, pRegFrame, pvFault, EMCODETYPE_ALL);1038 VBOXSTRICTRC rc = EMInterpretInstructionDisasState(pVCpu, pDis, CPUMCTX2CORE(pCtx), pvFault, EMCODETYPE_ALL); 1039 1039 if (RT_SUCCESS(rc)) 1040 1040 AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rc))); /* ASSUMES no complicated stuff here. */ … … 1042 1042 { 1043 1043 LogFlow(("pgmRZPoolAccessPfHandlerSimple: Interpretation failed for %04x:%RGv - opcode=%d\n", 1044 pRegFrame->cs.Sel, (RTGCPTR)pRegFrame->rip, pDis->pCurInstr->uOpcode));1044 pCtx->cs.Sel, (RTGCPTR)pCtx->rip, pDis->pCurInstr->uOpcode)); 1045 1045 rc = VINF_EM_RAW_EMULATE_INSTR; 1046 1046 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitorPf,EmulateInstr)); … … 1088 1088 * @remarks The @a uUser argument is the index of the PGMPOOLPAGE. 1089 1089 */ 1090 DECLCALLBACK(VBOXSTRICTRC) pgmRZPoolAccessPfHandler(PVMCC pVM, PVMCPUCC pVCpu, RTGCUINT uErrorCode, PCPUMCTX CORE pRegFrame,1090 DECLCALLBACK(VBOXSTRICTRC) pgmRZPoolAccessPfHandler(PVMCC pVM, PVMCPUCC pVCpu, RTGCUINT uErrorCode, PCPUMCTX pCtx, 1091 1091 RTGCPTR pvFault, RTGCPHYS GCPhysFault, uint64_t uUser) 1092 1092 { … … 1185 1185 */ 1186 1186 pVCpu->pgm.s.cPoolAccessHandler++; 1187 if ( pPage->GCPtrLastAccessHandlerRip >= p RegFrame->rip - 0x40 /* observed loops in Windows 7 x64 */1188 && pPage->GCPtrLastAccessHandlerRip < p RegFrame->rip + 0x401187 if ( pPage->GCPtrLastAccessHandlerRip >= pCtx->rip - 0x40 /* observed loops in Windows 7 x64 */ 1188 && pPage->GCPtrLastAccessHandlerRip < pCtx->rip + 0x40 1189 1189 && pvFault == (pPage->GCPtrLastAccessHandlerFault + pDis->Param1.cb) 1190 1190 && pVCpu->pgm.s.cPoolAccessHandler == pPage->cLastAccessHandler + 1) … … 1213 1213 || pgmPoolIsPageLocked(pPage) 1214 1214 ) 1215 && !(fReused = pgmRZPoolMonitorIsReused(pVM, pVCpu, p RegFrame, pDis, pvFault, pPage))1215 && !(fReused = pgmRZPoolMonitorIsReused(pVM, pVCpu, pCtx, pDis, pvFault, pPage)) 1216 1216 && !pgmRZPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK)) 1217 1217 { … … 1221 1221 if (!(pDis->fPrefix & (DISPREFIX_REP | DISPREFIX_REPNE))) 1222 1222 { 1223 rc = pgmRZPoolAccessPfHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, p RegFrame, GCPhysFault, pvFault, &fReused);1223 rc = pgmRZPoolAccessPfHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault, &fReused); 1224 1224 if (fReused) 1225 1225 goto flushPage; … … 1235 1235 pPage->GCPtrLastAccessHandlerFault = pvFault; 1236 1236 pPage->cLastAccessHandler = pVCpu->pgm.s.cPoolAccessHandler; 1237 pPage->GCPtrLastAccessHandlerRip = p RegFrame->rip;1237 pPage->GCPtrLastAccessHandlerRip = pCtx->rip; 1238 1238 /* Make sure we don't kick out a page too quickly. */ 1239 1239 if (pPage->cModifications > 8) … … 1261 1261 */ 1262 1262 if ( pDis->pCurInstr->uOpcode == OP_STOSWD 1263 && !p RegFrame->eflags.Bits.u1DF1263 && !pCtx->eflags.Bits.u1DF 1264 1264 && pDis->uOpMode == pDis->uCpuMode 1265 1265 && pDis->uAddrMode == pDis->uCpuMode) … … 1269 1269 if ( pDis->uCpuMode == DISCPUMODE_32BIT 1270 1270 && pDis->fPrefix == DISPREFIX_REP 1271 && p RegFrame->ecx <= 0x201272 && p RegFrame->ecx * 4 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)1271 && pCtx->ecx <= 0x20 1272 && pCtx->ecx * 4 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK) 1273 1273 && !((uintptr_t)pvFault & 3) 1274 && (p RegFrame->eax == 0 || pRegFrame->eax == 0x80) /* the two values observed. */1274 && (pCtx->eax == 0 || pCtx->eax == 0x80) /* the two values observed. */ 1275 1275 ) 1276 1276 { 1277 1277 fValidStosd = true; 1278 p RegFrame->rcx &= 0xffffffff; /* paranoia */1278 pCtx->rcx &= 0xffffffff; /* paranoia */ 1279 1279 } 1280 1280 else 1281 1281 if ( pDis->uCpuMode == DISCPUMODE_64BIT 1282 1282 && pDis->fPrefix == (DISPREFIX_REP | DISPREFIX_REX) 1283 && p RegFrame->rcx <= 0x201284 && p RegFrame->rcx * 8 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK)1283 && pCtx->rcx <= 0x20 1284 && pCtx->rcx * 8 <= GUEST_PAGE_SIZE - ((uintptr_t)pvFault & GUEST_PAGE_OFFSET_MASK) 1285 1285 && !((uintptr_t)pvFault & 7) 1286 && (p RegFrame->rax == 0 || pRegFrame->rax == 0x80) /* the two values observed. */1286 && (pCtx->rax == 0 || pCtx->rax == 0x80) /* the two values observed. */ 1287 1287 ) 1288 1288 { … … 1292 1292 if (fValidStosd) 1293 1293 { 1294 rc = pgmRZPoolAccessPfHandlerSTOSD(pVM, pPool, pPage, pDis, p RegFrame, GCPhysFault, pvFault);1294 rc = pgmRZPoolAccessPfHandlerSTOSD(pVM, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault); 1295 1295 STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->StatMonitorPfRZ, &pPool->StatMonitorPfRZRepStosd, a); 1296 1296 PGM_UNLOCK(pVM); … … 1302 1302 STAM_COUNTER_INC(&pPool->StatMonitorPfRZRepPrefix); 1303 1303 Log4(("pgmRZPoolAccessPfHandler: eax=%#x ecx=%#x edi=%#x esi=%#x rip=%RGv opcode=%d prefix=%#x\n", 1304 p RegFrame->eax, pRegFrame->ecx, pRegFrame->edi, pRegFrame->esi, (RTGCPTR)pRegFrame->rip, pDis->pCurInstr->uOpcode, pDis->fPrefix));1304 pCtx->eax, pCtx->ecx, pCtx->edi, pCtx->esi, (RTGCPTR)pCtx->rip, pDis->pCurInstr->uOpcode, pDis->fPrefix)); 1305 1305 fNotReusedNotForking = true; 1306 1306 } … … 1314 1314 && (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT) 1315 1315 && ( fNotReusedNotForking 1316 || ( !pgmRZPoolMonitorIsReused(pVM, pVCpu, p RegFrame, pDis, pvFault, pPage)1316 || ( !pgmRZPoolMonitorIsReused(pVM, pVCpu, pCtx, pDis, pvFault, pPage) 1317 1317 && !pgmRZPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK)) 1318 1318 ) … … 1391 1391 * the reuse detection must be fixed. 1392 1392 */ 1393 rc = pgmRZPoolAccessPfHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, p RegFrame, GCPhysFault, pvFault);1393 rc = pgmRZPoolAccessPfHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, pCtx, GCPhysFault, pvFault); 1394 1394 if ( rc == VINF_EM_RAW_EMULATE_INSTR 1395 1395 && fReused) … … 1397 1397 Assert(!PGMPOOL_PAGE_IS_NESTED(pPage)); /* temporary, remove later. */ 1398 1398 /* Make sure that the current instruction still has shadow page backing, otherwise we'll end up in a loop. */ 1399 if (PGMShwGetPage(pVCpu, p RegFrame->rip, NULL, NULL) == VINF_SUCCESS)1399 if (PGMShwGetPage(pVCpu, pCtx->rip, NULL, NULL) == VINF_SUCCESS) 1400 1400 rc = VINF_SUCCESS; /* safe to restart the instruction. */ 1401 1401 }
Note:
See TracChangeset
for help on using the changeset viewer.

