コード例 #1
0
ファイル: xen_disk.c プロジェクト: AmesianX/qemu-kvm
static void ioreq_unmap(struct ioreq *ioreq)
{
    int gnt = ioreq->blkdev->xendev.gnttabdev;
    int i;

    if (ioreq->v.niov == 0)
        return;
    if (batch_maps) {
	if (!ioreq->pages)
	    return;
	if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0)
	    xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
			  strerror(errno));
	ioreq->blkdev->cnt_map -= ioreq->v.niov;
	ioreq->pages = NULL;
    } else {
	for (i = 0; i < ioreq->v.niov; i++) {
	    if (!ioreq->page[i])
		continue;
	    if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0)
		xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: %s\n",
			      strerror(errno));
	    ioreq->blkdev->cnt_map--;
	    ioreq->page[i] = NULL;
	}
    }
}
コード例 #2
0
ファイル: xen_nic.c プロジェクト: ChenXuJasper/qemu
static void net_disconnect(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);

    xen_be_unbind_evtchn(&netdev->xendev);

    if (netdev->txs) {
        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
        netdev->txs = NULL;
    }
    if (netdev->rxs) {
        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
        netdev->rxs = NULL;
    }
}
コード例 #3
0
ファイル: io.c プロジェクト: CPFL/gxen
void libxenvchan_close(struct libxenvchan *ctrl)
{
	if (!ctrl)
		return;
	if (ctrl->read.order >= PAGE_SHIFT)
		munmap(ctrl->read.buffer, 1 << ctrl->read.order);
	if (ctrl->write.order >= PAGE_SHIFT)
		munmap(ctrl->write.buffer, 1 << ctrl->write.order);
	if (ctrl->ring) {
		if (ctrl->is_server) {
			ctrl->ring->srv_live = 0;
			xc_gntshr_munmap(ctrl->gntshr, ctrl->ring, PAGE_SIZE);
		} else {
			ctrl->ring->cli_live = 0;
			xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, PAGE_SIZE);
		}
	}
	if (ctrl->event) {
		if (ctrl->event_port >= 0 && ctrl->ring)
			xc_evtchn_notify(ctrl->event, ctrl->event_port);
		xc_evtchn_close(ctrl->event);
	}
	if (ctrl->is_server) {
		if (ctrl->gntshr)
			xc_gntshr_close(ctrl->gntshr);
	} else {
		if (ctrl->gnttab)
			xc_gnttab_close(ctrl->gnttab);
	}
	free(ctrl);
}
コード例 #4
0
ファイル: xen_nic.c プロジェクト: ChenXuJasper/qemu
static int net_connect(struct XenDevice *xendev)
{
    struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
    int rx_copy;

    if (xenstore_read_fe_int(&netdev->xendev, "tx-ring-ref",
                             &netdev->tx_ring_ref) == -1) {
        return -1;
    }
    if (xenstore_read_fe_int(&netdev->xendev, "rx-ring-ref",
                             &netdev->rx_ring_ref) == -1) {
        return 1;
    }
    if (xenstore_read_fe_int(&netdev->xendev, "event-channel",
                             &netdev->xendev.remote_port) == -1) {
        return -1;
    }

    if (xenstore_read_fe_int(&netdev->xendev, "request-rx-copy", &rx_copy) == -1) {
        rx_copy = 0;
    }
    if (rx_copy == 0) {
        xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n");
        return -1;
    }

    netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
                                          netdev->xendev.dom,
                                          netdev->tx_ring_ref,
                                          PROT_READ | PROT_WRITE);
    if (!netdev->txs) {
        return -1;
    }
    netdev->rxs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
                                          netdev->xendev.dom,
                                          netdev->rx_ring_ref,
                                          PROT_READ | PROT_WRITE);
    if (!netdev->rxs) {
        xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
        netdev->txs = NULL;
        return -1;
    }
    BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
    BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XC_PAGE_SIZE);

    xen_be_bind_evtchn(&netdev->xendev);

    xen_be_printf(&netdev->xendev, 1, "ok: tx-ring-ref %d, rx-ring-ref %d, "
                  "remote port %d, local port %d\n",
                  netdev->tx_ring_ref, netdev->rx_ring_ref,
                  netdev->xendev.remote_port, netdev->xendev.local_port);

    net_tx_packets(netdev);
    return 0;
}
コード例 #5
0
ファイル: gnttab_stubs.c プロジェクト: johnelse/ocaml-gnt
CAMLprim value stub_gnttab_unmap(value xgh, value array)
{
    CAMLparam2(xgh, array);

    int size = Caml_ba_array_val(array)->dim[0];
    int pages = size >> XC_PAGE_SHIFT;
    int result = xc_gnttab_munmap(_G(xgh), Caml_ba_data_val(array), pages);
    if(result!=0) {
        caml_failwith("Failed to unmap grant");
    }

    CAMLreturn(Val_unit);
}
コード例 #6
0
ファイル: td-blkif.c プロジェクト: andyhhp/blktap
int
tapdisk_xenblkif_destroy(struct td_xenblkif * blkif)
{
    int err;

    ASSERT(blkif);

    if (tapdisk_xenblkif_chkrng_event_id(blkif) >= 0) {
        tapdisk_server_unregister_event(
				tapdisk_xenblkif_chkrng_event_id(blkif));
        blkif->chkrng_event = -1;
    }

    tapdisk_xenblkif_reqs_free(blkif);

    if (blkif->ctx) {
        if (blkif->port >= 0)
            xc_evtchn_unbind(blkif->ctx->xce_handle, blkif->port);

        if (blkif->rings.common.sring) {
            err = xc_gnttab_munmap(blkif->ctx->xcg_handle,
					blkif->rings.common.sring, blkif->ring_n_pages);
			if (unlikely(err)) {
				err = errno;
				EPRINTF("failed to unmap ring page %p (%d pages): %s "
						"(error ignored)\n",
						blkif->rings.common.sring, blkif->ring_n_pages,
						strerror(err));
				err = 0;
			}
		}

		list_del(&blkif->entry_ctx);
        list_del(&blkif->entry);
        tapdisk_xenio_ctx_put(blkif->ctx);
    }
    err = td_metrics_vbd_stop(&blkif->vbd_stats);
    if (unlikely(err))
        EPRINTF("failed to destroy blkfront stats file: %s\n", strerror(-err));

    err = tapdisk_xenblkif_stats_destroy(blkif);
    if (unlikely(err)) {
        EPRINTF("failed to clean up ring stats file: %s (error ignored)\n",
                strerror(-err));
        err = 0;
    }

    free(blkif);

    return err;
}
コード例 #7
0
ファイル: xen_console.c プロジェクト: avasani/modified-xen
static void con_disconnect(struct XenDevice *xendev)
{
    struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);

    if (con->chr)
        qemu_chr_add_handlers(con->chr, NULL, NULL, NULL, NULL);
    xen_be_unbind_evtchn(&con->xendev);

    if (con->sring) {
        if (!xendev->gnttabdev)
	    munmap(con->sring, XC_PAGE_SIZE);
        else
            xc_gnttab_munmap(xendev->gnttabdev, con->sring, 1);
	con->sring = NULL;
    }
}
コード例 #8
0
ファイル: xen_nic.c プロジェクト: D3cedut0/QEMU
static ssize_t net_rx_packet(VLANClientState *nc, const uint8_t *buf, size_t size)
{
    struct XenNetDev *netdev = DO_UPCAST(NICState, nc, nc)->opaque;
    netif_rx_request_t rxreq;
    RING_IDX rc, rp;
    void *page;

    if (netdev->xendev.be_state != XenbusStateConnected) {
        return -1;
    }

    rc = netdev->rx_ring.req_cons;
    rp = netdev->rx_ring.sring->req_prod;
    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

    if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
        xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");
        return -1;
    }
    if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {
        xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",
                      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);
        return -1;
    }

    memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
    netdev->rx_ring.req_cons = ++rc;

    page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
                                   netdev->xendev.dom,
                                   rxreq.gref, PROT_WRITE);
    if (page == NULL) {
        xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",
                      rxreq.gref);
        net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
        return -1;
    }
    memcpy(page + NET_IP_ALIGN, buf, size);
    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
    net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);

    return size;
}
コード例 #9
0
ファイル: xen_disk.c プロジェクト: AmesianX/qemu-kvm
static void blk_disconnect(struct XenDevice *xendev)
{
    struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);

    if (blkdev->bs) {
        if (!blkdev->dinfo) {
            /* close/delete only if we created it ourself */
            bdrv_close(blkdev->bs);
            bdrv_delete(blkdev->bs);
        }
	blkdev->bs = NULL;
    }
    xen_be_unbind_evtchn(&blkdev->xendev);

    if (blkdev->sring) {
	xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
	blkdev->cnt_map--;
	blkdev->sring = NULL;
    }
}
コード例 #10
0
ファイル: libIVC.c プロジェクト: AlexanderAA/HaLVM
void closeConnection(libIVC_t *iface, ivc_connection_t *con)
{
  void *ptr = con->inbuf ? con->inbuf : con->outbuf;
  uint32_t size;

  switch(con->type) {
    case ivcInputChannel:
      size = con->insize + sizeof(struct bufstate);
      break;
    case ivcOutputChannel:
      size = con->outsize + sizeof(struct bufstate);
      break;
    case ivcInputOutputChannel:
      size = con->insize + con->outsize + (2 * sizeof(struct bufstate));
      break;
    default:
      assert(0);
  }

  xc_gnttab_munmap(iface->gt, ptr, (size + 4095) / 4096);
  free(con);
}
コード例 #11
0
ファイル: xen_nic.c プロジェクト: D3cedut0/QEMU
static void net_tx_packets(struct XenNetDev *netdev)
{
    netif_tx_request_t txreq;
    RING_IDX rc, rp;
    void *page;
    void *tmpbuf = NULL;

    for (;;) {
        rc = netdev->tx_ring.req_cons;
        rp = netdev->tx_ring.sring->req_prod;
        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

        while ((rc != rp)) {
            if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc)) {
                break;
            }
            memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
            netdev->tx_ring.req_cons = ++rc;

#if 1
            /* should not happen in theory, we don't announce the *
             * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
            if (txreq.flags & NETTXF_extra_info) {
                xen_be_printf(&netdev->xendev, 0, "FIXME: extra info flag\n");
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
            if (txreq.flags & NETTXF_more_data) {
                xen_be_printf(&netdev->xendev, 0, "FIXME: more data flag\n");
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
#endif

            if (txreq.size < 14) {
                xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }

            if ((txreq.offset + txreq.size) > XC_PAGE_SIZE) {
                xen_be_printf(&netdev->xendev, 0, "error: page crossing\n");
                net_tx_error(netdev, &txreq, rc);
                continue;
            }

            xen_be_printf(&netdev->xendev, 3, "tx packet ref %d, off %d, len %d, flags 0x%x%s%s%s%s\n",
                          txreq.gref, txreq.offset, txreq.size, txreq.flags,
                          (txreq.flags & NETTXF_csum_blank)     ? " csum_blank"     : "",
                          (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
                          (txreq.flags & NETTXF_more_data)      ? " more_data"      : "",
                          (txreq.flags & NETTXF_extra_info)     ? " extra_info"     : "");

            page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
                                           netdev->xendev.dom,
                                           txreq.gref, PROT_READ);
            if (page == NULL) {
                xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference failed (%d)\n",
                              txreq.gref);
                net_tx_error(netdev, &txreq, rc);
                continue;
            }
            if (txreq.flags & NETTXF_csum_blank) {
                /* have read-only mapping -> can't fill checksum in-place */
                if (!tmpbuf) {
                    tmpbuf = g_malloc(XC_PAGE_SIZE);
                }
                memcpy(tmpbuf, page + txreq.offset, txreq.size);
                net_checksum_calculate(tmpbuf, txreq.size);
                qemu_send_packet(&netdev->nic->nc, tmpbuf, txreq.size);
            } else {
                qemu_send_packet(&netdev->nic->nc, page + txreq.offset, txreq.size);
            }
            xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
            net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
        }
        if (!netdev->tx_work) {
            break;
        }
        netdev->tx_work = 0;
    }
    g_free(tmpbuf);
}
コード例 #12
0
ファイル: init.c プロジェクト: Fantu/Xen
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;
}
コード例 #13
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;
}
コード例 #14
0
ファイル: fs-backend.c プロジェクト: tumf/xen-3.3.1
static void *handle_mount(void *data)
{
    int more, notify;
    struct fs_mount *mount = (struct fs_mount *)data;
    
    printf("Starting a thread for mount: %d\n", mount->mount_id);
    allocate_request_array(mount);

    for(;;)
    {
        int nr_consumed=0;
        RING_IDX cons, rp;
        struct fsif_request *req;

        handle_aio_events(mount);
moretodo:
        rp = mount->ring.sring->req_prod;
        xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

        while ((cons = mount->ring.req_cons) != rp)
        {
            int i;
            struct fs_op *op;

            printf("Got a request at %d (of %d)\n", 
                    cons, RING_SIZE(&mount->ring));
            req = RING_GET_REQUEST(&mount->ring, cons);
            printf("Request type=%d\n", req->type); 
            for(i=0;;i++)
            {
                op = fsops[i];
                if(op == NULL)
                {
                    /* We've reached the end of the array, no appropirate
                     * handler found. Warn, ignore and continue. */
                    printf("WARN: Unknown request type: %d\n", req->type);
                    mount->ring.req_cons++; 
                    break;
                }
                if(op->type == req->type)
                {
                    /* There needs to be a dispatch handler */
                    assert(op->dispatch_handler != NULL);
                    op->dispatch_handler(mount, req);
                    break;
                }
             }

            nr_consumed++;
        }
        printf("Backend consumed: %d requests\n", nr_consumed);
        RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more);
        if(more) goto moretodo;

        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
        printf("Pushed responces and notify=%d\n", notify);
        if(notify)
            xc_evtchn_notify(mount->evth, mount->local_evtchn);
    }
 
    printf("Destroying thread for mount: %d\n", mount->mount_id);
    xc_gnttab_munmap(mount->gnth, mount->ring.sring, 1);
    xc_gnttab_close(mount->gnth);
    xc_evtchn_unbind(mount->evth, mount->local_evtchn);
    xc_evtchn_close(mount->evth);
    free(mount->frontend);
    pthread_exit(NULL);
}