CAMLprim value stub_gntshr_munmap_batched(value xgh, value share) { CAMLparam2(xgh, share); CAMLlocal1(ml_map); #ifdef HAVE_GNTSHR ml_map = Field(share, 1); int size = Bigarray_val(ml_map)->dim[0]; int pages = size >> XC_PAGE_SHIFT; #ifdef linux /* Bug in xen-4.4 libxc xc_linux_osdep implementation, work-around by using the kernel interface directly. */ int result = munmap(Data_bigarray_val(ml_map), size); #else int result = xc_gntshr_munmap(_G(xgh), Data_bigarray_val(ml_map), pages); #endif if(result != 0) failwith_xc(_G(xgh)); #else gntshr_missing(); #endif CAMLreturn(Val_unit); }
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; }
/* 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; }