/* Return the top address of the page it is mapped into the * component */ static vaddr_t stkmgr_stk_add_to_spd(struct cos_stk_item *stk_item, struct spd_stk_info *info) { vaddr_t d_addr, stk_addr, ret; spdid_t d_spdid; assert(info && stk_item); assert(EMPTY_LIST(stk_item, next, prev)); d_spdid = info->spdid; // FIXME: Race condition ret = d_addr = (vaddr_t)valloc_alloc(cos_spd_id(), d_spdid, 1); /* d_addr = info->ci->cos_heap_ptr; */ /* info->ci->cos_heap_ptr += PAGE_SIZE; */ /* ret = info->ci->cos_heap_ptr; */ // DOUT("Setting flags and assigning flags\n"); stk_item->stk->flags = 0xDEADBEEF; stk_item->stk->next = (void *)0xDEADBEEF; stk_addr = (vaddr_t)(stk_item->hptr); if(d_addr != mman_alias_page(cos_spd_id(), stk_addr, d_spdid, d_addr)){ printc("<stkmgr>: Unable to map stack into component"); BUG(); } // DOUT("Mapped page\n"); stk_item->d_addr = d_addr; stk_item->parent_spdid = d_spdid; // Add stack to allocated stack array // DOUT("Adding to local spdid stk list\n"); ADD_LIST(&info->stk_list, stk_item, next, prev); info->num_allocated++; assert(info->num_allocated == stkmgr_num_alloc_stks(info->spdid)); return ret; }
static int boot_spd_map_memory(struct cobj_header *h, spdid_t spdid, vaddr_t comp_info) { unsigned int i; vaddr_t dest_daddr; local_md[spdid].spdid = spdid; local_md[spdid].h = h; local_md[spdid].page_start = cos_get_heap_ptr(); local_md[spdid].comp_info = comp_info; for (i = 0 ; i < h->nsect ; i++) { struct cobj_sect *sect; char *dsrc; int left; sect = cobj_sect_get(h, i); dest_daddr = sect->vaddr; left = cobj_sect_size(h, i); while (left > 0) { dsrc = cos_get_vas_page(); if ((vaddr_t)dsrc != mman_get_page(cos_spd_id(), (vaddr_t)dsrc, 0)) BUG(); if (dest_daddr != (mman_alias_page(cos_spd_id(), (vaddr_t)dsrc, spdid, dest_daddr))) BUG(); dest_daddr += PAGE_SIZE; left -= PAGE_SIZE; } } local_md[spdid].page_end = (void*)dest_daddr; return 0; }
static void alias_test() { int i; vaddr_t addr = 0; printc("\n<<< ALIAS TEST BEGIN! >>>\n"); for (i = 0; i<PAGE_NUM; i++) { d_addr[i] = mm_test2(); #ifdef TEN2TEN /* 10 to 10 */ addr = s_addr[i]; #else /* 1 to 10 */ addr = s_addr[0]; #endif /* printc("s_addr %p d_addr %p\n", addr, d_addr[i]); */ /* rdtscll(start); */ if (d_addr[i]!= mman_alias_page(cos_spd_id(), addr, cos_spd_id()+1, d_addr[i])) BUG(); /* rdtscll(end); */ /* printc("cost %llu\n", end - start); */ } #ifdef BEST_TEST mm_test2_34(); #endif printc("<<< ALIAS TEST END! >>>\n\n"); return; }
// all cbufs that created for this component void mgr_map_client_mem(struct cos_cbuf_item *cci, struct spd_tmem_info *sti) { char *l_addr, *d_addr; spdid_t d_spdid; // struct cb_desc *d; assert(sti && cci); assert(EMPTY_LIST(cci, next, prev)); d_spdid = sti->spdid; /* TODO: multiple pages cbuf! */ d_addr = valloc_alloc(cos_spd_id(), sti->spdid, 1); l_addr = cci->desc.addr; //initialized in cos_init() assert(d_addr && l_addr); /* ...map it into the requesting component */ if (unlikely(!mman_alias_page(cos_spd_id(), (vaddr_t)l_addr, d_spdid, (vaddr_t)d_addr))) goto err; /* DOUT("<<<MAPPED>>> mgr addr %p client addr %p\n ",l_addr, d_addr); */ cci->desc.owner.addr = (vaddr_t)d_addr; cci->parent_spdid = d_spdid; assert(cci->desc.cbid == 0); // add the cbuf to shared vect here? now we do it in the client. // and l_addr and d_addr has been assinged done: return; err: DOUT("Cbuf mgr: Cannot alias page to client!\n"); mman_release_page(cos_spd_id(), (vaddr_t)l_addr, 0); /* valloc_free(cos_spd_id(), cos_spd_id(), l_addr, 1); */ valloc_free(cos_spd_id(), d_spdid, (void *)d_addr, 1); goto done; }
int cinfo_map(spdid_t spdid, vaddr_t map_addr, spdid_t target) { vaddr_t cinfo_addr; cinfo_addr = (vaddr_t)cos_vect_lookup(&spd_info_addresses, target); if (0 == cinfo_addr) return -1; if (map_addr != (mman_alias_page(cos_spd_id(), cinfo_addr, spdid, map_addr))) { return -1; } return 0; }
int cbufp_retrieve(spdid_t spdid, int cbid, int len) { struct cbufp_comp_info *cci; struct cbufp_info *cbi; struct cbuf_meta *meta; struct cbufp_maps *map; vaddr_t dest; void *page; int ret = -1; CBUFP_TAKE(); cci = cbufp_comp_info_get(spdid); if (!cci) goto done; cbi = cmap_lookup(&cbufs, cbid); if (!cbi) goto done; /* shouldn't cbuf2buf your own buffer! */ if (cbi->owner.spdid == spdid) goto done; meta = cbufp_meta_lookup(cci, cbid); if (!meta) goto done; map = malloc(sizeof(struct cbufp_maps)); if (!map) goto done; dest = (vaddr_t)valloc_alloc(cos_spd_id(), spdid, 1); if (!dest) goto free; map->spdid = spdid; map->m = meta; map->addr = dest; INIT_LIST(map, next, prev); ADD_LIST(&cbi->owner, map, next, prev); page = cbi->mem; assert(page); if (dest != (mman_alias_page(cos_spd_id(), (vaddr_t)page, spdid, dest))) { assert(0); valloc_free(cos_spd_id(), spdid, (void *)dest, 1); } meta->nfo.c.flags |= CBUFM_TOUCHED; meta->nfo.c.ptr = map->addr >> PAGE_ORDER; ret = 0; done: CBUFP_RELEASE(); return ret; free: free(map); goto done; }
static int cbuf_map(spdid_t spdid, vaddr_t daddr, void *page, unsigned long size, int flags) { unsigned long off; assert(size == round_to_page(size)); assert(daddr); assert(page); for (off = 0 ; off < size ; off += PAGE_SIZE) { vaddr_t d = daddr + off; if (unlikely(d != (mman_alias_page(cos_spd_id(), ((vaddr_t)page) + off, spdid, d, flags)))) { for (d = daddr + off - PAGE_SIZE ; d >= daddr ; d -= PAGE_SIZE) { mman_revoke_page(spdid, d, 0); } return -ENOMEM; } } return 0; }
int stkmgr_stack_introspect(spdid_t d_spdid, vaddr_t d_addr, spdid_t s_spdid, vaddr_t s_addr) { struct cos_stk_item *si; int ret = -1; TAKE(); si = stkmgr_get_spds_stk_item(s_spdid, s_addr); if (!si) goto err; if(d_addr != mman_alias_page(cos_spd_id(), (vaddr_t)si->hptr, d_spdid, d_addr)){ printc("<stkmgr>: Unable to map stack into component during introspection\n"); BUG(); } ret = 0; err: RELEASE(); return ret; }
int cbufp_alloc_map(spdid_t spdid, vaddr_t *daddr, void **page, int size) { void *p; vaddr_t dest; assert(size == PAGE_SIZE); dest = (vaddr_t)valloc_alloc(cos_spd_id(), spdid, 1); assert(dest); p = alloc_page(); assert(p); memset(p, 0, PAGE_SIZE); if (dest != (mman_alias_page(cos_spd_id(), (vaddr_t)p, spdid, dest))) { assert(0); valloc_free(cos_spd_id(), spdid, (void *)dest, 1); } *page = p; *daddr = dest; return 0; }
static void all_in_one() { int i; for (i = 0; i<PAGE_NUM; i++) { s_addr[i] = (vaddr_t)cos_get_vas_page(); d_addr[i] = mm_test2(); } for (i = 0; i<PAGE_NUM; i++) { /* rdtscll(start); */ mman_get_page(cos_spd_id(), s_addr[i], 0); mman_alias_page(cos_spd_id(), s_addr[i], cos_spd_id()+1, d_addr[i]); mman_revoke_page(cos_spd_id(), s_addr[i], 0); /* rdtscll(end); */ /* printc("grant-alias-revoke cost %llu\n", end - start); */ /* mman_release_page(cos_spd_id(), s_addr[i], 0); */ } return; }
vaddr_t cbuf_c_register(spdid_t spdid, long cbid) { struct spd_tmem_info *sti; vaddr_t p, mgr_addr; /* DOUT("\nREGISTERED!!!\n"); */ sti = get_spd_info(spdid); mgr_addr = (vaddr_t)alloc_page(); p = (vaddr_t)valloc_alloc(cos_spd_id(), spdid, 1); if (p != (mman_alias_page(cos_spd_id(), mgr_addr, spdid, p))) { DOUT("mapped faied p is %p\n",(void *)p); valloc_free(cos_spd_id(), spdid, (void *)p, 1); return -1; } sti->managed = 1; /* __spd_cbvect_add_range(sti, cbid, (struct cbuf_vect_intern_struct *)mgr_addr); */ __spd_cbvect_add_range(sti, cbid, mgr_addr); return p; }
vaddr_t __sg_mman_alias_page(spdid_t s_spd, vaddr_t s_addr, spdid_t d_spd, vaddr_t d_addr) { return mman_alias_page(s_spd, s_addr, d_spd, d_addr); }
void * cbuf_c_retrieve(spdid_t spdid, int cbid, int len) { void *ret = NULL; char *l_addr, *d_addr; struct cb_desc *d; struct cb_mapping *m; TAKE(); d = cos_map_lookup(&cb_ids, cbid); /* sanity and access checks */ if (!d || d->obj_sz < len) goto done; #ifdef PRINCIPAL_CHECKS if (d->principal != cos_get_thd_id()) goto done; #endif /* DOUT("info: thd_id %d obj_size %d addr %p\n", d->principal, d->obj_sz, d->addr); */ m = malloc(sizeof(struct cb_mapping)); if (!m) goto done; /* u64_t start,end; */ /* rdtscll(start); */ INIT_LIST(m, next, prev); d_addr = valloc_alloc(cos_spd_id(), spdid, 1); l_addr = d->addr; //cbuf_item addr, initialized in cos_init() /* l_addr = d->owner.addr; // mapped from owner */ assert(d_addr && l_addr); /* rdtscll(end); */ /* printc("cost of valloc: %lu\n", end-start); */ /* rdtscll(start); */ /* if (!mman_alias_page(cos_spd_id(), (vaddr_t)d->addr, spdid, (vaddr_t)page)) goto err; */ if (unlikely(!mman_alias_page(cos_spd_id(), (vaddr_t)l_addr, spdid, (vaddr_t)d_addr))) { printc("No alias!\n"); goto err; } /* DOUT("<<<MAPPED>>> mgr addr %p client addr %p\n ",l_addr, d_addr); */ /* rdtscll(end); */ /* printc("cost of mman_alias_page: %lu\n", end-start); */ m->cbd = d; m->spd = spdid; m->addr = (vaddr_t)d_addr; //struct cb_mapping *m; ADD_LIST(&d->owner, m, next, prev); ret = (void *)d_addr; done: RELEASE(); return ret; err: valloc_free(cos_spd_id(), spdid, d_addr, 1); free(m); goto done; }
static int shared_page_setup(int thd_id) { // thd_id is the upcall thread on the server side. struct srv_thd_info *thd; int cspd, sspd; vaddr_t ring_mgr, ring_cli, ring_srv; assert(thd_id); thd = &srv_thd_info[thd_id]; cspd = thd->cli_spd_id; sspd = thd->srv_spd_id; if (!cspd || !sspd) goto err; ring_mgr = (vaddr_t)alloc_page(); if (!ring_mgr) { printc("par_mgr: alloc ring buffer failed in mgr %ld.\n", cos_spd_id()); goto err; } srv_thd_info[thd_id].mgr_ring = ring_mgr; ring_cli = (vaddr_t)valloc_alloc(cos_spd_id(), cspd, 1); if (unlikely(!ring_cli)) { printc("par_mgr: vaddr alloc failed in client comp %d.\n", cspd); goto err_cli; } if (unlikely(ring_cli != mman_alias_page(cos_spd_id(), ring_mgr, cspd, ring_cli, MAPPING_RW))) { printc("par_mgr: alias to client %d failed.\n", cspd); goto err_cli_alias; } comp_info[cspd].cli_thd_info[cos_get_thd_id()]->cap_info[thd->cli_cap_id].cap_ring = ring_cli; ring_srv = (vaddr_t)valloc_alloc(cos_spd_id(), sspd, 1); if (unlikely(!ring_srv)) { goto err_srv; printc("par_mgr: vaddr alloc failed in server comp %d.\n", sspd); } if (unlikely(ring_srv != mman_alias_page(cos_spd_id(), ring_mgr, sspd, ring_srv, MAPPING_RW))) { printc("par_mgr: alias to server %d failed.\n", sspd); goto err_srv_alias; } srv_thd_info[thd_id].srv_ring = ring_srv; /* Initialize the ring buffer. Passing NULL because we use * continuous ring (struct + data region). The ring starts * from the second cache line of the page. (First cache line * is used for the server thread active flag) */ CK_RING_INIT(inv_ring, (CK_RING_INSTANCE(inv_ring) *)((void *)ring_mgr + CACHE_LINE), NULL, leqpow2((PAGE_SIZE - CACHE_LINE - sizeof(CK_RING_INSTANCE(inv_ring))) / 2 / sizeof(struct inv_data))); return 0; err_srv_alias: valloc_free(cos_spd_id(), sspd, (void *)ring_srv, 1); err_srv: mman_revoke_page(cos_spd_id(), ring_mgr, 0); err_cli_alias: valloc_free(cos_spd_id(), cspd, (void *)ring_cli, 1); err_cli: free_page((void *)ring_mgr); err: return -1; }