Esempio n. 1
0
/*
 * Call to give up a page of memory in an spd at an address.
 */
void mman_revoke_page(spdid_t spd, vaddr_t addr, int flags)
{
	int alias, i;
	struct mem_cell *mc;
	struct mapping_info *mi;

	mc = find_cell(spd, addr, &alias);
	if (!mc) {
		/* FIXME: add return codes to this call */
		return;
	}
	mi = mc->map;
	for (i = 0 ; i < MAX_ALIASES ; i++) {
		int idx;

		if (i == alias || !mi[i].owner_spd || 
		    !is_descendent(mi, alias, i)) continue;
		idx = cos_mmap_cntl(COS_MMAP_REVOKE, 0, mi[i].owner_spd, 
				    mi[i].addr, 0);
		assert(&cells[idx] == mc);
		/* mark page as removed */
		mi[i].addr = 0;
		mc->naliases--;
	}
	/* Go through and free all pages marked as removed */
	for (i = 0 ; i < MAX_ALIASES ; i++) {
		if (mi[i].addr == 0 && 
		    mi[i].owner_spd) {
			mi[i].owner_spd = 0;
			mi[i].parent = 0;
		}
	}

	return;
}
Esempio n. 2
0
/* 
 * Call to get a page of memory at a location.
 */
vaddr_t mman_get_page(spdid_t spd, vaddr_t addr, int flags)
{
	struct mem_cell *c;
	struct mapping_info *m;

	c = find_unused();
	if (!c) {
		printc("mm: no more available pages!\n");
		goto err;
	}

	c->naliases++;
	m = c->map;
	m->owner_spd = spd;
	m->addr = addr;
	m->parent = -1;

	/* Here we check for overwriting an already established mapping. */
	if (cos_mmap_cntl(COS_MMAP_GRANT, 0, spd, addr, cell_index(c))) {
		printc("mm: could not grant page @ %x to spd %d\n", 
		       (unsigned int)addr, (unsigned int)spd);
		m->owner_spd = m->addr = 0;
		goto err;
	}

	return addr;
err:
	return 0;
}
Esempio n. 3
0
/* 
 * Make an alias to a page in a source spd @ a source address to a
 * destination spd/addr
 */
vaddr_t mman_alias_page(spdid_t s_spd, vaddr_t s_addr, spdid_t d_spd, vaddr_t d_addr)
{
	int alias = -1, i;
	struct mem_cell *c;
	struct mapping_info *base;
	
	c = find_cell(s_spd, s_addr, &alias);
	if (-1 == alias) {printc("WTF\n");goto err;}
	assert(alias >= 0 && alias < MAX_ALIASES);
	base = c->map;
	for (i = 0 ; i < MAX_ALIASES ; i++) {
		if (alias == i || base[i].owner_spd != 0 || base[i].addr != 0) {
			continue;
		}

		if (cos_mmap_cntl(COS_MMAP_GRANT, 0, d_spd, d_addr, cell_index(c))) {
			printc("mm: could not alias page @ %x to spd %d from %x(%d)\n", 
			       (unsigned int)d_addr, (unsigned int)d_spd, (unsigned int)s_addr, (unsigned int)s_spd);
			goto err;
		}
		base[i].owner_spd = d_spd;
		base[i].addr = d_addr;
		base[i].parent = alias;
		c->naliases++;

		return d_addr;
	}
	/* no available alias slots! */
err:
	return 0;
}
Esempio n. 4
0
static inline void *
__page_get(void)
{
	void *hp = cos_get_vas_page();
	struct frame *f = frame_alloc();

	assert(hp && f);
	frame_ref(f);
	if (cos_mmap_cntl(COS_MMAP_GRANT, 0, cos_spd_id(), (vaddr_t)hp, frame_index(f))) {
		BUG();
	}
	return hp;
}
Esempio n. 5
0
static inline void *
__page_get(void)
{
	void *hp = cos_get_vas_page();
	struct frame *f = frame_alloc();

	assert(hp && f);
	frame_ref(f);
	f->nmaps  = -1; 	 /* belongs to us... */
	f->c.addr = (vaddr_t)hp; /* ...at this address */
	if (cos_mmap_cntl(COS_MMAP_GRANT, MAPPING_RW, cos_spd_id(), (vaddr_t)hp, frame_index(f))) {
		printc("grant @ %p for frame %d\n", hp, frame_index(f));
		BUG();
	}
	return hp;
}
Esempio n. 6
0
/* Make a child mapping */
static struct mapping *
mapping_crt(struct mapping *p, struct frame *f, spdid_t dest, vaddr_t to, int flags)
{
	struct comp_vas *cv = cvas_lookup(dest);
	struct mapping *m = NULL;
	long idx = to >> PAGE_SHIFT;

	assert(!p || p->f == f);
	assert(dest && to);

	/* no vas structure for this spd yet... */
	if (!cv) {
		cv = cvas_alloc(dest);
		if (!cv) goto done;
		assert(cv == cvas_lookup(dest));
	}
	assert(cv->pages);
	if (cvect_lookup(cv->pages, idx)) goto collision;

	cvas_ref(cv);
	m = cslab_alloc_mapping();
	if (!m) goto collision;

	if (cos_mmap_cntl(COS_MMAP_GRANT, flags, dest, to, frame_index(f))) {
		printc("mem_man: could not grant at %x:%d\n", dest, (int)to);
		goto no_mapping;
	}
	mapping_init(m, dest, to, p, f);
	assert(!p || frame_nrefs(f) > 0);
	frame_ref(f);
	assert(frame_nrefs(f) > 0);
	if (cvect_add(cv->pages, m, idx)) BUG();
done:
	return m;
no_mapping:
	cslab_free_mapping(m);
collision:
	cvas_deref(cv);
	m = NULL;
	goto done;
}
static void
__mapping_destroy(struct mapping *m)
{
	struct comp_vas *cv;
	int idx;

	assert(m);
	assert(EMPTY_LIST(m, _s, s_));
	assert(m->p == NULL && m->c == NULL);
	cv = cvas_lookup(m->spdid);

	assert(cv && cv->pages);
	assert(m == cvect_lookup(cv->pages, m->addr >> PAGE_SHIFT));
	cvect_del(cv->pages, m->addr >> PAGE_SHIFT);
	cvas_deref(cv);

	idx = cos_mmap_cntl(COS_MMAP_REVOKE, 0, m->spdid, m->addr, 0);
	assert(idx == frame_index(m->f));
	frame_deref(m->f);
	cslab_free_mapping(m);
}
Esempio n. 8
0
/* 
 * FIXME: change interface to include the component making the call to
 * make sure that it owns the page it is trying to unmap (and the one
 * it is unmapping is a descendent.
 */
void mman_release_page(spdid_t spd, vaddr_t addr, int flags)
{
	int alias;
	long idx;
	struct mem_cell *mc;
	struct mapping_info *mi;

	mman_revoke_page(spd, addr, flags);
	mc = find_cell(spd, addr, &alias);
	if (!mc) {
		/* FIXME: add return codes to this call */
		return;
	}
	mi = mc->map;
	idx = cos_mmap_cntl(COS_MMAP_REVOKE, 0, mi[alias].owner_spd, 
			    mi[alias].addr, 0);
	assert(&cells[idx] == mc);
	mi[alias].addr = 0;
	mi[alias].owner_spd = 0;
	mi[alias].parent = 0;
	mc->naliases--;

	return;
}