/****************************************************************************** * xc_evtchn.c * * API for manipulating and accessing inter-domain event channels. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Copyright (c) 2004, K A Fraser. */ #include "xc_private.h" static int do_evtchn_op(xc_interface *xch, int cmd, void *arg, size_t arg_size, int silently_fail) { int ret = -1; DECLARE_HYPERCALL; DECLARE_HYPERCALL_BOUNCE(arg, arg_size, XC_HYPERCALL_BUFFER_BOUNCE_BOTH); if ( xc_hypercall_bounce_pre(xch, arg) ) { PERROR("do_evtchn_op: bouncing arg failed"); goto out; } hypercall.op = __HYPERVISOR_event_channel_op; hypercall.arg[0] = cmd; hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg); if ((ret = do_xen_hypercall(xch, &hypercall)) < 0 && !silently_fail) ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret); xc_hypercall_bounce_post(xch, arg); out: return ret; } evtchn_port_or_error_t xc_evtchn_alloc_unbound(xc_interface *xch, uint32_t dom, uint32_t remote_dom) { int rc; struct evtchn_alloc_unbound arg = { .dom = (domid_t)dom, .remote_dom = (domid_t)remote_dom }; rc = do_evtchn_op(xch, EVTCHNOP_alloc_unbound, &arg, sizeof(arg), 0); if ( rc == 0 ) rc = arg.port; return rc; } int xc_evtchn_reset(xc_interface *xch, uint32_t dom) { struct evtchn_reset arg = { .dom = (domid_t)dom }; return do_evtchn_op(xch, EVTCHNOP_reset, &arg, sizeof(arg), 0); } int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status) { return do_evtchn_op(xch, EVTCHNOP_status, status, sizeof(*status), 1); } int xc_evtchn_fd(xc_evtchn *xce) { return xce->ops->u.evtchn.fd(xce, xce->ops_handle); } int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) { return xce->ops->u.evtchn.notify(xce, xce->ops_handle, port); } evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) { return xce->ops->u.evtchn.bind_unbound_port(xce, xce->ops_handle, domid); } evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, evtchn_port_t remote_port) { return xce->ops->u.evtchn.bind_interdomain(xce, xce->ops_handle, domid, remote_port); } evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) { return xce->ops->u.evtchn.bind_virq(xce, xce->ops_handle, virq); } int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) { return xce->ops->u.evtchn.unbind(xce, xce->ops_handle, port); } evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) { return xce->ops->u.evtchn.pending(xce, xce->ops_handle); } int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) { return xce->ops->u.evtchn.unmask(xce, xce->ops_handle, port); } /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */