diff mbox

[XEN,v8,02/29] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.

Message ID 1452864188-2417-3-git-send-email-ian.campbell@citrix.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ian Campbell Jan. 15, 2016, 1:22 p.m. UTC
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@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---

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.

v2: Update doc at same time
    Removed some stray compat thing
v3: Moved to tools/libs/evtchn
v4: typedef the xenevtchn_handle in xenguest.h instead of #include, to
    avoid leaking the libxenevtchn namespace into callers who may not
    want it. (And also to avoid adding lots of -I to places like
    stubdom builds)
v5: Handle NULL passed to _close()
v6: Properly port xen-access to new API (instead of a single function call)
v7: Added mk-headers-$(XEN_TARGET_ARCH) build dependency instead of
    open coding the recursion.
v8: Remove *.so on clean, add distclean target.
---
 .gitignore                                    |   1 +
 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                       |   5 +-
 tools/xenstore/xenstored_core.c               |   6 +-
 tools/xenstore/xenstored_domain.c             |  25 +--
 tools/xentrace/Makefile                       |   5 +-
 tools/xentrace/xentrace.c                     |  13 +-
 61 files changed, 1539 insertions(+), 925 deletions(-)
 create mode 100644 tools/libs/evtchn/Makefile
 create mode 100644 tools/libs/evtchn/core.c
 create mode 100644 tools/libs/evtchn/freebsd.c
 create mode 100644 tools/libs/evtchn/include/xenevtchn.h
 create mode 100644 tools/libs/evtchn/libxenevtchn.map
 create mode 100644 tools/libs/evtchn/linux.c
 create mode 100644 tools/libs/evtchn/minios.c
 create mode 100644 tools/libs/evtchn/netbsd.c
 create mode 100644 tools/libs/evtchn/private.h
 create mode 100644 tools/libs/evtchn/solaris.c
 create mode 100644 tools/libxc/include/xenctrl_compat.h
 create mode 100644 tools/libxc/xc_evtchn_compat.c

Comments

Boris Ostrovsky Jan. 22, 2016, 5:12 p.m. UTC | #1
On 01/15/2016 08:22 AM, Ian Campbell wrote:
> libxenevtchn will provide a stable API and ABI for accessing the
> evtchn device.

I think this patch breaks the build:

root@ovs101> gcc  -O1 -fno-omit-frame-pointer -m64 -g 
-fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes 
-Wdeclaration-after-statement -Wno-unused-but-set-variable   -O0 -g3 
-D__XEN_TOOLS__ -MMD -MF .core.o.d -D_LARGEFILE_SOURCE 
-D_LARGEFILE64_SOURCE -fno-optimize-sibling-calls  -Werror 
-Wmissing-prototypes -I./include 
-I/root/xen/tools/libs/evtchn/../../../tools/include 
-I/root/xen/tools/libs/evtchn/../../../tools/libs/toollog/include 
-I/root/xen/tools/libs/evtchn/../../../tools/include  -c -o core.o core.c
In file included from private.h:5,
                  from core.c:19:
./include/xenevtchn.h:36: error: redefinition of typedef ‘xentoollog_logger’
/root/xen/tools/libs/evtchn/../../../tools/libs/toollog/include/xentoollog.h:44: 
note: previous declaration of ‘xentoollog_logger’ was here

