VirtualBox

Changeset 108879 in vbox for trunk/src/VBox/VMM/testcase


Ignore:
Timestamp:
Apr 8, 2025 9:14:30 AM (4 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
168330
Message:

VMM/testcase/tstPGMAllGst-armv8: Updates to the testcase, basic functionality is working, bugref:10388

Location:
trunk/src/VBox/VMM/testcase
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/testcase/Makefile.kmk

    r108859 r108879  
    10041004# ARMv8 PGM guest page table walking testcase.
    10051005#
     1006TST_PGMALLGST_ARMV8_FILE = $(tstPGMAllGst-armv8_0_OUTDIR)/tstPGMAllGst-armv8-tests.cpp
     1007TST_PGMALLGST_ARMV8_SOURCES := \
     1008        tstPGMAllGst_armv8_1=tstPGMAllGst-armv8.json
     1009
     1010TST_PGMALLGST_ARMV8_PATH_SOURCES := $(PATH_SUB_CURRENT)
     1011
     1012$$(TST_PGMALLGST_ARMV8_FILE): $(MAKEFILE_CURRENT) \
     1013                $(foreach source,$(TST_PGMALLGST_ARMV8_SOURCES),$(TST_PGMALLGST_ARMV8_PATH_SOURCES)/$(lastword $(subst =,$(SP),$(source)))) \
     1014                $(VBOX_BIN2C) \
     1015                | $$(dir $$@)
     1016        $(QUIET)$(RM) -f -- $@
     1017        $(QUIET)$(APPEND) -n "$@" \
     1018        '' \
     1019        '#include "tstPGMAllGst-armv8-tests.h"' \
     1020              ''
     1021        $(foreach source,$(TST_PGMALLGST_ARMV8_SOURCES), $(NLTAB)$(VBOX_BIN2C) -ascii --append \
     1022                "$(firstword $(subst =,$(SP),$(source)))" \
     1023                "$(TST_PGMALLGST_ARMV8_PATH_SOURCES)/$(lastword $(subst =,$(SP),$(source)))" \
     1024                "$@")
     1025
     1026OTHER_CLEAN += $(TST_PGMALLGST_ARMV8_FILE)
     1027
    10061028tstPGMAllGst-armv8_TEMPLATE         = VBoxR3TstExe
    1007 tstPGMAllGst-armv8_INCS             = $(VBOX_PATH_VMM_SRC)/include
     1029tstPGMAllGst-armv8_INCS             = \
     1030        $(VBOX_PATH_VMM_SRC)/include \
     1031        .
    10081032tstPGMAllGst-armv8_DEFS             = IN_VMM_R3 VBOX_VMM_TARGET_ARMV8 $(VMM_COMMON_DEFS)
    1009 tstPGMAllGst-armv8_SOURCES          = tstPGMAllGst-armv8.cpp
     1033tstPGMAllGst-armv8_SOURCES          = \
     1034        tstPGMAllGst-armv8.cpp \
     1035        $(TST_PGMALLGST_ARMV8_FILE)
    10101036tstPGMAllGst-armv8_LIBS             = $(LIB_RUNTIME)
    10111037
  • trunk/src/VBox/VMM/testcase/tstPGMAllGst-armv8.cpp

    r108873 r108879  
    11/* $Id$ */
    22/** @file
    3  * PDM Queue Testcase.
     3 * PGM page table walking testcase - ARMv8 variant.
    44 */
    55
    66/*
    7  * Copyright (C) 2022-2024 Oracle and/or its affiliates.
     7 * Copyright (C) 2025 Oracle and/or its affiliates.
    88 *
    99 * This file is part of VirtualBox base platform packages, as
     
    5555#include <iprt/zero.h>
    5656
     57#include "tstPGMAllGst-armv8-tests.h"
     58
    5759
    5860/*********************************************************************************************************************************
     
    239241    RTMemPageFree(pMmuCfg->pVM, sizeof(VM) + sizeof(VMCPU));
    240242    RTAvlrU64Destroy(&pMmuCfg->TreeMem, tstDestroyChunk, NULL);
    241 }
    242 
    243 
    244 static void tstBasic(void)
    245 {
    246     /*
    247      * Create an fake VM structure.
    248      */
    249     int rc = tstMmuCfgInit(&g_MmuCfg);
    250     if (RT_FAILURE(rc))
    251         return;
    252 
    253     /** @todo */
    254 
    255     tstMmuCfgDestroy(&g_MmuCfg);
    256243}
    257244
     
    417404            RTJsonIteratorFree(hIt);
    418405        }
     406        else if (rc == VERR_JSON_IS_EMPTY) /* Empty address space is valid. */
     407            rc = VINF_SUCCESS;
    419408        else
    420409            RTTestFailed(hTest, "Failed to traverse JSON object with %Rrc", rc);
     
    521510
    522511
     512DECLINLINE(int) tstResultQueryBoolDef(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, bool *pf, bool fDef)
     513{
     514    int rc = RTJsonValueQueryBooleanByName(hMemResult, pszName, pf);
     515    if (rc == VERR_NOT_FOUND)
     516    {
     517        *pf = fDef;
     518        rc = VINF_SUCCESS;
     519    }
     520    else if (RT_FAILURE(rc))
     521        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     522
     523    return rc;
     524}
     525
     526
     527DECLINLINE(int) tstResultQueryGCPhysDef(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, RTGCPHYS *pGCPhys, RTGCPHYS GCPhysDef)
     528{
     529    int64_t i64 = 0;
     530    int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
     531    if (rc == VERR_NOT_FOUND)
     532    {
     533        *pGCPhys = GCPhysDef;
     534        rc = VINF_SUCCESS;
     535    }
     536    else if (RT_FAILURE(rc))
     537        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     538    else
     539        *pGCPhys = (RTGCPHYS)i64;
     540
     541    return rc;
     542}
     543
     544
     545DECLINLINE(int) tstResultQueryGCPhys(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, RTGCPHYS *pGCPhys)
     546{
     547    int64_t i64 = 0;
     548    int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
     549    if (RT_FAILURE(rc))
     550        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     551    else
     552        *pGCPhys = (RTGCPHYS)i64;
     553
     554    return rc;
     555}
     556
     557
     558DECLINLINE(int) tstResultQueryU8(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, uint8_t *pu8)
     559{
     560    int64_t i64 = 0;
     561    int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
     562    if (RT_FAILURE(rc))
     563        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     564    else if (i64 < 0 || i64 > UINT8_MAX)
     565        RTTestFailed(hTest, "Value %#RI64 for '%s' is out of bounds", i64, pszName);
     566    else
     567        *pu8 = (uint8_t)i64;
     568
     569    return rc;
     570}
     571
     572
     573DECLINLINE(int) tstResultQueryU32(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, uint32_t *pu32)
     574{
     575    int64_t i64 = 0;
     576    int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
     577    if (RT_FAILURE(rc))
     578        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     579    else if (i64 < 0 || i64 > UINT32_MAX)
     580        RTTestFailed(hTest, "Value %#RI64 for '%s' is out of bounds", i64, pszName);
     581    else
     582        *pu32 = (uint32_t)i64;
     583
     584    return rc;
     585}
     586
     587
     588DECLINLINE(int) tstResultQueryU64(RTTEST hTest, RTJSONVAL hMemResult, const char *pszName, uint64_t *pu64)
     589{
     590    int64_t i64 = 0;
     591    int rc = RTJsonValueQueryIntegerByName(hMemResult, pszName, &i64);
     592    if (RT_FAILURE(rc))
     593        RTTestFailed(hTest, "Querying '%s' failed with %Rrc", pszName, rc);
     594    else
     595        *pu64 = (uint64_t)i64;
     596
     597    return rc;
     598}
     599
     600
     601static int tstResultInit(RTTEST hTest, RTJSONVAL hMemResult, PPGMPTWALK pWalkResult)
     602{
     603    int rc = tstResultQueryBoolDef(hTest, hMemResult, "Succeeded", &pWalkResult->fSucceeded, true);
     604    if (RT_SUCCESS(rc))
     605        rc = tstResultQueryBoolDef(hTest, hMemResult, "IsSlat", &pWalkResult->fIsSlat, false);
     606    if (RT_SUCCESS(rc))
     607        rc = tstResultQueryBoolDef(hTest, hMemResult, "IsLinearAddrValid", &pWalkResult->fIsLinearAddrValid, false);
     608    if (RT_SUCCESS(rc))
     609        rc = tstResultQueryBoolDef(hTest, hMemResult, "NotPresent", &pWalkResult->fNotPresent, false);
     610    if (RT_SUCCESS(rc))
     611        rc = tstResultQueryBoolDef(hTest, hMemResult, "BadPhysAddr", &pWalkResult->fBadPhysAddr, false);
     612    if (RT_SUCCESS(rc))
     613        rc = tstResultQueryBoolDef(hTest, hMemResult, "RsvdError", &pWalkResult->fRsvdError, false);
     614    if (RT_SUCCESS(rc))
     615        rc = tstResultQueryBoolDef(hTest, hMemResult, "BigPage", &pWalkResult->fBigPage, false);
     616    if (RT_SUCCESS(rc))
     617        rc = tstResultQueryBoolDef(hTest, hMemResult, "GigantPage", &pWalkResult->fGigantPage, false);
     618    if (RT_SUCCESS(rc))
     619        rc = tstResultQueryGCPhys(hTest, hMemResult, "GCPhys", &pWalkResult->GCPhys);
     620    if (RT_SUCCESS(rc))
     621        rc = tstResultQueryGCPhysDef(hTest, hMemResult, "GCPhysNested", &pWalkResult->GCPhysNested, 0);
     622    if (RT_SUCCESS(rc))
     623        rc = tstResultQueryU8(hTest, hMemResult, "Level", &pWalkResult->uLevel);
     624    if (RT_SUCCESS(rc))
     625        rc = tstResultQueryU32(hTest, hMemResult, "fFailed", &pWalkResult->fFailed);
     626    if (RT_SUCCESS(rc))
     627        rc = tstResultQueryU64(hTest, hMemResult, "Effective", &pWalkResult->fEffective);
     628
     629    return rc;
     630}
     631
     632
    523633static void tstExecute(RTTEST hTest, PVM pVM, RTGCPTR GCPtr, RTJSONVAL hMemResult)
    524634{
     
    530640                    : pVCpu->pgm.s.aidxGuestModeDataTtbr0[1];
    531641
    532     PGMPTWALK Walk;
     642    PGMPTWALK Walk; RT_ZERO(Walk);
    533643    AssertReleaseReturnVoid(idx < RT_ELEMENTS(g_aPgmGuestModeData));
    534644    AssertReleaseReturnVoid(g_aPgmGuestModeData[idx].pfnGetPage);
     
    536646    if (RT_SUCCESS(rc))
    537647    {
    538         RT_NOREF(hMemResult);
     648        PGMPTWALK WalkResult; RT_ZERO(WalkResult);
     649        WalkResult.GCPtr = GCPtr;
     650
     651        rc = tstResultInit(hTest, hMemResult, &WalkResult);
     652        if (RT_SUCCESS(rc))
     653        {
     654            if (memcmp(&Walk, &WalkResult, sizeof(Walk)))
     655            {
     656                if (Walk.GCPtr != WalkResult.GCPtr)
     657                    RTTestFailed(hTest, "Result GCPtr=%RGv != Expected GCPtr=%RGv", Walk.GCPtr, WalkResult.GCPtr);
     658                if (Walk.GCPhysNested != WalkResult.GCPhysNested)
     659                    RTTestFailed(hTest, "Result GCPhysNested=%RGp != Expected GCPhysNested=%RGp", Walk.GCPhysNested, WalkResult.GCPhysNested);
     660                if (Walk.GCPhys != WalkResult.GCPhys)
     661                    RTTestFailed(hTest, "Result GCPhys=%RGp != Expected GCPhys=%RGp", Walk.GCPhys, WalkResult.GCPhys);
     662                if (Walk.fSucceeded != WalkResult.fSucceeded)
     663                    RTTestFailed(hTest, "Result fSucceeded=%RTbool != Expected fSucceeded=%RTbool", Walk.fSucceeded, WalkResult.fSucceeded);
     664                if (Walk.fIsSlat != WalkResult.fIsSlat)
     665                    RTTestFailed(hTest, "Result fIsSlat=%RTbool != Expected fIsSlat=%RTbool", Walk.fIsSlat, WalkResult.fIsSlat);
     666                if (Walk.fIsLinearAddrValid != WalkResult.fIsLinearAddrValid)
     667                    RTTestFailed(hTest, "Result fIsLinearAddrValid=%RTbool != Expected fIsLinearAddrValid=%RTbool", Walk.fIsLinearAddrValid, WalkResult.fIsLinearAddrValid);
     668                if (Walk.uLevel != WalkResult.uLevel)
     669                    RTTestFailed(hTest, "Result uLevel=%RU8 != Expected uLevel=%RU8", Walk.uLevel, WalkResult.uLevel);
     670                if (Walk.fNotPresent != WalkResult.fNotPresent)
     671                    RTTestFailed(hTest, "Result fNotPresent=%RTbool != Expected fNotPresent=%RTbool", Walk.fNotPresent, WalkResult.fNotPresent);
     672                if (Walk.fBadPhysAddr != WalkResult.fBadPhysAddr)
     673                    RTTestFailed(hTest, "Result fBadPhysAddr=%RTbool != Expected fBadPhysAddr=%RTbool", Walk.fBadPhysAddr, WalkResult.fBadPhysAddr);
     674                if (Walk.fRsvdError != WalkResult.fRsvdError)
     675                    RTTestFailed(hTest, "Result fRsvdError=%RTbool != Expected fRsvdError=%RTbool", Walk.fRsvdError, WalkResult.fRsvdError);
     676                if (Walk.fBigPage != WalkResult.fBigPage)
     677                    RTTestFailed(hTest, "Result fBigPage=%RTbool != Expected fBigPage=%RTbool", Walk.fBigPage, WalkResult.fBigPage);
     678                if (Walk.fGigantPage != WalkResult.fGigantPage)
     679                    RTTestFailed(hTest, "Result fGigantPage=%RTbool != Expected fGigantPage=%RTbool", Walk.fGigantPage, WalkResult.fGigantPage);
     680                if (Walk.fFailed != WalkResult.fFailed)
     681                    RTTestFailed(hTest, "Result fFailed=%#RX32 != Expected fFailed=%#RX32", Walk.fFailed, WalkResult.fFailed);
     682                if (Walk.fEffective != WalkResult.fEffective)
     683                    RTTestFailed(hTest, "Result fEffective=%#RX64 != Expected fEffective=%#RX64", Walk.fEffective, WalkResult.fEffective);
     684            }
     685        }
    539686    }
    540687    else
     
    625772
    626773
    627 static void tstLoadFromFile(RTTEST hTest, const char *pszFilename)
     774static void tstLoadAndRun(RTTEST hTest, RTJSONVAL hRoot)
    628775{
    629776    int rc = tstMmuCfgInit(&g_MmuCfg);
     
    634781    }
    635782
     783    RTJSONVALTYPE enmType = RTJsonValueGetType(hRoot);
     784    if (enmType == RTJSONVALTYPE_ARRAY)
     785    {
     786        /* Array of testcases. */
     787        RTJSONIT hIt = NIL_RTJSONIT;
     788        rc = RTJsonIteratorBeginArray(hRoot, &hIt);
     789        if (RT_SUCCESS(rc))
     790        {
     791            for (;;)
     792            {
     793                RTJSONVAL hTestcase = NIL_RTJSONVAL;
     794                rc = RTJsonIteratorQueryValue(hIt, &hTestcase, NULL /*ppszName*/);
     795                if (RT_SUCCESS(rc))
     796                {
     797                    tstExecuteTestcase(hTest, hTestcase);
     798                    RTJsonValueRelease(hTestcase);
     799                }
     800                else
     801                    RTTestFailed(hTest, "Failed to retrieve testcase with %Rrc", rc);
     802
     803                rc = RTJsonIteratorNext(hIt);
     804                if (RT_FAILURE(rc))
     805                    break;
     806            }
     807            if (rc == VERR_JSON_ITERATOR_END)
     808                rc = VINF_SUCCESS;
     809            RTJsonIteratorFree(hIt);
     810        }
     811        else  /* An empty array is also an error */
     812            RTTestFailed(hTest, "Failed to traverse JSON array with %Rrc", rc);
     813    }
     814    else if (enmType == RTJSONVALTYPE_OBJECT)
     815    {
     816        /* Single testcase. */
     817        tstExecuteTestcase(hTest, hRoot);
     818    }
     819    else
     820        RTTestFailed(hTest, "JSON root is not an array or object containing a testcase");
     821    RTJsonValueRelease(hRoot);
     822    tstMmuCfgDestroy(&g_MmuCfg);
     823}
     824
     825
     826static void tstLoadFromFile(RTTEST hTest, const char *pszFilename)
     827{
    636828    /* Load the configuration from the JSON config file. */
    637829    RTERRINFOSTATIC ErrInfo;
    638830    RTJSONVAL hRoot = NIL_RTJSONVAL;
    639     rc = RTJsonParseFromFile(&hRoot, RTJSON_PARSE_F_JSON5, pszFilename, RTErrInfoInitStatic(&ErrInfo));
    640     if (RT_SUCCESS(rc))
    641     {
    642         RTJSONVALTYPE enmType = RTJsonValueGetType(hRoot);
    643         if (enmType == RTJSONVALTYPE_ARRAY)
    644         {
    645             /* Array of testcases. */
    646             RTJSONIT hIt = NIL_RTJSONIT;
    647             rc = RTJsonIteratorBeginArray(hRoot, &hIt);
    648             if (RT_SUCCESS(rc))
    649             {
    650                 for (;;)
    651                 {
    652                     RTJSONVAL hTestcase = NIL_RTJSONVAL;
    653                     rc = RTJsonIteratorQueryValue(hIt, &hTestcase, NULL /*ppszName*/);
    654                     if (RT_SUCCESS(rc))
    655                     {
    656                         tstExecuteTestcase(hTest, hTestcase);
    657                         RTJsonValueRelease(hTestcase);
    658                     }
    659                     else
    660                         RTTestFailed(hTest, "Failed to retrieve testcase with %Rrc", rc);
    661 
    662                     rc = RTJsonIteratorNext(hIt);
    663                     if (RT_FAILURE(rc))
    664                         break;
    665                 }
    666                 if (rc == VERR_JSON_ITERATOR_END)
    667                     rc = VINF_SUCCESS;
    668                 RTJsonIteratorFree(hIt);
    669             }
    670             else  /* An empty array is also an error */
    671                 RTTestFailed(hTest, "Failed to traverse JSON array with %Rrc", rc);
    672         }
    673         else if (enmType == RTJSONVALTYPE_OBJECT)
    674         {
    675             /* Single testcase. */
    676             tstExecuteTestcase(hTest, hRoot);
    677         }
    678         else
    679             RTTestFailed(hTest, "JSON root is not an array or object containing a testcase");
    680         RTJsonValueRelease(hRoot);
    681     }
     831    int rc = RTJsonParseFromFile(&hRoot, RTJSON_PARSE_F_JSON5, pszFilename, RTErrInfoInitStatic(&ErrInfo));
     832    if (RT_SUCCESS(rc))
     833        tstLoadAndRun(hTest, hRoot);
    682834    else
    683835    {
     
    689841                         pszFilename, rc);
    690842    }
    691 
    692     tstMmuCfgDestroy(&g_MmuCfg);
     843}
     844
     845
     846static void tstBasic(RTTEST hTest)
     847{
     848    RTERRINFOSTATIC ErrInfo;
     849    RTJSONVAL hRoot = NIL_RTJSONVAL;
     850    int rc = RTJsonParseFromBuf(&hRoot, RTJSON_PARSE_F_JSON5,
     851                                g_abtstPGMAllGst_armv8_1, g_cbtstPGMAllGst_armv8_1,
     852                                RTErrInfoInitStatic(&ErrInfo));
     853    if (RT_SUCCESS(rc))
     854        tstLoadAndRun(hTest, hRoot);
     855    else
     856    {
     857        if (RTErrInfoIsSet(&ErrInfo.Core))
     858            RTTestFailed(hTest, "RTJsonParseFromBuf() failed with %Rrc\n%s", rc, ErrInfo.Core.pszMsg);
     859        else
     860            RTTestFailed(hTest, "RTJsonParseFromBuf() failed with %Rrc", rc);
     861    }
    693862}
    694863
     
    710879                tstLoadFromFile(g_hTest, argv[1]);
    711880            else
    712                 tstBasic();
     881                tstBasic(g_hTest);
    713882            rcExit = RTTestSummaryAndDestroy(g_hTest);
    714883        }
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