Changeset 72555 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jun 14, 2018 9:28:31 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
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.
Note:
See TracChangeset
for help on using the changeset viewer.