-boris
Ian Campbell Jan. 25, 2016, 9:48 a.m. UTC | #2
On Fri, 2016-01-22 at 12:12 -0500, Boris Ostrovsky wrote:
> On 01/15/2016 08:22 AM, Ian Campbell wrote:
> > libxenevtchn will provide a stable API and ABI for accessing the
> > evtchn device.
> 
> I think this patch breaks the build:
> 
> root@ovs101> gcc  -O1 -fno-omit-frame-pointer -m64 -g 
> -fno-strict-aliasing -std=gnu99 -Wall -Wstrict-prototypes 
> -Wdeclaration-after-statement -Wno-unused-but-set-variable   -O0 -g3 
> -D__XEN_TOOLS__ -MMD -MF .core.o.d -D_LARGEFILE_SOURCE 
> -D_LARGEFILE64_SOURCE -fno-optimize-sibling-calls  -Werror 
> -Wmissing-prototypes -I./include 
> -I/root/xen/tools/libs/evtchn/../../../tools/include 
> -I/root/xen/tools/libs/evtchn/../../../tools/libs/toollog/include 
> -I/root/xen/tools/libs/evtchn/../../../tools/include  -c -o core.o core.c
> In file included from private.h:5,
>                   from core.c:19:
> ./include/xenevtchn.h:36: error: redefinition of typedef ‘xentoollog_logger’
> /root/xen/tools/libs/evtchn/../../../tools/libs/toollog/include/xentoollog.h:44: 
> note: previous declaration of ‘xentoollog_logger’ was here

Hrm, it seems to be OK by the end of the series, in that it built for me
before push and has passed smoke-test. So I may have introduced a bisection
hazard (sorry) but it's too late to fix that unfortunately.

Various of the tools/libs/*/include/*.h have a

    /* Callers who don't care don't need to #include <xentoollog.h> */
    typedef struct xentoollog_logger xentoollog_logger;

but since that typedef matches in all cases I think it is allowed to be
repeated like this, isn't it?

Ian.
Ian Jackson Jan. 25, 2016, 2:35 p.m. UTC | #3
Ian Campbell writes ("Re: [Xen-devel] [PATCH XEN v8 02/29] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn."):
> Various of the tools/libs/*/include/*.h have a
> 
>     /* Callers who don't care don't need to #include <xentoollog.h> */
>     typedef struct xentoollog_logger xentoollog_logger;
> 
> but since that typedef matches in all cases I think it is allowed to be
> repeated like this, isn't it?

No, I'm afraid not.  It is permitted to repeatedly mention `struct
xentoollog_logger', but the typedef must only occur once in any
translation unit.

If it is desirable to let callers avoid including xentoollog.h, then
all those headers need to say:

  struct xentoollog_logger;
  int some_function(..., struct xentoollog_logger *lg, ...);

So in your patches something like:

  struct xentoollog_logger;

  xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
                                   unsigned open_flags);

The separate `struct xentoollog_logger;' is needed because otherwise
the `struct xentoollog_logger *logger' in the formal parameters of
xenevtchn_open is a declaration, rather than a reference to a
previously-declared thing, and if it is a declaration its scope is
only the contained function prototype, so other mentions of `struct
xentoollog_logger' are treated as references to a different type.
This is, of course, insane.

Ian.
Boris Ostrovsky Jan. 25, 2016, 2:39 p.m. UTC | #4
On 01/25/2016 09:35 AM, Ian Jackson wrote:
> Ian Campbell writes ("Re: [Xen-devel] [PATCH XEN v8 02/29] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn."):
>> Various of the tools/libs/*/include/*.h have a
>>
>>      /* Callers who don't care don't need to #include <xentoollog.h> */
>>      typedef struct xentoollog_logger xentoollog_logger;
>>
>> but since that typedef matches in all cases I think it is allowed to be
>> repeated like this, isn't it?
> No, I'm afraid not.  It is permitted to repeatedly mention `struct
> xentoollog_logger', but the typedef must only occur once in any
> translation unit.
>
> If it is desirable to let callers avoid including xentoollog.h, then
> all those headers need to say:
>
>    struct xentoollog_logger;
>    int some_function(..., struct xentoollog_logger *lg, ...);
>
> So in your patches something like:
>
>    struct xentoollog_logger;
>
>    xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
>                                     unsigned open_flags);
>
> The separate `struct xentoollog_logger;' is needed because otherwise
> the `struct xentoollog_logger *logger' in the formal parameters of
> xenevtchn_open is a declaration, rather than a reference to a
> previously-declared thing, and if it is a declaration its scope is
> only the contained function prototype, so other mentions of `struct
> xentoollog_logger' are treated as references to a different type.
> This is, of course, insane.
>

(I was just about to respond to IanC's earlier message)

It builds on my desktop (gcc 4.9.2) but not on an older setup (4.4.7). 
BTW, I should have explicitly said so: I haven't bisected to this commit 
--- it just looked like this ould be the culprit.

-boris
Ian Campbell Jan. 25, 2016, 2:47 p.m. UTC | #5
On Mon, 2016-01-25 at 14:35 +0000, Ian Jackson wrote:
> Ian Campbell writes ("Re: [Xen-devel] [PATCH XEN v8 02/29] tools:
> Refactor /dev/xen/evtchn wrappers into libxenevtchn."):
> > Various of the tools/libs/*/include/*.h have a
> > 
> >     /* Callers who don't care don't need to #include <xentoollog.h> */
> >     typedef struct xentoollog_logger xentoollog_logger;
> > 
> > but since that typedef matches in all cases I think it is allowed to be
> > repeated like this, isn't it?
> 
> No, I'm afraid not.

:-/

>   It is permitted to repeatedly mention `struct
> xentoollog_logger', but the typedef must only occur once in any
> translation unit.

