static void *framebuffer_grant_test(uint32_t domid, uint32_t num_pages) { xc_gnttab *xcg; int i = 0; uint32_t refs[2560]; void *p; memset(refs, 0, 2560*sizeof(uint32_t)); xcg = xc_gnttab_open(NULL, 0); if ( !xcg ) { printf("Failed to open grant device, dying.\n"); return; } for (i = 0; i < num_pages; i++) { refs[i] = i; } p = xc_gnttab_map_domain_grant_refs(xcg, num_pages, domid, refs, PROT_READ); if ( p ) { printf("Mapped %d refs, ptr: %p\n", i, p); } else { printf("Failed to map at ref: %d\n", 0); abort(); } xc_gnttab_close(xcg); return p; }
ivc_connection_t *makeConnection(libIVC_t *iface, char *name, ivc_contype_t type, float per) { char *key, *val, *rdomstr = NULL, *rrefstr = NULL, *rpstr = NULL; uint32_t me, other, num_refs, *grants; struct xs_permissions perms; ivc_connection_t *res; evtchn_port_t port; unsigned int len; void *buffer; /* me <- xsGetDomId */ me = getMyDomId(iface); /* removePath xs targetPath */ ASPRINTF(&key, "/rendezvous/%s", name); xs_rm(iface->xs, 0, key); /* xsMakeDirectory xs targetPath */ xs_mkdir(iface->xs, 0, key); /* xsSetPermissions xs targetPath [ReadWritePerm me] */ perms.id = me; perms.perms = XS_PERM_READ | XS_PERM_WRITE; xs_set_permissions(iface->xs, 0, key, &perms, 1); /* xsWrite xs (targetPath ++ "/LeftDomId") (show me) */ free(key), ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name); ASPRINTF(&val, "dom%d", me); xs_write(iface->xs, 0, key, val, strlen(val)); /* other <- read <$> waitForKey xs (targetPAth ++ "/RightDomId") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name); while(!rdomstr) { rdomstr = xs_read(iface->xs, 0, key, &len); }; sscanf(rdomstr, "dom%d", &other); /* grants <- read <$> waitForKey xs (targetPAth ++ "/RightGrantRefs") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name); while(!rrefstr) { rrefstr = xs_read(iface->xs, 0, key, &len); } grants = parseRefs(rrefstr, &num_refs); buffer = xc_gnttab_map_domain_grant_refs(iface->gt, num_refs, other, grants, PROT_READWRITE); assert(buffer); /* ports <- read <$> waitForKey xs (targetPAth ++ "/RightPorts") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name); while(!rpstr) { rpstr = xs_read(iface->xs, 0, key, &len); } sscanf(rpstr, "[echan:%d]", &port); port = xc_evtchn_bind_interdomain(iface->ec, other, port); assert(port >= 0); /* res <- acceptConnection other grants ports extra */ res = buildChannel(iface, other, type, port, buffer, num_refs * 4096, per, 0); /* xsWrite xs (targetPath ++ "/LeftConnectionConfirmed") "True" */ free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name); free(val), ASPRINTF(&val, "True"); xs_write(iface->xs, 0, key, val, strlen(val)); /* return res */ return res; }
static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref) { int rv = -1; uint32_t *grants; ctrl->ring = xc_gnttab_map_grant_ref_notify(ctrl->gnttab, domain, ring_ref, PROT_READ|PROT_WRITE, offsetof(struct vchan_interface, cli_live), ctrl->event_port); if (!ctrl->ring) goto out; ctrl->write.order = ctrl->ring->left_order; ctrl->read.order = ctrl->ring->right_order; ctrl->write.shr = &ctrl->ring->left; ctrl->read.shr = &ctrl->ring->right; if (ctrl->write.order < SMALL_RING_SHIFT || ctrl->write.order > MAX_RING_SHIFT) goto out_unmap_ring; if (ctrl->read.order < SMALL_RING_SHIFT || ctrl->read.order > MAX_RING_SHIFT) goto out_unmap_ring; if (ctrl->read.order == ctrl->write.order && ctrl->read.order < PAGE_SHIFT) goto out_unmap_ring; grants = ctrl->ring->grants; switch (ctrl->write.order) { case SMALL_RING_SHIFT: ctrl->write.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET; break; case LARGE_RING_SHIFT: ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET; break; default: { int pages_left = 1 << (ctrl->write.order - PAGE_SHIFT); ctrl->write.buffer = xc_gnttab_map_domain_grant_refs(ctrl->gnttab, pages_left, domain, grants, PROT_READ|PROT_WRITE); if (!ctrl->write.buffer) goto out_unmap_ring; grants += pages_left; } } switch (ctrl->read.order) { case SMALL_RING_SHIFT: ctrl->read.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET; break; case LARGE_RING_SHIFT: ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET; break; default: { int pages_right = 1 << (ctrl->read.order - PAGE_SHIFT); ctrl->read.buffer = xc_gnttab_map_domain_grant_refs(ctrl->gnttab, pages_right, domain, grants, PROT_READ); if (!ctrl->read.buffer) goto out_unmap_left; } } rv = 0; out: return rv; out_unmap_left: if (ctrl->write.order >= PAGE_SHIFT) xc_gnttab_munmap(ctrl->gnttab, ctrl->write.buffer, 1 << (ctrl->write.order - PAGE_SHIFT)); out_unmap_ring: xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, 1); ctrl->ring = 0; ctrl->write.order = ctrl->read.order = 0; rv = -1; goto out; }