int xc_suspend_evtchn_init(xc_interface *xch, xc_evtchn *xce, int domid, int port) { int rc, suspend_evtchn = -1; if (lock_suspend_event(xch, domid)) return -EINVAL; suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); if (suspend_evtchn < 0) { ERROR("failed to bind suspend event channel: %d", suspend_evtchn); goto cleanup; } rc = xc_domain_subscribe_for_suspend(xch, domid, port); if (rc < 0) { ERROR("failed to subscribe to domain: %d", rc); goto cleanup; } /* event channel is pending immediately after binding */ xc_await_suspend(xch, xce, suspend_evtchn); return suspend_evtchn; cleanup: xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn); return -1; }
static int xenfb_bind(struct xenfb_device *dev) { struct xenfb *xenfb = dev->xenfb; unsigned long mfn; evtchn_port_t evtchn; if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "page-ref", "%lu", &mfn) < 0) return -1; if (xenfb_xs_scanf1(xenfb->xsh, dev->otherend, "event-channel", "%u", &evtchn) < 0) return -1; dev->port = xc_evtchn_bind_interdomain(xenfb->evt_xch, dev->otherend_id, evtchn); if (dev->port == -1) return -1; dev->page = xc_map_foreign_range(xenfb->xc, dev->otherend_id, XC_PAGE_SIZE, PROT_READ | PROT_WRITE, mfn); if (dev->page == NULL) return -1; return 0; }
static int init_evt_cli(struct libxenvchan *ctrl, int domain, xentoollog_logger *logger) { evtchn_port_or_error_t port; ctrl->event = xc_evtchn_open(logger, 0); if (!ctrl->event) return -1; port = xc_evtchn_bind_interdomain(ctrl->event, domain, ctrl->event_port); if (port < 0) goto fail; ctrl->event_port = port; if (xc_evtchn_unmask(ctrl->event, ctrl->event_port)) goto fail; return 0; fail: if (port >= 0) xc_evtchn_unbind(ctrl->event, port); xc_evtchn_close(ctrl->event); ctrl->event = NULL; return -1; }
int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce, int domid, int port, int *lockfd) { int rc, suspend_evtchn = -1; if (lock_suspend_event(xch, domid, lockfd)) { errno = EINVAL; goto cleanup; } suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); if (suspend_evtchn < 0) { ERROR("failed to bind suspend event channel: %d", suspend_evtchn); goto cleanup; } rc = xc_domain_subscribe_for_suspend(xch, domid, port); if (rc < 0) { ERROR("failed to subscribe to domain: %d", rc); goto cleanup; } return suspend_evtchn; cleanup: xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn, lockfd); return -1; }
static int suspend_evtchn_init(int xc, int domid) { struct xs_handle *xs; char path[128]; char *portstr; unsigned int plen; int port; int rc; si.xce = -1; si.suspend_evtchn = -1; xs = xs_daemon_open(); if (!xs) { warnx("failed to get xenstore handle"); return -1; } sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid); portstr = xs_read(xs, XBT_NULL, path, &plen); xs_daemon_close(xs); if (!portstr || !plen) { warnx("could not read suspend event channel"); return -1; } port = atoi(portstr); free(portstr); si.xce = xc_evtchn_open(); if (si.xce < 0) { warnx("failed to open event channel handle"); goto cleanup; } si.suspend_evtchn = xc_evtchn_bind_interdomain(si.xce, domid, port); if (si.suspend_evtchn < 0) { warnx("failed to bind suspend event channel: %d", si.suspend_evtchn); goto cleanup; } rc = xc_domain_subscribe_for_suspend(xc, domid, port); if (rc < 0) { warnx("failed to subscribe to domain: %d", rc); goto cleanup; } /* event channel is pending immediately after binding */ await_suspend(); return 0; cleanup: suspend_evtchn_release(); return -1; }
CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid, value remote_port) { evtchn_port_or_error_t rc; rc = xc_evtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port)); if (rc == -1) caml_failwith("evtchn bind_interdomain failed"); return Val_int(rc); }
ivc_connection_t *makeConnection(libIVC_t *iface, char *name, ivc_contype_t type, float per) { char *key, *val, *rdomstr = NULL, *rrefstr = NULL, *rpstr = NULL; uint32_t me, other, num_refs, *grants; struct xs_permissions perms; ivc_connection_t *res; evtchn_port_t port; unsigned int len; void *buffer; /* me <- xsGetDomId */ me = getMyDomId(iface); /* removePath xs targetPath */ ASPRINTF(&key, "/rendezvous/%s", name); xs_rm(iface->xs, 0, key); /* xsMakeDirectory xs targetPath */ xs_mkdir(iface->xs, 0, key); /* xsSetPermissions xs targetPath [ReadWritePerm me] */ perms.id = me; perms.perms = XS_PERM_READ | XS_PERM_WRITE; xs_set_permissions(iface->xs, 0, key, &perms, 1); /* xsWrite xs (targetPath ++ "/LeftDomId") (show me) */ free(key), ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name); ASPRINTF(&val, "dom%d", me); xs_write(iface->xs, 0, key, val, strlen(val)); /* other <- read <$> waitForKey xs (targetPAth ++ "/RightDomId") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name); while(!rdomstr) { rdomstr = xs_read(iface->xs, 0, key, &len); }; sscanf(rdomstr, "dom%d", &other); /* grants <- read <$> waitForKey xs (targetPAth ++ "/RightGrantRefs") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name); while(!rrefstr) { rrefstr = xs_read(iface->xs, 0, key, &len); } grants = parseRefs(rrefstr, &num_refs); buffer = xc_gnttab_map_domain_grant_refs(iface->gt, num_refs, other, grants, PROT_READWRITE); assert(buffer); /* ports <- read <$> waitForKey xs (targetPAth ++ "/RightPorts") */ free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name); while(!rpstr) { rpstr = xs_read(iface->xs, 0, key, &len); } sscanf(rpstr, "[echan:%d]", &port); port = xc_evtchn_bind_interdomain(iface->ec, other, port); assert(port >= 0); /* res <- acceptConnection other grants ports extra */ res = buildChannel(iface, other, type, port, buffer, num_refs * 4096, per, 0); /* xsWrite xs (targetPath ++ "/LeftConnectionConfirmed") "True" */ free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name); free(val), ASPRINTF(&val, "True"); xs_write(iface->xs, 0, key, val, strlen(val)); /* return res */ return res; }
CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid, value remote_port) { CAMLparam3(xce, domid, remote_port); CAMLlocal1(port); evtchn_port_or_error_t rc; rc = xc_evtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port)); if (rc == -1) caml_failwith("evtchn bind_interdomain failed"); port = Val_int(rc); CAMLreturn(port); }
CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid, value remote_port) { CAMLparam3(xce, domid, remote_port); evtchn_port_or_error_t rc; rc = xc_evtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port)); if (rc == -1) { perror("xc_evtchn_bind_interdomain"); caml_failwith(strerror(errno)); } CAMLreturn(Val_int(rc)); }
int xen_be_bind_evtchn(struct XenDevice *xendev) { if (xendev->local_port != -1) { return 0; } xendev->local_port = xc_evtchn_bind_interdomain (xendev->evtchndev, xendev->dom, xendev->remote_port); if (xendev->local_port == -1) { xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n"); return -1; } xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), xen_be_evtchn_event, NULL, xendev); return 0; }