Ejemplo n.º 1
0
ivc_connection_t *acceptConnection(libIVC_t *iface,
                                   char *name,
                                   ivc_contype_t type,
                                   uint32_t num_pages,
                                   float per)
{
  char *key, *val, *domStr = NULL;
  uint32_t me, other, *gs, ps;
  unsigned int len;
  void *buffer;

  /* we can only do this if we create grant references */
  if(!iface->gs) return NULL;
  /* other <- read `fmap` waitForKey xs (targetPath ++ "/LeftDomId) */
  ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name);
  while(!domStr) { domStr = xs_read(iface->xs, 0, key, &len); }
  sscanf(domStr, "dom%d", &other);
  /* me <- xsGetDomId */
  me = getMyDomId(iface);
  /* (gs, ps, confirm) <- makeConnection other extra */
  gs = calloc(num_pages, sizeof(uint32_t));
  buffer = xc_gntshr_share_pages(iface->gs, other, num_pages, gs, 1);
  assert(buffer);
  ps = xc_evtchn_bind_unbound_port(iface->ec, other);
  assert(ps);
  /* xsWrite xs (targetPath ++ "/RightDomId") (show me) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name);
  free(val), ASPRINTF(&val, "dom%d", me);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightGrantRefs") (show gs) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name);
  free(val), val = showGrantRefList(gs, num_pages);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightPorts") (show ps) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name);
  free(val), ASPRINTF(&val, "[echan:%d]", ps);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* _ <- waitForKey xs (targetPath ++ "/LeftConnectionConfirmed") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name);
  free(val), val = NULL;
  while(!val) { val = xs_read(iface->xs, 0, key, &len); }
  /* removePath xs targetPath */
  free(key), ASPRINTF(&key, "/rendezvous/%s", name);
  xs_rm(iface->xs, 0, key);
  /* confirm */
  return buildChannel(iface, other, type, ps, buffer, 4096 * num_pages, per, 1);
}
CAMLprim value stub_xc_gntshr_share_pages(value xgh, value domid, value count, value writeable) {
	CAMLparam4(xgh, domid, count, writeable);
	CAMLlocal4(result, ml_refs, ml_refs_cons, ml_map);
#ifdef HAVE_GNTSHR
	void *map;
	uint32_t *refs;
	uint32_t c_domid;
	int c_count;
	int i;
	c_count = Int_val(count);
	c_domid = Int32_val(domid);
	result = caml_alloc(2, 0);
	refs = (uint32_t *) malloc(c_count * sizeof(uint32_t));

	map = xc_gntshr_share_pages(_G(xgh), c_domid, c_count, refs, Bool_val(writeable));

	if(NULL == map) {
		free(refs);
		failwith_xc(_G(xgh));
	}

	// Construct the list of grant references.
	ml_refs = Val_emptylist;
	for(i = c_count - 1; i >= 0; i--) {
		ml_refs_cons = caml_alloc(2, 0);

		Store_field(ml_refs_cons, 0, caml_copy_int32(refs[i]));
		Store_field(ml_refs_cons, 1, ml_refs);

		ml_refs = ml_refs_cons;
	}

	ml_map = caml_ba_alloc_dims(XC_GNTTAB_BIGARRAY, 1,
		map, c_count << XC_PAGE_SHIFT);

	Store_field(result, 0, ml_refs);
	Store_field(result, 1, ml_map);

	free(refs);
#else
	gntshr_missing();
#endif
	CAMLreturn(result);
}
Ejemplo n.º 3
0
Archivo: init.c Proyecto: Fantu/Xen
static int init_gnt_srv(struct libxenvchan *ctrl, int domain)
{
	int pages_left = ctrl->read.order >= PAGE_SHIFT ? 1 << (ctrl->read.order - PAGE_SHIFT) : 0;
	int pages_right = ctrl->write.order >= PAGE_SHIFT ? 1 << (ctrl->write.order - PAGE_SHIFT) : 0;
	uint32_t ring_ref = -1;
	void *ring;

	ring = xc_gntshr_share_page_notify(ctrl->gntshr, domain,
			&ring_ref, 1, offsetof(struct vchan_interface, srv_live),
			ctrl->event_port);

	if (!ring)
		goto out;

	memset(ring, 0, PAGE_SIZE);

	ctrl->ring = ring;
	ctrl->read.shr = &ctrl->ring->left;
	ctrl->write.shr = &ctrl->ring->right;
	ctrl->ring->left_order = ctrl->read.order;
	ctrl->ring->right_order = ctrl->write.order;
	ctrl->ring->cli_live = 2;
	ctrl->ring->srv_live = 1;
	ctrl->ring->cli_notify = VCHAN_NOTIFY_WRITE;

	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:
		ctrl->read.buffer = xc_gntshr_share_pages(ctrl->gntshr, domain,
			pages_left, ctrl->ring->grants, 1);
		if (!ctrl->read.buffer)
			goto out_ring;
	}

	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:
		ctrl->write.buffer = xc_gntshr_share_pages(ctrl->gntshr, domain,
			pages_right, ctrl->ring->grants + pages_left, 1);
		if (!ctrl->write.buffer)
			goto out_unmap_left;
	}

