Changeset 72580 in vbox for trunk/src/VBox
- Timestamp:
- Jun 16, 2018 3:57:07 PM (7 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r72579 r72580 404 404 405 405 /** 406 * Worker for EMHistoryExec that checks for ring-3 returns and flags 407 * continuation of the EMHistoryExec run there. 408 */ 409 DECL_FORCE_INLINE(void) emHistoryExecSetContinueExitRecIdx(PVMCPU pVCpu, VBOXSTRICTRC rcStrict, PCEMEXITREC pExitRec) 410 { 411 pVCpu->em.s.idxContinueExitRec = UINT16_MAX; 412 #ifdef IN_RING3 413 RT_NOREF_PV(rcStrict); RT_NOREF_PV(pExitRec); 414 #else 415 switch (VBOXSTRICTRC_VAL(rcStrict)) 416 { 417 case VINF_SUCCESS: 418 default: 419 break; 420 421 /* Only status codes that EMHandleRCTmpl.h will resume EMHistoryExec with. */ 422 case VINF_IOM_R3_IOPORT_READ: /* -> emR3ExecuteIOInstruction */ 423 case VINF_IOM_R3_IOPORT_WRITE: /* -> emR3ExecuteIOInstruction */ 424 case VINF_IOM_R3_IOPORT_COMMIT_WRITE: /* -> VMCPU_FF_IOM -> VINF_EM_RESUME_R3_HISTORY_EXEC -> emR3ExecuteIOInstruction */ 425 case VINF_IOM_R3_MMIO_READ: /* -> emR3ExecuteInstruction */ 426 case VINF_IOM_R3_MMIO_WRITE: /* -> emR3ExecuteInstruction */ 427 case VINF_IOM_R3_MMIO_READ_WRITE: /* -> emR3ExecuteInstruction */ 428 case VINF_IOM_R3_MMIO_COMMIT_WRITE: /* -> VMCPU_FF_IOM -> VINF_EM_RESUME_R3_HISTORY_EXEC -> emR3ExecuteIOInstruction */ 429 case VINF_CPUM_R3_MSR_READ: /* -> emR3ExecuteInstruction */ 430 case VINF_CPUM_R3_MSR_WRITE: /* -> emR3ExecuteInstruction */ 431 case VINF_GIM_R3_HYPERCALL: /* -> emR3ExecuteInstruction */ 432 pVCpu->em.s.idxContinueExitRec = (uint16_t)(pExitRec - &pVCpu->em.s.aExitRecords[0]); 433 break; 434 } 435 #endif /* !IN_RING3 */ 436 } 437 438 439 /** 406 440 * Execute using history. 407 441 * … … 439 473 LogFlow(("EMHistoryExec/EXEC_WITH_MAX: %Rrc cExits=%u cMaxExitDistance=%u cInstructions=%u\n", 440 474 VBOXSTRICTRC_VAL(rcStrict), ExecStats.cExits, ExecStats.cMaxExitDistance, ExecStats.cInstructions)); 475 emHistoryExecSetContinueExitRecIdx(pVCpu, rcStrict, pExitRec); 441 476 return rcStrict; 442 477 } … … 456 491 LogFlow(("EMHistoryExec/EXEC_PROBE: %Rrc cExits=%u cMaxExitDistance=%u cInstructions=%u\n", 457 492 VBOXSTRICTRC_VAL(rcStrict), ExecStats.cExits, ExecStats.cMaxExitDistance, ExecStats.cInstructions)); 493 emHistoryExecSetContinueExitRecIdx(pVCpu, rcStrict, pExitRecUnconst); 458 494 if (ExecStats.cExits >= 2) 459 495 { … … 463 499 LogFlow(("EMHistoryExec/EXEC_PROBE: -> EXEC_WITH_MAX %u\n", ExecStats.cMaxExitDistance)); 464 500 } 501 #ifndef IN_RING3 502 else if (pVCpu->em.s.idxContinueExitRec != UINT16_MAX) 503 LogFlow(("EMHistoryExec/EXEC_PROBE: -> ring-3\n")); 504 #endif 465 505 else 466 506 { 467 507 pExitRecUnconst->enmAction = EMEXITACTION_NORMAL_PROBED; 508 pVCpu->em.s.idxContinueExitRec = UINT16_MAX; 468 509 LogFlow(("EMHistoryExec/EXEC_PROBE: -> PROBED\n")); 469 /** @todo check for return to ring-3 and such and optimize/reprobe. */470 510 } 471 511 return rcStrict; … … 484 524 485 525 526 /** 527 * Worker for emHistoryAddOrUpdateRecord. 528 */ 486 529 DECL_FORCE_INLINE(PCEMEXITREC) emHistoryRecordInit(PEMEXITREC pExitRec, uint64_t uFlatPC, uint32_t uFlagsAndType, uint64_t uExitNo) 487 530 { … … 497 540 498 541 542 /** 543 * Worker for emHistoryAddOrUpdateRecord. 544 */ 499 545 DECL_FORCE_INLINE(PCEMEXITREC) emHistoryRecordInitNew(PVMCPU pVCpu, PEMEXITENTRY pHistEntry, uintptr_t idxSlot, 500 546 PEMEXITREC pExitRec, uint64_t uFlatPC, … … 505 551 LogFlow(("emHistoryRecordInitNew: [%#x] = %#07x %016RX64; (%u of %u used)\n", idxSlot, uFlagsAndType, uFlatPC, 506 552 pVCpu->em.s.cExitRecordUsed, RT_ELEMENTS(pVCpu->em.s.aExitRecords) )); 553 return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo); 554 } 555 556 557 /** 558 * Worker for emHistoryAddOrUpdateRecord. 559 */ 560 DECL_FORCE_INLINE(PCEMEXITREC) emHistoryRecordInitReplacement(PEMEXITENTRY pHistEntry, uintptr_t idxSlot, 561 PEMEXITREC pExitRec, uint64_t uFlatPC, 562 uint32_t uFlagsAndType, uint64_t uExitNo) 563 { 564 pHistEntry->idxSlot = (uint32_t)idxSlot; 565 LogFlow(("emHistoryRecordInitReplacement: [%#x] = %#07x %016RX64 replacing %#07x %016RX64 with %u hits, %u exits old\n", 566 idxSlot, uFlagsAndType, uFlatPC, pExitRec->uFlagsAndType, pExitRec->uFlatPC, pExitRec->cHits, 567 uExitNo - pExitRec->uLastExitNo)); 507 568 return emHistoryRecordInit(pExitRec, uFlatPC, uFlagsAndType, uExitNo); 508 569 } … … 615 676 STAM_REL_COUNTER_INC(&pVCpu->em.s.aStatHistoryRecReplaced[iOldestStep]); 616 677 pExitRec = &pVCpu->em.s.aExitRecords[idxOldest]; 617 return emHistoryRecordInit New(pVCpu,pHistEntry, idxOldest, pExitRec, uFlatPC, uFlagsAndType, uExitNo);678 return emHistoryRecordInitReplacement(pHistEntry, idxOldest, pExitRec, uFlatPC, uFlagsAndType, uExitNo); 618 679 } 619 680 } … … 689 750 */ 690 751 if ( (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM 752 && pVCpu->em.s.fExitOptimizationEnabled 691 753 && uFlatPC != UINT64_MAX) 692 754 return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, uFlatPC, pHistEntry, uExitNo); … … 769 831 */ 770 832 if ( (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM 833 && pVCpu->em.s.fExitOptimizationEnabled 771 834 && pHistEntry->uFlatPC != UINT64_MAX) 772 835 return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, pHistEntry->uFlatPC, pHistEntry, uExitNo); … … 804 867 * If common exit type, we will insert/update the exit into the exit record hash table. 805 868 */ 806 if ((uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM) 869 if ( (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM 870 && pVCpu->em.s.fExitOptimizationEnabled) 807 871 return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, uFlatPC, pHistEntry, uExitNo); 808 872 return NULL; -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r72579 r72580 149 149 } 150 150 151 LogRel(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fRawRing1Enabled=%RTbool fIemExecutesAll=%RTbool fGuruOnTripleFault=%RTbool\n", 152 pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->fRawRing1Enabled, pVM->em.s.fIemExecutesAll, pVM->em.s.fGuruOnTripleFault)); 151 /** 152 * @cfgm{/EM/ExitOptimizationEnabled, bool, true} 153 * Whether to try correlate exit history, detect hot spots and try optimize 154 * these using IEM if there are other exits close by. 155 */ 156 bool fExitOptimizationEnabled = true; 157 rc = CFGMR3QueryBoolDef(pCfgEM, "ExitOptimizationEnabled", &fExitOptimizationEnabled, true); 158 AssertLogRelRCReturn(rc, rc); 159 for (VMCPUID i = 0; i < pVM->cCpus; i++) 160 pVM->aCpus[i].em.s.fExitOptimizationEnabled = fExitOptimizationEnabled; 161 162 LogRel(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fRawRing1Enabled=%RTbool fIemExecutesAll=%RTbool fGuruOnTripleFault=%RTbool fExitOptimizationEnabled=%RTbool\n", 163 pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->fRawRing1Enabled, pVM->em.s.fIemExecutesAll, pVM->em.s.fGuruOnTripleFault, fExitOptimizationEnabled)); 153 164 154 165 #ifdef VBOX_WITH_REM … … 175 186 PVMCPU pVCpu = &pVM->aCpus[i]; 176 187 177 pVCpu->em.s.enmState = (i == 0) ? EMSTATE_NONE : EMSTATE_WAIT_SIPI; 178 pVCpu->em.s.enmPrevState = EMSTATE_NONE; 179 pVCpu->em.s.fForceRAW = false; 180 181 pVCpu->em.s.pCtx = CPUMQueryGuestCtxPtr(pVCpu); 188 pVCpu->em.s.enmState = i == 0 ? EMSTATE_NONE : EMSTATE_WAIT_SIPI; 189 pVCpu->em.s.enmPrevState = EMSTATE_NONE; 190 pVCpu->em.s.fForceRAW = false; 191 pVCpu->em.s.u64TimeSliceStart = 0; /* paranoia */ 192 pVCpu->em.s.idxContinueExitRec = UINT16_MAX; 193 194 pVCpu->em.s.pCtx = CPUMQueryGuestCtxPtr(pVCpu); 182 195 #ifdef VBOX_WITH_RAW_MODE 183 196 if (VM_IS_RAW_MODE_ENABLED(pVM)) … … 187 200 } 188 201 #endif 189 190 /* Force reset of the time slice. */191 pVCpu->em.s.u64TimeSliceStart = 0;192 202 193 203 # define EM_REG_COUNTER(a, b, c) \ … … 1774 1784 /* IOM has pending work (comitting an I/O or MMIO write). */ 1775 1785 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_IOM)) 1786 { 1776 1787 rc = IOMR3ProcessForceFlag(pVM, pVCpu, rc); 1788 if (pVCpu->em.s.idxContinueExitRec >= RT_ELEMENTS(pVCpu->em.s.aExitRecords)) 1789 { /* half likely, or at least it's a line shorter. */ } 1790 else if (rc == VINF_SUCCESS) 1791 rc = VINF_EM_RESUME_R3_HISTORY_EXEC; 1792 else 1793 pVCpu->em.s.idxContinueExitRec = UINT16_MAX; 1794 } 1777 1795 1778 1796 #ifdef VBOX_WITH_RAW_MODE -
trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp
r72488 r72580 179 179 PCPUMCTX pCtx = pVCpu->em.s.pCtx; 180 180 #endif 181 int rc;182 181 NOREF(rcRC); 183 182 … … 199 198 */ 200 199 STAM_PROFILE_START(&pVCpu->em.s.StatIEMEmu, a); 201 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 202 rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu)); 200 201 VBOXSTRICTRC rcStrict; 202 uint32_t idxContinueExitRec = pVCpu->em.s.idxContinueExitRec; 203 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 204 if (idxContinueExitRec >= RT_ELEMENTS(pVCpu->em.s.aExitRecords)) 205 { 206 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 207 rcStrict = IEMExecOne(pVCpu); 208 } 209 else 210 { 211 RT_UNTRUSTED_VALIDATED_FENCE(); 212 rcStrict = EMHistoryExec(pVCpu, &pVCpu->em.s.aExitRecords[idxContinueExitRec], 0); 213 LogFlow(("emR3NemExecuteInstruction: %Rrc (EMHistoryExec)\n", VBOXSTRICTRC_VAL(rcStrict))); 214 } 215 203 216 STAM_PROFILE_STOP(&pVCpu->em.s.StatIEMEmu, a); 204 217 205 if ( rc == VERR_IEM_ASPECT_NOT_IMPLEMENTED206 || rc == VERR_IEM_INSTR_NOT_IMPLEMENTED)218 if ( rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED 219 || rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED) 207 220 { 208 221 #ifdef VBOX_WITH_REM … … 215 228 pVM->em.s.idLastRemCpu = pVCpu->idCpu; 216 229 217 rc = REMR3EmulateInstruction(pVM, pVCpu);230 rcStrict = REMR3EmulateInstruction(pVM, pVCpu); 218 231 EMRemUnlock(pVM); 219 232 STAM_PROFILE_STOP(&pVCpu->em.s.StatREMEmu, b); … … 222 235 #endif /* !VBOX_WITH_REM */ 223 236 } 224 return rc;237 return VBOXSTRICTRC_TODO(rcStrict); 225 238 } 226 239 … … 259 272 STAM_PROFILE_START(&pVCpu->em.s.StatIOEmu, a); 260 273 261 #if 0 262 PCPUMCTX pCtx = pVCpu->em.s.pCtx; 263 264 /* 265 * Try to restart the io instruction that was refused in ring-0. 266 */ 267 VBOXSTRICTRC rcStrict = HMR3RestartPendingIOInstr(pVM, pVCpu, pCtx); 268 if (IOM_SUCCESS(rcStrict)) 269 { 274 /* 275 * Hand it over to the interpreter. 276 */ 277 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 278 VBOXSTRICTRC rcStrict; 279 uint32_t idxContinueExitRec = pVCpu->em.s.idxContinueExitRec; 280 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE(); 281 if (idxContinueExitRec >= RT_ELEMENTS(pVCpu->em.s.aExitRecords)) 282 { 283 rcStrict = IEMExecOne(pVCpu); 284 LogFlow(("emR3NemExecuteIOInstruction: %Rrc (IEMExecOne)\n", VBOXSTRICTRC_VAL(rcStrict))); 285 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoIem); 286 } 287 else 288 { 289 RT_UNTRUSTED_VALIDATED_FENCE(); 290 rcStrict = EMHistoryExec(pVCpu, &pVCpu->em.s.aExitRecords[idxContinueExitRec], 0); 291 LogFlow(("emR3NemExecuteIOInstruction: %Rrc (EMHistoryExec)\n", VBOXSTRICTRC_VAL(rcStrict))); 270 292 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoRestarted); 271 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a); 272 return VBOXSTRICTRC_TODO(rcStrict); /* rip already updated. */ 273 } 274 AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)), 275 RT_SUCCESS_NP(rcStrict) ? VERR_IPE_UNEXPECTED_INFO_STATUS : VBOXSTRICTRC_TODO(rcStrict)); 276 #endif 277 278 /* 279 * Hand it over to the interpreter. 280 */ 281 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 282 VBOXSTRICTRC rcStrict = IEMExecOne(pVCpu); 283 LogFlow(("emR3NemExecuteIOInstruction: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 284 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoIem); 293 } 285 294 286 295 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a); -
trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
r72492 r72580 217 217 case VINF_IOM_R3_IOPORT_READ: 218 218 case VINF_IOM_R3_IOPORT_WRITE: 219 case VINF_EM_RESUME_R3_HISTORY_EXEC: /* Resume EMHistoryExec after VMCPU_FF_IOM. */ 219 220 rc = emR3ExecuteIOInstruction(pVM, pVCpu); 220 221 break; -
trunk/src/VBox/VMM/include/EMInternal.h
r72579 r72580 400 400 #endif 401 401 402 /** Pointer to the guest CPUM state. (R3 Ptr) */ 402 /** Pointer to the guest CPUM state. (R3 Ptr) 403 * @obsolete Use pVCpu->cpum.GstCtx! */ 403 404 R3PTRTYPE(PCPUMCTX) pCtx; 404 405 … … 499 500 #endif 500 501 502 /** Exit history table (6KB). */ 503 EMEXITENTRY aExitHistory[256]; 501 504 /** Where to store the next exit history entry. 502 505 * Since aExitHistory is 256 items longs, we'll just increment this and … … 504 507 * wrapped around or not. */ 505 508 uint64_t iNextExit; 506 /** Exit history table (6KB). */ 507 EMEXITENTRY aExitHistory[256]; 508 509 /** Whether exit optimizations are enabled or not. */ 510 bool fExitOptimizationEnabled; 511 /** Explicit padding. */ 512 bool afPadding2[1]; 513 /** Index into aExitRecords set by EMHistoryExec when returning to ring-3. 514 * This is UINT16_MAX if not armed. */ 515 uint16_t volatile idxContinueExitRec; 516 /** Number of exit records in use. */ 517 uint32_t cExitRecordUsed; 509 518 /** Hit statistics for each lookup step. */ 510 519 STAMCOUNTER aStatHistoryRecHits[16]; … … 515 524 /** New record statistics for each lookup step. */ 516 525 STAMCOUNTER aStatHistoryRecNew[16]; 517 /** Number of exit records in use. */ 518 uint32_t cExitRecordUsed; 519 /** Explicit padding. */ 520 uint32_t uPadding2; 526 521 527 /** Exit records (32KB). (Aligned on 32 byte boundrary.) */ 522 528 EMEXITREC aExitRecords[1024];
Note:
See TracChangeset
for help on using the changeset viewer.