VirtualBox

Changeset 105423 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Jul 21, 2024 12:03:10 PM (7 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164079
Message:

VMM/IEM: More 'info dtlb/itlb' details. bugref:10727

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r105410 r105423  
    193193     * Initialize per-CPU data and register statistics.
    194194     */
     195#if 1
    195196    uint64_t const uInitialTlbRevision = UINT64_C(0) - (IEMTLB_REVISION_INCR * 200U);
    196197    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
    197202
    198203    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
     
    10711076
    10721077#define IEMR3INFOTLB_F_ONLY_VALID   RT_BIT_32(0)
     1078#define IEMR3INFOTLB_F_CHECK        RT_BIT_32(1)
    10731079
    10741080/** Worker for iemR3InfoTlbPrintSlots and iemR3InfoTlbPrintAddress. */
    1075 static void iemR3InfoTlbPrintSlot(PCDBGFINFOHLP pHlp, IEMTLB const *pTlb, IEMTLBENTRY const *pTlbe,
     1081static void iemR3InfoTlbPrintSlot(PVMCPU pVCpu, PCDBGFINFOHLP pHlp, IEMTLB const *pTlb, IEMTLBENTRY const *pTlbe,
    10761082                                  uint32_t uSlot, uint32_t fFlags)
    10771083{
     
    10871093    RTGCPTR const  GCPtr = (RTGCINTPTR)((pTlbe->uTag & ~IEMTLB_REVISION_MASK) << (64 - IEMTLB_TAG_ADDR_WIDTH))
    10881094                         >>                                                      (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,
    10921166                    (pTlbe->uTag & IEMTLB_REVISION_MASK) == uTlbRevision ? "valid  "
    10931167                    : (pTlbe->uTag & IEMTLB_REVISION_MASK) == 0          ? "empty  "
    10941168                                                                         : "expired",
    1095                     GCPtr,
    1096                     pTlbe->GCPhys, pTlbe->pbMappingR3,
     1169                    GCPtr, /* -> */
     1170                    pTlbe->GCPhys, /* / */ pTlbe->pbMappingR3,
     1171                    /* / */
    10971172                    (uint32_t)(pTlbe->fFlagsAndPhysRev & ~IEMTLBE_F_PHYS_REV),
     1173                    /* */
    10981174                    pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_WRITE      ? "R-" : "RW",
    10991175                    pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_EXEC       ? "-"  : "X",
    11001176                    pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_NO_ACCESSED   ? "-"  : "A",
    11011177                    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",
    11031179                    !(uSlot & 1)                                         ? "-"  : "G",
     1180                    pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PT_LARGE_PAGE    ? "4K" : "2M",
     1181                    /* / */
    11041182                    pTlbe->fFlagsAndPhysRev & IEMTLBE_F_PG_NO_WRITE      ? "-"  : "w",
    11051183                    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",
    11091188                    (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);
    11111191}
    11121192
     
    11291209        {
    11301210            IEMTLBENTRY const Tlbe = pTlb->aEntries[uSlot];
    1131             iemR3InfoTlbPrintSlot(pHlp, pTlb, &Tlbe, uSlot, fFlags);
     1211            iemR3InfoTlbPrintSlot(pVCpu, pHlp, pTlb, &Tlbe, uSlot, fFlags);
    11321212            uSlot = (uSlot + 1) % RT_ELEMENTS(pTlb->aEntries);
    11331213        }
     
    11511231                    Tlbe.uTag == (uTag | pTlb->uTlbRevision)  ? "match"
    11521232                    : (Tlbe.uTag & ~IEMTLB_REVISION_MASK) == uTag ? "expired" : "mismatch");
    1153     iemR3InfoTlbPrintSlot(pHlp, pTlb, &Tlbe, uSlot, fFlags);
     1233    iemR3InfoTlbPrintSlot(pVCpu, pHlp, pTlb, &Tlbe, uSlot, fFlags);
    11541234}
    11551235
     
    11651245        { "--cpu",          'c', RTGETOPT_REQ_UINT32                          },
    11661246        { "--vcpu",         'c', RTGETOPT_REQ_UINT32                          },
     1247        { "--check",        'C', RTGETOPT_REQ_NOTHING                         },
    11671248        { "all",            'A', RTGETOPT_REQ_NOTHING                         },
    11681249        { "--all",          'A', RTGETOPT_REQ_NOTHING                         },
     
    11731254    };
    11741255
    1175     char  szDefault[] = "-A";
    1176     char *papszDefaults[2] = { szDefault, NULL };
    1177     if (cArgs == 0)
    1178     {
    1179         cArgs     = 1;
    1180         papszArgs = papszDefaults;
    1181     }
    1182 
    11831256    RTGETOPTSTATE State;
    11841257    int rc = RTGetOptInit(&State, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 0 /*iFirst*/, 0 /*fFlags*/);
    11851258    AssertRCReturnVoid(rc);
    11861259
     1260    uint32_t        cActionArgs  = 0;
    11871261    bool            fNeedHeader  = true;
    11881262    bool            fAddressMode = true;
    11891263    uint32_t        fFlags       = 0;
    1190     PVMCPU          pVCpu        = VMMGetCpu(pVM);
     1264    PVMCPU const    pVCpuCall    = VMMGetCpu(pVM);
     1265    PVMCPU          pVCpu        = pVCpuCall;
    11911266    if (!pVCpu)
    11921267        pVCpu = VMMGetCpuById(pVM, 0);
     
    12041279                    pVCpu = VMMGetCpuById(pVM, ValueUnion.u32);
    12051280                    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                    }
    12061287                }
     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;
    12071298                break;
    12081299
     
    12111302                                         ValueUnion.u64, fFlags, &fNeedHeader);
    12121303                fAddressMode = true;
     1304                cActionArgs++;
    12131305                break;
    12141306
     
    12161308                iemR3InfoTlbPrintSlots(pVCpu, pHlp, fITlb ? &pVCpu->iem.s.CodeTlb : &pVCpu->iem.s.DataTlb,
    12171309                                       0, RT_ELEMENTS(pVCpu->iem.s.CodeTlb.aEntries), fFlags, &fNeedHeader);
     1310                cActionArgs++;
    12181311                break;
    12191312
     
    12221315                                       ValueUnion.PairU32.uFirst, ValueUnion.PairU32.uSecond, fFlags, &fNeedHeader);
    12231316                fAddressMode = false;
     1317                cActionArgs++;
    12241318                break;
    12251319
     
    12281322                                       ValueUnion.u32, 1, fFlags, &fNeedHeader);
    12291323                fAddressMode = false;
     1324                cActionArgs++;
    12301325                break;
    12311326
     
    12551350                        pHlp->pfnPrintf(pHlp, "error: Invalid or malformed TLB slot number '%s': %Rrc\n", ValueUnion.psz, rc);
    12561351                }
     1352                cActionArgs++;
    12571353                break;
    12581354
     
    12641360                                "  -c<n>, --cpu=<n>, --vcpu=<n>\n"
    12651361                                "    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"
    12661364                                "  -A, --all, all\n"
    12671365                                "    Display all the TLB entries (default if no other args).\n"
     
    12851383        }
    12861384    }
     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);
    12871392}
    12881393
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette