[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
libxenevtchn will provide a stable API and ABI for accessing the evtchn device. The functions are moved into the xenevtchn namespace to make a clean break from libxc and avoid ambiguity regarding which interfaces are stable. All in-tree users are updated to use the new names. Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will provide a compat API for the old names, which is used by qemu-xen for the time being. The dynamic osdep mechanism from libxc is not preserved, the alternative backend (a xen-api/xapi shim) is no longer around. (Nested virt probably suffices for this use case now). This leaves a few event channel related functions which go via privcmd (EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in libxenctrl. Specifically: - xc_evtchn_alloc_unbound - xc_evtchn_reset - xc_evtchn_status These functions do not appear to be needed by qemu-dm, qemu-pv (provision of device model to HVM guests and PV backends respectively) or by libvchan suggesting they are not needed by non-toolstack uses of event channels. QEMU does use these in hw/xenpv/xen_domainbuild.c but that is a "toolstack use". The new library uses a version script to ensure that only expected symbols are exported and to version them such that ABI guarantees can be kept in the future. Build tested with Linux and mini-os/stubdom, but not FreeBSD, NetBSD or Solaris. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- Must be applied with: - "qemu-xen-traditional: Use libxenevtchn" and a corresponding QEMU_TAG update folded here. - "mini-os: Include libxenevtchn with libxc"" and a corresponding bump to MINIOS_UPSTREAM_REVISION folded in here. --- .gitignore | 1 + docs/misc/libxenctrl-functions.pandoc | 9 +- stubdom/Makefile | 19 +- tools/Makefile | 6 +- tools/Rules.mk | 19 +- tools/console/Makefile | 2 + tools/console/daemon/io.c | 43 +++-- tools/libvchan/Makefile | 6 +- tools/libvchan/init.c | 20 +- tools/libvchan/io.c | 12 +- tools/libvchan/libxenvchan.h | 3 +- tools/libxc/Makefile | 8 +- tools/libxc/include/xenctrl.h | 99 +--------- tools/libxc/include/xenctrl_compat.h | 48 +++++ tools/libxc/include/xenguest.h | 10 +- tools/libxc/xc_evtchn_compat.c | 75 ++++++++ tools/libxc/xc_freebsd_osdep.c | 101 ---------- tools/libxc/xc_linux_osdep.c | 95 --------- tools/libxc/xc_minios.c | 221 --------------------- tools/libxc/xc_netbsd.c | 109 ----------- tools/libxc/xc_private.c | 40 ---- tools/libxc/xc_private.h | 7 - tools/libxc/xc_solaris.c | 97 ---------- tools/libxc/xc_suspend.c | 18 +- tools/libxenevtchn/Makefile | 65 +++++++ tools/libxenevtchn/core.c | 60 ++++++ tools/libxenevtchn/freebsd.c | 122 ++++++++++++ tools/libxenevtchn/include/xenevtchn.h | 154 +++++++++++++++ tools/libxenevtchn/libxenevtchn.map | 14 ++ tools/libxenevtchn/linux.c | 133 +++++++++++++ tools/libxenevtchn/minios.c | 257 +++++++++++++++++++++++++ tools/libxenevtchn/netbsd.c | 132 +++++++++++++ tools/libxenevtchn/private.h | 15 ++ tools/libxenevtchn/solaris.c | 120 ++++++++++++ tools/libxl/Makefile | 5 +- tools/libxl/libxl.c | 2 +- tools/libxl/libxl_dom.c | 4 +- tools/libxl/libxl_event.c | 14 +- tools/libxl/libxl_internal.h | 5 +- tools/misc/Makefile | 7 +- tools/misc/xen-hptool.c | 13 +- tools/misc/xen-lowmemd.c | 15 +- tools/ocaml/libs/eventchn/Makefile | 4 +- tools/ocaml/libs/eventchn/xeneventchn_stubs.c | 20 +- tools/python/setup.py | 7 +- tools/tests/xen-access/xen-access.c | 2 +- tools/xcutils/Makefile | 4 +- tools/xenmon/Makefile | 2 + tools/xenmon/xenbaked.c | 13 +- tools/xenpaging/Makefile | 4 +- tools/xenpaging/xenpaging.c | 18 +- tools/xenpaging/xenpaging.h | 3 +- tools/xenstore/Makefile | 5 +- tools/xenstore/xenstored_core.c | 6 +- tools/xenstore/xenstored_domain.c | 25 +-- tools/xentrace/Makefile | 2 + tools/xentrace/xentrace.c | 13 +- 57 files changed, 1413 insertions(+), 920 deletions(-) create mode 100644 tools/libxc/include/xenctrl_compat.h create mode 100644 tools/libxc/xc_evtchn_compat.c create mode 100644 tools/libxenevtchn/Makefile create mode 100644 tools/libxenevtchn/core.c create mode 100644 tools/libxenevtchn/freebsd.c create mode 100644 tools/libxenevtchn/include/xenevtchn.h create mode 100644 tools/libxenevtchn/libxenevtchn.map create mode 100644 tools/libxenevtchn/linux.c create mode 100644 tools/libxenevtchn/minios.c create mode 100644 tools/libxenevtchn/netbsd.c create mode 100644 tools/libxenevtchn/private.h create mode 100644 tools/libxenevtchn/solaris.c diff --git a/.gitignore b/.gitignore index 49935f2..24fab66 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ stubdom/include stubdom/ioemu stubdom/xenstore stubdom/libxentoollog-* +stubdom/libxenevtchn-* stubdom/libxc-* stubdom/lwip-* stubdom/mini-os-* diff --git a/docs/misc/libxenctrl-functions.pandoc b/docs/misc/libxenctrl-functions.pandoc index 60aa6fb..5d09e62 100644 --- a/docs/misc/libxenctrl-functions.pandoc +++ b/docs/misc/libxenctrl-functions.pandoc @@ -1009,9 +1009,6 @@ Gathered by: - xc_pfn_to_mfn - xc_query_page_offline_status - xc_read_image - - xc_suspend_evtchn_init_exclusive - - xc_suspend_evtchn_init_sane - - xc_suspend_evtchn_release - xc_try_bzip2_decode - xc_try_lz4_decode - _xc_try_lzma_decode @@ -1019,6 +1016,12 @@ Gathered by: - xc_try_lzo1x_decode - xc_try_xz_decode +Use privcmd and evtchn device handles: + + - xc_suspend_evtchn_init_exclusive. Used by xen-hptool and libxl. + - xc_suspend_evtchn_init_sane. Unused + - xc_suspend_evtchn_release. Used by xen-hptool and libxl. + # Symbols used by qemu $ nm tools/qemu-xen-dir-remote/i386-softmmu/qemu-system-i386 | grep \\bU.xc_ diff --git a/stubdom/Makefile b/stubdom/Makefile index b8b0d43..b4dd39a 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -318,6 +318,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET) ln -sf $(XEN_ROOT)/tools/libxentoollog/include/*.h . && \ ln -sf $(XEN_ROOT)/tools/libxentoollog/*.c . && \ ln -sf $(XEN_ROOT)/tools/libxentoollog/Makefile . ) + mkdir -p libxenevtchn-$(XEN_TARGET_ARCH)/include + [ -h libxenevtchn-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxenevtchn-$(XEN_TARGET_ARCH) && \ + ln -sf $(XEN_ROOT)/tools/libxenevtchn/*.h . && \ + ln -sf $(XEN_ROOT)/tools/libxenevtchn/include/*.h include/ && \ + ln -sf $(XEN_ROOT)/tools/libxenevtchn/*.c . && \ + ln -sf $(XEN_ROOT)/tools/libxenevtchn/Makefile . ) mkdir -p libxc-$(XEN_TARGET_ARCH) [ -h libxc-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxc-$(XEN_TARGET_ARCH) && \ ln -sf $(XEN_ROOT)/tools/libxc/*.h . && \ @@ -352,12 +358,23 @@ libxentoollog-$(XEN_TARGET_ARCH)/libxentoollog.a: $(NEWLIB_STAMPFILE) CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxentoollog-$(XEN_TARGET_ARCH) ####### +# libxenevtchn +####### + +.PHONY: libxenevtchn +libxenevtchn: libxenevtchn-$(XEN_TARGET_ARCH)/libxenevtchn.a +libxenevtchn-$(XEN_TARGET_ARCH)/libxenevtchn.a: $(NEWLIB_STAMPFILE) + $(MAKE) -C $(XEN_ROOT)/tools/include + $(MAKE) DESTDIR= -C $(MINI_OS) links + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxenevtchn-$(XEN_TARGET_ARCH) + +####### # libxc ####### .PHONY: libxc libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a -libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog cross-zlib +libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog libxenevtchn cross-zlib $(MAKE) -C $(XEN_ROOT)/tools/include $(MAKE) DESTDIR= -C $(MINI_OS) links CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH) diff --git a/tools/Makefile b/tools/Makefile index 777591a..3497c53 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -4,6 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk SUBDIRS-y := SUBDIRS-y += include SUBDIRS-y += libxentoollog +SUBDIRS-y += libxenevtchn SUBDIRS-y += libxc SUBDIRS-$(FLASK_ENABLE) += flask SUBDIRS-y += xenstore @@ -248,8 +249,10 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find --libdir=$(LIBEXEC_LIB) \ --includedir=$(LIBEXEC_INC) \ --source-path=$$source \ - --extra-cflags="-I$(XEN_ROOT)/tools/include \ + --extra-cflags="-DXC_WANT_COMPAT_EVTCHN_API=1 \ + -I$(XEN_ROOT)/tools/include \ -I$(XEN_ROOT)/tools/libxentoollog/include \ + -I$(XEN_ROOT)/tools/libxenevtchn/include \ -I$(XEN_ROOT)/tools/libxc/include \ -I$(XEN_ROOT)/tools/xenstore/include \ -I$(XEN_ROOT)/tools/xenstore/compat/include \ @@ -257,6 +260,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find --extra-ldflags="-L$(XEN_ROOT)/tools/libxc \ -L$(XEN_ROOT)/tools/xenstore \ -Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog \ + -Wl,-rpath-link=$(XEN_ROOT)/tools/libxenevtchn \ $(QEMU_UPSTREAM_RPATH)" \ --bindir=$(LIBEXEC_BIN) \ --datadir=$(SHAREDIR)/qemu-xen \ diff --git a/tools/Rules.mk b/tools/Rules.mk index b8b8559..fd3a7db 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -11,6 +11,7 @@ INSTALL = $(XEN_ROOT)/tools/cross-install XEN_INCLUDE = $(XEN_ROOT)/tools/include XEN_LIBXENTOOLLOG = $(XEN_ROOT)/tools/libxentoollog +XEN_LIBXENEVTCHN = $(XEN_ROOT)/tools/libxenevtchn XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore @@ -39,13 +40,17 @@ CFLAGS_libxentoollog = -I$(XEN_LIBXENTOOLLOG)/include $(CFLAGS_xeninclude) LDLIBS_libxentoollog = $(XEN_LIBXENTOOLLOG)/libxentoollog$(libextension) SHLIB_libxentoollog = -Wl,-rpath-link=$(XEN_LIBXENTOOLLOG) +CFLAGS_libxenevtchn = -I$(XEN_LIBXENEVTCHN)/include $(CFLAGS_xeninclude) +LDLIBS_libxenevtchn = $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension) +SHLIB_libxenevtchn = -Wl,-rpath-link=$(XEN_LIBXENEVTCHN) + CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude) -LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(XEN_LIBXC)/libxenctrl$(libextension) -SHLIB_libxenctrl = $(SHLIB_libxentoollog) -Wl,-rpath-link=$(XEN_LIBXC) +LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenctrl$(libextension) +SHLIB_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBXC) -CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_xeninclude) -LDLIBS_libxenguest = $(XEN_LIBXC)/libxenguest$(libextension) -SHLIB_libxenguest = -Wl,-rpath-link=L$(XEN_LIBXC) +CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude) +LDLIBS_libxenguest = $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenguest$(libextension) +SHLIB_libxenguest = $(SHLIB_libxenevtchn) -Wl,-rpath-link=L$(XEN_LIBXC) CFLAGS_libxenstore = -I$(XEN_XENSTORE)/include $(CFLAGS_xeninclude) LDLIBS_libxenstore = $(XEN_XENSTORE)/libxenstore$(libextension) @@ -56,8 +61,8 @@ LDLIBS_libxenstat = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBXENSTAT)/ SHLIB_libxenstat = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBXENSTAT) CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN) -LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBVCHAN)/libxenvchan$(libextension) -SHLIB_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBVCHAN) +LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) $(XEN_LIBVCHAN)/libxenvchan$(libextension) +SHLIB_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBVCHAN) ifeq ($(debug),y) # Disable optimizations and enable debugging information for macros diff --git a/tools/console/Makefile b/tools/console/Makefile index 71f8088..0141d7f 100644 --- a/tools/console/Makefile +++ b/tools/console/Makefile @@ -3,8 +3,10 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror +CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += $(CFLAGS_libxenstore) +LDLIBS += $(LDLIBS_libxenevtchn) LDLIBS += $(LDLIBS_libxenctrl) LDLIBS += $(LDLIBS_libxenstore) LDLIBS += $(SOCKET_LIBS) diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index ac08b5b..3842362 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -22,6 +22,7 @@ #include "utils.h" #include "io.h" +#include <xenevtchn.h> #include <xenstore.h> #include <xen/io/console.h> #include <xen/grant_table.h> @@ -102,7 +103,7 @@ struct domain { int ring_ref; evtchn_port_or_error_t local_port; evtchn_port_or_error_t remote_port; - xc_evtchn *xce_handle; + xenevtchn_handle *xce_handle; int xce_pollfd_idx; struct xencons_interface *interface; int event_count; @@ -186,7 +187,7 @@ static void buffer_append(struct domain *dom) xen_mb(); intf->out_cons = cons; - xc_evtchn_notify(dom->xce_handle, dom->local_port); + xenevtchn_notify(dom->xce_handle, dom->local_port); /* Get the data to the logfile as early as possible because if * no one is listening on the console pty then it will fill up @@ -585,22 +586,22 @@ static int domain_create_ring(struct domain *dom) dom->local_port = -1; dom->remote_port = -1; if (dom->xce_handle != NULL) - xc_evtchn_close(dom->xce_handle); + xenevtchn_close(dom->xce_handle); /* Opening evtchn independently for each console is a bit * wasteful, but that's how the code is structured... */ - dom->xce_handle = xc_evtchn_open(NULL, 0); + dom->xce_handle = xenevtchn_open(NULL, 0); if (dom->xce_handle == NULL) { err = errno; goto out; } - rc = xc_evtchn_bind_interdomain(dom->xce_handle, + rc = xenevtchn_bind_interdomain(dom->xce_handle, dom->domid, remote_port); if (rc == -1) { err = errno; - xc_evtchn_close(dom->xce_handle); + xenevtchn_close(dom->xce_handle); dom->xce_handle = NULL; goto out; } @@ -610,7 +611,7 @@ static int domain_create_ring(struct domain *dom) if (dom->master_fd == -1) { if (!domain_create_tty(dom)) { err = errno; - xc_evtchn_close(dom->xce_handle); + xenevtchn_close(dom->xce_handle); dom->xce_handle = NULL; dom->local_port = -1; dom->remote_port = -1; @@ -750,7 +751,7 @@ static void shutdown_domain(struct domain *d) watch_domain(d, false); domain_unmap_interface(d); if (d->xce_handle != NULL) - xc_evtchn_close(d->xce_handle); + xenevtchn_close(d->xce_handle); d->xce_handle = NULL; } @@ -840,7 +841,7 @@ static void handle_tty_read(struct domain *dom) } xen_wmb(); intf->in_prod = prod; - xc_evtchn_notify(dom->xce_handle, dom->local_port); + xenevtchn_notify(dom->xce_handle, dom->local_port); } else { domain_close_tty(dom); shutdown_domain(dom); @@ -872,7 +873,7 @@ static void handle_ring_read(struct domain *dom) if (dom->is_dead) return; - if ((port = xc_evtchn_pending(dom->xce_handle)) == -1) + if ((port = xenevtchn_pending(dom->xce_handle)) == -1) return; dom->event_count++; @@ -880,7 +881,7 @@ static void handle_ring_read(struct domain *dom) buffer_append(dom); if (dom->event_count < RATE_LIMIT_ALLOWANCE) - (void)xc_evtchn_unmask(dom->xce_handle, port); + (void)xenevtchn_unmask(dom->xce_handle, port); } static void handle_xs(void) @@ -907,7 +908,7 @@ static void handle_xs(void) free(vec); } -static void handle_hv_logs(xc_evtchn *xce_handle, bool force) +static void handle_hv_logs(xenevtchn_handle *xce_handle, bool force) { static char buffer[1024*16]; char *bufptr = buffer; @@ -915,7 +916,7 @@ static void handle_hv_logs(xc_evtchn *xce_handle, bool force) static uint32_t index = 0; evtchn_port_or_error_t port = -1; - if (!force && ((port = xc_evtchn_pending(xce_handle)) == -1)) + if (!force && ((port = xenevtchn_pending(xce_handle)) == -1)) return; do @@ -939,7 +940,7 @@ static void handle_hv_logs(xc_evtchn *xce_handle, bool force) } while (size == sizeof(buffer)); if (port != -1) - (void)xc_evtchn_unmask(xce_handle, port); + (void)xenevtchn_unmask(xce_handle, port); } static void handle_log_reload(void) @@ -1007,10 +1008,10 @@ void handle_io(void) evtchn_port_or_error_t log_hv_evtchn = -1; int xce_pollfd_idx = -1; int xs_pollfd_idx = -1; - xc_evtchn *xce_handle = NULL; + xenevtchn_handle *xce_handle = NULL; if (log_hv) { - xce_handle = xc_evtchn_open(NULL, 0); + xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) { dolog(LOG_ERR, "Failed to open xce handle: %d (%s)", errno, strerror(errno)); @@ -1019,7 +1020,7 @@ void handle_io(void) log_hv_fd = create_hv_log(); if (log_hv_fd == -1) goto out; - log_hv_evtchn = xc_evtchn_bind_virq(xce_handle, VIRQ_CON_RING); + log_hv_evtchn = xenevtchn_bind_virq(xce_handle, VIRQ_CON_RING); if (log_hv_evtchn == -1) { dolog(LOG_ERR, "Failed to bind to VIRQ_CON_RING: " "%d (%s)", errno, strerror(errno)); @@ -1048,7 +1049,7 @@ void handle_io(void) xs_pollfd_idx = set_fds(xs_fileno(xs), POLLIN|POLLPRI); if (log_hv) - xce_pollfd_idx = set_fds(xc_evtchn_fd(xce_handle), + xce_pollfd_idx = set_fds(xenevtchn_fd(xce_handle), POLLIN|POLLPRI); if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) @@ -1067,7 +1068,7 @@ void handle_io(void) if ((now+5) > d->next_period) { d->next_period = now + RATE_LIMIT_PERIOD; if (d->event_count >= RATE_LIMIT_ALLOWANCE) { - (void)xc_evtchn_unmask(d->xce_handle, d->local_port); + (void)xenevtchn_unmask(d->xce_handle, d->local_port); } d->event_count = 0; } @@ -1083,7 +1084,7 @@ void handle_io(void) if (discard_overflowed_data || !d->buffer.max_capacity || d->buffer.size < d->buffer.max_capacity) { - int evtchn_fd = xc_evtchn_fd(d->xce_handle); + int evtchn_fd = xenevtchn_fd(d->xce_handle); d->xce_pollfd_idx = set_fds(evtchn_fd, POLLIN|POLLPRI); } @@ -1203,7 +1204,7 @@ void handle_io(void) log_hv_fd = -1; } if (xce_handle != NULL) { - xc_evtchn_close(xce_handle); + xenevtchn_close(xce_handle); xce_handle = NULL; } if (xcg_handle != NULL) { diff --git a/tools/libvchan/Makefile b/tools/libvchan/Makefile index 3c50fe6..84128a3 100644 --- a/tools/libvchan/Makefile +++ b/tools/libvchan/Makefile @@ -10,9 +10,9 @@ NODE_OBJS = node.o NODE2_OBJS = node-select.o LIBVCHAN_PIC_OBJS = $(patsubst %.o,%.opic,$(LIBVCHAN_OBJS)) -LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) -$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl) -$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxenctrl) +LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) $(LDLIBS_libxenevtchn) +$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) +$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) MAJOR = 1.0 MINOR = 0 diff --git a/tools/libvchan/init.c b/tools/libvchan/init.c index de10817..fef6c8d 100644 --- a/tools/libvchan/init.c +++ b/tools/libvchan/init.c @@ -217,25 +217,25 @@ static int init_evt_srv(struct libxenvchan *ctrl, int domain, xentoollog_logger { evtchn_port_or_error_t port; - ctrl->event = xc_evtchn_open(logger, 0); + ctrl->event = xenevtchn_open(logger, 0); if (!ctrl->event) return -1; - port = xc_evtchn_bind_unbound_port(ctrl->event, domain); + port = xenevtchn_bind_unbound_port(ctrl->event, domain); if (port < 0) goto fail; ctrl->event_port = port; - if (xc_evtchn_unmask(ctrl->event, ctrl->event_port)) + if (xenevtchn_unmask(ctrl->event, ctrl->event_port)) goto fail; return 0; fail: if (port >= 0) - xc_evtchn_unbind(ctrl->event, port); + xenevtchn_unbind(ctrl->event, port); - xc_evtchn_close(ctrl->event); + xenevtchn_close(ctrl->event); ctrl->event = NULL; return -1; @@ -347,26 +347,26 @@ static int init_evt_cli(struct libxenvchan *ctrl, int domain, xentoollog_logger { evtchn_port_or_error_t port; - ctrl->event = xc_evtchn_open(logger, 0); + ctrl->event = xenevtchn_open(logger, 0); if (!ctrl->event) return -1; - port = xc_evtchn_bind_interdomain(ctrl->event, + port = xenevtchn_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)) + if (xenevtchn_unmask(ctrl->event, ctrl->event_port)) goto fail; return 0; fail: if (port >= 0) - xc_evtchn_unbind(ctrl->event, port); + xenevtchn_unbind(ctrl->event, port); - xc_evtchn_close(ctrl->event); + xenevtchn_close(ctrl->event); ctrl->event = NULL; return -1; diff --git a/tools/libvchan/io.c b/tools/libvchan/io.c index e66bc4e..4bd15ed 100644 --- a/tools/libvchan/io.c +++ b/tools/libvchan/io.c @@ -106,7 +106,7 @@ static inline int send_notify(struct libxenvchan *ctrl, uint8_t bit) notify = ctrl->is_server ? &ctrl->ring->srv_notify : &ctrl->ring->cli_notify; prev = __sync_fetch_and_and(notify, ~bit); if (prev & bit) - return xc_evtchn_notify(ctrl->event, ctrl->event_port); + return xenevtchn_notify(ctrl->event, ctrl->event_port); else return 0; } @@ -195,10 +195,10 @@ int libxenvchan_buffer_space(struct libxenvchan *ctrl) int libxenvchan_wait(struct libxenvchan *ctrl) { - int ret = xc_evtchn_pending(ctrl->event); + int ret = xenevtchn_pending(ctrl->event); if (ret < 0) return -1; - xc_evtchn_unmask(ctrl->event, ret); + xenevtchn_unmask(ctrl->event, ret); return 0; } @@ -351,7 +351,7 @@ int libxenvchan_is_open(struct libxenvchan* ctrl) int libxenvchan_fd_for_select(struct libxenvchan *ctrl) { - return xc_evtchn_fd(ctrl->event); + return xenevtchn_fd(ctrl->event); } void libxenvchan_close(struct libxenvchan *ctrl) @@ -373,8 +373,8 @@ void libxenvchan_close(struct libxenvchan *ctrl) } if (ctrl->event) { if (ctrl->ring) - xc_evtchn_notify(ctrl->event, ctrl->event_port); - xc_evtchn_close(ctrl->event); + xenevtchn_notify(ctrl->event, ctrl->event_port); + xenevtchn_close(ctrl->event); } if (ctrl->is_server) { if (ctrl->gntshr) diff --git a/tools/libvchan/libxenvchan.h b/tools/libvchan/libxenvchan.h index 6365d36..0517dda 100644 --- a/tools/libvchan/libxenvchan.h +++ b/tools/libvchan/libxenvchan.h @@ -45,6 +45,7 @@ #include <xen/io/libxenvchan.h> #include <xen/sys/evtchn.h> +#include <xenevtchn.h> #include <xenctrl.h> struct libxenvchan_ring { @@ -72,7 +73,7 @@ struct libxenvchan { /* Pointer to shared ring page */ struct vchan_interface *ring; /* event channel interface */ - xc_evtchn *event; + xenevtchn_handle *event; uint32_t event_port; /* informative flags: are we acting as server? */ int is_server:1; diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 877ea62..8b69f93 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -47,6 +47,7 @@ CTRL_SRCS-$(CONFIG_FreeBSD) += xc_freebsd.c xc_freebsd_osdep.c CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c +CTRL_SRCS-y += xc_evtchn_compat.c GUEST_SRCS-y := GUEST_SRCS-y += xg_private.c xc_suspend.c @@ -114,6 +115,7 @@ CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE CFLAGS += $(PTHREAD_CFLAGS) CFLAGS += $(CFLAGS_libxentoollog) +CFLAGS += $(CFLAGS_libxenevtchn) CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y)) CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y)) @@ -167,7 +169,7 @@ install: build $(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(libdir) $(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenctrl.so.$(MAJOR) $(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenctrl.so - $(INSTALL_DATA) include/xenctrl.h include/xenctrlosdep.h $(DESTDIR)$(includedir) + $(INSTALL_DATA) include/xenctrl.h include/xenctrl_compat.h include/xenctrlosdep.h $(DESTDIR)$(includedir) $(INSTALL_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir) $(INSTALL_DATA) libxenguest.a $(DESTDIR)$(libdir) $(SYMLINK_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenguest.so.$(MAJOR) @@ -210,7 +212,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR) $(SYMLINK_SHLIB) $< $@ libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS) - $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) # libxenguest @@ -233,7 +235,7 @@ xc_dom_bzimageloader.opic: CFLAGS += $(call zlib-options,D) libxenguest.so.$(MAJOR).$(MINOR): COMPRESSION_LIBS = $(call zlib-options,l) libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so - $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) xenctrl_osdep_ENOSYS.so: $(OSDEP_PIC_OBJS) libxenctrl.so $(CC) $(LDFLAGS) $(SHLIB_LDFLAGS) -o $@ $(OSDEP_PIC_OBJS) $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index f7b6533..90649a9 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -118,7 +118,6 @@ */ typedef struct xc_interface_core xc_interface; -typedef struct xenevtchn_handle xc_evtchn; typedef struct xc_interface_core xc_gnttab; typedef struct xc_interface_core xc_gntshr; @@ -1106,7 +1105,6 @@ int xc_cpupool_movedomain(xc_interface *xch, */ xc_cpumap_t xc_cpupool_freeinfo(xc_interface *xch); - /* * EVENT CHANNEL FUNCTIONS * @@ -1141,101 +1139,7 @@ int xc_evtchn_reset(xc_interface *xch, typedef struct evtchn_status xc_evtchn_status_t; int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status); -/* - * Return a handle to the event channel driver, or NULL on failure, in - * which case errno will be set appropriately. - * - * Note: - * After fork a child process must not use any opened xc evtchn - * handle inherited from their parent. They must open a new handle if - * they want to interact with xc. - * - * Before Xen pre-4.1 this function would sometimes report errors with perror. - */ -xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, - unsigned open_flags); -/* - * Close a handle previously allocated with xc_evtchn_open(). - */ -int xc_evtchn_close(xc_evtchn *xce); - -/* - * Return an fd that can be select()ed on. - * - * Note that due to bugs, setting this fd to non blocking may not - * work: you would hope that it would result in xc_evtchn_pending - * failing with EWOULDBLOCK if there are no events signaled, but in - * fact it may block. (Bug is present in at least Linux 3.12, and - * perhaps on other platforms or later version.) - * - * To be safe, you must use poll() or select() before each call to - * xc_evtchn_pending. If you have multiple threads (or processes) - * sharing a single xce handle this will not work, and there is no - * straightforward workaround. Please design your program some other - * way. - */ -int xc_evtchn_fd(xc_evtchn *xce); - -/* - * Notify the given event channel. Returns -1 on failure, in which case - * errno will be set appropriately. - */ -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port); - -/* - * Returns a new event port awaiting interdomain connection from the given - * domain ID, or -1 on failure, in which case errno will be set appropriately. - */ -evtchn_port_or_error_t -xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid); - -/* - * Returns a new event port bound to the remote port for the given domain ID, - * or -1 on failure, in which case errno will be set appropriately. - */ -evtchn_port_or_error_t -xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, - evtchn_port_t remote_port); - -/* - * Bind an event channel to the given VIRQ. Returns the event channel bound to - * the VIRQ, or -1 on failure, in which case errno will be set appropriately. - */ -evtchn_port_or_error_t -xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq); - -/* - * Unbind the given event channel. Returns -1 on failure, in which case errno - * will be set appropriately. - */ -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port); - -/* - * Return the next event channel to become pending, or -1 on failure, in which - * case errno will be set appropriately. - * - * At the hypervisor level the event channel will have been masked, - * and then cleared, by the underlying machinery (evtchn kernel - * driver, or equivalent). So if the event channel is signaled again - * after it is returned here, it will be queued up, and delivered - * again after you unmask it. (See the documentation in the Xen - * public header event_channel.h.) - * - * On receiving the notification from xc_evtchn_pending, you should - * normally: check (by other means) what work needs doing; do the - * necessary work (if any); unmask the event channel with - * xc_evtchn_unmask (if you want to receive any further - * notifications). - */ -evtchn_port_or_error_t -xc_evtchn_pending(xc_evtchn *xce); - -/* - * Unmask the given event channel. Returns -1 on failure, in which case errno - * will be set appropriately. - */ -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port); int xc_physdev_pci_access_modify(xc_interface *xch, uint32_t domid, @@ -2785,6 +2689,9 @@ int xc_psr_cmt_get_data(xc_interface *xch, uint32_t rmid, uint32_t cpu, int xc_psr_cmt_enabled(xc_interface *xch); #endif +/* Compat shims */ +#include "xenctrl_compat.h" + #endif /* XENCTRL_H */ /* diff --git a/tools/libxc/include/xenctrl_compat.h b/tools/libxc/include/xenctrl_compat.h new file mode 100644 index 0000000..48daeb2 --- /dev/null +++ b/tools/libxc/include/xenctrl_compat.h @@ -0,0 +1,48 @@ +/* + * Compat shims for use of 3rd party consumers of libxenctrl + * functionality which has been split into separate libraries. + * + * New code should use the separate libraries. + * + * Each interface must be opted-into separately by defining: + * + * XC_WANT_COMPAT_EVTCHN_API + * - Functions relating to /dev/xen/evtchn + */ +#ifndef XENCTRL_COMPAT_H +#define XENCTRL_COMPAT_H + +#ifdef XC_WANT_COMPAT_EVTCHN_API + +typedef struct xenevtchn_handle xc_evtchn; + +xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, + unsigned open_flags); +int xc_evtchn_close(xc_evtchn *xce); +int xc_evtchn_fd(xc_evtchn *xce); +int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port); +evtchn_port_or_error_t +xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid); +evtchn_port_or_error_t +xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, + evtchn_port_t remote_port); +evtchn_port_or_error_t +xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq); +int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port); +evtchn_port_or_error_t +xc_evtchn_pending(xc_evtchn *xce); +int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port); + +#endif /* XC_WANT_COMPAT_EVTCHN_API */ + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h index 7581263..6fcdb4f 100644 --- a/tools/libxc/include/xenguest.h +++ b/tools/libxc/include/xenguest.h @@ -23,6 +23,8 @@ #ifndef XENGUEST_H #define XENGUEST_H +#include <xenevtchn.h> + #define XC_NUMA_NO_NODE (~0U) #define XCFLAGS_LIVE (1 << 0) @@ -281,18 +283,18 @@ int xc_hvm_build_target_mem(xc_interface *xch, * Sets *lockfd to -1. * Has deallocated everything even on error. */ -int xc_suspend_evtchn_release(xc_interface *xch, xc_evtchn *xce, int domid, int suspend_evtchn, int *lockfd); +int xc_suspend_evtchn_release(xc_interface *xch, xenevtchn_handle *xce, int domid, int suspend_evtchn, int *lockfd); /** * This function eats the initial notification. * xce must not be used for anything else * See xc_suspend_evtchn_init_sane re lockfd. */ -int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce, +int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xenevtchn_handle *xce, int domid, int port, int *lockfd); /* xce must not be used for anything else */ -int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn); +int xc_await_suspend(xc_interface *xch, xenevtchn_handle *xce, int suspend_evtchn); /** * The port will be signaled immediately after this call @@ -301,7 +303,7 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn); * and fed to xc_suspend_evtchn_release. (On error *lockfd is * undefined and xc_suspend_evtchn_release is not allowed.) */ -int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce, +int xc_suspend_evtchn_init_sane(xc_interface *xch, xenevtchn_handle *xce, int domid, int port, int *lockfd); int xc_get_bit_size(xc_interface *xch, diff --git a/tools/libxc/xc_evtchn_compat.c b/tools/libxc/xc_evtchn_compat.c new file mode 100644 index 0000000..5d3e4ba --- /dev/null +++ b/tools/libxc/xc_evtchn_compat.c @@ -0,0 +1,75 @@ +/* + * Compat shims for use of 3rd party consumers of libxenctrl xc_evtchn + * functionality which has been split into separate libraries. + */ + +#include <xenevtchn.h> + +#define XC_WANT_COMPAT_EVTCHN_API +#include "xenctrl.h" + +xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, + unsigned open_flags) +{ + return xenevtchn_open(logger, open_flags); +} + +int xc_evtchn_close(xc_evtchn *xce) +{ + return xenevtchn_close(xce); +} + +int xc_evtchn_fd(xc_evtchn *xce) +{ + return xenevtchn_fd(xce); +} + +int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) +{ + return xenevtchn_notify(xce, port); +} + +evtchn_port_or_error_t +xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) +{ + return xenevtchn_bind_unbound_port(xce, domid); +} + +evtchn_port_or_error_t +xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, + evtchn_port_t remote_port) +{ + return xenevtchn_bind_interdomain(xce, domid, remote_port); +} + +evtchn_port_or_error_t +xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) +{ + return xenevtchn_bind_virq(xce, virq); +} + +int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) +{ + return xenevtchn_unbind(xce, port); +} + +evtchn_port_or_error_t +xc_evtchn_pending(xc_evtchn *xce) +{ + return xenevtchn_pending(xce); +} + +int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) +{ + return xenevtchn_unmask(xce, port); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xc_freebsd_osdep.c b/tools/libxc/xc_freebsd_osdep.c index 7274274..57a7d89 100644 --- a/tools/libxc/xc_freebsd_osdep.c +++ b/tools/libxc/xc_freebsd_osdep.c @@ -32,13 +32,11 @@ #include <sys/ioctl.h> #include <xen/memory.h> -#include <xen/sys/evtchn.h> #include "xenctrl.h" #include "xenctrlosdep.h" #define PRIVCMD_DEV "/dev/xen/privcmd" -#define EVTCHN_DEV "/dev/xen/evtchn" #define PERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m \ " (%d = %s)", ## _a , errno, xc_strerror(xch, errno)) @@ -252,105 +250,6 @@ static struct xc_osdep_ops freebsd_privcmd_ops = { }, }; -/*-------------------------- Evtchn device interface -------------------------*/ -int osdep_evtchn_open(xc_evtchn *xce) -{ - int fd = open(EVTCHN_DEV, O_RDWR); - if ( fd == -1 ) - return -1; - xce->fd = fd; - return 0; -} - -int osdep_evtchn_close(xc_evtchn *xce) -{ - if ( xce->fd == -1 ) - return 0; - - return close(xce->fd); -} - -int xc_evtchn_fd(xc_evtchn *xce) -{ - return xce->fd; -} - -/*------------------------------ Evtchn interface ----------------------------*/ -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_notify notify; - - notify.port = port; - - return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} - -evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) -{ - int ret, fd = xce->fd; - struct ioctl_evtchn_bind_unbound_port bind; - - bind.remote_domain = domid; - - ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); - return ( ret == 0 ) ? bind.port : ret; -} - -evtchn_port_or_error_t -xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, evtchn_port_t remote_port) -{ - int ret, fd = xce->fd; - struct ioctl_evtchn_bind_interdomain bind; - - bind.remote_domain = domid; - bind.remote_port = remote_port; - - ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); - return ( ret == 0 ) ? bind.port : ret; -} - -evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) -{ - int ret, fd = xce->fd; - struct ioctl_evtchn_bind_virq bind; - - bind.virq = virq; - - ret = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - return ( ret == 0 ) ? bind.port : ret; -} - -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_unbind unbind; - - unbind.port = port; - - return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); -} - -evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) -{ - int fd = xce->fd; - evtchn_port_t port; - - if ( read(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - - return port; -} - -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - - if ( write(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - return 0; -} - /*---------------------------- FreeBSD interface -----------------------------*/ static struct xc_osdep_ops * freebsd_osdep_init(xc_interface *xch, enum xc_osdep_type type) diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c index 3c96c76..2230e44 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -32,7 +32,6 @@ #include <sys/ioctl.h> #include <xen/memory.h> -#include <xen/sys/evtchn.h> #include <xen/sys/gntdev.h> #include <xen/sys/gntalloc.h> @@ -456,100 +455,6 @@ static struct xc_osdep_ops linux_privcmd_ops = { #define DEVXEN "/dev/xen/" -int osdep_evtchn_open(xc_evtchn *xce) -{ - int fd = open(DEVXEN "evtchn", O_RDWR); - if ( fd == -1 ) - return -1; - xce->fd = fd; - return 0; -} - -int osdep_evtchn_close(xc_evtchn *xce) -{ - if ( xce->fd == -1 ) - return 0; - - return close(xce->fd); -} - -int xc_evtchn_fd(xc_evtchn *xce) -{ - return xce->fd; -} - -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_notify notify; - - notify.port = port; - - return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} - -evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_unbound_port bind; - - bind.remote_domain = domid; - - return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); -} - -evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, - evtchn_port_t remote_port) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_interdomain bind; - - bind.remote_domain = domid; - bind.remote_port = remote_port; - - return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); -} - -evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_virq bind; - - bind.virq = virq; - - return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); -} - -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_unbind unbind; - - unbind.port = port; - - return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); -} - -evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) -{ - int fd = xce->fd; - evtchn_port_t port; - - if ( read(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - - return port; -} - -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - - if ( write(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - return 0; -} - static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg) { int fd = open(DEVXEN "gntdev", O_RDWR); diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index e9c4d8b..7878cfa 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -20,14 +20,11 @@ */ #undef NDEBUG -#include "xen-external/bsd-sys-queue.h" #include <mini-os/types.h> #include <mini-os/os.h> #include <mini-os/mm.h> #include <mini-os/lib.h> #include <mini-os/gntmap.h> -#include <mini-os/events.h> -#include <mini-os/wait.h> #include <sys/mman.h> #include <xen/memory.h> @@ -42,13 +39,9 @@ #include "xc_private.h" void minios_interface_close_fd(int fd); -void minios_evtchn_close_fd(int fd); void minios_gnttab_close_fd(int fd); extern void minios_interface_close_fd(int fd); -extern void minios_evtchn_close_fd(int fd); - -extern struct wait_queue_head event_queue; static xc_osdep_handle minios_privcmd_open(xc_interface *xch) { @@ -198,220 +191,6 @@ static struct xc_osdep_ops minios_privcmd_ops = { }, }; - -/* XXX Note: This is not threadsafe */ -static struct evtchn_port_info* port_alloc(int fd) { - struct evtchn_port_info *port_info; - port_info = malloc(sizeof(struct evtchn_port_info)); - if (port_info == NULL) - return NULL; - port_info->pending = 0; - port_info->port = -1; - port_info->bound = 0; - - LIST_INSERT_HEAD(&files[fd].evtchn.ports, port_info, list); - return port_info; -} - -static void port_dealloc(struct evtchn_port_info *port_info) { - if (port_info->bound) - unbind_evtchn(port_info->port); - LIST_REMOVE(port_info, list); - free(port_info); -} - -int osdep_evtchn_open(xc_evtchn *xce) -{ - int fd = alloc_fd(FTYPE_EVTCHN); - if ( fd == -1 ) - return -1; - LIST_INIT(&files[fd].evtchn.ports); - xce->fd = fd; - printf("evtchn_open() -> %d\n", fd); - return 0; -} - -int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h) -{ - if ( xce->fd == -1 ) - return 0; - - return close(xce->fd); -} - -void minios_evtchn_close_fd(int fd) -{ - struct evtchn_port_info *port_info, *tmp; - LIST_FOREACH_SAFE(port_info, &files[fd].evtchn.ports, list, tmp) - port_dealloc(port_info); - - files[fd].type = FTYPE_NONE; -} - -int xc_evtchn_fd(xc_evtchn *xce) -{ - return xce->fd; -} - -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) -{ - int ret; - - ret = notify_remote_via_evtchn(port); - - if (ret < 0) { - errno = -ret; - ret = -1; - } - return ret; -} - -static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) -{ - int fd = (int)(intptr_t)data; - struct evtchn_port_info *port_info; - assert(files[fd].type == FTYPE_EVTCHN); - mask_evtchn(port); - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { - if (port_info->port == port) - goto found; - } - printk("Unknown port for handle %d\n", fd); - return; - - found: - port_info->pending = 1; - files[fd].read = 1; - wake_up(&event_queue); -} - -evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) -{ - int fd = xce->fd; - struct evtchn_port_info *port_info; - int ret; - evtchn_port_t port; - - assert(get_current() == main_thread); - port_info = port_alloc(fd); - if (port_info == NULL) - return -1; - - printf("xc_evtchn_bind_unbound_port(%d)", domid); - ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)fd, &port); - printf(" = %d\n", ret); - - if (ret < 0) { - port_dealloc(port_info); - errno = -ret; - return -1; - } - port_info->bound = 1; - port_info->port = port; - unmask_evtchn(port); - return port; -} - -evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, - evtchn_port_t remote_port) -{ - int fd = xce->fd; - struct evtchn_port_info *port_info; - evtchn_port_t local_port; - int ret; - - assert(get_current() == main_thread); - port_info = port_alloc(fd); - if (port_info == NULL) - return -1; - - printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port); - ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)fd, &local_port); - printf(" = %d\n", ret); - - if (ret < 0) { - port_dealloc(port_info); - errno = -ret; - return -1; - } - port_info->bound = 1; - port_info->port = local_port; - unmask_evtchn(local_port); - return local_port; -} - -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct evtchn_port_info *port_info; - - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { - if (port_info->port == port) { - port_dealloc(port_info); - return 0; - } - } - printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, fd); - errno = EINVAL; - return -1; -} - -evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) -{ - int fd = xce->fd; - struct evtchn_port_info *port_info; - evtchn_port_t port; - - assert(get_current() == main_thread); - port_info = port_alloc(fd); - if (port_info == NULL) - return -1; - - printf("xc_evtchn_bind_virq(%d)", virq); - port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)fd); - - if (port < 0) { - port_dealloc(port_info); - errno = -port; - return -1; - } - port_info->bound = 1; - port_info->port = port; - unmask_evtchn(port); - return port; -} - -evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) -{ - int fd = xce->fd; - struct evtchn_port_info *port_info; - unsigned long flags; - evtchn_port_t ret = -1; - - local_irq_save(flags); - files[fd].read = 0; - - LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { - if (port_info->port != -1 && port_info->pending) { - if (ret == -1) { - ret = port_info->port; - port_info->pending = 0; - } else { - files[fd].read = 1; - break; - } - } - } - local_irq_restore(flags); - return ret; -} - -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) -{ - unmask_evtchn(port); - return 0; -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c index f9bc100..48fd5d7 100644 --- a/tools/libxc/xc_netbsd.c +++ b/tools/libxc/xc_netbsd.c @@ -20,7 +20,6 @@ #include "xc_private.h" -#include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> #include <malloc.h> @@ -224,114 +223,6 @@ static struct xc_osdep_ops netbsd_privcmd_ops = { }, }; -#define EVTCHN_DEV_NAME "/dev/xenevt" - -int osdep_evtchn_open(xc_evtchn *xce) -{ - int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); - if ( fd == -1 ) - return -1; - xce->fd = fd; - return 0; -} - -int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h) -{ - if ( xce->fd == -1 ) - return 0; - - return close(xce->fd); -} - -int xc_evtchn_fd(xc_evtchn *xce) -{ - return xce->fd; -} - -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_notify notify; - - notify.port = port; - - return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} - -evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn * xce, int domid) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_unbound_port bind; - int ret; - - bind.remote_domain = domid; - - ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); - if (ret == 0) - return bind.port; - else - return -1; -} - -evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, - evtchn_port_t remote_port) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_interdomain bind; - int ret; - - bind.remote_domain = domid; - bind.remote_port = remote_port; - - ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); - if (ret == 0) - return bind.port; - else - return -1; -} - -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_unbind unbind; - - unbind.port = port; - - return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); -} - -evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_virq bind; - int err; - - bind.virq = virq; - - err = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); - if (err) - return -1; - else - return bind.port; -} - -evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) -{ - int fd = xce->fd; - evtchn_port_t port; - - if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 ) - return -1; - - return port; -} - -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - return write_exact(fd, (char *)&port, sizeof(port)); -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 9f0ada7..375430c 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -252,46 +252,6 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall) return xch->ops->u.privcmd.hypercall(xch, xch->ops_handle, hypercall); } -xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, unsigned open_flags) -{ - xc_evtchn *xce = malloc(sizeof(*xce)); - int rc; - - if (!xce) return NULL; - - xce->fd = -1; - xce->logger = logger; - xce->logger_tofree = NULL; - - if (!xce->logger) { - xce->logger = xce->logger_tofree = - (xentoollog_logger*) - xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); - if (!xce->logger) goto err; - } - - rc = osdep_evtchn_open(xce); - if ( rc < 0 ) goto err; - - return xce; - -err: - osdep_evtchn_close(xce); - xtl_logger_destroy(xce->logger_tofree); - free(xce); - return NULL; -} - -int xc_evtchn_close(xc_evtchn *xce) -{ - int rc; - - rc = osdep_evtchn_close(xce); - xtl_logger_destroy(xce->logger_tofree); - free(xce); - return rc; -} - xc_gnttab *xc_gnttab_open(xentoollog_logger *logger, unsigned open_flags) { diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 4c66766..61f2f45 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -124,13 +124,6 @@ struct xc_interface_core { xc_osdep_handle ops_handle; /* opaque data for xc_osdep_ops */ }; -struct xenevtchn_handle { - xentoollog_logger *logger, *logger_tofree; - int fd; -}; -int osdep_evtchn_open(xc_evtchn *xce); -int osdep_evtchn_close(xc_evtchn *xce); - void xc_report_error(xc_interface *xch, int code, const char *fmt, ...) __attribute__((format(printf,3,4))); void xc_reportv(xc_interface *xch, xentoollog_logger *lg, xentoollog_level, diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c index 8867d97..182bd7d 100644 --- a/tools/libxc/xc_solaris.c +++ b/tools/libxc/xc_solaris.c @@ -21,7 +21,6 @@ #include "xc_private.h" #include <xen/memory.h> -#include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> #include <malloc.h> @@ -195,102 +194,6 @@ static struct xc_osdep_ops solaris_privcmd_ops = { }, }; -int osdep_evtchn_open(xc_evtchn *xce) -{ - int fd; - - if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 ) - { - PERROR("Could not open event channel interface"); - return -1; - } - - xce->fd = fd; - return 0; -} - -int osdep_evtchn_close(xc_evtchn *xce) -{ - if ( xce->fd == -1 ) - return 0; - - return close(xce->fd); -} - -int xc_evtchn_fd(xc_evtchn *xce) -{ - return xce->fd; -} - -int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_notify notify; - - notify.port = port; - - return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} - -evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_unbound_port bind; - - bind.remote_domain = domid; - - return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); -} - -evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, - evtchn_port_t remote_port) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_interdomain bind; - - bind.remote_domain = domid; - bind.remote_port = remote_port; - - return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); -} - -evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq) -{ - int fd = xce->fd; - struct ioctl_evtchn_bind_virq bind; - - bind.virq = virq; - - return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); -} - -int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - struct ioctl_evtchn_unbind unbind; - - unbind.port = port; - - return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); -} - -evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce) -{ - int fd = xce->fd; - evtchn_port_t port; - - if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 ) - return -1; - - return port; -} - -int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port) -{ - int fd = xce->fd; - return write_exact(fd, (char *)&port, sizeof(port)); -} - /* Optionally flush file to disk and discard page cache */ void discard_file_cache(xc_interface *xch, int fd, int flush) { diff --git a/tools/libxc/xc_suspend.c b/tools/libxc/xc_suspend.c index e22f4ac..139edb4 100644 --- a/tools/libxc/xc_suspend.c +++ b/tools/libxc/xc_suspend.c @@ -17,6 +17,8 @@ #include <unistd.h> #include <fcntl.h> +#include <xenevtchn.h> + #include "xc_private.h" #include "xenguest.h" @@ -125,12 +127,12 @@ static int unlock_suspend_event(xc_interface *xch, int domid, int *lockfd) return -1; } -int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn) +int xc_await_suspend(xc_interface *xch, xenevtchn_handle *xce, int suspend_evtchn) { int rc; do { - rc = xc_evtchn_pending(xce); + rc = xenevtchn_pending(xce); if (rc < 0) { ERROR("error polling suspend notification channel: %d", rc); return -1; @@ -138,7 +140,7 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn) } while (rc != suspend_evtchn); /* harmless for one-off suspend */ - if (xc_evtchn_unmask(xce, suspend_evtchn) < 0) + if (xenevtchn_unmask(xce, suspend_evtchn) < 0) ERROR("failed to unmask suspend notification channel: %d", rc); return 0; @@ -146,16 +148,16 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn) /* Internal callers are allowed to call this with suspend_evtchn<0 * but *lockfd>0. */ -int xc_suspend_evtchn_release(xc_interface *xch, xc_evtchn *xce, +int xc_suspend_evtchn_release(xc_interface *xch, xenevtchn_handle *xce, int domid, int suspend_evtchn, int *lockfd) { if (suspend_evtchn >= 0) - xc_evtchn_unbind(xce, suspend_evtchn); + xenevtchn_unbind(xce, suspend_evtchn); return unlock_suspend_event(xch, domid, lockfd); } -int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce, +int xc_suspend_evtchn_init_sane(xc_interface *xch, xenevtchn_handle *xce, int domid, int port, int *lockfd) { int rc, suspend_evtchn = -1; @@ -165,7 +167,7 @@ int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce, goto cleanup; } - suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); + suspend_evtchn = xenevtchn_bind_interdomain(xce, domid, port); if (suspend_evtchn < 0) { ERROR("failed to bind suspend event channel: %d", suspend_evtchn); goto cleanup; @@ -185,7 +187,7 @@ cleanup: return -1; } -int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce, +int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xenevtchn_handle *xce, int domid, int port, int *lockfd) { int suspend_evtchn; diff --git a/tools/libxenevtchn/Makefile b/tools/libxenevtchn/Makefile new file mode 100644 index 0000000..b968b36 --- /dev/null +++ b/tools/libxenevtchn/Makefile @@ -0,0 +1,65 @@ +XEN_ROOT = $(CURDIR)/../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1 +MINOR = 0 +SHLIB_LDFLAGS += -Wl,--version-script=libxenevtchn.map + +CFLAGS += -Werror -Wmissing-prototypes +CFLAGS += -I./include $(CFLAGS_xeninclude) +CFLAGS += $(CFLAGS_libxentoollog) + +SRCS-y += core.c +SRCS-$(CONFIG_Linux) += linux.c +SRCS-$(CONFIG_FreeBSD) += freebsd.c +SRCS-$(CONFIG_SunOS) += solaris.c +SRCS-$(CONFIG_NetBSD) += netbsd.c +SRCS-$(CONFIG_MiniOS) += minios.c + +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y)) + +LIB := libxenevtchn.a +ifneq ($(nosharedlibs),y) +LIB += libxenevtchn.so +endif + +.PHONY: all +all: build + +.PHONY: build +build: + $(MAKE) libs + +.PHONY: libs +libs: $(LIB) + + +libxenevtchn.a: $(LIB_OBJS) + $(AR) rc $@ $^ + +libxenevtchn.so: libxenevtchn.so.$(MAJOR) + $(SYMLINK_SHLIB) $< $@ +libxenevtchn.so.$(MAJOR): libxenevtchn.so.$(MAJOR).$(MINOR) + $(SYMLINK_SHLIB) $< $@ + +libxenevtchn.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxenevtchn.map + $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenevtchn.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(APPEND_LDFLAGS) + +.PHONY: install +install: build + $(INSTALL_DIR) $(DESTDIR)$(libdir) + $(INSTALL_DIR) $(DESTDIR)$(includedir) + $(INSTALL_SHLIB) libxenevtchn.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir) + $(INSTALL_DATA) libxenevtchn.a $(DESTDIR)$(libdir) + $(SYMLINK_SHLIB) libxenevtchn.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenevtchn.so.$(MAJOR) + $(SYMLINK_SHLIB) libxenevtchn.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenevtchn.so + $(INSTALL_DATA) include/xenevtchn.h $(DESTDIR)$(includedir) + +.PHONY: TAGS +TAGS: + etags -t *.c *.h + +.PHONY: clean +clean: + rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS) diff --git a/tools/libxenevtchn/core.c b/tools/libxenevtchn/core.c new file mode 100644 index 0000000..89b41c9 --- /dev/null +++ b/tools/libxenevtchn/core.c @@ -0,0 +1,60 @@ +/* + * 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 + */ + +#include <unistd.h> +#include <stdlib.h> + +#include "private.h" + +xenevtchn_handle *xenevtchn_open(xentoollog_logger *logger, unsigned open_flags) +{ + xenevtchn_handle *xce = malloc(sizeof(*xce)); + int rc; + + if (!xce) return NULL; + + xce->fd = -1; + xce->logger = logger; + xce->logger_tofree = NULL; + + if (!xce->logger) { + xce->logger = xce->logger_tofree = + (xentoollog_logger*) + xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); + if (!xce->logger) goto err; + } + + rc = osdep_evtchn_open(xce); + if ( rc < 0 ) goto err; + + return xce; + +err: + osdep_evtchn_close(xce); + xtl_logger_destroy(xce->logger_tofree); + free(xce); + return NULL; +} + +int xenevtchn_close(xenevtchn_handle *xce) +{ + int rc; + + rc = osdep_evtchn_close(xce); + xtl_logger_destroy(xce->logger_tofree); + free(xce); + return rc; +} diff --git a/tools/libxenevtchn/freebsd.c b/tools/libxenevtchn/freebsd.c new file mode 100644 index 0000000..e1fb38e --- /dev/null +++ b/tools/libxenevtchn/freebsd.c @@ -0,0 +1,122 @@ + /****************************************************************************** + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * 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. + * + * Split off from xc_freebsd_osdep.c + */ + +#include <fcntl.h> + +#include <xen/sys/evtchn.h> + +#include "private.h" + +#define EVTCHN_DEV "/dev/xen/evtchn" + +int osdep_evtchn_open(xenevtchn_handle *xce) +{ + int fd = open(EVTCHN_DEV, O_RDWR); + if ( fd == -1 ) + return -1; + xce->fd = fd; + return 0; +} + +int osdep_evtchn_close(xenevtchn_handle *xce) +{ + if ( xce->fd == -1 ) + return 0; + + return close(xce->fd); +} + +int xenevtchn_fd(xenevtchn_handle *xce) +{ + return xce->fd; +} + +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid) +{ + int ret, fd = xce->fd; + struct ioctl_evtchn_bind_unbound_port bind; + + bind.remote_domain = domid; + + ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); + return ( ret == 0 ) ? bind.port : ret; +} + +evtchn_port_or_error_t +xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, evtchn_port_t remote_port) +{ + int ret, fd = xce->fd; + struct ioctl_evtchn_bind_interdomain bind; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + return ( ret == 0 ) ? bind.port : ret; +} + +evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq) +{ + int ret, fd = xce->fd; + struct ioctl_evtchn_bind_virq bind; + + bind.virq = virq; + + ret = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); + return ( ret == 0 ) ? bind.port : ret; +} + +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce) +{ + int fd = xce->fd; + evtchn_port_t port; + + if ( read(fd, &port, sizeof(port)) != sizeof(port) ) + return -1; + + return port; +} + +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + + if ( write(fd, &port, sizeof(port)) != sizeof(port) ) + return -1; + return 0; +} diff --git a/tools/libxenevtchn/include/xenevtchn.h b/tools/libxenevtchn/include/xenevtchn.h new file mode 100644 index 0000000..d969994 --- /dev/null +++ b/tools/libxenevtchn/include/xenevtchn.h @@ -0,0 +1,154 @@ +/* + * 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. + * + * Split off from: + * xenctrl.h + * + * A library for low-level access to the Xen control interfaces. + * + * Copyright (c) 2003-2004, K A Fraser. + */ + +#ifndef XENEVTCHN_H +#define XENEVTCHN_H + +#include <stdint.h> + +#include <xen/event_channel.h> + +/* A port identifier is guaranteed to fit in 31 bits. */ +typedef int evtchn_port_or_error_t; + +typedef struct xenevtchn_handle xenevtchn_handle; + +/* Callers who don't care don't need to #include <xentoollog.h> */ +typedef struct xentoollog_logger xentoollog_logger; + +/* + * EVENT CHANNEL FUNCTIONS + * + * None of these do any logging. + */ + +/* + * Return a handle to the event channel driver, or NULL on failure, in + * which case errno will be set appropriately. + * + * Note: + * After fork a child process must not use any opened xc evtchn + * handle inherited from their parent. They must open a new handle if + * they want to interact with xc. + * + * Before Xen pre-4.1 this function would sometimes report errors with perror. + */ +/* Currently no flags are defined */ +xenevtchn_handle *xenevtchn_open(xentoollog_logger *logger, unsigned open_flags); + +/* + * Close a handle previously allocated with xenevtchn_open(). + */ +int xenevtchn_close(xenevtchn_handle *xce); + +/* + * Return an fd that can be select()ed on. + * + * Note that due to bugs, setting this fd to non blocking may not + * work: you would hope that it would result in xenevtchn_pending + * failing with EWOULDBLOCK if there are no events signaled, but in + * fact it may block. (Bug is present in at least Linux 3.12, and + * perhaps on other platforms or later version.) + * + * To be safe, you must use poll() or select() before each call to + * xenevtchn_pending. If you have multiple threads (or processes) + * sharing a single xce handle this will not work, and there is no + * straightforward workaround. Please design your program some other + * way. + */ +int xenevtchn_fd(xenevtchn_handle *xce); + +/* + * Notify the given event channel. Returns -1 on failure, in which case + * errno will be set appropriately. + */ +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port); + +/* + * Returns a new event port awaiting interdomain connection from the given + * domain ID, or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_or_error_t +xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid); + +/* + * Returns a new event port bound to the remote port for the given domain ID, + * or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_or_error_t +xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, + evtchn_port_t remote_port); + +/* + * Bind an event channel to the given VIRQ. Returns the event channel bound to + * the VIRQ, or -1 on failure, in which case errno will be set appropriately. + */ +evtchn_port_or_error_t +xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq); + +/* + * Unbind the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port); + +/* + * Return the next event channel to become pending, or -1 on failure, in which + * case errno will be set appropriately. + * + * At the hypervisor level the event channel will have been masked, + * and then cleared, by the underlying machinery (evtchn kernel + * driver, or equivalent). So if the event channel is signaled again + * after it is returned here, it will be queued up, and delivered + * again after you unmask it. (See the documentation in the Xen + * public header event_channel.h.) + * + * On receiving the notification from xenevtchn_pending, you should + * normally: check (by other means) what work needs doing; do the + * necessary work (if any); unmask the event channel with + * xenevtchn_unmask (if you want to receive any further + * notifications). + */ +evtchn_port_or_error_t +xenevtchn_pending(xenevtchn_handle *xce); + +/* + * Unmask the given event channel. Returns -1 on failure, in which case errno + * will be set appropriately. + */ +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port); + +#ifdef XENEVTCHN_XC_COMPAT +typedef struct xc_interface_core xc_evtchn; + + +#endif + +#endif + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ + diff --git a/tools/libxenevtchn/libxenevtchn.map b/tools/libxenevtchn/libxenevtchn.map new file mode 100644 index 0000000..1437940 --- /dev/null +++ b/tools/libxenevtchn/libxenevtchn.map @@ -0,0 +1,14 @@ +VERS_1.0 { + global: + xenevtchn_fd; + xenevtchn_bind_unbound_port; + xenevtchn_unbind; + xenevtchn_unmask; + xenevtchn_notify; + xenevtchn_bind_interdomain; + xenevtchn_bind_virq; + xenevtchn_open; + xenevtchn_close; + xenevtchn_pending; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libxenevtchn/linux.c b/tools/libxenevtchn/linux.c new file mode 100644 index 0000000..185244c --- /dev/null +++ b/tools/libxenevtchn/linux.c @@ -0,0 +1,133 @@ +/* + * 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. + * + * Split out from xc_linus_osdep.c: + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> + +#include <sys/ioctl.h> + +#include <xen/sys/evtchn.h> + +#include "private.h" + +int osdep_evtchn_open(xenevtchn_handle *xce) +{ + int fd = open("/dev/xen/evtchn", O_RDWR); + if ( fd == -1 ) + return -1; + xce->fd = fd; + return 0; +} + +int osdep_evtchn_close(xenevtchn_handle *xce) +{ + if ( xce->fd == -1 ) + return 0; + + return close(xce->fd); +} + +int xenevtchn_fd(xenevtchn_handle *xce) +{ + return xce->fd; +} + +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, + int domid) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_unbound_port bind; + + bind.remote_domain = domid; + + return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); +} + +evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, + int domid, + evtchn_port_t remote_port) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_interdomain bind; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); +} + +evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, + unsigned int virq) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_virq bind; + + bind.virq = virq; + + return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); +} + +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce) +{ + int fd = xce->fd; + evtchn_port_t port; + + if ( read(fd, &port, sizeof(port)) != sizeof(port) ) + return -1; + + return port; +} + +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + + if ( write(fd, &port, sizeof(port)) != sizeof(port) ) + return -1; + return 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxenevtchn/minios.c b/tools/libxenevtchn/minios.c new file mode 100644 index 0000000..c776822 --- /dev/null +++ b/tools/libxenevtchn/minios.c @@ -0,0 +1,257 @@ +/****************************************************************************** + * + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>. + * All rights reserved. + * Use is subject to license terms. + * + * 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. + * + * Split off from xc_minios.c + */ + +#include "xen-external/bsd-sys-queue.h" +#include <mini-os/types.h> +#include <mini-os/os.h> +#include <mini-os/lib.h> +#include <mini-os/events.h> +#include <mini-os/wait.h> + +#include <sys/socket.h> + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdint.h> +#include <inttypes.h> +#include <malloc.h> + +#include "private.h" + +extern void minios_evtchn_close_fd(int fd); + +extern struct wait_queue_head event_queue; + +//void minios_evtchn_close_fd(int fd); + +/* XXX Note: This is not threadsafe */ +static struct evtchn_port_info* port_alloc(int fd) { + struct evtchn_port_info *port_info; + port_info = malloc(sizeof(struct evtchn_port_info)); + if (port_info == NULL) + return NULL; + port_info->pending = 0; + port_info->port = -1; + port_info->bound = 0; + + LIST_INSERT_HEAD(&files[fd].evtchn.ports, port_info, list); + return port_info; +} + +static void port_dealloc(struct evtchn_port_info *port_info) { + if (port_info->bound) + unbind_evtchn(port_info->port); + LIST_REMOVE(port_info, list); + free(port_info); +} + +int osdep_evtchn_open(xenevtchn_handle *xce) +{ + int fd = alloc_fd(FTYPE_EVTCHN); + if ( fd == -1 ) + return -1; + LIST_INIT(&files[fd].evtchn.ports); + xce->fd = fd; + printf("evtchn_open() -> %d\n", fd); + return 0; +} + +int osdep_evtchn_close(xenevtchn_handle *xce) +{ + if ( xce->fd == -1 ) + return 0; + + return close(xce->fd); +} + +void minios_evtchn_close_fd(int fd) +{ + struct evtchn_port_info *port_info, *tmp; + LIST_FOREACH_SAFE(port_info, &files[fd].evtchn.ports, list, tmp) + port_dealloc(port_info); + + files[fd].type = FTYPE_NONE; +} + +int xenevtchn_fd(xenevtchn_handle *xce) +{ + return xce->fd; +} + +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port) +{ + int ret; + + ret = notify_remote_via_evtchn(port); + + if (ret < 0) { + errno = -ret; + ret = -1; + } + return ret; +} + +static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data) +{ + int fd = (int)(intptr_t)data; + struct evtchn_port_info *port_info; + assert(files[fd].type == FTYPE_EVTCHN); + mask_evtchn(port); + LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port == port) + goto found; + } + printk("Unknown port for handle %d\n", fd); + return; + + found: + port_info->pending = 1; + files[fd].read = 1; + wake_up(&event_queue); +} + +evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid) +{ + int fd = xce->fd; + struct evtchn_port_info *port_info; + int ret; + evtchn_port_t port; + + assert(get_current() == main_thread); + port_info = port_alloc(fd); + if (port_info == NULL) + return -1; + + printf("xenevtchn_bind_unbound_port(%d)", domid); + ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)fd, &port); + printf(" = %d\n", ret); + + if (ret < 0) { + port_dealloc(port_info); + errno = -ret; + return -1; + } + port_info->bound = 1; + port_info->port = port; + unmask_evtchn(port); + return port; +} + +evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, + evtchn_port_t remote_port) +{ + int fd = xce->fd; + struct evtchn_port_info *port_info; + evtchn_port_t local_port; + int ret; + + assert(get_current() == main_thread); + port_info = port_alloc(fd); + if (port_info == NULL) + return -1; + + printf("xenevtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port); + ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)fd, &local_port); + printf(" = %d\n", ret); + + if (ret < 0) { + port_dealloc(port_info); + errno = -ret; + return -1; + } + port_info->bound = 1; + port_info->port = local_port; + unmask_evtchn(local_port); + return local_port; +} + +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct evtchn_port_info *port_info; + + LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port == port) { + port_dealloc(port_info); + return 0; + } + } + printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, fd); + errno = EINVAL; + return -1; +} + +evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq) +{ + int fd = xce->fd; + struct evtchn_port_info *port_info; + evtchn_port_t port; + + assert(get_current() == main_thread); + port_info = port_alloc(fd); + if (port_info == NULL) + return -1; + + printf("xenevtchn_bind_virq(%d)", virq); + port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)fd); + + if (port < 0) { + port_dealloc(port_info); + errno = -port; + return -1; + } + port_info->bound = 1; + port_info->port = port; + unmask_evtchn(port); + return port; +} + +evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce) +{ + int fd = xce->fd; + struct evtchn_port_info *port_info; + unsigned long flags; + evtchn_port_t ret = -1; + + local_irq_save(flags); + files[fd].read = 0; + + LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) { + if (port_info->port != -1 && port_info->pending) { + if (ret == -1) { + ret = port_info->port; + port_info->pending = 0; + } else { + files[fd].read = 1; + break; + } + } + } + local_irq_restore(flags); + return ret; +} + +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port) +{ + unmask_evtchn(port); + return 0; +} + diff --git a/tools/libxenevtchn/netbsd.c b/tools/libxenevtchn/netbsd.c new file mode 100644 index 0000000..c99d138 --- /dev/null +++ b/tools/libxenevtchn/netbsd.c @@ -0,0 +1,132 @@ +/****************************************************************************** + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * 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. + * + * Split out from xc_netbsd.c + */ + +#include <fcntl.h> + +#include <xen/sys/evtchn.h> + +#include "private.h" + +#define EVTCHN_DEV_NAME "/dev/xenevt" + +int osdep_evtchn_open(xenevtchn_handle *xce) +{ + int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR); + if ( fd == -1 ) + return -1; + xce->fd = fd; + return 0; +} + +int osdep_evtchn_close(xenevtchn_handle *xce, xc_osdep_handle h) +{ + if ( xce->fd == -1 ) + return 0; + + return close(xce->fd); +} + +int xenevtchn_fd(xenevtchn_handle *xce) +{ + return xce->fd; +} + +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle * xce, int domid) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_unbound_port bind; + int ret; + + bind.remote_domain = domid; + + ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); + if (ret == 0) + return bind.port; + else + return -1; +} + +evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, + evtchn_port_t remote_port) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_interdomain bind; + int ret; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + if (ret == 0) + return bind.port; + else + return -1; +} + +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_virq bind; + int err; + + bind.virq = virq; + + err = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); + if (err) + return -1; + else + return bind.port; +} + +evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce) +{ + int fd = xce->fd; + evtchn_port_t port; + + if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 ) + return -1; + + return port; +} + +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + return write_exact(fd, (char *)&port, sizeof(port)); +} + diff --git a/tools/libxenevtchn/private.h b/tools/libxenevtchn/private.h new file mode 100644 index 0000000..107c438 --- /dev/null +++ b/tools/libxenevtchn/private.h @@ -0,0 +1,15 @@ +#ifndef XENEVTCHN_PRIVATE_H +#define XENEVTCHN_PRIVATE_H + +#include <xentoollog.h> +#include <xenevtchn.h> + +struct xenevtchn_handle { + xentoollog_logger *logger, *logger_tofree; + int fd; +}; + +int osdep_evtchn_open(xenevtchn_handle *xce); +int osdep_evtchn_close(xenevtchn_handle *xce); + +#endif diff --git a/tools/libxenevtchn/solaris.c b/tools/libxenevtchn/solaris.c new file mode 100644 index 0000000..dcd2632 --- /dev/null +++ b/tools/libxenevtchn/solaris.c @@ -0,0 +1,120 @@ +/****************************************************************************** + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * 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. + * + * Split out from xc_solaris.c + */ + +#include <fcntl.h> + +#include <xen/sys/evtchn.h> + +#include "private.h" + +int osdep_evtchn_open(xenevtchn_handle *xce) +{ + int fd; + + if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 ) + { + PERROR("Could not open event channel interface"); + return -1; + } + + xce->fd = fd; + return 0; +} + +int osdep_evtchn_close(xenevtchn_handle *xce) +{ + if ( xce->fd == -1 ) + return 0; + + return close(xce->fd); +} + +int xenevtchn_fd(xenevtchn_handle *xce) +{ + return xce->fd; +} + +int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_notify notify; + + notify.port = port; + + return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + +evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_unbound_port bind; + + bind.remote_domain = domid; + + return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); +} + +evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, + evtchn_port_t remote_port) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_interdomain bind; + + bind.remote_domain = domid; + bind.remote_port = remote_port; + + return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); +} + +evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq) +{ + int fd = xce->fd; + struct ioctl_evtchn_bind_virq bind; + + bind.virq = virq; + + return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); +} + +int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + struct ioctl_evtchn_unbind unbind; + + unbind.port = port; + + return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); +} + +evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce) +{ + int fd = xce->fd; + evtchn_port_t port; + + if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 ) + return -1; + + return port; +} + +int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port) +{ + int fd = xce->fd; + return write_exact(fd, (char *)&port, sizeof(port)); +} + diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile index 387dc91..6183f5a 100644 --- a/tools/libxl/Makefile +++ b/tools/libxl/Makefile @@ -20,12 +20,13 @@ LIBUUID_LIBS += -luuid endif LIBXL_LIBS = -LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS) +LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS) ifeq ($(CONFIG_REMUS_NETBUF),y) LIBXL_LIBS += $(LIBNL3_LIBS) endif CFLAGS_LIBXL += $(CFLAGS_libxentoollog) +CFLAGS_LIBXL += $(CFLAGS_libxenevtchn) CFLAGS_LIBXL += $(CFLAGS_libxenctrl) CFLAGS_LIBXL += $(CFLAGS_libxenguest) CFLAGS_LIBXL += $(CFLAGS_libxenstore) @@ -142,7 +143,7 @@ $(XEN_INIT_DOM0_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(XEN_INIT_DOM0_OBJS): CFLAGS += $(CFLAGS_libxenstore) SAVE_HELPER_OBJS = libxl_save_helper.o _libxl_save_msgs_helper.o -$(SAVE_HELPER_OBJS): CFLAGS += $(CFLAGS_libxenctrl) +$(SAVE_HELPER_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) PKG_CONFIG = xenlight.pc xlutil.pc diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 9117b01..45a9493 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -178,7 +178,7 @@ int libxl_ctx_free(libxl_ctx *ctx) if (ctx->xch) xc_interface_close(ctx->xch); libxl_version_info_dispose(&ctx->version_info); if (ctx->xsh) xs_daemon_close(ctx->xsh); - if (ctx->xce) xc_evtchn_close(ctx->xce); + if (ctx->xce) xenevtchn_close(ctx->xce); libxl__poller_dispose(&ctx->poller_app); assert(LIBXL_LIST_EMPTY(&ctx->pollers_event)); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index 867172a..843741d 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -1424,9 +1424,9 @@ static void domain_suspend_callback_common(libxl__egc *egc, if ((hvm_s_state == 0) && (dss->guest_evtchn.port >= 0)) { LOG(DEBUG, "issuing %s suspend request via event channel", dss->hvm ? "PVHVM" : "PV"); - ret = xc_evtchn_notify(CTX->xce, dss->guest_evtchn.port); + ret = xenevtchn_notify(CTX->xce, dss->guest_evtchn.port); if (ret < 0) { - LOG(ERROR, "xc_evtchn_notify failed ret=%d", ret); + LOG(ERROR, "xenevtchn_notify failed ret=%d", ret); goto err; } diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c index 9ff4e78..0e842bf 100644 --- a/tools/libxl/libxl_event.c +++ b/tools/libxl/libxl_event.c @@ -705,7 +705,7 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev, /* OK, that's that workaround done. We can actually check for * work for us to do: */ - port = xc_evtchn_pending(CTX->xce); + port = xenevtchn_pending(CTX->xce); if (port < 0) { if (errno == EAGAIN) break; @@ -731,20 +731,20 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev, } int libxl__ctx_evtchn_init(libxl__gc *gc) { - xc_evtchn *xce; + xenevtchn_handle *xce; int rc, fd; if (CTX->xce) return 0; - xce = xc_evtchn_open(CTX->lg, 0); + xce = xenevtchn_open(CTX->lg, 0); if (!xce) { LOGE(ERROR,"cannot open libxc evtchn handle"); rc = ERROR_FAIL; goto out; } - fd = xc_evtchn_fd(xce); + fd = xenevtchn_fd(xce); assert(fd >= 0); rc = libxl_fd_set_nonblock(CTX, fd, 1); @@ -754,7 +754,7 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) { return 0; out: - xc_evtchn_close(xce); + xenevtchn_close(xce); return rc; } @@ -776,14 +776,14 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev) if (!libxl__ev_fd_isregistered(&CTX->evtchn_efd)) { rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd, evtchn_fd_callback, - xc_evtchn_fd(CTX->xce), POLLIN); + xenevtchn_fd(CTX->xce), POLLIN); if (rc) goto out; } if (evev->waiting) return 0; - r = xc_evtchn_unmask(CTX->xce, evev->port); + r = xenevtchn_unmask(CTX->xce, evev->port); if (r) { LOGE(ERROR,"cannot unmask event channel %d",evev->port); rc = ERROR_FAIL; diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index bb3a5c7..f6ad21f 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -46,6 +46,7 @@ #include <sys/file.h> #include <sys/ioctl.h> +#include <xenevtchn.h> #include <xenstore.h> #include <xenctrl.h> #include <xenguest.h> @@ -377,7 +378,7 @@ struct libxl__ctx { uint32_t watch_counter; /* helps disambiguate slot reuse */ libxl__ev_fd watch_efd; - xc_evtchn *xce; /* waiting must be done only with libxl__ev_evtchn* */ + xenevtchn_handle *xce; /* waiting must be done only with libxl__ev_evtchn* */ LIBXL_LIST_HEAD(, libxl__ev_evtchn) evtchns_waiting; libxl__ev_fd evtchn_efd; @@ -829,7 +830,7 @@ static inline int libxl__ev_xswatch_isregistered(const libxl__ev_xswatch *xw) * When the event is signaled then the callback will be made, once. * Then you must call libxl__ev_evtchn_wait again, if desired. * - * You must NOT call xc_evtchn_unmask. wait will do that for you. + * You must NOT call xenevtchn_unmask. wait will do that for you. * * Calling libxl__ev_evtchn_cancel will arrange for libxl to disregard * future occurrences of event. Both libxl__ev_evtchn_wait and diff --git a/tools/misc/Makefile b/tools/misc/Makefile index c4490f3..cf6a475 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -4,6 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror # Include configure output (config.h) CFLAGS += -include $(XEN_ROOT)/tools/config.h +CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += $(CFLAGS_xeninclude) CFLAGS += $(CFLAGS_libxenstore) @@ -88,18 +89,18 @@ xenlockprof: xenlockprof.o # xen-hptool incorrectly uses libxc internals xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc xen-hptool: xen-hptool.o - $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) # xen-mfndump incorrectly uses libxc internals xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc xen-mfndump: xen-mfndump.o - $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS) xenwatchdogd: xenwatchdogd.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) xen-lowmemd: xen-lowmemd.o - $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) gtraceview: gtraceview.o $(CC) $(LDFLAGS) -o $@ $< $(CURSES_LIBS) $(TINFO_LIBS) $(APPEND_LDFLAGS) diff --git a/tools/misc/xen-hptool.c b/tools/misc/xen-hptool.c index c7561a9..ebcc9e8 100644 --- a/tools/misc/xen-hptool.c +++ b/tools/misc/xen-hptool.c @@ -1,3 +1,4 @@ +#include <xenevtchn.h> #include <xenctrl.h> #include <xc_private.h> #include <xc_core.h> @@ -98,7 +99,7 @@ static int hp_mem_query_func(int argc, char *argv[]) return ret; } -static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid, +static int suspend_guest(xc_interface *xch, xenevtchn_handle *xce, int domid, int *evtchn, int *lockfd) { int port, rc, suspend_evtchn = -1; @@ -123,7 +124,7 @@ static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid, } *evtchn = suspend_evtchn; - rc = xc_evtchn_notify(xce, suspend_evtchn); + rc = xenevtchn_notify(xce, suspend_evtchn); if (rc < 0) { fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc); @@ -198,8 +199,8 @@ static int hp_mem_offline_func(int argc, char *argv[]) else if (status & PG_OFFLINE_OWNED) { int result, suspend_evtchn = -1, suspend_lockfd = -1; - xc_evtchn *xce; - xce = xc_evtchn_open(NULL, 0); + xenevtchn_handle *xce; + xce = xenevtchn_open(NULL, 0); if (xce == NULL) { @@ -214,7 +215,7 @@ static int hp_mem_offline_func(int argc, char *argv[]) { fprintf(stderr, "Failed to suspend guest %d for" " mfn %lx\n", domid, mfn); - xc_evtchn_close(xce); + xenevtchn_close(xce); return -1; } @@ -238,7 +239,7 @@ static int hp_mem_offline_func(int argc, char *argv[]) xc_domain_resume(xch, domid, 1); xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn, &suspend_lockfd); - xc_evtchn_close(xce); + xenevtchn_close(xce); } break; } diff --git a/tools/misc/xen-lowmemd.c b/tools/misc/xen-lowmemd.c index 82ffd75..3200404 100644 --- a/tools/misc/xen-lowmemd.c +++ b/tools/misc/xen-lowmemd.c @@ -4,22 +4,23 @@ */ #include <stdio.h> +#include <xenevtchn.h> #include <xenctrl.h> #include <xenstore.h> #include <stdlib.h> #include <string.h> static evtchn_port_t virq_port = -1; -static xc_evtchn *xce_handle = NULL; +static xenevtchn_handle *xce_handle = NULL; static xc_interface *xch = NULL; static struct xs_handle *xs_handle = NULL; void cleanup(void) { if (virq_port > -1) - xc_evtchn_unbind(xce_handle, virq_port); + xenevtchn_unbind(xce_handle, virq_port); if (xce_handle) - xc_evtchn_close(xce_handle); + xenevtchn_close(xce_handle); if (xch) xc_interface_close(xch); if (xs_handle) @@ -94,7 +95,7 @@ int main(int argc, char *argv[]) return 1; } - xce_handle = xc_evtchn_open(NULL, 0); + xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) { perror("Failed to open evtchn device"); @@ -108,7 +109,7 @@ int main(int argc, char *argv[]) return 3; } - if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1) + if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1) { perror("Failed to bind to domain exception virq port"); return 4; @@ -120,7 +121,7 @@ int main(int argc, char *argv[]) { evtchn_port_t port; - if ((port = xc_evtchn_pending(xce_handle)) == -1) + if ((port = xenevtchn_pending(xce_handle)) == -1) { perror("Failed to listen for pending event channel"); return 5; @@ -134,7 +135,7 @@ int main(int argc, char *argv[]) return 6; } - if (xc_evtchn_unmask(xce_handle, port) == -1) + if (xenevtchn_unmask(xce_handle, port) == -1) { perror("Failed to unmask port"); return 7; diff --git a/tools/ocaml/libs/eventchn/Makefile b/tools/ocaml/libs/eventchn/Makefile index 2d8d618..154efd4 100644 --- a/tools/ocaml/libs/eventchn/Makefile +++ b/tools/ocaml/libs/eventchn/Makefile @@ -2,13 +2,13 @@ TOPLEVEL=$(CURDIR)/../.. XEN_ROOT=$(TOPLEVEL)/../.. include $(TOPLEVEL)/common.make -CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude) +CFLAGS += $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude) OBJS = xeneventchn INTF = $(foreach obj, $(OBJS),$(obj).cmi) LIBS = xeneventchn.cma xeneventchn.cmxa -LIBS_xeneventchn = $(LDLIBS_libxenctrl) +LIBS_xeneventchn = $(LDLIBS_libxenevtchn) all: $(INTF) $(LIBS) $(PROGRAMS) diff --git a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c index 5939e7c..c2d4737 100644 --- a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c +++ b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c @@ -24,7 +24,7 @@ #include <xen/sysctl.h> #include <xen/xen.h> #include <xen/sys/evtchn.h> -#include <xenctrl.h> +#include <xenevtchn.h> #define CAML_NAME_SPACE #include <caml/mlvalues.h> @@ -34,14 +34,14 @@ #include <caml/callback.h> #include <caml/fail.h> -#define _H(__h) ((xc_evtchn *)(__h)) +#define _H(__h) ((xenevtchn_handle *)(__h)) CAMLprim value stub_eventchn_init(void) { CAMLparam0(); CAMLlocal1(result); - xc_evtchn *xce = xc_evtchn_open(NULL, XC_OPENFLAG_NON_REENTRANT); + xenevtchn_handle *xce = xenevtchn_open(NULL, 0); if (xce == NULL) caml_failwith("open failed"); @@ -55,7 +55,7 @@ CAMLprim value stub_eventchn_fd(value xce) CAMLlocal1(result); int fd; - fd = xc_evtchn_fd(_H(xce)); + fd = xenevtchn_fd(_H(xce)); if (fd == -1) caml_failwith("evtchn fd failed"); @@ -69,7 +69,7 @@ CAMLprim value stub_eventchn_notify(value xce, value port) CAMLparam2(xce, port); int rc; - rc = xc_evtchn_notify(_H(xce), Int_val(port)); + rc = xenevtchn_notify(_H(xce), Int_val(port)); if (rc == -1) caml_failwith("evtchn notify failed"); @@ -83,7 +83,7 @@ CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid, CAMLlocal1(port); evtchn_port_or_error_t rc; - rc = xc_evtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port)); + rc = xenevtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port)); if (rc == -1) caml_failwith("evtchn bind_interdomain failed"); port = Val_int(rc); @@ -97,7 +97,7 @@ CAMLprim value stub_eventchn_bind_dom_exc_virq(value xce) CAMLlocal1(port); evtchn_port_or_error_t rc; - rc = xc_evtchn_bind_virq(_H(xce), VIRQ_DOM_EXC); + rc = xenevtchn_bind_virq(_H(xce), VIRQ_DOM_EXC); if (rc == -1) caml_failwith("evtchn bind_dom_exc_virq failed"); port = Val_int(rc); @@ -110,7 +110,7 @@ CAMLprim value stub_eventchn_unbind(value xce, value port) CAMLparam2(xce, port); int rc; - rc = xc_evtchn_unbind(_H(xce), Int_val(port)); + rc = xenevtchn_unbind(_H(xce), Int_val(port)); if (rc == -1) caml_failwith("evtchn unbind failed"); @@ -123,7 +123,7 @@ CAMLprim value stub_eventchn_pending(value xce) CAMLlocal1(result); evtchn_port_or_error_t port; - port = xc_evtchn_pending(_H(xce)); + port = xenevtchn_pending(_H(xce)); if (port == -1) caml_failwith("evtchn pending failed"); result = Val_int(port); @@ -137,7 +137,7 @@ CAMLprim value stub_eventchn_unmask(value xce, value _port) evtchn_port_t port; port = Int_val(_port); - if (xc_evtchn_unmask(_H(xce), port)) + if (xenevtchn_unmask(_H(xce), port)) caml_failwith("evtchn unmask failed"); CAMLreturn(Val_unit); } diff --git a/tools/python/setup.py b/tools/python/setup.py index e55ee01..906d880 100644 --- a/tools/python/setup.py +++ b/tools/python/setup.py @@ -8,13 +8,18 @@ extra_compile_args = [ "-fno-strict-aliasing", "-Werror" ] PATH_XEN = XEN_ROOT + "/tools/include" PATH_LIBXENTOOLLOG = XEN_ROOT + "/tools/libxentoollog" +PATH_LIBXENEVTCHN = XEN_ROOT + "/tools/libxenevtchn" PATH_LIBXC = XEN_ROOT + "/tools/libxc" PATH_LIBXL = XEN_ROOT + "/tools/libxl" PATH_XENSTORE = XEN_ROOT + "/tools/xenstore" xc = Extension("xc", extra_compile_args = extra_compile_args, - include_dirs = [ PATH_XEN, PATH_LIBXENTOOLLOG + "/include", PATH_LIBXC + "/include", "xen/lowlevel/xc" ], + include_dirs = [ PATH_XEN, + PATH_LIBXENTOOLLOG + "/include", + PATH_LIBXENEVTCHN + "/include", + PATH_LIBXC + "/include", + "xen/lowlevel/xc" ], library_dirs = [ PATH_LIBXC ], libraries = [ "xenctrl", "xenguest" ], depends = [ PATH_LIBXC + "/libxenctrl.so", PATH_LIBXC + "/libxenguest.so", "-Wl,-rpath-link="+PATH_LIBXENTOOLLOG ], diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c index 12ab921..d68ae84 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -79,7 +79,7 @@ static void close_handler(int sig) int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms) { - struct pollfd fd = { .fd = xc_evtchn_fd(xce), .events = POLLIN | POLLERR }; + struct pollfd fd = { .fd = xenevtchn_fd(xce), .events = POLLIN | POLLERR }; int port; int rc; diff --git a/tools/xcutils/Makefile b/tools/xcutils/Makefile index fff519d..2d1f112 100644 --- a/tools/xcutils/Makefile +++ b/tools/xcutils/Makefile @@ -16,8 +16,8 @@ PROGRAMS = readnotes lsevtchn CFLAGS += -Werror # incorrectly uses libxc internals -CFLAGS_readnotes.o := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc -CFLAGS_lsevtchn.o := $(CFLAGS_libxenctrl) +CFLAGS_readnotes.o := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc +CFLAGS_lsevtchn.o := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) .PHONY: all all: build diff --git a/tools/xenmon/Makefile b/tools/xenmon/Makefile index 5095682..fa80983 100644 --- a/tools/xenmon/Makefile +++ b/tools/xenmon/Makefile @@ -14,8 +14,10 @@ XEN_ROOT=$(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror +CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) LDLIBS += $(LDLIBS_libxenctrl) +LDLIBS += $(LDLIBS_libxenevtchn) SCRIPTS = xenmon.py diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c index dc61d14..f092aec 100644 --- a/tools/xenmon/xenbaked.c +++ b/tools/xenmon/xenbaked.c @@ -38,6 +38,7 @@ #include <unistd.h> #include <errno.h> #include <signal.h> +#include <xenevtchn.h> #include <xenctrl.h> #include <xen/xen.h> #include <string.h> @@ -268,7 +269,7 @@ static void log_event(int event_id) } int virq_port; -xc_evtchn *xce_handle = NULL; +xenevtchn_handle *xce_handle = NULL; /* Returns the event channel handle. */ /* Stolen from xenstore code */ @@ -280,12 +281,12 @@ static int eventchn_init(void) if (0) return -1; - xce_handle = xc_evtchn_open(NULL, 0); + xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) perror("Failed to open evtchn device"); - if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1) + if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1) perror("Failed to bind to domain exception virq port"); virq_port = rc; @@ -305,7 +306,7 @@ static void wait_for_event(void) return; } - evtchn_fd = xc_evtchn_fd(xce_handle); + evtchn_fd = xenevtchn_fd(xce_handle); FD_ZERO(&inset); FD_SET(evtchn_fd, &inset); @@ -315,13 +316,13 @@ static void wait_for_event(void) ret = select(evtchn_fd+1, &inset, NULL, NULL, &tv); if ( (ret == 1) && FD_ISSET(evtchn_fd, &inset)) { - if ((port = xc_evtchn_pending(xce_handle)) == -1) + if ((port = xenevtchn_pending(xce_handle)) == -1) perror("Failed to read from event fd"); // if (port == virq_port) // printf("got the event I was looking for\r\n"); - if (xc_evtchn_unmask(xce_handle, port) == -1) + if (xenevtchn_unmask(xce_handle, port) == -1) perror("Failed to write to event fd"); } } diff --git a/tools/xenpaging/Makefile b/tools/xenpaging/Makefile index e63d894..d491867 100644 --- a/tools/xenpaging/Makefile +++ b/tools/xenpaging/Makefile @@ -2,8 +2,8 @@ XEN_ROOT=$(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk # xenpaging.c and file_ops.c incorrectly use libxc internals -CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc -LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS) +CFLAGS += $(CFLAGS_libxentoollog) $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc +LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS) LDFLAGS += $(PTHREAD_LDFLAGS) POLICY = default diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c index 3f4c2e9..6776896 100644 --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -74,7 +74,7 @@ static void xenpaging_mem_paging_flush_ioemu_cache(struct xenpaging *paging) static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging) { xc_interface *xch = paging->xc_handle; - xc_evtchn *xce = paging->vm_event.xce_handle; + xenevtchn_handle *xce = paging->vm_event.xce_handle; char **vec, *val; unsigned int num; struct pollfd fd[2]; @@ -83,7 +83,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging) int timeout; /* Wait for event channel and xenstore */ - fd[0].fd = xc_evtchn_fd(xce); + fd[0].fd = xenevtchn_fd(xce); fd[0].events = POLLIN | POLLERR; fd[1].fd = xs_fileno(paging->xs_handle); fd[1].events = POLLIN | POLLERR; @@ -147,7 +147,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging) if ( rc && fd[0].revents & POLLIN ) { DPRINTF("Got event from evtchn\n"); - port = xc_evtchn_pending(xce); + port = xenevtchn_pending(xce); if ( port == -1 ) { PERROR("Failed to read port from event channel"); @@ -155,7 +155,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging) goto err; } - rc = xc_evtchn_unmask(xce, port); + rc = xenevtchn_unmask(xce, port); if ( rc < 0 ) { PERROR("Failed to unmask event channel port"); @@ -394,7 +394,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[]) } /* Open event channel */ - paging->vm_event.xce_handle = xc_evtchn_open(NULL, 0); + paging->vm_event.xce_handle = xenevtchn_open(NULL, 0); if ( paging->vm_event.xce_handle == NULL ) { PERROR("Failed to open event channel"); @@ -402,7 +402,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[]) } /* Bind event notification */ - rc = xc_evtchn_bind_interdomain(paging->vm_event.xce_handle, + rc = xenevtchn_bind_interdomain(paging->vm_event.xce_handle, paging->vm_event.domain_id, paging->vm_event.evtchn_port); if ( rc < 0 ) @@ -532,7 +532,7 @@ static void xenpaging_teardown(struct xenpaging *paging) } /* Unbind VIRQ */ - rc = xc_evtchn_unbind(paging->vm_event.xce_handle, paging->vm_event.port); + rc = xenevtchn_unbind(paging->vm_event.xce_handle, paging->vm_event.port); if ( rc != 0 ) { PERROR("Error unbinding event port"); @@ -540,7 +540,7 @@ static void xenpaging_teardown(struct xenpaging *paging) paging->vm_event.port = -1; /* Close event channel */ - rc = xc_evtchn_close(paging->vm_event.xce_handle); + rc = xenevtchn_close(paging->vm_event.xce_handle); if ( rc != 0 ) { PERROR("Error closing event channel"); @@ -693,7 +693,7 @@ static int xenpaging_resume_page(struct xenpaging *paging, vm_event_response_t * } /* Tell Xen page is ready */ - return xc_evtchn_notify(paging->vm_event.xce_handle, paging->vm_event.port); + return xenevtchn_notify(paging->vm_event.xce_handle, paging->vm_event.port); } static int xenpaging_populate_page(struct xenpaging *paging, unsigned long gfn, int i) diff --git a/tools/xenpaging/xenpaging.h b/tools/xenpaging/xenpaging.h index 25d511d..6c12030 100644 --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -25,6 +25,7 @@ #define __XEN_PAGING2_H__ +#include <xenevtchn.h> #include <xc_private.h> #include <xen/event_channel.h> #include <xen/vm_event.h> @@ -33,7 +34,7 @@ struct vm_event { domid_t domain_id; - xc_evtchn *xce_handle; + xenevtchn_handle *xce_handle; int port; vm_event_back_ring_t back_ring; uint32_t evtchn_port; diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 1b4a494..c161046 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -9,6 +9,7 @@ CFLAGS += -I. # Include configure output (config.h) CFLAGS += -include $(XEN_ROOT)/tools/config.h CFLAGS += -I./include +CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += -DXEN_LIB_STORED="\"$(XEN_LIB_STORED)\"" @@ -75,10 +76,10 @@ endif init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest) init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE) - $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS) + $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS) xenstored: $(XENSTORED_OBJS) - $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) + $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) xenstored.a: $(XENSTORED_OBJS) $(AR) cr $@ $^ diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index b18000d..7f1e489 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -41,6 +41,8 @@ #include <assert.h> #include <setjmp.h> +#include <xenevtchn.h> + #include "utils.h" #include "list.h" #include "talloc.h" @@ -64,7 +66,7 @@ #include <systemd/sd-daemon.h> #endif -extern xc_evtchn *xce_handle; /* in xenstored_domain.c */ +extern xenevtchn_handle *xce_handle; /* in xenstored_domain.c */ static int xce_pollfd_idx = -1; static struct pollfd *fds; static unsigned int current_array_size; @@ -373,7 +375,7 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx, set_fd(reopen_log_pipe[0], POLLIN|POLLPRI); if (xce_handle != NULL) - xce_pollfd_idx = set_fd(xc_evtchn_fd(xce_handle), + xce_pollfd_idx = set_fd(xenevtchn_fd(xce_handle), POLLIN|POLLPRI); list_for_each_entry(conn, &connections, list) { diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 6d0394d..51959da 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -30,6 +30,7 @@ #include "xenstored_transaction.h" #include "xenstored_watch.h" +#include <xenevtchn.h> #include <xenctrl.h> #include <xen/grant_table.h> @@ -37,7 +38,7 @@ static xc_interface **xc_handle; xc_gnttab **xcg_handle; static evtchn_port_t virq_port; -xc_evtchn *xce_handle = NULL; +xenevtchn_handle *xce_handle = NULL; struct domain { @@ -129,7 +130,7 @@ static int writechn(struct connection *conn, xen_mb(); intf->rsp_prod += len; - xc_evtchn_notify(xce_handle, conn->domain->port); + xenevtchn_notify(xce_handle, conn->domain->port); return len; } @@ -159,7 +160,7 @@ static int readchn(struct connection *conn, void *data, unsigned int len) xen_mb(); intf->req_cons += len; - xc_evtchn_notify(xce_handle, conn->domain->port); + xenevtchn_notify(xce_handle, conn->domain->port); return len; } @@ -191,7 +192,7 @@ static int destroy_domain(void *_domain) list_del(&domain->list); if (domain->port) { - if (xc_evtchn_unbind(xce_handle, domain->port) == -1) + if (xenevtchn_unbind(xce_handle, domain->port) == -1) eprintf("> Unbinding port %i failed!\n", domain->port); } @@ -240,13 +241,13 @@ void handle_event(void) { evtchn_port_t port; - if ((port = xc_evtchn_pending(xce_handle)) == -1) + if ((port = xenevtchn_pending(xce_handle)) == -1) barf_perror("Failed to read from event fd"); if (port == virq_port) domain_cleanup(); - if (xc_evtchn_unmask(xce_handle, port) == -1) + if (xenevtchn_unmask(xce_handle, port) == -1) barf_perror("Failed to write to event fd"); } @@ -288,7 +289,7 @@ static struct domain *new_domain(void *context, unsigned int domid, talloc_set_destructor(domain, destroy_domain); /* Tell kernel we're interested in this event. */ - rc = xc_evtchn_bind_interdomain(xce_handle, domid, port); + rc = xenevtchn_bind_interdomain(xce_handle, domid, port); if (rc == -1) return NULL; domain->port = rc; @@ -393,8 +394,8 @@ void do_introduce(struct connection *conn, struct buffered_data *in) } else if ((domain->mfn == mfn) && (domain->conn != conn)) { /* Use XS_INTRODUCE for recreating the xenbus event-channel. */ if (domain->port) - xc_evtchn_unbind(xce_handle, domain->port); - rc = xc_evtchn_bind_interdomain(xce_handle, domid, port); + xenevtchn_unbind(xce_handle, domain->port); + rc = xenevtchn_bind_interdomain(xce_handle, domid, port); domain->port = (rc == -1) ? 0 : rc; domain->remote_port = port; } else { @@ -615,7 +616,7 @@ static int dom0_init(void) talloc_steal(dom0->conn, dom0); - xc_evtchn_notify(xce_handle, dom0->port); + xenevtchn_notify(xce_handle, dom0->port); return 0; } @@ -644,7 +645,7 @@ void domain_init(void) else talloc_set_destructor(xcg_handle, close_xcg_handle); - xce_handle = xc_evtchn_open(NULL, 0); + xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) barf_perror("Failed to open evtchn device"); @@ -652,7 +653,7 @@ void domain_init(void) if (dom0_init() != 0) barf_perror("Failed to initialize dom0 state"); - if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1) + if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1) barf_perror("Failed to bind to domain exception virq port"); virq_port = rc; } diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 5360960..fc94e04 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -3,7 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror +CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) +LDLIBS += $(LDLIBS_libxenevtchn) LDLIBS += $(LDLIBS_libxenctrl) BIN = diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c index 4ee1458..c970d42 100644 --- a/tools/xentrace/xentrace.c +++ b/tools/xentrace/xentrace.c @@ -30,6 +30,7 @@ #include <xen/xen.h> #include <xen/trace.h> +#include <xenevtchn.h> #include <xenctrl.h> #define PERROR(_m, _a...) \ @@ -74,7 +75,7 @@ settings_t opts; int interrupted = 0; /* gets set if we get a SIGHUP */ static xc_interface *xc_handle; -static xc_evtchn *xce_handle = NULL; +static xenevtchn_handle *xce_handle = NULL; static int virq_port = -1; static int outfd = 1; @@ -602,13 +603,13 @@ static void event_init(void) { int rc; - xce_handle = xc_evtchn_open(NULL, 0); + xce_handle = xenevtchn_open(NULL, 0); if (xce_handle == NULL) { perror("event channel open"); exit(EXIT_FAILURE); } - rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF); + rc = xenevtchn_bind_virq(xce_handle, VIRQ_TBUF); if (rc == -1) { PERROR("failed to bind to VIRQ port"); exit(EXIT_FAILURE); @@ -623,7 +624,7 @@ static void event_init(void) static void wait_for_event_or_timeout(unsigned long milliseconds) { int rc; - struct pollfd fd = { .fd = xc_evtchn_fd(xce_handle), + struct pollfd fd = { .fd = xenevtchn_fd(xce_handle), .events = POLLIN | POLLERR }; int port; @@ -636,7 +637,7 @@ static void wait_for_event_or_timeout(unsigned long milliseconds) } if (rc == 1) { - port = xc_evtchn_pending(xce_handle); + port = xenevtchn_pending(xce_handle); if (port == -1) { PERROR("failed to read port from evtchn"); exit(EXIT_FAILURE); @@ -647,7 +648,7 @@ static void wait_for_event_or_timeout(unsigned long milliseconds) port, virq_port); exit(EXIT_FAILURE); } - rc = xc_evtchn_unmask(xce_handle, port); + rc = xenevtchn_unmask(xce_handle, port); if (rc == -1) { PERROR("failed to write port to evtchn"); exit(EXIT_FAILURE); -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |