- Timestamp:
- Oct 11, 2007 3:57:00 PM (17 years ago)
- svn:sync-xref-src-repo-rev:
- 25193
- Location:
- trunk
- Files:
-
- 5 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/gvmm.h
r5233 r5240 107 107 GVMMR0DECL(int) GVMMR0Init(void); 108 108 GVMMR0DECL(void) GVMMR0Term(void); 109 GVMMR0DECL(int) GVMMR0SetConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t u64Value); 110 GVMMR0DECL(int) GVMMR0QueryConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t *pu64Value); 109 111 110 112 GVMMR0DECL(int) GVMMR0CreateVM(PSUPDRVSESSION pSession, PVM *ppVM); -
trunk/include/VBox/vmm.h
r5233 r5240 404 404 VMMR0_DO_GMM_SEED_CHUNK, 405 405 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, 408 410 409 411 /** The start of the R0 service operations. */ … … 431 433 } VMMR0OPERATION; 432 434 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 */ 440 typedef 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 */ 456 typedef GCFGMVALUEREQ *PGCFGMVALUEREQ; 457 458 433 459 /** 434 460 * The Ring 0 entry point, called by the interrupt gate. -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r5233 r5240 107 107 * The first entry is unused as it represents the NIL handle. */ 108 108 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; 109 122 } GVMM; 110 123 /** Pointer to the GVMM instance data. */ … … 202 215 } 203 216 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 204 222 g_pGVMM = pGVMM; 205 223 LogFlow(("GVMMR0Init: pGVMM=%p\n", pGVMM)); … … 249 267 250 268 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 */ 281 GVMMR0DECL(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 */ 334 GVMMR0DECL(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; 251 361 } 252 362 … … 1128 1238 if (u64 <= u64Now) 1129 1239 { 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 { 1131 1273 int rc = RTSemEventMultiSignal(pCurGVM->gvmm.s.HaltEventMulti); 1132 1274 AssertRC(rc); 1133 1275 cWoken++; 1134 1276 } 1135 else1136 {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 }1144 1277 } 1145 1278 } 1146 1279 } 1147 1280 1148 if (cTodo 2nd)1281 if (cTodo3rd) 1149 1282 { 1150 1283 for (unsigned i = pGVMM->iUsedHead; … … 1155 1288 if ( VALID_PTR(pCurGVM) 1156 1289 && 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) 1158 1292 { 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 } 1182 1299 } 1183 1300 } … … 1232 1349 if ( u64Now < u64ExpireGipTime 1233 1350 && ( pGVMM->cVMs > 1 1234 || (u64ExpireGipTime - u64Now > 750000 /* 0.750 ms */))) /** @todo make this configurable */1351 || (u64ExpireGipTime - u64Now >= pGVMM->nsMinSleep))) 1235 1352 { 1236 1353 pGVM->gvmm.s.StatsSched.cHaltBlocking++; -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r5233 r5240 803 803 return GMMR0SeedChunk(pVM, (RTR3PTR)u64Arg); 804 804 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 805 833 806 834 #if 0//def VBOX_WITH_INTERNAL_NETWORKING - currently busted -
trunk/src/VBox/VMM/testcase/Makefile.kmk
r5124 r5240 22 22 # Target lists. 23 23 # 24 PROGRAMS += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm 24 PROGRAMS += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm tstGlobalConfig 25 25 ifneq ($(BUILD_TARGET),win) 26 26 PROGRAMS += tstVMMFork … … 103 103 tstAsmStructs.cpp_DEPS = $(PATH_TARGET)/tstAsmStructsHC.h $(PATH_TARGET)/tstAsmStructsGC.h 104 104 105 106 tstGlobalConfig_TEMPLATE= VBOXR3TSTEXE 107 tstGlobalConfig_SOURCES = tstGlobalConfig.cpp 108 tstGlobalConfig_LIBS = $(LIB_RUNTIME) 105 109 106 110 tstMMHyperHeap_TEMPLATE = VBOXR3TSTEXE -
trunk/src/VBox/VMM/testcase/tstGlobalConfig.cpp
r5232 r5240 1 1 /* $Id$ */ 2 2 /** @file 3 * VMM Testcase.3 * Ring-3 Management program for the GCFGM mock-up. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 200 6-2007 innotek GmbH7 * Copyright (C) 2007 innotek GmbH 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 * Header Files * 21 21 *******************************************************************************/ 22 #include <VBox/vm.h>23 22 #include <VBox/vmm.h> 24 #include <VBox/cpum.h>25 23 #include <VBox/err.h> 26 #include <VBox/log.h>27 24 #include <iprt/assert.h> 28 #include <iprt/runtime.h> 29 #include <iprt/semaphore.h> 25 #include <iprt/initterm.h> 30 26 #include <iprt/stream.h> 27 #include <iprt/string.h> 31 28 32 29 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 */ 34 static int Usage(void) 35 { 36 RTPrintf("usage: tstGlobalConfig <value-name> [new value]\n"); 37 return 1; 38 } 39 39 40 40 41 41 int main(int argc, char **argv) 42 42 { 43 int rcRet = 0; /* error count. */ 44 45 RTR3Init(); 43 RTR3Init(false, 0); 46 44 47 45 /* 48 * Create empty VM.46 * Parse args, building the request as we do so. 49 47 */ 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) 54 51 { 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; 80 55 } 81 56 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; 83 122 }
Note:
See TracChangeset
for help on using the changeset viewer.