VirtualBox

Changeset 108910 in vbox


Ignore:
Timestamp:
Apr 9, 2025 9:08:53 AM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168378
Message:

VMM/testcase/tstPGMAllGst-armv8.cpp: Add support for testing QueryPageFast callbacks, bugref:10388

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/VBox/VMM/VMMAll/PGMAllGst-armv8.cpp.h

    r108856 r108910  
    133133    pWalk->GCPtr      = GCPtr;
    134134    pWalk->GCPhys     = GCPtr & ~(RTGCPHYS)GUEST_PAGE_OFFSET_MASK;
    135     pWalk->fEffective = X86_PTE_P | X86_PTE_RW | X86_PTE_US; /** @todo */
     135    pWalk->fEffective =   PGM_PTATTRS_PR_MASK | PGM_PTATTRS_PW_MASK | PGM_PTATTRS_PX_MASK | PGM_PTATTRS_PGCS_MASK
     136                        | PGM_PTATTRS_UR_MASK | PGM_PTATTRS_UW_MASK | PGM_PTATTRS_UX_MASK | PGM_PTATTRS_UGCS_MASK;
    136137    return VINF_SUCCESS;
    137138}
     
    147148    pWalk->fInfo        = PGM_WALKINFO_SUCCEEDED;
    148149    pWalk->fFailed      = PGM_WALKFAIL_SUCCESS;
    149     pWalk->fEffective   = X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_A | X86_PTE_D; /** @todo */
     150    pWalk->fEffective =   PGM_PTATTRS_PR_MASK | PGM_PTATTRS_PW_MASK | PGM_PTATTRS_PX_MASK | PGM_PTATTRS_PGCS_MASK
     151                        | PGM_PTATTRS_UR_MASK | PGM_PTATTRS_UW_MASK | PGM_PTATTRS_UX_MASK | PGM_PTATTRS_UGCS_MASK;
    150152    return VINF_SUCCESS;
    151153}
  • TabularUnified trunk/src/VBox/VMM/testcase/tstPGMAllGst-armv8.cpp

    r108886 r108910  
    359359
    360360
     361static int tstMmuCfgReadU32(RTTEST hTest, RTJSONVAL hObj, const char *pszName, PCTSTCFGBITFIELD paBitfields, uint32_t *pu32Result)
     362{
     363    uint64_t u64 = 0;
     364    int rc = tstMmuCfgReadU64(hTest, hObj, pszName, paBitfields, &u64);
     365    if (RT_FAILURE(rc))
     366        return rc;
     367
     368    *pu32Result = (uint32_t)u64;
     369
     370    return VINF_SUCCESS;
     371}
     372
     373
    361374static DECLCALLBACK(int) tstZeroChunk(PAVLRU64NODECORE pCore, void *pvParam)
    362375{
     
    785798
    786799
    787 DECLINLINE(int) tstResultQueryU64(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, uint64_t *pu64)
    788 {
    789     int64_t i64 = 0;
    790     int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
    791     if (RT_FAILURE(rc))
    792         RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
    793     else
    794         *pu64 = (uint64_t)i64;
    795 
    796     return rc;
    797 }
    798 
    799 
    800800static int tstResultInit(RTTEST hTest, RTJSONVAL hMemResult, PPGMPTWALK pWalkResult)
    801801{
     
    824824        rc = tstResultQueryU32(hTest, hMemResult, "fFailed", &pWalkResult->fFailed);
    825825    if (RT_SUCCESS(rc))
    826         rc = tstResultQueryU64(hTest, hMemResult, "Effective", &pWalkResult->fEffective);
     826    {
     827        static const TSTCFGBITFIELD s_aPtAttrs[] =
     828        {
     829#define BITFIELD_CREATE_BOOL(a_Name) \
     830            { #a_Name, PGM_PTATTRS_##a_Name##_SHIFT, 1, NULL }
     831
     832            BITFIELD_CREATE_BOOL(PR),
     833            BITFIELD_CREATE_BOOL(PW),
     834            BITFIELD_CREATE_BOOL(PX),
     835            BITFIELD_CREATE_BOOL(PGCS),
     836            BITFIELD_CREATE_BOOL(UR),
     837            BITFIELD_CREATE_BOOL(UW),
     838            BITFIELD_CREATE_BOOL(UX),
     839            BITFIELD_CREATE_BOOL(UGCS),
     840            { NULL,     0, 0, NULL }
     841
     842#undef BITFIELD_CREATE_BOOL
     843        };
     844
     845        rc = tstMmuCfgReadU64(hTest, hMemResult, "Effective", &s_aPtAttrs[0], &pWalkResult->fEffective);
     846    }
    827847
    828848    return rc;
     
    889909
    890910
    891 static int tstTestcaseMmuRun(RTTEST hTest, RTJSONVAL hTestcase)
     911static int tstTestcaseMmuRunGetPage(RTTEST hTest, RTJSONVAL hTestcase)
    892912{
    893913    RTJSONVAL hVal = NIL_RTJSONVAL;
    894     int rc = RTJsonValueQueryByName(hTestcase, "Tests", &hVal);
     914    int rc = RTJsonValueQueryByName(hTestcase, "GetPage", &hVal);
    895915    if (RT_SUCCESS(rc))
    896916    {
     
    935955        RTJsonValueRelease(hVal);
    936956    }
     957    else if (rc == VERR_NOT_FOUND)
     958        rc = VINF_SUCCESS;
     959    else
     960        RTTestFailed(hTest, "Failed to query \"Tests\" %Rrc", rc);
     961
     962    return rc;
     963}
     964
     965
     966static int tstResultQueryPageFastInit(RTTEST hTest, RTJSONVAL hMemResult, PPGMPTWALKFAST pWalkResult)
     967{
     968    int rc = tstResultQueryGCPhys(hTest, hMemResult, "GCPhys", &pWalkResult->GCPhys);
     969    if (RT_SUCCESS(rc))
     970        rc = tstResultQueryGCPhysDef(hTest, hMemResult, "GCPhysNested", &pWalkResult->GCPhysNested, 0);
     971    if (RT_SUCCESS(rc))
     972    {
     973        static const TSTCFGBITFIELD s_aInfo[] =
     974        {
     975#define BITFIELD_CREATE_BOOL(a_Name, a_offBit) \
     976            { #a_Name, a_offBit, 1, NULL }
     977            BITFIELD_CREATE_BOOL(Succeeded,          0),
     978            BITFIELD_CREATE_BOOL(IsSlat,             1),
     979            BITFIELD_CREATE_BOOL(BigPage,            7),
     980            BITFIELD_CREATE_BOOL(GiganticPage,       8),
     981            BITFIELD_CREATE_BOOL(IsLinearAddrValid, 10),
     982            { NULL,     0, 0, NULL }
     983        };
     984        AssertCompile(PGM_WALKINFO_SUCCEEDED            == RT_BIT_32(0));
     985        AssertCompile(PGM_WALKINFO_IS_SLAT              == RT_BIT_32(1));
     986        AssertCompile(PGM_WALKINFO_BIG_PAGE             == RT_BIT_32(7));
     987        AssertCompile(PGM_WALKINFO_GIGANTIC_PAGE        == RT_BIT_32(8));
     988        AssertCompile(PGM_WALKINFO_IS_LINEAR_ADDR_VALID == RT_BIT_32(10));
     989
     990        rc = tstMmuCfgReadU32(hTest, hMemResult, "Info", &s_aInfo[0], &pWalkResult->fInfo);
     991    }
     992    if (RT_SUCCESS(rc))
     993    {
     994        static const TSTCFGBITFIELD s_aFailed[] =
     995        {
     996            BITFIELD_CREATE_BOOL(NotPresent,          0),
     997            BITFIELD_CREATE_BOOL(ReservedBits,        1),
     998            BITFIELD_CREATE_BOOL(BadPhysicalAddress,  2),
     999            BITFIELD_CREATE_BOOL(NotWritable,         6),
     1000            BITFIELD_CREATE_BOOL(NotExecutable,       7),
     1001            BITFIELD_CREATE_BOOL(NotAccessibleByMode, 8),
     1002            { NULL,     0, 0, NULL }
     1003
     1004#undef BITFIELD_CREATE_BOOL
     1005        };
     1006        AssertCompile(PGM_WALKFAIL_NOT_PRESENT            == RT_BIT_32(0));
     1007        AssertCompile(PGM_WALKFAIL_RESERVED_BITS          == RT_BIT_32(1));
     1008        AssertCompile(PGM_WALKFAIL_BAD_PHYSICAL_ADDRESS   == RT_BIT_32(2));
     1009        AssertCompile(PGM_WALKFAIL_NOT_WRITABLE           == RT_BIT_32(6));
     1010        AssertCompile(PGM_WALKFAIL_NOT_EXECUTABLE         == RT_BIT_32(7));
     1011        AssertCompile(PGM_WALKFAIL_NOT_ACCESSIBLE_BY_MODE == RT_BIT_32(8));
     1012
     1013        rc = tstMmuCfgReadU32(hTest, hMemResult, "Failed", &s_aFailed[0], &pWalkResult->fFailed);
     1014    }
     1015    if (RT_SUCCESS(rc))
     1016    {
     1017        static const TSTCFGBITFIELD s_aPtAttrs[] =
     1018        {
     1019#define BITFIELD_CREATE_BOOL(a_Name) \
     1020            { #a_Name, PGM_PTATTRS_##a_Name##_SHIFT, 1, NULL }
     1021
     1022            BITFIELD_CREATE_BOOL(PR),
     1023            BITFIELD_CREATE_BOOL(PW),
     1024            BITFIELD_CREATE_BOOL(PX),
     1025            BITFIELD_CREATE_BOOL(PGCS),
     1026            BITFIELD_CREATE_BOOL(UR),
     1027            BITFIELD_CREATE_BOOL(UW),
     1028            BITFIELD_CREATE_BOOL(UX),
     1029            BITFIELD_CREATE_BOOL(UGCS),
     1030            { NULL,     0, 0, NULL }
     1031
     1032#undef BITFIELD_CREATE_BOOL
     1033        };
     1034
     1035        rc = tstMmuCfgReadU64(hTest, hMemResult, "Effective", &s_aPtAttrs[0], &pWalkResult->fEffective);
     1036    }
     1037
     1038    return rc;
     1039}
     1040
     1041
     1042static void tstExecuteQueryPageFast(RTTEST hTest, PVM pVM, RTGCPTR GCPtr, uint32_t fFlags, RTJSONVAL hMemResult)
     1043{
     1044    PVMCPUCC pVCpu = pVM->apCpusR3[0];
     1045
     1046    /** @todo Incorporate EL (for nested virt and EL3 later on). */
     1047    uintptr_t idx =   (GCPtr & RT_BIT_64(55))
     1048                    ? pVCpu->pgm.s.aidxGuestModeDataTtbr1[1]
     1049                    : pVCpu->pgm.s.aidxGuestModeDataTtbr0[1];
     1050
     1051    PGMPTWALKFAST Walk; PGMPTWALKFAST_ZERO(&Walk);
     1052    AssertReleaseReturnVoid(idx < RT_ELEMENTS(g_aPgmGuestModeData));
     1053    AssertReleaseReturnVoid(g_aPgmGuestModeData[idx].pfnQueryPageFast);
     1054    int rc = g_aPgmGuestModeData[idx].pfnQueryPageFast(pVCpu, GCPtr, fFlags, &Walk);
     1055    if (RT_SUCCESS(rc))
     1056    {
     1057        PGMPTWALKFAST WalkResult; PGMPTWALKFAST_ZERO(&WalkResult);
     1058        WalkResult.GCPtr = GCPtr;
     1059
     1060        rc = tstResultQueryPageFastInit(hTest, hMemResult, &WalkResult);
     1061        if (RT_SUCCESS(rc))
     1062        {
     1063            if (memcmp(&Walk, &WalkResult, sizeof(Walk)))
     1064            {
     1065                if (Walk.GCPtr != WalkResult.GCPtr)
     1066                    RTTestFailed(hTest, "Result GCPtr=%RGv != Expected GCPtr=%RGv", Walk.GCPtr, WalkResult.GCPtr);
     1067                if (Walk.GCPhys != WalkResult.GCPhys)
     1068                    RTTestFailed(hTest, "Result GCPhys=%RGp != Expected GCPhys=%RGp", Walk.GCPhys, WalkResult.GCPhys);
     1069                if (Walk.GCPhysNested != WalkResult.GCPhysNested)
     1070                    RTTestFailed(hTest, "Result GCPhysNested=%RGp != Expected GCPhysNested=%RGp", Walk.GCPhysNested, WalkResult.GCPhysNested);
     1071                if (Walk.fInfo != WalkResult.fInfo)
     1072                    RTTestFailed(hTest, "Result fInfo=%#RX32 != Expected fInfo=%#RX32", Walk.fInfo, WalkResult.fInfo);
     1073                if (Walk.fFailed != WalkResult.fFailed)
     1074                    RTTestFailed(hTest, "Result fFailed=%#RX32 != Expected fFailed=%#RX32", Walk.fFailed, WalkResult.fFailed);
     1075                if (Walk.fEffective != WalkResult.fEffective)
     1076                    RTTestFailed(hTest, "Result fEffective=%#RX64 != Expected fEffective=%#RX64", Walk.fEffective, WalkResult.fEffective);
     1077            }
     1078        }
     1079    }
     1080    else
     1081        RTTestFailed(hTest, "Resolving virtual address %#RX64 to physical address failed with %Rrc", GCPtr, rc);
     1082}
     1083
     1084
     1085static int tstTestcaseMmuRunQueryPageFast(RTTEST hTest, RTJSONVAL hTestcase)
     1086{
     1087    RTJSONVAL hVal = NIL_RTJSONVAL;
     1088    int rc = RTJsonValueQueryByName(hTestcase, "QueryPageFast", &hVal);
     1089    if (RT_SUCCESS(rc))
     1090    {
     1091        RTJSONIT hIt = NIL_RTJSONIT;
     1092        rc = RTJsonIteratorBeginArray(hVal, &hIt);
     1093        if (RT_SUCCESS(rc))
     1094        {
     1095            for (;;)
     1096            {
     1097                RTJSONVAL hMemObj = NIL_RTJSONVAL;
     1098                rc = RTJsonIteratorQueryValue(hIt, &hMemObj, NULL);
     1099                if (RT_SUCCESS(rc))
     1100                {
     1101                    uint64_t GCPtr = 0;
     1102                    rc = RTJsonValueQueryIntegerByName(hMemObj, "GCPtr", (int64_t *)&GCPtr);
     1103                    if (rc == VINF_SUCCESS)
     1104                    {
     1105                        static const TSTCFGBITFIELD s_aQPage[] =
     1106                        {
     1107#define BITFIELD_CREATE_BOOL(a_Name, a_offBit) \
     1108                            { #a_Name, a_offBit, 1, NULL }
     1109
     1110                            BITFIELD_CREATE_BOOL(READ,    0),
     1111                            BITFIELD_CREATE_BOOL(WRITE,   1),
     1112                            BITFIELD_CREATE_BOOL(EXECUTE, 2),
     1113                            BITFIELD_CREATE_BOOL(USER,    3),
     1114                            { NULL,     0, 0, NULL }
     1115
     1116#undef BITFIELD_CREATE_BOOL
     1117                        };
     1118                        AssertCompile(PGMQPAGE_F_READ      == RT_BIT_32(0));
     1119                        AssertCompile(PGMQPAGE_F_WRITE     == RT_BIT_32(1));
     1120                        AssertCompile(PGMQPAGE_F_EXECUTE   == RT_BIT_32(2));
     1121                        AssertCompile(PGMQPAGE_F_USER_MODE == RT_BIT_32(3));
     1122
     1123                        uint32_t fFlags = 0;
     1124                        rc = tstMmuCfgReadU32(hTest, hMemObj, "Flags", &s_aQPage[0], &fFlags);
     1125                        if (RT_SUCCESS(rc))
     1126                        {
     1127                            RTJSONVAL hMemResult = NIL_RTJSONVAL;
     1128                            rc = RTJsonValueQueryByName(hMemObj, "Result", &hMemResult);
     1129                            if (RT_SUCCESS(rc))
     1130                            {
     1131                                tstExecuteQueryPageFast(hTest, g_MmuCfg.pVM, GCPtr, fFlags, hMemResult);
     1132                                RTJsonValueRelease(hMemResult);
     1133                            }
     1134                            else
     1135                            {
     1136                                RTTestFailed(hTest, "Querying 'Result' failed with %Rrc", rc);
     1137                                break;
     1138                            }
     1139                        }
     1140                    }
     1141                    else
     1142                    {
     1143                        RTTestFailed(hTest, "Querying 'GCPtr' failed with %Rrc", rc);
     1144                        break;
     1145                    }
     1146
     1147                    RTJsonValueRelease(hMemObj);
     1148                }
     1149                else
     1150                    RTTestFailed(hTest, "Failed to retrieve memory range with %Rrc", rc);
     1151
     1152                rc = RTJsonIteratorNext(hIt);
     1153                if (RT_FAILURE(rc))
     1154                    break;
     1155            }
     1156            if (rc == VERR_JSON_ITERATOR_END)
     1157                rc = VINF_SUCCESS;
     1158            RTJsonIteratorFree(hIt);
     1159        }
     1160        else
     1161            RTTestFailed(hTest, "Failed to traverse JSON array with %Rrc", rc);
     1162
     1163
     1164        RTJsonValueRelease(hVal);
     1165    }
     1166    else if (rc == VERR_NOT_FOUND)
     1167        rc = VINF_SUCCESS;
    9371168    else
    9381169        RTTestFailed(hTest, "Failed to query \"Tests\" %Rrc", rc);
     
    9601191                rc = tstTestcaseMmuConfigPrepare(hTest, &g_MmuCfg, hTestcase);
    9611192            if (RT_SUCCESS(rc))
    962                 rc = tstTestcaseMmuRun(hTest, hTestcase);
     1193                rc = tstTestcaseMmuRunGetPage(hTest, hTestcase);
     1194            if (RT_SUCCESS(rc))
     1195                rc = tstTestcaseMmuRunQueryPageFast(hTest, hTestcase);
    9631196        }
    9641197        else
  • TabularUnified trunk/src/VBox/VMM/testcase/tstPGMAllGst-armv8.json

    r108886 r108910  
    3535        AddressSpace: { },
    3636
    37         Tests:
     37        GetPage:
    3838        {
    3939            /* GCPtr: { Expected Result } */
    40             0x0:      { GCPhys:    0x0, Level: 0, fFailed: 0x0, Effective: 0x7 },
    41             0xffff:   { GCPhys: 0xf000, Level: 0, fFailed: 0x0, Effective: 0x7 },
     40            0x0:      { GCPhys:    0x0, Level: 0, fFailed: 0x0, Effective: { PR: 1, PW: 1, PX: 1, PGCS: 1, UR: 1, UW: 1, UX: 1, UGCS: 1} },
     41            0xffff:   { GCPhys: 0xf000, Level: 0, fFailed: 0x0, Effective: { PR: 1, PW: 1, PX: 1, PGCS: 1, UR: 1, UW: 1, UX: 1, UGCS: 1} },
    4242        }
    4343    },
     
    5555        },
    5656
    57         Tests:
     57        GetPage:
    5858        {
    5959            /* GCPtr: { Expected Result } */
    6060            0x0:      { GCPhys: 0x0000c00000000000, Level: 0, GigantPage: true, fFailed: 0x0, Effective: 0x0 },
    61         }
     61        },
     62
     63        QueryPageFast:
     64        [
     65            {
     66                GCPtr: 0x0,
     67                Flags: { READ: 1, USER: 1 },
     68                Result: { GCPhys: 0x0000c00000000000, Info: { Succeeded: 1, GiganticPage: 1}, Failed: 0, Effective: 0 },
     69            }
     70        ]
    6271    }
    6372]
Note: See TracChangeset for help on using the changeset viewer.

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