static void run_benchmark(coreid_t core, int requests) { errval_t err; struct capref ramcap; int i = -1; int bits = MEM_BITS; debug_printf("starting benchmark. allocating mem of size: %d\n", bits); //debug_printf("starting benchmark. allocating mem of size: %d to %d\n", // MINSIZEBITS, MINSIZEBITS+requests-1); sleep_init(); do { i++; // bits = MINSIZEBITS+i; trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_ALLOC, i); err = ram_alloc(&ramcap, bits); // milli_sleep(1); /* if ((i % 500 == 0) && (i > 0)) { debug_printf("allocated %d caps\n", i); } */ } while (err_is_ok(err)); // && (i < requests)); debug_printf("done benchmark. allocated %d caps (%lu bytes)\n", i, i * (1UL << bits)); }
int main(int argc, char **argv) { struct capref theram; // Get an 8K RAM cap errval_t err = ram_alloc(&theram, 13); assert(err_is_ok(err)); for(int i = 0; i < 100; i++) { thread_yield(); } struct capability cap; err = debug_cap_identify(theram, &cap); assert(err_is_ok(err)); assert(cap.type == ObjType_RAM); printf("got RAM at 0x%" PRIxGENPADDR ", size %u\n", cap.u.ram.base, cap.u.ram.bits); struct capref leftcap, rightcap; // XXX: Hopefully allocates two consecutive slots err = slot_alloc(&leftcap); assert(err_is_ok(err)); err = slot_alloc(&rightcap); assert(err_is_ok(err)); // Split in half err = cap_retype(leftcap, theram, ObjType_RAM, 12); assert(err_is_ok(err)); err = debug_cap_identify(leftcap, &cap); assert(err_is_ok(err)); assert(cap.type == ObjType_RAM); printf("left half at 0x%" PRIxGENPADDR ", size %u\n", cap.u.ram.base, cap.u.ram.bits); err = debug_cap_identify(rightcap, &cap); assert(err_is_ok(err)); assert(cap.type == ObjType_RAM); printf("right half at 0x%" PRIxGENPADDR ", size %u\n", cap.u.ram.base, cap.u.ram.bits); // Delete the parent (8K range) printf("deleting parent\n"); err = cap_delete(theram); assert(err_is_ok(err)); // Delete the left half (4K) printf("deleting left half\n"); err = cap_delete(leftcap); assert(err_is_ok(err)); // Delete the right half (4K) printf("deleting right half\n"); err = cap_delete(rightcap); assert(err_is_ok(err)); return 0; }
void rom_setvramsize(rom_t *r,int banks) { banks *= 0x2000; //if vram size hasnt changed, return if(r->vramsize == banks) return; //set vram size and create mask r->vramsize = banks; r->vrammask = rom_createmask(banks); //allocate (or reallocate) memory r->vram = ram_alloc(r->vramsize,r->vram); r->vcache = (cache_t*)ram_alloc(r->vramsize,r->vcache); r->vcache_hflip = (cache_t*)ram_alloc(r->vramsize,r->vcache_hflip); log_message("vram size set to %dk\n",banks); }
static void ram_hack(void) { errval_t err; for (int i = 0; i < 100; i++) { err = ram_alloc(&ram_caps[i], BASE_PAGE_BITS); assert(err_is_ok(err)); } err = ram_alloc_set(my_ram_alloc); assert(err_is_ok(err)); }
void rom_setwramsize(rom_t *r,int banks) { banks *= 0x1000; //if wram size hasnt changed, return if(r->wramsize == banks) return; //set wram size and create mask r->wramsize = banks; r->wrammask = rom_createmask(banks); //allocate (or reallocate) memory r->wram = ram_alloc(r->wramsize,r->wram); log_message("wram size set to %dk\n",banks); }
static void create_caps(void) { errval_t err; // allocate a bunch of ramcaps for (int i=0; i<CAPS_PER_CORE; i++) { err = ram_alloc(&my_caps[i], CHILD_BITS); if (err_is_fail(err)) { DEBUG_ERR(err, "xcorecap: RAM alloc failed\n"); abort(); } err = slot_alloc(&retyped_caps[i]); if (err_is_fail(err)) { DEBUG_ERR(err, "slot alloc err\n"); abort(); } } printf("core %i caps created\n", my_coreid); }
static void run_benchmark(coreid_t core) { errval_t err; struct capref ramcap; debug_printf("starting benchmark. allocating mem of size: %d\n", MEM_BITS); int i = -1; do { i++; err = ram_alloc(&ramcap, MEM_BITS); } while (err_is_ok(err)); debug_printf("done benchmark. allocated %d caps (%lu bytes)\n", i, i * (1UL << MEM_BITS)); ns_barrier_register_n(core, "mem_bench"); }
static void run_benchmark_0(coreid_t core) { assert(core == 0); errval_t err; struct capref ramcap; debug_printf("starting benchmark. allocating mem of size: %d\n", MEM_BITS); int i = -1; do { i++; err = ram_alloc(&ramcap, MEM_BITS); } while (err_is_ok(err) && (i < 10)); debug_printf("done benchmark. allocated %d caps (%lu bytes)\n", i, i * (1UL << MEM_BITS)); }
static void run_benchmark(coreid_t core, int requests) { errval_t err; struct capref ramcap; int i = -1; int bits = MEM_BITS; debug_printf("starting benchmark. allocating mem of size: %d\n", bits); //debug_printf("starting benchmark. allocating mem of size: %d to %d\n", // MINSIZEBITS, MINSIZEBITS+requests-1); sleep_init(); // NOTE: because this is allocating and freeing, it should never stop. // it should also never have to steal do { i++; // bits = MINSIZEBITS+i; trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_ALLOC, i); err = ram_alloc(&ramcap, bits); if (err_is_fail(err)) { DEBUG_ERR(err, "ram_alloc failed"); } milli_sleep(1); err = ram_free(ramcap); if (err_is_fail(err)) { DEBUG_ERR(err, "ram_free failed"); } if ((i % 500 == 0) && (i > 0)) { debug_printf("allocated %d caps\n", i); } } while (err_is_ok(err)); // && (i < requests)); debug_printf("done benchmark. allocated %d caps (%lu bytes)\n", i, i * (1UL << bits)); }
int map_unmap(void) { errval_t err; struct capref mem; DEBUG_MAP_UNMAP("ram_alloc\n"); err = ram_alloc(&mem, BASE_PAGE_BITS); if (err_is_fail(err)) { printf("ram_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } struct capref frame; DEBUG_MAP_UNMAP("retype\n"); err = slot_alloc(&frame); if (err_is_fail(err)) { printf("slot_alloc: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } err = cap_retype(frame, mem, ObjType_Frame, BASE_PAGE_BITS); if (err_is_fail(err)) { printf("cap_retype: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } DEBUG_MAP_UNMAP("delete ram cap\n"); err = cap_destroy(mem); if (err_is_fail(err)) { printf("cap_delete(mem): %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } struct frame_identity fi; err = invoke_frame_identify(frame, &fi); if (err_is_fail(err)) { printf("frame_identify: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } DEBUG_MAP_UNMAP("frame: base = 0x%"PRIxGENPADDR", bits = %d\n", fi.base, fi.bits); #ifdef NKMTEST_DEBUG_MAP_UNMAP dump_pmap(get_current_pmap()); #endif struct vregion *vr; struct memobj *memobj; void *vaddr; DEBUG_MAP_UNMAP("map\n"); err = vspace_map_one_frame(&vaddr, BASE_PAGE_SIZE, frame, &memobj, &vr); if (err_is_fail(err)) { printf("vspace_map_one_frame: %s (%"PRIuERRV")\n", err_getstring(err), err); } char *memory = vaddr; DEBUG_MAP_UNMAP("vaddr = %p\n", vaddr); #ifdef NKMTEST_DEBUG_MAP_UNMAP dump_pmap(get_current_pmap()); #endif DEBUG_MAP_UNMAP("write 1\n"); int i; for (i = 0; i < BASE_PAGE_SIZE; i++) { memory[i] = i % INT8_MAX; } DEBUG_MAP_UNMAP("verify 1\n"); for (i = 0; i < BASE_PAGE_SIZE; i++) { assert(memory[i] == i % INT8_MAX); } DEBUG_MAP_UNMAP("delete frame cap\n"); err = cap_destroy(frame); if (err_is_fail(err)) { printf("cap_delete(frame): %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } #ifdef NKMTEST_DEBUG_MAP_UNMAP // no mapping should remain here dump_pmap(get_current_pmap()); err = debug_dump_hw_ptables(); if (err_is_fail(err)) { printf("kernel dump ptables: %s (%"PRIuERRV")\n", err_getstring(err), err); return 1; } #endif printf("%s: done\n", __FUNCTION__); return 0; }
/** * \brief Setup an initial cspace * * Create an initial cspace layout */ static errval_t spawn_setup_cspace(struct spawninfo *si) { errval_t err; struct capref t1; /* Create root CNode */ err = cnode_create(&si->rootcn_cap, &si->rootcn, DEFAULT_CNODE_SLOTS, NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_ROOTCN); } /* Create taskcn */ err = cnode_create(&si->taskcn_cap, &si->taskcn, DEFAULT_CNODE_SLOTS, NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_TASKCN); } // Mint into rootcn setting the guard t1.cnode = si->rootcn; t1.slot = ROOTCN_SLOT_TASKCN; err = cap_mint(t1, si->taskcn_cap, 0, GUARD_REMAINDER(2 * DEFAULT_CNODE_BITS)); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_MINT_TASKCN); } /* Create slot_alloc_cnode */ t1.cnode = si->rootcn; t1.slot = ROOTCN_SLOT_SLOT_ALLOC0; err = cnode_create_raw(t1, NULL, (1<<SLOT_ALLOC_CNODE_BITS), NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE); } t1.cnode = si->rootcn; t1.slot = ROOTCN_SLOT_SLOT_ALLOC1; err = cnode_create_raw(t1, NULL, (1<<SLOT_ALLOC_CNODE_BITS), NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE); } t1.cnode = si->rootcn; t1.slot = ROOTCN_SLOT_SLOT_ALLOC2; err = cnode_create_raw(t1, NULL, (1<<SLOT_ALLOC_CNODE_BITS), NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE); } // Create DCB si->dcb.cnode = si->taskcn; si->dcb.slot = TASKCN_SLOT_DISPATCHER; err = dispatcher_create(si->dcb); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_DISPATCHER); } // Give domain endpoint to itself (in taskcn) struct capref selfep = { .cnode = si->taskcn, .slot = TASKCN_SLOT_SELFEP, }; err = cap_retype(selfep, si->dcb, ObjType_EndPoint, 0); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_SELFEP); } // Map root CNode (in taskcn) t1.cnode = si->taskcn; t1.slot = TASKCN_SLOT_ROOTCN; err = cap_mint(t1, si->rootcn_cap, 0, 0); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_MINT_ROOTCN); } #ifdef TRACING_EXISTS // Set up tracing for the child err = trace_setup_child(si->taskcn, si->handle); if (err_is_fail(err)) { printf("Warning: error setting up tracing for child domain\n"); // SYS_DEBUG(err, ...); } #endif // XXX: copy over argspg? memset(&si->argspg, 0, sizeof(si->argspg)); /* Fill up basecn */ struct capref basecn_cap; struct cnoderef basecn; // Create basecn in rootcn basecn_cap.cnode = si->rootcn; basecn_cap.slot = ROOTCN_SLOT_BASE_PAGE_CN; err = cnode_create_raw(basecn_cap, &basecn, DEFAULT_CNODE_SLOTS, NULL); if (err_is_fail(err)) { return err_push(err, LIB_ERR_CNODE_CREATE); } // Place the ram caps for (uint8_t i = 0; i < DEFAULT_CNODE_SLOTS; i++) { struct capref base = { .cnode = basecn, .slot = i }; struct capref ram; err = ram_alloc(&ram, BASE_PAGE_BITS); if (err_is_fail(err)) { return err_push(err, LIB_ERR_RAM_ALLOC); } err = cap_copy(base, ram); if (err_is_fail(err)) { return err_push(err, LIB_ERR_CAP_COPY); } err = cap_destroy(ram); if (err_is_fail(err)) { return err_push(err, LIB_ERR_CAP_DESTROY); } } return SYS_ERR_OK; } static errval_t spawn_setup_vspace(struct spawninfo *si) { errval_t err; /* Create pagecn */ si->pagecn_cap = (struct capref){.cnode = si->rootcn, .slot = ROOTCN_SLOT_PAGECN}; err = cnode_create_raw(si->pagecn_cap, &si->pagecn, PAGE_CNODE_SLOTS, NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_PAGECN); } /* Init pagecn's slot allocator */ // XXX: satisfy a peculiarity of the single_slot_alloc_init_raw API size_t bufsize = SINGLE_SLOT_ALLOC_BUFLEN(PAGE_CNODE_SLOTS); void *buf = malloc(bufsize); assert(buf != NULL); err = single_slot_alloc_init_raw(&si->pagecn_slot_alloc, si->pagecn_cap, si->pagecn, PAGE_CNODE_SLOTS, buf, bufsize); if (err_is_fail(err)) { return err_push(err, LIB_ERR_SINGLE_SLOT_ALLOC_INIT_RAW); } // Create root of pagetable err = si->pagecn_slot_alloc.a.alloc(&si->pagecn_slot_alloc.a, &si->vtree); if (err_is_fail(err)) { return err_push(err, LIB_ERR_SLOT_ALLOC); } // top-level table should always live in slot 0 of pagecn assert(si->vtree.slot == 0); switch(si->cpu_type) { case CPU_X86_64: case CPU_K1OM: err = vnode_create(si->vtree, ObjType_VNode_x86_64_pml4); break; case CPU_X86_32: case CPU_SCC: #ifdef CONFIG_PAE err = vnode_create(si->vtree, ObjType_VNode_x86_32_pdpt); #else err = vnode_create(si->vtree, ObjType_VNode_x86_32_pdir); #endif break; case CPU_ARM5: case CPU_ARM7: err = vnode_create(si->vtree, ObjType_VNode_ARM_l1); break; default: assert(!"Other architecture"); return err_push(err, SPAWN_ERR_UNKNOWN_TARGET_ARCH); } if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_CREATE_VNODE); } err = spawn_vspace_init(si, si->vtree, si->cpu_type); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_VSPACE_INIT); } return SYS_ERR_OK; } #if 0 /** * \brief Lookup and map an image */ static errval_t spawn_map(const char *name, struct bootinfo *bi, lvaddr_t *binary, size_t *binary_size) { errval_t err; /* Get the module from the multiboot */ struct mem_region *module = multiboot_find_module(bi, name); if (module == NULL) { return SPAWN_ERR_FIND_MODULE; } /* Map the image */ err = spawn_map_module(module, binary_size, binary, NULL); if (err_is_fail(err)) { return err_push(err, SPAWN_ERR_MAP_MODULE); } return SYS_ERR_OK; }
int invalid_mappings(void) { // outline: // get pml4, pdpt, pdir, ptable, and frame // check all combinations to make sure that restrictions are implemented // correctly in kernel space // VALID: // map pdpt in pml4 // map pdir in pdpt // map pt in pdir // map frame in {pt, pdir, pdpt} // INVALID: // all other combinations errval_t err; struct capref caps[7]; struct capref mapping; // allocate slot for mapping cap: can reuse` err = slot_alloc(&mapping); if (err_is_fail(err)) { debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // allocate caps for (int i = 0; i < 5; i++) { // get 4k block struct capref mem; err = ram_alloc(&mem, BASE_PAGE_BITS); if (err_is_fail(err)) { debug_printf("ram_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // get slot for retype dest err = slot_alloc(&caps[i]); if (err_is_fail(err)) { debug_printf("slot_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // retype to selected type err = cap_retype(caps[i], mem, types[i], BASE_PAGE_BITS); if (err_is_fail(err)) { debug_printf("cap_retype: %s (%ld)\n", err_getstring(err), err); return 1; } // cleanup source cap DEBUG_INVALID_MAPPINGS("delete ram cap\n"); err = cap_destroy(mem); if (err_is_fail(err)) { debug_printf("cap_delete(mem): %s (%ld)\n", err_getstring(err), err); return 1; } } // cap 6: 2M frame size_t rb = 0; err = frame_alloc(&caps[5], X86_64_LARGE_PAGE_SIZE, &rb); if (err_is_fail(err) || rb != X86_64_LARGE_PAGE_SIZE) { debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } // cap 7: 1G frame err = frame_alloc(&caps[6], X86_64_HUGE_PAGE_SIZE, &rb); if (err_is_fail(err) || rb != X86_64_HUGE_PAGE_SIZE) { debug_printf("frame_alloc: %s (%ld)\n", err_getstring(err), err); return 1; } paging_x86_64_flags_t attr = 0; // select dest (ignore frame, asserts) for (int i = 0; i < 4; i++) { // select source for (int j = 0; j < 7; j++) { if (j >= 4) { // frame attr = FRAME_ACCESS_DEFAULT; } else { // ptable attr = PTABLE_ACCESS_DEFAULT; } // try mapping err = vnode_map(caps[i], caps[j], /*slot*/0, attr, /*off*/0, /*count*/1, mapping); check_result(err, i, j); // unmap if mapping succeeded if (err_is_ok(err)) { err = vnode_unmap(caps[i], mapping); if (err_is_fail(err)) { DEBUG_ERR(err, "vnode_unmap"); } assert(err_is_ok(err)); // XXX: better API? err = cap_delete(mapping); assert(err_is_ok(err)); } } } printf("All tests executed: %d PASSED, %d FAILED\n", pass, fail); return 0; }
static errval_t cow_init(size_t bufsize, size_t granularity, struct cnoderef *cow_cn, size_t *frame_count) { assert(cow_cn); assert(frame_count); errval_t err; struct capref frame, cncap; struct cnoderef cnode; // get RAM cap bufsize = (bufsize / granularity + 1) * granularity; err = slot_alloc(&frame); assert(err_is_ok(err)); size_t rambits = log2floor(bufsize); debug_printf("bits = %zu\n", rambits); err = ram_alloc(&frame, rambits); assert(err_is_ok(err)); // calculate #slots cslot_t cap_count = bufsize / granularity; cslot_t slots; // get CNode err = cnode_create(&cncap, &cnode, cap_count, &slots); assert(err_is_ok(err)); assert(slots >= cap_count); // retype RAM into Frames struct capref first_frame = (struct capref) { .cnode = cnode, .slot = 0 }; err = cap_retype(first_frame, frame, ObjType_Frame, log2floor(granularity)); assert(err_is_ok(err)); err = cap_destroy(frame); assert(err_is_ok(err)); *frame_count = slots; *cow_cn = cnode; return SYS_ERR_OK; } // create cow-enabled vregion & backing // Can copy-on-write in granularity-sized chunks static errval_t vspace_map_one_frame_cow(void **buf, size_t size, struct capref frame, vregion_flags_t flags, struct memobj **memobj, struct vregion **vregion, size_t granularity) { errval_t err; if (!memobj) { memobj = malloc(sizeof(*memobj)); } assert(memobj); if (!vregion) { vregion = malloc(sizeof(*vregion)); } assert(vregion); err = vspace_map_anon_attr(buf, memobj, vregion, size, &size, flags); assert(err_is_ok(err)); size_t chunks = size / granularity; cslot_t slots; struct capref cncap; struct cnoderef cnode; err = cnode_create(&cncap, &cnode, chunks, &slots); assert(err_is_ok(err)); assert(slots >= chunks); struct capref fc = (struct capref) { .cnode = cnode, .slot = 0 }; for (int i = 0; i < chunks; i++) { err = cap_copy(fc, frame); assert(err_is_ok(err)); err = (*memobj)->f.fill_foff(*memobj, i * granularity, fc, granularity, i*granularity); assert(err_is_ok(err)); err = (*memobj)->f.pagefault(*memobj, *vregion, i * granularity, 0); assert(err_is_ok(err)); fc.slot++; } return SYS_ERR_OK; } int main(int argc, char *argv[]) { errval_t err; struct capref frame; size_t retsize; void *vbuf; struct vregion *vregion; uint8_t *buf; debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = frame_alloc(&frame, BUFSIZE, &retsize); assert(retsize >= BUFSIZE); if (err_is_fail(err)) { debug_printf("frame_alloc: %s\n", err_getstring(err)); return 1; } debug_printf("%s:%d: %zu\n", __FUNCTION__, __LINE__, retsize); // setup region err = vspace_map_one_frame_attr(&vbuf, retsize, frame, VREGION_FLAGS_READ_WRITE, NULL, &vregion); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("vaddr: %p\n", vbuf); // write stuff to region buf = vbuf; debug_printf("%s:%d: %p, %lu pages\n", __FUNCTION__, __LINE__, buf, BUFSIZE / BASE_PAGE_SIZE); memset(buf, 0xAA, BUFSIZE); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); // create cow copy // setup exception handler thread_set_exception_handler(handler, NULL, ex_stack, ex_stack+EX_STACK_SIZE, NULL, NULL); assert(err_is_ok(err)); debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = cow_init(BUFSIZE, BASE_PAGE_SIZE, &cow_frames, &cow_frame_count); assert(err_is_ok(err)); // create r/o copy of region and tell exception handler bounds debug_printf("%s:%d\n", __FUNCTION__, __LINE__); err = vspace_map_one_frame_cow(&cow_vbuf, retsize, frame, VREGION_FLAGS_READ, NULL, &cow_vregion, BASE_PAGE_SIZE); if (err_is_fail(err)) { debug_printf("vspace_map: %s\n", err_getstring(err)); return 1; } debug_printf("cow_vaddr: %p\n", cow_vbuf); // do stuff cow copy uint8_t *cbuf = cow_vbuf; for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i+=2) { cbuf[i * BASE_PAGE_SIZE + 1] = 0x55; } // verify results for (int i = 0; i < BUFSIZE / BASE_PAGE_SIZE; i++) { printf("page %d\n", i); printf("buf[0] = %d; cbuf[0] = %d\n", buf[i*BASE_PAGE_SIZE], cbuf[i*BASE_PAGE_SIZE]); printf("buf[1] = %d; cbuf[1] = %d\n", buf[i*BASE_PAGE_SIZE+1], cbuf[i*BASE_PAGE_SIZE+1]); } debug_dump_hw_ptables(); return EXIT_SUCCESS; }