Changeset 105423 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jul 21, 2024 12:03:10 PM (7 months ago)
- svn:sync-xref-src-repo-rev:
- 164079
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/IEMR3.cpp
r105410 r105423 193 193 * Initialize per-CPU data and register statistics. 194 194 */ 195 #if 1 195 196 uint64_t const uInitialTlbRevision = UINT64_C(0) - (IEMTLB_REVISION_INCR * 200U); 196 197 uint64_t const uInitialTlbPhysRev = UINT64_C(0) - (IEMTLB_PHYS_REV_INCR * 100U); 198 #else 199 uint64_t const uInitialTlbRevision = UINT64_C(0) + (IEMTLB_REVISION_INCR * 4U); 200 uint64_t const uInitialTlbPhysRev = UINT64_C(0) + (IEMTLB_PHYS_REV_INCR * 4U); 201 #endif 197 202 198 203 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) … … 1071 1076 1072 1077 #define IEMR3INFOTLB_F_ONLY_VALID RT_BIT_32(0) 1078 #define IEMR3INFOTLB_F_CHECK RT_BIT_32(1) 1073 1079 1074 1080 /** Worker for iemR3InfoTlbPrintSlots and iemR3InfoTlbPrintAddress. */ 1075 static void iemR3InfoTlbPrintSlot(P CDBGFINFOHLP pHlp, IEMTLB const *pTlb, IEMTLBENTRY const *pTlbe,1081 static void iemR3InfoTlbPrintSlot(PVMCPU pVCpu, PCDBGFINFOHLP pHlp, IEMTLB const *pTlb, IEMTLBENTRY const *pTlbe, 1076 1082 uint32_t uSlot, uint32_t fFlags) 1077 1083 { … … 1087 1093 RTGCPTR const GCPtr = (RTGCINTPTR)((pTlbe->uTag & ~IEMTLB_REVISION_MASK) << (64 - IEMTLB_TAG_ADDR_WIDTH)) 1088 1094 >> (64 - IEMTLB_TAG_ADDR_WIDTH - GUEST_PAGE_SHIFT); 1089 pHlp->pfnPrintf(pHlp, "%0*x: %s %#018RX64 -> %RGp / %p / %#05x %s%s%s%s%s%s/%s%s%s%s/%s %s\n", 1090 RT_ELEMENTS(pTlb->aEntries) >= 0x1000 ? 4 : RT_ELEMENTS(pTlb->aEntries) >= 0x100 ? 3 : 2, 1091 uSlot, 1095 const char *pszValid = ""; 1096 #ifndef VBOX_VMM_TARGET_ARMV8 1097 char szTmp[128]; 1098 if (fFlags & IEMR3INFOTLB_F_CHECK) 1099 { 1100 PGMPTWALKFAST WalkFast; 1101 int rc = PGMGstQueryPageFast(pVCpu, GCPtr, 0 /*fFlags - don't check or modify anything */, &WalkFast); 1102 pszValid = szTmp; 1103 if (RT_FAILURE(rc)) 1104 switch (rc) 1105 { 1106 case VERR_PAGE_TABLE_NOT_PRESENT: 1107 switch ((WalkFast.fFailed & PGM_WALKFAIL_LEVEL_MASK) >> PGM_WALKFAIL_LEVEL_SHIFT) 1108 { 1109 case 1: pszValid = " stale(page-not-present)"; break; 1110 case 2: pszValid = " stale(pd-entry-not-present)"; break; 1111 case 3: pszValid = " stale(pdptr-entry-not-present)"; break; 1112 case 4: pszValid = " stale(pml4-entry-not-present)"; break; 1113 case 5: pszValid = " stale(pml5-entry-not-present)"; break; 1114 default: pszValid = " stale(VERR_PAGE_TABLE_NOT_PRESENT)"; break; 1115 } 1116 break; 1117 default: RTStrPrintf(szTmp, sizeof(szTmp), " stale(rc=%d)", rc); break; 1118 } 1119 else if (WalkFast.GCPhys != pTlbe->GCPhys) 1120 RTStrPrintf(szTmp, sizeof(szTmp), " stale(GCPhys=%RGp)", WalkFast.GCPhys); 1121 else if ( (~WalkFast.fEffective & (X86_PTE_RW | X86_PTE_US | X86_PTE_G | X86_PTE_A | X86_PTE_D)) 1122 == ( (pTlbe->fFlagsAndPhysRev & ( IEMTLBE_F_PT_NO_WRITE | IEMTLBE_F_PT_NO_USER 1123 | IEMTLBE_F_PT_NO_DIRTY | IEMTLBE_F_PT_NO_ACCESSED)) 1124 | (!(uSlot & 1) << X86_PTE_BIT_G) ) ) 1125 pszValid = " still-valid"; 1126 else if ( (~WalkFast.fEffective & (X86_PTE_RW | X86_PTE_US | X86_PTE_G)) 1127 == ( (pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_WRITE | IEMTLBE_F_PT_NO_USER)) 1128 | (!(uSlot & 1) << X86_PTE_BIT_G) ) ) 1129 switch ( (~WalkFast.fEffective & (X86_PTE_A | X86_PTE_D)) 1130 ^ (pTlbe->fFlagsAndPhysRev & (IEMTLBE_F_PT_NO_DIRTY | IEMTLBE_F_PT_NO_ACCESSED)) ) 1131 { 1132 case X86_PTE_A: 1133 pszValid = WalkFast.fEffective & X86_PTE_A ? " still-valid(accessed-now)" : " still-valid(accessed-no-more)"; 1134 break; 1135 case X86_PTE_D: 1136 pszValid = WalkFast.fEffective & X86_PTE_D ? " still-valid(dirty-now)" : " still-valid(dirty-no-more)"; 1137 break; 1138 case X86_PTE_D | X86_PTE_A: 1139 RTStrPrintf(szTmp, sizeof(szTmp), " still-valid(%s%s)", 1140 (~WalkFast.fEffective & X86_PTE_D) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_DIRTY) ? "" 1141 : WalkFast.fEffective & X86_PTE_D ? "dirty-now" : "dirty-no-more", 1142 (~WalkFast.fEffective & X86_PTE_A) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED) ? "" 1143 : WalkFast.fEffective & X86_PTE_A ? " accessed-now" : " accessed-no-more"); 1144 break; 1145 default: AssertFailed(); break; 1146 } 1147 else 1148 RTStrPrintf(szTmp, sizeof(szTmp), " stale(%s%s%s%s%s)", 1149 (~WalkFast.fEffective & X86_PTE_RW) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_WRITE) ? "" 1150 : WalkFast.fEffective & X86_PTE_RW ? "writeable-now" : "writable-no-more", 1151 (~WalkFast.fEffective & X86_PTE_US) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_USER) ? "" 1152 : WalkFast.fEffective & X86_PTE_US ? " user-now" : " user-no-more", 1153 (~WalkFast.fEffective & X86_PTE_G) == (!(uSlot & 1) << X86_PTE_BIT_G) ? "" 1154 : WalkFast.fEffective & X86_PTE_G ? " global-now" : " global-no-more", 1155 (~WalkFast.fEffective & X86_PTE_D) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_DIRTY) ? "" 1156 : WalkFast.fEffective & X86_PTE_D ? " dirty-now" : " dirty-no-more", 1157 (~WalkFast.fEffective & X86_PTE_A) == (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED) ? "" 1158 : WalkFast.fEffective & X86_PTE_A ? " accessed-now" : " accessed-no-more"); 1159 } 1160 #else 1161 RT_NOREF(pVCpu); 1162 #endif 1163 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, 1092 1166 (pTlbe->uTag & IEMTLB_REVISION_MASK) == uTlbRevision ? "valid " 1093 1167 : (pTlbe->uTag & IEMTLB_REVISION_MASK) == 0 ? "empty " 1094 1168 : "expired", 1095 GCPtr, 1096 pTlbe->GCPhys, pTlbe->pbMappingR3, 1169 GCPtr, /* -> */ 1170 pTlbe->GCPhys, /* / */ pTlbe->pbMappingR3, 1171 /* / */ 1097 1172 (uint32_t)(pTlbe->fFlagsAndPhysRev & ~IEMTLBE_F_PHYS_REV), 1173 /* */ 1098 1174 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_WRITE ? "R-" : "RW", 1099 1175 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_EXEC ? "-" : "X", 1100 1176 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED ? "-" : "A", 1101 1177 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_DIRTY ? "-" : "D", 1102 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_ LARGE_PAGE ? "-" : "S",1178 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_USER ? "U" : "S", 1103 1179 !(uSlot & 1) ? "-" : "G", 1180 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE ? "4K" : "2M", 1181 /* / */ 1104 1182 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_NO_WRITE ? "-" : "w", 1105 1183 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_NO_READ ? "-" : "r", 1106 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_UNASSIGNED ? "U" : "-", 1107 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_CODE_PAGE ? "C" : "-", 1108 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_NO_MAPPINGR3 ? "S" : "M", 1184 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_UNASSIGNED ? "u" : "-", 1185 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_CODE_PAGE ? "c" : "-", 1186 /* / */ 1187 pTlbe->fFlagsAndPhysRev & IEMTLBE_F_NO_MAPPINGR3 ? "N" : "M", 1109 1188 (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PHYS_REV) == pTlb->uTlbPhysRev ? "phys-valid" 1110 : (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PHYS_REV) == 0 ? "phys-empty" : "phys-expired"); 1189 : (pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PHYS_REV) == 0 ? "phys-empty" : "phys-expired", 1190 pszValid); 1111 1191 } 1112 1192 … … 1129 1209 { 1130 1210 IEMTLBENTRY const Tlbe = pTlb->aEntries[uSlot]; 1131 iemR3InfoTlbPrintSlot(p Hlp, pTlb, &Tlbe, uSlot, fFlags);1211 iemR3InfoTlbPrintSlot(pVCpu, pHlp, pTlb, &Tlbe, uSlot, fFlags); 1132 1212 uSlot = (uSlot + 1) % RT_ELEMENTS(pTlb->aEntries); 1133 1213 } … … 1151 1231 Tlbe.uTag == (uTag | pTlb->uTlbRevision) ? "match" 1152 1232 : (Tlbe.uTag & ~IEMTLB_REVISION_MASK) == uTag ? "expired" : "mismatch"); 1153 iemR3InfoTlbPrintSlot(p Hlp, pTlb, &Tlbe, uSlot, fFlags);1233 iemR3InfoTlbPrintSlot(pVCpu, pHlp, pTlb, &Tlbe, uSlot, fFlags); 1154 1234 } 1155 1235 … … 1165 1245 { "--cpu", 'c', RTGETOPT_REQ_UINT32 }, 1166 1246 { "--vcpu", 'c', RTGETOPT_REQ_UINT32 }, 1247 { "--check", 'C', RTGETOPT_REQ_NOTHING }, 1167 1248 { "all", 'A', RTGETOPT_REQ_NOTHING }, 1168 1249 { "--all", 'A', RTGETOPT_REQ_NOTHING }, … … 1173 1254 }; 1174 1255 1175 char szDefault[] = "-A";1176 char *papszDefaults[2] = { szDefault, NULL };1177 if (cArgs == 0)1178 {1179 cArgs = 1;1180 papszArgs = papszDefaults;1181 }1182 1183 1256 RTGETOPTSTATE State; 1184 1257 int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /*iFirst*/, 0 /*fFlags*/); 1185 1258 AssertRCReturnVoid(rc); 1186 1259 1260 uint32_t cActionArgs = 0; 1187 1261 bool fNeedHeader = true; 1188 1262 bool fAddressMode = true; 1189 1263 uint32_t fFlags = 0; 1190 PVMCPU pVCpu = VMMGetCpu(pVM); 1264 PVMCPU const pVCpuCall = VMMGetCpu(pVM); 1265 PVMCPU pVCpu = pVCpuCall; 1191 1266 if (!pVCpu) 1192 1267 pVCpu = VMMGetCpuById(pVM, 0); … … 1204 1279 pVCpu = VMMGetCpuById(pVM, ValueUnion.u32); 1205 1280 fNeedHeader = true; 1281 if (!pVCpuCall || pVCpuCall->idCpu != ValueUnion.u32) 1282 { 1283 pHlp->pfnPrintf(pHlp, "info: Can't check guest PTs when switching to a different VCpu! Targetting %u, on %u.\n", 1284 ValueUnion.u32, pVCpuCall->idCpu); 1285 fFlags &= ~IEMR3INFOTLB_F_CHECK; 1286 } 1206 1287 } 1288 break; 1289 1290 case 'C': 1291 if (!pVCpuCall) 1292 pHlp->pfnPrintf(pHlp, "error: Can't check guest PT when not running on an EMT!\n"); 1293 else if (pVCpu != pVCpuCall) 1294 pHlp->pfnPrintf(pHlp, "error: Can't check guest PTs when on a different EMT! Targetting %u, on %u.\n", 1295 pVCpu->idCpu, pVCpuCall->idCpu); 1296 else 1297 fFlags |= IEMR3INFOTLB_F_CHECK; 1207 1298 break; 1208 1299 … … 1211 1302 ValueUnion.u64, fFlags, &fNeedHeader); 1212 1303 fAddressMode = true; 1304 cActionArgs++; 1213 1305 break; 1214 1306 … … 1216 1308 iemR3InfoTlbPrintSlots(pVCpu, pHlp, fITlb ? &pVCpu->iem.s.CodeTlb : &pVCpu->iem.s.DataTlb, 1217 1309 0, RT_ELEMENTS(pVCpu->iem.s.CodeTlb.aEntries), fFlags, &fNeedHeader); 1310 cActionArgs++; 1218 1311 break; 1219 1312 … … 1222 1315 ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond, fFlags, &fNeedHeader); 1223 1316 fAddressMode = false; 1317 cActionArgs++; 1224 1318 break; 1225 1319 … … 1228 1322 ValueUnion.u32, 1, fFlags, &fNeedHeader); 1229 1323 fAddressMode = false; 1324 cActionArgs++; 1230 1325 break; 1231 1326 … … 1255 1350 pHlp->pfnPrintf(pHlp, "error: Invalid or malformed TLB slot number '%s': %Rrc\n", ValueUnion.psz, rc); 1256 1351 } 1352 cActionArgs++; 1257 1353 break; 1258 1354 … … 1264 1360 " -c<n>, --cpu=<n>, --vcpu=<n>\n" 1265 1361 " Selects the CPU which TLBs we're looking at. Default: Caller / 0\n" 1362 " -C,--check\n" 1363 " Check valid entries against guest PTs.\n" 1266 1364 " -A, --all, all\n" 1267 1365 " Display all the TLB entries (default if no other args).\n" … … 1285 1383 } 1286 1384 } 1385 1386 /* 1387 * If no action taken, we display all (-A) by default. 1388 */ 1389 if (!cActionArgs) 1390 iemR3InfoTlbPrintSlots(pVCpu, pHlp, fITlb ? &pVCpu->iem.s.CodeTlb : &pVCpu->iem.s.DataTlb, 1391 0, RT_ELEMENTS(pVCpu->iem.s.CodeTlb.aEntries), fFlags, &fNeedHeader); 1287 1392 } 1288 1393
Note:
See TracChangeset
for help on using the changeset viewer.