[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
commit b7f76a699dcfadc0a52ab45b33cc72dbf3a69e7b Author: Ian Campbell <ian.campbell@xxxxxxxxxx> AuthorDate: Mon Jun 1 16:20:09 2015 +0100 Commit: Ian Campbell <ian.campbell@xxxxxxxxxx> CommitDate: Fri Jan 22 12:21:07 2016 +0000 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. This is used by qemu-xen for the time being. qemu-xen-traditional is updated in lockstep. 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 Note that xc_evtchn_alloc_unbound's functionality is also provided by xenevtchn_bind_unbound_port() (née xc_evtchn_bind_unbound_port) and is probably redundant. 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. Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> [ ijc -- updated MINIOS_UPSTREAM_REVISION and QEMU_TRADITIONAL_REVISION ] --- .gitignore | 1 + Config.mk | 12 +- stubdom/Makefile | 17 ++- tools/Makefile | 5 +- tools/Rules.mk | 14 +- tools/console/Makefile | 2 + tools/console/daemon/io.c | 43 ++-- tools/libs/Makefile | 1 + tools/libs/evtchn/Makefile | 69 +++++++ tools/libs/evtchn/core.c | 72 +++++++ tools/libs/evtchn/freebsd.c | 138 +++++++++++++ tools/libs/evtchn/include/xenevtchn.h | 150 ++++++++++++++ tools/libs/evtchn/libxenevtchn.map | 19 ++ tools/libs/evtchn/linux.c | 136 +++++++++++++ tools/libs/evtchn/minios.c | 269 +++++++++++++++++++++++++ tools/libs/evtchn/netbsd.c | 147 ++++++++++++++ tools/libs/evtchn/private.h | 25 +++ tools/libs/evtchn/solaris.c | 135 +++++++++++++ tools/libs/toollog/include/xentoollog.h | 10 + tools/libs/toollog/xtl_core.c | 10 + tools/libs/toollog/xtl_logger_stdio.c | 10 + 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 | 14 +- 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/libxl/Makefile | 5 +- tools/libxl/libxl.c | 2 +- tools/libxl/libxl_dom_suspend.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/Makefile | 3 +- tools/tests/xen-access/xen-access.c | 21 +- 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 | 3 +- tools/xenstore/xenstored_core.c | 6 +- tools/xenstore/xenstored_domain.c | 25 ++- tools/xentrace/Makefile | 5 +- tools/xentrace/xentrace.c | 13 +- 62 files changed, 1544 insertions(+), 930 deletions(-) diff --git a/.gitignore b/.gitignore index 141c2be..e7af9f7 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ stubdom/ioemu stubdom/ioemu/ stubdom/libs-* stubdom/libxc-* +stubdom/libxenevtchn-* stubdom/libxentoollog-* stubdom/lwip-* stubdom/lwip/ diff --git a/Config.mk b/Config.mk index d654af8..e202d3f 100644 --- a/Config.mk +++ b/Config.mk @@ -251,9 +251,9 @@ MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git endif OVMF_UPSTREAM_REVISION ?= 52a99493cce88a9d4ec8a02d7f1bd1a1001ce60d QEMU_UPSTREAM_REVISION ?= master -MINIOS_UPSTREAM_REVISION ?= d25773c8afa2f4dbbb466116daeb60159ddd22bd -# Thu Dec 3 11:23:25 2015 +0000 -# mini-os: Include libxentoollog with libxc +MINIOS_UPSTREAM_REVISION ?= fb66c855c983aa07644cb179fd9bfe96d55f317d +# Fri Jan 15 13:24:00 2016 +0000 +# mini-os: Include libxenevtchn with libxc SEABIOS_UPSTREAM_REVISION ?= 3403ac4313812752be6e6aac35239ca6888a8cab # Mon Dec 28 13:50:41 2015 +0100 @@ -262,9 +262,9 @@ SEABIOS_UPSTREAM_REVISION ?= 3403ac4313812752be6e6aac35239ca6888a8cab ETHERBOOT_NICS ?= rtl8139 8086100e -QEMU_TRADITIONAL_REVISION ?= 569eac99e8ddccd15fe78e8a3af5622afe780e3b -# Mon Jan 4 15:34:29 2016 +0000 -# MSI-X: avoid array overrun upon MSI-X table writes +QEMU_TRADITIONAL_REVISION ?= ca2ff968de42d47dcda8973aa1528a14f99992d3 +# Fri Jan 15 13:23:53 2016 +0000 +# qemu-xen-traditional: Use libxenevtchn # Specify which qemu-dm to use. This may be `ioemu' to use the old # Mercurial in-tree version, or a local directory, or a git URL. diff --git a/stubdom/Makefile b/stubdom/Makefile index 9c77205..702d66b 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -319,6 +319,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET) ln -sf $(XEN_ROOT)/tools/libs/toollog/include/*.h . && \ ln -sf $(XEN_ROOT)/tools/libs/toollog/*.c . && \ ln -sf $(XEN_ROOT)/tools/libs/toollog/Makefile . ) + mkdir -p libs-$(XEN_TARGET_ARCH)/evtchn/include + [ -h libs-$(XEN_TARGET_ARCH)/evtchn/Makefile ] || ( cd libs-$(XEN_TARGET_ARCH)/evtchn && \ + ln -sf $(XEN_ROOT)/tools/libs/evtchn/*.h . && \ + ln -sf $(XEN_ROOT)/tools/libs/evtchn/include/*.h include/ && \ + ln -sf $(XEN_ROOT)/tools/libs/evtchn/*.c . && \ + ln -sf $(XEN_ROOT)/tools/libs/evtchn/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 . && \ @@ -351,12 +357,21 @@ libs-$(XEN_TARGET_ARCH)/toollog/libxentoollog.a: mk-headers-$(XEN_TARGET_ARCH) $ CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libs-$(XEN_TARGET_ARCH)/toollog ####### +# libxenevtchn +####### + +.PHONY: libxenevtchn +libxenevtchn: libs-$(XEN_TARGET_ARCH)/evtchn/libxenevtchn.a +libs-$(XEN_TARGET_ARCH)/evtchn/libxenevtchn.a: mk-headers-$(XEN_TARGET_ARCH) $(NEWLIB_STAMPFILE) + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libs-$(XEN_TARGET_ARCH)/evtchn + +####### # libxc ####### .PHONY: libxc libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a -libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: mk-headers-$(XEN_TARGET_ARCH) libxentoollog cross-zlib +libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: mk-headers-$(XEN_TARGET_ARCH) libxentoollog libxenevtchn cross-zlib CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH) libxc-$(XEN_TARGET_ARCH)/libxenguest.a: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a diff --git a/tools/Makefile b/tools/Makefile index ccd0ae7..55b5d44 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -249,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/libs/toollog/include \ + -I$(XEN_ROOT)/tools/libs/evtchn/include \ -I$(XEN_ROOT)/tools/libxc/include \ -I$(XEN_ROOT)/tools/xenstore/include \ -I$(XEN_ROOT)/tools/xenstore/compat/include \ @@ -258,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/libs/toollog \ + -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/evtchn \ $(QEMU_UPSTREAM_RPATH)" \ --bindir=$(LIBEXEC_BIN) \ --datadir=$(SHAREDIR)/qemu-xen \ diff --git a/tools/Rules.mk b/tools/Rules.mk index 0652e4b..75d02c4 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/libs/toollog +XEN_LIBXENEVTCHN = $(XEN_ROOT)/tools/libs/evtchn XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore @@ -82,13 +83,18 @@ SHDEPS_libxentoollog = LDLIBS_libxentoollog = $(XEN_LIBXENTOOLLOG)/libxentoollog$(libextension) SHLIB_libxentoollog = -Wl,-rpath-link=$(XEN_LIBXENTOOLLOG) +CFLAGS_libxenevtchn = -I$(XEN_LIBXENEVTCHN)/include $(CFLAGS_xeninclude) +SHDEPS_libxenevtchn = +LDLIBS_libxenevtchn = $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension) +SHLIB_libxenevtchn = -Wl,-rpath-link=$(XEN_LIBXENEVTCHN) + CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude) -SHDEPS_libxenctrl = $(SHLIB_libxentoollog) +SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) LDLIBS_libxenctrl = $(SHDEPS_libxenctrl) $(XEN_LIBXC)/libxenctrl$(libextension) SHLIB_libxenctrl = $(SHDEPS_libxenctrl) -Wl,-rpath-link=$(XEN_LIBXC) -CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_xeninclude) -SHDEPS_libxenguest = +CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude) +SHDEPS_libxenguest = $(SHLIB_libxenevtchn) LDLIBS_libxenguest = $(SHDEPS_libxenguest) $(XEN_LIBXC)/libxenguest$(libextension) SHLIB_libxenguest = $(SHDEPS_libxenguest) -Wl,-rpath-link=$(XEN_LIBXC) @@ -103,7 +109,7 @@ LDLIBS_libxenstat = $(SHDEPS_libxenstat) $(XEN_LIBXENSTAT)/libxenstat$(libexten SHLIB_libxenstat = $(SHDEPS_libxenstat) -Wl,-rpath-link=$(XEN_LIBXENSTAT) CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN) -SHDEPS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) +SHDEPS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) LDLIBS_libxenvchan = $(SHDEPS_libxenvchan) $(XEN_LIBVCHAN)/libxenvchan$(libextension) SHLIB_libxenvchan = $(SHDEPS_libxenvchan) -Wl,-rpath-link=$(XEN_LIBVCHAN) diff --git a/tools/console/Makefile b/tools/console/Makefile index 77e8f29..4b3a492 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 cafc7b7..2f2e9c5 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -21,6 +21,7 @@ #include "utils.h" #include "io.h" +#include <xenevtchn.h> #include <xenstore.h> #include <xen/io/console.h> #include <xen/grant_table.h> @@ -101,7 +102,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; @@ -185,7 +186,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 @@ -584,22 +585,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; } @@ -609,7 +610,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; @@ -749,7 +750,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; } @@ -839,7 +840,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); @@ -871,7 +872,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++; @@ -879,7 +880,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) @@ -906,7 +907,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; @@ -914,7 +915,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 @@ -938,7 +939,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) @@ -1006,10 +1007,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)); @@ -1018,7 +1019,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)); @@ -1047,7 +1048,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) @@ -1066,7 +1067,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; } @@ -1082,7 +1083,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); } @@ -1202,7 +1203,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/libs/Makefile b/tools/libs/Makefile index 73be500..0e3f523 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -3,5 +3,6 @@ include $(XEN_ROOT)/tools/Rules.mk SUBDIRS-y := SUBDIRS-y += toollog +SUBDIRS-y += evtchn all clean install distclean: %: subdirs-% diff --git a/tools/libs/evtchn/Makefile b/tools/libs/evtchn/Makefile new file mode 100644 index 0000000..46a807f --- /dev/null +++ b/tools/libs/evtchn/Makefile @@ -0,0 +1,69 @@ +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) -Wl,$(SONAME_LDFLAG) -Wl,libxenevtchn.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(LDLIBS_libxentoollog) $(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) + rm -f libxenevtchn.so.$(MAJOR).$(MINOR) libxenevtchn.so.$(MAJOR) + +.PHONY: distclean +distclean: clean diff --git a/tools/libs/evtchn/core.c b/tools/libs/evtchn/core.c new file mode 100644 index 0000000..c31e08c --- /dev/null +++ b/tools/libs/evtchn/core.c @@ -0,0 +1,72 @@ +/* + * 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, see <http://www.gnu.org/licenses/>. + */ + +#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; + + if ( !xce ) + return 0; + + rc = osdep_evtchn_close(xce); + xtl_logger_destroy(xce->logger_tofree); + free(xce); + return rc; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/evtchn/freebsd.c b/tools/libs/evtchn/freebsd.c new file mode 100644 index 0000000..636f052 --- /dev/null +++ b/tools/libs/evtchn/freebsd.c @@ -0,0 +1,138 @@ + /****************************************************************************** + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see <http://www.gnu.org/licenses/>. + * + * Split off from xc_freebsd_osdep.c + */ + +#include <fcntl.h> +#include <unistd.h> + +#include <sys/ioctl.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; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/evtchn/include/xenevtchn.h b/tools/libs/evtchn/include/xenevtchn.h new file mode 100644 index 0000000..3380fa3 --- /dev/null +++ b/tools/libs/evtchn/include/xenevtchn.h @@ -0,0 +1,150 @@ +/* + * 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, see <http://www.gnu.org/licenses/>. + * + * 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); + +#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/libs/evtchn/libxenevtchn.map b/tools/libs/evtchn/libxenevtchn.map new file mode 100644 index 0000000..625a1e2 --- /dev/null +++ b/tools/libs/evtchn/libxenevtchn.map @@ -0,0 +1,19 @@ +VERS_1.0 { + global: + xenevtchn_open; + xenevtchn_close; + + xenevtchn_fd; + + xenevtchn_bind_unbound_port; + xenevtchn_bind_interdomain; + xenevtchn_bind_virq; + + xenevtchn_notify; + + xenevtchn_unbind; + xenevtchn_unmask; + + xenevtchn_pending; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libs/evtchn/linux.c b/tools/libs/evtchn/linux.c new file mode 100644 index 0000000..27fd6e9 --- /dev/null +++ b/tools/libs/evtchn/linux.c @@ -0,0 +1,136 @@ +/* + * 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, see <http://www.gnu.org/licenses/>. + * + * 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/libs/evtchn/minios.c b/tools/libs/evtchn/minios.c new file mode 100644 index 0000000..fb913a2 --- /dev/null +++ b/tools/libs/evtchn/minios.c @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see <http://www.gnu.org/licenses/>. + * + * 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; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/evtchn/netbsd.c b/tools/libs/evtchn/netbsd.c new file mode 100644 index 0000000..c4123fe --- /dev/null +++ b/tools/libs/evtchn/netbsd.c @@ -0,0 +1,147 @@ +/****************************************************************************** + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see <http://www.gnu.org/licenses/>. + * + * Split out from xc_netbsd.c + */ + +#include <fcntl.h> +#include <unistd.h> + +#include <sys/ioctl.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) +{ + 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)); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/evtchn/private.h b/tools/libs/evtchn/private.h new file mode 100644 index 0000000..fcd0e96 --- /dev/null +++ b/tools/libs/evtchn/private.h @@ -0,0 +1,25 @@ +#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 + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/evtchn/solaris.c b/tools/libs/evtchn/solaris.c new file mode 100644 index 0000000..114cefb --- /dev/null +++ b/tools/libs/evtchn/solaris.c @@ -0,0 +1,135 @@ +/****************************************************************************** + * + * 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. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see <http://www.gnu.org/licenses/>. + * + * Split out from xc_solaris.c + */ + +#include <fcntl.h> +#include <unistd.h> + +#include <sys/ioctl.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)); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toollog/include/xentoollog.h b/tools/libs/toollog/include/xentoollog.h index 853e9c7..76f17fe 100644 --- a/tools/libs/toollog/include/xentoollog.h +++ b/tools/libs/toollog/include/xentoollog.h @@ -134,3 +134,13 @@ const char *xtl_level_to_string(xentoollog_level); /* never fails */ #endif /* XENTOOLLOG_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toollog/xtl_core.c b/tools/libs/toollog/xtl_core.c index c4724a0..099d2f3 100644 --- a/tools/libs/toollog/xtl_core.c +++ b/tools/libs/toollog/xtl_core.c @@ -81,3 +81,13 @@ void xtl_logger_destroy(struct xentoollog_logger *logger) { if (!logger) return; logger->destroy(logger); } + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/toollog/xtl_logger_stdio.c b/tools/libs/toollog/xtl_logger_stdio.c index 0cd9206..f9c5bd8 100644 --- a/tools/libs/toollog/xtl_logger_stdio.c +++ b/tools/libs/toollog/xtl_logger_stdio.c @@ -190,3 +190,13 @@ xentoollog_logger_stdiostream *xtl_createlogger_stdiostream return XTL_NEW_LOGGER(stdiostream, newlogger); } + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ 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 77be4e7..66cb103 100644 --- a/tools/libvchan/init.c +++ b/tools/libvchan/init.c @@ -216,25 +216,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; @@ -346,26 +346,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 381cc05..53393a5 100644 --- a/tools/libvchan/io.c +++ b/tools/libvchan/io.c @@ -105,7 +105,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; } @@ -196,10 +196,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; } @@ -352,7 +352,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) @@ -374,8 +374,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 0944a0e..1544378 100644 --- a/tools/libvchan/libxenvchan.h +++ b/tools/libvchan/libxenvchan.h @@ -44,6 +44,7 @@ #include <xen/io/libxenvchan.h> #include <xen/sys/evtchn.h> +#include <xenevtchn.h> #include <xenctrl.h> struct libxenvchan_ring { @@ -71,7 +72,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 940708f..b8fc6a5 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -48,6 +48,7 @@ CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c CTRL_SRCS-$(CONFIG_NetBSDRump) += 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 @@ -111,6 +112,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)) @@ -164,7 +166,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) @@ -207,7 +209,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 @@ -230,7 +232,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 1bf70f9..53f3033 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -117,7 +117,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; @@ -1085,7 +1084,6 @@ int xc_cpupool_movedomain(xc_interface *xch, */ xc_cpumap_t xc_cpupool_freeinfo(xc_interface *xch); - /* * EVENT CHANNEL FUNCTIONS * @@ -1120,101 +1118,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, @@ -2851,6 +2755,9 @@ int xc_psr_cat_get_l3_info(xc_interface *xch, uint32_t socket, bool *cdp_enabled); #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 8f918b1..050a537 100644 --- a/tools/libxc/include/xenguest.h +++ b/tools/libxc/include/xenguest.h @@ -34,6 +34,12 @@ #define X86_64_B_SIZE 64 #define X86_32_B_SIZE 32 +/* + * User not using xc_suspend_* / xc_await_suspent may not want to + * include the full libxenevtchn API here. + */ +typedef struct xenevtchn_handle xenevtchn_handle; + /* callbacks provided by xc_domain_save */ struct save_callbacks { /* Called after expiration of checkpoint interval, @@ -161,18 +167,18 @@ struct xc_hvm_firmware_module { * 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 @@ -181,7 +187,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_mark_page_online(xc_interface *xch, unsigned long start, 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 4323e16..339997c 100644 --- a/tools/libxc/xc_freebsd_osdep.c +++ b/tools/libxc/xc_freebsd_osdep.c @@ -31,13 +31,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)) @@ -251,105 +249,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 90544fb..65299d0 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -31,7 +31,6 @@ #include <sys/ioctl.h> #include <xen/memory.h> -#include <xen/sys/evtchn.h> #include <xen/sys/gntdev.h> #include <xen/sys/gntalloc.h> @@ -461,100 +460,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 4ace1b5..db7b344 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -19,14 +19,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> @@ -41,13 +38,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) { @@ -197,220 +190,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 b1b828f..fe4f0a1 100644 --- a/tools/libxc/xc_netbsd.c +++ b/tools/libxc/xc_netbsd.c @@ -19,7 +19,6 @@ #include "xc_private.h" -#include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> #include <malloc.h> @@ -223,114 +222,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 cb79f22..56d54b6 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -251,46 +251,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 f4d155a..a32accb 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -123,13 +123,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 088228a..ed7987c 100644 --- a/tools/libxc/xc_solaris.c +++ b/tools/libxc/xc_solaris.c @@ -20,7 +20,6 @@ #include "xc_private.h" #include <xen/memory.h> -#include <xen/sys/evtchn.h> #include <unistd.h> #include <fcntl.h> #include <malloc.h> @@ -194,102 +193,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; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |