Beispiel #1
0
static int shared_pagefault(struct vmproc *vmp, struct vir_region *region,
	struct phys_region *ph, int write, vfs_callback_t cb,
	void *state, int statelen, int *io)
{
	struct vir_region *src_region;
	struct vmproc *src_vmp;
	struct phys_region *pr;

	if(getsrc(region, &src_vmp, &src_region) != OK) {
		return EINVAL;
	}

	assert(ph->ph->phys == MAP_NONE);
	pb_free(ph->ph);

	if(!(pr = physblock_get(src_region, ph->offset))) {
		int r;
		if((r=map_pf(src_vmp, src_region, ph->offset, write,
			NULL, NULL, 0, io)) != OK)
			return r;
		if(!(pr = physblock_get(src_region, ph->offset))) {
			panic("missing region after pagefault handling");
		}
	}

	pb_link(ph, pr->ph, ph->offset, region);

	return OK;
}
Beispiel #2
0
int
do_mapcache(message *msg)
{
	dev_t dev = msg->m_u.m_vmmcp.dev;
	u64_t dev_off = (u64_t) msg->m_u.m_vmmcp.dev_offset_pages * VM_PAGE_SIZE;
	u64_t ino_off = (u64_t) msg->m_u.m_vmmcp.ino_offset_pages * VM_PAGE_SIZE;
	int n;
	int bytes = msg->m_u.m_vmmcp.pages * VM_PAGE_SIZE;
	struct vir_region *vr;
	struct vmproc *caller;
	vir_bytes offset;
	int io = 0;

	if(vm_isokendpt(msg->m_source, &n) != OK) panic("bogus source");
	caller = &vmproc[n];

	if(bytes < VM_PAGE_SIZE) return EINVAL;

	if(!(vr = map_page_region(caller, VM_PAGE_SIZE, VM_DATATOP, bytes,
		VR_ANON | VR_WRITABLE, 0, &mem_type_cache))) {
		printf("VM: map_page_region failed\n");
		return ENOMEM;
	}

	assert(vr->length == bytes);

	for(offset = 0; offset < bytes; offset += VM_PAGE_SIZE) {
		struct cached_page *hb;

		assert(vr->length == bytes);
		assert(offset < vr->length);

		if(!(hb = find_cached_page_bydev(dev, dev_off + offset,
			msg->m_u.m_vmmcp.ino, ino_off + offset, 1))) {
			map_unmap_region(caller, vr, 0, bytes);
			return ENOENT;
		}

		assert(!vr->param.pb_cache);
		vr->param.pb_cache = hb->page;

		assert(vr->length == bytes);
		assert(offset < vr->length);

		if(map_pf(caller, vr, offset, 1, NULL, NULL, 0, &io) != OK) {
			map_unmap_region(caller, vr, 0, bytes);
			printf("VM: map_pf failed\n");
			return ENOMEM;
		}
		assert(!vr->param.pb_cache);
	}

	memset(msg, 0, sizeof(*msg));

	msg->m_u.m_vmmcp_reply.addr = (void *) vr->vaddr;
 
 	assert(vr);

#if CACHE_SANITY
	cache_sanitycheck_internal();
#endif

	return OK;
}