static void doInVmmTests(RTTEST hTest) { /* * Create empty VM structure and init SSM. */ int rc = SUPR3Init(NULL); if (RT_FAILURE(rc)) { RTTestSkipped(hTest, "SUPR3Init failed with rc=%Rrc", rc); return; } PVM pVM; RTTESTI_CHECK_RC_RETV(SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM), VINF_SUCCESS); PUVM pUVM = (PUVM)RTMemPageAlloc(sizeof(*pUVM)); pUVM->u32Magic = UVM_MAGIC; pUVM->pVM = pVM; pVM->pUVM = pUVM; /* * Do the testing. */ RTTESTI_CHECK_RC_RETV(STAMR3InitUVM(pUVM), VINF_SUCCESS); RTTESTI_CHECK_RC_RETV(MMR3InitUVM(pUVM), VINF_SUCCESS); RTTESTI_CHECK_RC_RETV(CFGMR3Init(pVM, NULL, NULL), VINF_SUCCESS); RTTESTI_CHECK_RETV(CFGMR3GetRoot(pVM) != NULL); doTestsOnDefaultValues(CFGMR3GetRoot(pVM)); doGeneralTests(CFGMR3GetRoot(pVM)); /* done */ RTTESTI_CHECK_RC_RETV(CFGMR3Term(pVM), VINF_SUCCESS); }
/** * Entry point. */ extern "C" DECLEXPORT(int) TrustedMain(int argc, char **argv, char **envp) { /* * Init runtime. */ RTR3InitExe(argc, &argv, 0); /* * Create empty VM structure and call MMR3Init(). */ PVM pVM; RTR0PTR pvR0; SUPPAGE aPages[RT_ALIGN_Z(sizeof(*pVM) + NUM_CPUS * sizeof(VMCPU), PAGE_SIZE) >> PAGE_SHIFT]; int rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) rc = SUPR3LowAlloc(RT_ELEMENTS(aPages), (void **)&pVM, &pvR0, &aPages[0]); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc); return 1; } memset(pVM, 0, sizeof(*pVM)); /* wtf? */ pVM->paVMPagesR3 = aPages; pVM->pVMR0 = pvR0; static UVM s_UVM; PUVM pUVM = &s_UVM; pUVM->pVM = pVM; pVM->pUVM = pUVM; pVM->cCpus = NUM_CPUS; pVM->cbSelf = RT_UOFFSETOF(VM, aCpus[pVM->cCpus]); rc = STAMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3Init(pVM, NULL, NULL); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3Init(pVM); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: MMR3Init failed! rc=%Rrc\n", rc); return 1; } /* * Try allocate. */ static struct { size_t cb; unsigned uAlignment; void *pvAlloc; unsigned iFreeOrder; } aOps[] = { { 16, 0, NULL, 0 }, { 16, 4, NULL, 1 }, { 16, 8, NULL, 2 }, { 16, 16, NULL, 5 }, { 16, 32, NULL, 4 }, { 32, 0, NULL, 3 }, { 31, 0, NULL, 6 }, { 1024, 0, NULL, 8 }, { 1024, 32, NULL, 10 }, { 1024, 32, NULL, 12 }, { PAGE_SIZE, PAGE_SIZE, NULL, 13 }, { 1024, 32, NULL, 9 }, { PAGE_SIZE, 32, NULL, 11 }, { PAGE_SIZE, PAGE_SIZE, NULL, 14 }, { 16, 0, NULL, 15 }, { 9, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 36, 0, NULL, 7 }, { 16, 0, NULL, 7 }, { 12344, 0, NULL, 7 }, { 50, 0, NULL, 7 }, { 16, 0, NULL, 7 }, }; unsigned i; #ifdef DEBUG MMHyperHeapDump(pVM); #endif size_t cbBefore = MMHyperHeapGetFreeSize(pVM); static char szFill[] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; /* allocate */ for (i = 0; i < RT_ELEMENTS(aOps); i++) { rc = MMHyperAlloc(pVM, aOps[i].cb, aOps[i].uAlignment, MM_TAG_VM, &aOps[i].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %d i=%d\n", aOps[i].cb, aOps[i].uAlignment, rc, i); return 1; } memset(aOps[i].pvAlloc, szFill[i], aOps[i].cb); if (RT_ALIGN_P(aOps[i].pvAlloc, (aOps[i].uAlignment ? aOps[i].uAlignment : 8)) != aOps[i].pvAlloc) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %p, invalid alignment!\n", aOps[i].cb, aOps[i].uAlignment, aOps[i].pvAlloc); return 1; } } /* free and allocate the same node again. */ for (i = 0; i < RT_ELEMENTS(aOps); i++) { if ( !aOps[i].pvAlloc || aOps[i].uAlignment == PAGE_SIZE) continue; //size_t cbBeforeSub = MMHyperHeapGetFreeSize(pVM); rc = MMHyperFree(pVM, aOps[i].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperFree(, %p,) -> %d i=%d\n", aOps[i].pvAlloc, rc, i); return 1; } //RTPrintf("debug: i=%d cbBeforeSub=%d now=%d\n", i, cbBeforeSub, MMHyperHeapGetFreeSize(pVM)); void *pv; rc = MMHyperAlloc(pVM, aOps[i].cb, aOps[i].uAlignment, MM_TAG_VM_REQ, &pv); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperAlloc(, %#x, %#x,) -> %d i=%d\n", aOps[i].cb, aOps[i].uAlignment, rc, i); return 1; } if (pv != aOps[i].pvAlloc) { RTPrintf("Failure: Free+Alloc returned different address. new=%p old=%p i=%d (doesn't work with delayed free)\n", pv, aOps[i].pvAlloc, i); //return 1; } aOps[i].pvAlloc = pv; #if 0 /* won't work :/ */ size_t cbAfterSub = MMHyperHeapGetFreeSize(pVM); if (cbBeforeSub != cbAfterSub) { RTPrintf("Failure: cbBeforeSub=%d cbAfterSub=%d. i=%d\n", cbBeforeSub, cbAfterSub, i); return 1; } #endif } /* free it in a specific order. */ int cFreed = 0; for (i = 0; i < RT_ELEMENTS(aOps); i++) { unsigned j; for (j = 0; j < RT_ELEMENTS(aOps); j++) { if ( aOps[j].iFreeOrder != i || !aOps[j].pvAlloc) continue; RTPrintf("j=%d i=%d free=%d cb=%d pv=%p\n", j, i, MMHyperHeapGetFreeSize(pVM), aOps[j].cb, aOps[j].pvAlloc); if (aOps[j].uAlignment == PAGE_SIZE) cbBefore -= aOps[j].cb; else { rc = MMHyperFree(pVM, aOps[j].pvAlloc); if (RT_FAILURE(rc)) { RTPrintf("Failure: MMHyperFree(, %p,) -> %d j=%d i=%d\n", aOps[j].pvAlloc, rc, i, j); return 1; } } aOps[j].pvAlloc = NULL; cFreed++; } } Assert(cFreed == RT_ELEMENTS(aOps)); RTPrintf("i=done free=%d\n", MMHyperHeapGetFreeSize(pVM)); /* check that we're back at the right amount of free memory. */ size_t cbAfter = MMHyperHeapGetFreeSize(pVM); if (cbBefore != cbAfter) { RTPrintf("Warning: Either we've split out an alignment chunk at the start, or we've got\n" " an alloc/free accounting bug: cbBefore=%d cbAfter=%d\n", cbBefore, cbAfter); #ifdef DEBUG MMHyperHeapDump(pVM); #endif } RTPrintf("tstMMHyperHeap: Success\n"); #ifdef LOG_ENABLED RTLogFlush(NULL); #endif return 0; }
int main() { /* * Init runtime. */ RTR3InitExeNoArguments(RTR3INIT_FLAGS_SUPLIB); /* * Create empty VM structure and init SSM. */ PVM pVM; int rc = SUPR3Init(NULL); if (RT_SUCCESS(rc)) rc = SUPR3PageAlloc(RT_ALIGN_Z(sizeof(*pVM), PAGE_SIZE) >> PAGE_SHIFT, (void **)&pVM); if (RT_FAILURE(rc)) { RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc); return 1; } static UVM s_UVM; PUVM pUVM = &s_UVM; pUVM->pVM = pVM; pVM->pUVM = pUVM; rc = STAMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = MMR3InitUVM(pUVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: STAMR3Init failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3Init(pVM, NULL, NULL); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3Init failed. rc=%Rrc\n", rc); return 1; } if (!CFGMR3GetRoot(pVM)) { RTPrintf("FAILURE: CFGMR3GetRoot failed\n"); return 1; } /* integer */ uint64_t u64; rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &u64); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } size_t cb; rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "RamSize", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != sizeof(uint64_t)) { RTPrintf("FAILURE: Incorrect valuesize %d for \"RamSize\" value.\n", cb); return 1; } /* string */ char *pszName = NULL; rc = CFGMR3QueryStringAlloc(CFGMR3GetRoot(pVM), "Name", &pszName); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryStringAlloc(,\"Name\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3QuerySize(CFGMR3GetRoot(pVM), "Name", &cb); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QuerySize(,\"RamSize\",) failed. rc=%Rrc\n", rc); return 1; } if (cb != strlen(pszName) + 1) { RTPrintf("FAILURE: Incorrect valuesize %d for \"Name\" value '%s'.\n", cb, pszName); return 1; } MMR3HeapFree(pszName); /* test multilevel node creation */ PCFGMNODE pChild = NULL; rc = CFGMR3InsertNode(CFGMR3GetRoot(pVM), "First/Second/Third//Final", &pChild); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertNode(,\"First/Second/Third//Final\" failed. rc=%Rrc\n", rc); return 1; } rc = CFGMR3InsertInteger(pChild, "BoolValue", 1); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3InsertInteger(,\"BoolValue\", 1) failed. rc=%Rrc\n", rc); return 1; } PCFGMNODE pNode = CFGMR3GetChild(CFGMR3GetRoot(pVM), "First/Second/Third/Final"); if (pNode != pChild) { RTPrintf("FAILURE: CFGMR3GetChild(,\"First/Second/Third/Final/BoolValue\") failed. pNode=%p expected %p\n", pNode, pChild); return 1; } bool f = false; rc = CFGMR3QueryBool(pNode, "BoolValue", &f); if (RT_FAILURE(rc) || !f) { RTPrintf("FAILURE: CFGMR3QueryBool(,\"BoolValue\",) failed. rc=%Rrc f=%d\n", rc, f); return 1; } /* done */ rc = CFGMR3Term(pVM); if (RT_FAILURE(rc)) { RTPrintf("FAILURE: CFGMR3QueryU64(,\"RamSize\" failed. rc=%Rrc\n", rc); return 1; } RTPrintf("tstCFGM: SUCCESS\n"); return rc; }