/* Stolen from xenstore code */ static int eventchn_init(void) { int rc; // to revert to old way: if (0) return -1; xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) perror("Failed to open evtchn device"); if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1) perror("Failed to bind to domain exception virq port"); virq_port = rc; return xce_handle == NULL ? -1 : 0; }
int main(int argc, char *argv[]) { int rc; atexit(cleanup); xch = xc_interface_open(NULL, NULL, 0); if (xch == NULL) { perror("Failed to open xc interface"); return 1; } xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) { perror("Failed to open evtchn device"); return 2; } xs_handle = xs_daemon_open(); if (xs_handle == NULL) { perror("Failed to open xenstore connection"); return 3; } if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1) { perror("Failed to bind to domain exception virq port"); return 4; } virq_port = rc; while(1) { evtchn_port_t port; if ((port = xenevtchn_pending(xce_handle)) == -1) { perror("Failed to listen for pending event channel"); return 5; } if (port != virq_port) { char data[BUFSZ]; snprintf(data, BUFSZ, "Wrong port, got %d expected %d", port, virq_port); perror(data); return 6; } if (xenevtchn_unmask(xce_handle, port) == -1) { perror("Failed to unmask port"); return 7; } printf("Got a virq kick, time to get work\n"); handle_low_mem(); } return 0; }
static int xen_9pfs_connect(struct XenLegacyDevice *xendev) { Error *err = NULL; int i; Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); V9fsState *s = &xen_9pdev->state; QemuOpts *fsdev; if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings", &xen_9pdev->num_rings) == -1 || xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) { return -1; } xen_9pdev->rings = g_new0(Xen9pfsRing, xen_9pdev->num_rings); for (i = 0; i < xen_9pdev->num_rings; i++) { char *str; int ring_order; xen_9pdev->rings[i].priv = xen_9pdev; xen_9pdev->rings[i].evtchn = -1; xen_9pdev->rings[i].local_port = -1; str = g_strdup_printf("ring-ref%u", i); if (xenstore_read_fe_int(&xen_9pdev->xendev, str, &xen_9pdev->rings[i].ref) == -1) { g_free(str); goto out; } g_free(str); str = g_strdup_printf("event-channel-%u", i); if (xenstore_read_fe_int(&xen_9pdev->xendev, str, &xen_9pdev->rings[i].evtchn) == -1) { g_free(str); goto out; } g_free(str); xen_9pdev->rings[i].intf = xen_be_map_grant_ref(&xen_9pdev->xendev, xen_9pdev->rings[i].ref, PROT_READ | PROT_WRITE); if (!xen_9pdev->rings[i].intf) { goto out; } ring_order = xen_9pdev->rings[i].intf->ring_order; if (ring_order > MAX_RING_ORDER) { goto out; } xen_9pdev->rings[i].ring_order = ring_order; xen_9pdev->rings[i].data = xen_be_map_grant_refs(&xen_9pdev->xendev, xen_9pdev->rings[i].intf->ref, (1 << ring_order), PROT_READ | PROT_WRITE); if (!xen_9pdev->rings[i].data) { goto out; } xen_9pdev->rings[i].ring.in = xen_9pdev->rings[i].data; xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data + XEN_FLEX_RING_SIZE(ring_order); xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]); xen_9pdev->rings[i].out_cons = 0; xen_9pdev->rings[i].out_size = 0; xen_9pdev->rings[i].inprogress = false; xen_9pdev->rings[i].evtchndev = xenevtchn_open(NULL, 0); if (xen_9pdev->rings[i].evtchndev == NULL) { goto out; } qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev)); xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain (xen_9pdev->rings[i].evtchndev, xendev->dom, xen_9pdev->rings[i].evtchn); if (xen_9pdev->rings[i].local_port == -1) { xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed port=%d\n", xen_9pdev->rings[i].evtchn); goto out; } xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings[i]); } xen_9pdev->security_model = xenstore_read_be_str(xendev, "security_model"); xen_9pdev->path = xenstore_read_be_str(xendev, "path"); xen_9pdev->id = s->fsconf.fsdev_id = g_strdup_printf("xen9p%d", xendev->dev); xen_9pdev->tag = s->fsconf.tag = xenstore_read_fe_str(xendev, "tag"); fsdev = qemu_opts_create(qemu_find_opts("fsdev"), s->fsconf.tag, 1, NULL); qemu_opt_set(fsdev, "fsdriver", "local", NULL); qemu_opt_set(fsdev, "path", xen_9pdev->path, NULL); qemu_opt_set(fsdev, "security_model", xen_9pdev->security_model, NULL); qemu_opts_set_id(fsdev, s->fsconf.fsdev_id); qemu_fsdev_add(fsdev, &err); if (err) { error_report_err(err); } v9fs_device_realize_common(s, &xen_9p_transport, NULL); return 0; out: xen_9pfs_free(xendev); return -1; }