For some reason I thought the typedef's could be repeated so long as they
were identical.

Seems at least Debian's gcc tolerates such things (which makes me wonder
how many more instances of this might have snuck in, I guess folks like
Boris would have spotted them pretty quick).

> If it is desirable to let callers avoid including xentoollog.h, then
> all those headers need to say:
> 
>   struct xentoollog_logger;
>   int some_function(..., struct xentoollog_logger *lg, ...);
> 
> So in your patches something like:
> 
>   struct xentoollog_logger;
> 
>   xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
>                                    unsigned open_flags);

I'll do something like this for tools/libs/*/include.

FYI the underlying patches are all in since Friday.


> 
> The separate `struct xentoollog_logger;' is needed because otherwise
> the `struct xentoollog_logger *logger' in the formal parameters of
> xenevtchn_open is a declaration, rather than a reference to a
> previously-declared thing, and if it is a declaration its scope is
> only the contained function prototype, so other mentions of `struct
> xentoollog_logger' are treated as references to a different type.
> This is, of course, insane.
> 
> Ian.
Andrew Cooper Jan. 25, 2016, 2:49 p.m. UTC | #6
On 25/01/16 14:47, Ian Campbell wrote:
> On Mon, 2016-01-25 at 14:35 +0000, Ian Jackson wrote:
>> Ian Campbell writes ("Re: [Xen-devel] [PATCH XEN v8 02/29] tools:
>> Refactor /dev/xen/evtchn wrappers into libxenevtchn."):
>>> Various of the tools/libs/*/include/*.h have a
>>>
>>>     /* Callers who don't care don't need to #include <xentoollog.h> */
>>>     typedef struct xentoollog_logger xentoollog_logger;
>>>
>>> but since that typedef matches in all cases I think it is allowed to be
>>> repeated like this, isn't it?
>> No, I'm afraid not.
> :-/
>
>>   It is permitted to repeatedly mention `struct
>> xentoollog_logger', but the typedef must only occur once in any
>> translation unit.
> For some reason I thought the typedef's could be repeated so long as they
> were identical.
>
> Seems at least Debian's gcc tolerates such things (which makes me wonder
> how many more instances of this might have snuck in, I guess folks like
> Boris would have spotted them pretty quick).
>
>> If it is desirable to let callers avoid including xentoollog.h, then
>> all those headers need to say:
>>
>>   struct xentoollog_logger;
>>   int some_function(..., struct xentoollog_logger *lg, ...);
>>
>> So in your patches something like:
>>
>>   struct xentoollog_logger;
>>
>>   xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
>>                                    unsigned open_flags);
> I'll do something like this for tools/libs/*/include.
>
> FYI the underlying patches are all in since Friday.

