CAMLprim value stub_gnttab_mapv_batched( value xgh, value array, value writable) { CAMLparam3(xgh, array, writable); CAMLlocal4(domid, reference, contents, pair); int count = Wosize_val(array) / 2; uint32_t domids[count]; uint32_t refs[count]; int i; for (i = 0; i < count; i++) { domids[i] = Int_val(Field(array, i * 2 + 0)); refs[i] = Int_val(Field(array, i * 2 + 1)); } void *map = xc_gnttab_map_grant_refs(_G(xgh), count, domids, refs, Bool_val(writable)?PROT_READ | PROT_WRITE : PROT_READ); if(map==NULL) { caml_failwith("Failed to map grant ref"); } contents = caml_ba_alloc_dims(XC_GNTTAB_BIGARRAY, 1, map, count << XC_PAGE_SHIFT); pair = caml_alloc_tuple(2); Store_field(pair, 0, contents); /* grant_handle */ Store_field(pair, 1, contents); /* Io_page.t */ CAMLreturn(pair); }
static int ioreq_map(struct ioreq *ioreq) { XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev; int i; if (ioreq->v.niov == 0 || ioreq->mapped == 1) { return 0; } if (batch_maps) { ioreq->pages = xc_gnttab_map_grant_refs (gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot); if (ioreq->pages == NULL) { xen_be_printf(&ioreq->blkdev->xendev, 0, "can't map %d grant refs (%s, %d maps)\n", ioreq->v.niov, strerror(errno), ioreq->blkdev->cnt_map); return -1; } for (i = 0; i < ioreq->v.niov; i++) { ioreq->v.iov[i].iov_base = ioreq->pages + i * XC_PAGE_SIZE + (uintptr_t)ioreq->v.iov[i].iov_base; } ioreq->blkdev->cnt_map += ioreq->v.niov; } else { for (i = 0; i < ioreq->v.niov; i++) { ioreq->page[i] = xc_gnttab_map_grant_ref (gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot); if (ioreq->page[i] == NULL) { xen_be_printf(&ioreq->blkdev->xendev, 0, "can't map grant ref %d (%s, %d maps)\n", ioreq->refs[i], strerror(errno), ioreq->blkdev->cnt_map); ioreq_unmap(ioreq); return -1; } ioreq->v.iov[i].iov_base = ioreq->page[i] + (uintptr_t)ioreq->v.iov[i].iov_base; ioreq->blkdev->cnt_map++; } } ioreq->mapped = 1; return 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; }