Changeset 105440 in vbox for trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
- Timestamp:
- Jul 23, 2024 10:50:17 AM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r105428 r105440 50 50 #include <iprt/assert.h> 51 51 #include <iprt/getopt.h> 52 #ifdef IEM_WITH_TLB_TRACE 53 # include <iprt/mem.h> 54 #endif 52 55 #include <iprt/string.h> 53 56 … … 64 67 static FNDBGFINFOARGVINT iemR3InfoITlb; 65 68 static FNDBGFINFOARGVINT iemR3InfoDTlb; 69 #ifdef IEM_WITH_TLB_TRACE 70 static FNDBGFINFOARGVINT iemR3InfoTlbTrace; 71 #endif 66 72 #if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8) 67 73 static FNDBGFINFOARGVINT iemR3InfoTb; … … 203 209 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 204 210 { 205 PVMCPU pVCpu = pVM->apCpusR3[idCpu];211 PVMCPU const pVCpu = pVM->apCpusR3[idCpu]; 206 212 AssertCompile(sizeof(pVCpu->iem.s) <= sizeof(pVCpu->iem.padding)); /* (tstVMStruct can't do it's job w/o instruction stats) */ 207 213 … … 286 292 */ 287 293 pVCpu->iem.s.uTbNativeRecompileAtUsedCount = uTbNativeRecompileAtUsedCount; 294 #endif 295 296 #ifdef IEM_WITH_TLB_TRACE 297 /* 298 * Allocate trace buffer. 299 */ 300 pVCpu->iem.s.idxTlbTraceEntry = 0; 301 pVCpu->iem.s.cTlbTraceEntriesShift = 19;//16; 302 pVCpu->iem.s.paTlbTraceEntries = (PIEMTLBTRACEENTRY)RTMemPageAlloc( RT_BIT_Z(pVCpu->iem.s.cTlbTraceEntriesShift) 303 * sizeof(*pVCpu->iem.s.paTlbTraceEntries)); 304 AssertLogRelReturn(pVCpu->iem.s.paTlbTraceEntries, VERR_NO_PAGE_MEMORY); 288 305 #endif 289 306 } … … 958 975 DBGFR3InfoRegisterInternalArgv(pVM, "itlb", "IEM instruction TLB", iemR3InfoITlb, DBGFINFO_FLAGS_RUN_ON_EMT); 959 976 DBGFR3InfoRegisterInternalArgv(pVM, "dtlb", "IEM instruction TLB", iemR3InfoDTlb, DBGFINFO_FLAGS_RUN_ON_EMT); 977 #ifdef IEM_WITH_TLB_TRACE 978 DBGFR3InfoRegisterInternalArgv(pVM, "tlbtrace", "IEM TLB trace log", iemR3InfoTlbTrace, DBGFINFO_FLAGS_RUN_ON_EMT); 979 #endif 960 980 #if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8) 961 981 DBGFR3InfoRegisterInternalArgv(pVM, "tb", "IEM translation block", iemR3InfoTb, DBGFINFO_FLAGS_RUN_ON_EMT); … … 972 992 { 973 993 NOREF(pVM); 994 #ifdef IEM_WITH_TLB_TRACE 995 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) 996 { 997 PVMCPU const pVCpu = pVM->apCpusR3[idCpu]; 998 RTMemPageFree(pVCpu->iem.s.paTlbTraceEntries, 999 RT_BIT_Z(pVCpu->iem.s.cTlbTraceEntriesShift) * sizeof(*pVCpu->iem.s.paTlbTraceEntries)); 1000 } 1001 #endif 974 1002 return VINF_SUCCESS; 975 1003 } … … 1162 1190 #endif 1163 1191 1164 pHlp->pfnPrintf(pHlp, "%0*x: %s %#018RX64 -> %RGp / %p / %#05x %s%s%s%s%s%s%s/%s%s%s%s/%s %s%s\n",1165 RT_ELEMENTS(pTlb->aEntries) >= 0x1000 ? 4 : RT_ELEMENTS(pTlb->aEntries) >= 0x100 ? 3 : 2,uSlot,1192 pHlp->pfnPrintf(pHlp, IEMTLB_SLOT_FMT ": %s %#018RX64 -> %RGp / %p / %#05x %s%s%s%s%s%s%s/%s%s%s%s/%s %s%s\n", 1193 uSlot, 1166 1194 (pTlbe->uTag & IEMTLB_REVISION_MASK) == uTlbRevision ? "valid " 1167 1195 : (pTlbe->uTag & IEMTLB_REVISION_MASK) == 0 ? "empty " … … 1410 1438 } 1411 1439 1440 1441 #ifdef IEM_WITH_TLB_TRACE 1442 /** 1443 * @callback_method_impl{FNDBGFINFOARGVINT, tlbtrace} 1444 */ 1445 static DECLCALLBACK(void) iemR3InfoTlbTrace(PVM pVM, PCDBGFINFOHLP pHlp, int cArgs, char **papszArgs) 1446 { 1447 /* 1448 * Parse arguments. 1449 */ 1450 static RTGETOPTDEF const s_aOptions[] = 1451 { 1452 { "--cpu", 'c', RTGETOPT_REQ_UINT32 }, 1453 { "--vcpu", 'c', RTGETOPT_REQ_UINT32 }, 1454 { "--last", 'l', RTGETOPT_REQ_UINT32 }, 1455 { "--limit", 'l', RTGETOPT_REQ_UINT32 }, 1456 { "--stop-at-global-flush", 'g', RTGETOPT_REQ_NOTHING }, 1457 }; 1458 1459 RTGETOPTSTATE State; 1460 int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /*iFirst*/, 0 /*fFlags*/); 1461 AssertRCReturnVoid(rc); 1462 1463 uint32_t cLimit = UINT32_MAX; 1464 bool fStopAtGlobalFlush = false; 1465 PVMCPU const pVCpuCall = VMMGetCpu(pVM); 1466 PVMCPU pVCpu = pVCpuCall; 1467 if (!pVCpu) 1468 pVCpu = VMMGetCpuById(pVM, 0); 1469 1470 RTGETOPTUNION ValueUnion; 1471 while ((rc = RTGetOpt(&State, &ValueUnion)) != 0) 1472 { 1473 switch (rc) 1474 { 1475 case 'c': 1476 if (ValueUnion.u32 >= pVM->cCpus) 1477 pHlp->pfnPrintf(pHlp, "error: Invalid CPU ID: %u\n", ValueUnion.u32); 1478 else if (!pVCpu || pVCpu->idCpu != ValueUnion.u32) 1479 pVCpu = VMMGetCpuById(pVM, ValueUnion.u32); 1480 break; 1481 1482 case 'l': 1483 cLimit = ValueUnion.u32; 1484 break; 1485 1486 case 'g': 1487 fStopAtGlobalFlush = true; 1488 break; 1489 1490 case 'h': 1491 pHlp->pfnPrintf(pHlp, 1492 "Usage: info tlbtrace [options]\n" 1493 "\n" 1494 "Options:\n" 1495 " -c<n>, --cpu=<n>, --vcpu=<n>\n" 1496 " Selects the CPU which TLB trace we're looking at. Default: Caller / 0\n" 1497 " -l<n>, --last=<n>\n" 1498 " Limit display to the last N entries. Default: all\n" 1499 " -g,--stop-at-global-flush\n" 1500 " Stop after the first global flush entry.\n" 1501 ); 1502 return; 1503 1504 default: 1505 pHlp->pfnGetOptError(pHlp, rc, &ValueUnion, &State); 1506 return; 1507 } 1508 } 1509 1510 /* 1511 * Get the details. 1512 */ 1513 AssertReturnVoid(pVCpu); 1514 Assert(pVCpu->iem.s.cTlbTraceEntriesShift <= 28); 1515 uint32_t idx = pVCpu->iem.s.idxTlbTraceEntry; 1516 uint32_t const cShift = RT_MIN(pVCpu->iem.s.cTlbTraceEntriesShift, 28); 1517 uint32_t const fMask = RT_BIT_32(cShift) - 1; 1518 uint32_t cLeft = RT_MIN(RT_MIN(idx, RT_BIT_32(cShift)), cLimit); 1519 PCIEMTLBTRACEENTRY paEntries = pVCpu->iem.s.paTlbTraceEntries; 1520 if (cLeft && paEntries) 1521 { 1522 /* 1523 * Display the entries. 1524 */ 1525 pHlp->pfnPrintf(pHlp, "TLB Trace for CPU %u:\n", pVCpu->idCpu); 1526 while (cLeft-- > 0) 1527 { 1528 PCIEMTLBTRACEENTRY const pCur = &paEntries[--idx & fMask]; 1529 switch (pCur->enmType) 1530 { 1531 case kIemTlbTraceType_InvlPg: 1532 pHlp->pfnPrintf(pHlp, "%u: %016RX64 invlpg %RGv slot=" IEMTLB_SLOT_FMT "\n", 1533 idx, pCur->rip, pCur->u64Param, (uint32_t)IEMTLB_ADDR_TO_EVEN_INDEX(pCur->u64Param)); 1534 break; 1535 case kIemTlbTraceType_Flush: 1536 pHlp->pfnPrintf(pHlp, "%u: %016RX64 flush %s rev=%#RX64\n", idx, pCur->rip, 1537 pCur->bParam ? "data" : "code", pCur->u64Param); 1538 break; 1539 case kIemTlbTraceType_FlushGlobal: 1540 pHlp->pfnPrintf(pHlp, "%u: %016RX64 flush %s rev=%#RX64 grev=%#RX64\n", idx, pCur->rip, 1541 pCur->bParam ? "data" : "code", pCur->u64Param, pCur->u64Param2); 1542 if (fStopAtGlobalFlush) 1543 return; 1544 break; 1545 case kIemTlbTraceType_Load: 1546 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load %s %RGv slot=" IEMTLB_SLOT_FMT "\n", 1547 idx, pCur->rip, pCur->bParam ? "data" : "code", 1548 pCur->u64Param, (uint32_t)IEMTLB_ADDR_TO_EVEN_INDEX(pCur->u64Param)); 1549 break; 1550 case kIemTlbTraceType_LoadGlobal: 1551 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load %s %RGv slot=" IEMTLB_SLOT_FMT " (global)\n", 1552 idx, pCur->rip, pCur->bParam ? "data" : "code", 1553 pCur->u64Param, (uint32_t)IEMTLB_ADDR_TO_EVEN_INDEX(pCur->u64Param)); 1554 break; 1555 case kIemTlbTraceType_Load_Cr0: 1556 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load cr0 %08RX64 (was %08RX64)\n", 1557 idx, pCur->rip, pCur->u64Param, pCur->u64Param2); 1558 break; 1559 case kIemTlbTraceType_Load_Cr3: 1560 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load cr3 %016RX64 (was %016RX64)\n", 1561 idx, pCur->rip, pCur->u64Param, pCur->u64Param2); 1562 break; 1563 case kIemTlbTraceType_Load_Cr4: 1564 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load cr4 %08RX64 (was %08RX64)\n", 1565 idx, pCur->rip, pCur->u64Param, pCur->u64Param2); 1566 break; 1567 case kIemTlbTraceType_Load_Efer: 1568 pHlp->pfnPrintf(pHlp, "%u: %016RX64 load efer %016RX64 (was %016RX64)\n", 1569 idx, pCur->rip, pCur->u64Param, pCur->u64Param2); 1570 break; 1571 case kIemTlbTraceType_Invalid: 1572 pHlp->pfnPrintf(pHlp, "%u: Invalid!\n"); 1573 break; 1574 } 1575 } 1576 } 1577 else 1578 pHlp->pfnPrintf(pHlp, "No trace entries to display\n"); 1579 } 1580 #endif /* IEM_WITH_TLB_TRACE */ 1581 1412 1582 #if defined(VBOX_WITH_IEM_RECOMPILER) && !defined(VBOX_VMM_TARGET_ARMV8) 1413 1583 /**
Note:
See TracChangeset
for help on using the changeset viewer.