- Timestamp:
- Jun 14, 2018 9:28:31 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123048
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r72490 r72555 401 401 402 402 #endif /* IN_RING3 */ 403 404 405 /** 406 * Adds an exit to the history for this CPU. 407 * 408 * @returns Suggested action to take. 409 * @param pVCpu The corss context virtual CPU structure. 410 * @param uFlagsAndType Combined flags and type (see EMEXIT_MAKE_FLAGS_AND_TYPE). 411 * @param uFlatPC The flattened program counter (RIP). 412 * @param uTimestamp The TSC value for the exit, 0 if not available. 413 * @thread EMT(pVCpu) 414 */ 415 VMM_INT_DECL(EMEXITACTION) EMHistoryAddExit(PVMCPU pVCpu, uint32_t uFlagsAndType, uint64_t uFlatPC, uint64_t uTimestamp) 416 { 417 VMCPU_ASSERT_EMT(pVCpu); 418 419 /* 420 * Add the exit history entry. 421 */ 422 AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitHistory) == 256); 423 PEMEXITENTRY pHistEntry = &pVCpu->em.s.aExitHistory[(uintptr_t)(pVCpu->em.s.iNextExit++) & 0xff]; 424 pHistEntry->uFlatPC = uFlatPC; 425 pHistEntry->uTimestamp = uTimestamp; 426 pHistEntry->uFlagsAndType = uFlagsAndType; 427 pHistEntry->idxSlot = UINT32_MAX; 428 429 /* 430 * If common exit type, we will insert/update the exit into the shared hash table. 431 */ 432 if ((uFlagsAndType & EMEXIT_F_KIND_MASK) == EMEXIT_F_KIND_EM) 433 { 434 /** @todo later */ 435 } 436 437 return EMEXITACTION_NORMAL; 438 } 439 403 440 404 441 /** -
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r72551 r72555 1909 1909 * Emulate the memory access, either access handler or special memory. 1910 1910 */ 1911 EMHistoryAddExit(pVCpu, 1912 pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 1913 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE) 1914 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ), 1915 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 1911 1916 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header); 1912 1917 VBOXSTRICTRC rcStrict; … … 1998 2003 * Emulate the memory access, either access handler or special memory. 1999 2004 */ 2005 EMHistoryAddExit(pVCpu, 2006 pExit->MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessWrite 2007 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_WRITE) 2008 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO_READ), 2009 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2010 2000 2011 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 2001 2012 rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM | CPUMCTX_EXTRN_DS | CPUMCTX_EXTRN_ES); … … 2052 2063 * Simple port I/O. 2053 2064 */ 2065 EMHistoryAddExit(pVCpu, 2066 pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 2067 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_WRITE) 2068 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_READ), 2069 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2070 2054 2071 static uint32_t const s_fAndMask[8] = 2055 2072 { UINT32_MAX, UINT32_C(0xff), UINT32_C(0xffff), UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX }; … … 2125 2142 * the opcode bytes for possible evil prefixes. 2126 2143 */ 2144 EMHistoryAddExit(pVCpu, 2145 pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 2146 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_WRITE) 2147 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_READ), 2148 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2149 2127 2150 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header); 2128 2151 pCtx->fExtrn &= ~( CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDI | CPUMCTX_EXTRN_RSI … … 2196 2219 * Simple port I/O. 2197 2220 */ 2221 EMHistoryAddExit(pVCpu, 2222 pExit->MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessWrite 2223 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_WRITE) 2224 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_READ), 2225 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2226 2198 2227 static uint32_t const s_fAndMask[8] = 2199 2228 { UINT32_MAX, UINT32_C(0xff), UINT32_C(0xffff), UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX }; … … 2249 2278 * the opcode bytes for possible evil prefixes. 2250 2279 */ 2280 EMHistoryAddExit(pVCpu, 2281 pExit->MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessWrite 2282 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_WRITE) 2283 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_READ), 2284 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2285 2251 2286 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 2252 2287 pCtx->fExtrn &= ~( CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDI | CPUMCTX_EXTRN_RSI … … 2320 2355 * Just copy the state we've got and handle it in the loop for now. 2321 2356 */ 2357 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_INTTERRUPT_WINDOW), 2358 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2359 2322 2360 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, &pMsg->Header); 2323 2361 Log4(("IntWinExit/%u: %04x:%08RX64/%s: %u IF=%d InterruptShadow=%d\n", … … 2354 2392 * Just copy the state we've got and handle it in the loop for now. 2355 2393 */ 2394 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_INTTERRUPT_WINDOW), 2395 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2396 2356 2397 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 2357 2398 Log4(("IntWinExit/%u: %04x:%08RX64/%s: %u IF=%d InterruptShadow=%d\n", … … 2374 2415 * @param pMsg The message. 2375 2416 * @param pCtx The register context. 2417 * @sa nemR3WinHandleExitCpuId 2376 2418 */ 2377 2419 NEM_TMPL_STATIC VBOXSTRICTRC nemHCWinHandleMessageCpuId(PVMCPU pVCpu, HV_X64_CPUID_INTERCEPT_MESSAGE const *pMsg, PCPUMCTX pCtx) … … 2385 2427 * function and make everyone use it. 2386 2428 */ 2429 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_CPUID), 2430 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2431 2387 2432 /** @todo Combine implementations into IEMExecDecodedCpuId as this will 2388 2433 * only get weirder with nested VT-x and AMD-V support. */ … … 2419 2464 * @param pExit The VM exit information to handle. 2420 2465 * @param pCtx The register context. 2421 * @sa nemHCWinHandleMessage InterruptWindow2466 * @sa nemHCWinHandleMessageCpuId 2422 2467 */ 2423 2468 NEM_TMPL_STATIC VBOXSTRICTRC … … 2432 2477 * function and make everyone use it. 2433 2478 */ 2479 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_CPUID), 2480 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2481 2434 2482 /** @todo Combine implementations into IEMExecDecodedCpuId as this will 2435 2483 * only get weirder with nested VT-x and AMD-V support. */ … … 2487 2535 if (pMsg->Header.ExecutionState.Cpl == 0) 2488 2536 { 2537 EMHistoryAddExit(pVCpu, 2538 pMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE 2539 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_WRITE) 2540 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_READ), 2541 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2542 2489 2543 /* 2490 2544 * Get all the MSR state. Since we're getting EFER, we also need to … … 2613 2667 * get CR0, CR4 and CR3. 2614 2668 */ 2669 EMHistoryAddExit(pVCpu, 2670 pExit->MsrAccess.AccessInfo.IsWrite 2671 ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_WRITE) 2672 : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MSR_READ), 2673 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2674 2615 2675 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 2616 2676 rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, … … 2873 2933 case X86_XCPT_UD: 2874 2934 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionUd); 2935 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_UD), 2936 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2937 2875 2938 if (nemHcWinIsInterestingUndefinedOpcode(pMsg->InstructionByteCount, pMsg->InstructionBytes, 2876 2939 pMsg->Header.ExecutionState.EferLma && pMsg->Header.CsSegment.Long )) … … 2893 2956 case X86_XCPT_DB: 2894 2957 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionDb); 2958 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_DB), 2959 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2895 2960 Log4(("XcptExit/%u: %04x:%08RX64/%s: #DB - TODO\n", 2896 2961 pVCpu->idCpu, pMsg->Header.CsSegment.Selector, pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header) )); … … 2899 2964 case X86_XCPT_BP: 2900 2965 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionBp); 2966 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_BP), 2967 pMsg->Header.Rip + pMsg->Header.CsSegment.Base, ASMReadTSC()); 2901 2968 Log4(("XcptExit/%u: %04x:%08RX64/%s: #BP - TODO - %u\n", pVCpu->idCpu, pMsg->Header.CsSegment.Selector, 2902 2969 pMsg->Header.Rip, nemHCWinExecStateToLogStr(&pMsg->Header), pMsg->Header.InstructionLength)); … … 2971 3038 case X86_XCPT_UD: 2972 3039 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionUd); 3040 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_UD), 3041 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2973 3042 if (nemHcWinIsInterestingUndefinedOpcode(pExit->VpException.InstructionByteCount, pExit->VpException.InstructionBytes, 2974 3043 pExit->VpContext.ExecutionState.EferLma && pExit->VpContext.Cs.Long )) … … 2994 3063 case X86_XCPT_DB: 2995 3064 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionDb); 3065 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_DB), 3066 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 2996 3067 Log4(("XcptExit/%u: %04x:%08RX64/%s: #DB - TODO\n", 2997 3068 pVCpu->idCpu, pExit->VpContext.Cs.Selector, pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext) )); … … 3000 3071 case X86_XCPT_BP: 3001 3072 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionBp); 3073 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_XCPT_BP), 3074 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 3002 3075 Log4(("XcptExit/%u: %04x:%08RX64/%s: #BP - TODO - %u\n", pVCpu->idCpu, pExit->VpContext.Cs.Selector, 3003 3076 pExit->VpContext.Rip, nemR3WinExecStateToLogStr(&pExit->VpContext), pExit->VpContext.InstructionLength)); … … 3057 3130 * Let IEM decide whether this is really it. 3058 3131 */ 3132 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_UNRECOVERABLE_EXCEPTION), 3133 pMsgHdr->Rip + pMsgHdr->CsSegment.Base, ASMReadTSC()); 3059 3134 nemHCWinCopyStateFromX64Header(pVCpu, pCtx, pMsgHdr); 3060 3135 VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, pGVCpu, pCtx, … … 3112 3187 * Let IEM decide whether this is really it. 3113 3188 */ 3189 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_UNRECOVERABLE_EXCEPTION), 3190 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 3114 3191 nemR3WinCopyStateFromX64Header(pVCpu, pCtx, &pExit->VpContext); 3115 3192 VBOXSTRICTRC rcStrict = nemHCWinImportStateIfNeededStrict(pVCpu, NULL, pCtx, … … 3181 3258 case HvMessageTypeX64Halt: 3182 3259 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitHalt); 3260 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_HALT), 3261 pMsg->X64InterceptHeader.Rip + pMsg->X64InterceptHeader.CsSegment.Base, ASMReadTSC()); 3183 3262 Log4(("HaltExit\n")); 3184 3263 return VINF_EM_HALT; … … 3263 3342 case WHvRunVpExitReasonX64Halt: 3264 3343 STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitHalt); 3344 EMHistoryAddExit(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_NEM, NEMEXITTYPE_HALT), 3345 pExit->VpContext.Rip + pExit->VpContext.Cs.Base, ASMReadTSC()); 3265 3346 Log4(("HaltExit\n")); 3266 3347 return VINF_EM_HALT; -
trunk/src/VBox/VMM/VMMR3/EMR3Dbg.cpp
r69111 r72555 22 22 #define LOG_GROUP LOG_GROUP_EM 23 23 #include <VBox/vmm/em.h> 24 #include <VBox/vmm/hm.h> 25 #include <VBox/vmm/nem.h> 24 26 #include <VBox/dbg.h> 25 27 #include "EMInternal.h" 28 #include <VBox/vmm/vm.h> 29 #include <iprt/string.h> 30 #include <iprt/ctype.h> 26 31 27 32 … … 66 71 }; 67 72 73 VMM_INT_DECL(const char *) EMR3GetExitTypeName(uint32_t uExitType) 74 { 75 switch ((EMEXITTYPE)uExitType) 76 { 77 case EMEXITTYPE_INVALID: return "invalid"; 78 case EMEXITTYPE_IO_PORT_READ: return "I/O port read"; 79 case EMEXITTYPE_IO_PORT_WRITE: return "I/O port write"; 80 case EMEXITTYPE_IO_PORT_STR_READ: return "I/O port string read"; 81 case EMEXITTYPE_IO_PORT_STR_WRITE: return "I/O port string write"; 82 case EMEXITTYPE_MMIO_READ: return "MMIO read"; 83 case EMEXITTYPE_MMIO_WRITE: return "MMIO write"; 84 case EMEXITTYPE_MSR_READ: return "MSR read"; 85 case EMEXITTYPE_MSR_WRITE: return "MSR write"; 86 case EMEXITTYPE_CPUID: return "CPUID"; 87 } 88 return NULL; 89 } 90 91 /** 92 * Translates flags+type into an exit name. 93 * 94 * @returns Exit name. 95 * @param uFlagsAndType The exit to name. 96 * @param pszFallback Buffer for formatting a numeric fallback. 97 * @param cbFallback Size of fallback buffer. 98 */ 99 static const char *emR3HistoryGetExitName(uint32_t uFlagsAndType, char *pszFallback, size_t cbFallback) 100 { 101 const char *pszExitName; 102 switch (uFlagsAndType & EMEXIT_F_KIND_MASK) 103 { 104 case EMEXIT_F_KIND_EM: 105 pszExitName = EMR3GetExitTypeName(uFlagsAndType & EMEXIT_F_TYPE_MASK); 106 break; 107 108 case EMEXIT_F_KIND_VMX: 109 pszExitName = HMR3GetVmxExitName( uFlagsAndType & EMEXIT_F_TYPE_MASK); 110 break; 111 112 case EMEXIT_F_KIND_SVM: 113 pszExitName = HMR3GetSvmExitName( uFlagsAndType & EMEXIT_F_TYPE_MASK); 114 break; 115 116 case EMEXIT_F_KIND_NEM: 117 pszExitName = NEMR3GetExitName( uFlagsAndType & EMEXIT_F_TYPE_MASK); 118 break; 119 120 case EMEXIT_F_KIND_XCPT: 121 switch (uFlagsAndType & EMEXIT_F_TYPE_MASK) 122 { 123 case X86_XCPT_DE: return "Xcpt #DE"; 124 case X86_XCPT_DB: return "Xcpt #DB"; 125 case X86_XCPT_NMI: return "Xcpt #NMI"; 126 case X86_XCPT_BP: return "Xcpt #BP"; 127 case X86_XCPT_OF: return "Xcpt #OF"; 128 case X86_XCPT_BR: return "Xcpt #BR"; 129 case X86_XCPT_UD: return "Xcpt #UD"; 130 case X86_XCPT_NM: return "Xcpt #NM"; 131 case X86_XCPT_DF: return "Xcpt #DF"; 132 case X86_XCPT_CO_SEG_OVERRUN: return "Xcpt #CO_SEG_OVERRUN"; 133 case X86_XCPT_TS: return "Xcpt #TS"; 134 case X86_XCPT_NP: return "Xcpt #NP"; 135 case X86_XCPT_SS: return "Xcpt #SS"; 136 case X86_XCPT_GP: return "Xcpt #GP"; 137 case X86_XCPT_PF: return "Xcpt #PF"; 138 case X86_XCPT_MF: return "Xcpt #MF"; 139 case X86_XCPT_AC: return "Xcpt #AC"; 140 case X86_XCPT_MC: return "Xcpt #MC"; 141 case X86_XCPT_XF: return "Xcpt #XF"; 142 case X86_XCPT_VE: return "Xcpt #VE"; 143 case X86_XCPT_SX: return "Xcpt #SX"; 144 default: 145 pszExitName = NULL; 146 break; 147 } 148 break; 149 150 default: 151 AssertFailed(); 152 pszExitName = NULL; 153 break; 154 } 155 if (pszExitName) 156 return pszExitName; 157 RTStrPrintf(pszFallback, cbFallback, "%#06x", uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_TYPE_MASK)); 158 return pszFallback; 159 } 160 161 162 /** 163 * Displays the VM-exit history. 164 * 165 * @param pVM The cross context VM structure. 166 * @param pHlp The info helper functions. 167 * @param pszArgs Arguments, ignored. 168 */ 169 static DECLCALLBACK(void) emR3InfoExitHistory(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs) 170 { 171 NOREF(pszArgs); 172 173 /* 174 * Figure out target cpu and parse arguments. 175 */ 176 PVMCPU pVCpu = VMMGetCpu(pVM); 177 if (!pVCpu) 178 pVCpu = &pVM->aCpus[0]; 179 bool fReverse = true; 180 uint32_t cLeft = RT_ELEMENTS(pVCpu->em.s.aExitHistory); 181 182 while (pszArgs && *pszArgs) 183 { 184 pszArgs = RTStrStripL(pszArgs); 185 if (!*pszArgs) 186 break; 187 if (RT_C_IS_DIGIT(*pszArgs)) 188 { 189 /* The number to dump. */ 190 uint32_t uValue = cLeft; 191 RTStrToUInt32Ex(pszArgs, (char **)&pszArgs, 0, &uValue); 192 if (uValue > 0) 193 cLeft = RT_MIN(uValue, RT_ELEMENTS(pVCpu->em.s.aExitHistory)); 194 } 195 else if (RTStrCmp(pszArgs, "reverse") == 0) 196 { 197 pszArgs += 7; 198 fReverse = true; 199 } 200 else if (RTStrCmp(pszArgs, "ascending") == 0) 201 { 202 pszArgs += 9; 203 fReverse = false; 204 } 205 else if (RTStrCmp(pszArgs, "asc") == 0) 206 { 207 pszArgs += 3; 208 fReverse = false; 209 } 210 else 211 { 212 const char *pszStart = pszArgs; 213 while (*pszArgs && !RT_C_IS_SPACE(*pszArgs)) 214 pszArgs++; 215 pHlp->pfnPrintf(pHlp, "Unknown option: %.*s\n", pszArgs - pszStart, pszArgs); 216 } 217 } 218 219 /* 220 * Do the job. 221 */ 222 uint64_t idx = pVCpu->em.s.iNextExit; 223 if (idx == 0) 224 pHlp->pfnPrintf(pHlp, "CPU[%u]: VM-exit history: empty\n", pVCpu->idCpu); 225 else 226 { 227 /* 228 * Print header. 229 */ 230 pHlp->pfnPrintf(pHlp, "CPU[%u]: VM-exit history:\n", pVCpu->idCpu); 231 pHlp->pfnPrintf(pHlp, " Exit No.: TSC timestamp / delta Flat RIP Exit Name\n"); 232 233 /* 234 * Adjust bounds if ascending order. 235 */ 236 if (!fReverse) 237 { 238 if (idx > cLeft) 239 idx -= cLeft; 240 else 241 { 242 cLeft = idx; 243 idx = 0; 244 } 245 } 246 247 /* 248 * Print the entries. 249 */ 250 uint64_t uPrevTimestamp = 0; 251 do 252 { 253 if (fReverse) 254 idx -= 1; 255 PCEMEXITENTRY const pEntry = &pVCpu->em.s.aExitHistory[(uintptr_t)idx & 0xff]; 256 if (!fReverse) 257 idx += 1; 258 259 /* Get the exit name. */ 260 char szExitName[16]; 261 const char *pszExitName = emR3HistoryGetExitName(pEntry->uFlagsAndType, szExitName, sizeof(szExitName)); 262 263 int64_t offDelta = uPrevTimestamp != 0 && pEntry->uTimestamp != 0 ? pEntry->uTimestamp - uPrevTimestamp : 0; 264 uPrevTimestamp = pEntry->uTimestamp; 265 266 if (pEntry->idxSlot == UINT32_MAX) 267 pHlp->pfnPrintf(pHlp, " %10RU64: %#018RX64/%+-9RI64 %016RX64 %#06x %s\n", 268 idx, pEntry->uTimestamp, offDelta, pEntry->uFlatPC, pEntry->uFlagsAndType, pszExitName); 269 else 270 { 271 /** @todo more on this later */ 272 pHlp->pfnPrintf(pHlp, " %10RU64: %#018RX64/%+-9RI64 %016RX64 %#06x %s slot=%#x\n", 273 idx, pEntry->uTimestamp, offDelta, pEntry->uFlatPC, pEntry->uFlagsAndType, pszExitName, 274 pEntry->idxSlot); 275 } 276 } while (--cLeft > 0 && idx > 0); 277 } 278 } 279 68 280 69 281 int emR3InitDbg(PVM pVM) 70 282 { 71 RT_NOREF_PV(pVM); 72 int rc = VINF_SUCCESS; 283 /* 284 * Register info dumpers. 285 */ 286 int rc = DBGFR3InfoRegisterInternalEx(pVM, "exits", "Dumps the VM-exit history.", 287 emR3InfoExitHistory, DBGFINFO_FLAGS_ALL_EMTS); 288 AssertLogRelRCReturn(rc, rc); 289 73 290 #ifdef VBOX_WITH_DEBUGGER 291 /* 292 * Register debugger commands. 293 */ 74 294 rc = DBGCRegisterCommands(&g_aCmds[0], RT_ELEMENTS(g_aCmds)); 75 AssertLogRelRC (rc);295 AssertLogRelRCReturn(rc, rc); 76 296 #endif 77 return rc; 78 } 79 297 298 return VINF_SUCCESS; 299 } 300 -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r72208 r72555 3646 3646 3647 3647 /** 3648 * Gets the name of a VT-x exit code. 3649 * 3650 * @returns Pointer to read only string if @a uExit is known, otherwise NULL. 3651 * @param uExit The VT-x exit to name. 3652 */ 3653 VMMR3DECL(const char *) HMR3GetVmxExitName(uint32_t uExit) 3654 { 3655 if (uExit < RT_ELEMENTS(g_apszVTxExitReasons)) 3656 return g_apszVTxExitReasons[uExit]; 3657 return NULL; 3658 } 3659 3660 3661 /** 3662 * Gets the name of an AMD-V exit code. 3663 * 3664 * @returns Pointer to read only string if @a uExit is known, otherwise NULL. 3665 * @param uExit The AMD-V exit to name. 3666 */ 3667 VMMR3DECL(const char *) HMR3GetSvmExitName(uint32_t uExit) 3668 { 3669 if (uExit < RT_ELEMENTS(g_apszAmdVExitReasons)) 3670 return g_apszAmdVExitReasons[uExit]; 3671 return hmSvmGetSpecialExitReasonDesc(uExit); 3672 } 3673 3674 3675 /** 3648 3676 * Displays the guest VM-exit history. 3649 3677 * -
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r72526 r72555 327 327 328 328 329 /** 330 * Gets the name of a generic NEM exit code. 331 * 332 * @returns Pointer to read only string if @a uExit is known, otherwise NULL. 333 * @param uExit The NEM exit to name. 334 */ 335 VMMR3DECL(const char *) NEMR3GetExitName(uint32_t uExit) 336 { 337 switch ((NEMEXITTYPE)uExit) 338 { 339 case NEMEXITTYPE_UNRECOVERABLE_EXCEPTION: return "NEM unrecoverable exception"; 340 case NEMEXITTYPE_INVALID_VP_REGISTER_VALUE: return "NEM invalid vp register value"; 341 case NEMEXITTYPE_INTTERRUPT_WINDOW: return "NEM interrupt window"; 342 case NEMEXITTYPE_HALT: return "NEM halt"; 343 case NEMEXITTYPE_XCPT_UD: return "NEM #UD"; 344 case NEMEXITTYPE_XCPT_DB: return "NEM #DB"; 345 case NEMEXITTYPE_XCPT_BP: return "NEM #BP"; 346 case NEMEXITTYPE_CANCELED: return "NEM canceled"; 347 } 348 349 return NULL; 350 } 351 329 352 330 353 VMMR3_INT_DECL(VBOXSTRICTRC) NEMR3RunGC(PVM pVM, PVMCPU pVCpu) -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r72546 r72555 1445 1445 */ 1446 1446 1447 #if 1&& defined(DEBUG_bird)1447 #if 0 && defined(DEBUG_bird) 1448 1448 /* 1449 1449 * Poke and probe a little. -
trunk/src/VBox/VMM/include/EMInternal.h
r72490 r72555 292 292 293 293 /** 294 * Exit history entry. 295 * 296 * @remarks We could perhaps trim this down a little bit by assuming uFlatPC 297 * only needs 48 bits (currently true but will change) and stuffing 298 * the flags+type in the available 16 bits made available. The 299 * timestamp could likewise be shortened to accomodate the index, or 300 * we might skip the index entirely. However, since we will have to 301 * deal with 56-bit wide PC address before long, there's not point. 302 * 303 * On the upside, there are unused bits in both uFlagsAndType and the 304 * idxSlot fields if needed for anything. 305 */ 306 typedef struct EMEXITENTRY 307 { 308 /** The flat PC (CS:EIP/RIP) address of the exit. */ 309 uint64_t uFlatPC; 310 /** The EMEXIT_MAKE_FLAGS_AND_TYPE */ 311 uint32_t uFlagsAndType; 312 /** The index into the exit slot hash table. 313 * UINT32_MAX if too many collisions and not entered into it. */ 314 uint32_t idxSlot; 315 /** The TSC timestamp of the exit. 316 * This is 0 if not timestamped. */ 317 uint64_t uTimestamp; 318 } EMEXITENTRY; 319 /** Pointer to an exit history entry. */ 320 typedef EMEXITENTRY *PEMEXITENTRY; 321 /** Pointer to a const exit history entry. */ 322 typedef EMEXITENTRY const *PCEMEXITENTRY; 323 324 325 /** 294 326 * Converts a EM pointer into a VM pointer. 295 327 * @returns Pointer to the VM structure the EM is part of. … … 464 496 uint64_t padding1; 465 497 #endif 498 499 /** Where to store the next exit history entry. 500 * Since aExitHistory is 256 items longs, we'll just increment this and 501 * mask it when using it. That help the readers detect whether we've 502 * wrapped around or not. */ 503 uint64_t iNextExit; 504 /** Exit history table (6KB). */ 505 EMEXITENTRY aExitHistory[256]; 466 506 } EMCPU; 467 507 /** Pointer to EM VM instance data. */ -
trunk/src/VBox/VMM/include/NEMInternal.h
r72541 r72555 102 102 # define NEM_TMPL_STATIC 103 103 #endif 104 105 106 /** 107 * Generic NEM exit type enumeration for use with EMHistoryAddExit. 108 * 109 * On windows we've got two different set of exit types and they are both jumping 110 * around the place value wise, so EM can use their values. 111 * 112 * @note We only have exit types for exits not covered by EM here. 113 */ 114 typedef enum NEMEXITTYPE 115 { 116 /* windows: */ 117 NEMEXITTYPE_UNRECOVERABLE_EXCEPTION = 1, 118 NEMEXITTYPE_INVALID_VP_REGISTER_VALUE, 119 NEMEXITTYPE_INTTERRUPT_WINDOW, 120 NEMEXITTYPE_HALT, 121 NEMEXITTYPE_XCPT_UD, 122 NEMEXITTYPE_XCPT_DB, 123 NEMEXITTYPE_XCPT_BP, 124 NEMEXITTYPE_CANCELED 125 } NEMEXITTYPE; 104 126 105 127
Note:
See TracChangeset
for help on using the changeset viewer.