out:
	return ring_ref;
out_unmap_left:
	if (pages_left)
		xc_gntshr_munmap(ctrl->gntshr, ctrl->read.buffer, pages_left);
out_ring:
	xc_gntshr_munmap(ctrl->gntshr, ring, 1);
	ring_ref = -1;
	ctrl->ring = NULL;
	ctrl->write.order = ctrl->read.order = 0;
	goto out;
}
Ejemplo n.º 4
0
/* Open an interface to gntshr or gnttab each time it is needed. */
int test_open_multiple() {
    xc_gntshr *gntshr_if;
    xc_gnttab *gnttab_if;

    uint32_t refs[PAGE_COUNT];
    uint32_t domids[PAGE_COUNT];
    void* local_share;
    void* remote_share;

    int i;
    int err;

    gntshr_if = xc_gntshr_open(NULL, 0);
    if(!gntshr_if) {
        printf("Failed to open gntshr interface.\n");
        return 1;
    }
    gnttab_if = xc_gnttab_open(NULL, 0);
    if(!gnttab_if) {
        printf("Failed to open gnttab interface.\n");
        return 1;
    }

    local_share = xc_gntshr_share_pages(gntshr_if, DOMID, PAGE_COUNT, refs, 0);
    if(!local_share) {
        printf("Failed to share memory.\n");
        return 1;
    }

    for(i = 0; i < PAGE_COUNT; i++) {
        printf("Sharing page with ref %d.\n", refs[i]);
    }

    for(i = 0; i < PAGE_COUNT; i++) {
        domids[i] = DOMID;
    }
    remote_share = xc_gnttab_map_grant_refs(
            gnttab_if,
            PAGE_COUNT,
            domids,
            refs,
            PROT_READ);
    if(!remote_share) {
        printf("Failed to map memory.\n");
        return 1;
    }

    if(xc_gntshr_close(gntshr_if)) {
        printf("Failed to close gntshr interface.\n");
        return 1;
    }
    if(xc_gnttab_close(gnttab_if)) {
        printf("Failed to close gnttab interface.\n");
        return 1;
    }

    gntshr_if = xc_gntshr_open(NULL, 0);
    if(!gntshr_if) {
        printf("Failed to open gntshr interface.\n");
        return 1;
    }
    gnttab_if = xc_gnttab_open(NULL, 0);
    if(!gnttab_if) {
        printf("Failed to open gnttab interface.\n");
        return 1;
    }

    err = xc_gnttab_munmap(gnttab_if, remote_share, 1);
    if(err) {
        printf("Failed to unmap memory - got error code %d.\n", err);
        return 1;
    }

    err = xc_gntshr_munmap(gntshr_if, local_share, 1);
    if(err) {
        printf("Failed to unshare memory - got error code %d.\n", err);
        return 1;
    }

    if(xc_gntshr_close(gntshr_if)) {
        printf("Failed to close gntshr interface.\n");
        return 1;
    }
    if(xc_gnttab_close(gnttab_if)) {
        printf("Failed to close gnttab interface.\n");
        return 1;
    }

    return 0;
}