- Timestamp:
- Jun 15, 2018 11:00:02 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/em.h
r72559 r72560 215 215 * 216 216 * @{ */ 217 #define EMEXIT_F_TYPE_MASK UINT32_C(0x0fff) /**< The exit type mask. */ 218 #define EMEXIT_F_KIND_EM UINT32_C(0x0000) /**< EMEXITTYPE */ 219 #define EMEXIT_F_KIND_VMX UINT32_C(0x1000) /**< VT-x exit codes. */ 220 #define EMEXIT_F_KIND_SVM UINT32_C(0x2000) /**< SVM exit codes. */ 221 #define EMEXIT_F_KIND_NEM UINT32_C(0x3000) /**< NEMEXITTYPE */ 222 #define EMEXIT_F_KIND_XCPT UINT32_C(0x4000) /**< Exception numbers (raw-mode). */ 223 #define EMEXIT_F_KIND_MASK UINT32_C(0x7000) 224 #define EMEXIT_F_CS_EIP UINT32_C(0x8000) 217 #define EMEXIT_F_TYPE_MASK UINT32_C(0x00000fff) /**< The exit type mask. */ 218 #define EMEXIT_F_KIND_EM UINT32_C(0x00000000) /**< EMEXITTYPE */ 219 #define EMEXIT_F_KIND_VMX UINT32_C(0x00001000) /**< VT-x exit codes. */ 220 #define EMEXIT_F_KIND_SVM UINT32_C(0x00002000) /**< SVM exit codes. */ 221 #define EMEXIT_F_KIND_NEM UINT32_C(0x00003000) /**< NEMEXITTYPE */ 222 #define EMEXIT_F_KIND_XCPT UINT32_C(0x00004000) /**< Exception numbers (raw-mode). */ 223 #define EMEXIT_F_KIND_MASK UINT32_C(0x00007000) 224 #define EMEXIT_F_CS_EIP UINT32_C(0x00008000) /**< The PC is EIP in the low dword and CS in the high. */ 225 #define EMEXIT_F_UNFLATTENED_PC UINT32_C(0x00010000) /**< The PC hasn't had CS.BASE added to it. */ 225 226 /** Combines flags and exit type into EMHistoryAddExit() input. */ 226 227 #define EMEXIT_MAKE_FLAGS_AND_TYPE(a_fFlags, a_uType) ((a_fFlags) | (uint32_t)(a_uType)) … … 239 240 VMMRC_INT_DECL(void) EMRCHistoryAddExitNoTs(PVMCPU pVCpu, uint32_t uFlagsAndType, uint16_t uCs, uint32_t uEip); 240 241 #endif 242 #ifdef IN_RING0 243 VMMR0_INT_DECL(void) EMR0HistoryUpdatePC(PVMCPU pVCpu, uint64_t uFlatPC, bool fFlattened); 244 #endif 245 241 246 242 247 /** @name Deprecated interpretation related APIs (use IEM). -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r72559 r72560 407 407 * 408 408 * @returns Suggested action to take. 409 * @param pVCpu The c orss context virtual CPU structure.409 * @param pVCpu The cross context virtual CPU structure. 410 410 * @param uFlagsAndType Combined flags and type (see EMEXIT_MAKE_FLAGS_AND_TYPE). 411 * @param uFlatPC The flattened program counter (RIP). 411 * @param uFlatPC The flattened program counter (RIP). UINT64_MAX if not available. 412 412 * @param uTimestamp The TSC value for the exit, 0 if not available. 413 413 * @thread EMT(pVCpu) … … 446 446 * we start seriously caring about raw-mode again, we may extend it. 447 447 * 448 * @param pVCpu The c orss context virtual CPU structure.448 * @param pVCpu The cross context virtual CPU structure. 449 449 * @param uFlagsAndType Combined flags and type (see EMEXIT_MAKE_FLAGS_AND_TYPE). 450 450 * @param uCs The CS. … … 460 460 pHistEntry->uFlagsAndType = uFlagsAndType | EMEXIT_F_CS_EIP; 461 461 pHistEntry->idxSlot = UINT32_MAX; 462 } 463 #endif 464 465 466 #ifdef IN_RING0 467 /** 468 * Interface that VT-x uses to supply the PC of an exit when CS:RIP is being read. 469 * 470 * @param pVCpu The cross context virtual CPU structure. 471 * @param uFlatPC The flattened program counter (RIP). UINT64_MAX if not available. 472 * @param fFlattened Set if RIP was subjected to CS.BASE, clear if not. 473 */ 474 VMMR0_INT_DECL(void) EMR0HistoryUpdatePC(PVMCPU pVCpu, uint64_t uFlatPC, bool fFlattened) 475 { 476 AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitHistory) == 256); 477 PEMEXITENTRY pHistEntry = &pVCpu->em.s.aExitHistory[((uintptr_t)pVCpu->em.s.iNextExit - 1) & 0xff]; 478 pHistEntry->uFlatPC = uFlatPC; 479 if (fFlattened) 480 pHistEntry->uFlagsAndType &= ~EMEXIT_F_UNFLATTENED_PC; 481 else 482 pHistEntry->uFlagsAndType |= EMEXIT_F_UNFLATTENED_PC; 462 483 } 463 484 #endif -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r72534 r72560 1040 1040 pVmcbCtrl->u64MSRPMPhysAddr = pVCpu->hm.s.svm.HCPhysMsrBitmap; 1041 1041 1042 /* Initialize the #VMEXIT history array with end-of-array markers (UINT16_MAX). */1043 Assert(!pVCpu->hm.s.idxExitHistoryFree);1044 HMCPU_EXIT_HISTORY_RESET(pVCpu);1045 1046 1042 /* Initially all VMCB clean bits MBZ indicating that everything should be loaded from the VMCB in memory. */ 1047 1043 Assert(pVmcbCtrl->u32VmcbCleanBits == 0); … … 1061 1057 memcpy(pbMsrBitmapCur, pbMsrBitmap, SVM_MSRPM_PAGES << X86_PAGE_4K_SHIFT); 1062 1058 pVmcbCtrlCur->u64MSRPMPhysAddr = pVCpuCur->hm.s.svm.HCPhysMsrBitmap; 1063 1064 /* Initialize the #VMEXIT history array with end-of-array markers (UINT16_MAX). */1065 Assert(!pVCpuCur->hm.s.idxExitHistoryFree);1066 HMCPU_EXIT_HISTORY_RESET(pVCpuCur);1067 1059 1068 1060 /* Initially all VMCB clean bits MBZ indicating that everything should be loaded from the VMCB in memory. */ … … 4584 4576 4585 4577 pSvmTransient->u64ExitCode = pVmcbCtrl->u64ExitCode; /* Save the #VMEXIT reason. */ 4586 HMCPU_EXIT_HISTORY_ADD(pVCpu, pVmcbCtrl->u64ExitCode); /* Update the #VMEXIT history array. */4587 4578 pVmcbCtrl->u32VmcbCleanBits = HMSVM_VMCB_CLEAN_ALL; /* Mark the VMCB-state cache as unmodified by VMM. */ 4588 4579 pSvmTransient->fVectoringDoublePF = false; /* Vectoring double page-fault needs to be determined later. */ … … 4611 4602 } 4612 4603 } 4604 4605 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_SVM, pSvmTransient->u64ExitCode & EMEXIT_F_TYPE_MASK), 4606 pMixedCtx->cs.u64Base + pMixedCtx->rip, uHostTsc); 4613 4607 } 4614 4608 -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r72533 r72560 2844 2844 Log4(("VMXR0SetupVM: pVCpu=%p idCpu=%RU32\n", pVCpu, pVCpu->idCpu)); 2845 2845 2846 /* Initialize the VM-exit history array with end-of-array markers (UINT16_MAX). */2847 Assert(!pVCpu->hm.s.idxExitHistoryFree);2848 HMCPU_EXIT_HISTORY_RESET(pVCpu);2849 2850 2846 /* Set revision dword at the beginning of the VMCS structure. */ 2851 2847 *(uint32_t *)pVCpu->hm.s.vmx.pvVmcs = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hm.s.vmx.Msrs.u64BasicInfo); … … 3653 3649 Log4(("Load[%RU32]: VMX_VMCS_GUEST_RIP=%#RX64 fContextUseFlags=%#RX32\n", pVCpu->idCpu, pMixedCtx->rip, 3654 3650 HMCPU_CF_VALUE(pVCpu))); 3651 3652 /* Update the exit history entry with the correct CS.BASE + RIP or just RIP. */ 3653 if (HMCPU_CF_IS_SET(pVCpu, HM_CHANGED_GUEST_SEGMENT_REGS)) 3654 EMR0HistoryUpdatePC(pVCpu, pMixedCtx->cs.u64Base + pMixedCtx->rip, true); 3655 else 3656 EMR0HistoryUpdatePC(pVCpu, pMixedCtx->rip, false); 3655 3657 } 3656 3658 return rc; … … 4594 4596 Log4(("Load[%RU32]: CS=%#RX16 Base=%#RX64 Limit=%#RX32 Attr=%#RX32\n", pVCpu->idCpu, pMixedCtx->cs.Sel, 4595 4597 pMixedCtx->cs.u64Base, pMixedCtx->cs.u32Limit, pMixedCtx->cs.Attr.u)); 4598 4599 /* Update the exit history entry with the correct CS.BASE + RIP. */ 4600 if (HMCPU_CF_IS_PENDING(pVCpu, HM_CHANGED_GUEST_RIP)) 4601 EMR0HistoryUpdatePC(pVCpu, pMixedCtx->cs.u64Base + pMixedCtx->rip, true); 4596 4602 } 4597 4603 … … 9208 9214 { 9209 9215 NOREF(pVM); 9216 uint64_t uHostTsc = ASMReadTSC(); 9210 9217 9211 9218 Assert(!VMMRZCallRing3IsEnabled(pVCpu)); … … 9219 9226 9220 9227 if (!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT)) 9221 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC()+ pVCpu->hm.s.vmx.u64TSCOffset);9228 TMCpuTickSetLastSeen(pVCpu, uHostTsc + pVCpu->hm.s.vmx.u64TSCOffset); 9222 9229 9223 9230 STAM_PROFILE_ADV_STOP_START(&pVCpu->hm.s.StatInGC, &pVCpu->hm.s.StatExit1, x); … … 9261 9268 * 9262 9269 * See Intel spec. 26.7 "VM-Entry failures during or after loading guest state". 9270 * 9271 * Note! We don't have CS or RIP at this point. Will probably address that later 9272 * by amending the history entry added here. 9263 9273 */ 9264 HMCPU_EXIT_HISTORY_ADD(pVCpu, pVmxTransient->uExitReason); 9274 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_SVM, pVmxTransient->uExitReason & EMEXIT_F_TYPE_MASK), 9275 UINT64_MAX, uHostTsc); 9265 9276 9266 9277 if (!pVmxTransient->fVMEntryFailed) -
trunk/src/VBox/VMM/VMMR3/EMR3Dbg.cpp
r72558 r72560 290 290 * Register info dumpers. 291 291 */ 292 int rc = DBGFR3InfoRegisterInternalEx(pVM, "exits", "Dumps the VM-exit history.", 293 emR3InfoExitHistory, DBGFINFO_FLAGS_ALL_EMTS); 292 const char *pszExitsDesc = "Dumps the VM-exit history. Arguments: Number of entries; 'asc', 'ascending' or 'reverse'."; 293 int rc = DBGFR3InfoRegisterInternalEx(pVM, "exits", pszExitsDesc, emR3InfoExitHistory, DBGFINFO_FLAGS_ALL_EMTS); 294 AssertLogRelRCReturn(rc, rc); 295 rc = DBGFR3InfoRegisterInternalEx(pVM, "exithistory", pszExitsDesc, emR3InfoExitHistory, DBGFINFO_FLAGS_ALL_EMTS); 294 296 AssertLogRelRCReturn(rc, rc); 295 297 -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r72555 r72560 383 383 static DECLCALLBACK(int) hmR3Load(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass); 384 384 static DECLCALLBACK(void) hmR3InfoSvmNstGstVmcbCache(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 385 static DECLCALLBACK(void) hmR3Info ExitHistory(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);385 static DECLCALLBACK(void) hmR3Info(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 386 386 static DECLCALLBACK(void) hmR3InfoEventPending(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs); 387 387 static int hmR3InitCPU(PVM pVM); … … 439 439 * Register info handlers. 440 440 */ 441 rc = DBGFR3InfoRegisterInternalEx(pVM, "exithistory", "Dumps the HM VM-exit history.", hmR3InfoExitHistory, 442 DBGFINFO_FLAGS_ALL_EMTS); 441 rc = DBGFR3InfoRegisterInternalEx(pVM, "hm", "Dumps HM info.", hmR3Info, DBGFINFO_FLAGS_ALL_EMTS); 443 442 AssertRCReturn(rc, rc); 444 443 … … 3680 3679 * @param pszArgs Arguments, ignored. 3681 3680 */ 3682 static DECLCALLBACK(void) hmR3Info ExitHistory(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)3681 static DECLCALLBACK(void) hmR3Info(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 3683 3682 { 3684 3683 NOREF(pszArgs); … … 3689 3688 if (HMIsEnabled(pVM)) 3690 3689 { 3691 bool const fIsVtx = pVM->hm.s.vmx.fSupported; 3692 const char * const *papszDesc; 3693 unsigned cMaxExitDesc; 3694 if (fIsVtx) 3695 { 3696 cMaxExitDesc = MAX_EXITREASON_VTX; 3697 papszDesc = &g_apszVTxExitReasons[0]; 3698 pHlp->pfnPrintf(pHlp, "CPU[%u]: VT-x VM-exit history:\n", pVCpu->idCpu); 3699 } 3690 if (pVM->hm.s.vmx.fSupported) 3691 pHlp->pfnPrintf(pHlp, "CPU[%u]: VT-x info:\n", pVCpu->idCpu); 3700 3692 else 3701 { 3702 cMaxExitDesc = MAX_EXITREASON_AMDV; 3703 papszDesc = &g_apszAmdVExitReasons[0]; 3704 pHlp->pfnPrintf(pHlp, "CPU[%u]: AMD-V #VMEXIT history:\n", pVCpu->idCpu); 3705 } 3706 3707 pHlp->pfnPrintf(pHlp, " idxExitHistoryFree = %u\n", pVCpu->hm.s.idxExitHistoryFree); 3708 unsigned const idxLast = pVCpu->hm.s.idxExitHistoryFree > 0 ? 3709 pVCpu->hm.s.idxExitHistoryFree - 1 : 3710 RT_ELEMENTS(pVCpu->hm.s.auExitHistory) - 1; 3711 for (unsigned i = 0; i < RT_ELEMENTS(pVCpu->hm.s.auExitHistory); i++) 3712 { 3713 uint16_t const uExit = pVCpu->hm.s.auExitHistory[i]; 3714 const char *pszExit = NULL; 3715 if (uExit <= cMaxExitDesc) 3716 pszExit = papszDesc[uExit]; 3717 else if (!fIsVtx) 3718 pszExit = hmSvmGetSpecialExitReasonDesc(uExit); 3719 else 3720 pszExit = NULL; 3721 3722 pHlp->pfnPrintf(pHlp, " auExitHistory[%2u] = 0x%04x %s %s\n", i, uExit, pszExit, 3723 idxLast == i ? "<-- Latest exit" : ""); 3724 } 3725 pHlp->pfnPrintf(pHlp, "HM error = %#x (%u)\n", pVCpu->hm.s.u32HMError, pVCpu->hm.s.u32HMError); 3693 pHlp->pfnPrintf(pHlp, "CPU[%u]: AMD-V info:\n", pVCpu->idCpu); 3694 pHlp->pfnPrintf(pHlp, " HM error = %#x (%u)\n", pVCpu->hm.s.u32HMError, pVCpu->hm.s.u32HMError); 3726 3695 } 3727 3696 else -
trunk/src/VBox/VMM/include/EMInternal.h
r72555 r72560 306 306 typedef struct EMEXITENTRY 307 307 { 308 /** The flat PC (CS:EIP/RIP) address of the exit. */ 308 /** The flat PC (CS:EIP/RIP) address of the exit. 309 * UINT64_MAX if not available. */ 309 310 uint64_t uFlatPC; 310 311 /** The EMEXIT_MAKE_FLAGS_AND_TYPE */ -
trunk/src/VBox/VMM/include/HMInternal.h
r72532 r72560 128 128 #define HMCPU_CF_VALUE(pVCpu) (ASMAtomicUoReadU32(&(pVCpu)->hm.s.fContextUseFlags)) 129 129 130 131 /** Resets/initializes the VM-exit/\#VMEXIT history array. */132 #define HMCPU_EXIT_HISTORY_RESET(pVCpu) (memset(&(pVCpu)->hm.s.auExitHistory, 0xff, sizeof((pVCpu)->hm.s.auExitHistory)))133 134 /** Updates the VM-exit/\#VMEXIT history array. */135 #define HMCPU_EXIT_HISTORY_ADD(pVCpu, a_ExitReason) \136 do { \137 AssertMsg((pVCpu)->hm.s.idxExitHistoryFree < RT_ELEMENTS((pVCpu)->hm.s.auExitHistory), ("%u\n", (pVCpu)->hm.s.idxExitHistoryFree)); \138 (pVCpu)->hm.s.auExitHistory[(pVCpu)->hm.s.idxExitHistoryFree++] = (uint16_t)(a_ExitReason); \139 if ((pVCpu)->hm.s.idxExitHistoryFree == RT_ELEMENTS((pVCpu)->hm.s.auExitHistory)) \140 (pVCpu)->hm.s.idxExitHistoryFree = 0; \141 (pVCpu)->hm.s.auExitHistory[(pVCpu)->hm.s.idxExitHistoryFree] = UINT16_MAX; \142 } while (0)143 130 144 131 /** Maximum number of exit reason statistics counters. */ … … 970 957 * HMR0Enter and cleared in HMR0Leave. */ 971 958 RTCPUID idEnteredCpu; 972 973 /** VT-x/AMD-V VM-exit/\#VMXEXIT history, circular array. */974 uint16_t auExitHistory[31];975 /** The index of the next free slot in the history array. */976 uint16_t idxExitHistoryFree;977 959 978 960 /** For saving stack space, the disassembler state is allocated here instead of
Note:
See TracChangeset
for help on using the changeset viewer.