How about doing the header strictness check on all headers at one?  If
repeating typedefs is a gccism, that should catch it.

~Andrew
Ian Campbell Jan. 25, 2016, 3:28 p.m. UTC | #7
On Mon, 2016-01-25 at 14:49 +0000, Andrew Cooper wrote:
> On 25/01/16 14:47, Ian Campbell wrote:
> > On Mon, 2016-01-25 at 14:35 +0000, Ian Jackson wrote:
> > > Ian Campbell writes ("Re: [Xen-devel] [PATCH XEN v8 02/29] tools:
> > > Refactor /dev/xen/evtchn wrappers into libxenevtchn."):
> > > > Various of the tools/libs/*/include/*.h have a
> > > > 
> > > >     /* Callers who don't care don't need to #include <xentoollog.h>
> > > > */
> > > >     typedef struct xentoollog_logger xentoollog_logger;
> > > > 
> > > > but since that typedef matches in all cases I think it is allowed
> > > > to be
> > > > repeated like this, isn't it?
> > > No, I'm afraid not.
> > :-/
> > 
> > >   It is permitted to repeatedly mention `struct
> > > xentoollog_logger', but the typedef must only occur once in any
> > > translation unit.
> > For some reason I thought the typedef's could be repeated so long as
> > they
> > were identical.
> > 
> > Seems at least Debian's gcc tolerates such things (which makes me
> > wonder
> > how many more instances of this might have snuck in, I guess folks like
> > Boris would have spotted them pretty quick).
> > 
> > > If it is desirable to let callers avoid including xentoollog.h, then
> > > all those headers need to say:
> > > 
> > >   struct xentoollog_logger;
> > >   int some_function(..., struct xentoollog_logger *lg, ...);
> > > 
> > > So in your patches something like:
> > > 
> > >   struct xentoollog_logger;
> > > 
> > >   xenevtchn_handle *xenevtchn_open(struct xentoollog_logger *logger,
> > >                                    unsigned open_flags);
> > I'll do something like this for tools/libs/*/include.
> > 
> > FYI the underlying patches are all in since Friday.
> 
> How about doing the header strictness check on all headers at one?  If
> repeating typedefs is a gccism, that should catch it.

AFAICT the issue here is that newer gcc tolerates duplicate typedefs under
many circumstances. Seems to take -pedantic-errors to make it not, and I
don't see another to enable the warning.

Ian.
diff mbox

Patch

diff --git a/.gitignore b/.gitignore
index 02b2100..f79a7b3 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/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 9f74ac7..99e016a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -248,8 +248,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 \
@@ -257,6 +259,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, &notify);
+}
+
+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, &notify);
+}
+
+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@eu.citrix.com>.
+ * 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, &notify);
+}
+
+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, &notify);
+}
+
+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 881dcd5..8f31c4d 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, &notify);
-}
-
-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, &notify);
-}
-
-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, &notify);
-}
-
-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;
-
-    notify.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
-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 bba36e7..8361c7b 100644
--- a/tools/libxc/xc_suspend.c
+++ b/tools/libxc/xc_suspend.c
@@ -16,6 +16,8 @@ 
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <xenevtchn.h>
+
 #include "xc_private.h"
 #include "xenguest.h"
 
@@ -124,12 +126,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;
@@ -137,7 +139,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;
@@ -145,16 +147,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;
@@ -164,7 +166,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;
@@ -184,7 +186,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/libxl/Makefile b/tools/libxl/Makefile
index 2abae0c..10b1741 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)
@@ -159,7 +160,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 9207621..249fed8 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -186,7 +186,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_put(ctx, ctx->poller_app);
     ctx->poller_app = NULL;
diff --git a/tools/libxl/libxl_dom_suspend.c b/tools/libxl/libxl_dom_suspend.c
index 3313ad1..16f603f 100644
--- a/tools/libxl/libxl_dom_suspend.c
+++ b/tools/libxl/libxl_dom_suspend.c
@@ -109,9 +109,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);
             rc = ERROR_FAIL;
             goto err;
         }
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 139e49a..8548365 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -739,7 +739,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;
@@ -765,20 +765,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);
@@ -788,7 +788,7 @@  int libxl__ctx_evtchn_init(libxl__gc *gc) {
     return 0;
 
  out:
-    xc_evtchn_close(xce);
+    xenevtchn_close(xce);
     return rc;
 }
 
@@ -810,14 +810,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 a556a38..77bf251 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -48,6 +48,7 @@ 
 #include <sys/file.h>
 #include <sys/ioctl.h>
 
+#include <xenevtchn.h>
 #include <xenstore.h>
 #include <xenctrl.h>
 #include <xenguest.h>
@@ -448,7 +449,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;
 
@@ -925,7 +926,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 604b314..8faf1c0 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/libs/toollog"
+PATH_LIBXENEVTCHN = XEN_ROOT + "/tools/libs/evtchn"
 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" ],
diff --git a/tools/tests/xen-access/Makefile b/tools/tests/xen-access/Makefile
index dd70f9f..25ff469 100644
--- a/tools/tests/xen-access/Makefile
+++ b/tools/tests/xen-access/Makefile
@@ -5,6 +5,7 @@  CFLAGS += -Werror
 
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_libxenguest)
+CFLAGS += $(CFLAGS_libxenevtchn)
 CFLAGS += $(CFLAGS_xeninclude)
 
 TARGETS-y := xen-access
@@ -24,6 +25,6 @@  clean:
 distclean: clean
 
 xen-access: xen-access.o Makefile
-	$(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest)
+	$(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenevtchn)
 
 -include $(DEPS)
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index a52ca6e..7993947 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -39,6 +39,7 @@ 
 #include <sys/poll.h>
 
 #include <xenctrl.h>
+#include <xenevtchn.h>
 #include <xen/vm_event.h>
 
 #if defined(__arm__) || defined(__aarch64__)
@@ -54,7 +55,7 @@ 
 
 typedef 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;
@@ -77,9 +78,9 @@  static void close_handler(int sig)
     interrupted = sig;
 }
 
-int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)
+int xc_wait_for_event_or_timeout(xc_interface *xch, xenevtchn_handle *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;
 
@@ -95,14 +96,14 @@  int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned lon
 
     if ( rc == 1 )
     {
-        port = xc_evtchn_pending(xce);
+        port = xenevtchn_pending(xce);
         if ( port == -1 )
         {
             ERROR("Failed to read port from event channel");
             goto err;
         }
 
-        rc = xc_evtchn_unmask(xce, port);
+        rc = xenevtchn_unmask(xce, port);
         if ( rc != 0 )
         {
             ERROR("Failed to unmask event channel port");
@@ -143,7 +144,7 @@  int xenaccess_teardown(xc_interface *xch, xenaccess_t *xenaccess)
     /* Unbind VIRQ */
     if ( evtchn_bind )
     {
-        rc = xc_evtchn_unbind(xenaccess->vm_event.xce_handle,
+        rc = xenevtchn_unbind(xenaccess->vm_event.xce_handle,
                               xenaccess->vm_event.port);
         if ( rc != 0 )
         {
@@ -155,7 +156,7 @@  int xenaccess_teardown(xc_interface *xch, xenaccess_t *xenaccess)
     /* Close event channel */
     if ( evtchn_open )
     {
-        rc = xc_evtchn_close(xenaccess->vm_event.xce_handle);
+        rc = xenevtchn_close(xenaccess->vm_event.xce_handle);
         if ( rc != 0 )
         {
             ERROR("Error closing event channel");
@@ -223,7 +224,7 @@  xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
     mem_access_enable = 1;
 
     /* Open event channel */
-    xenaccess->vm_event.xce_handle = xc_evtchn_open(NULL, 0);
+    xenaccess->vm_event.xce_handle = xenevtchn_open(NULL, 0);
     if ( xenaccess->vm_event.xce_handle == NULL )
     {
         ERROR("Failed to open event channel");
@@ -232,7 +233,7 @@  xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
     evtchn_open = 1;
 
     /* Bind event notification */
-    rc = xc_evtchn_bind_interdomain(xenaccess->vm_event.xce_handle,
+    rc = xenevtchn_bind_interdomain(xenaccess->vm_event.xce_handle,
                                     xenaccess->vm_event.domain_id,
                                     xenaccess->vm_event.evtchn_port);
     if ( rc < 0 )
@@ -678,7 +679,7 @@  int main(int argc, char *argv[])
         }
 
         /* Tell Xen page is ready */
-        rc = xc_evtchn_notify(xenaccess->vm_event.xce_handle,
+        rc = xenevtchn_notify(xenaccess->vm_event.xce_handle,
                               xenaccess->vm_event.port);
 
         if ( rc != 0 )
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 20ea100..98056f2 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 1ddb29b..e4602ef 100644
--- a/tools/xenmon/xenbaked.c
+++ b/tools/xenmon/xenbaked.c
@@ -37,6 +37,7 @@ 
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xen/xen.h>
 #include <string.h>
@@ -267,7 +268,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 */
@@ -279,12 +280,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;
   
@@ -304,7 +305,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);
@@ -314,13 +315,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 b5ffee6..df99c6a 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -73,7 +73,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];
@@ -82,7 +82,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;
@@ -146,7 +146,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");
@@ -154,7 +154,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");
@@ -393,7 +393,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");
@@ -401,7 +401,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 )
@@ -531,7 +531,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");
@@ -539,7 +539,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");
@@ -692,7 +692,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 c6ab77c..d0f8d20 100644
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -24,6 +24,7 @@ 
 #define __XEN_PAGING2_H__
 
 
+#include <xenevtchn.h>
 #include <xc_private.h>
 #include <xen/event_channel.h>
 #include <xen/vm_event.h>
@@ -32,7 +33,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 3c0307e..f62c192 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -40,6 +40,8 @@ 
 #include <assert.h>
 #include <setjmp.h>
 
+#include <xenevtchn.h>
+
 #include "utils.h"
 #include "list.h"
 #include "talloc.h"
@@ -63,7 +65,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;
@@ -372,7 +374,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 dcd6581..6ceec29 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -29,6 +29,7 @@ 
 #include "xenstored_transaction.h"
 #include "xenstored_watch.h"
 
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xen/grant_table.h>
 
@@ -36,7 +37,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
 {
@@ -128,7 +129,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;
 }
@@ -158,7 +159,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;
 }
@@ -190,7 +191,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);
 	}
 
@@ -239,13 +240,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");
 }
 
@@ -287,7 +288,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;
@@ -392,8 +393,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 {
@@ -614,7 +615,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; 
 }
@@ -643,7 +644,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");
@@ -651,7 +652,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 6c13cd1..0157be2 100644
--- a/tools/xentrace/Makefile
+++ b/tools/xentrace/Makefile
@@ -3,8 +3,11 @@  include $(XEN_ROOT)/tools/Rules.mk
 
 CFLAGS += -Werror
 
+CFLAGS += $(CFLAGS_libxenevtchn)
 CFLAGS += $(CFLAGS_libxenctrl)
-LDLIBS += $(LDLIBS_libxenctrl) $(ARGP_LDFLAGS)
+LDLIBS += $(LDLIBS_libxenevtchn)
+LDLIBS += $(LDLIBS_libxenctrl)
+LDLIBS += $(ARGP_LDFLAGS)
 
 BIN-$(CONFIG_X86) = xenalyze
 BIN      = $(BIN-y)
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);