VirtualBox

Changeset 5240 in vbox for trunk


Ignore:
Timestamp:
Oct 11, 2007 3:57:00 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
25193
Message:

GCFGM mock-up.

Location:
trunk
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gvmm.h

    r5233 r5240  
    107107GVMMR0DECL(int)     GVMMR0Init(void);
    108108GVMMR0DECL(void)    GVMMR0Term(void);
     109GVMMR0DECL(int)     GVMMR0SetConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t u64Value);
     110GVMMR0DECL(int)     GVMMR0QueryConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t *pu64Value);
    109111
    110112GVMMR0DECL(int)     GVMMR0CreateVM(PSUPDRVSESSION pSession, PVM *ppVM);
  • trunk/include/VBox/vmm.h

    r5233 r5240  
    404404    VMMR0_DO_GMM_SEED_CHUNK,
    405405
    406     /** Gets the GMM and GVMM stats. */
    407     VMMR0_DO_GET_GXX_STATS,
     406    /** Set a GVMM or GMM configuration value. */
     407    VMMR0_DO_GCFGM_SET_VALUE,
     408    /** Query a GVMM or GMM configuration value. */
     409    VMMR0_DO_GCFGM_QUERY_VALUE,
    408410
    409411    /** The start of the R0 service operations. */
     
    431433} VMMR0OPERATION;
    432434
     435
     436/**
     437 * Request buffer for VMMR0_DO_GCFGM_SET_VALUE and VMMR0_DO_GCFGM_QUERY_VALUE.
     438 * @todo Move got GCFGM.h when it's implemented.
     439 */
     440typedef struct GCFGMVALUEREQ
     441{
     442    /** The request header.*/
     443    SUPVMMR0REQHDR      Hdr;
     444    /** The support driver session handle. */
     445    PSUPDRVSESSION      pSession;
     446    /** The value.
     447     * This is input for the set request and output for the query. */
     448    uint64_t            u64Value;
     449    /** The variable name.
     450     * This is fixed sized just to make things simple for the mock-up. */
     451    char                szName[48];
     452} GCFGMVALUEREQ;
     453/** Pointer to a VMMR0_DO_GCFGM_SET_VALUE and VMMR0_DO_GCFGM_QUERY_VALUE request buffer.
     454 * @todo Move got GCFGM.h when it's implemented.
     455 */
     456typedef GCFGMVALUEREQ *PGCFGMVALUEREQ;
     457
     458
    433459/**
    434460 * The Ring 0 entry point, called by the interrupt gate.
  • trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp

    r5233 r5240  
    107107     * The first entry is unused as it represents the NIL handle. */
    108108    GVMHANDLE           aHandles[128];
     109
     110    /** The minimum sleep time, in nano seconds.
     111     * @gcfgm   /GVMM/MinSleep      32-bit  0..100000000
     112     */
     113    uint32_t            nsMinSleep;
     114    /** The limit for the first round of early wakeups, given in nano seconds.
     115     * @gcfgm   /GVMM/EarlyWakeUp1  32-bit  0..100000000
     116     */
     117    uint32_t            nsEarlyWakeUp1;
     118    /** The limit for the second round of early wakeups, given in nano seconds.
     119     * @gcfgm   /GVMM/EarlyWakeUp2  32-bit  0..100000000
     120     */
     121    uint32_t            nsEarlyWakeUp2;
    109122} GVMM;
    110123/** Pointer to the GVMM instance data. */
     
    202215            }
    203216
     217            /* The default configuration values. */
     218            pGVMM->nsMinSleep     = 750000 /* ns (0.750 ms) */; /** @todo this should be adjusted to be 75% (or something) of the scheduler granularity... */
     219            pGVMM->nsEarlyWakeUp1 =  25000 /* ns (0.025 ms) */;
     220            pGVMM->nsEarlyWakeUp2 =  50000 /* ns (0.050 ms) */;
     221
    204222            g_pGVMM = pGVMM;
    205223            LogFlow(("GVMMR0Init: pGVMM=%p\n", pGVMM));
     
    249267
    250268    RTMemFree(pGVMM);
     269}
     270
     271
     272/**
     273 * A quick hack for setting global config values.
     274 *
     275 * @returns VBox status code.
     276 *
     277 * @param   pSession    The session handle. Used for authentication.
     278 * @param   pszName     The variable name.
     279 * @param   u64Value    The new value.
     280 */
     281GVMMR0DECL(int) GVMMR0SetConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t u64Value)
     282{
     283    /*
     284     * Validate input.
     285     */
     286    PGVMM pGVMM;
     287    GVMM_GET_VALID_INSTANCE(pGVMM, VERR_INTERNAL_ERROR);
     288    AssertPtrReturn(pSession, VERR_INVALID_HANDLE);
     289    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     290
     291    /*
     292     * String switch time!
     293     */
     294    if (strncmp(pszName, "/GVMM/", sizeof("/GVMM/") - 1))
     295        return VERR_CFGM_VALUE_NOT_FOUND; /* borrow status codes from CFGM... */
     296    int rc = VINF_SUCCESS;
     297    pszName += sizeof("/GVMM/") - 1;
     298    if (!strcmp(pszName, "MinSleep"))
     299    {
     300        if (u64Value <= 100000000)
     301            pGVMM->nsMinSleep = u64Value;
     302        else
     303            rc = VERR_OUT_OF_RANGE;
     304    }
     305    else if (!strcmp(pszName, "EarlyWakeUp1"))
     306    {
     307        if (u64Value <= 100000000)
     308            pGVMM->nsEarlyWakeUp1 = u64Value;
     309        else
     310            rc = VERR_OUT_OF_RANGE;
     311    }
     312    else if (!strcmp(pszName, "EarlyWakeUp2"))
     313    {
     314        if (u64Value <= 100000000)
     315            pGVMM->nsEarlyWakeUp2 = u64Value;
     316        else
     317            rc = VERR_OUT_OF_RANGE;
     318    }
     319    else
     320        rc = VERR_CFGM_VALUE_NOT_FOUND;
     321    return rc;
     322}
     323
     324
     325/**
     326 * A quick hack for getting global config values.
     327 *
     328 * @returns VBox status code.
     329 *
     330 * @param   pSession    The session handle. Used for authentication.
     331 * @param   pszName     The variable name.
     332 * @param   u64Value    The new value.
     333 */
     334GVMMR0DECL(int) GVMMR0QueryConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t *pu64Value)
     335{
     336    /*
     337     * Validate input.
     338     */
     339    PGVMM pGVMM;
     340    GVMM_GET_VALID_INSTANCE(pGVMM, VERR_INTERNAL_ERROR);
     341    AssertPtrReturn(pSession, VERR_INVALID_HANDLE);
     342    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     343    AssertPtrReturn(pu64Value, VERR_INVALID_POINTER);
     344
     345    /*
     346     * String switch time!
     347     */
     348    if (strncmp(pszName, "/GVMM/", sizeof("/GVMM/") - 1))
     349        return VERR_CFGM_VALUE_NOT_FOUND; /* borrow status codes from CFGM... */
     350    int rc = VINF_SUCCESS;
     351    pszName += sizeof("/GVMM/") - 1;
     352    if (!strcmp(pszName, "MinSleep"))
     353        *pu64Value = pGVMM->nsMinSleep;
     354    else if (!strcmp(pszName, "EarlyWakeUp1"))
     355        *pu64Value = pGVMM->nsEarlyWakeUp1;
     356    else if (!strcmp(pszName, "EarlyWakeUp2"))
     357        *pu64Value = pGVMM->nsEarlyWakeUp2;
     358    else
     359        rc = VERR_CFGM_VALUE_NOT_FOUND;
     360    return rc;
    251361}
    252362
     
    11281238                if (u64 <= u64Now)
    11291239                {
    1130                     ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0);
     1240                    if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1241                    {
     1242                        int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
     1243                        AssertRC(rc);
     1244                        cWoken++;
     1245                    }
     1246                }
     1247                else
     1248                {
     1249                    cHalted++;
     1250                    if (u64 <= u64Now + pGVMM->nsEarlyWakeUp1)
     1251                        cTodo2nd++;
     1252                    else if (u64 <= u64Now + pGVMM->nsEarlyWakeUp2)
     1253                        cTodo3rd++;
     1254                }
     1255            }
     1256        }
     1257    }
     1258
     1259    if (cTodo2nd)
     1260    {
     1261        for (unsigned i = pGVMM->iUsedHead;
     1262             i != NIL_GVM_HANDLE && i < RT_ELEMENTS(pGVMM->aHandles);
     1263             i = pGVMM->aHandles[i].iNext)
     1264        {
     1265            PGVM pCurGVM = pGVMM->aHandles[i].pGVM;
     1266            if (    VALID_PTR(pCurGVM)
     1267                &&  pCurGVM->u32Magic == GVM_MAGIC
     1268                &&  pCurGVM->gvmm.s.u64HaltExpire
     1269                &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp1)
     1270            {
     1271                if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1272                {
    11311273                    int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    11321274                    AssertRC(rc);
    11331275                    cWoken++;
    11341276                }
    1135                 else
    1136                 {
    1137                     cHalted++;
    1138                     /** @todo make these limits configurable! */
    1139                     if (u64 <= u64Now + 25000 /* 0.025 ms */)
    1140                         cTodo2nd++;
    1141                     else if (u64 <= u64Now + 50000 /* 0.050 ms */)
    1142                         cTodo3rd++;
    1143                 }
    11441277            }
    11451278        }
    11461279    }
    11471280
    1148     if (cTodo2nd)
     1281    if (cTodo3rd)
    11491282    {
    11501283        for (unsigned i = pGVMM->iUsedHead;
     
    11551288            if (    VALID_PTR(pCurGVM)
    11561289                &&  pCurGVM->u32Magic == GVM_MAGIC
    1157                 &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + 25000 /* 0.025 ms */)
     1290                &&  pCurGVM->gvmm.s.u64HaltExpire
     1291                &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + pGVMM->nsEarlyWakeUp2)
    11581292            {
    1159                 ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0);
    1160                 int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    1161                 AssertRC(rc);
    1162                 cWoken++;
    1163             }
    1164         }
    1165     }
    1166 
    1167     if (cTodo3rd)
    1168     {
    1169         for (unsigned i = pGVMM->iUsedHead;
    1170              i != NIL_GVM_HANDLE && i < RT_ELEMENTS(pGVMM->aHandles);
    1171              i = pGVMM->aHandles[i].iNext)
    1172         {
    1173             PGVM pCurGVM = pGVMM->aHandles[i].pGVM;
    1174             if (    VALID_PTR(pCurGVM)
    1175                 &&  pCurGVM->u32Magic == GVM_MAGIC
    1176                 &&  pCurGVM->gvmm.s.u64HaltExpire <= u64Now + 50000 /* 0.050 ms */)
    1177             {
    1178                 ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0);
    1179                 int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
    1180                 AssertRC(rc);
    1181                 cWoken++;
     1293                if (ASMAtomicXchgU64(&pCurGVM->gvmm.s.u64HaltExpire, 0))
     1294                {
     1295                    int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti);
     1296                    AssertRC(rc);
     1297                    cWoken++;
     1298                }
    11821299            }
    11831300        }
     
    12321349    if (    u64Now < u64ExpireGipTime
    12331350        &&  (   pGVMM->cVMs > 1
    1234              || (u64ExpireGipTime - u64Now > 750000 /* 0.750 ms */))) /** @todo make this configurable */
     1351             || (u64ExpireGipTime - u64Now >= pGVMM->nsMinSleep)))
    12351352    {
    12361353        pGVM->gvmm.s.StatsSched.cHaltBlocking++;
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r5233 r5240  
    803803            return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg);
    804804
     805        /*
     806         * A quick GCFGM mock-up.
     807         */
     808        /** @todo GCFGM with proper access control, ring-3 management interface and all that. */
     809        case VMMR0_DO_GCFGM_SET_VALUE:
     810        case VMMR0_DO_GCFGM_QUERY_VALUE:
     811        {
     812            if (pVM || !pReqHdr || u64Arg)
     813                return VERR_INVALID_PARAMETER;
     814            PGCFGMVALUEREQ pReq = (PGCFGMVALUEREQ)pReqHdr;
     815            if (pReq->Hdr.cbReq != sizeof(*pReq))
     816                return VERR_INVALID_PARAMETER;
     817            int rc;
     818            if (enmOperation == VMMR0_DO_GCFGM_SET_VALUE)
     819            {
     820                rc = GVMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
     821                //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     822                //    rc = GMMR0SetConfig(pReq->pSession, &pReq->szName[0], pReq->u64Value);
     823            }
     824            else
     825            {
     826                rc = GVMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
     827                //if (rc == VERR_CFGM_VALUE_NOT_FOUND)
     828                //    rc = GMMR0QueryConfig(pReq->pSession, &pReq->szName[0], &pReq->u64Value);
     829            }
     830            return rc;
     831        }
     832
    805833
    806834#if 0//def VBOX_WITH_INTERNAL_NETWORKING - currently busted
  • trunk/src/VBox/VMM/testcase/Makefile.kmk

    r5124 r5240  
    2222# Target lists.
    2323#
    24 PROGRAMS   += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm
     24PROGRAMS   += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm tstGlobalConfig
    2525ifneq ($(BUILD_TARGET),win)
    2626PROGRAMS   += tstVMMFork
     
    103103tstAsmStructs.cpp_DEPS  = $(PATH_TARGET)/tstAsmStructsHC.h $(PATH_TARGET)/tstAsmStructsGC.h
    104104
     105
     106tstGlobalConfig_TEMPLATE= VBOXR3TSTEXE
     107tstGlobalConfig_SOURCES = tstGlobalConfig.cpp
     108tstGlobalConfig_LIBS    = $(LIB_RUNTIME)
    105109
    106110tstMMHyperHeap_TEMPLATE = VBOXR3TSTEXE
  • trunk/src/VBox/VMM/testcase/tstGlobalConfig.cpp

    r5232 r5240  
    11/* $Id$ */
    22/** @file
    3  * VMM Testcase.
     3 * Ring-3 Management program for the GCFGM mock-up.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2007 innotek GmbH
     7 * Copyright (C) 2007 innotek GmbH
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2020*   Header Files                                                               *
    2121*******************************************************************************/
    22 #include <VBox/vm.h>
    2322#include <VBox/vmm.h>
    24 #include <VBox/cpum.h>
    2523#include <VBox/err.h>
    26 #include <VBox/log.h>
    2724#include <iprt/assert.h>
    28 #include <iprt/runtime.h>
    29 #include <iprt/semaphore.h>
     25#include <iprt/initterm.h>
    3026#include <iprt/stream.h>
     27#include <iprt/string.h>
    3128
    3229
    33 /*******************************************************************************
    34 *   Defined Constants And Macros                                               *
    35 *******************************************************************************/
    36 #define TESTCASE    "tstVMM"
    37 
    38 VMMR3DECL(int) VMMDoTest(PVM pVM);
     30/**
     31 * Prints the usage and returns 1.
     32 * @return 1
     33 */
     34static int Usage(void)
     35{
     36    RTPrintf("usage: tstGlobalConfig <value-name> [new value]\n");
     37    return 1;
     38}
    3939
    4040
    4141int main(int argc, char **argv)
    4242{
    43     int     rcRet = 0;                  /* error count. */
    44 
    45     RTR3Init();
     43    RTR3Init(false, 0);
    4644
    4745    /*
    48      * Create empty VM.
     46     * Parse args, building the request as we do so.
    4947     */
    50     RTPrintf(TESTCASE ": Initializing...\n");
    51     PVM pVM;
    52     int rc = VMR3Create(NULL, NULL, NULL, NULL, &pVM);
    53     if (VBOX_SUCCESS(rc))
     48    if (argc <= 1)
     49        return Usage();
     50    if (argc > 3)
    5451    {
    55         /*
    56          * Do testing.
    57          */
    58         RTPrintf(TESTCASE ": Testing...\n");
    59         PVMREQ pReq1 = NULL;
    60         rc = VMR3ReqCall(pVM, &pReq1, RT_INDEFINITE_WAIT, (PFNRT)VMMDoTest, 1, pVM);
    61         AssertRC(rc);
    62         VMR3ReqFree(pReq1);
    63 
    64         STAMR3Dump(pVM, "*");
    65 
    66         /*
    67          * Cleanup.
    68          */
    69         rc = VMR3Destroy(pVM);
    70         if (!VBOX_SUCCESS(rc))
    71         {
    72             RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%d\n", rc);
    73             rcRet++;
    74         }
    75     }
    76     else
    77     {
    78         RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%d\n", rc);
    79         rcRet++;
     52        RTPrintf("syntax error: too many arguments\n");
     53        Usage();
     54        return 1;
    8055    }
    8156
    82     return rcRet;
     57    VMMR0OPERATION enmOp = VMMR0_DO_GCFGM_QUERY_VALUE;
     58    GCFGMVALUEREQ Req;
     59    memset(&Req, 0, sizeof(Req));
     60    Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     61    Req.Hdr.cbReq = sizeof(Req);
     62
     63    /* arg[1] = szName */
     64    size_t cch = strlen(argv[1]);
     65    if (cch < 2 || argv[1][0] != '/')
     66    {
     67        RTPrintf("syntax error: malformed name '%s'\n", argv[1]);
     68        return 1;
     69    }
     70    if (cch >= sizeof(Req.szName))
     71    {
     72        RTPrintf("syntax error: the name is too long. (max %zu chars)\n", argv[1], sizeof(Req.szName) - 1);
     73        return 1;
     74    }
     75    memcpy(&Req.szName[0], argv[1], cch + 1);
     76
     77    /* argv[2] = u64SetValue; optional */
     78    if (argc == 3)
     79    {
     80        char *pszNext = NULL;
     81        int rc = RTStrToUInt64Ex(argv[2], &pszNext, 0, &Req.u64Value);
     82        if (RT_FAILURE(rc) || *pszNext)
     83        {
     84            RTPrintf("syntax error: '%s' didn't convert successfully to a number. (%Rrc,'%s')\n", argv[2], rc, pszNext);
     85            return 1;
     86        }
     87        enmOp = VMMR0_DO_GCFGM_SET_VALUE;
     88    }
     89
     90    /*
     91     * Open the session, load ring-0 and issue the request.
     92     */
     93    PSUPDRVSESSION pSession;
     94    int rc = SUPInit(&pSession, 0);
     95    if (RT_FAILURE(rc))
     96    {
     97        RTPrintf("tstGlobalConfig: SUPInit -> %Rrc\n", rc);
     98        return 1;
     99    }
     100
     101    rc = SUPLoadVMM("./VMMR0.r0");
     102    if (RT_SUCCESS(rc))
     103    {
     104        Req.pSession = pSession;
     105        rc = SUPCallVMMR0Ex(NIL_RTR0PTR, enmOp, 0, &Req.Hdr);
     106        if (RT_SUCCESS(rc))
     107        {
     108            if (enmOp == VMMR0_DO_GCFGM_QUERY_VALUE)
     109                RTPrintf("%s = %RU64 (%#RX64)\n", Req.szName, Req.u64Value, Req.u64Value);
     110            else
     111                RTPrintf("Successfully set %s = %RU64 (%#RX64)\n", Req.szName, Req.u64Value, Req.u64Value);
     112        }
     113        else if (enmOp == VMMR0_DO_GCFGM_QUERY_VALUE)
     114            RTPrintf("error: Failed to query '%s', rc=%Rrc\n", Req.szName, rc);
     115        else
     116            RTPrintf("error: Failed to set '%s' to %RU64, rc=%Rrc\n", Req.szName, Req.u64Value, rc);
     117
     118    }
     119    SUPTerm(false /* not forced */);
     120
     121    return RT_FAILURE(rc) ? 1 : 0;
    83122}
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