[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] libxc: eliminate static variables, use xentoollog; API change



This patch eliminate the global variables in libxenctrl (used for
logging and error reporting).

Instead the information which was in the global variables is now in a
new xc_interface* opaque structure, which xc_interface open returns
instead of the raw file descriptor; furthermore, logging is done via
xentoollog.

There are three new parameters to xc_interface_open to control the
logging, but existing callers can just pass "0" for all three to get
the old behaviour.

All libxc callers have been adjusted accordingly.

Also update QEMU_TAG for corresponding qemu change.

Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 Config.mk                                          |    6 +-
 extras/mini-os/lib/sys.c                           |    5 +-
 stubdom/grub/kexec.c                               |   12 +-
 tools/console/daemon/io.c                          |   15 +-
 tools/console/daemon/utils.c                       |    8 +-
 tools/console/daemon/utils.h                       |    3 +-
 .../gdb/gdbserver/linux-xen-low.c                  |    2 +-
 tools/debugger/xenitp/xenitp.c                     |   10 +-
 tools/flask/libflask/flask_op.c                    |   39 +-
 tools/flask/libflask/include/libflask.h            |   39 +-
 tools/flask/utils/getenforce.c                     |    6 +-
 tools/flask/utils/loadpolicy.c                     |    6 +-
 tools/flask/utils/setenforce.c                     |    6 +-
 tools/fs-back/fs-backend.c                         |   21 +-
 tools/fs-back/fs-backend.h                         |    1 +
 tools/fs-back/fs-ops.c                             |   40 +-
 tools/libxc/ia64/xc_ia64.h                         |    4 +-
 tools/libxc/ia64/xc_ia64_hvm_build.c               |   28 +-
 tools/libxc/ia64/xc_ia64_linux_restore.c           |   26 +-
 tools/libxc/ia64/xc_ia64_linux_save.c              |   16 +-
 tools/libxc/ia64/xc_ia64_stubs.c                   |   14 +-
 tools/libxc/xc_acm.c                               |    4 +-
 tools/libxc/xc_core.c                              |  153 +++---
 tools/libxc/xc_core.h                              |   12 +-
 tools/libxc/xc_core_ia64.c                         |   24 +-
 tools/libxc/xc_core_ia64.h                         |    2 +-
 tools/libxc/xc_core_x86.c                          |   26 +-
 tools/libxc/xc_core_x86.h                          |    2 +-
 tools/libxc/xc_cpu_hotplug.c                       |    8 +-
 tools/libxc/xc_cpuid_x86.c                         |   57 ++-
 tools/libxc/xc_cpupool.c                           |   32 +-
 tools/libxc/xc_csched.c                            |    8 +-
 tools/libxc/xc_csched2.c                           |    8 +-
 tools/libxc/xc_dom.h                               |   32 +-
 tools/libxc/xc_dom_binloader.c                     |   42 +-
 tools/libxc/xc_dom_boot.c                          |   81 ++--
 tools/libxc/xc_dom_bzimageloader.c                 |   69 ++--
 tools/libxc/xc_dom_compat_linux.c                  |   31 +-
 tools/libxc/xc_dom_core.c                          |  253 +++++-----
 tools/libxc/xc_dom_elfloader.c                     |   61 ++-
 tools/libxc/xc_dom_ia64.c                          |   18 +-
 tools/libxc/xc_dom_x86.c                           |  125 +++---
 tools/libxc/xc_domain.c                            |  222 ++++----
 tools/libxc/xc_domain_restore.c                    |  192 ++++----
 tools/libxc/xc_domain_save.c                       |  195 ++++----
 tools/libxc/xc_evtchn.c                            |   16 +-
 tools/libxc/xc_flask.c                             |    4 +-
 tools/libxc/xc_hvm_build.c                         |   63 ++--
 tools/libxc/xc_linux.c                             |  124 +++---
 tools/libxc/xc_mem_event.c                         |   12 +-
 tools/libxc/xc_mem_paging.c                        |   16 +-
 tools/libxc/xc_memshr.c                            |   32 +-
 tools/libxc/xc_minios.c                            |   36 +-
 tools/libxc/xc_misc.c                              |   72 ++--
 tools/libxc/xc_netbsd.c                            |   40 +-
 tools/libxc/xc_offline_page.c                      |  111 +++--
 tools/libxc/xc_pagetab.c                           |   12 +-
 tools/libxc/xc_physdev.c                           |   14 +-
 tools/libxc/xc_pm.c                                |   88 ++--
 tools/libxc/xc_private.c                           |  241 ++++++----
 tools/libxc/xc_private.h                           |   88 ++--
 tools/libxc/xc_ptrace.c                            |   83 ++--
 tools/libxc/xc_ptrace.h                            |    9 +-
 tools/libxc/xc_ptrace_core.c                       |   36 +-
 tools/libxc/xc_resume.c                            |   54 +-
 tools/libxc/xc_sedf.c                              |    8 +-
 tools/libxc/xc_solaris.c                           |   42 +-
 tools/libxc/xc_suspend.c                           |   20 +-
 tools/libxc/xc_tbuf.c                              |   34 +-
 tools/libxc/xc_tmem.c                              |   71 ++--
 tools/libxc/xenctrl.h                              |  525 +++++++++++---------
 tools/libxc/xenguest.h                             |   47 +-
 tools/libxc/xg_private.c                           |   12 +-
 tools/libxc/xg_private.h                           |    8 +-
 tools/libxc/xg_save_restore.h                      |   10 +-
 tools/libxl/libxl.c                                |    4 +-
 tools/libxl/libxl.h                                |    2 +-
 tools/libxl/libxl_dom.c                            |    6 +-
 tools/libxl/libxl_internal.h                       |    2 +-
 tools/libxl/xenguest.c                             |    2 +-
 tools/memshr/interface.c                           |    6 +-
 tools/misc/xen-hptool.c                            |   34 +-
 tools/misc/xen-hvmctx.c                            |    7 +-
 tools/misc/xenlockprof.c                           |    4 +-
 tools/misc/xenperf.c                               |    5 +-
 tools/misc/xenpm.c                                 |  122 +++---
 tools/python/xen/lowlevel/acm/acm.c                |   26 +-
 tools/python/xen/lowlevel/checkpoint/checkpoint.h  |    2 +-
 .../python/xen/lowlevel/checkpoint/libcheckpoint.c |   12 +-
 tools/python/xen/lowlevel/flask/flask.c            |   44 +-
 tools/python/xen/lowlevel/xc/xc.c                  |  196 ++++----
 tools/security/secpol_tool.c                       |   16 +-
 tools/xcutils/lsevtchn.c                           |   11 +-
 tools/xcutils/readnotes.c                          |   11 +-
 tools/xcutils/xc_restore.c                         |   11 +-
 tools/xcutils/xc_save.c                            |   18 +-
 tools/xenmon/setmask.c                             |    2 +-
 tools/xenmon/xenbaked.c                            |   19 +-
 tools/xenpaging/file_ops.c                         |    1 +
 tools/xenpaging/policy.h                           |    3 +-
 tools/xenpaging/policy_default.c                   |    3 +-
 tools/xenpaging/xc.c                               |    9 +-
 tools/xenpaging/xc.h                               |    7 +-
 tools/xenpaging/xenpaging.c                        |   44 +-
 tools/xenpaging/xenpaging.h                        |    2 +-
 tools/xenstat/libxenstat/src/xenstat.c             |    4 +-
 tools/xenstat/libxenstat/src/xenstat_priv.h        |    2 +-
 tools/xenstore/xenstored_domain.c                  |   11 +-
 tools/xentrace/setsize.c                           |    2 +-
 tools/xentrace/xenctx.c                            |    6 +-
 tools/xentrace/xentrace.c                          |   14 +-
 111 files changed, 2383 insertions(+), 2179 deletions(-)
 create mode 100644 tools/libxc/INPROGRESS

diff --git a/Config.mk b/Config.mk
index 3750ab6..95de614 100644
--- a/Config.mk
+++ b/Config.mk
@@ -154,9 +154,9 @@ 
QEMU_REMOTE=http://xenbits.xensource.com/git-http/qemu-xen-unstable.git
 # CONFIG_QEMU ?= ../qemu-xen.git
 CONFIG_QEMU ?= $(QEMU_REMOTE)
 
-QEMU_TAG ?= 805ed3b20492d2f4bb465bfda65cedd286e23209
-# Fri May 21 15:46:55 2010 +0100
-# Wait for frontend state Connected before connecting the backend
+QEMU_TAG ?= ffb0cf2ad55e952dae55e6166c4fcea79be6cd30
+# Thu Apr 15 17:01:15 2010 +0100
+# Change callers of libxc to use new libxc API.
 
 # Optional components
 XENSTAT_XENTOP     ?= y
diff --git a/extras/mini-os/lib/sys.c b/extras/mini-os/lib/sys.c
index 9ce9954..4268174 100644
--- a/extras/mini-os/lib/sys.c
+++ b/extras/mini-os/lib/sys.c
@@ -84,7 +84,8 @@
 
 #define NOFILE 32
 extern int xc_evtchn_close(int fd);
-extern int xc_interface_close(int fd);
+struct xc_interface;
+extern int xc_interface_close_core(struct xc_interface*, int fd);
 extern int xc_gnttab_close(int fd);
 
 pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -413,7 +414,7 @@ int close(int fd)
        }
 #endif
        case FTYPE_XC:
-           xc_interface_close(fd);
+           xc_interface_close_core(0,fd);
            return 0;
        case FTYPE_EVTCHN:
             xc_evtchn_close(fd);
diff --git a/stubdom/grub/kexec.c b/stubdom/grub/kexec.c
index 5b86c50..5281d0b 100644
--- a/stubdom/grub/kexec.c
+++ b/stubdom/grub/kexec.c
@@ -50,7 +50,7 @@ static unsigned long *pages;
 static unsigned long *pages_mfns;
 static unsigned long allocated;
 
-int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
+int pin_table(xc_interface *xc_handle, unsigned int type, unsigned long mfn,
               domid_t dom);
 
 /* We need mfn to appear as target_pfn, so exchange with the MFN there */
@@ -109,7 +109,7 @@ void kexec(void *kernel, long kernel_size, void *module, 
long module_size, char
     int rc;
     domid_t domid = DOMID_SELF;
     xen_pfn_t pfn;
-    int xc_handle;
+    xc_interface *xc_handle;
     unsigned long i;
     void *seg;
     xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
@@ -118,9 +118,9 @@ void kexec(void *kernel, long kernel_size, void *module, 
long module_size, char
     unsigned long nr_m2p_updates;
 
     DEBUG("booting with cmdline %s\n", cmdline);
-    xc_handle = xc_interface_open();
+    xc_handle = xc_interface_open(0,0,0);
 
-    dom = xc_dom_allocate(cmdline, features);
+    dom = xc_dom_allocate(xc_handle, cmdline, features);
     dom->allocate = kexec_allocate;
 
     dom->kernel_blob = kernel;
@@ -160,7 +160,7 @@ void kexec(void *kernel, long kernel_size, void *module, 
long module_size, char
 #endif
 
     /* equivalent of xc_dom_mem_init */
-    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
+    dom->arch_hooks = xc_dom_find_arch_hooks(xc_handle, dom->guest_type);
     dom->total_pages = start_info.nr_pages;
 
     /* equivalent of arch_setup_meminit */
@@ -238,7 +238,7 @@ void kexec(void *kernel, long kernel_size, void *module, 
long module_size, char
         munmap((void*) pages[pfn], PAGE_SIZE);
 
     /* Pin the boot page table base */
-    if ( (rc = pin_table(dom->guest_xc, 
+    if ( (rc = pin_table(dom->xch,
 #ifdef __i386__
                 MMUEXT_PIN_L3_TABLE,
 #endif
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index 22833d7..7688a1a 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -24,7 +24,6 @@
 #include "io.h"
 #include <xs.h>
 #include <xen/io/console.h>
-#include <xenctrl.h>
 
 #include <stdlib.h>
 #include <errno.h>
@@ -68,7 +67,7 @@ static int log_time_hv_needts = 1;
 static int log_time_guest_needts = 1;
 static int log_hv_fd = -1;
 static evtchn_port_or_error_t log_hv_evtchn = -1;
-static int xc_handle = -1;
+static xc_interface *xch; /* why does xenconsoled have two xc handles ? */
 static int xce_handle = -1;
 
 struct buffer {
@@ -932,7 +931,7 @@ static void handle_hv_logs(void)
        if ((port = xc_evtchn_pending(xce_handle)) == -1)
                return;
 
-       if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0 && 
size > 0) {
+       if (xc_readconsolering(xch, &bufptr, &size, 0, 1, &index) == 0 && size 
> 0) {
                int logret;
                if (log_time_hv)
                        logret = write_with_timestamp(log_hv_fd, buffer, size,
@@ -972,8 +971,8 @@ void handle_io(void)
        int ret;
 
        if (log_hv) {
-               xc_handle = xc_interface_open();
-               if (xc_handle == -1) {
+               xch = xc_interface_open(0,0,0);
+               if (!xch) {
                        dolog(LOG_ERR, "Failed to open xc handle: %d (%s)",
                              errno, strerror(errno));
                        goto out;
@@ -1124,9 +1123,9 @@ void handle_io(void)
                close(log_hv_fd);
                log_hv_fd = -1;
        }
-       if (xc_handle != -1) {
-               xc_interface_close(xc_handle);
-               xc_handle = -1;
+       if (xch) {
+               xc_interface_close(xch);
+               xch = 0;
        }
        if (xce_handle != -1) {
                xc_evtchn_close(xce_handle);
diff --git a/tools/console/daemon/utils.c b/tools/console/daemon/utils.c
index 7b3cd19..aab6f42 100644
--- a/tools/console/daemon/utils.c
+++ b/tools/console/daemon/utils.c
@@ -38,7 +38,7 @@
 #include "utils.h"
 
 struct xs_handle *xs;
-int xc;
+xc_interface *xc;
 
 static void child_exit(int sig)
 {
@@ -116,8 +116,8 @@ bool xen_setup(void)
                goto out;
        }
 
-       xc = xc_interface_open();
-       if (xc == -1) {
+       xc = xc_interface_open(0,0,0);
+       if (!xc) {
                dolog(LOG_ERR, "Failed to contact hypervisor (%m)");
                goto out;
        }
@@ -137,7 +137,7 @@ bool xen_setup(void)
  out:
        if (xs)
                xs_daemon_close(xs);
-       if (xc != -1)
+       if (xc)
                xc_interface_close(xc);
        return false;
 }
diff --git a/tools/console/daemon/utils.h b/tools/console/daemon/utils.h
index 44b3e2a..6743e5f 100644
--- a/tools/console/daemon/utils.h
+++ b/tools/console/daemon/utils.h
@@ -24,6 +24,7 @@
 #include <stdbool.h>
 #include <syslog.h>
 #include <stdio.h>
+#include <xenctrl.h>
 
 #include "xs.h"
 
@@ -31,7 +32,7 @@ void daemonize(const char *pidfile);
 bool xen_setup(void);
 
 extern struct xs_handle *xs;
-extern int xc;
+extern xc_interface *xc;
 
 #if 1
 #define dolog(val, fmt, ...) do {                              \
diff --git 
a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c 
b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
index 8b0b6d9..8b29135 100644
--- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
+++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c
@@ -39,7 +39,7 @@
 
 #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
 
-static int xc_handle;
+static xc_interface *xc_handle;
 
 static inline int
 curvcpuid()
diff --git a/tools/debugger/xenitp/xenitp.c b/tools/debugger/xenitp/xenitp.c
index 847d7bd..812810c 100644
--- a/tools/debugger/xenitp/xenitp.c
+++ b/tools/debugger/xenitp/xenitp.c
@@ -40,7 +40,7 @@
 #include <xen/arch-ia64/debug_op.h>
 #endif
 
-static int xc_handle = 0;
+static xc_interface *xc_handle = 0;
 static int domid = 0;
 static vcpu_guest_context_t *cur_ctx;
 static int cur_vcpu;
@@ -59,7 +59,7 @@ static int cur_vcpu;
 int virt_to_phys (int is_inst, unsigned long vaddr, unsigned long *paddr);
 
 /* wrapper for vcpu_gest_context_any_t */
-static int xc_ia64_vcpu_getcontext(int xc_handle,
+static int xc_ia64_vcpu_getcontext(xc_interface *xc_handle,
                                    uint32_t domid,
                                    uint32_t vcpu,
                                    vcpu_guest_context_t *ctxt)
@@ -660,10 +660,10 @@ void print_tr (vcpu_guest_context_t *ctx)
 
 int lock_pages (void *addr, size_t len);
 void unlock_pages (void *addr, size_t len);
-int do_xen_hypercall (int xc_handle, privcmd_hypercall_t *hypercall);
+int do_xen_hypercall (xc_interface *xc_handle, privcmd_hypercall_t *hypercall);
 
 #ifdef HAVE_DEBUG_OP
-static int do_ia64_debug_op (int xc_handle,
+static int do_ia64_debug_op (xc_interface *xc_handle,
                             unsigned long cmd, unsigned long domain,
                             xen_ia64_debug_op_t *op)
 {
@@ -1663,7 +1663,7 @@ void xenitp (int vcpu)
         }
     }
 
-    xc_interface_close (xc_handle);
+    ret = xc_interface_close (xc_handle);
     if (ret < 0) {
         perror ("xc_interface_close");
         exit (-1);
diff --git a/tools/flask/libflask/flask_op.c b/tools/flask/libflask/flask_op.c
index 29c3cd1..d4b8ef0 100644
--- a/tools/flask/libflask/flask_op.c
+++ b/tools/flask/libflask/flask_op.c
@@ -20,9 +20,8 @@
 #include <stdint.h>
 #include <sys/ioctl.h>
 #include <libflask.h>
-#include <xenctrl.h>
 
-int flask_load(int xc_handle, char *buf, uint32_t size)
+int flask_load(xc_interface *xc_handle, char *buf, uint32_t size)
 {
     int err;
     flask_op_t op;
@@ -37,7 +36,7 @@ int flask_load(int xc_handle, char *buf, uint32_t size)
     return 0;
 }
 
-int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t 
*sid)
+int flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, 
uint32_t *sid)
 {
     int err;
     flask_op_t op;
@@ -54,7 +53,7 @@ int flask_context_to_sid(int xc_handle, char *buf, uint32_t 
size, uint32_t *sid)
     return 0;
 }
 
-int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size)
+int flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t 
size)
 {
     int err;
     flask_op_t op;
@@ -71,7 +70,7 @@ int flask_sid_to_context(int xc_handle, int sid, char *buf, 
uint32_t size)
     return 0;
 }
 
-int flask_getenforce(int xc_handle)
+int flask_getenforce(xc_interface *xc_handle)
 {
     int err;
     flask_op_t op;
@@ -91,7 +90,7 @@ int flask_getenforce(int xc_handle)
     return mode;
 }
 
-int flask_setenforce(int xc_handle, int mode)
+int flask_setenforce(xc_interface *xc_handle, int mode)
 {
     int err;
     flask_op_t op;
@@ -110,7 +109,7 @@ int flask_setenforce(int xc_handle, int mode)
     return 0;
 }
 
-int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext)
+int flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext)
 {
     int err;
     flask_op_t op;
@@ -139,7 +138,7 @@ int flask_add_pirq(int xc_handle, unsigned int pirq, char 
*scontext)
 
 }
 
-int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
+int flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long 
high,
                       char *scontext)
 {
     int err;
@@ -169,7 +168,7 @@ int flask_add_ioport(int xc_handle, unsigned long low, 
unsigned long high,
 
 }
 
-int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
+int flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long 
high,
                      char *scontext)
 {
     int err;
@@ -199,7 +198,7 @@ int flask_add_iomem(int xc_handle, unsigned long low, 
unsigned long high,
 
 }
 
-int flask_add_device(int xc_handle, unsigned long device, char *scontext)
+int flask_add_device(xc_interface *xc_handle, unsigned long device, char 
*scontext)
 {
     int err;
     flask_op_t op;
@@ -228,7 +227,7 @@ int flask_add_device(int xc_handle, unsigned long device, 
char *scontext)
 
 }
 
-int flask_del_pirq(int xc_handle, unsigned int pirq)
+int flask_del_pirq(xc_interface *xc_handle, unsigned int pirq)
 {
     int err;
     flask_op_t op;
@@ -257,7 +256,7 @@ int flask_del_pirq(int xc_handle, unsigned int pirq)
 
 }
 
-int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high)
+int flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long 
high)
 {
     int err;
     flask_op_t op;
@@ -286,7 +285,7 @@ int flask_del_ioport(int xc_handle, unsigned long low, 
unsigned long high)
 
 }
 
-int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high)
+int flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long 
high)
 {
     int err;
     flask_op_t op;
@@ -315,7 +314,7 @@ int flask_del_iomem(int xc_handle, unsigned long low, 
unsigned long high)
 
 }
 
-int flask_del_device(int xc_handle, unsigned long device)
+int flask_del_device(xc_interface *xc_handle, unsigned long device)
 {
     int err;
     flask_op_t op;
@@ -343,7 +342,7 @@ int flask_del_device(int xc_handle, unsigned long device)
 
 }
 
-int flask_access(int xc_handle, const char *scon, const char *tcon,
+int flask_access(xc_interface *xc_handle, const char *scon, const char *tcon,
                 u_int16_t tclass, u_int32_t req,
                 u_int32_t *allowed, u_int32_t *decided,
                 u_int32_t *auditallow, u_int32_t *auditdeny,
@@ -407,7 +406,7 @@ int flask_access(int xc_handle, const char *scon, const 
char *tcon,
 
 }
 
-int flask_avc_hashstats(int xc_handle, char *buf, int size)
+int flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size)
 {
     int err;
     flask_op_t op;
@@ -425,7 +424,7 @@ int flask_avc_hashstats(int xc_handle, char *buf, int size)
     return 0;
 }
 
-int flask_avc_cachestats(int xc_handle, char *buf, int size)
+int flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size)
 {
     int err;
     flask_op_t op;
@@ -443,7 +442,7 @@ int flask_avc_cachestats(int xc_handle, char *buf, int size)
     return 0;
 }
 
-int flask_policyvers(int xc_handle, char *buf, int size)
+int flask_policyvers(xc_interface *xc_handle, char *buf, int size)
 {
     int err;
     flask_op_t op;
@@ -461,7 +460,7 @@ int flask_policyvers(int xc_handle, char *buf, int size)
     return 0;
 }
 
-int flask_getavc_threshold(int xc_handle)
+int flask_getavc_threshold(xc_interface *xc_handle)
 {
     int err;
     flask_op_t op;
@@ -481,7 +480,7 @@ int flask_getavc_threshold(int xc_handle)
     return threshold;
 }
 
-int flask_setavc_threshold(int xc_handle, int threshold)
+int flask_setavc_threshold(xc_interface *xc_handle, int threshold)
 {
     int err;
     flask_op_t op;
diff --git a/tools/flask/libflask/include/libflask.h 
b/tools/flask/libflask/include/libflask.h
index 7548d4e..e4c34b8 100644
--- a/tools/flask/libflask/include/libflask.h
+++ b/tools/flask/libflask/include/libflask.h
@@ -14,32 +14,33 @@
 #include <stdint.h>
 #include <xen/xen.h>
 #include <xen/xsm/flask_op.h>
+#include <xenctrl.h>
 
-int flask_load(int xc_handle, char *buf, uint32_t size);
-int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t 
*sid);
-int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size);
-int flask_getenforce(int xc_handle);
-int flask_setenforce(int xc_handle, int mode);
-int flask_add_pirq(int xc_handle, unsigned int pirq, char *scontext);
-int flask_add_ioport(int xc_handle, unsigned long low, unsigned long high,
+int flask_load(xc_interface *xc_handle, char *buf, uint32_t size);
+int flask_context_to_sid(xc_interface *xc_handle, char *buf, uint32_t size, 
uint32_t *sid);
+int flask_sid_to_context(xc_interface *xc_handle, int sid, char *buf, uint32_t 
size);
+int flask_getenforce(xc_interface *xc_handle);
+int flask_setenforce(xc_interface *xc_handle, int mode);
+int flask_add_pirq(xc_interface *xc_handle, unsigned int pirq, char *scontext);
+int flask_add_ioport(xc_interface *xc_handle, unsigned long low, unsigned long 
high,
                       char *scontext);
-int flask_add_iomem(int xc_handle, unsigned long low, unsigned long high,
+int flask_add_iomem(xc_interface *xc_handle, unsigned long low, unsigned long 
high,
                      char *scontext);
-int flask_add_device(int xc_handle, unsigned long device, char *scontext);
-int flask_del_pirq(int xc_handle, unsigned int pirq);
-int flask_del_ioport(int xc_handle, unsigned long low, unsigned long high);
-int flask_del_iomem(int xc_handle, unsigned long low, unsigned long high);
-int flask_del_device(int xc_handle, unsigned long device);
-int flask_access(int xc_handle, const char *scon, const char *tcon,
+int flask_add_device(xc_interface *xc_handle, unsigned long device, char 
*scontext);
+int flask_del_pirq(xc_interface *xc_handle, unsigned int pirq);
+int flask_del_ioport(xc_interface *xc_handle, unsigned long low, unsigned long 
high);
+int flask_del_iomem(xc_interface *xc_handle, unsigned long low, unsigned long 
high);
+int flask_del_device(xc_interface *xc_handle, unsigned long device);
+int flask_access(xc_interface *xc_handle, const char *scon, const char *tcon,
                   u_int16_t tclass, u_int32_t req,
                   u_int32_t *allowed, u_int32_t *decided,
                   u_int32_t *auditallow, u_int32_t *auditdeny,
                   u_int32_t *seqno);
-int flask_avc_cachestats(int xc_handle, char *buf, int size);
-int flask_policyvers(int xc_handle, char *buf, int size);
-int flask_avc_hashstats(int xc_handle, char *buf, int size);
-int flask_getavc_threshold(int xc_handle);
-int flask_setavc_threshold(int xc_handle, int threshold);
+int flask_avc_cachestats(xc_interface *xc_handle, char *buf, int size);
+int flask_policyvers(xc_interface *xc_handle, char *buf, int size);
+int flask_avc_hashstats(xc_interface *xc_handle, char *buf, int size);
+int flask_getavc_threshold(xc_interface *xc_handle);
+int flask_setavc_threshold(xc_interface *xc_handle, int threshold);
 #define flask_add_single_ioport(x, l, s) flask_add_ioport(x, l, l, s)
 #define flask_add_single_iomem(x, l, s) flask_add_iomem(x, l, l, s)
 #define flask_del_single_ioport(x, l) flask_del_ioport(x, l, l)
diff --git a/tools/flask/utils/getenforce.c b/tools/flask/utils/getenforce.c
index 1706f6a..281fc81 100644
--- a/tools/flask/utils/getenforce.c
+++ b/tools/flask/utils/getenforce.c
@@ -27,13 +27,13 @@ static void usage (int argCnt, const char *args[])
 int main (int argCnt, const char *args[])
 {
     int ret;
-    int xch = 0;
+    xc_interface *xch = 0;
 
     if (argCnt != 1)
         usage(argCnt, args);
 
-    xch = xc_interface_open();
-    if ( xch < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
     {
         fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
                 strerror(errno));
diff --git a/tools/flask/utils/loadpolicy.c b/tools/flask/utils/loadpolicy.c
index 13e4cb2..4e99c71 100644
--- a/tools/flask/utils/loadpolicy.c
+++ b/tools/flask/utils/loadpolicy.c
@@ -35,7 +35,7 @@ int main (int argCnt, const char *args[])
     void *polMemCp = NULL;
     struct stat info;
     int ret;
-    int xch = 0;
+    xc_interface *xch = 0;
 
     if (argCnt != 2)
         usage(argCnt, args);
@@ -70,8 +70,8 @@ int main (int argCnt, const char *args[])
         goto cleanup;
     }
 
-    xch = xc_interface_open();
-    if ( xch < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
     {
         fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
                 strerror(errno));
diff --git a/tools/flask/utils/setenforce.c b/tools/flask/utils/setenforce.c
index 60e8eb0..63928bd 100644
--- a/tools/flask/utils/setenforce.c
+++ b/tools/flask/utils/setenforce.c
@@ -27,15 +27,15 @@ static void usage (int argCnt, const char *args[])
 int main (int argCnt, const char *args[])
 {
     int ret = 0;
-    int xch = 0;
+    xc_interface *xch = 0;
     long mode = 0;
     char *end;
 
     if (argCnt != 2)
         usage(argCnt, args);
 
-    xch = xc_interface_open();
-    if ( xch < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
     {
         fprintf(stderr, "Unable to create interface to xenctrl: %s\n",
                 strerror(errno));
diff --git a/tools/fs-back/fs-backend.c b/tools/fs-back/fs-backend.c
index e888282..1737baf 100644
--- a/tools/fs-back/fs-backend.c
+++ b/tools/fs-back/fs-backend.c
@@ -168,8 +168,9 @@ void terminate_mount_request(struct fs_mount *mount)
     }
     xenbus_write_backend_state(mount, STATE_CLOSED);
 
-    xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size);
-    xc_gnttab_close(mount->gnth);
+    xc_gnttab_munmap(mount->xch, mount->gnth,
+                     mount->ring.sring, mount->shared_ring_size);
+    xc_gnttab_close(mount->xch, mount->gnth);
     xc_evtchn_unbind(mount->evth, mount->local_evtchn);
     xc_evtchn_close(mount->evth);
 
@@ -213,6 +214,9 @@ static void handle_connection(int frontend_dom_id, int 
export_id, char *frontend
 
     mount = (struct fs_mount*)malloc(sizeof(struct fs_mount));
     memset(mount, 0, sizeof(struct fs_mount));
+    mount->xch = xc_interface_open(0,0,XC_OPENFLAG_DUMMY);
+    if (!mount->xch) goto error;
+
     mount->dom_id = frontend_dom_id;
     mount->export = export;
     mount->mount_id = mount_id++;
@@ -239,14 +243,14 @@ static void handle_connection(int frontend_dom_id, int 
export_id, char *frontend
         goto error;
     }
     mount->gnth = -1;
-    mount->gnth = xc_gnttab_open(); 
+    mount->gnth = xc_gnttab_open(mount->xch);
     if (mount->gnth < 0) {
         FS_DEBUG("ERROR: Couldn't open gnttab!\n");
         goto error;
     }
     for(i=0; i<mount->shared_ring_size; i++)
         dom_ids[i] = mount->dom_id;
-    sring = xc_gnttab_map_grant_refs(mount->gnth,
+    sring = xc_gnttab_map_grant_refs(mount->xch, mount->gnth,
                                      mount->shared_ring_size,
                                      dom_ids,
                                      mount->grefs,
@@ -279,13 +283,16 @@ static void handle_connection(int frontend_dom_id, int 
export_id, char *frontend
 error:
     xenbus_write_backend_state(mount, STATE_CLOSED);
     if (sring)
-        xc_gnttab_munmap(mount->gnth, mount->ring.sring, 
mount->shared_ring_size);
+        xc_gnttab_munmap(mount->xch, mount->gnth,
+                         mount->ring.sring, mount->shared_ring_size);
     if (mount->gnth > 0)
-        xc_gnttab_close(mount->gnth);
+        xc_gnttab_close(mount->xch, mount->gnth);
     if (mount->local_evtchn > 0)
         xc_evtchn_unbind(mount->evth, mount->local_evtchn);
     if (mount->evth > 0)
         xc_evtchn_close(mount->evth);
+    if (mount->xch)
+        xc_interface_close(mount->xch);
 }
 
 static void await_connections(void)
@@ -472,7 +479,7 @@ int main(void)
     /* Close the connection to XenStore when we are finished with everything */
     xs_daemon_close(xsh);
 #if 0
-    int xc_handle;
+    xc_interface *xc_handle;
     char *shared_page;
     int prot = PROT_READ | PROT_WRITE;
   
diff --git a/tools/fs-back/fs-backend.h b/tools/fs-back/fs-backend.h
index 713eb3d..9ffc9c2 100644
--- a/tools/fs-back/fs-backend.h
+++ b/tools/fs-back/fs-backend.h
@@ -44,6 +44,7 @@ struct fs_mount
     int mount_id;                     /* = backend id */
     grant_ref_t grefs[MAX_RING_SIZE];
     evtchn_port_t remote_evtchn;
+    xc_interface *xch; /* just for error logging, so a dummy */
     int evth;                         /* Handle to the event channel */
     evtchn_port_t local_evtchn;
     int gnth;
diff --git a/tools/fs-back/fs-ops.c b/tools/fs-back/fs-ops.c
index 2dc9ba6..8f87592 100644
--- a/tools/fs-back/fs-ops.c
+++ b/tools/fs-back/fs-ops.c
@@ -75,7 +75,7 @@ static void dispatch_file_open(struct fs_mount *mount, struct 
fsif_request *req)
 
     FS_DEBUG("Dispatching file open operation (gref=%d).\n", 
req->u.fopen.gref);
     /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
+    file_name = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                         mount->dom_id,
                                         req->u.fopen.gref,
                                         PROT_READ);
@@ -99,7 +99,7 @@ static void dispatch_file_open(struct fs_mount *mount, struct 
fsif_request *req)
         }
     }
 out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, file_name, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -159,7 +159,7 @@ static void dispatch_file_read(struct fs_mount *mount, 
struct fsif_request *req)
     assert(req->u.fread.len > 0); 
     count = (req->u.fread.len - 1) / XC_PAGE_SIZE + 1;
     assert(count <= FSIF_NR_READ_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
+    buf = xc_gnttab_map_domain_grant_refs(mount->xch, mount->gnth,
                                           count,
                                           mount->dom_id,
                                           req->u.fread.grefs,
@@ -192,7 +192,8 @@ static void dispatch_file_read(struct fs_mount *mount, 
struct fsif_request *req)
     priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
     if (aio_read(&priv_req->aiocb) < 0) {
         FS_DEBUG("ERROR: aio_read failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count);
+        xc_gnttab_munmap(mount->xch, mount->gnth,
+                         priv_req->page, priv_req->count);
         terminate_mount_request(mount);
     }
 
@@ -208,7 +209,8 @@ static void end_file_read(struct fs_mount *mount, struct 
fs_request *priv_req)
     uint16_t req_id;
 
     /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth,
+                         priv_req->page, priv_req->count) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -234,7 +236,7 @@ static void dispatch_file_write(struct fs_mount *mount, 
struct fsif_request *req
     assert(req->u.fwrite.len > 0); 
     count = (req->u.fwrite.len - 1) / XC_PAGE_SIZE + 1;
     assert(count <= FSIF_NR_WRITE_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
+    buf = xc_gnttab_map_domain_grant_refs(mount->xch, mount->gnth,
                                           count,
                                           mount->dom_id,
                                           req->u.fwrite.grefs,
@@ -267,7 +269,8 @@ static void dispatch_file_write(struct fs_mount *mount, 
struct fsif_request *req
     priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
     if (aio_write(&priv_req->aiocb) < 0) {
         FS_DEBUG("ERROR: aio_write failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count);
+        xc_gnttab_munmap(mount->xch, mount->gnth,
+                         priv_req->page, priv_req->count);
         terminate_mount_request(mount);
     }
 
@@ -284,7 +287,8 @@ static void end_file_write(struct fs_mount *mount, struct 
fs_request *priv_req)
     uint16_t req_id;
 
     /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth,
+                         priv_req->page, priv_req->count) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -391,7 +395,7 @@ static void dispatch_remove(struct fs_mount *mount, struct 
fsif_request *req)
 
     FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref);
     /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
+    file_name = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                         mount->dom_id,
                                         req->u.fremove.gref,
                                         PROT_READ);
@@ -405,7 +409,7 @@ static void dispatch_remove(struct fs_mount *mount, struct 
fsif_request *req)
         ret = remove(file_name);
     }
     FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, file_name, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -433,7 +437,7 @@ static void dispatch_rename(struct fs_mount *mount, struct 
fsif_request *req)
 
     FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref);
     /* Read the request, and open file */
-    buf = xc_gnttab_map_grant_ref(mount->gnth,
+    buf = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                   mount->dom_id,
                                   req->u.frename.gref,
                                   PROT_READ);
@@ -451,7 +455,7 @@ static void dispatch_rename(struct fs_mount *mount, struct 
fsif_request *req)
         ret = rename(old_file_name, new_file_name);
     }
     FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, buf, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, buf, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -483,7 +487,7 @@ static void dispatch_create(struct fs_mount *mount, struct 
fsif_request *req)
     /* Read the request, and create file/directory */
     mode = req->u.fcreate.mode;
     directory = req->u.fcreate.directory;
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
+    file_name = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                         mount->dom_id,
                                         req->u.fcreate.gref,
                                         PROT_READ);
@@ -519,7 +523,7 @@ static void dispatch_create(struct fs_mount *mount, struct 
fsif_request *req)
         }
     }
 out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, file_name, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -547,7 +551,7 @@ static void dispatch_list(struct fs_mount *mount, struct 
fsif_request *req)
     FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref);
     /* Read the request, and list directory */
     offset = req->u.flist.offset;
-    buf = file_name = xc_gnttab_map_grant_ref(mount->gnth,
+    buf = file_name = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                         mount->dom_id,
                                         req->u.flist.gref,
                                         PROT_READ | PROT_WRITE);
@@ -595,7 +599,7 @@ error_out:
     ret_val = ((nr_files << NR_FILES_SHIFT) & NR_FILES_MASK) | 
               ((error_code << ERROR_SHIFT) & ERROR_MASK) | 
               (dirent != NULL ? HAS_MORE_FLAG : 0);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, file_name, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
@@ -650,7 +654,7 @@ static void dispatch_fs_space(struct fs_mount *mount, 
struct fsif_request *req)
 
     FS_DEBUG("Dispatching fs space operation (gref=%d).\n", 
req->u.fspace.gref);
     /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
+    file_name = xc_gnttab_map_grant_ref(mount->xch, mount->gnth,
                                         mount->dom_id,
                                         req->u.fspace.gref,
                                         PROT_READ);
@@ -666,7 +670,7 @@ static void dispatch_fs_space(struct fs_mount *mount, 
struct fsif_request *req)
     if(ret >= 0)
         ret = stat.f_bsize * stat.f_bfree;
 
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
+    if (xc_gnttab_munmap(mount->xch, mount->gnth, file_name, 1) != 0) {
         FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
         terminate_mount_request(mount);
     }
diff --git a/tools/libxc/INPROGRESS b/tools/libxc/INPROGRESS
new file mode 100644
index 0000000..e69de29
diff --git a/tools/libxc/ia64/xc_ia64.h b/tools/libxc/ia64/xc_ia64.h
index 3c1d27e..d0c8da2 100644
--- a/tools/libxc/ia64/xc_ia64.h
+++ b/tools/libxc/ia64/xc_ia64.h
@@ -21,7 +21,7 @@
 #ifndef _XC_IA64_H_
 #define _XC_IA64_H_
 
-int xc_ia64_copy_memmap(int xc_handle, uint32_t domid,
+int xc_ia64_copy_memmap(xc_interface *xc_handle, uint32_t domid,
                         shared_info_t *live_shinfo,
                         xen_ia64_memmap_info_t **memmap_info_p,
                         unsigned long *memmap_info_num_pages_p);
@@ -32,7 +32,7 @@ struct xen_ia64_p2m_table {
 };
 
 void xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table);
-int xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, int xc_handle,
+int xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, xc_interface 
*xc_handle,
                     uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
                     unsigned long flag);
 void xc_ia64_p2m_unmap(struct xen_ia64_p2m_table *p2m_table);
diff --git a/tools/libxc/ia64/xc_ia64_hvm_build.c 
b/tools/libxc/ia64/xc_ia64_hvm_build.c
index 291679e..d3d02aa 100644
--- a/tools/libxc/ia64/xc_ia64_hvm_build.c
+++ b/tools/libxc/ia64/xc_ia64_hvm_build.c
@@ -13,7 +13,7 @@
 #include <xen/hvm/params.h>
 
 static int
-xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, void* src_page,
+xc_ia64_copy_to_domain_pages(xc_interface *xc_handle, uint32_t domid, void* 
src_page,
                              unsigned long dst_pfn, int nr_pages)
 {
     // N.B. gva should be page aligned
@@ -90,10 +90,10 @@ static int add_nvram_hob(void* hob_buf, unsigned long 
nvram_addr);
 static int build_hob(void* hob_buf, unsigned long hob_buf_size,
                      unsigned long dom_mem_size, unsigned long vcpus,
                      unsigned long nvram_addr);
-static int load_hob(int xc_handle,uint32_t dom, void *hob_buf);
+static int load_hob(xc_interface *xc_handle,uint32_t dom, void *hob_buf);
 
 static int
-xc_ia64_build_hob(int xc_handle, uint32_t dom,
+xc_ia64_build_hob(xc_interface *xc_handle, uint32_t dom,
                   unsigned long memsize, unsigned long vcpus,
                   unsigned long nvram_addr)
 {
@@ -239,7 +239,7 @@ err_out:
 }
 
 static int
-load_hob(int xc_handle, uint32_t dom, void *hob_buf)
+load_hob(xc_interface *xc_handle, uint32_t dom, void *hob_buf)
 {
     // hob_buf should be page aligned
     int hob_size;
@@ -545,7 +545,7 @@ nvram_init(const char *nvram_path)
 }
 
 static int 
-copy_from_nvram_to_GFW(int xc_handle, uint32_t dom, int nvram_fd)
+copy_from_nvram_to_GFW(xc_interface *xc_handle, uint32_t dom, int nvram_fd)
 {
     unsigned int nr_pages = NVRAM_SIZE >> PAGE_SHIFT;
     struct stat file_stat;
@@ -597,7 +597,7 @@ static int is_valid_address(void *addr)
  * can be got.
  */
 static int
-copy_from_GFW_to_nvram(int xc_handle, uint32_t dom, int nvram_fd)
+copy_from_GFW_to_nvram(xc_interface *xc_handle, uint32_t dom, int nvram_fd)
 {
     xen_pfn_t *pfn_list = NULL;
     char *tmp_ptr = NULL;
@@ -686,7 +686,7 @@ copy_from_GFW_to_nvram(int xc_handle, uint32_t dom, int 
nvram_fd)
     return 0;
 }
 
-int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom) 
+int xc_ia64_save_to_nvram(xc_interface *xc_handle, uint32_t dom) 
 {
     xc_dominfo_t info;
     uint64_t nvram_fd = 0;
@@ -717,7 +717,7 @@ int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom)
 #define NVRAM_DIR         "/var/lib/xen/nvram/"
 #define NVRAM_FILE_PREFIX "nvram_"
 
-int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom)
+int xc_ia64_nvram_init(xc_interface *xc_handle, char *dom_name, uint32_t dom)
 {
     uint64_t nvram_fd;
     char nvram_path[PATH_MAX] = NVRAM_DIR;
@@ -784,7 +784,7 @@ min(unsigned long lhs, unsigned long rhs)
 }
 
 static int
-xc_ia64_setup_memmap_info(int xc_handle, uint32_t dom,
+xc_ia64_setup_memmap_info(xc_interface *xc_handle, uint32_t dom,
                           unsigned long dom_memsize, /* in bytes */
                           unsigned long *pfns_special_pages, 
                           unsigned long nr_special_pages,
@@ -861,7 +861,7 @@ xc_ia64_setup_memmap_info(int xc_handle, uint32_t dom,
 
 /* setup shared_info page */
 static int
-xc_ia64_setup_shared_info(int xc_handle, uint32_t dom,
+xc_ia64_setup_shared_info(xc_interface *xc_handle, uint32_t dom,
                           unsigned long shared_info_pfn,
                           unsigned long memmap_info_pfn,
                           unsigned long memmap_info_num_pages)
@@ -891,7 +891,7 @@ xc_ia64_setup_shared_info(int xc_handle, uint32_t dom,
  * convenient to allocate discontiguous memory with different size.
  */
 static int
-setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
+setup_guest(xc_interface *xc_handle, uint32_t dom, unsigned long memsize,
             char *image, unsigned long image_size)
 {
     xen_pfn_t *pfn_list;
@@ -1055,7 +1055,7 @@ error_out:
 }
 
 int
-xc_hvm_build(int xc_handle, uint32_t domid, int memsize, const char 
*image_name)
+xc_hvm_build(xc_interface *xc_handle, uint32_t domid, int memsize, const char 
*image_name)
 {
     vcpu_guest_context_any_t st_ctxt_any;
     vcpu_guest_context_t *ctxt = &st_ctxt_any.c;
@@ -1105,7 +1105,7 @@ error_out:
  * memsize pages marked populate-on-demand, and with a PoD cache size
  * of target.  If target == memsize, pages are populated normally.
  */
-int xc_hvm_build_target_mem(int xc_handle,
+int xc_hvm_build_target_mem(xc_interface *xc_handle,
                             uint32_t domid,
                             int memsize,
                             int target,
@@ -1131,7 +1131,7 @@ int xc_hvm_build_target_mem(int xc_handle,
 #define _PAGE_AR_RW     (2 <<  9)       /* read & write */
 
 int
-xc_ia64_set_os_type(int xc_handle, char *guest_os_type, uint32_t dom)
+xc_ia64_set_os_type(xc_interface *xc_handle, char *guest_os_type, uint32_t dom)
 {
     DECLARE_DOMCTL;
 
diff --git a/tools/libxc/ia64/xc_ia64_linux_restore.c 
b/tools/libxc/ia64/xc_ia64_linux_restore.c
index ed62ab7..68a3873 100644
--- a/tools/libxc/ia64/xc_ia64_linux_restore.c
+++ b/tools/libxc/ia64/xc_ia64_linux_restore.c
@@ -29,7 +29,7 @@ static unsigned long p2m_size;
 static unsigned long nr_pfns;
 
 static int
-populate_page_if_necessary(int xc_handle, uint32_t dom, unsigned long gmfn,
+populate_page_if_necessary(xc_interface *xc_handle, uint32_t dom, unsigned 
long gmfn,
                            struct xen_ia64_p2m_table *p2m_table)
 {
     if (xc_ia64_p2m_present(p2m_table, gmfn))
@@ -39,7 +39,7 @@ populate_page_if_necessary(int xc_handle, uint32_t dom, 
unsigned long gmfn,
 }
 
 static int
-read_page(int xc_handle, int io_fd, uint32_t dom, unsigned long pfn)
+read_page(xc_interface *xc_handle, int io_fd, uint32_t dom, unsigned long pfn)
 {
     void *mem;
 
@@ -65,7 +65,7 @@ read_page(int xc_handle, int io_fd, uint32_t dom, unsigned 
long pfn)
  * pages here.
  */
 static int
-xc_ia64_recv_unallocated_list(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_recv_unallocated_list(xc_interface *xc_handle, int io_fd, uint32_t dom,
                               struct xen_ia64_p2m_table *p2m_table)
 {
     int rc = -1;
@@ -116,7 +116,7 @@ xc_ia64_recv_unallocated_list(int xc_handle, int io_fd, 
uint32_t dom,
 }
 
 static int
-xc_ia64_recv_vcpu_context(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_recv_vcpu_context(xc_interface *xc_handle, int io_fd, uint32_t dom,
                           uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any)
 {
     vcpu_guest_context_t *ctxt = &ctxt_any->c;
@@ -147,7 +147,7 @@ xc_ia64_recv_vcpu_context(int xc_handle, int io_fd, 
uint32_t dom,
 
 /* Read shared info.  */
 static int
-xc_ia64_recv_shared_info(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_recv_shared_info(xc_interface *xc_handle, int io_fd, uint32_t dom,
                          unsigned long shared_info_frame,
                          unsigned long *start_info_pfn)
 {
@@ -222,7 +222,7 @@ xc_ia64_recv_vcpumap(const xc_dominfo_t *info, int io_fd, 
uint64_t **vcpumapp)
 }
 
 static int
-xc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, int32_t dom,
+xc_ia64_pv_recv_vcpu_context(xc_interface *xc_handle, int io_fd, int32_t dom,
                              uint32_t vcpu)
 {
     int rc = -1;
@@ -254,7 +254,7 @@ xc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, 
int32_t dom,
 }
 
 static int
-xc_ia64_pv_recv_shared_info(int xc_handle, int io_fd, int32_t dom, 
+xc_ia64_pv_recv_shared_info(xc_interface *xc_handle, int io_fd, int32_t dom, 
                             unsigned long shared_info_frame,
                             struct xen_ia64_p2m_table *p2m_table,
                             unsigned int store_evtchn,
@@ -296,7 +296,7 @@ xc_ia64_pv_recv_shared_info(int xc_handle, int io_fd, 
int32_t dom,
 }
 
 static int
-xc_ia64_pv_recv_context_ver_one_or_two(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_pv_recv_context_ver_one_or_two(xc_interface *xc_handle, int io_fd, 
uint32_t dom,
                                        unsigned long shared_info_frame,
                                        struct xen_ia64_p2m_table *p2m_table,
                                        unsigned int store_evtchn,
@@ -320,7 +320,7 @@ xc_ia64_pv_recv_context_ver_one_or_two(int xc_handle, int 
io_fd, uint32_t dom,
 }
 
 static int
-xc_ia64_pv_recv_context_ver_three(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_pv_recv_context_ver_three(xc_interface *xc_handle, int io_fd, uint32_t 
dom,
                                   unsigned long shared_info_frame,
                                   struct xen_ia64_p2m_table *p2m_table,
                                   unsigned int store_evtchn,
@@ -365,7 +365,7 @@ xc_ia64_pv_recv_context_ver_three(int xc_handle, int io_fd, 
uint32_t dom,
 
 static int
 xc_ia64_pv_recv_context(unsigned long format_version,
-                        int xc_handle, int io_fd, uint32_t dom,
+                        xc_interface *xc_handle, int io_fd, uint32_t dom,
                         unsigned long shared_info_frame,
                         struct xen_ia64_p2m_table *p2m_table,
                         unsigned int store_evtchn,
@@ -399,7 +399,7 @@ xc_ia64_pv_recv_context(unsigned long format_version,
 }
 
 static int
-xc_ia64_hvm_recv_context(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_hvm_recv_context(xc_interface *xc_handle, int io_fd, uint32_t dom,
                          unsigned long shared_info_frame,
                          struct xen_ia64_p2m_table *p2m_table,
                          unsigned int store_evtchn, unsigned long *store_mfn,
@@ -521,7 +521,7 @@ out:
  * hvm domain requires IO pages allocated when XEN_DOMCTL_arch_setup
  */
 static int
-xc_ia64_hvm_domain_setup(int xc_handle, uint32_t dom)
+xc_ia64_hvm_domain_setup(xc_interface *xc_handle, uint32_t dom)
 {
     int rc;
     xen_pfn_t pfn_list[] = {
@@ -539,7 +539,7 @@ xc_ia64_hvm_domain_setup(int xc_handle, uint32_t dom)
 }
 
 int
-xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
+xc_domain_restore(xc_interface *xc_handle, int io_fd, uint32_t dom,
                   unsigned int store_evtchn, unsigned long *store_mfn,
                   unsigned int console_evtchn, unsigned long *console_mfn,
                   unsigned int hvm, unsigned int pae, int superpages)
diff --git a/tools/libxc/ia64/xc_ia64_linux_save.c 
b/tools/libxc/ia64/xc_ia64_linux_save.c
index dd70290..aee0154 100644
--- a/tools/libxc/ia64/xc_ia64_linux_save.c
+++ b/tools/libxc/ia64/xc_ia64_linux_save.c
@@ -54,7 +54,7 @@ static inline void set_bit(int nr, volatile void * addr)
 
 static int
 suspend_and_state(int (*suspend)(void*), void* data,
-                  int xc_handle, int io_fd,
+                  xc_interface *xc_handle, int io_fd,
                   int dom, xc_dominfo_t *info)
 {
     if ( !(*suspend)(data) ) {
@@ -86,7 +86,7 @@ md_is_not_ram(const efi_memory_desc_t *md)
  * page after pausing the domain.
  */
 static int
-xc_ia64_send_unallocated_list(int xc_handle, int io_fd, 
+xc_ia64_send_unallocated_list(xc_interface *xc_handle, int io_fd, 
                               struct xen_ia64_p2m_table *p2m_table,
                               xen_ia64_memmap_info_t *memmap_info, 
                               void *memmap_desc_start, void *memmap_desc_end)
@@ -155,7 +155,7 @@ xc_ia64_send_unallocated_list(int xc_handle, int io_fd,
 }
 
 static int
-xc_ia64_send_vcpu_context(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_send_vcpu_context(xc_interface *xc_handle, int io_fd, uint32_t dom,
                           uint32_t vcpu, vcpu_guest_context_any_t *ctxt_any)
 {
     vcpu_guest_context_t *ctxt = &ctxt_any->c;
@@ -174,7 +174,7 @@ xc_ia64_send_vcpu_context(int xc_handle, int io_fd, 
uint32_t dom,
 }
 
 static int
-xc_ia64_send_shared_info(int xc_handle, int io_fd, shared_info_t *live_shinfo)
+xc_ia64_send_shared_info(xc_interface *xc_handle, int io_fd, shared_info_t 
*live_shinfo)
 {
     if (write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
         ERROR("Error when writing to state file (1)");
@@ -184,7 +184,7 @@ xc_ia64_send_shared_info(int xc_handle, int io_fd, 
shared_info_t *live_shinfo)
 }
 
 static int
-xc_ia64_send_vcpumap(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_send_vcpumap(xc_interface *xc_handle, int io_fd, uint32_t dom,
                      const xc_dominfo_t *info, uint64_t max_virt_cpus,
                      uint64_t **vcpumapp)
 {
@@ -231,7 +231,7 @@ xc_ia64_send_vcpumap(int xc_handle, int io_fd, uint32_t dom,
 
 
 static int
-xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_pv_send_context(xc_interface *xc_handle, int io_fd, uint32_t dom,
                         const xc_dominfo_t *info, shared_info_t *live_shinfo)
 {
     int rc = -1;
@@ -280,7 +280,7 @@ xc_ia64_pv_send_context(int xc_handle, int io_fd, uint32_t 
dom,
 }
 
 static int
-xc_ia64_hvm_send_context(int xc_handle, int io_fd, uint32_t dom,
+xc_ia64_hvm_send_context(xc_interface *xc_handle, int io_fd, uint32_t dom,
                          const xc_dominfo_t *info, shared_info_t *live_shinfo)
 {
     int rc = -1;
@@ -381,7 +381,7 @@ out:
 }
 
 int
-xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
+xc_domain_save(xc_interface *xc_handle, int io_fd, uint32_t dom, uint32_t 
max_iters,
                uint32_t max_factor, uint32_t flags,
                struct save_callbacks* callbacks,
                int hvm, void (*switch_qemu_logdirty)(int, unsigned))
diff --git a/tools/libxc/ia64/xc_ia64_stubs.c b/tools/libxc/ia64/xc_ia64_stubs.c
index 0dcc83d..744b538 100644
--- a/tools/libxc/ia64/xc_ia64_stubs.c
+++ b/tools/libxc/ia64/xc_ia64_stubs.c
@@ -19,7 +19,7 @@ xc_ia64_fpsr_default(void)
 }
 
 static int
-xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf,
+xc_ia64_get_pfn_list(xc_interface *xc_handle, uint32_t domid, xen_pfn_t 
*pfn_buf,
                      unsigned int start_page, unsigned int nr_pages)
 {
     DECLARE_DOMCTL;
@@ -43,7 +43,7 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t 
*pfn_buf,
 }
 
 int
-xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t *pfn_buf,
+xc_get_pfn_list(xc_interface *xc_handle, uint32_t domid, uint64_t *pfn_buf,
                 unsigned long max_pfns)
 {
     return xc_ia64_get_pfn_list(xc_handle, domid, (xen_pfn_t *)pfn_buf,
@@ -51,7 +51,7 @@ xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t 
*pfn_buf,
 }
 
 long
-xc_get_max_pages(int xc_handle, uint32_t domid)
+xc_get_max_pages(xc_interface *xc_handle, uint32_t domid)
 {
     struct xen_domctl domctl;
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
@@ -63,7 +63,7 @@ xc_get_max_pages(int xc_handle, uint32_t domid)
 /* It is possible to get memmap_info and memmap by
    foreign domain page mapping. But it's racy. Use hypercall to avoid race. */
 static int
-xc_ia64_get_memmap(int xc_handle,
+xc_ia64_get_memmap(xc_interface *xc_handle,
                    uint32_t domid, char *buf, unsigned long bufsize)
 {
     privcmd_hypercall_t hypercall;
@@ -84,7 +84,7 @@ xc_ia64_get_memmap(int xc_handle,
 }
 
 int
-xc_ia64_copy_memmap(int xc_handle, uint32_t domid, shared_info_t *live_shinfo,
+xc_ia64_copy_memmap(xc_interface *xc_handle, uint32_t domid, shared_info_t 
*live_shinfo,
                     xen_ia64_memmap_info_t **memmap_info_p,
                     unsigned long *memmap_info_num_pages_p)
 {
@@ -163,7 +163,7 @@ xc_ia64_copy_memmap(int xc_handle, uint32_t domid, 
shared_info_t *live_shinfo,
 #define PTRS_PER_PTE    (1UL << (PAGE_SHIFT - 3))
 
 static void*
-xc_ia64_map_foreign_p2m(int xc_handle, uint32_t dom,
+xc_ia64_map_foreign_p2m(xc_interface *xc_handle, uint32_t dom,
                         struct xen_ia64_memmap_info *memmap_info,
                         unsigned long flags, unsigned long *p2m_size_p)
 {
@@ -219,7 +219,7 @@ xc_ia64_p2m_init(struct xen_ia64_p2m_table *p2m_table)
 }
 
 int
-xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, int xc_handle,
+xc_ia64_p2m_map(struct xen_ia64_p2m_table *p2m_table, xc_interface *xc_handle,
                 uint32_t domid, struct xen_ia64_memmap_info *memmap_info,
                 unsigned long flag)
 {
diff --git a/tools/libxc/xc_acm.c b/tools/libxc/xc_acm.c
index b4d89d0..d585a42 100644
--- a/tools/libxc/xc_acm.c
+++ b/tools/libxc/xc_acm.c
@@ -14,7 +14,7 @@
 
 #include "xc_private.h"
 
-int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned long arg_size)
+int xc_acm_op(xc_interface *xch, int cmd, void *arg, unsigned long arg_size)
 {
     int ret;
     DECLARE_HYPERCALL;
@@ -88,7 +88,7 @@ int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned 
long arg_size)
         PERROR("Could not lock memory for Xen hypercall");
         return -EFAULT;
     }
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0)
     {
         if ( errno == EACCES )
             DPRINTF("acmctl operation failed -- need to"
diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c
index d5e686b..b164e2a 100644
--- a/tools/libxc/xc_core.c
+++ b/tools/libxc/xc_core.c
@@ -66,7 +66,7 @@ struct xc_core_strtab {
 };
 
 static struct xc_core_strtab*
-xc_core_strtab_init(void)
+xc_core_strtab_init(xc_interface *xch)
 {
     struct xc_core_strtab *strtab;
     char *strings;
@@ -99,7 +99,7 @@ xc_core_strtab_free(struct xc_core_strtab *strtab)
 }
 
 static uint16_t
-xc_core_strtab_get(struct xc_core_strtab *strtab, const char *name)
+xc_core_strtab_get(xc_interface *xch, struct xc_core_strtab *strtab, const 
char *name)
 {
     uint16_t ret = 0;
     uint16_t len = strlen(name) + 1;
@@ -150,7 +150,7 @@ struct xc_core_section_headers {
 #define SHDR_INC        ((uint16_t)4)
 
 static struct xc_core_section_headers*
-xc_core_shdr_init(void)
+xc_core_shdr_init(xc_interface *xch)
 {
     struct xc_core_section_headers *sheaders;
     sheaders = malloc(sizeof(*sheaders));
@@ -176,7 +176,8 @@ xc_core_shdr_free(struct xc_core_section_headers *sheaders)
 }
 
 Elf64_Shdr*
-xc_core_shdr_get(struct xc_core_section_headers *sheaders)
+xc_core_shdr_get(xc_interface *xch,
+                 struct xc_core_section_headers *sheaders)
 {
     Elf64_Shdr *shdr;
 
@@ -203,13 +204,14 @@ xc_core_shdr_get(struct xc_core_section_headers *sheaders)
 }
 
 int
-xc_core_shdr_set(Elf64_Shdr *shdr,
+xc_core_shdr_set(xc_interface *xch,
+                 Elf64_Shdr *shdr,
                  struct xc_core_strtab *strtab,
                  const char *name, uint32_t type,
                  uint64_t offset, uint64_t size,
                  uint64_t addralign, uint64_t entsize)
 {
-    uint64_t name_idx = xc_core_strtab_get(strtab, name);
+    uint64_t name_idx = xc_core_strtab_get(xch, strtab, name);
     if ( name_idx == 0 )
         return -1;
 
@@ -252,44 +254,44 @@ xc_core_ehdr_init(Elf64_Ehdr *ehdr)
 }
 
 static int
-elfnote_fill_xen_version(int xc_handle,
+elfnote_fill_xen_version(xc_interface *xch,
                          struct xen_dumpcore_elfnote_xen_version_desc
                          *xen_version)
 {
     int rc;
     memset(xen_version, 0, sizeof(*xen_version));
 
-    rc = xc_version(xc_handle, XENVER_version, NULL);
+    rc = xc_version(xch, XENVER_version, NULL);
     if ( rc < 0 )
         return rc;
     xen_version->major_version = rc >> 16;
     xen_version->minor_version = rc & ((1 << 16) - 1);
 
-    rc = xc_version(xc_handle, XENVER_extraversion,
+    rc = xc_version(xch, XENVER_extraversion,
                     &xen_version->extra_version);
     if ( rc < 0 )
         return rc;
 
-    rc = xc_version(xc_handle, XENVER_compile_info,
+    rc = xc_version(xch, XENVER_compile_info,
                     &xen_version->compile_info);
     if ( rc < 0 )
         return rc;
 
-    rc = xc_version(xc_handle,
+    rc = xc_version(xch,
                     XENVER_capabilities, &xen_version->capabilities);
     if ( rc < 0 )
         return rc;
 
-    rc = xc_version(xc_handle, XENVER_changeset, &xen_version->changeset);
+    rc = xc_version(xch, XENVER_changeset, &xen_version->changeset);
     if ( rc < 0 )
         return rc;
 
-    rc = xc_version(xc_handle, XENVER_platform_parameters,
+    rc = xc_version(xch, XENVER_platform_parameters,
                     &xen_version->platform_parameters);
     if ( rc < 0 )
         return rc;
 
-    rc = xc_version(xc_handle, XENVER_pagesize, NULL);
+    rc = xc_version(xch, XENVER_pagesize, NULL);
     if ( rc < 0 )
         return rc;
     xen_version->pagesize = rc;
@@ -314,7 +316,7 @@ elfnote_init(struct elfnote *elfnote)
 }
 
 static int
-elfnote_dump_none(void *args, dumpcore_rtn_t dump_rtn)
+elfnote_dump_none(xc_interface *xch, void *args, dumpcore_rtn_t dump_rtn)
 {
     int sts;
     struct elfnote elfnote;
@@ -326,14 +328,15 @@ elfnote_dump_none(void *args, dumpcore_rtn_t dump_rtn)
 
     elfnote.descsz = sizeof(none);
     elfnote.type = XEN_ELFNOTE_DUMPCORE_NONE;
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
     if ( sts != 0 )
         return sts;
-    return dump_rtn(args, (char*)&none, sizeof(none));
+    return dump_rtn(xch, args, (char*)&none, sizeof(none));
 }
 
 static int
 elfnote_dump_core_header(
+    xc_interface *xch,
     void *args, dumpcore_rtn_t dump_rtn, const xc_dominfo_t *info,
     int nr_vcpus, unsigned long nr_pages)
 {
@@ -350,15 +353,15 @@ elfnote_dump_core_header(
     header.xch_nr_vcpus = nr_vcpus;
     header.xch_nr_pages = nr_pages;
     header.xch_page_size = PAGE_SIZE;
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
     if ( sts != 0 )
         return sts;
-    return dump_rtn(args, (char*)&header, sizeof(header));
+    return dump_rtn(xch, args, (char*)&header, sizeof(header));
 }
 
 static int
-elfnote_dump_xen_version(void *args, dumpcore_rtn_t dump_rtn, int xc_handle,
-                         unsigned int guest_width)
+elfnote_dump_xen_version(xc_interface *xch, void *args,
+                         dumpcore_rtn_t dump_rtn, unsigned int guest_width)
 {
     int sts;
     struct elfnote elfnote;
@@ -369,21 +372,22 @@ elfnote_dump_xen_version(void *args, dumpcore_rtn_t 
dump_rtn, int xc_handle,
 
     elfnote.descsz = sizeof(xen_version);
     elfnote.type = XEN_ELFNOTE_DUMPCORE_XEN_VERSION;
-    elfnote_fill_xen_version(xc_handle, &xen_version);
+    elfnote_fill_xen_version(xch, &xen_version);
     if (guest_width < sizeof(unsigned long))
     {
         // 32 bit elf file format differs in pagesize's alignment
         char *p = (char *)&xen_version.pagesize;
         memmove(p - 4, p, sizeof(xen_version.pagesize));
     }
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
     if ( sts != 0 )
         return sts;
-    return dump_rtn(args, (char*)&xen_version, sizeof(xen_version));
+    return dump_rtn(xch, args, (char*)&xen_version, sizeof(xen_version));
 }
 
 static int
-elfnote_dump_format_version(void *args, dumpcore_rtn_t dump_rtn)
+elfnote_dump_format_version(xc_interface *xch,
+                            void *args, dumpcore_rtn_t dump_rtn)
 {
     int sts;
     struct elfnote elfnote;
@@ -395,14 +399,14 @@ elfnote_dump_format_version(void *args, dumpcore_rtn_t 
dump_rtn)
     elfnote.descsz = sizeof(format_version);
     elfnote.type = XEN_ELFNOTE_DUMPCORE_FORMAT_VERSION;
     elfnote_fill_format_version(&format_version);
-    sts = dump_rtn(args, (char*)&elfnote, sizeof(elfnote));
+    sts = dump_rtn(xch, args, (char*)&elfnote, sizeof(elfnote));
     if ( sts != 0 )
         return sts;
-    return dump_rtn(args, (char*)&format_version, sizeof(format_version));
+    return dump_rtn(xch, args, (char*)&format_version, sizeof(format_version));
 }
 
 static int
-get_guest_width(int xc_handle,
+get_guest_width(xc_interface *xch,
                 uint32_t domid,
                 unsigned int *guest_width)
 {
@@ -412,7 +416,7 @@ get_guest_width(int xc_handle,
     domctl.domain = domid;
     domctl.cmd = XEN_DOMCTL_get_address_size;
 
-    if ( do_domctl(xc_handle, &domctl) != 0 )
+    if ( do_domctl(xch, &domctl) != 0 )
         return 1;
         
     *guest_width = domctl.u.address_size.size / 8;
@@ -420,7 +424,7 @@ get_guest_width(int xc_handle,
 }
 
 int
-xc_domain_dumpcore_via_callback(int xc_handle,
+xc_domain_dumpcore_via_callback(xc_interface *xch,
                                 uint32_t domid,
                                 void *args,
                                 dumpcore_rtn_t dump_rtn)
@@ -463,7 +467,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     struct xc_core_section_headers *sheaders = NULL;
     Elf64_Shdr *shdr;
  
-    if ( get_guest_width(xc_handle, domid, &dinfo->guest_width) != 0 )
+    if ( get_guest_width(xch, domid, &dinfo->guest_width) != 0 )
     {
         PERROR("Could not get address size for domain");
         return sts;
@@ -476,13 +480,13 @@ xc_domain_dumpcore_via_callback(int xc_handle,
         goto out;
     }
 
-    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
     {
         PERROR("Could not get info for domain");
         goto out;
     }
     /* Map the shared info frame */
-    live_shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    live_shinfo = xc_map_foreign_range(xch, domid, PAGE_SIZE,
                                        PROT_READ, info.shared_info_frame);
     if ( !live_shinfo && !info.hvm )
     {
@@ -506,10 +510,10 @@ xc_domain_dumpcore_via_callback(int xc_handle,
 
     for ( i = 0; i <= info.max_vcpu_id; i++ )
     {
-        if ( xc_vcpu_getcontext(xc_handle, domid, i, &ctxt[nr_vcpus]) == 0 )
+        if ( xc_vcpu_getcontext(xch, domid, i, &ctxt[nr_vcpus]) == 0 )
         {
             if ( xc_core_arch_context_get(&arch_ctxt, &ctxt[nr_vcpus],
-                                          xc_handle, domid) )
+                                          xch, domid) )
                 continue;
             nr_vcpus++;
         }
@@ -521,7 +525,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     }
 
     /* obtain memory map */
-    sts = xc_core_arch_memory_map_get(xc_handle, &arch_ctxt, &info,
+    sts = xc_core_arch_memory_map_get(xch, &arch_ctxt, &info,
                                       live_shinfo, &memory_map,
                                       &nr_memory_map);
     if ( sts != 0 )
@@ -548,7 +552,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
             goto out;
         }
 
-        sts = xc_core_arch_map_p2m(xc_handle, dinfo->guest_width, &info, 
live_shinfo,
+        sts = xc_core_arch_map_p2m(xch, dinfo->guest_width, &info, live_shinfo,
                                    &p2m, &p2m_size);
         if ( sts != 0 )
             goto out;
@@ -567,20 +571,20 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     xc_core_ehdr_init(&ehdr);
 
     /* create section header */
-    strtab = xc_core_strtab_init();
+    strtab = xc_core_strtab_init(xch);
     if ( strtab == NULL )
     {
         PERROR("Could not allocate string table");
         goto out;
     }
-    sheaders = xc_core_shdr_init();
+    sheaders = xc_core_shdr_init(xch);
     if ( sheaders == NULL )
     {
         PERROR("Could not allocate section headers");
         goto out;
     }
     /* null section */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("Could not get section header for null section");
@@ -588,7 +592,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     }
 
     /* .shstrtab */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("Could not get section header for shstrtab");
@@ -598,7 +602,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     /* strtab_shdr.sh_offset, strtab_shdr.sh_size aren't unknown.
      * fill it later
      */
-    sts = xc_core_shdr_set(shdr, strtab, ELF_SHSTRTAB, SHT_STRTAB, 0, 0, 0, 0);
+    sts = xc_core_shdr_set(xch, shdr, strtab, ELF_SHSTRTAB, SHT_STRTAB, 0, 0, 
0, 0);
     if ( sts != 0 )
         goto out;
 
@@ -610,27 +614,27 @@ xc_domain_dumpcore_via_callback(int xc_handle,
         sizeof(struct xen_dumpcore_elfnote_header) +       /* core header */
         sizeof(struct xen_dumpcore_elfnote_xen_version) +  /* xen version */
         sizeof(struct xen_dumpcore_elfnote_format_version);/* format version */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("Could not get section header for note section");
         goto out;
     }
-    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_NOTE, SHT_NOTE,
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_NOTE, SHT_NOTE,
                            offset, filesz, 0, 0);
     if ( sts != 0 )
         goto out;
     offset += filesz;
 
     /* prstatus */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("Could not get section header for .xen_prstatus");
         goto out;
     }
     filesz = sizeof(*ctxt) * nr_vcpus;
-    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PRSTATUS,
                            SHT_PROGBITS, offset, filesz,
                            __alignof__(*ctxt), sizeof(*ctxt));
     if ( sts != 0 )
@@ -647,14 +651,14 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     /* shared_info */
     if ( live_shinfo != NULL )
     {
-        shdr = xc_core_shdr_get(sheaders);
+        shdr = xc_core_shdr_get(xch,sheaders);
         if ( shdr == NULL )
         {
             PERROR("Could not get section header for .xen_shared_info");
             goto out;
         }
         filesz = PAGE_SIZE;
-        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_SHARED_INFO,
                                SHT_PROGBITS, offset, filesz,
                                __alignof__(*live_shinfo), PAGE_SIZE);
         if ( sts != 0 )
@@ -676,21 +680,21 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     offset += dummy_len;
 
     /* pages */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("could not get section headers for .xen_pages");
         goto out;
     }
     filesz = (uint64_t)nr_pages * PAGE_SIZE;
-    sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PAGES, SHT_PROGBITS,
+    sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PAGES, 
SHT_PROGBITS,
                            offset, filesz, PAGE_SIZE, PAGE_SIZE);
     if ( sts != 0 )
         goto out;
     offset += filesz;
 
     /* p2m/pfn table */
-    shdr = xc_core_shdr_get(sheaders);
+    shdr = xc_core_shdr_get(xch,sheaders);
     if ( shdr == NULL )
     {
         PERROR("Could not get section header for .xen_{p2m, pfn} table");
@@ -699,7 +703,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     if ( !auto_translated_physmap )
     {
         filesz = (uint64_t)nr_pages * sizeof(p2m_array[0]);
-        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_P2M,
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_P2M,
                                SHT_PROGBITS,
                                offset, filesz, __alignof__(p2m_array[0]),
                                sizeof(p2m_array[0]));
@@ -707,7 +711,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     else
     {
         filesz = (uint64_t)nr_pages * sizeof(pfn_array[0]);
-        sts = xc_core_shdr_set(shdr, strtab, XEN_DUMPCORE_SEC_PFN,
+        sts = xc_core_shdr_set(xch, shdr, strtab, XEN_DUMPCORE_SEC_PFN,
                                SHT_PROGBITS,
                                offset, filesz, __alignof__(pfn_array[0]),
                                sizeof(pfn_array[0]));
@@ -725,45 +729,45 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     ehdr.e_shnum = sheaders->num;
     ehdr.e_shstrndx = strtab_idx;
     ehdr.e_machine = ELF_ARCH_MACHINE;
-    sts = dump_rtn(args, (char*)&ehdr, sizeof(ehdr));
+    sts = dump_rtn(xch, args, (char*)&ehdr, sizeof(ehdr));
     if ( sts != 0 )
         goto out;
 
     /* section headers */
-    sts = dump_rtn(args, (char*)sheaders->shdrs,
+    sts = dump_rtn(xch, args, (char*)sheaders->shdrs,
                    sheaders->num * sizeof(sheaders->shdrs[0]));
     if ( sts != 0 )
         goto out;
 
     /* elf note section: xen core header */
-    sts = elfnote_dump_none(args, dump_rtn);
+    sts = elfnote_dump_none(xch, args, dump_rtn);
     if ( sts != 0 )
         goto out;
 
     /* elf note section: xen core header */
-    sts = elfnote_dump_core_header(args, dump_rtn, &info, nr_vcpus, nr_pages);
+    sts = elfnote_dump_core_header(xch, args, dump_rtn, &info, nr_vcpus, 
nr_pages);
     if ( sts != 0 )
         goto out;
 
     /* elf note section: xen version */
-    sts = elfnote_dump_xen_version(args, dump_rtn, xc_handle, 
dinfo->guest_width);
+    sts = elfnote_dump_xen_version(xch, args, dump_rtn, dinfo->guest_width);
     if ( sts != 0 )
         goto out;
 
     /* elf note section: format version */
-    sts = elfnote_dump_format_version(args, dump_rtn);
+    sts = elfnote_dump_format_version(xch, args, dump_rtn);
     if ( sts != 0 )
         goto out;
 
     /* prstatus: .xen_prstatus */
-    sts = dump_rtn(args, (char *)ctxt, sizeof(*ctxt) * nr_vcpus);
+    sts = dump_rtn(xch, args, (char *)ctxt, sizeof(*ctxt) * nr_vcpus);
     if ( sts != 0 )
         goto out;
 
     if ( live_shinfo != NULL )
     {
         /* shared_info: .xen_shared_info */
-        sts = dump_rtn(args, (char*)live_shinfo, PAGE_SIZE);
+        sts = dump_rtn(xch, args, (char*)live_shinfo, PAGE_SIZE);
         if ( sts != 0 )
             goto out;
     }
@@ -775,7 +779,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
 
     /* Pad the output data to page alignment. */
     memset(dummy, 0, PAGE_SIZE);
-    sts = dump_rtn(args, dummy, dummy_len);
+    sts = dump_rtn(xch, args, dummy, dummy_len);
     if ( sts != 0 )
         goto out;
 
@@ -835,7 +839,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
             }
 
             vaddr = xc_map_foreign_range(
-                xc_handle, domid, PAGE_SIZE, PROT_READ, gmfn);
+                xch, domid, PAGE_SIZE, PROT_READ, gmfn);
             if ( vaddr == NULL )
                 continue;
             memcpy(dump_mem, vaddr, PAGE_SIZE);
@@ -844,7 +848,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
             if ( (j + 1) % DUMP_INCREMENT == 0 )
             {
                 sts = dump_rtn(
-                    args, dump_mem_start, dump_mem - dump_mem_start);
+                    xch, args, dump_mem_start, dump_mem - dump_mem_start);
                 if ( sts != 0 )
                     goto out;
                 dump_mem = dump_mem_start;
@@ -855,7 +859,7 @@ xc_domain_dumpcore_via_callback(int xc_handle,
     }
 
 copy_done:
-    sts = dump_rtn(args, dump_mem_start, dump_mem - dump_mem_start);
+    sts = dump_rtn(xch, args, dump_mem_start, dump_mem - dump_mem_start);
     if ( sts != 0 )
         goto out;
     if ( j < nr_pages )
@@ -866,7 +870,7 @@ copy_done:
         IPRINTF("j (%ld) != nr_pages (%ld)", j, nr_pages);
         memset(dump_mem_start, 0, PAGE_SIZE);
         for (; j < nr_pages; j++) {
-            sts = dump_rtn(args, dump_mem_start, PAGE_SIZE);
+            sts = dump_rtn(xch, args, dump_mem_start, PAGE_SIZE);
             if ( sts != 0 )
                 goto out;
             if ( !auto_translated_physmap )
@@ -882,15 +886,15 @@ copy_done:
     /* p2m/pfn table: .xen_p2m/.xen_pfn */
     if ( !auto_translated_physmap )
         sts = dump_rtn(
-            args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
+            xch, args, (char *)p2m_array, sizeof(p2m_array[0]) * nr_pages);
     else
         sts = dump_rtn(
-            args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
+            xch, args, (char *)pfn_array, sizeof(pfn_array[0]) * nr_pages);
     if ( sts != 0 )
         goto out;
 
     /* elf section header string table: .shstrtab */
-    sts = dump_rtn(args, strtab->strings, strtab->length);
+    sts = dump_rtn(xch, args, strtab->strings, strtab->length);
     if ( sts != 0 )
         goto out;
 
@@ -926,7 +930,8 @@ struct dump_args {
 };
 
 /* Callback routine for writing to a local dump file. */
-static int local_file_dump(void *args, char *buffer, unsigned int length)
+static int local_file_dump(xc_interface *xch,
+                           void *args, char *buffer, unsigned int length)
 {
     struct dump_args *da = args;
 
@@ -940,14 +945,14 @@ static int local_file_dump(void *args, char *buffer, 
unsigned int length)
     {
         // Now dumping pages -- make sure we discard clean pages from
         // the cache after each write
-        discard_file_cache(da->fd, 0 /* no flush */);
+        discard_file_cache(xch, da->fd, 0 /* no flush */);
     }
 
     return 0;
 }
 
 int
-xc_domain_dumpcore(int xc_handle,
+xc_domain_dumpcore(xc_interface *xch,
                    uint32_t domid,
                    const char *corename)
 {
@@ -961,10 +966,10 @@ xc_domain_dumpcore(int xc_handle,
     }
 
     sts = xc_domain_dumpcore_via_callback(
-        xc_handle, domid, &da, &local_file_dump);
+        xch, domid, &da, &local_file_dump);
 
     /* flush and discard any remaining portion of the file from cache */
-    discard_file_cache(da.fd, 1/* flush first*/);
+    discard_file_cache(xch, da.fd, 1/* flush first*/);
 
     close(da.fd);
 
diff --git a/tools/libxc/xc_core.h b/tools/libxc/xc_core.h
index b6d9138..41713ef 100644
--- a/tools/libxc/xc_core.h
+++ b/tools/libxc/xc_core.h
@@ -119,9 +119,11 @@ struct xc_core_strtab;
 struct xc_core_section_headers;
 
 Elf64_Shdr*
-xc_core_shdr_get(struct xc_core_section_headers *sheaders);
+xc_core_shdr_get(xc_interface *xch,
+                 struct xc_core_section_headers *sheaders);
 int
-xc_core_shdr_set(Elf64_Shdr *shdr,
+xc_core_shdr_set(xc_interface *xch,
+                 Elf64_Shdr *shdr,
                  struct xc_core_strtab *strtab,
                  const char *name, uint32_t type,
                  uint64_t offset, uint64_t size,
@@ -134,16 +136,16 @@ struct xc_core_memory_map {
 typedef struct xc_core_memory_map xc_core_memory_map_t;
 int xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info);
 struct xc_core_arch_context;
-int xc_core_arch_memory_map_get(int xc_handle,
+int xc_core_arch_memory_map_get(xc_interface *xch,
                                 struct xc_core_arch_context *arch_ctxt,
                                 xc_dominfo_t *info, shared_info_any_t 
*live_shinfo,
                                 xc_core_memory_map_t **mapp,
                                 unsigned int *nr_entries);
-int xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width,
+int xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width,
                          xc_dominfo_t *info, shared_info_any_t *live_shinfo,
                          xen_pfn_t **live_p2m, unsigned long *pfnp);
 
-int xc_core_arch_map_p2m_writable(int xc_handle, unsigned int guest_width,
+int xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width,
                                   xc_dominfo_t *info,
                                   shared_info_any_t *live_shinfo,
                                   xen_pfn_t **live_p2m, unsigned long *pfnp);
diff --git a/tools/libxc/xc_core_ia64.c b/tools/libxc/xc_core_ia64.c
index 77c8596..10f93e5 100644
--- a/tools/libxc/xc_core_ia64.c
+++ b/tools/libxc/xc_core_ia64.c
@@ -67,7 +67,7 @@ xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info)
 
 /* see setup_guest() @ xc_linux_build.c */
 static int
-memory_map_get_old_domu(int xc_handle, xc_dominfo_t *info,
+memory_map_get_old_domu(xc_interface *xch, xc_dominfo_t *info,
                         shared_info_any_t *live_shinfo,
                         xc_core_memory_map_t **mapp, unsigned int *nr_entries)
 {
@@ -95,7 +95,7 @@ out:
 
 /* see setup_guest() @ xc_ia64_hvm_build.c */
 static int
-memory_map_get_old_hvm(int xc_handle, xc_dominfo_t *info, 
+memory_map_get_old_hvm(xc_interface *xch, xc_dominfo_t *info, 
                        shared_info_any_t *live_shinfo,
                        xc_core_memory_map_t **mapp, unsigned int *nr_entries)
 {
@@ -154,21 +154,21 @@ out:
 }
 
 static int
-memory_map_get_old(int xc_handle, xc_dominfo_t *info, 
+memory_map_get_old(xc_interface *xch, xc_dominfo_t *info, 
                    shared_info_any_t *live_shinfo,
                    xc_core_memory_map_t **mapp, unsigned int *nr_entries)
 {
     if ( info->hvm )
-        return memory_map_get_old_hvm(xc_handle, info, live_shinfo,
+        return memory_map_get_old_hvm(xch, info, live_shinfo,
                                       mapp, nr_entries);
     if ( live_shinfo == NULL )
         return -1;
-    return memory_map_get_old_domu(xc_handle, info, live_shinfo,
+    return memory_map_get_old_domu(xch, info, live_shinfo,
                                    mapp, nr_entries);
 }
 
 int
-xc_core_arch_memory_map_get(int xc_handle,
+xc_core_arch_memory_map_get(xc_interface *xch,
                             struct xc_core_arch_context *arch_ctxt,
                             xc_dominfo_t *info,
                             shared_info_any_t *live_shinfo,
@@ -191,7 +191,7 @@ xc_core_arch_memory_map_get(int xc_handle,
     }
 
     /* copy before use in case someone updating them */
-    if (xc_ia64_copy_memmap(xc_handle, info->domid, &live_shinfo->s,
+    if (xc_ia64_copy_memmap(xch, info->domid, &live_shinfo->s,
                             &memmap_info, NULL)) {
         goto old;
     }
@@ -223,7 +223,7 @@ xc_core_arch_memory_map_get(int xc_handle,
     }
     ret = 0;
 
-    xc_ia64_p2m_map(&arch_ctxt->p2m_table, xc_handle, info->domid,
+    xc_ia64_p2m_map(&arch_ctxt->p2m_table, xch, info->domid,
                     memmap_info, 0);
     if ( memmap_info != NULL )
         free(memmap_info);
@@ -232,11 +232,11 @@ xc_core_arch_memory_map_get(int xc_handle,
     
 old:
     DPRINTF("Falling back old method.\n");
-    return memory_map_get_old(xc_handle, info, live_shinfo, mapp, nr_entries);
+    return memory_map_get_old(xch, info, live_shinfo, mapp, nr_entries);
 }
 
 int
-xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, xc_dominfo_t 
*info,
+xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width, xc_dominfo_t 
*info,
                      shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
                      unsigned long *pfnp)
 {
@@ -273,7 +273,7 @@ xc_core_arch_context_free(struct xc_core_arch_context* 
arch_ctxt)
 int
 xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
                          vcpu_guest_context_any_t* ctxt_any,
-                         int xc_handle, uint32_t domid)
+                         xc_interface *xch, uint32_t domid)
 {
     vcpu_guest_context_t *ctxt = &ctxt_any->c;
     mapped_regs_t* mapped_regs;
@@ -302,7 +302,7 @@ xc_core_arch_context_get(struct xc_core_arch_context* 
arch_ctxt,
         arch_ctxt->mapped_regs = new;
     }
 
-    mapped_regs = xc_map_foreign_range(xc_handle, domid,
+    mapped_regs = xc_map_foreign_range(xch, domid,
                                        arch_ctxt->mapped_regs_size,
                                        PROT_READ, ctxt->privregs_pfn);
     if ( mapped_regs == NULL )
diff --git a/tools/libxc/xc_core_ia64.h b/tools/libxc/xc_core_ia64.h
index 89ffd6e..34571a0 100644
--- a/tools/libxc/xc_core_ia64.h
+++ b/tools/libxc/xc_core_ia64.h
@@ -41,7 +41,7 @@ xc_core_arch_context_free(struct xc_core_arch_context* 
arch_ctxt);
 int
 xc_core_arch_context_get(struct xc_core_arch_context* arch_ctxt,
                          vcpu_guest_context_any_t* ctxt,
-                         int xc_handle, uint32_t domid);
+                         xc_interface *xch, uint32_t domid);
 int
 xc_core_arch_context_get_shdr(struct xc_core_arch_context* arch_ctxt, 
                               struct xc_core_section_headers *sheaders,
diff --git a/tools/libxc/xc_core_x86.c b/tools/libxc/xc_core_x86.c
index 520cb68..975e49a 100644
--- a/tools/libxc/xc_core_x86.c
+++ b/tools/libxc/xc_core_x86.c
@@ -40,9 +40,9 @@ xc_core_arch_gpfn_may_present(struct xc_core_arch_context 
*arch_ctxt,
 }
 
 
-static int nr_gpfns(int xc_handle, domid_t domid)
+static int nr_gpfns(xc_interface *xch, domid_t domid)
 {
-    return xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &domid) + 1;
+    return xc_memory_op(xch, XENMEM_maximum_gpfn, &domid) + 1;
 }
 
 int
@@ -52,12 +52,12 @@ xc_core_arch_auto_translated_physmap(const xc_dominfo_t 
*info)
 }
 
 int
-xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused,
+xc_core_arch_memory_map_get(xc_interface *xch, struct xc_core_arch_context 
*unused,
                             xc_dominfo_t *info, shared_info_any_t *live_shinfo,
                             xc_core_memory_map_t **mapp,
                             unsigned int *nr_entries)
 {
-    unsigned long p2m_size = nr_gpfns(xc_handle, info->domid);
+    unsigned long p2m_size = nr_gpfns(xch, info->domid);
     xc_core_memory_map_t *map;
 
     map = malloc(sizeof(*map));
@@ -76,7 +76,7 @@ xc_core_arch_memory_map_get(int xc_handle, struct 
xc_core_arch_context *unused,
 }
 
 static int
-xc_core_arch_map_p2m_rw(int xc_handle, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
+xc_core_arch_map_p2m_rw(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
                         shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
                         unsigned long *pfnp, int rw)
 {
@@ -92,7 +92,7 @@ xc_core_arch_map_p2m_rw(int xc_handle, struct 
domain_info_context *dinfo, xc_dom
     int err;
     int i;
 
-    dinfo->p2m_size = nr_gpfns(xc_handle, info->domid);
+    dinfo->p2m_size = nr_gpfns(xch, info->domid);
     if ( dinfo->p2m_size < info->nr_pages  )
     {
         ERROR("p2m_size < nr_pages -1 (%lx < %lx", dinfo->p2m_size, 
info->nr_pages - 1);
@@ -100,7 +100,7 @@ xc_core_arch_map_p2m_rw(int xc_handle, struct 
domain_info_context *dinfo, xc_dom
     }
 
     live_p2m_frame_list_list =
-        xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
+        xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ,
                              GET_FIELD(live_shinfo, 
arch.pfn_to_mfn_frame_list_list));
 
     if ( !live_p2m_frame_list_list )
@@ -129,7 +129,7 @@ xc_core_arch_map_p2m_rw(int xc_handle, struct 
domain_info_context *dinfo, xc_dom
             p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
 
     live_p2m_frame_list =
-        xc_map_foreign_pages(xc_handle, dom, PROT_READ,
+        xc_map_foreign_pages(xch, dom, PROT_READ,
                              p2m_frame_list_list,
                              P2M_FLL_ENTRIES);
 
@@ -156,7 +156,7 @@ xc_core_arch_map_p2m_rw(int xc_handle, struct 
domain_info_context *dinfo, xc_dom
         for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- )
             p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i];
 
-    *live_p2m = xc_map_foreign_pages(xc_handle, dom,
+    *live_p2m = xc_map_foreign_pages(xch, dom,
                                     rw ? (PROT_READ | PROT_WRITE) : PROT_READ,
                                     p2m_frame_list,
                                     P2M_FL_ENTRIES);
@@ -191,24 +191,24 @@ out:
 }
 
 int
-xc_core_arch_map_p2m(int xc_handle, unsigned int guest_width, xc_dominfo_t 
*info,
+xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width, xc_dominfo_t 
*info,
                         shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
                         unsigned long *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
-    return xc_core_arch_map_p2m_rw(xc_handle, dinfo, info,
+    return xc_core_arch_map_p2m_rw(xch, dinfo, info,
                                    live_shinfo, live_p2m, pfnp, 0);
 }
 
 int
-xc_core_arch_map_p2m_writable(int xc_handle, unsigned int guest_width, 
xc_dominfo_t *info,
+xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width, 
xc_dominfo_t *info,
                               shared_info_any_t *live_shinfo, xen_pfn_t 
**live_p2m,
                               unsigned long *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
-    return xc_core_arch_map_p2m_rw(xc_handle, dinfo, info,
+    return xc_core_arch_map_p2m_rw(xch, dinfo, info,
                                    live_shinfo, live_p2m, pfnp, 1);
 }
 /*
diff --git a/tools/libxc/xc_core_x86.h b/tools/libxc/xc_core_x86.h
index 00955e2..a6144ff 100644
--- a/tools/libxc/xc_core_x86.h
+++ b/tools/libxc/xc_core_x86.h
@@ -30,7 +30,7 @@ struct xc_core_arch_context {
 
 #define xc_core_arch_context_init(arch_ctxt)            do {} while (0)
 #define xc_core_arch_context_free(arch_ctxt)            do {} while (0)
-#define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \
+#define xc_core_arch_context_get(arch_ctxt, ctxt, xch, domid) \
                                                                 (0)
 #define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn)    (0)
 
diff --git a/tools/libxc/xc_cpu_hotplug.c b/tools/libxc/xc_cpu_hotplug.c
index 4f68823..318d5dd 100644
--- a/tools/libxc/xc_cpu_hotplug.c
+++ b/tools/libxc/xc_cpu_hotplug.c
@@ -25,7 +25,7 @@
 
 #include "xc_private.h"
 
-int xc_cpu_online(int xc_handle, int cpu)
+int xc_cpu_online(xc_interface *xch, int cpu)
 {
     DECLARE_SYSCTL;
     int ret;
@@ -33,12 +33,12 @@ int xc_cpu_online(int xc_handle, int cpu)
     sysctl.cmd = XEN_SYSCTL_cpu_hotplug;
     sysctl.u.cpu_hotplug.cpu = cpu;
     sysctl.u.cpu_hotplug.op = XEN_SYSCTL_CPU_HOTPLUG_ONLINE;
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     return ret;
 }
 
-int xc_cpu_offline(int xc_handle, int cpu)
+int xc_cpu_offline(xc_interface *xch, int cpu)
 {
     DECLARE_SYSCTL;
     int ret;
@@ -46,7 +46,7 @@ int xc_cpu_offline(int xc_handle, int cpu)
     sysctl.cmd = XEN_SYSCTL_cpu_hotplug;
     sysctl.u.cpu_hotplug.cpu = cpu;
     sysctl.u.cpu_hotplug.op = XEN_SYSCTL_CPU_HOTPLUG_OFFLINE;
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     return ret;
 }
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 54174a2..0993824 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -31,10 +31,10 @@
 #define DEF_MAX_BASE 0x0000000du
 #define DEF_MAX_EXT  0x80000008u
 
-static int hypervisor_is_64bit(int xc)
+static int hypervisor_is_64bit(xc_interface *xch)
 {
     xen_capabilities_info_t xen_caps = "";
-    return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
+    return ((xc_version(xch, XENVER_capabilities, &xen_caps) == 0) &&
             (strstr(xen_caps, "x86_64") != NULL));
 }
 
@@ -75,7 +75,8 @@ static void xc_cpuid_brand_get(char *str)
 }
 
 static void amd_xc_cpuid_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
+    xc_interface *xch, domid_t domid,
+    const unsigned int *input, unsigned int *regs,
     int is_pae)
 {
     switch ( input[0] )
@@ -86,7 +87,7 @@ static void amd_xc_cpuid_policy(
         break;
 
     case 0x80000001: {
-        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
+        int is_64bit = hypervisor_is_64bit(xch) && is_pae;
 
         if ( !is_pae )
             clear_bit(X86_FEATURE_PAE, regs[3]);
@@ -123,7 +124,8 @@ static void amd_xc_cpuid_policy(
 }
 
 static void intel_xc_cpuid_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
+    xc_interface *xch, domid_t domid,
+    const unsigned int *input, unsigned int *regs,
     int is_pae)
 {
     switch ( input[0] )
@@ -139,7 +141,7 @@ static void intel_xc_cpuid_policy(
         break;
 
     case 0x80000001: {
-        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
+        int is_64bit = hypervisor_is_64bit(xch) && is_pae;
 
         /* Only a few features are advertised in Intel's 0x80000001. */
         regs[2] &= (is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0);
@@ -162,13 +164,14 @@ static void intel_xc_cpuid_policy(
 }
 
 static void xc_cpuid_hvm_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
+    xc_interface *xch, domid_t domid,
+    const unsigned int *input, unsigned int *regs)
 {
     char brand[13];
     unsigned long pae;
     int is_pae;
 
-    xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
+    xc_get_hvm_param(xch, domid, HVM_PARAM_PAE_ENABLED, &pae);
     is_pae = !!pae;
 
     switch ( input[0] )
@@ -265,17 +268,18 @@ static void xc_cpuid_hvm_policy(
 
     xc_cpuid_brand_get(brand);
     if ( strstr(brand, "AMD") )
-        amd_xc_cpuid_policy(xc, domid, input, regs, is_pae);
+        amd_xc_cpuid_policy(xch, domid, input, regs, is_pae);
     else
-        intel_xc_cpuid_policy(xc, domid, input, regs, is_pae);
+        intel_xc_cpuid_policy(xch, domid, input, regs, is_pae);
 
 }
 
 static void xc_cpuid_pv_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
+    xc_interface *xch, domid_t domid,
+    const unsigned int *input, unsigned int *regs)
 {
     DECLARE_DOMCTL;
-    int guest_64bit, xen_64bit = hypervisor_is_64bit(xc);
+    int guest_64bit, xen_64bit = hypervisor_is_64bit(xch);
     char brand[13];
 
     xc_cpuid_brand_get(brand);
@@ -283,7 +287,7 @@ static void xc_cpuid_pv_policy(
     memset(&domctl, 0, sizeof(domctl));
     domctl.domain = domid;
     domctl.cmd = XEN_DOMCTL_get_address_size;
-    do_domctl(xc, &domctl);
+    do_domctl(xch, &domctl);
     guest_64bit = (domctl.u.address_size.size == 64);
 
     if ( (input[0] & 0x7fffffff) == 1 )
@@ -352,23 +356,24 @@ static void xc_cpuid_pv_policy(
 }
 
 static int xc_cpuid_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
+    xc_interface *xch, domid_t domid,
+    const unsigned int *input, unsigned int *regs)
 {
     xc_dominfo_t        info;
 
-    if ( xc_domain_getinfo(xc, domid, 1, &info) == 0 )
+    if ( xc_domain_getinfo(xch, domid, 1, &info) == 0 )
         return -EINVAL;
 
     if ( info.hvm )
-        xc_cpuid_hvm_policy(xc, domid, input, regs);
+        xc_cpuid_hvm_policy(xch, domid, input, regs);
     else
-        xc_cpuid_pv_policy(xc, domid, input, regs);
+        xc_cpuid_pv_policy(xch, domid, input, regs);
 
     return 0;
 }
 
 static int xc_cpuid_do_domctl(
-    int xc, domid_t domid,
+    xc_interface *xch, domid_t domid,
     const unsigned int *input, const unsigned int *regs)
 {
     DECLARE_DOMCTL;
@@ -383,7 +388,7 @@ static int xc_cpuid_do_domctl(
     domctl.u.cpuid.ecx = regs[2];
     domctl.u.cpuid.edx = regs[3];
 
-    return do_domctl(xc, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 static char *alloc_str(void)
@@ -405,7 +410,7 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs)
     }
 }
 
-int xc_cpuid_apply_policy(int xc, domid_t domid)
+int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
 {
     unsigned int input[2] = { 0, 0 }, regs[4];
     unsigned int base_max, ext_max;
@@ -422,11 +427,11 @@ int xc_cpuid_apply_policy(int xc, domid_t domid)
     for ( ; ; )
     {
         cpuid(input, regs);
-        xc_cpuid_policy(xc, domid, input, regs);
+        xc_cpuid_policy(xch, domid, input, regs);
 
         if ( regs[0] || regs[1] || regs[2] || regs[3] )
         {
-            rc = xc_cpuid_do_domctl(xc, domid, input, regs);
+            rc = xc_cpuid_do_domctl(xch, domid, input, regs);
             if ( rc )
                 return rc;
 
@@ -462,7 +467,7 @@ int xc_cpuid_apply_policy(int xc, domid_t domid)
  *  's' -> (same) must be the same
  */
 int xc_cpuid_check(
-    int xc, const unsigned int *input,
+    xc_interface *xch, const unsigned int *input,
     const char **config,
     char **config_transformed)
 {
@@ -522,7 +527,7 @@ int xc_cpuid_check(
  * For 's' and 'x' the configuration is overwritten with the value applied.
  */
 int xc_cpuid_set(
-    int xc, domid_t domid, const unsigned int *input,
+    xc_interface *xch, domid_t domid, const unsigned int *input,
     const char **config, char **config_transformed)
 {
     int rc;
@@ -533,7 +538,7 @@ int xc_cpuid_set(
     cpuid(input, regs);
 
     memcpy(polregs, regs, sizeof(regs));
-    xc_cpuid_policy(xc, domid, input, polregs);
+    xc_cpuid_policy(xch, domid, input, polregs);
 
     for ( i = 0; i < 4; i++ )
     {
@@ -572,7 +577,7 @@ int xc_cpuid_set(
         }
     }
 
-    rc = xc_cpuid_do_domctl(xc, domid, input, regs);
+    rc = xc_cpuid_do_domctl(xch, domid, input, regs);
     if ( rc == 0 )
         return 0;
 
diff --git a/tools/libxc/xc_cpupool.c b/tools/libxc/xc_cpupool.c
index 12bcc0e..feec0e4 100644
--- a/tools/libxc/xc_cpupool.c
+++ b/tools/libxc/xc_cpupool.c
@@ -9,18 +9,18 @@
 #include <stdarg.h>
 #include "xc_private.h"
 
-static int do_sysctl_save(int xc_handle, struct xen_sysctl *sysctl)
+static int do_sysctl_save(xc_interface *xch, struct xen_sysctl *sysctl)
 {
     int ret;
 
     do {
-        ret = do_sysctl(xc_handle, sysctl);
+        ret = do_sysctl(xch, sysctl);
     } while ( (ret < 0) && (errno == EAGAIN) );
 
     return ret;
 }
 
-int xc_cpupool_create(int xc_handle,
+int xc_cpupool_create(xc_interface *xch,
                       uint32_t *ppoolid,
                       uint32_t sched_id)
 {
@@ -32,14 +32,14 @@ int xc_cpupool_create(int xc_handle,
     sysctl.u.cpupool_op.cpupool_id = (*ppoolid == 0) ?
         XEN_SYSCTL_CPUPOOL_PAR_ANY : *ppoolid;
     sysctl.u.cpupool_op.sched_id = sched_id;
-    if ( (err = do_sysctl_save(xc_handle, &sysctl)) != 0 )
+    if ( (err = do_sysctl_save(xch, &sysctl)) != 0 )
         return err;
 
     *ppoolid = sysctl.u.cpupool_op.cpupool_id;
     return 0;
 }
 
-int xc_cpupool_destroy(int xc_handle,
+int xc_cpupool_destroy(xc_interface *xch,
                        uint32_t poolid)
 {
     DECLARE_SYSCTL;
@@ -47,10 +47,10 @@ int xc_cpupool_destroy(int xc_handle,
     sysctl.cmd = XEN_SYSCTL_cpupool_op;
     sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_DESTROY;
     sysctl.u.cpupool_op.cpupool_id = poolid;
-    return do_sysctl_save(xc_handle, &sysctl);
+    return do_sysctl_save(xch, &sysctl);
 }
 
-int xc_cpupool_getinfo(int xc_handle, 
+int xc_cpupool_getinfo(xc_interface *xch, 
                        uint32_t first_poolid,
                        uint32_t n_max, 
                        xc_cpupoolinfo_t *info)
@@ -76,7 +76,7 @@ int xc_cpupool_getinfo(int xc_handle,
             PERROR("Could not lock memory for Xen hypercall");
             break;
         }
-        err = do_sysctl_save(xc_handle, &sysctl);
+        err = do_sysctl_save(xch, &sysctl);
         unlock_pages(local, sizeof (local));
 
         if ( err < 0 )
@@ -96,7 +96,7 @@ int xc_cpupool_getinfo(int xc_handle,
     return p;
 }
 
-int xc_cpupool_addcpu(int xc_handle,
+int xc_cpupool_addcpu(xc_interface *xch,
                       uint32_t poolid,
                       int cpu)
 {
@@ -106,10 +106,10 @@ int xc_cpupool_addcpu(int xc_handle,
     sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_ADDCPU;
     sysctl.u.cpupool_op.cpupool_id = poolid;
     sysctl.u.cpupool_op.cpu = (cpu < 0) ? XEN_SYSCTL_CPUPOOL_PAR_ANY : cpu;
-    return do_sysctl_save(xc_handle, &sysctl);
+    return do_sysctl_save(xch, &sysctl);
 }
 
-int xc_cpupool_removecpu(int xc_handle,
+int xc_cpupool_removecpu(xc_interface *xch,
                          uint32_t poolid,
                          int cpu)
 {
@@ -119,10 +119,10 @@ int xc_cpupool_removecpu(int xc_handle,
     sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_RMCPU;
     sysctl.u.cpupool_op.cpupool_id = poolid;
     sysctl.u.cpupool_op.cpu = (cpu < 0) ? XEN_SYSCTL_CPUPOOL_PAR_ANY : cpu;
-    return do_sysctl_save(xc_handle, &sysctl);
+    return do_sysctl_save(xch, &sysctl);
 }
 
-int xc_cpupool_movedomain(int xc_handle,
+int xc_cpupool_movedomain(xc_interface *xch,
                           uint32_t poolid,
                           uint32_t domid)
 {
@@ -132,10 +132,10 @@ int xc_cpupool_movedomain(int xc_handle,
     sysctl.u.cpupool_op.op = XEN_SYSCTL_CPUPOOL_OP_MOVEDOMAIN;
     sysctl.u.cpupool_op.cpupool_id = poolid;
     sysctl.u.cpupool_op.domid = domid;
-    return do_sysctl_save(xc_handle, &sysctl);
+    return do_sysctl_save(xch, &sysctl);
 }
 
-int xc_cpupool_freeinfo(int xc_handle,
+int xc_cpupool_freeinfo(xc_interface *xch,
                         uint64_t *cpumap)
 {
     int err;
@@ -153,7 +153,7 @@ int xc_cpupool_freeinfo(int xc_handle,
         return err;
     }
 
-    err = do_sysctl_save(xc_handle, &sysctl);
+    err = do_sysctl_save(xch, &sysctl);
     unlock_pages(local, sizeof (local));
 
     if (err < 0)
diff --git a/tools/libxc/xc_csched.c b/tools/libxc/xc_csched.c
index 4ea986f..ff9bb25 100644
--- a/tools/libxc/xc_csched.c
+++ b/tools/libxc/xc_csched.c
@@ -13,7 +13,7 @@
 
 int
 xc_sched_credit_domain_set(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     struct xen_domctl_sched_credit *sdom)
 {
@@ -25,12 +25,12 @@ xc_sched_credit_domain_set(
     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
     domctl.u.scheduler_op.u.credit = *sdom;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int
 xc_sched_credit_domain_get(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     struct xen_domctl_sched_credit *sdom)
 {
@@ -42,7 +42,7 @@ xc_sched_credit_domain_get(
     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT;
     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
 
-    err = do_domctl(xc_handle, &domctl);
+    err = do_domctl(xch, &domctl);
     if ( err == 0 )
         *sdom = domctl.u.scheduler_op.u.credit;
 
diff --git a/tools/libxc/xc_csched2.c b/tools/libxc/xc_csched2.c
index d25e59a..42cab68 100644
--- a/tools/libxc/xc_csched2.c
+++ b/tools/libxc/xc_csched2.c
@@ -13,7 +13,7 @@
 
 int
 xc_sched_credit2_domain_set(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     struct xen_domctl_sched_credit2 *sdom)
 {
@@ -25,12 +25,12 @@ xc_sched_credit2_domain_set(
     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
     domctl.u.scheduler_op.u.credit2 = *sdom;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int
 xc_sched_credit2_domain_get(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     struct xen_domctl_sched_credit2 *sdom)
 {
@@ -42,7 +42,7 @@ xc_sched_credit2_domain_get(
     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT2;
     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
 
-    err = do_domctl(xc_handle, &domctl);
+    err = do_domctl(xch, &domctl);
     if ( err == 0 )
         *sdom = domctl.u.scheduler_op.u.credit2;
 
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
index 58d3f49..8d8cf5b 100644
--- a/tools/libxc/xc_dom.h
+++ b/tools/libxc/xc_dom.h
@@ -93,7 +93,7 @@ struct xc_dom_image {
     unsigned int xenstore_evtchn;
     xen_pfn_t shared_info_mfn;
 
-    int guest_xc;
+    xc_interface *xch;
     domid_t guest_domid;
     int8_t vhpt_size_log2; /* for IA64 */
     int8_t superpages;
@@ -153,13 +153,16 @@ void xc_dom_register_arch_hooks(struct xc_dom_arch 
*hooks);
 
 /* --- main functions ---------------------------------------------- */
 
-struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char 
*features);
+struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
+                                     const char *cmdline, const char 
*features);
 void xc_dom_release_phys(struct xc_dom_image *dom);
 void xc_dom_release(struct xc_dom_image *dom);
 int xc_dom_mem_init(struct xc_dom_image *dom, unsigned int mem_mb);
 
-size_t xc_dom_check_gzip(void *blob, size_t ziplen);
-int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen);
+size_t xc_dom_check_gzip(xc_interface *xch,
+                     void *blob, size_t ziplen);
+int xc_dom_do_gunzip(xc_interface *xch,
+                     void *src, size_t srclen, void *dst, size_t dstlen);
 int xc_dom_try_gunzip(struct xc_dom_image *dom, void **blob, size_t * size);
 
 int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename);
@@ -170,11 +173,12 @@ int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const 
void *mem,
                        size_t memsize);
 
 int xc_dom_parse_image(struct xc_dom_image *dom);
-struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type);
+struct xc_dom_arch *xc_dom_find_arch_hooks(xc_interface *xch, char 
*guest_type);
 int xc_dom_build_image(struct xc_dom_image *dom);
 int xc_dom_update_guest_p2m(struct xc_dom_image *dom);
 
-int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid);
+int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch,
+                     domid_t domid);
 int xc_dom_boot_mem_init(struct xc_dom_image *dom);
 void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
                            xen_pfn_t count);
@@ -183,15 +187,17 @@ int xc_dom_compat_check(struct xc_dom_image *dom);
 
 /* --- debugging bits ---------------------------------------------- */
 
-extern FILE *xc_dom_logfile;
+int xc_dom_loginit(xc_interface *xch);
 
-void xc_dom_loginit(void);
-int xc_dom_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
-int xc_dom_panic_func(const char *file, int line, xc_error_code err,
+void xc_dom_printf(xc_interface *xch, const char *fmt, ...)
+     __attribute__ ((format(printf, 2, 3)));
+void xc_dom_panic_func(xc_interface *xch,
+                      const char *file, int line, xc_error_code err,
                       const char *fmt, ...)
-    __attribute__ ((format(printf, 4, 5)));
-#define xc_dom_panic(err, fmt, args...) \
-    xc_dom_panic_func(__FILE__, __LINE__, err, fmt, ## args)
+    __attribute__ ((format(printf, 5, 6)));
+
+#define xc_dom_panic(xch, err, fmt, args...) \
+    xc_dom_panic_func(xch, __FILE__, __LINE__, err, fmt, ## args)
 #define xc_dom_trace(mark) \
     xc_dom_printf("%s:%d: trace %s\n", __FILE__, __LINE__, mark)
 
diff --git a/tools/libxc/xc_dom_binloader.c b/tools/libxc/xc_dom_binloader.c
index e887620..77002b4 100644
--- a/tools/libxc/xc_dom_binloader.c
+++ b/tools/libxc/xc_dom_binloader.c
@@ -143,20 +143,20 @@ static int xc_dom_parse_bin_kernel(struct xc_dom_image 
*dom)
     if ( !image_info )
         return -EINVAL;
 
-    xc_dom_printf("%s: multiboot header fields\n", __FUNCTION__);
-    xc_dom_printf("  flags:         0x%" PRIx32 "\n", image_info->flags);
-    xc_dom_printf("  header_addr:   0x%" PRIx32 "\n", image_info->header_addr);
-    xc_dom_printf("  load_addr:     0x%" PRIx32 "\n", image_info->load_addr);
-    xc_dom_printf("  load_end_addr: 0x%" PRIx32 "\n", 
image_info->load_end_addr);
-    xc_dom_printf("  bss_end_addr:  0x%" PRIx32 "\n", 
image_info->bss_end_addr);
-    xc_dom_printf("  entry_addr:    0x%" PRIx32 "\n", image_info->entry_addr);
+    DOMPRINTF("%s: multiboot header fields", __FUNCTION__);
+    DOMPRINTF("  flags:         0x%" PRIx32 "", image_info->flags);
+    DOMPRINTF("  header_addr:   0x%" PRIx32 "", image_info->header_addr);
+    DOMPRINTF("  load_addr:     0x%" PRIx32 "", image_info->load_addr);
+    DOMPRINTF("  load_end_addr: 0x%" PRIx32 "", image_info->load_end_addr);
+    DOMPRINTF("  bss_end_addr:  0x%" PRIx32 "", image_info->bss_end_addr);
+    DOMPRINTF("  entry_addr:    0x%" PRIx32 "", image_info->entry_addr);
 
     /* Check the flags */
     if ( (image_info->flags & FLAGS_MASK) != FLAGS_REQUIRED )
     {
-        xc_dom_panic(XC_INVALID_KERNEL,
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
                      "%s: xen_bin_image_table flags required "
-                     "0x%08" PRIx32 " found 0x%08" PRIx32 "\n",
+                     "0x%08" PRIx32 " found 0x%08" PRIx32 "",
                      __FUNCTION__, FLAGS_REQUIRED, image_info->flags & 
FLAGS_MASK);
         return -EINVAL;
     }
@@ -166,7 +166,7 @@ static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom)
          ((char *) image_info - image) <
          (image_info->header_addr - image_info->load_addr) )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid header_addr.",
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid header_addr.",
                      __FUNCTION__);
         return -EINVAL;
     }
@@ -175,21 +175,21 @@ static int xc_dom_parse_bin_kernel(struct xc_dom_image 
*dom)
     load_end_addr = image_info->load_end_addr ?: start_addr + image_size;
     bss_end_addr = image_info->bss_end_addr ?: load_end_addr;
 
-    xc_dom_printf("%s: calculated addresses\n", __FUNCTION__);
-    xc_dom_printf("  start_addr:    0x%" PRIx32 "\n", start_addr);
-    xc_dom_printf("  load_end_addr: 0x%" PRIx32 "\n", load_end_addr);
-    xc_dom_printf("  bss_end_addr:  0x%" PRIx32 "\n", bss_end_addr);
+    DOMPRINTF("%s: calculated addresses", __FUNCTION__);
+    DOMPRINTF("  start_addr:    0x%" PRIx32 "", start_addr);
+    DOMPRINTF("  load_end_addr: 0x%" PRIx32 "", load_end_addr);
+    DOMPRINTF("  bss_end_addr:  0x%" PRIx32 "", bss_end_addr);
 
     if ( (start_addr + image_size) < load_end_addr )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid load_end_addr.\n",
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid load_end_addr.",
                      __FUNCTION__);
         return -EINVAL;
     }
 
     if ( bss_end_addr < load_end_addr)
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.\n",
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Invalid bss_end_addr.",
                      __FUNCTION__);
         return -EINVAL;
     }
@@ -217,7 +217,7 @@ static int xc_dom_parse_bin_kernel(struct xc_dom_image *dom)
         dom->guest_type = "xen-3.0-x86_32";
         if ( strstr(dom->xen_caps, "xen-3.0-x86_32p") )
         {
-            xc_dom_printf("%s: PAE fixup\n", __FUNCTION__);
+            DOMPRINTF("%s: PAE fixup", __FUNCTION__);
             dom->guest_type = "xen-3.0-x86_32p";
             dom->parms.pae  = 2;
         }
@@ -250,10 +250,10 @@ static int xc_dom_load_bin_kernel(struct xc_dom_image 
*dom)
     text_size = load_end_addr - image_info->load_addr;
     bss_size = bss_end_addr - load_end_addr;
 
-    xc_dom_printf("%s: calculated sizes\n", __FUNCTION__);
-    xc_dom_printf("  skip:      0x%" PRIx32 "\n", skip);
-    xc_dom_printf("  text_size: 0x%" PRIx32 "\n", text_size);
-    xc_dom_printf("  bss_size:  0x%" PRIx32 "\n", bss_size);
+    DOMPRINTF("%s: calculated sizes", __FUNCTION__);
+    DOMPRINTF("  skip:      0x%" PRIx32 "", skip);
+    DOMPRINTF("  text_size: 0x%" PRIx32 "", text_size);
+    DOMPRINTF("  bss_size:  0x%" PRIx32 "", bss_size);
 
     dest = xc_dom_vaddr_to_ptr(dom, dom->kernel_seg.vstart);
     memcpy(dest, image + skip, text_size);
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index e767e8c..af37181 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -34,33 +34,34 @@ static int setup_hypercall_page(struct xc_dom_image *dom)
     pfn = (dom->parms.virt_hypercall - dom->parms.virt_base)
         >> XC_DOM_PAGE_SHIFT(dom);
 
-    xc_dom_printf("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "\n", __FUNCTION__,
+    DOMPRINTF("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "", __FUNCTION__,
                   dom->parms.virt_hypercall, pfn);
     domctl.cmd = XEN_DOMCTL_hypercall_init;
     domctl.domain = dom->guest_domid;
     domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn);
-    rc = do_domctl(dom->guest_xc, &domctl);
+    rc = do_domctl(dom->xch, &domctl);
     if ( rc != 0 )
-        xc_dom_panic(XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)\n",
+        xc_dom_panic(dom->xch,
+                     XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)",
                      __FUNCTION__, rc);
     return rc;
 }
 
-static int launch_vm(int xc, domid_t domid, void *ctxt)
+static int launch_vm(xc_interface *xch, domid_t domid, void *ctxt)
 {
     DECLARE_DOMCTL;
     int rc;
 
-    xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt);
+    xc_dom_printf(xch, "%s: called, ctxt=%p", __FUNCTION__, ctxt);
     memset(&domctl, 0, sizeof(domctl));
     domctl.cmd = XEN_DOMCTL_setvcpucontext;
     domctl.domain = domid;
     domctl.u.vcpucontext.vcpu = 0;
     set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
-    rc = do_domctl(xc, &domctl);
+    rc = do_domctl(xch, &domctl);
     if ( rc != 0 )
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc);
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: SETVCPUCONTEXT failed (rc=%d)", __FUNCTION__, rc);
     return rc;
 }
 
@@ -73,13 +74,13 @@ static int clear_page(struct xc_dom_image *dom, xen_pfn_t 
pfn)
         return 0;
 
     dst = xc_dom_p2m_host(dom, pfn);
-    xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n",
-                  __FUNCTION__, pfn, dst);
-    rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst);
+    DOMPRINTF("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "",
+              __FUNCTION__, pfn, dst);
+    rc = xc_clear_domain_page(dom->xch, dom->guest_domid, dst);
     if ( rc != 0 )
-        xc_dom_panic(XC_INTERNAL_ERROR,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                      "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn
-                     ", rc=%d)\n", __FUNCTION__, pfn, rc);
+                     ", rc=%d)", __FUNCTION__, pfn, rc);
     return rc;
 }
 
@@ -99,33 +100,33 @@ int xc_dom_compat_check(struct xc_dom_image *dom)
           item != NULL ; item = strtok_r(NULL, " ", &ptr) )
     {
         match = !strcmp(dom->guest_type, item);
-        xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__,
-                      item, match ? " <= matches" : "");
+        DOMPRINTF("%s: supported guest type: %s%s", __FUNCTION__,
+                  item, match ? " <= matches" : "");
         if ( match )
             found++;
     }
     if ( !found )
-        xc_dom_panic(XC_INVALID_KERNEL,
-                     "%s: guest type %s not supported by xen kernel, sorry\n",
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                     "%s: guest type %s not supported by xen kernel, sorry",
                      __FUNCTION__, dom->guest_type);
 
     return found;
 }
 
-int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid)
+int xc_dom_boot_xen_init(struct xc_dom_image *dom, xc_interface *xch, domid_t 
domid)
 {
-    dom->guest_xc = xc;
+    dom->xch = xch;
     dom->guest_domid = domid;
 
-    dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL);
-    if ( xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0 )
+    dom->xen_version = xc_version(xch, XENVER_version, NULL);
+    if ( xc_version(xch, XENVER_capabilities, &dom->xen_caps) < 0 )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities");
+        xc_dom_panic(xch, XC_INTERNAL_ERROR, "can't get xen capabilities");
         return -1;
     }
-    xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__,
-                  dom->xen_version >> 16, dom->xen_version & 0xff,
-                  dom->xen_caps);
+    DOMPRINTF("%s: ver %d.%d, caps %s", __FUNCTION__,
+              dom->xen_version >> 16, dom->xen_version & 0xff,
+              dom->xen_caps);
     return 0;
 }
 
@@ -133,13 +134,13 @@ int xc_dom_boot_mem_init(struct xc_dom_image *dom)
 {
     long rc;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     rc = arch_setup_meminit(dom);
     if ( rc != 0 )
     {
-        xc_dom_panic(XC_OUT_OF_MEMORY,
-                     "%s: can't allocate low memory for domain\n",
+        xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
+                     "%s: can't allocate low memory for domain",
                      __FUNCTION__);
         return rc;
     }
@@ -159,24 +160,24 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, 
xen_pfn_t pfn,
     entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t));
     if ( entries == NULL )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                      "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn
-                     " [malloc]\n", __FUNCTION__, pfn, count);
+                     " [malloc]", __FUNCTION__, pfn, count);
         return NULL;
     }
 
     for ( i = 0; i < count; i++ )
         entries[i].mfn = xc_dom_p2m_host(dom, pfn + i);
 
-    ptr = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid,
+    ptr = xc_map_foreign_ranges(dom->xch, dom->guest_domid,
                 count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift,
                 entries, count);
     if ( ptr == NULL )
     {
         err = errno;
-        xc_dom_panic(XC_INTERNAL_ERROR,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                      "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn
-                     " [mmap, errno=%i (%s)]\n", __FUNCTION__, pfn, count,
+                     " [mmap, errno=%i (%s)]", __FUNCTION__, pfn, count,
                      err, strerror(err));
         return NULL;
     }
@@ -190,7 +191,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     vcpu_guest_context_any_t ctxt;
     int rc;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* misc ia64 stuff*/
     if ( (rc = arch_setup_bootearly(dom)) != 0 )
@@ -199,17 +200,17 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     /* collect some info */
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
     domctl.domain = dom->guest_domid;
-    rc = do_domctl(dom->guest_xc, &domctl);
+    rc = do_domctl(dom->xch, &domctl);
     if ( rc != 0 )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: getdomaininfo failed (rc=%d)\n", __FUNCTION__, rc);
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: getdomaininfo failed (rc=%d)", __FUNCTION__, rc);
         return rc;
     }
     if ( domctl.domain != dom->guest_domid )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: Huh? domid mismatch (%d != %d)\n", __FUNCTION__,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: Huh? domid mismatch (%d != %d)", __FUNCTION__,
                      domctl.domain, dom->guest_domid);
         return -1;
     }
@@ -249,7 +250,7 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     if ( (rc = dom->arch_hooks->vcpu(dom, &ctxt)) != 0 )
         return rc;
     xc_dom_unmap_all(dom);
-    rc = launch_vm(dom->guest_xc, dom->guest_domid, &ctxt);
+    rc = launch_vm(dom->xch, dom->guest_domid, &ctxt);
 
     return rc;
 }
diff --git a/tools/libxc/xc_dom_bzimageloader.c 
b/tools/libxc/xc_dom_bzimageloader.c
index 67a7b8c..bb57cbb 100644
--- a/tools/libxc/xc_dom_bzimageloader.c
+++ b/tools/libxc/xc_dom_bzimageloader.c
@@ -43,7 +43,7 @@ static int xc_try_bzip2_decode(
     ret = BZ2_bzDecompressInit(&stream, 0, 0);
     if ( ret != BZ_OK )
     {
-        xc_dom_printf("BZIP2: Error initting stream\n");
+        DOMPRINTF("BZIP2: Error initting stream");
         return -1;
     }
 
@@ -55,7 +55,7 @@ static int xc_try_bzip2_decode(
     out_buf = malloc(outsize);
     if ( out_buf == NULL )
     {
-        xc_dom_printf("BZIP2: Failed to alloc memory\n");
+        DOMPRINTF("BZIP2: Failed to alloc memory");
         goto bzip2_cleanup;
     }
 
@@ -73,7 +73,7 @@ static int xc_try_bzip2_decode(
             tmp_buf = realloc(out_buf, outsize * 2);
             if ( tmp_buf == NULL )
             {
-                xc_dom_printf("BZIP2: Failed to realloc memory\n");
+                DOMPRINTF("BZIP2: Failed to realloc memory");
                 free(out_buf);
                 goto bzip2_cleanup;
             }
@@ -88,18 +88,18 @@ static int xc_try_bzip2_decode(
         {
             if ( ret == BZ_STREAM_END )
             {
-                xc_dom_printf("BZIP2: Saw data stream end\n");
+                DOMPRINTF("BZIP2: Saw data stream end");
                 retval = 0;
                 break;
             }
-            xc_dom_printf("BZIP2: error\n");
+            DOMPRINTF("BZIP2: error");
         }
     }
 
     total = (((uint64_t)stream.total_out_hi32) << 32) | stream.total_out_lo32;
 
-    xc_dom_printf("%s: BZIP2 decompress OK, 0x%zx -> 0x%lx\n",
-                  __FUNCTION__, *size, (long unsigned int) total);
+    DOMPRINTF("%s: BZIP2 decompress OK, 0x%zx -> 0x%lx",
+              __FUNCTION__, *size, (long unsigned int) total);
 
     *blob = out_buf;
     *size = total;
@@ -115,8 +115,8 @@ static int xc_try_bzip2_decode(
 static int xc_try_bzip2_decode(
     struct xc_dom_image *dom, void **blob, size_t *size)
 {
-    xc_dom_printf("%s: BZIP2 decompress support unavailable\n",
-                  __FUNCTION__);
+    DOMPRINTF("%s: BZIP2 decompress support unavailable",
+              __FUNCTION__);
     return -1;
 }
 
@@ -162,7 +162,7 @@ static int xc_try_lzma_decode(
     ret = lzma_alone_decoder(&stream, physmem() / 3);
     if ( ret != LZMA_OK )
     {
-        xc_dom_printf("LZMA: Failed to init stream decoder\n");
+        DOMPRINTF("LZMA: Failed to init stream decoder");
         return -1;
     }
 
@@ -174,7 +174,7 @@ static int xc_try_lzma_decode(
     out_buf = malloc(outsize);
     if ( out_buf == NULL )
     {
-        xc_dom_printf("LZMA: Failed to alloc memory\n");
+        DOMPRINTF("LZMA: Failed to alloc memory");
         goto lzma_cleanup;
     }
 
@@ -192,7 +192,7 @@ static int xc_try_lzma_decode(
             tmp_buf = realloc(out_buf, outsize * 2);
             if ( tmp_buf == NULL )
             {
-                xc_dom_printf("LZMA: Failed to realloc memory\n");
+                DOMPRINTF("LZMA: Failed to realloc memory");
                 free(out_buf);
                 goto lzma_cleanup;
             }
@@ -207,7 +207,7 @@ static int xc_try_lzma_decode(
         {
             if ( ret == LZMA_STREAM_END )
             {
-                xc_dom_printf("LZMA: Saw data stream end\n");
+                DOMPRINTF("LZMA: Saw data stream end");
                 retval = 0;
                 break;
             }
@@ -243,14 +243,14 @@ static int xc_try_lzma_decode(
                 msg = "Internal program error (bug)";
                 break;
             }
-            xc_dom_printf("%s: LZMA decompression error %s\n",
-                          __FUNCTION__, msg);
+            DOMPRINTF("%s: LZMA decompression error %s",
+                      __FUNCTION__, msg);
             break;
         }
     }
 
-    xc_dom_printf("%s: LZMA decompress OK, 0x%zx -> 0x%zx\n",
-                  __FUNCTION__, *size, (size_t)stream.total_out);
+    DOMPRINTF("%s: LZMA decompress OK, 0x%zx -> 0x%zx",
+              __FUNCTION__, *size, (size_t)stream.total_out);
 
     *blob = out_buf;
     *size = stream.total_out;
@@ -266,8 +266,8 @@ static int xc_try_lzma_decode(
 static int xc_try_lzma_decode(
     struct xc_dom_image *dom, void **blob, size_t *size)
 {
-    xc_dom_printf("%s: LZMA decompress support unavailable\n",
-                  __FUNCTION__);
+    DOMPRINTF("%s: LZMA decompress support unavailable",
+              __FUNCTION__);
     return -1;
 }
 
@@ -330,15 +330,15 @@ static int xc_dom_probe_bzimage_kernel(struct 
xc_dom_image *dom)
 
     if ( dom->kernel_blob == NULL )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n",
-                     __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: no kernel image loaded", __FUNCTION__);
         return -EINVAL;
     }
 
     if ( dom->kernel_size < sizeof(struct setup_header) )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR, "%s: kernel image too small\n",
-                     __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: kernel image too small", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -346,15 +346,15 @@ static int xc_dom_probe_bzimage_kernel(struct 
xc_dom_image *dom)
 
     if ( memcmp(&hdr->header, HDR_MAGIC, HDR_MAGIC_SZ) != 0 )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not a bzImage\n",
-                     __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                     "%s: kernel is not a bzImage", __FUNCTION__);
         return -EINVAL;
     }
 
     if ( hdr->version < VERSION(2,8) )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: boot protocol too old (%04x)\n",
-                     __FUNCTION__, hdr->version);
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: boot protocol"
+                     " too old (%04x)", __FUNCTION__, hdr->version);
         return -EINVAL;
     }
 
@@ -366,9 +366,8 @@ static int xc_dom_probe_bzimage_kernel(struct xc_dom_image 
*dom)
         ret = xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
         if ( ret == -1 )
         {
-            xc_dom_panic(XC_INVALID_KERNEL,
-                         "%s: unable to gzip decompress kernel\n",
-                         __FUNCTION__);
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: unable to"
+                         " gzip decompress kernel", __FUNCTION__);
             return -EINVAL;
         }
     }
@@ -377,7 +376,7 @@ static int xc_dom_probe_bzimage_kernel(struct xc_dom_image 
*dom)
         ret = xc_try_bzip2_decode(dom, &dom->kernel_blob, &dom->kernel_size);
         if ( ret < 0 )
         {
-            xc_dom_panic(XC_INVALID_KERNEL,
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
                          "%s unable to BZIP2 decompress kernel",
                          __FUNCTION__);
             return -EINVAL;
@@ -388,16 +387,16 @@ static int xc_dom_probe_bzimage_kernel(struct 
xc_dom_image *dom)
         ret = xc_try_lzma_decode(dom, &dom->kernel_blob, &dom->kernel_size);
         if ( ret < 0 )
         {
-            xc_dom_panic(XC_INVALID_KERNEL,
-                         "%s unable to LZMA decompress kernel\n",
+            xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                         "%s unable to LZMA decompress kernel",
                          __FUNCTION__);
             return -EINVAL;
         }
     }
     else
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: unknown compression format\n",
-                     __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL,
+                     "%s: unknown compression format", __FUNCTION__);
         return -EINVAL;
     }
 
diff --git a/tools/libxc/xc_dom_compat_linux.c 
b/tools/libxc/xc_dom_compat_linux.c
index ef80962..772934a 100644
--- a/tools/libxc/xc_dom_compat_linux.c
+++ b/tools/libxc/xc_dom_compat_linux.c
@@ -22,7 +22,7 @@
 /* ------------------------------------------------------------------------ */
 
 static int xc_linux_build_internal(struct xc_dom_image *dom,
-                                   int xc_handle, uint32_t domid,
+                                   xc_interface *xch, uint32_t domid,
                                    unsigned int mem_mb,
                                    unsigned long flags,
                                    unsigned int store_evtchn,
@@ -36,7 +36,7 @@ static int xc_linux_build_internal(struct xc_dom_image *dom,
     dom->console_evtchn = console_evtchn;
     dom->xenstore_evtchn = store_evtchn;
 
-    if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 )
+    if ( (rc = xc_dom_boot_xen_init(dom, xch, domid)) != 0 )
         goto out;
     if ( (rc = xc_dom_parse_image(dom)) != 0 )
         goto out;
@@ -56,7 +56,7 @@ static int xc_linux_build_internal(struct xc_dom_image *dom,
     return rc;
 }
 
-int xc_linux_build_mem(int xc_handle, uint32_t domid,
+int xc_linux_build_mem(xc_interface *xch, uint32_t domid,
                        unsigned int mem_mb,
                        const char *image_buffer,
                        unsigned long image_size,
@@ -73,14 +73,14 @@ int xc_linux_build_mem(int xc_handle, uint32_t domid,
     struct xc_dom_image *dom;
     int rc;
 
-    xc_dom_loginit();
-    dom = xc_dom_allocate(cmdline, features);
+    xc_dom_loginit(xch);
+    dom = xc_dom_allocate(xch, cmdline, features);
     if ( (rc = xc_dom_kernel_mem(dom, image_buffer, image_size)) != 0 )
         goto out;
     if ( initrd && ((rc = xc_dom_ramdisk_mem(dom, initrd, initrd_len)) != 0) )
         goto out;
 
-    rc = xc_linux_build_internal(dom, xc_handle, domid,
+    rc = xc_linux_build_internal(dom, xch, domid,
                                  mem_mb, flags,
                                  store_evtchn, store_mfn,
                                  console_evtchn, console_mfn);
@@ -90,7 +90,7 @@ int xc_linux_build_mem(int xc_handle, uint32_t domid,
     return rc;
 }
 
-int xc_linux_build(int xc_handle, uint32_t domid,
+int xc_linux_build(xc_interface *xch, uint32_t domid,
                    unsigned int mem_mb,
                    const char *image_name,
                    const char *initrd_name,
@@ -105,15 +105,15 @@ int xc_linux_build(int xc_handle, uint32_t domid,
     struct xc_dom_image *dom;
     int rc;
 
-    xc_dom_loginit();
-    dom = xc_dom_allocate(cmdline, features);
+    xc_dom_loginit(xch);
+    dom = xc_dom_allocate(xch, cmdline, features);
     if ( (rc = xc_dom_kernel_file(dom, image_name)) != 0 )
         goto out;
     if ( initrd_name && strlen(initrd_name) &&
          ((rc = xc_dom_ramdisk_file(dom, initrd_name)) != 0) )
         goto out;
 
-    rc = xc_linux_build_internal(dom, xc_handle, domid,
+    rc = xc_linux_build_internal(dom, xch, domid,
                                  mem_mb, flags,
                                  store_evtchn, store_mfn,
                                  console_evtchn, console_mfn);
@@ -122,13 +122,14 @@ int xc_linux_build(int xc_handle, uint32_t domid,
     xc_dom_release(dom);
     return rc;
 }
-int xc_get_bit_size(const char *image_name, const char *cmdline, 
-                      const char *features, int *bit_size)
+int xc_get_bit_size(xc_interface *xch,
+                    const char *image_name, const char *cmdline, 
+                    const char *features, int *bit_size)
 {
     struct xc_dom_image *dom;
     int rc;
     *bit_size = 0;
-    dom = xc_dom_allocate(cmdline, features);
+    dom = xc_dom_allocate(xch, cmdline, features);
     if ( (rc = xc_dom_kernel_file(dom, image_name)) != 0 )
         goto out;
     if ( (rc = xc_dom_parse_image(dom)) != 0 )
@@ -145,7 +146,7 @@ out:
     return rc;
 }
 
-int xc_dom_linux_build(int xc_handle,
+int xc_dom_linux_build(xc_interface *xch,
                        struct xc_dom_image *dom,
                        uint32_t domid,
                        unsigned int mem_mb,
@@ -164,7 +165,7 @@ int xc_dom_linux_build(int xc_handle,
          ((rc = xc_dom_ramdisk_file(dom, initrd_name)) != 0) )
         return rc;
 
-    return xc_linux_build_internal(dom, xc_handle, domid,
+    return xc_linux_build_internal(dom, xch, domid,
                                    mem_mb, flags,
                                    store_evtchn, store_mfn,
                                    console_evtchn, console_mfn);
diff --git a/tools/libxc/xc_dom_core.c b/tools/libxc/xc_dom_core.c
index df8e83b..3dbb00f 100644
--- a/tools/libxc/xc_dom_core.c
+++ b/tools/libxc/xc_dom_core.c
@@ -16,6 +16,7 @@
 #include <stdarg.h>
 #include <inttypes.h>
 #include <zlib.h>
+#include <assert.h>
 
 #include "xg_private.h"
 #include "xc_dom.h"
@@ -23,74 +24,79 @@
 /* ------------------------------------------------------------------------ */
 /* debugging                                                                */
 
-FILE *xc_dom_logfile = NULL;
 
-void xc_dom_loginit(void)
-{
-    if ( xc_dom_logfile )
-        return;
-    xc_dom_logfile = fopen("/var/log/xen/domain-builder-ng.log", "a");
-    setvbuf(xc_dom_logfile, NULL, _IONBF, 0);
-    xc_dom_printf("### ----- xc domain builder logfile opened -----\n");
+
+static const char *default_logfile = "/var/log/xen/domain-builder-ng.log";
+
+int xc_dom_loginit(xc_interface *xch) {
+    if (xch->dombuild_logger) return 0;
+
+    if (!xch->dombuild_logger_file) {
+        xch->dombuild_logger_file = fopen(default_logfile, "a");
+        if (!xch->dombuild_logger_file) {
+            PERROR("Could not open logfile `%s'", default_logfile);
+            return -1;
+        }
+    }
+    
+    xch->dombuild_logger = xch->dombuild_logger_tofree =
+        (xentoollog_logger*)
+        xtl_createlogger_stdiostream(xch->dombuild_logger_file, XTL_DETAIL,
+             XTL_STDIOSTREAM_SHOW_DATE|XTL_STDIOSTREAM_SHOW_PID);
+    if (!xch->dombuild_logger)
+        return -1;
+
+    xc_dom_printf(xch, "### ----- xc domain builder logfile opened -----");
+
+    return 0;
 }
 
-int xc_dom_printf(const char *fmt, ...)
+void xc_dom_printf(xc_interface *xch, const char *fmt, ...)
 {
     va_list args;
-    char buf[1024];
-    int rc;
-
-    if ( !xc_dom_logfile )
-        return 0;
-
+    if (!xch->dombuild_logger) return;
     va_start(args, fmt);
-    rc = vsnprintf(buf, sizeof(buf), fmt, args);
+    xtl_logv(xch->dombuild_logger, XTL_DETAIL, -1, "domainbuilder", fmt, args);
     va_end(args);
-    rc = fwrite(buf, rc, 1, xc_dom_logfile);
-
-    return rc;
 }
 
-int xc_dom_panic_func(const char *file, int line, xc_error_code err,
-                      const char *fmt, ...)
+void xc_dom_panic_func(xc_interface *xch,
+                       const char *file, int line, xc_error_code err,
+                       const char *fmt, ...)
 {
     va_list args;
-    FILE *fp = stderr;
-    int rc = 0;
-    char pos[256];
     char msg[XC_MAX_ERROR_MSG_LEN];
 
-    if ( xc_dom_logfile )
-        fp = xc_dom_logfile;
-
-    snprintf(pos, sizeof(pos), "%s:%d: panic: ", file, line);
     va_start(args, fmt);
     vsnprintf(msg, sizeof(msg), fmt, args);
     va_end(args);
-    xc_set_error(err, "%s", msg);
-    rc = fprintf(fp, "%s%s", pos, msg);
-    return rc;
+    msg[sizeof(msg)-1] = 0;
+    
+    xc_report(xch,
+              xch->dombuild_logger ? xch->dombuild_logger : xch->error_handler,
+              XTL_ERROR, err, "panic: %s:%d: %s",
+              file, line, msg);
 }
 
-static void print_mem(const char *name, size_t mem)
+static void print_mem(struct xc_dom_image *dom, const char *name, size_t mem)
 {
     if ( mem > (32 * 1024 * 1024) )
-        xc_dom_printf("%-24s : %zd MB\n", name, mem / (1024 * 1024));
+        DOMPRINTF("%-24s : %zd MB", name, mem / (1024 * 1024));
     else if ( mem > (32 * 1024) )
-        xc_dom_printf("%-24s : %zd kB\n", name, mem / 1024);
+        DOMPRINTF("%-24s : %zd kB", name, mem / 1024);
     else
-        xc_dom_printf("%-24s : %zd bytes\n", name, mem);
+        DOMPRINTF("%-24s : %zd bytes", name, mem);
 }
 
 void xc_dom_log_memory_footprint(struct xc_dom_image *dom)
 {
-    xc_dom_printf("domain builder memory footprint\n");
-    xc_dom_printf("   allocated\n");
-    print_mem("      malloc", dom->alloc_malloc);
-    print_mem("      anon mmap", dom->alloc_mem_map);
-    xc_dom_printf("   mapped\n");
-    print_mem("      file mmap", dom->alloc_file_map);
-    print_mem("      domU mmap", dom->alloc_domU_map);
+    DOMPRINTF("domain builder memory footprint");
+    DOMPRINTF("   allocated");
+    print_mem(dom, "      malloc", dom->alloc_malloc);
+    print_mem(dom, "      anon mmap", dom->alloc_mem_map);
+    DOMPRINTF("   mapped");
+    print_mem(dom, "      file mmap", dom->alloc_file_map);
+    print_mem(dom, "      domU mmap", dom->alloc_domU_map);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -108,7 +114,7 @@ void *xc_dom_malloc(struct xc_dom_image *dom, size_t size)
     dom->memblocks = block;
     dom->alloc_malloc += sizeof(*block) + size;
     if ( size > (100 * 1024) )
-        print_mem(__FUNCTION__, size);
+        print_mem(dom, __FUNCTION__, size);
     return block->memory;
 }
 
@@ -134,7 +140,7 @@ void *xc_dom_malloc_page_aligned(struct xc_dom_image *dom, 
size_t size)
     dom->alloc_malloc += sizeof(*block);
     dom->alloc_mem_map += block->mmap_len;
     if ( size > (100 * 1024) )
-        print_mem(__FUNCTION__, size);
+        print_mem(dom, __FUNCTION__, size);
     return block->mmap_ptr;
 }
 
@@ -166,7 +172,7 @@ void *xc_dom_malloc_filemap(struct xc_dom_image *dom,
     dom->alloc_file_map += block->mmap_len;
     close(fd);
     if ( *size > (100 * 1024) )
-        print_mem(__FUNCTION__, *size);
+        print_mem(dom, __FUNCTION__, *size);
     return block->mmap_ptr;
 
  err:
@@ -204,7 +210,7 @@ char *xc_dom_strdup(struct xc_dom_image *dom, const char 
*str)
 /* ------------------------------------------------------------------------ */
 /* read files, copy memory blocks, with transparent gunzip                  */
 
-size_t xc_dom_check_gzip(void *blob, size_t ziplen)
+size_t xc_dom_check_gzip(xc_interface *xch, void *blob, size_t ziplen)
 {
     unsigned char *gzlen;
     size_t unziplen;
@@ -218,7 +224,8 @@ size_t xc_dom_check_gzip(void *blob, size_t ziplen)
     if ( (unziplen < 0) || (unziplen > (1024*1024*1024)) ) /* 1GB limit */
     {
         xc_dom_printf
-            ("%s: size (zip %zd, unzip %zd) looks insane, skip gunzip\n",
+            (xch,
+             "%s: size (zip %zd, unzip %zd) looks insane, skip gunzip",
              __FUNCTION__, ziplen, unziplen);
         return 0;
     }
@@ -226,7 +233,8 @@ size_t xc_dom_check_gzip(void *blob, size_t ziplen)
     return unziplen + 16;
 }
 
-int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, size_t dstlen)
+int xc_dom_do_gunzip(xc_interface *xch,
+                     void *src, size_t srclen, void *dst, size_t dstlen)
 {
     z_stream zStream;
     int rc;
@@ -239,20 +247,20 @@ int xc_dom_do_gunzip(void *src, size_t srclen, void *dst, 
size_t dstlen)
     rc = inflateInit2(&zStream, (MAX_WBITS + 32)); /* +32 means "handle gzip" 
*/
     if ( rc != Z_OK )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: inflateInit2 failed (rc=%d)\n", __FUNCTION__, rc);
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: inflateInit2 failed (rc=%d)", __FUNCTION__, rc);
         return -1;
     }
     rc = inflate(&zStream, Z_FINISH);
     inflateEnd(&zStream);
     if ( rc != Z_STREAM_END )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: inflate failed (rc=%d)\n", __FUNCTION__, rc);
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: inflate failed (rc=%d)", __FUNCTION__, rc);
         return -1;
     }
 
-    xc_dom_printf("%s: unzip ok, 0x%zx -> 0x%zx\n",
+    xc_dom_printf(xch, "%s: unzip ok, 0x%zx -> 0x%zx",
                   __FUNCTION__, srclen, dstlen);
     return 0;
 }
@@ -262,7 +270,7 @@ int xc_dom_try_gunzip(struct xc_dom_image *dom, void 
**blob, size_t * size)
     void *unzip;
     size_t unziplen;
 
-    unziplen = xc_dom_check_gzip(*blob, *size);
+    unziplen = xc_dom_check_gzip(dom->xch, *blob, *size);
     if ( unziplen == 0 )
         return 0;
 
@@ -270,7 +278,7 @@ int xc_dom_try_gunzip(struct xc_dom_image *dom, void 
**blob, size_t * size)
     if ( unzip == NULL )
         return -1;
 
-    if ( xc_dom_do_gunzip(*blob, *size, unzip, unziplen) == -1 )
+    if ( xc_dom_do_gunzip(dom->xch, *blob, *size, unzip, unziplen) == -1 )
         return -1;
 
     *blob = unzip;
@@ -292,8 +300,8 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t 
pfn,
          count > dom->total_pages ||
          pfn > dom->total_pages - count )
     {
-        xc_dom_printf("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")\n",
-                      __FUNCTION__, pfn, dom->total_pages);
+        DOMPRINTF("%s: pfn out of range (0x%" PRIpfn " > 0x%" PRIpfn ")",
+                  __FUNCTION__, pfn, dom->total_pages);
         return NULL;
     }
 
@@ -310,11 +318,11 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, 
xen_pfn_t pfn,
             if ( (pfn < phys->first) ||
                  ((pfn + count) > (phys->first + phys->count)) )
             {
-                xc_dom_printf("%s: request overlaps allocated block"
-                              " (req 0x%" PRIpfn "+0x%" PRIpfn ","
-                              " blk 0x%" PRIpfn "+0x%" PRIpfn ")\n",
-                              __FUNCTION__, pfn, count, phys->first,
-                              phys->count);
+                DOMPRINTF("%s: request overlaps allocated block"
+                          " (req 0x%" PRIpfn "+0x%" PRIpfn ","
+                          " blk 0x%" PRIpfn "+0x%" PRIpfn ")",
+                          __FUNCTION__, pfn, count, phys->first,
+                          phys->count);
                 return NULL;
             }
         }
@@ -331,9 +339,9 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t 
pfn,
     /* allocating is allowed with size specified only */
     if ( count == 0 )
     {
-        xc_dom_printf("%s: no block found, no size given,"
-                      " can't malloc (pfn 0x%" PRIpfn ")\n",
-                      __FUNCTION__, pfn);
+        DOMPRINTF("%s: no block found, no size given,"
+                  " can't malloc (pfn 0x%" PRIpfn ")",
+                  __FUNCTION__, pfn);
         return NULL;
     }
 
@@ -364,9 +372,9 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t 
pfn,
         if ( phys->ptr == MAP_FAILED )
         {
             err = errno;
-            xc_dom_panic(XC_OUT_OF_MEMORY,
+            xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
                          "%s: oom: can't allocate 0x%" PRIpfn " pages"
-                         " [mmap, errno=%i (%s)]\n",
+                         " [mmap, errno=%i (%s)]",
                          __FUNCTION__, count, err, strerror(err));
             return NULL;
         }
@@ -374,8 +382,8 @@ void *xc_dom_pfn_to_ptr(struct xc_dom_image *dom, xen_pfn_t 
pfn,
     }
 
 #if 1
-    xc_dom_printf("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p\n",
-                  __FUNCTION__, mode, phys->first, phys->count, phys->ptr);
+    DOMPRINTF("%s: %s: pfn 0x%" PRIpfn "+0x%" PRIpfn " at %p",
+              __FUNCTION__, mode, phys->first, phys->count, phys->ptr);
 #endif
     phys->next = dom->phys_pages;
     dom->phys_pages = phys;
@@ -395,16 +403,16 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
 
     if ( start & (page_size - 1) )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: segment start isn't page aligned (0x%" PRIx64 ")\n",
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: segment start isn't page aligned (0x%" PRIx64 ")",
                      __FUNCTION__, start);
         return -1;
     }
     if ( start < dom->virt_alloc_end )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                      "%s: segment start too low (0x%" PRIx64 " < 0x%" PRIx64
-                     ")\n", __FUNCTION__, start, dom->virt_alloc_end);
+                     ")", __FUNCTION__, start, dom->virt_alloc_end);
         return -1;
     }
 
@@ -414,9 +422,9 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
     if ( pages > dom->total_pages || /* double test avoids overflow probs */
          pages > dom->total_pages - seg->pfn)
     {
-        xc_dom_panic(XC_OUT_OF_MEMORY,
+        xc_dom_panic(dom->xch, XC_OUT_OF_MEMORY,
                      "%s: segment %s too large (0x%"PRIpfn" > "
-                     "0x%"PRIpfn" - 0x%"PRIpfn" pages)\n",
+                     "0x%"PRIpfn" - 0x%"PRIpfn" pages)",
                      __FUNCTION__, name, pages, dom->total_pages, seg->pfn);
         return -1;
     }
@@ -426,9 +434,9 @@ int xc_dom_alloc_segment(struct xc_dom_image *dom,
     if (dom->allocate)
         dom->allocate(dom, dom->virt_alloc_end);
 
-    xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
-                  "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n",
-                  __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages);
+    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
+              "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)",
+              __FUNCTION__, name, seg->vstart, seg->vend, seg->pfn, pages);
 
     /* map and clear pages */
     ptr = xc_dom_seg_to_ptr(dom, seg);
@@ -451,8 +459,8 @@ int xc_dom_alloc_page(struct xc_dom_image *dom, char *name)
         dom->allocate(dom, dom->virt_alloc_end);
     pfn = (start - dom->parms.virt_base) / page_size;
 
-    xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n",
-                  __FUNCTION__, name, start, pfn);
+    DOMPRINTF("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")",
+              __FUNCTION__, name, start, pfn);
     return pfn;
 }
 
@@ -469,8 +477,8 @@ void xc_dom_unmap_one(struct xc_dom_image *dom, xen_pfn_t 
pfn)
     }
     if ( !phys )
     {
-        xc_dom_printf("%s: Huh? no mapping with pfn 0x%" PRIpfn "\n",
-                      __FUNCTION__, pfn);
+        DOMPRINTF("%s: Huh? no mapping with pfn 0x%" PRIpfn "",
+                  __FUNCTION__, pfn);
         return;
     }
 
@@ -505,16 +513,17 @@ static struct xc_dom_loader *xc_dom_find_loader(struct 
xc_dom_image *dom)
 
     while ( loader != NULL )
     {
-        xc_dom_printf("%s: trying %s loader ... ", __FUNCTION__, loader->name);
+        DOMPRINTF("%s: trying %s loader ... ", __FUNCTION__, loader->name);
         if ( loader->probe(dom) == 0 )
         {
-            xc_dom_printf("OK\n");
+            DOMPRINTF("loader probe OK");
             return loader;
         }
-        xc_dom_printf("failed\n");
+        DOMPRINTF("loader probe failed");
         loader = loader->next;
     }
-    xc_dom_panic(XC_INVALID_KERNEL, "%s: no loader found\n", __FUNCTION__);
+    xc_dom_panic(dom->xch,
+                 XC_INVALID_KERNEL, "%s: no loader found", __FUNCTION__);
     return NULL;
 }
 
@@ -524,7 +533,7 @@ void xc_dom_register_arch_hooks(struct xc_dom_arch *hooks)
     first_hook = hooks;
 }
 
-struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
+struct xc_dom_arch *xc_dom_find_arch_hooks(xc_interface *xch, char *guest_type)
 {
     struct xc_dom_arch *hooks = first_hook;
 
@@ -534,8 +543,8 @@ struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
             return hooks;
         hooks = hooks->next;
     }
-    xc_dom_panic(XC_INVALID_KERNEL,
-                 "%s: not found (type %s)\n", __FUNCTION__, guest_type);
+    xc_dom_panic(xch, XC_INVALID_KERNEL,
+                 "%s: not found (type %s)", __FUNCTION__, guest_type);
     return NULL;
 }
 
@@ -544,24 +553,27 @@ struct xc_dom_arch *xc_dom_find_arch_hooks(char 
*guest_type)
 
 void xc_dom_release(struct xc_dom_image *dom)
 {
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
     if ( dom->phys_pages )
         xc_dom_unmap_all(dom);
     xc_dom_free_all(dom);
     free(dom);
 }
 
-struct xc_dom_image *xc_dom_allocate(const char *cmdline, const char *features)
+struct xc_dom_image *xc_dom_allocate(xc_interface *xch,
+                                     const char *cmdline, const char *features)
 {
     struct xc_dom_image *dom;
 
-    xc_dom_printf("%s: cmdline=\"%s\", features=\"%s\"\n",
+    xc_dom_printf(xch, "%s: cmdline=\"%s\", features=\"%s\"",
                   __FUNCTION__, cmdline, features);
     dom = malloc(sizeof(*dom));
     if ( !dom )
         goto err;
 
     memset(dom, 0, sizeof(*dom));
+    dom->xch = xch;
+
     if ( cmdline )
         dom->cmdline = xc_dom_strdup(dom, cmdline);
     if ( features )
@@ -584,7 +596,7 @@ struct xc_dom_image *xc_dom_allocate(const char *cmdline, 
const char *features)
 
 int xc_dom_kernel_file(struct xc_dom_image *dom, const char *filename)
 {
-    xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename);
+    DOMPRINTF("%s: filename=\"%s\"", __FUNCTION__, filename);
     dom->kernel_blob = xc_dom_malloc_filemap(dom, filename, &dom->kernel_size);
     if ( dom->kernel_blob == NULL )
         return -1;
@@ -593,7 +605,7 @@ int xc_dom_kernel_file(struct xc_dom_image *dom, const char 
*filename)
 
 int xc_dom_ramdisk_file(struct xc_dom_image *dom, const char *filename)
 {
-    xc_dom_printf("%s: filename=\"%s\"\n", __FUNCTION__, filename);
+    DOMPRINTF("%s: filename=\"%s\"", __FUNCTION__, filename);
     dom->ramdisk_blob =
         xc_dom_malloc_filemap(dom, filename, &dom->ramdisk_size);
     if ( dom->ramdisk_blob == NULL )
@@ -604,7 +616,7 @@ int xc_dom_ramdisk_file(struct xc_dom_image *dom, const 
char *filename)
 
 int xc_dom_kernel_mem(struct xc_dom_image *dom, const void *mem, size_t 
memsize)
 {
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
     dom->kernel_blob = (void *)mem;
     dom->kernel_size = memsize;
     return xc_dom_try_gunzip(dom, &dom->kernel_blob, &dom->kernel_size);
@@ -613,7 +625,7 @@ int xc_dom_kernel_mem(struct xc_dom_image *dom, const void 
*mem, size_t memsize)
 int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem,
                        size_t memsize)
 {
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
     dom->ramdisk_blob = (void *)mem;
     dom->ramdisk_size = memsize;
 //    return xc_dom_try_gunzip(dom, &dom->ramdisk_blob, &dom->ramdisk_size);
@@ -624,7 +636,7 @@ int xc_dom_parse_image(struct xc_dom_image *dom)
 {
     int i;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* parse kernel image */
     dom->kernel_loader = xc_dom_find_loader(dom);
@@ -634,8 +646,8 @@ int xc_dom_parse_image(struct xc_dom_image *dom)
         goto err;
     if ( dom->guest_type == NULL )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: guest_type not set\n", __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                     "%s: guest_type not set", __FUNCTION__);
         goto err;
     }
 
@@ -647,8 +659,8 @@ int xc_dom_parse_image(struct xc_dom_image *dom)
         if ( (dom->f_active[i] & dom->parms.f_supported[i]) !=
              dom->f_active[i] )
         {
-            xc_dom_panic(XC_INVALID_PARAM,
-                         "%s: unsupported feature requested\n", __FUNCTION__);
+            xc_dom_panic(dom->xch, XC_INVALID_PARAM,
+                         "%s: unsupported feature requested", __FUNCTION__);
             goto err;
         }
     }
@@ -663,10 +675,10 @@ int xc_dom_mem_init(struct xc_dom_image *dom, unsigned 
int mem_mb)
     unsigned int page_shift;
     xen_pfn_t nr_pages;
 
-    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
+    dom->arch_hooks = xc_dom_find_arch_hooks(dom->xch, dom->guest_type);
     if ( dom->arch_hooks == NULL )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n",
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: arch hooks not set",
                      __FUNCTION__);
         return -1;
     }
@@ -674,12 +686,12 @@ int xc_dom_mem_init(struct xc_dom_image *dom, unsigned 
int mem_mb)
     page_shift = XC_DOM_PAGE_SHIFT(dom);
     nr_pages = mem_mb << (20 - page_shift);
 
-    xc_dom_printf("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each\n",
-                  __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10));
+    DOMPRINTF("%s: mem %d MB, pages 0x%" PRIpfn " pages, %dk each",
+               __FUNCTION__, mem_mb, nr_pages, 1 << (page_shift-10));
     dom->total_pages = nr_pages;
 
-    xc_dom_printf("%s: 0x%" PRIpfn " pages\n",
-                  __FUNCTION__, dom->total_pages);
+    DOMPRINTF("%s: 0x%" PRIpfn " pages",
+              __FUNCTION__, dom->total_pages);
 
     return 0;
 }
@@ -696,8 +708,8 @@ int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
     switch ( dom->arch_hooks->sizeof_pfn )
     {
     case 4:
-        xc_dom_printf("%s: dst 32bit, pages 0x%" PRIpfn " \n",
-                      __FUNCTION__, dom->total_pages);
+        DOMPRINTF("%s: dst 32bit, pages 0x%" PRIpfn "",
+                  __FUNCTION__, dom->total_pages);
         p2m_32 = dom->p2m_guest;
         for ( i = 0; i < dom->total_pages; i++ )
             if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
@@ -706,8 +718,8 @@ int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
                 p2m_32[i] = (uint32_t) - 1;
         break;
     case 8:
-        xc_dom_printf("%s: dst 64bit, pages 0x%" PRIpfn " \n",
-                      __FUNCTION__, dom->total_pages);
+        DOMPRINTF("%s: dst 64bit, pages 0x%" PRIpfn "",
+                  __FUNCTION__, dom->total_pages);
         p2m_64 = dom->p2m_guest;
         for ( i = 0; i < dom->total_pages; i++ )
             if ( dom->p2m_host[i] != INVALID_P2M_ENTRY )
@@ -716,7 +728,7 @@ int xc_dom_update_guest_p2m(struct xc_dom_image *dom)
                 p2m_64[i] = (uint64_t) - 1;
         break;
     default:
-        xc_dom_panic(XC_INTERNAL_ERROR,
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                      "sizeof_pfn is invalid (is %d, can be 4 or 8)",
                      dom->arch_hooks->sizeof_pfn);
         return -1;
@@ -728,12 +740,12 @@ int xc_dom_build_image(struct xc_dom_image *dom)
 {
     unsigned int page_size;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* check for arch hooks */
     if ( dom->arch_hooks == NULL )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR, "%s: arch hooks not set\n",
+        xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: arch hooks not set",
                      __FUNCTION__);
         goto err;
     }
@@ -754,7 +766,7 @@ int xc_dom_build_image(struct xc_dom_image *dom)
         size_t unziplen, ramdisklen;
         void *ramdiskmap;
 
-        unziplen = xc_dom_check_gzip(dom->ramdisk_blob, dom->ramdisk_size);
+        unziplen = xc_dom_check_gzip(dom->xch, dom->ramdisk_blob, 
dom->ramdisk_size);
         ramdisklen = unziplen ? unziplen : dom->ramdisk_size;
         if ( xc_dom_alloc_segment(dom, &dom->ramdisk_seg, "ramdisk", 0,
                                   ramdisklen) != 0 )
@@ -762,7 +774,8 @@ int xc_dom_build_image(struct xc_dom_image *dom)
         ramdiskmap = xc_dom_seg_to_ptr(dom, &dom->ramdisk_seg);
         if ( unziplen )
         {
-            if ( xc_dom_do_gunzip(dom->ramdisk_blob, dom->ramdisk_size,
+            if ( xc_dom_do_gunzip(dom->xch,
+                                  dom->ramdisk_blob, dom->ramdisk_size,
                                   ramdiskmap, ramdisklen) == -1 )
                 goto err;
         }
@@ -783,10 +796,10 @@ int xc_dom_build_image(struct xc_dom_image *dom)
     }
     if ( dom->alloc_bootstack )
         dom->bootstack_pfn = xc_dom_alloc_page(dom, "boot stack");
-    xc_dom_printf("%-20s: virt_alloc_end : 0x%" PRIx64 "\n",
-                  __FUNCTION__, dom->virt_alloc_end);
-    xc_dom_printf("%-20s: virt_pgtab_end : 0x%" PRIx64 "\n",
-                  __FUNCTION__, dom->virt_pgtab_end);
+    DOMPRINTF("%-20s: virt_alloc_end : 0x%" PRIx64 "",
+              __FUNCTION__, dom->virt_alloc_end);
+    DOMPRINTF("%-20s: virt_pgtab_end : 0x%" PRIx64 "",
+              __FUNCTION__, dom->virt_pgtab_end);
     return 0;
 
  err:
diff --git a/tools/libxc/xc_dom_elfloader.c b/tools/libxc/xc_dom_elfloader.c
index 280f722..7ecab25 100644
--- a/tools/libxc/xc_dom_elfloader.c
+++ b/tools/libxc/xc_dom_elfloader.c
@@ -21,11 +21,18 @@
 
 static void log_callback(struct elf_binary *elf, void *caller_data,
                          int iserr, const char *fmt, va_list al) {
-    vfprintf(caller_data,fmt,al);
+    struct xc_interface *xch = caller_data;
+
+    xc_reportv(xch,
+          xch->dombuild_logger ? xch->dombuild_logger : xch->error_handler,
+                       iserr ? XTL_ERROR : XTL_DETAIL,
+                       iserr ? XC_INVALID_KERNEL : XC_ERROR_NONE,
+                       fmt, al);
 }
 
-void xc_elf_set_logfile(struct elf_binary *elf, FILE *f, int verbose) {
-    elf_set_log(elf, log_callback, f, verbose);
+void xc_elf_set_logfile(struct xc_interface *xch, struct elf_binary *elf,
+                        int verbose) {
+    elf_set_log(elf, log_callback, xch, verbose);
 }
 
 /* ------------------------------------------------------------------------ */
@@ -68,7 +75,8 @@ static int check_elf_kernel(struct xc_dom_image *dom, int 
verbose)
     if ( dom->kernel_blob == NULL )
     {
         if ( verbose )
-            xc_dom_panic(XC_INTERNAL_ERROR, "%s: no kernel image loaded\n",
+            xc_dom_panic(dom->xch,
+                         XC_INTERNAL_ERROR, "%s: no kernel image loaded",
                          __FUNCTION__);
         return -EINVAL;
     }
@@ -76,7 +84,8 @@ static int check_elf_kernel(struct xc_dom_image *dom, int 
verbose)
     if ( !elf_is_elfbinary(dom->kernel_blob) )
     {
         if ( verbose )
-            xc_dom_panic(XC_INVALID_KERNEL, "%s: kernel is not an ELF image\n",
+            xc_dom_panic(dom->xch,
+                         XC_INVALID_KERNEL, "%s: kernel is not an ELF image",
                          __FUNCTION__);
         return -EINVAL;
     }
@@ -100,8 +109,8 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
 
     if ( elf_swap(elf) )
     {
-        xc_dom_printf("%s: non-native byte order, bsd symtab not supported\n",
-                      __FUNCTION__);
+        DOMPRINTF("%s: non-native byte order, bsd symtab not supported",
+                  __FUNCTION__);
         return 0;
     }
 
@@ -150,18 +159,17 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
*dom,
     if ( elf_init(&syms, hdr + sizeof(int), size - sizeof(int)) )
         return -1;
 
-    if ( xc_dom_logfile )
-        xc_elf_set_logfile(&syms, xc_dom_logfile, 1);
+    xc_elf_set_logfile(dom->xch, &syms, 1);
 
     symtab = dom->bsd_symtab_start + sizeof(int);
     maxaddr = elf_round_up(&syms, symtab + elf_size(&syms, syms.ehdr) +
                            elf_shdr_count(&syms) * elf_size(&syms, shdr));
 
-    xc_dom_printf("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64
-                  " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "\n",
-                  __FUNCTION__, load ? "load" : "parse",
-                  dom->bsd_symtab_start, dom->kernel_seg.vend,
-                  symtab, maxaddr);
+    DOMPRINTF("%s/%s: bsd_symtab_start=%" PRIx64 ", kernel.end=0x%" PRIx64
+              " -- symtab=0x%" PRIx64 ", maxaddr=0x%" PRIx64 "",
+              __FUNCTION__, load ? "load" : "parse",
+              dom->bsd_symtab_start, dom->kernel_seg.vend,
+              symtab, maxaddr);
 
     count = elf_shdr_count(&syms);
     for ( h = 0; h < count; h++ )
@@ -199,10 +207,10 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image 
*dom,
             size = elf_uval(&syms, shdr, sh_size);
             maxaddr = elf_round_up(&syms, maxaddr + size);
             tables++;
-            xc_dom_printf("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "\n",
-                          __FUNCTION__, h,
-                          type == SHT_SYMTAB ? "symtab" : "strtab",
-                          size, maxaddr);
+            DOMPRINTF("%s: h=%d %s, size=0x%zx, maxaddr=0x%" PRIx64 "",
+                      __FUNCTION__, h,
+                      type == SHT_SYMTAB ? "symtab" : "strtab",
+                      size, maxaddr);
 
             if ( load )
             {
@@ -222,7 +230,7 @@ static int xc_dom_load_elf_symtab(struct xc_dom_image *dom,
 
     if ( tables == 0 )
     {
-        xc_dom_printf("%s: no symbol table present\n", __FUNCTION__);
+        DOMPRINTF("%s: no symbol table present", __FUNCTION__);
         dom->bsd_symtab_start = 0;
         return 0;
     }
@@ -243,11 +251,10 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image 
*dom)
     elf = xc_dom_malloc(dom, sizeof(*elf));
     dom->private_loader = elf;
     rc = elf_init(elf, dom->kernel_blob, dom->kernel_size);
-    if ( xc_dom_logfile )
-        xc_elf_set_logfile(elf, xc_dom_logfile, 1);
+    xc_elf_set_logfile(dom->xch, elf, 1);
     if ( rc != 0 )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: corrupted ELF image\n",
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: corrupted ELF image",
                      __FUNCTION__);
         return rc;
     }
@@ -255,8 +262,8 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
     /* Find the section-header strings table. */
     if ( elf->sec_strtab == NULL )
     {
-        xc_dom_panic(XC_INVALID_KERNEL, "%s: ELF image has no shstrtab\n",
-                     __FUNCTION__);
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: ELF image"
+                     " has no shstrtab", __FUNCTION__);
         return -EINVAL;
     }
 
@@ -273,9 +280,9 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
         xc_dom_load_elf_symtab(dom, elf, 0);
 
     dom->guest_type = xc_dom_guest_type(dom, elf);
-    xc_dom_printf("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
-                  __FUNCTION__, dom->guest_type,
-                  dom->kernel_seg.vstart, dom->kernel_seg.vend);
+    DOMPRINTF("%s: %s: 0x%" PRIx64 " -> 0x%" PRIx64 "",
+              __FUNCTION__, dom->guest_type,
+              dom->kernel_seg.vstart, dom->kernel_seg.vend);
     return 0;
 }
 
diff --git a/tools/libxc/xc_dom_ia64.c b/tools/libxc/xc_dom_ia64.c
index f5d4418..a9c8e63 100644
--- a/tools/libxc/xc_dom_ia64.c
+++ b/tools/libxc/xc_dom_ia64.c
@@ -44,7 +44,7 @@ int start_info_ia64(struct xc_dom_image *dom)
     struct xen_ia64_boot_param_ia64 *bp =
         (struct xen_ia64_boot_param_ia64 *)(start_info + 1);
 
-    xc_dom_printf("%s\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(start_info, 0, sizeof(*start_info));
     sprintf(start_info->magic, dom->guest_type);
@@ -84,7 +84,7 @@ int shared_info_ia64(struct xc_dom_image *dom, void *ptr)
     shared_info_ia64_t *shared_info = ptr;
     int i;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(shared_info, 0, sizeof(*shared_info));
     for (i = 0; i < XEN_LEGACY_MAX_VCPUS; i++)
@@ -101,7 +101,7 @@ static int vcpu_ia64(struct xc_dom_image *dom, void *ptr)
 {
     vcpu_guest_context_ia64_t *ctxt = ptr;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* clear everything */
     memset(ctxt, 0, sizeof(*ctxt));
@@ -193,8 +193,8 @@ static int ia64_setup_memmap(struct xc_dom_image *dom)
     /* setup memmap page */
     memmap_info_num_pages = 1;
     memmap_info_pfn = dom->start_info_pfn - 1;
-    xc_dom_printf("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx\n",
-                  __FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
+    DOMPRINTF("%s: memmap: mfn 0x%" PRIpfn " pages 0x%lx",
+              __FUNCTION__, memmap_info_pfn, memmap_info_num_pages);
     memmap_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
                                        page_size * memmap_info_num_pages,
                                        PROT_READ | PROT_WRITE,
@@ -244,7 +244,7 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
     DECLARE_DOMCTL;
     int rc;
 
-    xc_dom_printf("%s: setup firmware for %s\n", __FUNCTION__, 
dom->guest_type);
+    DOMPRINTF("%s: setup firmware for %s", __FUNCTION__, dom->guest_type);
 
     if (dom->guest_type && strcmp(dom->guest_type,
                                   "hvm-3.0-ia64-sioemu") == 0) {
@@ -255,7 +255,7 @@ int arch_setup_bootearly(struct xc_dom_image *dom)
         domctl.cmd = XEN_DOMCTL_arch_setup;
         domctl.domain = dom->guest_domid;
         rc = xc_domctl(dom->guest_xc, &domctl);
-        xc_dom_printf("%s: hvm-3.0-ia64-sioemu: %d\n", __FUNCTION__, rc);
+        DOMPRINTF("%s: hvm-3.0-ia64-sioemu: %d", __FUNCTION__, rc);
         return rc;
     }
 
@@ -296,8 +296,8 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
     shared_info_t *shared_info;
 
     /* setup shared_info page */
-    xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n",
-                  __FUNCTION__, dom->shared_info_mfn);
+    DOMPRINTF("%s: shared_info: mfn 0x%" PRIpfn "",
+              __FUNCTION__, dom->shared_info_mfn);
     shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
                                        page_size,
                                        PROT_READ | PROT_WRITE,
diff --git a/tools/libxc/xc_dom_x86.c b/tools/libxc/xc_dom_x86.c
index eddb93a..2eaa755 100644
--- a/tools/libxc/xc_dom_x86.c
+++ b/tools/libxc/xc_dom_x86.c
@@ -34,7 +34,8 @@
 #define round_up(addr, mask)     ((addr) | (mask))
 
 static unsigned long
-nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned long bits)
+nr_page_tables(struct xc_dom_image *dom,
+               xen_vaddr_t start, xen_vaddr_t end, unsigned long bits)
 {
     xen_vaddr_t mask = bits_to_mask(bits);
     int tables;
@@ -56,9 +57,9 @@ nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned 
long bits)
         tables = ((end - start) >> bits) + 1;
     }
 
-    xc_dom_printf("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64
-                  " -> 0x%016" PRIx64 ", %d table(s)\n",
-                  __FUNCTION__, mask, bits, start, end, tables);
+    DOMPRINTF("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64
+              " -> 0x%016" PRIx64 ", %d table(s)",
+              __FUNCTION__, mask, bits, start, end, tables);
     return tables;
 }
 
@@ -77,17 +78,17 @@ static int count_pgtables(struct xc_dom_image *dom, int pae,
         try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86,
                                 bits_to_mask(22)); /* 4MB alignment */
         dom->pg_l4 =
-            nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits);
+            nr_page_tables(dom, dom->parms.virt_base, try_virt_end, l4_bits);
         dom->pg_l3 =
-            nr_page_tables(dom->parms.virt_base, try_virt_end, l3_bits);
+            nr_page_tables(dom, dom->parms.virt_base, try_virt_end, l3_bits);
         dom->pg_l2 =
-            nr_page_tables(dom->parms.virt_base, try_virt_end, l2_bits);
+            nr_page_tables(dom, dom->parms.virt_base, try_virt_end, l2_bits);
         dom->pg_l1 =
-            nr_page_tables(dom->parms.virt_base, try_virt_end, l1_bits);
+            nr_page_tables(dom, dom->parms.virt_base, try_virt_end, l1_bits);
         if (pae && try_virt_end < 0xc0000000)
         {
-            xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n",
-                          __FUNCTION__);
+            DOMPRINTF("%s: PAE: extra l2 page table for l3#3",
+                      __FUNCTION__);
             dom->pg_l2++;
         }
         dom->pgtables = dom->pg_l4 + dom->pg_l3 + dom->pg_l2 + dom->pg_l1;
@@ -168,18 +169,17 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image 
*dom,
     xen_pfn_t new_l3mfn;
     struct xc_mmu *mmu;
     void *l3tab;
-    int xc = dom->guest_xc;
 
-    mmu = xc_alloc_mmu_updates(xc, dom->guest_domid);
+    mmu = xc_alloc_mmu_updates(dom->xch, dom->guest_domid);
     if ( mmu == NULL )
     {
-        xc_dom_printf("%s: failed at %d\n", __FUNCTION__, __LINE__);
+        DOMPRINTF("%s: failed at %d", __FUNCTION__, __LINE__);
         return l3mfn;
     }
 
     xc_dom_unmap_one(dom, l3pfn);
 
-    new_l3mfn = xc_make_page_below_4G(dom->guest_xc, dom->guest_domid, l3mfn);
+    new_l3mfn = xc_make_page_below_4G(dom->xch, dom->guest_domid, l3mfn);
     if ( !new_l3mfn )
         goto out;
 
@@ -187,13 +187,13 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image 
*dom,
     if ( xc_dom_update_guest_p2m(dom) != 0 )
         goto out;
 
-    if ( xc_add_mmu_update(xc, mmu,
+    if ( xc_add_mmu_update(dom->xch, mmu,
                            (((unsigned long long)new_l3mfn)
                             << XC_DOM_PAGE_SHIFT(dom)) |
                            MMU_MACHPHYS_UPDATE, l3pfn) )
         goto out;
 
-    if ( xc_flush_mmu_updates(xc, mmu) )
+    if ( xc_flush_mmu_updates(dom->xch, mmu) )
         goto out;
 
     /*
@@ -207,9 +207,9 @@ static xen_pfn_t move_l3_below_4G(struct xc_dom_image *dom,
     l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
     memset(l3tab, 0, XC_DOM_PAGE_SIZE(dom));
 
-    xc_dom_printf("%s: successfully relocated L3 below 4G. "
-                  "(L3 PFN %#"PRIpfn" MFN %#"PRIpfn"=>%#"PRIpfn")\n",
-                  __FUNCTION__, l3pfn, l3mfn, new_l3mfn);
+    DOMPRINTF("%s: successfully relocated L3 below 4G. "
+              "(L3 PFN %#"PRIpfn" MFN %#"PRIpfn"=>%#"PRIpfn")",
+              __FUNCTION__, l3pfn, l3mfn, new_l3mfn);
 
     l3mfn = new_l3mfn;
 
@@ -239,9 +239,9 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image 
*dom)
 
         if ( l3mfn >= 0x100000 )
         {
-            xc_dom_panic(XC_INTERNAL_ERROR,"%s: cannot move L3 below 4G. "
-                         "extended-cr3 not supported by guest. "
-                         "(L3 PFN %#"PRIpfn" MFN %#"PRIpfn")\n",
+            xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,"%s: cannot move L3"
+                         " below 4G. extended-cr3 not supported by guest. "
+                         "(L3 PFN %#"PRIpfn" MFN %#"PRIpfn")",
                          __FUNCTION__, l3pfn, l3mfn);
             return -EINVAL;
         }
@@ -288,7 +288,7 @@ static int setup_pgtables_x86_32_pae(struct xc_dom_image 
*dom)
 
     if ( dom->virt_pgtab_end <= 0xc0000000 )
     {
-        xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__);
+        DOMPRINTF("%s: PAE: extra l2 page table for l3#3", __FUNCTION__);
         l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
     }
     return 0;
@@ -418,7 +418,7 @@ static int start_info_x86_32(struct xc_dom_image *dom)
         xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom->
         shared_info_mfn;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(start_info, 0, sizeof(*start_info));
     strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
@@ -458,7 +458,7 @@ static int start_info_x86_64(struct xc_dom_image *dom)
         xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom->
         shared_info_mfn;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(start_info, 0, sizeof(*start_info));
     strncpy(start_info->magic, dom->guest_type, sizeof(start_info->magic));
@@ -495,7 +495,7 @@ static int shared_info_x86_32(struct xc_dom_image *dom, 
void *ptr)
     shared_info_x86_32_t *shared_info = ptr;
     int i;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(shared_info, 0, sizeof(*shared_info));
     for ( i = 0; i < XEN_LEGACY_MAX_VCPUS; i++ )
@@ -508,7 +508,7 @@ static int shared_info_x86_64(struct xc_dom_image *dom, 
void *ptr)
     shared_info_x86_64_t *shared_info = ptr;
     int i;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     memset(shared_info, 0, sizeof(*shared_info));
     for ( i = 0; i < XEN_LEGACY_MAX_VCPUS; i++ )
@@ -523,7 +523,7 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
     vcpu_guest_context_x86_32_t *ctxt = ptr;
     xen_pfn_t cr3_pfn;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* clear everything */
     memset(ctxt, 0, sizeof(*ctxt));
@@ -551,8 +551,8 @@ static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
 
     cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
     ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn);
-    xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
-                  __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
+    DOMPRINTF("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "",
+              __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
 
     return 0;
 }
@@ -562,7 +562,7 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
     vcpu_guest_context_x86_64_t *ctxt = ptr;
     xen_pfn_t cr3_pfn;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(dom->xch);
 
     /* clear everything */
     memset(ctxt, 0, sizeof(*ctxt));
@@ -586,8 +586,8 @@ static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
     ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
     cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
     ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
-    xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
-                  __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
+    DOMPRINTF("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "",
+              __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
 
     return 0;
 }
@@ -639,7 +639,7 @@ static void __init register_arch_hooks(void)
     xc_dom_register_arch_hooks(&xc_dom_64);
 }
 
-static int x86_compat(int xc, domid_t domid, char *guest_type)
+static int x86_compat(xc_interface *xch, domid_t domid, char *guest_type)
 {
     static const struct {
         char           *guest;
@@ -661,36 +661,36 @@ static int x86_compat(int xc, domid_t domid, char 
*guest_type)
         /* nothing to do */
         return 0;
 
-    xc_dom_printf("%s: guest %s, address size %" PRId32 "\n", __FUNCTION__,
+    xc_dom_printf(xch, "%s: guest %s, address size %" PRId32 "", __FUNCTION__,
                   guest_type, domctl.u.address_size.size);
-    rc = do_domctl(xc, &domctl);
+    rc = do_domctl(xch, &domctl);
     if ( rc != 0 )
-        xc_dom_printf("%s: warning: failed (rc=%d)\n",
+        xc_dom_printf(xch, "%s: warning: failed (rc=%d)",
                       __FUNCTION__, rc);
     return rc;
 }
 
 
-static int x86_shadow(int xc, domid_t domid)
+static int x86_shadow(xc_interface *xch, domid_t domid)
 {
     int rc, mode;
 
-    xc_dom_printf("%s: called\n", __FUNCTION__);
+    DOMPRINTF_CALLED(xch);
 
     mode = XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT |
         XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE;
 
-    rc = xc_shadow_control(xc, domid,
+    rc = xc_shadow_control(xch, domid,
                            XEN_DOMCTL_SHADOW_OP_ENABLE,
                            NULL, 0, NULL, mode, NULL);
     if ( rc != 0 )
     {
-        xc_dom_panic(XC_INTERNAL_ERROR,
-                     "%s: SHADOW_OP_ENABLE (mode=0x%x) failed (rc=%d)\n",
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: SHADOW_OP_ENABLE (mode=0x%x) failed (rc=%d)",
                      __FUNCTION__, mode, rc);
         return rc;
     }
-    xc_dom_printf("%s: shadow enabled (mode=0x%x)\n", __FUNCTION__, mode);
+    xc_dom_printf(xch, "%s: shadow enabled (mode=0x%x)", __FUNCTION__, mode);
     return rc;
 }
 
@@ -699,13 +699,13 @@ int arch_setup_meminit(struct xc_dom_image *dom)
     int rc;
     xen_pfn_t pfn, allocsz, i, j, mfn;
 
-    rc = x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type);
+    rc = x86_compat(dom->xch, dom->guest_domid, dom->guest_type);
     if ( rc )
         return rc;
     if ( xc_dom_feature_translated(dom) )
     {
         dom->shadow_enabled = 1;
-        rc = x86_shadow(dom->guest_xc, dom->guest_domid);
+        rc = x86_shadow(dom->xch, dom->guest_domid);
         if ( rc )
             return rc;
     }
@@ -716,10 +716,10 @@ int arch_setup_meminit(struct xc_dom_image *dom)
         int count = dom->total_pages >> SUPERPAGE_PFN_SHIFT;
         xen_pfn_t extents[count];
 
-        xc_dom_printf("Populating memory with %d superpages\n", count);
+        DOMPRINTF("Populating memory with %d superpages", count);
         for ( pfn = 0; pfn < count; pfn++ )
             extents[pfn] = pfn << SUPERPAGE_PFN_SHIFT;
-        rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid,
+        rc = xc_domain_memory_populate_physmap(dom->xch, dom->guest_domid,
                                                count, SUPERPAGE_PFN_SHIFT, 0,
                                                extents);
         if ( rc )
@@ -749,7 +749,7 @@ int arch_setup_meminit(struct xc_dom_image *dom)
             if ( allocsz > 1024*1024 )
                 allocsz = 1024*1024;
             rc = xc_domain_memory_populate_physmap(
-                dom->guest_xc, dom->guest_domid, allocsz,
+                dom->xch, dom->guest_domid, allocsz,
                 0, 0, &dom->p2m_host[i]);
         }
     }
@@ -759,7 +759,7 @@ int arch_setup_meminit(struct xc_dom_image *dom)
 
 int arch_setup_bootearly(struct xc_dom_image *dom)
 {
-    xc_dom_printf("%s: doing nothing\n", __FUNCTION__);
+    DOMPRINTF("%s: doing nothing", __FUNCTION__);
     return 0;
 }
 
@@ -786,13 +786,13 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
     {
         /* paravirtualized guest */
         xc_dom_unmap_one(dom, dom->pgtables_seg.pfn);
-        rc = pin_table(dom->guest_xc, pgd_type,
+        rc = pin_table(dom->xch, pgd_type,
                        xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
                        dom->guest_domid);
         if ( rc != 0 )
         {
-            xc_dom_panic(XC_INTERNAL_ERROR,
-                         "%s: pin_table failed (pfn 0x%" PRIpfn ", rc=%d)\n",
+            xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
+                         "%s: pin_table failed (pfn 0x%" PRIpfn ", rc=%d)",
                          __FUNCTION__, dom->pgtables_seg.pfn, rc);
             return rc;
         }
@@ -809,11 +809,11 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
         xatp.space = XENMAPSPACE_shared_info;
         xatp.idx = 0;
         xatp.gpfn = dom->shared_info_pfn;
-        rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
+        rc = xc_memory_op(dom->xch, XENMEM_add_to_physmap, &xatp);
         if ( rc != 0 )
         {
-            xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed "
-                         "(pfn=0x%" PRIpfn ", rc=%d)\n",
+            xc_dom_panic(dom->xch, XC_INTERNAL_ERROR, "%s: mapping"
+                         " shared_info failed (pfn=0x%" PRIpfn ", rc=%d)",
                          __FUNCTION__, xatp.gpfn, rc);
             return rc;
         }
@@ -825,18 +825,17 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
             xatp.space = XENMAPSPACE_grant_table;
             xatp.idx = i;
             xatp.gpfn = dom->total_pages + i;
-            rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
+            rc = xc_memory_op(dom->xch, XENMEM_add_to_physmap, &xatp);
             if ( rc != 0 )
             {
                 if ( (i > 0) && (errno == EINVAL) )
                 {
-                    xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__,
-                                  i);
+                    DOMPRINTF("%s: %d grant tables mapped", __FUNCTION__, i);
                     break;
                 }
-                xc_dom_panic(XC_INTERNAL_ERROR,
+                xc_dom_panic(dom->xch, XC_INTERNAL_ERROR,
                              "%s: mapping grant tables failed " "(pfn=0x%"
-                             PRIpfn ", rc=%d)\n", __FUNCTION__, xatp.gpfn, rc);
+                             PRIpfn ", rc=%d)", __FUNCTION__, xatp.gpfn, rc);
                 return rc;
             }
         }
@@ -844,9 +843,9 @@ int arch_setup_bootlate(struct xc_dom_image *dom)
     }
 
     /* setup shared_info page */
-    xc_dom_printf("%s: shared_info: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n",
-                  __FUNCTION__, dom->shared_info_pfn, dom->shared_info_mfn);
-    shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid,
+    DOMPRINTF("%s: shared_info: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "",
+              __FUNCTION__, dom->shared_info_pfn, dom->shared_info_mfn);
+    shared_info = xc_map_foreign_range(dom->xch, dom->guest_domid,
                                        PAGE_SIZE_X86,
                                        PROT_READ | PROT_WRITE,
                                        shinfo);
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 4f2cf2d..c575eff 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -11,7 +11,7 @@
 #include <xen/memory.h>
 #include <xen/hvm/hvm_op.h>
 
-int xc_domain_create(int xc_handle,
+int xc_domain_create(xc_interface *xch,
                      uint32_t ssidref,
                      xen_domain_handle_t handle,
                      uint32_t flags,
@@ -25,7 +25,7 @@ int xc_domain_create(int xc_handle,
     domctl.u.createdomain.ssidref = ssidref;
     domctl.u.createdomain.flags   = flags;
     memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t));
-    if ( (err = do_domctl(xc_handle, &domctl)) != 0 )
+    if ( (err = do_domctl(xch, &domctl)) != 0 )
         return err;
 
     *pdomid = (uint16_t)domctl.domain;
@@ -33,27 +33,27 @@ int xc_domain_create(int xc_handle,
 }
 
 
-int xc_domain_pause(int xc_handle,
+int xc_domain_pause(xc_interface *xch,
                     uint32_t domid)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_pausedomain;
     domctl.domain = (domid_t)domid;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 
-int xc_domain_unpause(int xc_handle,
+int xc_domain_unpause(xc_interface *xch,
                       uint32_t domid)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_unpausedomain;
     domctl.domain = (domid_t)domid;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 
-int xc_domain_destroy(int xc_handle,
+int xc_domain_destroy(xc_interface *xch,
                       uint32_t domid)
 {
     int ret;
@@ -61,12 +61,12 @@ int xc_domain_destroy(int xc_handle,
     domctl.cmd = XEN_DOMCTL_destroydomain;
     domctl.domain = (domid_t)domid;
     do {
-        ret = do_domctl(xc_handle, &domctl);
+        ret = do_domctl(xch, &domctl);
     } while ( ret && (errno == EAGAIN) );
     return ret;
 }
 
-int xc_domain_shutdown(int xc_handle,
+int xc_domain_shutdown(xc_interface *xch,
                        uint32_t domid,
                        int reason)
 {
@@ -86,7 +86,7 @@ int xc_domain_shutdown(int xc_handle,
         goto out1;
     }
 
-    ret = do_xen_hypercall(xc_handle, &hypercall);
+    ret = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(&arg, sizeof(arg));
 
@@ -95,7 +95,7 @@ int xc_domain_shutdown(int xc_handle,
 }
 
 
-int xc_vcpu_setaffinity(int xc_handle,
+int xc_vcpu_setaffinity(xc_interface *xch,
                         uint32_t domid,
                         int vcpu,
                         uint64_t *cpumap, int cpusize)
@@ -125,7 +125,7 @@ int xc_vcpu_setaffinity(int xc_handle,
         goto out;
     }
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     unlock_pages(local, cpusize);
 
@@ -135,7 +135,7 @@ int xc_vcpu_setaffinity(int xc_handle,
 }
 
 
-int xc_vcpu_getaffinity(int xc_handle,
+int xc_vcpu_getaffinity(xc_interface *xch,
                         uint32_t domid,
                         int vcpu,
                         uint64_t *cpumap, int cpusize)
@@ -164,7 +164,7 @@ int xc_vcpu_getaffinity(int xc_handle,
         goto out;
     }
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     unlock_pages(local, sizeof (local));
     bitmap_byte_to_64(cpumap, local, cpusize * 8);
@@ -174,7 +174,7 @@ out:
 }
 
 
-int xc_domain_getinfo(int xc_handle,
+int xc_domain_getinfo(xc_interface *xch,
                       uint32_t first_domid,
                       unsigned int max_doms,
                       xc_dominfo_t *info)
@@ -190,7 +190,7 @@ int xc_domain_getinfo(int xc_handle,
     {
         domctl.cmd = XEN_DOMCTL_getdomaininfo;
         domctl.domain = (domid_t)next_domid;
-        if ( (rc = do_domctl(xc_handle, &domctl)) < 0 )
+        if ( (rc = do_domctl(xch, &domctl)) < 0 )
             break;
         info->domid      = (uint16_t)domctl.domain;
 
@@ -235,7 +235,7 @@ int xc_domain_getinfo(int xc_handle,
     return nr_doms;
 }
 
-int xc_domain_getinfolist(int xc_handle,
+int xc_domain_getinfolist(xc_interface *xch,
                           uint32_t first_domain,
                           unsigned int max_domains,
                           xc_domaininfo_t *info)
@@ -251,7 +251,7 @@ int xc_domain_getinfolist(int xc_handle,
     sysctl.u.getdomaininfolist.max_domains  = max_domains;
     set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
 
-    if ( xc_sysctl(xc_handle, &sysctl) < 0 )
+    if ( xc_sysctl(xch, &sysctl) < 0 )
         ret = -1;
     else
         ret = sysctl.u.getdomaininfolist.num_domains;
@@ -262,7 +262,7 @@ int xc_domain_getinfolist(int xc_handle,
 }
 
 /* get info from hvm guest for save */
-int xc_domain_hvm_getcontext(int xc_handle,
+int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
                              uint8_t *ctxt_buf,
                              uint32_t size)
@@ -279,7 +279,7 @@ int xc_domain_hvm_getcontext(int xc_handle,
         if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
             return ret;
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     if ( ctxt_buf ) 
         unlock_pages(ctxt_buf, size);
@@ -289,7 +289,7 @@ int xc_domain_hvm_getcontext(int xc_handle,
 
 /* Get just one element of the HVM guest context.
  * size must be >= HVM_SAVE_LENGTH(type) */
-int xc_domain_hvm_getcontext_partial(int xc_handle,
+int xc_domain_hvm_getcontext_partial(xc_interface *xch,
                                      uint32_t domid,
                                      uint16_t typecode,
                                      uint16_t instance,
@@ -311,7 +311,7 @@ int xc_domain_hvm_getcontext_partial(int xc_handle,
     if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
         return ret;
     
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     if ( ctxt_buf ) 
         unlock_pages(ctxt_buf, size);
@@ -320,7 +320,7 @@ int xc_domain_hvm_getcontext_partial(int xc_handle,
 }
 
 /* set info to hvm guest for restore */
-int xc_domain_hvm_setcontext(int xc_handle,
+int xc_domain_hvm_setcontext(xc_interface *xch,
                              uint32_t domid,
                              uint8_t *ctxt_buf,
                              uint32_t size)
@@ -336,14 +336,14 @@ int xc_domain_hvm_setcontext(int xc_handle,
     if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
         return ret;
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     unlock_pages(ctxt_buf, size);
 
     return ret;
 }
 
-int xc_vcpu_getcontext(int xc_handle,
+int xc_vcpu_getcontext(xc_interface *xch,
                        uint32_t domid,
                        uint32_t vcpu,
                        vcpu_guest_context_any_t *ctxt)
@@ -360,14 +360,14 @@ int xc_vcpu_getcontext(int xc_handle,
     
     if ( (rc = lock_pages(ctxt, sz)) != 0 )
         return rc;
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     unlock_pages(ctxt, sz);
 
     return rc;
 }
 
 
-int xc_shadow_control(int xc_handle,
+int xc_shadow_control(xc_interface *xch,
                       uint32_t domid,
                       unsigned int sop,
                       unsigned long *dirty_bitmap,
@@ -387,7 +387,7 @@ int xc_shadow_control(int xc_handle,
     set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap,
                          (uint8_t *)dirty_bitmap);
 
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
 
     if ( stats )
         memcpy(stats, &domctl.u.shadow_op.stats,
@@ -399,7 +399,7 @@ int xc_shadow_control(int xc_handle,
     return (rc == 0) ? domctl.u.shadow_op.pages : rc;
 }
 
-int xc_domain_setmaxmem(int xc_handle,
+int xc_domain_setmaxmem(xc_interface *xch,
                         uint32_t domid,
                         unsigned int max_memkb)
 {
@@ -407,10 +407,10 @@ int xc_domain_setmaxmem(int xc_handle,
     domctl.cmd = XEN_DOMCTL_max_mem;
     domctl.domain = (domid_t)domid;
     domctl.u.max_mem.max_memkb = max_memkb;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_pin_memory_cacheattr(int xc_handle,
+int xc_domain_pin_memory_cacheattr(xc_interface *xch,
                                    uint32_t domid,
                                    uint64_t start,
                                    uint64_t end,
@@ -422,12 +422,12 @@ int xc_domain_pin_memory_cacheattr(int xc_handle,
     domctl.u.pin_mem_cacheattr.start = start;
     domctl.u.pin_mem_cacheattr.end = end;
     domctl.u.pin_mem_cacheattr.type = type;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 #if defined(__i386__) || defined(__x86_64__)
 #include "xc_e820.h"
-int xc_domain_set_memmap_limit(int xc_handle,
+int xc_domain_set_memmap_limit(xc_interface *xch,
                                uint32_t domid,
                                unsigned long map_limitkb)
 {
@@ -453,7 +453,7 @@ int xc_domain_set_memmap_limit(int xc_handle,
         goto out;
     }
 
-    rc = xc_memory_op(xc_handle, XENMEM_set_memory_map, &fmap);
+    rc = xc_memory_op(xch, XENMEM_set_memory_map, &fmap);
 
  out:
     unlock_pages(&fmap, sizeof(fmap));
@@ -461,7 +461,7 @@ int xc_domain_set_memmap_limit(int xc_handle,
     return rc;
 }
 #else
-int xc_domain_set_memmap_limit(int xc_handle,
+int xc_domain_set_memmap_limit(xc_interface *xch,
                                uint32_t domid,
                                unsigned long map_limitkb)
 {
@@ -471,7 +471,7 @@ int xc_domain_set_memmap_limit(int xc_handle,
 }
 #endif
 
-int xc_domain_set_time_offset(int xc_handle,
+int xc_domain_set_time_offset(xc_interface *xch,
                               uint32_t domid,
                               int32_t time_offset_seconds)
 {
@@ -479,19 +479,19 @@ int xc_domain_set_time_offset(int xc_handle,
     domctl.cmd = XEN_DOMCTL_settimeoffset;
     domctl.domain = (domid_t)domid;
     domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_disable_migrate(int xc_handle, uint32_t domid)
+int xc_domain_disable_migrate(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_disable_migrate;
     domctl.domain = (domid_t)domid;
     domctl.u.disable_migrate.disable = 1;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_set_tsc_info(int xc_handle,
+int xc_domain_set_tsc_info(xc_interface *xch,
                            uint32_t domid,
                            uint32_t tsc_mode,
                            uint64_t elapsed_nsec,
@@ -505,10 +505,10 @@ int xc_domain_set_tsc_info(int xc_handle,
     domctl.u.tsc_info.info.elapsed_nsec = elapsed_nsec;
     domctl.u.tsc_info.info.gtsc_khz = gtsc_khz;
     domctl.u.tsc_info.info.incarnation = incarnation;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_get_tsc_info(int xc_handle,
+int xc_domain_get_tsc_info(xc_interface *xch,
                            uint32_t domid,
                            uint32_t *tsc_mode,
                            uint64_t *elapsed_nsec,
@@ -524,7 +524,7 @@ int xc_domain_get_tsc_info(int xc_handle,
     set_xen_guest_handle(domctl.u.tsc_info.out_info, &info);
     if ( (rc = lock_pages(&info, sizeof(info))) != 0 )
         return rc;
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     if ( rc == 0 )
     {
         *tsc_mode = info.tsc_mode;
@@ -537,7 +537,7 @@ int xc_domain_get_tsc_info(int xc_handle,
 }
 
 
-int xc_domain_memory_increase_reservation(int xc_handle,
+int xc_domain_memory_increase_reservation(xc_interface *xch,
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
@@ -555,7 +555,7 @@ int xc_domain_memory_increase_reservation(int xc_handle,
     /* may be NULL */
     set_xen_guest_handle(reservation.extent_start, extent_start);
 
-    err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
+    err = xc_memory_op(xch, XENMEM_increase_reservation, &reservation);
     if ( err == nr_extents )
         return 0;
 
@@ -571,7 +571,7 @@ int xc_domain_memory_increase_reservation(int xc_handle,
     return err;
 }
 
-int xc_domain_memory_decrease_reservation(int xc_handle,
+int xc_domain_memory_decrease_reservation(xc_interface *xch,
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
@@ -594,7 +594,7 @@ int xc_domain_memory_decrease_reservation(int xc_handle,
         return -1;
     }
 
-    err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
+    err = xc_memory_op(xch, XENMEM_decrease_reservation, &reservation);
     if ( err == nr_extents )
         return 0;
 
@@ -609,7 +609,7 @@ int xc_domain_memory_decrease_reservation(int xc_handle,
     return err;
 }
 
-int xc_domain_memory_populate_physmap(int xc_handle,
+int xc_domain_memory_populate_physmap(xc_interface *xch,
                                       uint32_t domid,
                                       unsigned long nr_extents,
                                       unsigned int extent_order,
@@ -625,7 +625,7 @@ int xc_domain_memory_populate_physmap(int xc_handle,
     };
     set_xen_guest_handle(reservation.extent_start, extent_start);
 
-    err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
+    err = xc_memory_op(xch, XENMEM_populate_physmap, &reservation);
     if ( err == nr_extents )
         return 0;
 
@@ -640,7 +640,7 @@ int xc_domain_memory_populate_physmap(int xc_handle,
     return err;
 }
 
-static int xc_domain_memory_pod_target(int xc_handle,
+static int xc_domain_memory_pod_target(xc_interface *xch,
                                        int op,
                                        uint32_t domid,
                                        uint64_t target_pages,
@@ -655,7 +655,7 @@ static int xc_domain_memory_pod_target(int xc_handle,
         .target_pages = target_pages
     };
 
-    err = xc_memory_op(xc_handle, op, &pod_target);
+    err = xc_memory_op(xch, op, &pod_target);
 
     if ( err < 0 )
     {
@@ -679,14 +679,14 @@ static int xc_domain_memory_pod_target(int xc_handle,
 }
                                        
 
-int xc_domain_memory_set_pod_target(int xc_handle,
+int xc_domain_memory_set_pod_target(xc_interface *xch,
                                     uint32_t domid,
                                     uint64_t target_pages,
                                     uint64_t *tot_pages,
                                     uint64_t *pod_cache_pages,
                                     uint64_t *pod_entries)
 {
-    return xc_domain_memory_pod_target(xc_handle,
+    return xc_domain_memory_pod_target(xch,
                                        XENMEM_set_pod_target,
                                        domid,
                                        target_pages,
@@ -695,13 +695,13 @@ int xc_domain_memory_set_pod_target(int xc_handle,
                                        pod_entries);
 }
 
-int xc_domain_memory_get_pod_target(int xc_handle,
+int xc_domain_memory_get_pod_target(xc_interface *xch,
                                     uint32_t domid,
                                     uint64_t *tot_pages,
                                     uint64_t *pod_cache_pages,
                                     uint64_t *pod_entries)
 {
-    return xc_domain_memory_pod_target(xc_handle,
+    return xc_domain_memory_pod_target(xch,
                                        XENMEM_get_pod_target,
                                        domid,
                                        -1,
@@ -710,16 +710,16 @@ int xc_domain_memory_get_pod_target(int xc_handle,
                                        pod_entries);
 }
 
-int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max)
+int xc_domain_max_vcpus(xc_interface *xch, uint32_t domid, unsigned int max)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_max_vcpus;
     domctl.domain = (domid_t)domid;
     domctl.u.max_vcpus.max    = max;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_sethandle(int xc_handle, uint32_t domid,
+int xc_domain_sethandle(xc_interface *xch, uint32_t domid,
                         xen_domain_handle_t handle)
 {
     DECLARE_DOMCTL;
@@ -727,10 +727,10 @@ int xc_domain_sethandle(int xc_handle, uint32_t domid,
     domctl.domain = (domid_t)domid;
     memcpy(domctl.u.setdomainhandle.handle, handle,
            sizeof(xen_domain_handle_t));
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_vcpu_getinfo(int xc_handle,
+int xc_vcpu_getinfo(xc_interface *xch,
                     uint32_t domid,
                     uint32_t vcpu,
                     xc_vcpuinfo_t *info)
@@ -742,14 +742,14 @@ int xc_vcpu_getinfo(int xc_handle,
     domctl.domain = (domid_t)domid;
     domctl.u.getvcpuinfo.vcpu   = (uint16_t)vcpu;
 
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
 
     memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
 
     return rc;
 }
 
-int xc_domain_ioport_permission(int xc_handle,
+int xc_domain_ioport_permission(xc_interface *xch,
                                 uint32_t domid,
                                 uint32_t first_port,
                                 uint32_t nr_ports,
@@ -763,10 +763,10 @@ int xc_domain_ioport_permission(int xc_handle,
     domctl.u.ioport_permission.nr_ports = nr_ports;
     domctl.u.ioport_permission.allow_access = allow_access;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_availheap(int xc_handle,
+int xc_availheap(xc_interface *xch,
                  int min_width,
                  int max_width,
                  int node,
@@ -780,14 +780,14 @@ int xc_availheap(int xc_handle,
     sysctl.u.availheap.max_bitwidth = max_width;
     sysctl.u.availheap.node = node;
 
-    rc = xc_sysctl(xc_handle, &sysctl);
+    rc = xc_sysctl(xch, &sysctl);
 
     *bytes = sysctl.u.availheap.avail_bytes;
 
     return rc;
 }
 
-int xc_vcpu_setcontext(int xc_handle,
+int xc_vcpu_setcontext(xc_interface *xch,
                        uint32_t domid,
                        uint32_t vcpu,
                        vcpu_guest_context_any_t *ctxt)
@@ -809,14 +809,14 @@ int xc_vcpu_setcontext(int xc_handle,
 
     if ( (rc = lock_pages(ctxt, sz)) != 0 )
         return rc;
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     
     unlock_pages(ctxt, sz);
 
     return rc;
 }
 
-int xc_domain_irq_permission(int xc_handle,
+int xc_domain_irq_permission(xc_interface *xch,
                              uint32_t domid,
                              uint8_t pirq,
                              uint8_t allow_access)
@@ -828,10 +828,10 @@ int xc_domain_irq_permission(int xc_handle,
     domctl.u.irq_permission.pirq = pirq;
     domctl.u.irq_permission.allow_access = allow_access;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_iomem_permission(int xc_handle,
+int xc_domain_iomem_permission(xc_interface *xch,
                                uint32_t domid,
                                unsigned long first_mfn,
                                unsigned long nr_mfns,
@@ -845,10 +845,10 @@ int xc_domain_iomem_permission(int xc_handle,
     domctl.u.iomem_permission.nr_mfns = nr_mfns;
     domctl.u.iomem_permission.allow_access = allow_access;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_send_trigger(int xc_handle,
+int xc_domain_send_trigger(xc_interface *xch,
                            uint32_t domid,
                            uint32_t trigger,
                            uint32_t vcpu)
@@ -860,10 +860,10 @@ int xc_domain_send_trigger(int xc_handle,
     domctl.u.sendtrigger.trigger = trigger;
     domctl.u.sendtrigger.vcpu = vcpu;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value)
+int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned 
long value)
 {
     DECLARE_HYPERCALL;
     xen_hvm_param_t arg;
@@ -882,7 +882,7 @@ int xc_set_hvm_param(int handle, domid_t dom, int param, 
unsigned long value)
     return rc;
 }
 
-int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value)
+int xc_get_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned 
long *value)
 {
     DECLARE_HYPERCALL;
     xen_hvm_param_t arg;
@@ -901,7 +901,7 @@ int xc_get_hvm_param(int handle, domid_t dom, int param, 
unsigned long *value)
     return rc;
 }
 
-int xc_domain_setdebugging(int xc_handle,
+int xc_domain_setdebugging(xc_interface *xch,
                            uint32_t domid,
                            unsigned int enable)
 {
@@ -910,11 +910,11 @@ int xc_domain_setdebugging(int xc_handle,
     domctl.cmd = XEN_DOMCTL_setdebugging;
     domctl.domain = domid;
     domctl.u.setdebugging.enable = enable;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_assign_device(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t machine_bdf)
 {
@@ -924,11 +924,11 @@ int xc_assign_device(
     domctl.domain = domid;
     domctl.u.assign_device.machine_bdf = machine_bdf;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_get_device_group(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t machine_bdf,
     uint32_t max_sdevs,
@@ -951,7 +951,7 @@ int xc_get_device_group(
         PERROR("Could not lock memory for xc_get_device_group\n");
         return -ENOMEM;
     }
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     unlock_pages(sdev_array, max_sdevs * sizeof(*sdev_array));
 
     *num_sdevs = domctl.u.get_device_group.num_sdevs;
@@ -959,7 +959,7 @@ int xc_get_device_group(
 }
 
 int xc_test_assign_device(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t machine_bdf)
 {
@@ -969,11 +969,11 @@ int xc_test_assign_device(
     domctl.domain = domid;
     domctl.u.assign_device.machine_bdf = machine_bdf;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_deassign_device(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t machine_bdf)
 {
@@ -983,11 +983,11 @@ int xc_deassign_device(
     domctl.domain = domid;
     domctl.u.assign_device.machine_bdf = machine_bdf;
  
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_domain_update_msi_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t gvec,
     uint32_t pirq,
@@ -1010,12 +1010,12 @@ int xc_domain_update_msi_irq(
     bind->u.msi.gflags = gflags;
     bind->u.msi.gtable = gtable;
 
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     return rc;
 }
 
 int xc_domain_unbind_msi_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t gvec,
     uint32_t pirq,
@@ -1036,13 +1036,13 @@ int xc_domain_unbind_msi_irq(
     bind->u.msi.gvec = gvec;
     bind->u.msi.gflags = gflags;
 
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     return rc;
 }
 
 /* Pass-through: binds machine irq to guests irq */
 int xc_domain_bind_pt_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq,
     uint8_t irq_type,
@@ -1072,12 +1072,12 @@ int xc_domain_bind_pt_irq(
     else if ( irq_type == PT_IRQ_TYPE_ISA )
         bind->u.isa.isa_irq = isa_irq;
     
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     return rc;
 }
 
 int xc_domain_unbind_pt_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq,
     uint8_t irq_type,
@@ -1102,12 +1102,12 @@ int xc_domain_unbind_pt_irq(
     bind->u.pci.intx = intx;
     bind->u.isa.isa_irq = isa_irq;
     
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
     return rc;
 }
 
 int xc_domain_bind_pt_pci_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq,
     uint8_t bus,
@@ -1115,22 +1115,22 @@ int xc_domain_bind_pt_pci_irq(
     uint8_t intx)
 {
 
-    return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
+    return (xc_domain_bind_pt_irq(xch, domid, machine_irq,
                                   PT_IRQ_TYPE_PCI, bus, device, intx, 0));
 }
 
 int xc_domain_bind_pt_isa_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint8_t machine_irq)
 {
 
-    return (xc_domain_bind_pt_irq(xc_handle, domid, machine_irq,
+    return (xc_domain_bind_pt_irq(xch, domid, machine_irq,
                                   PT_IRQ_TYPE_ISA, 0, 0, 0, machine_irq));
 }
 
 int xc_domain_memory_mapping(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     unsigned long first_gfn,
     unsigned long first_mfn,
@@ -1146,11 +1146,11 @@ int xc_domain_memory_mapping(
     domctl.u.memory_mapping.nr_mfns = nr_mfns;
     domctl.u.memory_mapping.add_mapping = add_mapping;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_domain_ioport_mapping(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t first_gport,
     uint32_t first_mport,
@@ -1166,11 +1166,11 @@ int xc_domain_ioport_mapping(
     domctl.u.ioport_mapping.nr_ports = nr_ports;
     domctl.u.ioport_mapping.add_mapping = add_mapping;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_domain_set_target(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t target)
 {
@@ -1180,11 +1180,11 @@ int xc_domain_set_target(
     domctl.domain = domid;
     domctl.u.set_target.target = target;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_domain_subscribe_for_suspend(
-    int xc_handle, domid_t dom, evtchn_port_t port)
+    xc_interface *xch, domid_t dom, evtchn_port_t port)
 {
     DECLARE_DOMCTL;
 
@@ -1192,10 +1192,10 @@ int xc_domain_subscribe_for_suspend(
     domctl.domain = dom;
     domctl.u.subscribe.port = port;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_domain_set_machine_address_size(int xc,
+int xc_domain_set_machine_address_size(xc_interface *xch,
                                        uint32_t domid,
                                        unsigned int width)
 {
@@ -1206,11 +1206,11 @@ int xc_domain_set_machine_address_size(int xc,
     domctl.cmd    = XEN_DOMCTL_set_machine_address_size;
     domctl.u.address_size.size = width;
 
-    return do_domctl(xc, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 
-int xc_domain_get_machine_address_size(int xc, uint32_t domid)
+int xc_domain_get_machine_address_size(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     int rc;
@@ -1219,12 +1219,12 @@ int xc_domain_get_machine_address_size(int xc, uint32_t 
domid)
     domctl.domain = domid;
     domctl.cmd    = XEN_DOMCTL_get_machine_address_size;
 
-    rc = do_domctl(xc, &domctl);
+    rc = do_domctl(xch, &domctl);
 
     return rc == 0 ? domctl.u.address_size.size : rc;
 }
 
-int xc_domain_suppress_spurious_page_faults(int xc, uint32_t domid)
+int xc_domain_suppress_spurious_page_faults(xc_interface *xc, uint32_t domid)
 {
     DECLARE_DOMCTL;
 
@@ -1236,7 +1236,7 @@ int xc_domain_suppress_spurious_page_faults(int xc, 
uint32_t domid)
 
 }
 
-int xc_domain_debug_control(int xc, uint32_t domid, uint32_t sop, uint32_t 
vcpu)
+int xc_domain_debug_control(xc_interface *xc, uint32_t domid, uint32_t sop, 
uint32_t vcpu)
 {
     DECLARE_DOMCTL;
 
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 8aa58a1..34a175c 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -62,7 +62,8 @@ struct restore_ctx {
 #define SUPER_PAGE_TRACKING(pfn) ( (pfn) != INVALID_SUPER_PAGE )
 #define SUPER_PAGE_DONE(pfn)     ( SUPER_PAGE_START(pfn) )
 
-static int super_page_populated(struct restore_ctx *ctx, unsigned long pfn)
+static int super_page_populated(xc_interface *xch,
+                                struct restore_ctx *ctx, unsigned long pfn)
 {
     int i;
     pfn &= ~(SUPERPAGE_NR_PFNS - 1);
@@ -78,7 +79,7 @@ static int super_page_populated(struct restore_ctx *ctx, 
unsigned long pfn)
  * Break a 2M page and move contents of [extent start, next_pfn-1] to
  * some new allocated 4K pages
  */
-static int break_super_page(int xc_handle,
+static int break_super_page(xc_interface *xch,
                             uint32_t dom,
                             struct restore_ctx *ctx,
                             xen_pfn_t next_pfn)
@@ -118,7 +119,7 @@ static int break_super_page(int xc_handle,
         page_array[i] = start_pfn + i;
     }
 
-    ram_base = xc_map_foreign_pages(xc_handle, dom, PROT_READ,
+    ram_base = xc_map_foreign_pages(xch, dom, PROT_READ,
                                     page_array, tot_pfns);
 
     if ( ram_base == NULL )
@@ -132,7 +133,7 @@ static int break_super_page(int xc_handle,
     munmap(ram_base, tot_pfns * PAGE_SIZE);
 
     /* free the super page */
-    if ( xc_domain_memory_decrease_reservation(xc_handle, dom, 1,
+    if ( xc_domain_memory_decrease_reservation(xch, dom, 1,
                                    SUPERPAGE_PFN_SHIFT, &start_pfn) != 0 )
     {
         ERROR("free 2M page failure @ 0x%ld.\n", next_pfn);
@@ -149,7 +150,7 @@ static int break_super_page(int xc_handle,
     for ( i = start_pfn; i < start_pfn + tot_pfns; i++ )
     {
         mfn = i;
-        if (xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0,
+        if (xc_domain_memory_populate_physmap(xch, dom, 1, 0,
                                               0, &mfn) != 0)
         {
             ERROR("Failed to allocate physical memory.!\n");
@@ -166,7 +167,7 @@ static int break_super_page(int xc_handle,
         page_array[i] = start_pfn + i;
     }
 
-    ram_base = xc_map_foreign_pages(xc_handle, dom, PROT_WRITE,
+    ram_base = xc_map_foreign_pages(xch, dom, PROT_WRITE,
                                     page_array, tot_pfns);
     if ( ram_base == NULL )
     {
@@ -192,7 +193,7 @@ out:
  * If new pages fit the missing one in the 2M extent, do nothing; Else take
  * place of the original 2M page by some 4K pages.
  */
-static int allocate_mfn_list(int xc_handle,
+static int allocate_mfn_list(xc_interface *xch,
                               uint32_t dom,
                               struct restore_ctx *ctx,
                               unsigned long nr_extents,
@@ -221,7 +222,7 @@ static int allocate_mfn_list(int xc_handle,
              !SUPER_PAGE_DONE(sp_pfn))
         {
             /* break previously allocated super page*/
-            if ( break_super_page(xc_handle, dom, ctx, sp_pfn) != 0 )
+            if ( break_super_page(xch, dom, ctx, sp_pfn) != 0 )
             {
                 ERROR("Break previous super page fail!\n");
                 return 1;
@@ -244,13 +245,13 @@ static int allocate_mfn_list(int xc_handle,
         goto normal_page;
 
     pfn = batch_buf[0] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
-    if  ( super_page_populated(ctx, pfn) )
+    if  ( super_page_populated(xch, ctx, pfn) )
         goto normal_page;
 
     pfn &= ~(SUPERPAGE_NR_PFNS - 1);
     mfn =  pfn;
 
-    if ( xc_domain_memory_populate_physmap(xc_handle, dom, 1,
+    if ( xc_domain_memory_populate_physmap(xch, dom, 1,
                 SUPERPAGE_PFN_SHIFT, 0, &mfn) == 0)
     {
         for ( i = pfn; i < pfn + SUPERPAGE_NR_PFNS; i++, mfn++ )
@@ -279,7 +280,7 @@ normal_page:
         pfn = mfn = batch_buf[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK;
         if ( ctx->p2m[pfn] == INVALID_P2M_ENTRY )
         {
-            if (xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0,
+            if (xc_domain_memory_populate_physmap(xch, dom, 1, 0,
                         0, &mfn) != 0)
             {
                 ERROR("Failed to allocate physical memory.! pfn=0x%lx, 
mfn=0x%lx.\n",
@@ -294,7 +295,7 @@ normal_page:
     return 0;
 }
 
-static int allocate_physmem(int xc_handle, uint32_t dom,
+static int allocate_physmem(xc_interface *xch, uint32_t dom,
                             struct restore_ctx *ctx,
                             unsigned long *region_pfn_type, int region_size,
                             unsigned int hvm, xen_pfn_t *region_mfn, int 
superpages)
@@ -337,7 +338,7 @@ static int allocate_physmem(int xc_handle, uint32_t dom,
         if ( SUPER_PAGE_START(pfn) )
         {
             /* Start of a 2M extent, populate previsous buf */
-            if ( allocate_mfn_list(xc_handle, dom, ctx,
+            if ( allocate_mfn_list(xch, dom, ctx,
                                    batch_buf_len, batch_buf,
                                    &required_pfn, superpages) != 0 )
             {
@@ -359,7 +360,7 @@ static int allocate_physmem(int xc_handle, uint32_t dom,
         else if ( SUPER_PAGE_TRACKING(required_pfn) )
         {
             /* break of a 2M extent, populate previous buf */
-            if ( allocate_mfn_list(xc_handle, dom, ctx,
+            if ( allocate_mfn_list(xch, dom, ctx,
                                    batch_buf_len, batch_buf,
                                    &required_pfn, superpages) != 0 )
             {
@@ -400,7 +401,7 @@ static int allocate_physmem(int xc_handle, uint32_t dom,
 alloc_page:
     if ( batch_buf )
     {
-        if ( allocate_mfn_list(xc_handle, dom, ctx,
+        if ( allocate_mfn_list(xch, dom, ctx,
                     batch_buf_len, batch_buf,
                     &required_pfn,
                     superpages) != 0 )
@@ -493,7 +494,7 @@ static ssize_t read_exact_timed(int fd, void* buf, size_t 
size)
 ** This function inverts that operation, replacing the pfn values with
 ** the (now known) appropriate mfn values.
 */
-static int uncanonicalize_pagetable(int xc_handle, uint32_t dom, struct 
restore_ctx *ctx,
+static int uncanonicalize_pagetable(xc_interface *xch, uint32_t dom, struct 
restore_ctx *ctx,
                                     void *page, int superpages)
 {
     int i, pte_last;
@@ -520,7 +521,7 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t 
dom, struct restore_
         if ( ctx->p2m[pfn] == INVALID_P2M_ENTRY )
         {
             unsigned long force_pfn = superpages ? FORCE_SP_MASK : pfn;
-            if (allocate_mfn_list(xc_handle, dom, ctx,
+            if (allocate_mfn_list(xch, dom, ctx,
                         1, &pfn, &force_pfn, superpages) != 0)
                 return 0;
         }
@@ -538,7 +539,8 @@ static int uncanonicalize_pagetable(int xc_handle, uint32_t 
dom, struct restore_
 
 
 /* Load the p2m frame list, plus potential extended info chunk */
-static xen_pfn_t *load_p2m_frame_list(struct restore_ctx *ctx,
+static xen_pfn_t *load_p2m_frame_list(
+    xc_interface *xch, struct restore_ctx *ctx,
     int io_fd, int *pae_extended_cr3, int *ext_vcpucontext)
 {
     xen_pfn_t *p2m_frame_list;
@@ -685,7 +687,8 @@ typedef struct {
 } tailbuf_t;
 
 /* read stream until EOF, growing buffer as necssary */
-static int compat_buffer_qemu(int fd, struct tailbuf_hvm *buf)
+static int compat_buffer_qemu(xc_interface *xch,
+                              int fd, struct tailbuf_hvm *buf)
 {
     uint8_t *qbuf, *tmp;
     int blen = 0, dlen = 0;
@@ -733,7 +736,8 @@ static int compat_buffer_qemu(int fd, struct tailbuf_hvm 
*buf)
     return 0;
 }
 
-static int buffer_qemu(int fd, struct tailbuf_hvm *buf)
+static int buffer_qemu(xc_interface *xch,
+                       int fd, struct tailbuf_hvm *buf)
 {
     uint32_t qlen;
     uint8_t *tmp;
@@ -770,7 +774,7 @@ static int buffer_qemu(int fd, struct tailbuf_hvm *buf)
     return 0;
 }
 
-static int dump_qemu(uint32_t dom, struct tailbuf_hvm *buf)
+static int dump_qemu(xc_interface *xch, uint32_t dom, struct tailbuf_hvm *buf)
 {
     int saved_errno;
     char path[256];
@@ -794,7 +798,8 @@ static int dump_qemu(uint32_t dom, struct tailbuf_hvm *buf)
     return 0;
 }
 
-static int buffer_tail_hvm(struct restore_ctx *ctx, struct tailbuf_hvm *buf, 
int fd,
+static int buffer_tail_hvm(xc_interface *xch, struct restore_ctx *ctx,
+                           struct tailbuf_hvm *buf, int fd,
                            unsigned int max_vcpu_id, uint64_t vcpumap,
                            int ext_vcpucontext)
 {
@@ -846,16 +851,17 @@ static int buffer_tail_hvm(struct restore_ctx *ctx, 
struct tailbuf_hvm *buf, int
      * until EOF. Remus gets around this by sending a different signature
      * which includes a length prefix */
     if ( !memcmp(qemusig, "QemuDeviceModelRecord", sizeof(qemusig)) )
-        return compat_buffer_qemu(fd, buf);
+        return compat_buffer_qemu(xch, fd, buf);
     else if ( !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) )
-        return buffer_qemu(fd, buf);
+        return buffer_qemu(xch, fd, buf);
 
     qemusig[20] = '\0';
     ERROR("Invalid QEMU signature: %s", qemusig);
     return -1;
 }
 
-static int buffer_tail_pv(struct restore_ctx *ctx, struct tailbuf_pv *buf, int 
fd,
+static int buffer_tail_pv(xc_interface *xch, struct restore_ctx *ctx,
+                          struct tailbuf_pv *buf, int fd,
                           unsigned int max_vcpu_id, uint64_t vcpumap,
                           int ext_vcpucontext)
 {
@@ -933,14 +939,15 @@ static int buffer_tail_pv(struct restore_ctx *ctx, struct 
tailbuf_pv *buf, int f
     return -1;
 }
 
-static int buffer_tail(struct restore_ctx *ctx, tailbuf_t *buf, int fd, 
unsigned int max_vcpu_id,
+static int buffer_tail(xc_interface *xch, struct restore_ctx *ctx,
+                       tailbuf_t *buf, int fd, unsigned int max_vcpu_id,
                        uint64_t vcpumap, int ext_vcpucontext)
 {
     if ( buf->ishvm )
-        return buffer_tail_hvm(ctx, &buf->u.hvm, fd, max_vcpu_id, vcpumap,
+        return buffer_tail_hvm(xch, ctx, &buf->u.hvm, fd, max_vcpu_id, vcpumap,
                                ext_vcpucontext);
     else
-        return buffer_tail_pv(ctx, &buf->u.pv, fd, max_vcpu_id, vcpumap,
+        return buffer_tail_pv(xch, ctx, &buf->u.pv, fd, max_vcpu_id, vcpumap,
                               ext_vcpucontext);
 }
 
@@ -1011,7 +1018,8 @@ static void pagebuf_free(pagebuf_t* buf)
     }
 }
 
-static int pagebuf_get_one(pagebuf_t* buf, int fd, int xch, uint32_t dom)
+static int pagebuf_get_one(xc_interface *xch,
+                           pagebuf_t* buf, int fd, uint32_t dom)
 {
     int count, countpages, oldcount, i;
     void* ptmp;
@@ -1030,7 +1038,7 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
     } else if (count == -1) {
         DPRINTF("Entering page verify mode\n");
         buf->verify = 1;
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if (count == -2) {
         buf->new_ctxt_format = 1;
         if ( read_exact(fd, &buf->max_vcpu_id, sizeof(buf->max_vcpu_id)) ||
@@ -1040,7 +1048,7 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
             return -1;
         }
         // DPRINTF("Max VCPU ID: %d, vcpumap: %llx\n", buf->max_vcpu_id, 
buf->vcpumap);
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if (count == -3) {
         /* Skip padding 4 bytes then read the EPT identity PT location. */
         if ( read_exact(fd, &buf->identpt, sizeof(uint32_t)) ||
@@ -1050,7 +1058,7 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
             return -1;
         }
         // DPRINTF("EPT identity map address: %llx\n", buf->identpt);
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if ( count == -4 )  {
         /* Skip padding 4 bytes then read the vm86 TSS location. */
         if ( read_exact(fd, &buf->vm86_tss, sizeof(uint32_t)) ||
@@ -1060,21 +1068,21 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
             return -1;
         }
         // DPRINTF("VM86 TSS location: %llx\n", buf->vm86_tss);
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if ( count == -5 ) {
         DPRINTF("xc_domain_restore start tmem\n");
         if ( xc_tmem_restore(xch, dom, fd) ) {
             ERROR("error reading/restoring tmem");
             return -1;
         }
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     }
     else if ( count == -6 ) {
         if ( xc_tmem_restore_extra(xch, dom, fd) ) {
             ERROR("error reading/restoring tmem extra");
             return -1;
         }
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if ( count == -7 ) {
         uint32_t tsc_mode, khz, incarn;
         uint64_t nsec;
@@ -1086,7 +1094,7 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
             ERROR("error reading/restoring tsc info");
             return -1;
         }
-        return pagebuf_get_one(buf, fd, xch, dom);
+        return pagebuf_get_one(xch, buf, fd, dom);
     } else if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
         ERROR("Max batch size exceeded (%d). Giving up.", count);
         return -1;
@@ -1141,14 +1149,14 @@ static int pagebuf_get_one(pagebuf_t* buf, int fd, int 
xch, uint32_t dom)
     return count;
 }
 
-static int pagebuf_get(pagebuf_t* buf, int fd, int xch, uint32_t dom)
+static int pagebuf_get(xc_interface *xch, pagebuf_t* buf, int fd, uint32_t dom)
 {
     int rc;
 
     buf->nr_physpages = buf->nr_pages = 0;
 
     do {
-        rc = pagebuf_get_one(buf, fd, xch, dom);
+        rc = pagebuf_get_one(xch, buf, fd, dom);
     } while (rc > 0);
 
     if (rc < 0)
@@ -1157,7 +1165,7 @@ static int pagebuf_get(pagebuf_t* buf, int fd, int xch, 
uint32_t dom)
     return rc;
 }
 
-static int apply_batch(int xc_handle, uint32_t dom, struct restore_ctx *ctx,
+static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx 
*ctx,
                        xen_pfn_t* region_mfn, unsigned long* pfn_type, int 
pae_extended_cr3,
                        unsigned int hvm, struct xc_mmu* mmu,
                        pagebuf_t* pagebuf, int curbatch, int superpages)
@@ -1180,7 +1188,7 @@ static int apply_batch(int xc_handle, uint32_t dom, 
struct restore_ctx *ctx,
     if (j > MAX_BATCH_SIZE)
         j = MAX_BATCH_SIZE;
 
-    if (allocate_physmem(xc_handle, dom, ctx, &pagebuf->pfn_types[curbatch],
+    if (allocate_physmem(xch, dom, ctx, &pagebuf->pfn_types[curbatch],
                          j, hvm, region_mfn, superpages) != 0)
     {
         ERROR("allocate_physmem() failed\n");
@@ -1190,7 +1198,7 @@ static int apply_batch(int xc_handle, uint32_t dom, 
struct restore_ctx *ctx,
     /* Map relevant mfns */
     pfn_err = calloc(j, sizeof(*pfn_err));
     region_base = xc_map_foreign_bulk(
-        xc_handle, dom, PROT_WRITE, region_mfn, pfn_err, j);
+        xch, dom, PROT_WRITE, region_mfn, pfn_err, j);
 
     if ( region_base == NULL )
     {
@@ -1249,7 +1257,7 @@ static int apply_batch(int xc_handle, uint32_t dom, 
struct restore_ctx *ctx,
                 pae_extended_cr3 ||
                 (pagetype != XEN_DOMCTL_PFINFO_L1TAB)) {
 
-                if (!uncanonicalize_pagetable(xc_handle, dom, ctx,
+                if (!uncanonicalize_pagetable(xch, dom, ctx,
                                               page, superpages)) {
                     /*
                     ** Failing to uncanonicalize a page table can be ok
@@ -1293,7 +1301,7 @@ static int apply_batch(int xc_handle, uint32_t dom, 
struct restore_ctx *ctx,
         }
 
         if ( !hvm &&
-             xc_add_mmu_update(xc_handle, mmu,
+             xc_add_mmu_update(xch, mmu,
                                (((unsigned long long)mfn) << PAGE_SHIFT)
                                | MMU_MACHPHYS_UPDATE, pfn) )
         {
@@ -1311,7 +1319,7 @@ static int apply_batch(int xc_handle, uint32_t dom, 
struct restore_ctx *ctx,
     return rc;
 }
 
-int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
+int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
                       unsigned int hvm, unsigned int pae, int superpages)
@@ -1319,7 +1327,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     DECLARE_DOMCTL;
     int rc = 1, frc, i, j, n, m, pae_extended_cr3 = 0, ext_vcpucontext = 0;
     unsigned long mfn, pfn;
-    unsigned int prev_pc, this_pc;
+    unsigned int prev_pc;
     int nraces = 0;
 
     /* The new domain's shared-info frame number. */
@@ -1386,7 +1394,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     }
     DPRINTF("xc_domain_restore start: p2m_size = %lx\n", dinfo->p2m_size);
 
-    if ( !get_platform_info(xc_handle, dom,
+    if ( !get_platform_info(xch, dom,
                             &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, 
&dinfo->guest_width) )
     {
         ERROR("Unable to get platform info.");
@@ -1402,7 +1410,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     if ( !hvm ) 
     {
         /* Load the p2m frame list, plus potential extended info chunk */
-        p2m_frame_list = load_p2m_frame_list(ctx,
+        p2m_frame_list = load_p2m_frame_list(xch, ctx,
             io_fd, &pae_extended_cr3, &ext_vcpucontext);
         if ( !p2m_frame_list )
             goto out;
@@ -1412,7 +1420,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         domctl.domain = dom;
         domctl.cmd    = XEN_DOMCTL_set_address_size;
         domctl.u.address_size.size = dinfo->guest_width * 8;
-        frc = do_domctl(xc_handle, &domctl);
+        frc = do_domctl(xch, &domctl);
         if ( frc != 0 )
         {
             ERROR("Unable to set guest address size.");
@@ -1447,7 +1455,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     /* Get the domain's shared-info frame. */
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
     domctl.domain = (domid_t)dom;
-    if ( xc_domctl(xc_handle, &domctl) < 0 )
+    if ( xc_domctl(xch, &domctl) < 0 )
     {
         ERROR("Could not get information on new domain");
         goto out;
@@ -1458,14 +1466,14 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
     for ( pfn = 0; pfn < dinfo->p2m_size; pfn++ )
         ctx->p2m[pfn] = INVALID_P2M_ENTRY;
 
-    mmu = xc_alloc_mmu_updates(xc_handle, dom);
+    mmu = xc_alloc_mmu_updates(xch, dom);
     if ( mmu == NULL )
     {
         ERROR("Could not initialise for MMU updates");
         goto out;
     }
 
-    DPRINTF("Reloading memory pages:   0%%\n");
+    xc_report_progress_start(xch, "Reloading memory pages", dinfo->p2m_size);
 
     /*
      * Now simply read each saved frame into its new machine frame.
@@ -1479,23 +1487,18 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
     {
         int j, curbatch;
 
-        this_pc = (n * 100) / dinfo->p2m_size;
-        if ( (this_pc - prev_pc) >= 5 )
-        {
-            PPRINTF("\b\b\b\b%3d%%", this_pc);
-            prev_pc = this_pc;
-        }
+        xc_report_progress_step(xch, n, dinfo->p2m_size);
 
         if ( !completed ) {
             pagebuf.nr_physpages = pagebuf.nr_pages = 0;
-            if ( pagebuf_get_one(&pagebuf, io_fd, xc_handle, dom) < 0 ) {
+            if ( pagebuf_get_one(xch, &pagebuf, io_fd, dom) < 0 ) {
                 ERROR("Error when reading batch\n");
                 goto out;
             }
         }
         j = pagebuf.nr_pages;
 
-        PPRINTF("batch %d\n",j);
+        DPRINTF("batch %d\n",j);
 
         if ( j == 0 ) {
             /* catch vcpu updates */
@@ -1505,9 +1508,9 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
             }
             /* should this be deferred? does it change? */
             if ( pagebuf.identpt )
-                xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT, 
pagebuf.identpt);
+                xc_set_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, 
pagebuf.identpt);
             if ( pagebuf.vm86_tss )
-                xc_set_hvm_param(xc_handle, dom, HVM_PARAM_VM86_TSS, 
pagebuf.vm86_tss);
+                xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, 
pagebuf.vm86_tss);
             break;  /* our work here is done */
         }
 
@@ -1516,7 +1519,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         while ( curbatch < j ) {
             int brc;
 
-            brc = apply_batch(xc_handle, dom, ctx, region_mfn, pfn_type,
+            brc = apply_batch(xch, dom, ctx, region_mfn, pfn_type,
                               pae_extended_cr3, hvm, mmu, &pagebuf, curbatch, 
superpages);
             if ( brc < 0 )
                 goto out;
@@ -1537,7 +1540,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         m += j;
         if ( m > MAX_PAGECACHE_USAGE )
         {
-            discard_file_cache(io_fd, 0 /* no flush */);
+            discard_file_cache(xch, io_fd, 0 /* no flush */);
             m = 0;
         }
     }
@@ -1546,7 +1549,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
      * Ensure we flush all machphys updates before potential PAE-specific
      * reallocations below.
      */
-    if ( !hvm && xc_flush_mmu_updates(xc_handle, mmu) )
+    if ( !hvm && xc_flush_mmu_updates(xch, mmu) )
     {
         ERROR("Error doing flush_mmu_updates()");
         goto out;
@@ -1557,7 +1560,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     if ( !completed ) {
         int flags = 0;
 
-        if ( buffer_tail(ctx, &tailbuf, io_fd, max_vcpu_id, vcpumap,
+        if ( buffer_tail(xch, ctx, &tailbuf, io_fd, max_vcpu_id, vcpumap,
                          ext_vcpucontext) < 0 ) {
             ERROR ("error buffering image tail");
             goto out;
@@ -1571,13 +1574,13 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
 
     // DPRINTF("Buffered checkpoint\n");
 
-    if ( pagebuf_get(&pagebuf, io_fd, xc_handle, dom) ) {
+    if ( pagebuf_get(xch, &pagebuf, io_fd, dom) ) {
         ERROR("error when buffering batch, finishing\n");
         goto finish;
     }
     memset(&tmptail, 0, sizeof(tmptail));
     tmptail.ishvm = hvm;
-    if ( buffer_tail(ctx, &tmptail, io_fd, max_vcpu_id, vcpumap,
+    if ( buffer_tail(xch, ctx, &tmptail, io_fd, max_vcpu_id, vcpumap,
                      ext_vcpucontext) < 0 ) {
         ERROR ("error buffering image tail, finishing");
         goto finish;
@@ -1619,7 +1622,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
                 uint64_t *l3tab;
 
                 l3tab = (uint64_t *)
-                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                    xc_map_foreign_range(xch, dom, PAGE_SIZE,
                                          PROT_READ, ctx->p2m[i]);
 
                 for ( j = 0; j < 4; j++ )
@@ -1627,7 +1630,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
 
                 munmap(l3tab, PAGE_SIZE);
 
-                new_mfn = xc_make_page_below_4G(xc_handle, dom, ctx->p2m[i]);
+                new_mfn = xc_make_page_below_4G(xch, dom, ctx->p2m[i]);
                 if ( !new_mfn )
                 {
                     ERROR("Couldn't get a page below 4GB :-(");
@@ -1635,7 +1638,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
                 }
 
                 ctx->p2m[i] = new_mfn;
-                if ( xc_add_mmu_update(xc_handle, mmu,
+                if ( xc_add_mmu_update(xch, mmu,
                                        (((unsigned long long)new_mfn)
                                         << PAGE_SHIFT) |
                                        MMU_MACHPHYS_UPDATE, i) )
@@ -1645,7 +1648,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
                 }
 
                 l3tab = (uint64_t *)
-                    xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+                    xc_map_foreign_range(xch, dom, PAGE_SIZE,
                                          PROT_READ | PROT_WRITE, ctx->p2m[i]);
 
                 for ( j = 0; j < 4; j++ )
@@ -1670,7 +1673,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
             if ( (i == (dinfo->p2m_size-1)) || (j == MAX_BATCH_SIZE) )
             {
                 region_base = xc_map_foreign_pages(
-                    xc_handle, dom, PROT_READ | PROT_WRITE, region_mfn, j);
+                    xch, dom, PROT_READ | PROT_WRITE, region_mfn, j);
                 if ( region_base == NULL )
                 {
                     ERROR("map batch failed");
@@ -1680,7 +1683,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
                 for ( k = 0; k < j; k++ )
                 {
                     if ( !uncanonicalize_pagetable(
-                        xc_handle, dom, ctx,
+                        xch, dom, ctx,
                         region_base + k*PAGE_SIZE, superpages) )
                     {
                         ERROR("failed uncanonicalize pt!");
@@ -1693,7 +1696,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
             }
         }
 
-        if ( xc_flush_mmu_updates(xc_handle, mmu) )
+        if ( xc_flush_mmu_updates(xch, mmu) )
         {
             ERROR("Error doing xc_flush_mmu_updates()");
             goto out;
@@ -1738,7 +1741,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         /* Batch full? Then flush. */
         if ( nr_pins == MAX_PIN_BATCH )
         {
-            if ( xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0 )
+            if ( xc_mmuext_op(xch, pin, nr_pins, dom) < 0 )
             {
                 ERROR("Failed to pin batch of %d page tables", nr_pins);
                 goto out;
@@ -1748,13 +1751,12 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
     }
 
     /* Flush final partial batch. */
-    if ( (nr_pins != 0) && (xc_mmuext_op(xc_handle, pin, nr_pins, dom) < 0) )
+    if ( (nr_pins != 0) && (xc_mmuext_op(xch, pin, nr_pins, dom) < 0) )
     {
         ERROR("Failed to pin batch of %d page tables", nr_pins);
         goto out;
     }
 
-    DPRINTF("\b\b\b\b100%%\n");
     DPRINTF("Memory reloaded (%ld pages)\n", ctx->nr_pfns);
 
     /* Get the list of PFNs that are not in the psuedo-phys map */
@@ -1783,7 +1785,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
             };
             set_xen_guest_handle(reservation.extent_start, 
tailbuf.u.pv.pfntab);
 
-            if ( (frc = xc_memory_op(xc_handle, XENMEM_decrease_reservation,
+            if ( (frc = xc_memory_op(xch, XENMEM_decrease_reservation,
                                      &reservation)) != nr_frees )
             {
                 ERROR("Could not decrease reservation : %d", frc);
@@ -1831,7 +1833,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
             mfn = ctx->p2m[pfn];
             SET_FIELD(&ctxt, user_regs.edx, mfn);
             start_info = xc_map_foreign_range(
-                xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
+                xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn);
             SET_FIELD(start_info, nr_pages, dinfo->p2m_size);
             SET_FIELD(start_info, shared_info, shared_info_frame<<PAGE_SHIFT);
             SET_FIELD(start_info, flags, 0);
@@ -1906,7 +1908,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         domctl.domain = (domid_t)dom;
         domctl.u.vcpucontext.vcpu = i;
         set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt.c);
-        frc = xc_domctl(xc_handle, &domctl);
+        frc = xc_domctl(xch, &domctl);
         if ( frc != 0 )
         {
             ERROR("Couldn't build vcpu%d", i);
@@ -1919,7 +1921,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
         vcpup += 128;
         domctl.cmd = XEN_DOMCTL_set_ext_vcpucontext;
         domctl.domain = dom;
-        frc = xc_domctl(xc_handle, &domctl);
+        frc = xc_domctl(xch, &domctl);
         if ( frc != 0 )
         {
             ERROR("Couldn't set extended vcpu%d info\n", i);
@@ -1933,7 +1935,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
 
     /* Restore contents of shared-info page. No checking needed. */
     new_shared_info = xc_map_foreign_range(
-        xc_handle, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
+        xch, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
 
     /* restore saved vcpu_info and arch specific info */
     MEMCPY_FIELD(new_shared_info, old_shared_info, vcpu_info);
@@ -1963,7 +1965,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     }
 
     /* Copy the P2M we've constructed to the 'live' P2M */
-    if ( !(ctx->live_p2m = xc_map_foreign_pages(xc_handle, dom, PROT_WRITE,
+    if ( !(ctx->live_p2m = xc_map_foreign_pages(xch, dom, PROT_WRITE,
                                            p2m_frame_list, P2M_FL_ENTRIES)) )
     {
         ERROR("Couldn't map p2m table");
@@ -1988,29 +1990,29 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
 
   finish_hvm:
     /* Dump the QEMU state to a state file for QEMU to load */
-    if ( dump_qemu(dom, &tailbuf.u.hvm) ) {
+    if ( dump_qemu(xch, dom, &tailbuf.u.hvm) ) {
         ERROR("Error dumping QEMU state to file");
         goto out;
     }
 
     /* These comms pages need to be zeroed at the start of day */
-    if ( xc_clear_domain_page(xc_handle, dom, tailbuf.u.hvm.magicpfns[0]) ||
-         xc_clear_domain_page(xc_handle, dom, tailbuf.u.hvm.magicpfns[1]) ||
-         xc_clear_domain_page(xc_handle, dom, tailbuf.u.hvm.magicpfns[2]) )
+    if ( xc_clear_domain_page(xch, dom, tailbuf.u.hvm.magicpfns[0]) ||
+         xc_clear_domain_page(xch, dom, tailbuf.u.hvm.magicpfns[1]) ||
+         xc_clear_domain_page(xch, dom, tailbuf.u.hvm.magicpfns[2]) )
     {
         ERROR("error zeroing magic pages");
         goto out;
     }
 
-    if ( (frc = xc_set_hvm_param(xc_handle, dom,
+    if ( (frc = xc_set_hvm_param(xch, dom,
                                  HVM_PARAM_IOREQ_PFN, 
tailbuf.u.hvm.magicpfns[0]))
-         || (frc = xc_set_hvm_param(xc_handle, dom,
+         || (frc = xc_set_hvm_param(xch, dom,
                                     HVM_PARAM_BUFIOREQ_PFN, 
tailbuf.u.hvm.magicpfns[1]))
-         || (frc = xc_set_hvm_param(xc_handle, dom,
+         || (frc = xc_set_hvm_param(xch, dom,
                                     HVM_PARAM_STORE_PFN, 
tailbuf.u.hvm.magicpfns[2]))
-         || (frc = xc_set_hvm_param(xc_handle, dom,
+         || (frc = xc_set_hvm_param(xch, dom,
                                     HVM_PARAM_PAE_ENABLED, pae))
-         || (frc = xc_set_hvm_param(xc_handle, dom,
+         || (frc = xc_set_hvm_param(xch, dom,
                                     HVM_PARAM_STORE_EVTCHN,
                                     store_evtchn)) )
     {
@@ -2019,7 +2021,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t 
dom,
     }
     *store_mfn = tailbuf.u.hvm.magicpfns[2];
 
-    frc = xc_domain_hvm_setcontext(xc_handle, dom, tailbuf.u.hvm.hvmbuf,
+    frc = xc_domain_hvm_setcontext(xch, dom, tailbuf.u.hvm.hvmbuf,
                                    tailbuf.u.hvm.reclen);
     if ( frc )
     {
@@ -2032,14 +2034,14 @@ int xc_domain_restore(int xc_handle, int io_fd, 
uint32_t dom,
 
  out:
     if ( (rc != 0) && (dom != 0) )
-        xc_domain_destroy(xc_handle, dom);
+        xc_domain_destroy(xch, dom);
     free(mmu);
     free(ctx->p2m);
     free(pfn_type);
     tailbuf_free(&tailbuf);
 
     /* discard cache for save file  */
-    discard_file_cache(io_fd, 1 /*flush*/);
+    discard_file_cache(xch, io_fd, 1 /*flush*/);
 
     DPRINTF("Restore exit with rc=%d\n", rc);
     
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 876ca6d..425c6b3 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -137,7 +137,8 @@ static uint64_t tv_delta(struct timeval *new, struct 
timeval *old)
             (new->tv_usec - old->tv_usec));
 }
 
-static int noncached_write(int fd, int live, void *buffer, int len) 
+static int noncached_write(xc_interface *xch,
+                           int fd, int live, void *buffer, int len) 
 {
     static int write_count = 0;
     int rc = (write_exact(fd, buffer, len) == 0) ? len : -1;
@@ -146,14 +147,14 @@ static int noncached_write(int fd, int live, void 
*buffer, int len)
     if ( write_count >= (MAX_PAGECACHE_USAGE * PAGE_SIZE) )
     {
         /* Time to discard cache - dont care if this fails */
-        discard_file_cache(fd, 0 /* no flush */);
+        discard_file_cache(xch, fd, 0 /* no flush */);
         write_count = 0;
     }
 
     return rc;
 }
 
-static int outbuf_init(struct outbuf* ob, size_t size)
+static int outbuf_init(xc_interface *xch, struct outbuf* ob, size_t size)
 {
     memset(ob, 0, sizeof(*ob));
 
@@ -167,7 +168,8 @@ static int outbuf_init(struct outbuf* ob, size_t size)
     return 0;
 }
 
-static inline int outbuf_write(struct outbuf* ob, void* buf, size_t len)
+static inline int outbuf_write(xc_interface *xch,
+                               struct outbuf* ob, void* buf, size_t len)
 {
     if ( len > ob->size - ob->pos ) {
         DPRINTF("outbuf_write: %zu > %zu@%zu\n", len, ob->size - ob->pos, 
ob->pos);
@@ -181,7 +183,7 @@ static inline int outbuf_write(struct outbuf* ob, void* 
buf, size_t len)
 }
 
 /* prep for nonblocking I/O */
-static int outbuf_flush(struct outbuf* ob, int fd)
+static int outbuf_flush(xc_interface *xch, struct outbuf* ob, int fd)
 {
     int rc;
     int cur = 0;
@@ -207,27 +209,29 @@ static int outbuf_flush(struct outbuf* ob, int fd)
 }
 
 /* if there's no room in the buffer, flush it and try again. */
-static inline int outbuf_hardwrite(struct outbuf* ob, int fd, void* buf,
+static inline int outbuf_hardwrite(xc_interface *xch,
+                                   struct outbuf* ob, int fd, void* buf,
                                    size_t len)
 {
     if ( !len )
         return 0;
 
-    if ( !outbuf_write(ob, buf, len) )
+    if ( !outbuf_write(xch, ob, buf, len) )
         return 0;
 
-    if ( outbuf_flush(ob, fd) < 0 )
+    if ( outbuf_flush(xch, ob, fd) < 0 )
         return -1;
 
-    return outbuf_write(ob, buf, len);
+    return outbuf_write(xch, ob, buf, len);
 }
 
 /* start buffering output once we've reached checkpoint mode. */
-static inline int write_buffer(int dobuf, struct outbuf* ob, int fd, void* buf,
+static inline int write_buffer(xc_interface *xch,
+                               int dobuf, struct outbuf* ob, int fd, void* buf,
                                size_t len)
 {
     if ( dobuf )
-        return outbuf_hardwrite(ob, fd, buf, len);
+        return outbuf_hardwrite(xch, ob, fd, buf, len);
     else
         return write_exact(fd, buf, len);
 }
@@ -259,7 +263,7 @@ static inline void initialize_mbit_rate()
     mbit_rate = START_MBIT_RATE;
 }
 
-static int ratewrite(int io_fd, int live, void *buf, int n)
+static int ratewrite(xc_interface *xch, int io_fd, int live, void *buf, int n)
 {
     static int budget = 0;
     static int burst_time_us = -1;
@@ -319,22 +323,23 @@ static int ratewrite(int io_fd, int live, void *buf, int 
n)
 #else /* ! ADAPTIVE SAVE */
 
 #define RATE_IS_MAX() (0)
-#define ratewrite(_io_fd, _live, _buf, _n) noncached_write((_io_fd), (_live), 
(_buf), (_n))
+#define ratewrite(xch, _io_fd, _live, _buf, _n) noncached_write((xch), 
(_io_fd), (_live), (_buf), (_n))
 #define initialize_mbit_rate()
 
 #endif
 
 /* like write_buffer for ratewrite, which returns number of bytes written */
-static inline int ratewrite_buffer(int dobuf, struct outbuf* ob, int fd,
+static inline int ratewrite_buffer(xc_interface *xch,
+                                   int dobuf, struct outbuf* ob, int fd,
                                    int live, void* buf, size_t len)
 {
     if ( dobuf )
-        return outbuf_hardwrite(ob, fd, buf, len) ? -1 : len;
+        return outbuf_hardwrite(xch, ob, fd, buf, len) ? -1 : len;
     else
-        return ratewrite(fd, live, buf, len);
+        return ratewrite(xch, fd, live, buf, len);
 }
 
-static int print_stats(int xc_handle, uint32_t domid, int pages_sent,
+static int print_stats(xc_interface *xch, uint32_t domid, int pages_sent,
                        xc_shadow_op_stats_t *stats, int print)
 {
     static struct timeval wall_last;
@@ -348,8 +353,8 @@ static int print_stats(int xc_handle, uint32_t domid, int 
pages_sent,
 
     gettimeofday(&wall_now, NULL);
 
-    d0_cpu_now = xc_domain_get_cpu_usage(xc_handle, 0, /* FIXME */ 0)/1000;
-    d1_cpu_now = xc_domain_get_cpu_usage(xc_handle, domid, /* FIXME */ 0)/1000;
+    d0_cpu_now = xc_domain_get_cpu_usage(xch, 0, /* FIXME */ 0)/1000;
+    d1_cpu_now = xc_domain_get_cpu_usage(xch, domid, /* FIXME */ 0)/1000;
 
     if ( (d0_cpu_now == -1) || (d1_cpu_now == -1) )
         DPRINTF("ARRHHH!!\n");
@@ -389,7 +394,7 @@ static int print_stats(int xc_handle, uint32_t domid, int 
pages_sent,
 }
 
 
-static int analysis_phase(int xc_handle, uint32_t domid, struct save_ctx *ctx,
+static int analysis_phase(xc_interface *xch, uint32_t domid, struct save_ctx 
*ctx,
                           unsigned long *arr, int runs)
 {
     long long start, now;
@@ -403,14 +408,14 @@ static int analysis_phase(int xc_handle, uint32_t domid, 
struct save_ctx *ctx,
     {
         int i;
 
-        xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN,
+        xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_CLEAN,
                           arr, dinfo->p2m_size, NULL, 0, NULL);
         DPRINTF("#Flush\n");
         for ( i = 0; i < 40; i++ )
         {
             usleep(50000);
             now = llgettimeofday();
-            xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_PEEK,
+            xc_shadow_control(xch, domid, XEN_DOMCTL_SHADOW_OP_PEEK,
                               NULL, 0, NULL, 0, &stats);
             DPRINTF("now= %lld faults= %"PRId32" dirty= %"PRId32"\n",
                     ((now-start)+500)/1000,
@@ -422,7 +427,7 @@ static int analysis_phase(int xc_handle, uint32_t domid, 
struct save_ctx *ctx,
 }
 
 static int suspend_and_state(int (*suspend)(void*), void* data,
-                             int xc_handle, int io_fd, int dom,
+                             xc_interface *xch, int io_fd, int dom,
                              xc_dominfo_t *info)
 {
     if ( !(*suspend)(data) )
@@ -431,7 +436,7 @@ static int suspend_and_state(int (*suspend)(void*), void* 
data,
         return -1;
     }
 
-    if ( (xc_domain_getinfo(xc_handle, dom, 1, info) != 1) ||
+    if ( (xc_domain_getinfo(xch, dom, 1, info) != 1) ||
          !info->shutdown || (info->shutdown_reason != SHUTDOWN_suspend) )
     {
         ERROR("Domain not in suspended state");
@@ -446,7 +451,7 @@ static int suspend_and_state(int (*suspend)(void*), void* 
data,
 ** finished resuming from a previous restore operation, so we wait a while for
 ** it to update the MFN to a reasonable value.
 */
-static void *map_frame_list_list(int xc_handle, uint32_t dom,
+static void *map_frame_list_list(xc_interface *xch, uint32_t dom,
                                  struct save_ctx *ctx,
                                  shared_info_any_t *shinfo)
 {
@@ -467,7 +472,7 @@ static void *map_frame_list_list(int xc_handle, uint32_t 
dom,
         return NULL;
     }
 
-    p = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, fll);
+    p = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ, fll);
     if ( p == NULL )
         ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
 
@@ -597,7 +602,7 @@ static int canonicalize_pagetable(struct save_ctx *ctx,
     return race;
 }
 
-xen_pfn_t *xc_map_m2p(int xc_handle,
+xen_pfn_t *xc_map_m2p(xc_interface *xch,
                                  unsigned long max_mfn,
                                  int prot,
                                  unsigned long *mfn0)
@@ -623,7 +628,7 @@ xen_pfn_t *xc_map_m2p(int xc_handle,
     }
     set_xen_guest_handle(xmml.extent_start, extent_start);
 
-    if ( xc_memory_op(xc_handle, XENMEM_machphys_mfn_list, &xmml) ||
+    if ( xc_memory_op(xch, XENMEM_machphys_mfn_list, &xmml) ||
          (xmml.nr_extents != m2p_chunks) )
     {
         ERROR("xc_get_m2p_mfns");
@@ -640,7 +645,7 @@ xen_pfn_t *xc_map_m2p(int xc_handle,
     for ( i = 0; i < m2p_chunks; i++ )
         entries[i].mfn = extent_start[i];
 
-    m2p = xc_map_foreign_ranges(xc_handle, DOMID_XEN,
+    m2p = xc_map_foreign_ranges(xch, DOMID_XEN,
                        m2p_size, prot, M2P_CHUNK_SIZE,
                        entries, m2p_chunks);
     if (m2p == NULL)
@@ -662,7 +667,7 @@ err0:
 }
 
 
-static xen_pfn_t *map_and_save_p2m_table(int xc_handle, 
+static xen_pfn_t *map_and_save_p2m_table(xc_interface *xch, 
                                          int io_fd, 
                                          uint32_t dom,
                                          struct save_ctx *ctx,
@@ -684,7 +689,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
 
     int i, success = 0;
 
-    live_p2m_frame_list_list = map_frame_list_list(xc_handle, dom, ctx,
+    live_p2m_frame_list_list = map_frame_list_list(xch, dom, ctx,
                                                    live_shinfo);
     if ( !live_p2m_frame_list_list )
         goto out;
@@ -709,7 +714,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
             p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i];
 
     live_p2m_frame_list =
-        xc_map_foreign_pages(xc_handle, dom, PROT_READ,
+        xc_map_foreign_pages(xch, dom, PROT_READ,
                              p2m_frame_list_list,
                              P2M_FLL_ENTRIES);
     if ( !live_p2m_frame_list )
@@ -744,7 +749,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
        (its not clear why it would want to change them, and we'll be OK
        from a safety POV anyhow. */
 
-    p2m = xc_map_foreign_pages(xc_handle, dom, PROT_READ,
+    p2m = xc_map_foreign_pages(xch, dom, PROT_READ,
                                p2m_frame_list,
                                P2M_FL_ENTRIES);
     if ( !p2m )
@@ -777,7 +782,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
         p2m_frame_list[i/FPP] = mfn_to_pfn(p2m_frame_list[i/FPP]);
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
+    if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) )
     {
         ERROR("Could not get vcpu context");
         goto out;
@@ -838,13 +843,13 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
 }
 
 /* must be done AFTER suspend_and_state() */
-static int save_tsc_info(int xc_handle, uint32_t dom, int io_fd)
+static int save_tsc_info(xc_interface *xch, uint32_t dom, int io_fd)
 {
     int marker = -7;
     uint32_t tsc_mode, khz, incarn;
     uint64_t nsec;
 
-    if ( xc_domain_get_tsc_info(xc_handle, dom, &tsc_mode,
+    if ( xc_domain_get_tsc_info(xch, dom, &tsc_mode,
                                 &nsec, &khz, &incarn) < 0  ||
          write_exact(io_fd, &marker, sizeof(marker)) ||
          write_exact(io_fd, &tsc_mode, sizeof(tsc_mode)) ||
@@ -855,7 +860,7 @@ static int save_tsc_info(int xc_handle, uint32_t dom, int 
io_fd)
     return 0;
 }
 
-int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
+int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t 
max_iters,
                    uint32_t max_factor, uint32_t flags,
                    struct save_callbacks* callbacks,
                    int hvm, void (*switch_qemu_logdirty)(int, unsigned))
@@ -866,7 +871,8 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
     int rc = 1, frc, i, j, last_iter = 0, iter = 0;
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
-    int race = 0, sent_last_iter, skip_this_iter;
+    int race = 0, sent_last_iter, skip_this_iter = 0;
+    unsigned int sent_this_iter = 0;
     int tmem_saved = 0;
 
     /* The new domain's shared-info frame number. */
@@ -921,7 +927,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
 
     int completed = 0;
 
-    outbuf_init(&ob, OUTBUF_SIZE);
+    outbuf_init(xch, &ob, OUTBUF_SIZE);
 
     /* If no explicit control parameters given, use defaults */
     max_iters  = max_iters  ? : DEF_MAX_ITERS;
@@ -929,14 +935,14 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
     initialize_mbit_rate();
 
-    if ( !get_platform_info(xc_handle, dom,
+    if ( !get_platform_info(xch, dom,
                             &ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, 
&dinfo->guest_width) )
     {
         ERROR("Unable to get platform info.");
         return 1;
     }
 
-    if ( xc_domain_getinfo(xc_handle, dom, 1, &info) != 1 )
+    if ( xc_domain_getinfo(xch, dom, 1, &info) != 1 )
     {
         ERROR("Could not get domain info");
         return 1;
@@ -947,7 +953,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
     /* Map the shared info frame */
     if ( !hvm )
     {
-        live_shinfo = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
+        live_shinfo = xc_map_foreign_range(xch, dom, PAGE_SIZE,
                                            PROT_READ, shared_info_frame);
         if ( !live_shinfo )
         {
@@ -957,7 +963,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
     }
 
     /* Get the size of the P2M table */
-    dinfo->p2m_size = xc_memory_op(xc_handle, XENMEM_maximum_gpfn, &dom) + 1;
+    dinfo->p2m_size = xc_memory_op(xch, XENMEM_maximum_gpfn, &dom) + 1;
 
     if ( dinfo->p2m_size > ~XEN_DOMCTL_PFINFO_LTAB_MASK )
     {
@@ -969,17 +975,17 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
     if ( live )
     {
         /* Live suspend. Enable log-dirty mode. */
-        if ( xc_shadow_control(xc_handle, dom,
+        if ( xc_shadow_control(xch, dom,
                                XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
                                NULL, 0, NULL, 0, NULL) < 0 )
         {
             /* log-dirty already enabled? There's no test op,
                so attempt to disable then reenable it */
-            frc = xc_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_OFF,
+            frc = xc_shadow_control(xch, dom, XEN_DOMCTL_SHADOW_OP_OFF,
                                     NULL, 0, NULL, 0, NULL);
             if ( frc >= 0 )
             {
-                frc = xc_shadow_control(xc_handle, dom,
+                frc = xc_shadow_control(xch, dom,
                                         XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY,
                                         NULL, 0, NULL, 0, NULL);
             }
@@ -998,7 +1004,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
     else
     {
         /* This is a non-live suspend. Suspend the domain .*/
-        if ( suspend_and_state(callbacks->suspend, callbacks->data, xc_handle,
+        if ( suspend_and_state(callbacks->suspend, callbacks->data, xch,
                                io_fd, dom, &info) )
         {
             ERROR("Domain appears not to have suspended");
@@ -1040,7 +1046,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
     if ( hvm ) 
     {
         /* Need another buffer for HVM context */
-        hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0);
+        hvm_buf_size = xc_domain_hvm_getcontext(xch, dom, 0, 0);
         if ( hvm_buf_size == -1 )
         {
             ERROR("Couldn't get HVM context size from Xen");
@@ -1054,7 +1060,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         }
     }
 
-    analysis_phase(xc_handle, dom, ctx, to_skip, 0);
+    analysis_phase(xch, dom, ctx, to_skip, 0);
 
     pfn_type   = xc_memalign(PAGE_SIZE, ROUNDUP(
                               MAX_BATCH_SIZE * sizeof(*pfn_type), PAGE_SHIFT));
@@ -1076,7 +1082,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
     }
 
     /* Setup the mfn_to_pfn table mapping */
-    if ( !(ctx->live_m2p = xc_map_m2p(xc_handle, ctx->max_mfn, PROT_READ, 
&ctx->m2p_mfn0)) )
+    if ( !(ctx->live_m2p = xc_map_m2p(xch, ctx->max_mfn, PROT_READ, 
&ctx->m2p_mfn0)) )
     {
         ERROR("Failed to map live M2P table");
         goto out;
@@ -1094,7 +1100,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         int err = 0;
 
         /* Map the P2M table, and write the list of P2M frames */
-        ctx->live_p2m = map_and_save_p2m_table(xc_handle, io_fd, dom, ctx, 
live_shinfo);
+        ctx->live_p2m = map_and_save_p2m_table(xch, io_fd, dom, ctx, 
live_shinfo);
         if ( ctx->live_p2m == NULL )
         {
             ERROR("Failed to map/save the p2m frame list");
@@ -1118,57 +1124,55 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         DPRINTF("Had %d unexplained entries in p2m table\n", err);
     }
 
-    print_stats(xc_handle, dom, 0, &stats, 0);
+    print_stats(xch, dom, 0, &stats, 0);
 
-    tmem_saved = xc_tmem_save(xc_handle, dom, io_fd, live, -5);
+    tmem_saved = xc_tmem_save(xch, dom, io_fd, live, -5);
     if ( tmem_saved == -1 )
     {
         ERROR("Error when writing to state file (tmem)");
         goto out;
     }
 
-    if ( !live && save_tsc_info(xc_handle, dom, io_fd) < 0 )
+    if ( !live && save_tsc_info(xch, dom, io_fd) < 0 )
     {
         ERROR("Error when writing to state file (tsc)");
         goto out;
     }
 
   copypages:
-#define wrexact(fd, buf, len) write_buffer(last_iter, &ob, (fd), (buf), (len))
+#define wrexact(fd, buf, len) write_buffer(xch, last_iter, &ob, (fd), (buf), 
(len))
 #ifdef ratewrite
 #undef ratewrite
 #endif
-#define ratewrite(fd, live, buf, len) ratewrite_buffer(last_iter, &ob, (fd), 
(live), (buf), (len))
+#define ratewrite(fd, live, buf, len) ratewrite_buffer(xch, last_iter, &ob, 
(fd), (live), (buf), (len))
 
     /* Now write out each data page, canonicalising page tables as we go... */
     for ( ; ; )
     {
-        unsigned int prev_pc, sent_this_iter, N, batch, run;
+        unsigned int N, batch, run;
+        char reportbuf[80];
+
+        snprintf(reportbuf, sizeof(reportbuf),
+                 "Saving memory: iter %d (last sent %u skipped %u)",
+                 iter, sent_this_iter, skip_this_iter);
+
+        xc_report_progress_start(xch, reportbuf, dinfo->p2m_size);
 
         iter++;
         sent_this_iter = 0;
         skip_this_iter = 0;
-        prev_pc = 0;
         N = 0;
 
-        DPRINTF("Saving memory pages: iter %d   0%%", iter);
-
         while ( N < dinfo->p2m_size )
         {
-            unsigned int this_pc = (N * 100) / dinfo->p2m_size;
-
-            if ( (this_pc - prev_pc) >= 5 )
-            {
-                DPRINTF("\b\b\b\b%3d%%", this_pc);
-                prev_pc = this_pc;
-            }
+            xc_report_progress_step(xch, N, dinfo->p2m_size);
 
             if ( !last_iter )
             {
                 /* Slightly wasteful to peek the whole array evey time,
                    but this is fast enough for the moment. */
                 frc = xc_shadow_control(
-                    xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, 
+                    xch, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, 
                     dinfo->p2m_size, NULL, 0, NULL);
                 if ( frc != dinfo->p2m_size )
                 {
@@ -1275,7 +1279,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
                 goto skip; /* vanishingly unlikely... */
 
             region_base = xc_map_foreign_bulk(
-                xc_handle, dom, PROT_READ, pfn_type, pfn_err, batch);
+                xch, dom, PROT_READ, pfn_type, pfn_err, batch);
             if ( region_base == NULL )
             {
                 ERROR("map batch failed");
@@ -1303,7 +1307,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
             else
             {
                 /* Get page types */
-                if ( xc_get_pfn_type_batch(xc_handle, dom, batch, pfn_type) )
+                if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
                 {
                     ERROR("get_pfn_type_batch failed");
                     goto out;
@@ -1437,12 +1441,9 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
         total_sent += sent_this_iter;
 
-        DPRINTF("\r %d: sent %d, skipped %d, ",
-                iter, sent_this_iter, skip_this_iter );
-
         if ( last_iter )
         {
-            print_stats( xc_handle, dom, sent_this_iter, &stats, 1);
+            print_stats( xch, dom, sent_this_iter, &stats, 1);
 
             DPRINTF("Total pages sent= %ld (%.2fx)\n",
                     total_sent, ((float)total_sent)/dinfo->p2m_size );
@@ -1480,7 +1481,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
                 last_iter = 1;
 
                 if ( suspend_and_state(callbacks->suspend, callbacks->data,
-                                       xc_handle, io_fd, dom, &info) )
+                                       xch, io_fd, dom, &info) )
                 {
                     ERROR("Domain appears not to have suspended");
                     goto out;
@@ -1488,13 +1489,13 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
                 DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
                 if ( (tmem_saved > 0) &&
-                     (xc_tmem_save_extra(xc_handle,dom,io_fd,-6) == -1) )
+                     (xc_tmem_save_extra(xch,dom,io_fd,-6) == -1) )
                 {
                         ERROR("Error when writing to state file (tmem)");
                         goto out;
                 }
 
-                if ( save_tsc_info(xc_handle, dom, io_fd) < 0 )
+                if ( save_tsc_info(xch, dom, io_fd) < 0 )
                 {
                     ERROR("Error when writing to state file (tsc)");
                     goto out;
@@ -1503,7 +1504,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
             }
 
-            if ( xc_shadow_control(xc_handle, dom, 
+            if ( xc_shadow_control(xch, dom, 
                                    XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, 
                                    dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
             {
@@ -1513,7 +1514,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
             sent_last_iter = sent_this_iter;
 
-            print_stats(xc_handle, dom, sent_this_iter, &stats, 1);
+            print_stats(xch, dom, sent_this_iter, &stats, 1);
 
         }
     } /* end of infinite for loop */
@@ -1536,7 +1537,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         for ( i = 1; i <= info.max_vcpu_id; i++ )
         {
             xc_vcpuinfo_t vinfo;
-            if ( (xc_vcpu_getinfo(xc_handle, dom, i, &vinfo) == 0) &&
+            if ( (xc_vcpu_getinfo(xch, dom, i, &vinfo) == 0) &&
                  vinfo.online )
                 vcpumap |= 1ULL << i;
         }
@@ -1558,7 +1559,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         } chunk = { 0, };
 
         chunk.id = -3;
-        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT,
+        xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT,
                          (unsigned long *)&chunk.data);
 
         if ( (chunk.data != 0) &&
@@ -1569,7 +1570,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         }
 
         chunk.id = -4;
-        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_VM86_TSS,
+        xc_get_hvm_param(xch, dom, HVM_PARAM_VM86_TSS,
                          (unsigned long *)&chunk.data);
 
         if ( (chunk.data != 0) &&
@@ -1594,11 +1595,11 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
 
         /* Save magic-page locations. */
         memset(magic_pfns, 0, sizeof(magic_pfns));
-        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN,
+        xc_get_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN,
                          (unsigned long *)&magic_pfns[0]);
-        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN,
+        xc_get_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN,
                          (unsigned long *)&magic_pfns[1]);
-        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN,
+        xc_get_hvm_param(xch, dom, HVM_PARAM_STORE_PFN,
                          (unsigned long *)&magic_pfns[2]);
         if ( wrexact(io_fd, magic_pfns, sizeof(magic_pfns)) )
         {
@@ -1607,7 +1608,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         }
 
         /* Get HVM context from Xen and save it too */
-        if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, 
+        if ( (rec_size = xc_domain_hvm_getcontext(xch, dom, hvm_buf, 
                                                   hvm_buf_size)) == -1 )
         {
             ERROR("HVM:Could not get hvm buffer");
@@ -1668,7 +1669,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         }
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
+    if ( xc_vcpu_getcontext(xch, dom, 0, &ctxt) )
     {
         ERROR("Could not get vcpu context");
         goto out;
@@ -1688,7 +1689,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         if ( !(vcpumap & (1ULL << i)) )
             continue;
 
-        if ( (i != 0) && xc_vcpu_getcontext(xc_handle, dom, i, &ctxt) )
+        if ( (i != 0) && xc_vcpu_getcontext(xch, dom, i, &ctxt) )
         {
             ERROR("No context for VCPU%d", i);
             goto out;
@@ -1740,7 +1741,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         domctl.cmd = XEN_DOMCTL_get_ext_vcpucontext;
         domctl.domain = dom;
         domctl.u.ext_vcpucontext.vcpu = i;
-        if ( xc_domctl(xc_handle, &domctl) < 0 )
+        if ( xc_domctl(xch, &domctl) < 0 )
         {
             ERROR("No extended context for VCPU%d", i);
             goto out;
@@ -1781,32 +1782,32 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
         callbacks->postcopy(callbacks->data);
 
     /* Flush last write and discard cache for file. */
-    if ( outbuf_flush(&ob, io_fd) < 0 ) {
+    if ( outbuf_flush(xch, &ob, io_fd) < 0 ) {
         ERROR("Error when flushing output buffer\n");
         rc = 1;
     }
 
-    discard_file_cache(io_fd, 1 /* flush */);
+    discard_file_cache(xch, io_fd, 1 /* flush */);
 
     /* checkpoint_cb can spend arbitrarily long in between rounds */
     if (!rc && callbacks->checkpoint &&
         callbacks->checkpoint(callbacks->data) > 0)
     {
         /* reset stats timer */
-        print_stats(xc_handle, dom, 0, &stats, 0);
+        print_stats(xch, dom, 0, &stats, 0);
 
         rc = 1;
         /* last_iter = 1; */
-        if ( suspend_and_state(callbacks->suspend, callbacks->data, xc_handle,
+        if ( suspend_and_state(callbacks->suspend, callbacks->data, xch,
                                io_fd, dom, &info) )
         {
             ERROR("Domain appears not to have suspended");
             goto out;
         }
         DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
-        print_stats(xc_handle, dom, 0, &stats, 1);
+        print_stats(xch, dom, 0, &stats, 1);
 
-        if ( xc_shadow_control(xc_handle, dom,
+        if ( xc_shadow_control(xch, dom,
                                XEN_DOMCTL_SHADOW_OP_CLEAN, to_send,
                                dinfo->p2m_size, NULL, 0, &stats) != 
dinfo->p2m_size )
         {
@@ -1817,11 +1818,11 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t 
dom, uint32_t max_iters,
     }
 
     if ( tmem_saved != 0 && live )
-        xc_tmem_save_done(xc_handle, dom);
+        xc_tmem_save_done(xch, dom);
 
     if ( live )
     {
-        if ( xc_shadow_control(xc_handle, dom, 
+        if ( xc_shadow_control(xch, dom, 
                                XEN_DOMCTL_SHADOW_OP_OFF,
                                NULL, 0, NULL, 0, NULL) < 0 )
             DPRINTF("Warning - couldn't disable shadow mode");
diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c
index 204698a..385a29d 100644
--- a/tools/libxc/xc_evtchn.c
+++ b/tools/libxc/xc_evtchn.c
@@ -9,7 +9,7 @@
 #include "xc_private.h"
 
 
-static int do_evtchn_op(int xc_handle, int cmd, void *arg,
+static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
                         size_t arg_size, int silently_fail)
 {
     int ret = -1;
@@ -25,7 +25,7 @@ static int do_evtchn_op(int xc_handle, int cmd, void *arg,
         goto out;
     }
 
-    if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 && !silently_fail)
+    if ((ret = do_xen_hypercall(xch, &hypercall)) < 0 && !silently_fail)
         ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
 
     unlock_pages(arg, arg_size);
@@ -35,7 +35,7 @@ static int do_evtchn_op(int xc_handle, int cmd, void *arg,
 
 
 evtchn_port_or_error_t
-xc_evtchn_alloc_unbound(int xc_handle,
+xc_evtchn_alloc_unbound(xc_interface *xch,
                         uint32_t dom,
                         uint32_t remote_dom)
 {
@@ -45,22 +45,22 @@ xc_evtchn_alloc_unbound(int xc_handle,
         .remote_dom = (domid_t)remote_dom
     };
 
-    rc = do_evtchn_op(xc_handle, EVTCHNOP_alloc_unbound, &arg, sizeof(arg), 0);
+    rc = do_evtchn_op(xch, EVTCHNOP_alloc_unbound, &arg, sizeof(arg), 0);
     if ( rc == 0 )
         rc = arg.port;
 
     return rc;
 }
 
-int xc_evtchn_reset(int xc_handle,
+int xc_evtchn_reset(xc_interface *xch,
                     uint32_t dom)
 {
     struct evtchn_reset arg = { .dom = (domid_t)dom };
-    return do_evtchn_op(xc_handle, EVTCHNOP_reset, &arg, sizeof(arg), 0);
+    return do_evtchn_op(xch, EVTCHNOP_reset, &arg, sizeof(arg), 0);
 }
 
-int xc_evtchn_status(int xc_handle, xc_evtchn_status_t *status)
+int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status)
 {
-    return do_evtchn_op(xc_handle, EVTCHNOP_status, status,
+    return do_evtchn_op(xch, EVTCHNOP_status, status,
                         sizeof(*status), 1);
 }
diff --git a/tools/libxc/xc_flask.c b/tools/libxc/xc_flask.c
index bb2b612..6982445 100644
--- a/tools/libxc/xc_flask.c
+++ b/tools/libxc/xc_flask.c
@@ -9,7 +9,7 @@
 
 #include "xc_private.h"
 
-int xc_flask_op(int xc_handle, flask_op_t *op)
+int xc_flask_op(xc_interface *xch, flask_op_t *op)
 {
     int ret = -1;
     DECLARE_HYPERCALL;
@@ -23,7 +23,7 @@ int xc_flask_op(int xc_handle, flask_op_t *op)
         goto out;
     }
 
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
     {
         if ( errno == EACCES )
             fprintf(stderr, "XSM operation failed!\n");
diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c
index 4748690..82cbf1f 100644
--- a/tools/libxc/xc_hvm_build.c
+++ b/tools/libxc/xc_hvm_build.c
@@ -69,7 +69,8 @@ static void build_hvm_info(void *hvm_info_page, uint64_t 
mem_size)
 }
 
 static int loadelfimage(
-    struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
+    xc_interface *xch,
+    struct elf_binary *elf, uint32_t dom, unsigned long *parray)
 {
     privcmd_mmap_entry_t *entries = NULL;
     size_t pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -115,7 +116,7 @@ static int check_mmio_hole(uint64_t start, uint64_t memsize)
         return 1;
 }
 
-static int setup_guest(int xc_handle,
+static int setup_guest(xc_interface *xch,
                        uint32_t dom, int memsize, int target,
                        char *image, unsigned long image_size)
 {
@@ -149,7 +150,7 @@ static int setup_guest(int xc_handle,
     v_start = 0;
     v_end = (unsigned long long)memsize << 20;
 
-    if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
+    if ( xc_version(xch, XENVER_capabilities, &caps) != 0 )
     {
         PERROR("Could not get Xen capabilities\n");
         goto error_out;
@@ -191,7 +192,7 @@ static int setup_guest(int xc_handle,
      * ensure that we can be preempted and hence dom0 remains responsive.
      */
     rc = xc_domain_memory_populate_physmap(
-        xc_handle, dom, 0xa0, 0, 0, &page_array[0x00]);
+        xch, dom, 0xa0, 0, 0, &page_array[0x00]);
     cur_pages = 0xc0;
     stat_normal_pages = 0xc0;
     while ( (rc == 0) && (nr_pages > cur_pages) )
@@ -233,7 +234,7 @@ static int setup_guest(int xc_handle,
             set_xen_guest_handle(sp_req.extent_start, sp_extents);
             for ( i = 0; i < sp_req.nr_extents; i++ )
                 sp_extents[i] = page_array[cur_pages+(i<<SUPERPAGE_1GB_SHIFT)];
-            done = xc_memory_op(xc_handle, XENMEM_populate_physmap, &sp_req);
+            done = xc_memory_op(xch, XENMEM_populate_physmap, &sp_req);
             if ( done > 0 )
             {
                 stat_1gb_pages += done;
@@ -280,7 +281,7 @@ static int setup_guest(int xc_handle,
                 set_xen_guest_handle(sp_req.extent_start, sp_extents);
                 for ( i = 0; i < sp_req.nr_extents; i++ )
                     sp_extents[i] = 
page_array[cur_pages+(i<<SUPERPAGE_2MB_SHIFT)];
-                done = xc_memory_op(xc_handle, XENMEM_populate_physmap, 
&sp_req);
+                done = xc_memory_op(xch, XENMEM_populate_physmap, &sp_req);
                 if ( done > 0 )
                 {
                     stat_2mb_pages += done;
@@ -300,7 +301,7 @@ static int setup_guest(int xc_handle,
         if ( count != 0 )
         {
             rc = xc_domain_memory_populate_physmap(
-                xc_handle, dom, count, 0, 0, &page_array[cur_pages]);
+                xch, dom, count, 0, 0, &page_array[cur_pages]);
             cur_pages += count;
             stat_normal_pages += count;
             if ( pod_mode )
@@ -309,7 +310,7 @@ static int setup_guest(int xc_handle,
     }
 
     if ( pod_mode )
-        rc = xc_domain_memory_set_pod_target(xc_handle,
+        rc = xc_domain_memory_set_pod_target(xch,
                                              dom,
                                              pod_pages,
                                              NULL, NULL, NULL);
@@ -326,11 +327,11 @@ static int setup_guest(int xc_handle,
             "  1GB PAGES: 0x%016lx\n",
             stat_normal_pages, stat_2mb_pages, stat_1gb_pages);
     
-    if ( loadelfimage(&elf, xc_handle, dom, page_array) != 0 )
+    if ( loadelfimage(xch, &elf, dom, page_array) != 0 )
         goto error_out;
 
     if ( (hvm_info_page = xc_map_foreign_range(
-              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
+              xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               HVM_INFO_PFN)) == NULL )
         goto error_out;
     build_hvm_info(hvm_info_page, v_end);
@@ -341,9 +342,9 @@ static int setup_guest(int xc_handle,
     xatp.space = XENMAPSPACE_shared_info;
     xatp.idx   = 0;
     xatp.gpfn  = special_pfn(SPECIALPAGE_SHINFO);
-    if ( (xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp) != 0) ||
+    if ( (xc_memory_op(xch, XENMEM_add_to_physmap, &xatp) != 0) ||
          ((shared_info = xc_map_foreign_range(
-             xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
+             xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
              special_pfn(SPECIALPAGE_SHINFO))) == NULL) )
         goto error_out;
     memset(shared_info, 0, PAGE_SIZE);
@@ -358,21 +359,21 @@ static int setup_guest(int xc_handle,
         xen_pfn_t pfn = special_pfn(i);
         if ( i == SPECIALPAGE_SHINFO )
             continue;
-        rc = xc_domain_memory_populate_physmap(xc_handle, dom, 1, 0, 0, &pfn);
+        rc = xc_domain_memory_populate_physmap(xch, dom, 1, 0, 0, &pfn);
         if ( rc != 0 )
         {
             PERROR("Could not allocate %d'th special page.\n", i);
             goto error_out;
         }
-        if ( xc_clear_domain_page(xc_handle, dom, special_pfn(i)) )
+        if ( xc_clear_domain_page(xch, dom, special_pfn(i)) )
             goto error_out;
     }
 
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN,
+    xc_set_hvm_param(xch, dom, HVM_PARAM_STORE_PFN,
                      special_pfn(SPECIALPAGE_XENSTORE));
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN,
+    xc_set_hvm_param(xch, dom, HVM_PARAM_BUFIOREQ_PFN,
                      special_pfn(SPECIALPAGE_BUFIOREQ));
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN,
+    xc_set_hvm_param(xch, dom, HVM_PARAM_IOREQ_PFN,
                      special_pfn(SPECIALPAGE_IOREQ));
 
     /*
@@ -380,14 +381,14 @@ static int setup_guest(int xc_handle,
      * using Intel EPT. Create a 32-bit non-PAE page directory of superpages.
      */
     if ( (ident_pt = xc_map_foreign_range(
-              xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
+              xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
               special_pfn(SPECIALPAGE_IDENT_PT))) == NULL )
         goto error_out;
     for ( i = 0; i < PAGE_SIZE / sizeof(*ident_pt); i++ )
         ident_pt[i] = ((i << 22) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
                        _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE);
     munmap(ident_pt, PAGE_SIZE);
-    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT,
+    xc_set_hvm_param(xch, dom, HVM_PARAM_IDENT_PT,
                      special_pfn(SPECIALPAGE_IDENT_PT) << PAGE_SHIFT);
 
     /* Insert JMP <rel32> instruction at address 0x0 to reach entry point. */
@@ -395,7 +396,7 @@ static int setup_guest(int xc_handle,
     if ( entry_eip != 0 )
     {
         char *page0 = xc_map_foreign_range(
-            xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
+            xch, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, 0);
         if ( page0 == NULL )
             goto error_out;
         page0[0] = 0xe9;
@@ -411,7 +412,7 @@ static int setup_guest(int xc_handle,
     return -1;
 }
 
-static int xc_hvm_build_internal(int xc_handle,
+static int xc_hvm_build_internal(xc_interface *xch,
                                  uint32_t domid,
                                  int memsize,
                                  int target,
@@ -424,13 +425,13 @@ static int xc_hvm_build_internal(int xc_handle,
         return -1;
     }
 
-    return setup_guest(xc_handle, domid, memsize, target, image, image_size);
+    return setup_guest(xch, domid, memsize, target, image, image_size);
 }
 
 /* xc_hvm_build:
  * Create a domain for a virtualized Linux, using files/filenames.
  */
-int xc_hvm_build(int xc_handle,
+int xc_hvm_build(xc_interface *xch,
                  uint32_t domid,
                  int memsize,
                  const char *image_name)
@@ -440,10 +441,10 @@ int xc_hvm_build(int xc_handle,
     unsigned long image_size;
 
     if ( (image_name == NULL) ||
-         ((image = xc_read_image(image_name, &image_size)) == NULL) )
+         ((image = xc_read_image(xch, image_name, &image_size)) == NULL) )
         return -1;
 
-    sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, 
image_size);
+    sts = xc_hvm_build_internal(xch, domid, memsize, memsize, image, 
image_size);
 
     free(image);
 
@@ -456,7 +457,7 @@ int xc_hvm_build(int xc_handle,
  * memsize pages marked populate-on-demand, and with a PoD cache size
  * of target.  If target == memsize, pages are populated normally.
  */
-int xc_hvm_build_target_mem(int xc_handle,
+int xc_hvm_build_target_mem(xc_interface *xch,
                            uint32_t domid,
                            int memsize,
                            int target,
@@ -467,10 +468,10 @@ int xc_hvm_build_target_mem(int xc_handle,
     unsigned long image_size;
 
     if ( (image_name == NULL) ||
-         ((image = xc_read_image(image_name, &image_size)) == NULL) )
+         ((image = xc_read_image(xch, image_name, &image_size)) == NULL) )
         return -1;
 
-    sts = xc_hvm_build_internal(xc_handle, domid, memsize, target, image, 
image_size);
+    sts = xc_hvm_build_internal(xch, domid, memsize, target, image, 
image_size);
 
     free(image);
 
@@ -480,7 +481,7 @@ int xc_hvm_build_target_mem(int xc_handle,
 /* xc_hvm_build_mem:
  * Create a domain for a virtualized Linux, using memory buffers.
  */
-int xc_hvm_build_mem(int xc_handle,
+int xc_hvm_build_mem(xc_interface *xch,
                      uint32_t domid,
                      int memsize,
                      const char *image_buffer,
@@ -498,14 +499,14 @@ int xc_hvm_build_mem(int xc_handle,
         return -1;
     }
 
-    img = xc_inflate_buffer(image_buffer, image_size, &img_len);
+    img = xc_inflate_buffer(xch, image_buffer, image_size, &img_len);
     if ( img == NULL )
     {
         ERROR("unable to inflate ram disk buffer");
         return -1;
     }
 
-    sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize,
+    sts = xc_hvm_build_internal(xch, domid, memsize, memsize,
                                 img, img_len);
 
     /* xc_inflate_buffer may return the original buffer pointer (for
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c
index 55ceda1..4df8e58 100644
--- a/tools/libxc/xc_linux.c
+++ b/tools/libxc/xc_linux.c
@@ -20,7 +20,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open(void)
+int xc_interface_open_core(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/proc/xen/privcmd", O_RDWR);
@@ -59,12 +59,12 @@ int xc_interface_open(void)
     return -1;
 }
 
-int xc_interface_close(int xc_handle)
+int xc_interface_close_core(xc_interface *xch, int fd)
 {
-    return close(xc_handle);
+    return close(fd);
 }
 
-static int xc_map_foreign_batch_single(int xc_handle, uint32_t dom,
+static int xc_map_foreign_batch_single(xc_interface *xch, uint32_t dom,
                                        xen_pfn_t *mfn, unsigned long addr)
 {
     privcmd_mmapbatch_t ioctlx;
@@ -79,24 +79,24 @@ static int xc_map_foreign_batch_single(int xc_handle, 
uint32_t dom,
     {
         *mfn ^= XEN_DOMCTL_PFINFO_PAGEDTAB;
         usleep(100);
-        rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
+        rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
     }
     while ( (rc < 0) && (errno == ENOENT) );
 
     return rc;
 }
 
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
                            xen_pfn_t *arr, int num)
 {
     privcmd_mmapbatch_t ioctlx;
     void *addr;
     int rc;
 
-    addr = mmap(NULL, num << PAGE_SHIFT, prot, MAP_SHARED, xc_handle, 0);
+    addr = mmap(NULL, num << PAGE_SHIFT, prot, MAP_SHARED, xch->fd, 0);
     if ( addr == MAP_FAILED )
     {
-        perror("xc_map_foreign_batch: mmap failed");
+        PERROR("xc_map_foreign_batch: mmap failed");
         return NULL;
     }
 
@@ -105,7 +105,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     ioctlx.addr = (unsigned long)addr;
     ioctlx.arr = arr;
 
-    rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
+    rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
     if ( (rc < 0) && (errno == ENOENT) )
     {
         int i;
@@ -116,7 +116,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
                  XEN_DOMCTL_PFINFO_PAGEDTAB )
             {
                 unsigned long paged_addr = (unsigned long)addr + (i << 
PAGE_SHIFT);
-                rc = xc_map_foreign_batch_single(xc_handle, dom, &arr[i],
+                rc = xc_map_foreign_batch_single(xch, dom, &arr[i],
                                                  paged_addr);
                 if ( rc < 0 )
                     goto out;
@@ -128,7 +128,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     if ( rc < 0 )
     {
         int saved_errno = errno;
-        perror("xc_map_foreign_batch: ioctl failed");
+        PERROR("xc_map_foreign_batch: ioctl failed");
         (void)munmap(addr, num << PAGE_SHIFT);
         errno = saved_errno;
         return NULL;
@@ -137,7 +137,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     return addr;
 }
 
-void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_bulk(xc_interface *xch, uint32_t dom, int prot,
                           const xen_pfn_t *arr, int *err, unsigned int num)
 {
     privcmd_mmapbatch_v2_t ioctlx;
@@ -146,10 +146,10 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, 
int prot,
     int rc;
 
     addr = mmap(NULL, (unsigned long)num << PAGE_SHIFT, prot, MAP_SHARED,
-                xc_handle, 0);
+                xch->fd, 0);
     if ( addr == MAP_FAILED )
     {
-        perror("xc_map_foreign_batch: mmap failed");
+        PERROR("xc_map_foreign_batch: mmap failed");
         return NULL;
     }
 
@@ -159,7 +159,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
     ioctlx.arr = arr;
     ioctlx.err = err;
 
-    rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
+    rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
 
     if ( rc < 0 && errno == ENOENT )
     {
@@ -175,7 +175,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
             ioctlx.err = err + i;
             do {
                 usleep(100);
-                rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
+                rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH_V2, &ioctlx);
             } while ( rc < 0 && err[i] == -ENOENT );
         }
     }
@@ -199,7 +199,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
             ioctlx.addr = (unsigned long)addr;
             ioctlx.arr = pfn;
 
-            rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
+            rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx);
 
             rc = rc < 0 ? -errno : 0;
 
@@ -219,7 +219,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
                         err[i] = rc ?: -EINVAL;
                         continue;
                     }
-                    rc = xc_map_foreign_batch_single(xc_handle, dom, pfn + i,
+                    rc = xc_map_foreign_batch_single(xch, dom, pfn + i,
                         (unsigned long)addr + ((unsigned long)i<<PAGE_SHIFT));
                     if ( rc < 0 )
                     {
@@ -253,7 +253,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
     {
         int saved_errno = errno;
 
-        perror("xc_map_foreign_bulk: ioctl failed");
+        PERROR("xc_map_foreign_bulk: ioctl failed");
         (void)munmap(addr, (unsigned long)num << PAGE_SHIFT);
         errno = saved_errno;
         return NULL;
@@ -262,7 +262,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
     return addr;
 }
 
-void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot,
+void *xc_map_foreign_range(xc_interface *xch, uint32_t dom, int size, int prot,
                            unsigned long mfn)
 {
     xen_pfn_t *arr;
@@ -276,12 +276,12 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom, 
int size, int prot,
     for ( i = 0; i < num; i++ )
         arr[i] = mfn + i;
 
-    ret = xc_map_foreign_pages(xc_handle, dom, prot, arr, num);
+    ret = xc_map_foreign_pages(xch, dom, prot, arr, num);
     free(arr);
     return ret;
 }
 
-void *xc_map_foreign_ranges(int xc_handle, uint32_t dom, size_t size, int prot,
+void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom, size_t size, int 
prot,
                             size_t chunksize, privcmd_mmap_entry_t entries[],
                             int nentries)
 {
@@ -300,19 +300,19 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom, 
size_t size, int prot,
         for ( j = 0; j < num_per_entry; j++ )
             arr[i * num_per_entry + j] = entries[i].mfn + j;
 
-    ret = xc_map_foreign_pages(xc_handle, dom, prot, arr, num);
+    ret = xc_map_foreign_pages(xch, dom, prot, arr, num);
     free(arr);
     return ret;
 }
 
-static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
+static int do_privcmd(xc_interface *xch, int cmd, unsigned long data)
 {
-    return ioctl(xc_handle, cmd, data);
+    return ioctl(xch->fd, cmd, data);
 }
 
-int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
 {
-    return do_privcmd(xc_handle, IOCTL_PRIVCMD_HYPERCALL,
+    return do_privcmd(xch, IOCTL_PRIVCMD_HYPERCALL,
                       (unsigned long)hypercall);
 }
 
@@ -401,7 +401,6 @@ int xc_evtchn_open(void)
              (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) )
             goto reopen;
 
-        PERROR("Could not open event channel interface");
         return -1;
     }
 
@@ -485,7 +484,7 @@ int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
 }
 
 /* Optionally flush file to disk and discard page cache */
-void discard_file_cache(int fd, int flush) 
+void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
     off_t cur = 0;
     int saved_errno = errno;
@@ -521,7 +520,7 @@ void discard_file_cache(int fd, int flush)
 
 #define GNTTAB_DEV_NAME "/dev/xen/gntdev"
 
-int xc_gnttab_open(void)
+int xc_gnttab_open(xc_interface *xch)
 {
     struct stat st;
     int fd;
@@ -549,13 +548,13 @@ reopen:
     return fd;
 }
 
-int xc_gnttab_close(int xcg_handle)
+int xc_gnttab_close(xc_interface *xch, int xcg_handle)
 {
     return close(xcg_handle);
 }
 
-void *xc_gnttab_map_grant_ref(int xcg_handle, uint32_t domid, uint32_t ref,
-                              int prot)
+void *xc_gnttab_map_grant_ref(xc_interface *xch, int xcg_handle,
+                              uint32_t domid, uint32_t ref, int prot)
 {
     struct ioctl_gntdev_map_grant_ref map;
     void *addr;
@@ -564,8 +563,10 @@ void *xc_gnttab_map_grant_ref(int xcg_handle, uint32_t 
domid, uint32_t ref,
     map.refs[0].domid = domid;
     map.refs[0].ref = ref;
 
-    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) )
+    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, &map) ) {
+        PERROR("xc_gnttab_map_grant_ref: ioctl MAP_GRANT_REF failed");
         return NULL;
+    }
 
 mmap_again:    
     addr = mmap(NULL, PAGE_SIZE, prot, MAP_SHARED, xcg_handle, map.index);
@@ -580,7 +581,7 @@ mmap_again:
             goto mmap_again;
         }
          /* Unmap the driver slots used to store the grant information. */
-        perror("xc_gnttab_map_grant_ref: mmap failed");
+        PERROR("xc_gnttab_map_grant_ref: mmap failed");
         unmap_grant.index = map.index;
         unmap_grant.count = 1;
         ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
@@ -591,7 +592,8 @@ mmap_again:
     return addr;
 }
 
-static void *do_gnttab_map_grant_refs(int xcg_handle, uint32_t count,
+static void *do_gnttab_map_grant_refs(xc_interface *xch,
+                                      int xcg_handle, uint32_t count,
                                       uint32_t *domids, int domids_stride,
                                       uint32_t *refs, int prot)
 {
@@ -612,8 +614,10 @@ static void *do_gnttab_map_grant_refs(int xcg_handle, 
uint32_t count,
 
     map->count = count;
 
-    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, map) )
+    if ( ioctl(xcg_handle, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) {
+        PERROR("xc_gnttab_map_grant_refs: ioctl MAP_GRANT_REF failed");
         goto out;
+    }
 
     addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, xcg_handle,
                 map->index);
@@ -623,7 +627,7 @@ static void *do_gnttab_map_grant_refs(int xcg_handle, 
uint32_t count,
         struct ioctl_gntdev_unmap_grant_ref unmap_grant;
 
         /* Unmap the driver slots used to store the grant information. */
-        perror("xc_gnttab_map_grant_refs: mmap failed");
+        PERROR("xc_gnttab_map_grant_refs: mmap failed");
         unmap_grant.index = map->index;
         unmap_grant.count = count;
         ioctl(xcg_handle, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant);
@@ -637,19 +641,22 @@ static void *do_gnttab_map_grant_refs(int xcg_handle, 
uint32_t count,
     return addr;
 }
 
-void *xc_gnttab_map_grant_refs(int xcg_handle, uint32_t count, uint32_t 
*domids,
+void *xc_gnttab_map_grant_refs(xc_interface *xch,
+                               int xcg_handle, uint32_t count, uint32_t 
*domids,
                                uint32_t *refs, int prot)
 {
-    return do_gnttab_map_grant_refs(xcg_handle, count, domids, 1, refs, prot);
+    return do_gnttab_map_grant_refs(xch, xcg_handle, count, domids, 1, refs, 
prot);
 }
 
-void *xc_gnttab_map_domain_grant_refs(int xcg_handle, uint32_t count,
+void *xc_gnttab_map_domain_grant_refs(xc_interface *xch,
+                                      int xcg_handle, uint32_t count,
                                       uint32_t domid, uint32_t *refs, int prot)
 {
-    return do_gnttab_map_grant_refs(xcg_handle, count, &domid, 0, refs, prot);
+    return do_gnttab_map_grant_refs(xch, xcg_handle, count, &domid, 0, refs, 
prot);
 }
 
-int xc_gnttab_munmap(int xcg_handle, void *start_address, uint32_t count)
+int xc_gnttab_munmap(xc_interface *xch,
+                     int xcg_handle, void *start_address, uint32_t count)
 {
     struct ioctl_gntdev_get_offset_for_vaddr get_offset;
     struct ioctl_gntdev_unmap_grant_ref unmap_grant;
@@ -688,7 +695,8 @@ int xc_gnttab_munmap(int xcg_handle, void *start_address, 
uint32_t count)
     return 0;
 }
 
-int xc_gnttab_set_max_grants(int xcg_handle, uint32_t count)
+int xc_gnttab_set_max_grants(xc_interface *xch,
+                             int xcg_handle, uint32_t count)
 {
     struct ioctl_gntdev_set_max_grants set_max;
     int rc;
@@ -700,7 +708,7 @@ int xc_gnttab_set_max_grants(int xcg_handle, uint32_t count)
     return 0;
 }
 
-int xc_gnttab_op(int xc_handle, int cmd, void * op, int op_size, int count)
+int xc_gnttab_op(xc_interface *xch, int cmd, void * op, int op_size, int count)
 {
     int ret = 0;
     DECLARE_HYPERCALL;
@@ -716,7 +724,7 @@ int xc_gnttab_op(int xc_handle, int cmd, void * op, int 
op_size, int count)
         goto out1;
     }
 
-    ret = do_xen_hypercall(xc_handle, &hypercall);
+    ret = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(op, count * op_size);
 
@@ -724,13 +732,13 @@ int xc_gnttab_op(int xc_handle, int cmd, void * op, int 
op_size, int count)
     return ret;
 }
 
-int xc_gnttab_get_version(int xc_handle, int domid)
+int xc_gnttab_get_version(xc_interface *xch, int domid)
 {
     struct gnttab_get_version query;
     int rc;
 
     query.dom = domid;
-    rc = xc_gnttab_op(xc_handle, GNTTABOP_get_version, &query, sizeof(query),
+    rc = xc_gnttab_op(xch, GNTTABOP_get_version, &query, sizeof(query),
                       1);
     if ( rc < 0 )
         return rc;
@@ -738,7 +746,7 @@ int xc_gnttab_get_version(int xc_handle, int domid)
         return query.version;
 }
 
-static void *_gnttab_map_table(int xc_handle, int domid, int *gnt_num)
+static void *_gnttab_map_table(xc_interface *xch, int domid, int *gnt_num)
 {
     int rc, i;
     struct gnttab_query_size query;
@@ -751,7 +759,7 @@ static void *_gnttab_map_table(int xc_handle, int domid, 
int *gnt_num)
         return NULL;
 
     query.dom = domid;
-    rc = xc_gnttab_op(xc_handle, GNTTABOP_query_size, &query, sizeof(query), 
1);
+    rc = xc_gnttab_op(xch, GNTTABOP_query_size, &query, sizeof(query), 1);
 
     if ( rc || (query.status != GNTST_okay) )
     {
@@ -783,7 +791,7 @@ static void *_gnttab_map_table(int xc_handle, int domid, 
int *gnt_num)
     set_xen_guest_handle(setup.frame_list, frame_list);
 
     /* XXX Any race with other setup_table hypercall? */
-    rc = xc_gnttab_op(xc_handle, GNTTABOP_setup_table, &setup, sizeof(setup),
+    rc = xc_gnttab_op(xch, GNTTABOP_setup_table, &setup, sizeof(setup),
                       1);
 
     if ( rc || (setup.status != GNTST_okay) )
@@ -795,7 +803,7 @@ static void *_gnttab_map_table(int xc_handle, int domid, 
int *gnt_num)
     for ( i = 0; i < setup.nr_frames; i++ )
         pfn_list[i] = frame_list[i];
 
-    gnt = xc_map_foreign_pages(xc_handle, domid, PROT_READ, pfn_list,
+    gnt = xc_map_foreign_pages(xch, domid, PROT_READ, pfn_list,
                                setup.nr_frames);
     if ( !gnt )
     {
@@ -815,20 +823,20 @@ err:
     return gnt;
 }
 
-grant_entry_v1_t *xc_gnttab_map_table_v1(int xc_handle, int domid,
+grant_entry_v1_t *xc_gnttab_map_table_v1(xc_interface *xch, int domid,
                                          int *gnt_num)
 {
-    if (xc_gnttab_get_version(xc_handle, domid) == 2)
+    if (xc_gnttab_get_version(xch, domid) == 2)
         return NULL;
-    return _gnttab_map_table(xc_handle, domid, gnt_num);
+    return _gnttab_map_table(xch, domid, gnt_num);
 }
 
-grant_entry_v2_t *xc_gnttab_map_table_v2(int xc_handle, int domid,
+grant_entry_v2_t *xc_gnttab_map_table_v2(xc_interface *xch, int domid,
                                          int *gnt_num)
 {
-    if (xc_gnttab_get_version(xc_handle, domid) != 2)
+    if (xc_gnttab_get_version(xch, domid) != 2)
         return NULL;
-    return _gnttab_map_table(xc_handle, domid, gnt_num);
+    return _gnttab_map_table(xch, domid, gnt_num);
 }
 
 /*
diff --git a/tools/libxc/xc_mem_event.c b/tools/libxc/xc_mem_event.c
index d90f879..e81db0e 100644
--- a/tools/libxc/xc_mem_event.c
+++ b/tools/libxc/xc_mem_event.c
@@ -23,7 +23,7 @@
 
 #include "xc_private.h"
 
-int xc_mem_event_control(int xc_handle, domid_t domain_id, unsigned int op,
+int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op,
                          unsigned int mode, void *shared_page,
                          void *ring_page, unsigned long gfn)
 {
@@ -39,20 +39,20 @@ int xc_mem_event_control(int xc_handle, domid_t domain_id, 
unsigned int op,
 
     domctl.u.mem_event_op.gfn = gfn;
     
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_mem_event_enable(int xc_handle, domid_t domain_id,
+int xc_mem_event_enable(xc_interface *xch, domid_t domain_id,
                         void *shared_page, void *ring_page)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_ENABLE, 0,
                                 shared_page, ring_page, INVALID_MFN);
 }
 
-int xc_mem_event_disable(int xc_handle, domid_t domain_id)
+int xc_mem_event_disable(xc_interface *xch, domid_t domain_id)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_DISABLE, 0,
                                 NULL, NULL, INVALID_MFN);
 }
diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c
index f59c24c..dd7c887 100644
--- a/tools/libxc/xc_mem_paging.c
+++ b/tools/libxc/xc_mem_paging.c
@@ -25,33 +25,33 @@
 #include "xc_private.h"
 
 
-int xc_mem_paging_nominate(int xc_handle, domid_t domain_id, unsigned long gfn)
+int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id, unsigned long 
gfn)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING_NOMINATE,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
                                 gfn);
 }
 
-int xc_mem_paging_evict(int xc_handle, domid_t domain_id, unsigned long gfn)
+int xc_mem_paging_evict(xc_interface *xch, domid_t domain_id, unsigned long 
gfn)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING_EVICT,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
                                 gfn);
 }
 
-int xc_mem_paging_prep(int xc_handle, domid_t domain_id, unsigned long gfn)
+int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING_PREP,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
                                 gfn);
 }
 
-int xc_mem_paging_resume(int xc_handle, domid_t domain_id, unsigned long gfn)
+int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id, unsigned long 
gfn)
 {
-    return xc_mem_event_control(xc_handle, domain_id,
+    return xc_mem_event_control(xch, domain_id,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING_RESUME,
                                 XEN_DOMCTL_MEM_EVENT_OP_PAGING, NULL, NULL,
                                 gfn);
diff --git a/tools/libxc/xc_memshr.c b/tools/libxc/xc_memshr.c
index 1d54a38..7fca923 100644
--- a/tools/libxc/xc_memshr.c
+++ b/tools/libxc/xc_memshr.c
@@ -25,7 +25,7 @@
 #include <xen/memory.h>
 #include <xen/grant_table.h>
 
-int xc_memshr_control(int xc_handle,
+int xc_memshr_control(xc_interface *xch,
                       uint32_t domid,
                       int enable)
 {
@@ -39,10 +39,10 @@ int xc_memshr_control(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_CONTROL;
     op->u.enable = enable;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_memshr_nominate_gfn(int xc_handle,
+int xc_memshr_nominate_gfn(xc_interface *xch,
                            uint32_t domid,
                            unsigned long gfn,
                            uint64_t *handle)
@@ -58,13 +58,13 @@ int xc_memshr_nominate_gfn(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GFN;
     op->u.nominate.u.gfn = gfn;
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
     if(!ret) *handle = op->u.nominate.handle; 
 
     return ret;
 }
 
-int xc_memshr_nominate_gref(int xc_handle,
+int xc_memshr_nominate_gref(xc_interface *xch,
                             uint32_t domid,
                             grant_ref_t gref,
                             uint64_t *handle)
@@ -80,13 +80,13 @@ int xc_memshr_nominate_gref(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_NOMINATE_GREF;
     op->u.nominate.u.grant_ref = gref;
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
     if(!ret) *handle = op->u.nominate.handle; 
 
     return ret;
 }
 
-int xc_memshr_share(int xc_handle,
+int xc_memshr_share(xc_interface *xch,
                     uint64_t source_handle,
                     uint64_t client_handle)
 {
@@ -101,10 +101,10 @@ int xc_memshr_share(int xc_handle,
     op->u.share.source_handle = source_handle;
     op->u.share.client_handle = client_handle;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_memshr_domain_resume(int xc_handle,
+int xc_memshr_domain_resume(xc_interface *xch,
                             uint32_t domid)
 {
     DECLARE_DOMCTL;
@@ -116,10 +116,10 @@ int xc_memshr_domain_resume(int xc_handle,
     op = &(domctl.u.mem_sharing_op);
     op->op = XEN_DOMCTL_MEM_SHARING_OP_RESUME;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_memshr_debug_gfn(int xc_handle,
+int xc_memshr_debug_gfn(xc_interface *xch,
                         uint32_t domid,
                         unsigned long gfn)
 {
@@ -133,10 +133,10 @@ int xc_memshr_debug_gfn(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GFN;
     op->u.debug.u.gfn = gfn;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_memshr_debug_mfn(int xc_handle,
+int xc_memshr_debug_mfn(xc_interface *xch,
                         uint32_t domid,
                         unsigned long mfn)
 {
@@ -150,10 +150,10 @@ int xc_memshr_debug_mfn(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_MFN;
     op->u.debug.u.mfn = mfn;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-int xc_memshr_debug_gref(int xc_handle,
+int xc_memshr_debug_gref(xc_interface *xch,
                          uint32_t domid,
                          grant_ref_t gref)
 {
@@ -167,6 +167,6 @@ int xc_memshr_debug_gref(int xc_handle,
     op->op = XEN_DOMCTL_MEM_SHARING_OP_DEBUG_GREF;
     op->u.debug.u.gref = gref;
 
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c
index 0ae8d69..0240822 100644
--- a/tools/libxc/xc_minios.c
+++ b/tools/libxc/xc_minios.c
@@ -33,18 +33,18 @@
 
 extern struct wait_queue_head event_queue;
 
-int xc_interface_open(void)
+int xc_interface_open_core(xc_interface *xch)
 {
     return alloc_fd(FTYPE_XC);
 }
 
-int xc_interface_close(int xc_handle)
+int xc_interface_close_core(xc_interface *xch, int fd)
 {
-    files[xc_handle].type = FTYPE_NONE;
+    files[fd].type = FTYPE_NONE;
     return 0;
 }
 
-void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_bulk(xc_interface *xch, uint32_t dom, int prot,
                           const xen_pfn_t *arr, int *err, unsigned int num)
 {
     unsigned long pt_prot = 0;
@@ -59,7 +59,7 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int 
prot,
     return map_frames_ex(arr, num, 1, 0, 1, dom, err, pt_prot);    
 }
 
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
                            xen_pfn_t *arr, int num)
 {
     unsigned long pt_prot = 0;
@@ -83,7 +83,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     return (void *) addr;
 }
 
-void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+void *xc_map_foreign_range(xc_interface *xch, uint32_t dom,
                            int size, int prot,
                            unsigned long mfn)
 {
@@ -100,7 +100,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, NULL, 
pt_prot);
 }
 
-void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries)
 {
@@ -130,7 +130,7 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
 }
 
 
-int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
 {
     multicall_entry_t call;
     int i, ret;
@@ -351,13 +351,13 @@ int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
 }
 
 /* Optionally flush file to disk and discard page cache */
-void discard_file_cache(int fd, int flush)
+void discard_file_cache(xc_interface *xch, int fd, int flush)
 {
     if (flush)
         fsync(fd);
 }
 
-int xc_gnttab_open(void)
+int xc_gnttab_open(xc_interface *xch)
 {
     int xcg_handle;
     xcg_handle = alloc_fd(FTYPE_GNTMAP);
@@ -365,14 +365,14 @@ int xc_gnttab_open(void)
     return xcg_handle;
 }
 
-int xc_gnttab_close(int xcg_handle)
+int xc_gnttab_close(xc_interface *xch, int xcg_handle)
 {
     gntmap_fini(&files[xcg_handle].gntmap);
     files[xcg_handle].type = FTYPE_NONE;
     return 0;
 }
 
-void *xc_gnttab_map_grant_ref(int xcg_handle,
+void *xc_gnttab_map_grant_ref(xc_interface *xch, int xcg_handle,
                               uint32_t domid,
                               uint32_t ref,
                               int prot)
@@ -384,7 +384,7 @@ void *xc_gnttab_map_grant_ref(int xcg_handle,
                                  prot & PROT_WRITE);
 }
 
-void *xc_gnttab_map_grant_refs(int xcg_handle,
+void *xc_gnttab_map_grant_refs(xc_interface *xch, int xcg_handle,
                                uint32_t count,
                                uint32_t *domids,
                                uint32_t *refs,
@@ -397,7 +397,7 @@ void *xc_gnttab_map_grant_refs(int xcg_handle,
                                  prot & PROT_WRITE);
 }
 
-void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
+void *xc_gnttab_map_domain_grant_refs(xc_interface *xch, int xcg_handle,
                                       uint32_t count,
                                       uint32_t domid,
                                       uint32_t *refs,
@@ -410,7 +410,7 @@ void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
                                  prot & PROT_WRITE);
 }
 
-int xc_gnttab_munmap(int xcg_handle,
+int xc_gnttab_munmap(xc_interface *xch, int xcg_handle,
                      void *start_address,
                      uint32_t count)
 {
@@ -425,7 +425,7 @@ int xc_gnttab_munmap(int xcg_handle,
     return ret;
 }
 
-int xc_gnttab_set_max_grants(int xcg_handle,
+int xc_gnttab_set_max_grants(xc_interface *xch, int xcg_handle,
                              uint32_t count)
 {
     int ret;
@@ -439,13 +439,13 @@ int xc_gnttab_set_max_grants(int xcg_handle,
 }
 
 grant_entry_v1_t *xc_gnttab_map_table_v1(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
 
 grant_entry_v2_t *xc_gnttab_map_table_v2(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index aa8f76d..5ec3795 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -7,7 +7,7 @@
 #include "xc_private.h"
 #include <xen/hvm/hvm_op.h>
 
-int xc_readconsolering(int xc_handle,
+int xc_readconsolering(xc_interface *xch,
                        char **pbuffer,
                        unsigned int *pnr_chars,
                        int clear, int incremental, uint32_t *pindex)
@@ -31,7 +31,7 @@ int xc_readconsolering(int xc_handle,
     if ( (ret = lock_pages(buffer, nr_chars)) != 0 )
         return ret;
 
-    if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 )
+    if ( (ret = do_sysctl(xch, &sysctl)) == 0 )
     {
         *pnr_chars = sysctl.u.readconsole.count;
         if ( pindex )
@@ -43,7 +43,7 @@ int xc_readconsolering(int xc_handle,
     return ret;
 }
 
-int xc_send_debug_keys(int xc_handle, char *keys)
+int xc_send_debug_keys(xc_interface *xch, char *keys)
 {
     int ret, len = strlen(keys);
     DECLARE_SYSCTL;
@@ -55,14 +55,14 @@ int xc_send_debug_keys(int xc_handle, char *keys)
     if ( (ret = lock_pages(keys, len)) != 0 )
         return ret;
 
-    ret = do_sysctl(xc_handle, &sysctl);
+    ret = do_sysctl(xch, &sysctl);
 
     unlock_pages(keys, len);
 
     return ret;
 }
 
-int xc_physinfo(int xc_handle,
+int xc_physinfo(xc_interface *xch,
                 xc_physinfo_t *put_info)
 {
     int ret;
@@ -72,7 +72,7 @@ int xc_physinfo(int xc_handle,
 
     memcpy(&sysctl.u.physinfo, put_info, sizeof(*put_info));
 
-    if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
+    if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
         return ret;
 
     memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info));
@@ -80,7 +80,7 @@ int xc_physinfo(int xc_handle,
     return 0;
 }
 
-int xc_topologyinfo(int xc_handle,
+int xc_topologyinfo(xc_interface *xch,
                 xc_topologyinfo_t *put_info)
 {
     int ret;
@@ -90,7 +90,7 @@ int xc_topologyinfo(int xc_handle,
 
     memcpy(&sysctl.u.topologyinfo, put_info, sizeof(*put_info));
 
-    if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
+    if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
         return ret;
 
     memcpy(put_info, &sysctl.u.topologyinfo, sizeof(*put_info));
@@ -98,7 +98,7 @@ int xc_topologyinfo(int xc_handle,
     return 0;
 }
 
-int xc_numainfo(int xc_handle,
+int xc_numainfo(xc_interface *xch,
                 xc_numainfo_t *put_info)
 {
     int ret;
@@ -108,7 +108,7 @@ int xc_numainfo(int xc_handle,
 
     memcpy(&sysctl.u.numainfo, put_info, sizeof(*put_info));
 
-    if ((ret = do_sysctl(xc_handle, &sysctl)) != 0)
+    if ((ret = do_sysctl(xch, &sysctl)) != 0)
         return ret;
 
     memcpy(put_info, &sysctl.u.numainfo, sizeof(*put_info));
@@ -117,7 +117,7 @@ int xc_numainfo(int xc_handle,
 }
 
 
-int xc_sched_id(int xc_handle,
+int xc_sched_id(xc_interface *xch,
                 int *sched_id)
 {
     int ret;
@@ -125,7 +125,7 @@ int xc_sched_id(int xc_handle,
 
     sysctl.cmd = XEN_SYSCTL_sched_id;
 
-    if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 )
+    if ( (ret = do_sysctl(xch, &sysctl)) != 0 )
         return ret;
 
     *sched_id = sysctl.u.sched_id.sched_id;
@@ -134,7 +134,7 @@ int xc_sched_id(int xc_handle,
 }
 
 #if defined(__i386__) || defined(__x86_64__)
-int xc_mca_op(int xc_handle, struct xen_mc *mc)
+int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
 {
     int ret = 0;
     DECLARE_HYPERCALL;
@@ -148,13 +148,13 @@ int xc_mca_op(int xc_handle, struct xen_mc *mc)
 
     hypercall.op = __HYPERVISOR_mca;
     hypercall.arg[0] = (unsigned long)mc;
-    ret = do_xen_hypercall(xc_handle, &hypercall);
+    ret = do_xen_hypercall(xch, &hypercall);
     unlock_pages(mc, sizeof(mc));
     return ret;
 }
 #endif
 
-int xc_perfc_control(int xc_handle,
+int xc_perfc_control(xc_interface *xch,
                      uint32_t opcode,
                      xc_perfc_desc_t *desc,
                      xc_perfc_val_t *val,
@@ -169,7 +169,7 @@ int xc_perfc_control(int xc_handle,
     set_xen_guest_handle(sysctl.u.perfc_op.desc, desc);
     set_xen_guest_handle(sysctl.u.perfc_op.val, val);
 
-    rc = do_sysctl(xc_handle, &sysctl);
+    rc = do_sysctl(xch, &sysctl);
 
     if ( nbr_desc )
         *nbr_desc = sysctl.u.perfc_op.nr_counters;
@@ -179,7 +179,7 @@ int xc_perfc_control(int xc_handle,
     return rc;
 }
 
-int xc_lockprof_control(int xc_handle,
+int xc_lockprof_control(xc_interface *xch,
                         uint32_t opcode,
                         uint32_t *n_elems,
                         uint64_t *time,
@@ -193,7 +193,7 @@ int xc_lockprof_control(int xc_handle,
     sysctl.u.lockprof_op.max_elem = n_elems ? *n_elems : 0;
     set_xen_guest_handle(sysctl.u.lockprof_op.data, data);
 
-    rc = do_sysctl(xc_handle, &sysctl);
+    rc = do_sysctl(xch, &sysctl);
 
     if (n_elems)
         *n_elems = sysctl.u.lockprof_op.nr_elem;
@@ -203,7 +203,7 @@ int xc_lockprof_control(int xc_handle,
     return rc;
 }
 
-int xc_getcpuinfo(int xc_handle, int max_cpus,
+int xc_getcpuinfo(xc_interface *xch, int max_cpus,
                   xc_cpuinfo_t *info, int *nr_cpus)
 {
     int rc;
@@ -216,7 +216,7 @@ int xc_getcpuinfo(int xc_handle, int max_cpus,
     if ( (rc = lock_pages(info, max_cpus*sizeof(*info))) != 0 )
         return rc;
 
-    rc = do_sysctl(xc_handle, &sysctl);
+    rc = do_sysctl(xch, &sysctl);
 
     unlock_pages(info, max_cpus*sizeof(*info));
 
@@ -228,7 +228,7 @@ int xc_getcpuinfo(int xc_handle, int max_cpus,
 
 
 int xc_hvm_set_pci_intx_level(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
     unsigned int level)
 {
@@ -253,7 +253,7 @@ int xc_hvm_set_pci_intx_level(
     arg->intx   = intx;
     arg->level  = level;
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     hcall_buf_release((void **)&arg, sizeof(*arg));
 
@@ -261,7 +261,7 @@ int xc_hvm_set_pci_intx_level(
 }
 
 int xc_hvm_set_isa_irq_level(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint8_t isa_irq,
     unsigned int level)
 {
@@ -283,7 +283,7 @@ int xc_hvm_set_isa_irq_level(
     arg->isa_irq = isa_irq;
     arg->level   = level;
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     hcall_buf_release((void **)&arg, sizeof(*arg));
 
@@ -291,7 +291,7 @@ int xc_hvm_set_isa_irq_level(
 }
 
 int xc_hvm_set_pci_link_route(
-    int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq)
+    xc_interface *xch, domid_t dom, uint8_t link, uint8_t isa_irq)
 {
     DECLARE_HYPERCALL;
     struct xen_hvm_set_pci_link_route arg;
@@ -311,7 +311,7 @@ int xc_hvm_set_pci_link_route(
         return rc;
     }
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(&arg, sizeof(arg));
 
@@ -319,7 +319,7 @@ int xc_hvm_set_pci_link_route(
 }
 
 int xc_hvm_track_dirty_vram(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint64_t first_pfn, uint64_t nr,
     unsigned long *dirty_bitmap)
 {
@@ -342,7 +342,7 @@ int xc_hvm_track_dirty_vram(
         return rc;
     }
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(&arg, sizeof(arg));
 
@@ -350,7 +350,7 @@ int xc_hvm_track_dirty_vram(
 }
 
 int xc_hvm_modified_memory(
-    int xc_handle, domid_t dom, uint64_t first_pfn, uint64_t nr)
+    xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr)
 {
     DECLARE_HYPERCALL;
     struct xen_hvm_modified_memory arg;
@@ -370,7 +370,7 @@ int xc_hvm_modified_memory(
         return rc;
     }
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(&arg, sizeof(arg));
 
@@ -378,7 +378,7 @@ int xc_hvm_modified_memory(
 }
 
 int xc_hvm_set_mem_type(
-    int xc_handle, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, 
uint64_t nr)
+    xc_interface *xch, domid_t dom, hvmmem_type_t mem_type, uint64_t 
first_pfn, uint64_t nr)
 {
     DECLARE_HYPERCALL;
     struct xen_hvm_set_mem_type arg;
@@ -399,7 +399,7 @@ int xc_hvm_set_mem_type(
         return rc;
     }
 
-    rc = do_xen_hypercall(xc_handle, &hypercall);
+    rc = do_xen_hypercall(xch, &hypercall);
 
     unlock_pages(&arg, sizeof(arg));
 
@@ -412,7 +412,7 @@ void *
 #ifdef __GNUC__
 __attribute__((__weak__))
 #endif
-xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+xc_map_foreign_bulk(xc_interface *xch, uint32_t dom, int prot,
                     const xen_pfn_t *arr, int *err, unsigned int num)
 {
     xen_pfn_t *pfn;
@@ -431,7 +431,7 @@ xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
     }
 
     memcpy(pfn, arr, num * sizeof(*arr));
-    ret = xc_map_foreign_batch(xc_handle, dom, prot, pfn, num);
+    ret = xc_map_foreign_batch(xch, dom, prot, pfn, num);
 
     if (ret) {
         for (i = 0; i < num; ++i)
@@ -451,7 +451,7 @@ xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
     return ret;
 }
 
-void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_pages(xc_interface *xch, uint32_t dom, int prot,
                            const xen_pfn_t *arr, int num)
 {
     void *res;
@@ -466,7 +466,7 @@ void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int 
prot,
     if (!err)
         return NULL;
 
-    res = xc_map_foreign_bulk(xc_handle, dom, prot, arr, err, num);
+    res = xc_map_foreign_bulk(xch, dom, prot, arr, err, num);
     if (res) {
         for (i = 0; i < num; i++) {
             if (err[i]) {
diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c
index 951926d..b08268a 100644
--- a/tools/libxc/xc_netbsd.c
+++ b/tools/libxc/xc_netbsd.c
@@ -15,7 +15,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open(void)
+int xc_interface_open_core(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/kern/xen/privcmd", O_RDWR);
@@ -51,19 +51,19 @@ int xc_interface_open(void)
     return -1;
 }
 
-int xc_interface_close(int xc_handle)
+int xc_interface_close(xc_interface *xch, int fd)
 {
-    return close(xc_handle);
+    return close(fd);
 }
 
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
                            xen_pfn_t *arr, int num)
 {
     privcmd_mmapbatch_t ioctlx;
     void *addr;
     addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_ANON | MAP_SHARED, -1, 0);
     if ( addr == MAP_FAILED ) {
-        perror("xc_map_foreign_batch: mmap failed");
+        PERROR("xc_map_foreign_batch: mmap failed");
         return NULL;
     }
 
@@ -71,10 +71,10 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     ioctlx.dom=dom;
     ioctlx.addr=(unsigned long)addr;
     ioctlx.arr=arr;
-    if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
+    if ( ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
     {
         int saved_errno = errno;
-        perror("xc_map_foreign_batch: ioctl failed");
+        PERROR("xc_map_foreign_batch: ioctl failed");
         (void)munmap(addr, num*PAGE_SIZE);
         errno = saved_errno;
         return NULL;
@@ -83,7 +83,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
 
 }
 
-void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+void *xc_map_foreign_range(xc_interface *xch, uint32_t dom,
                            int size, int prot,
                            unsigned long mfn)
 {
@@ -92,7 +92,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     void *addr;
     addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0);
     if ( addr == MAP_FAILED ) {
-        perror("xc_map_foreign_range: mmap failed");
+        PERROR("xc_map_foreign_range: mmap failed");
         return NULL;
     }
 
@@ -102,10 +102,10 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     entry.va=(unsigned long) addr;
     entry.mfn=mfn;
     entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
-    if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
+    if ( ioctl(xch->fd, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
     {
         int saved_errno = errno;
-        perror("xc_map_foreign_range: ioctl failed");
+        PERROR("xc_map_foreign_range: ioctl failed");
         (void)munmap(addr, size);
         errno = saved_errno;
         return NULL;
@@ -113,7 +113,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     return addr;
 }
 
-void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries)
 {
@@ -134,7 +134,7 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
        ioctlx.dom   = dom;
        ioctlx.entry = entries;
 
-       rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
+       rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAP, &ioctlx);
        if (rc)
                goto ioctl_failed;
 
@@ -150,18 +150,18 @@ mmap_failed:
 }
 
 
-static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
+static int do_privcmd(xc_interface *xch, unsigned int cmd, unsigned long data)
 {
-    int err = ioctl(xc_handle, cmd, data);
+    int err = ioctl(xch->fd, cmd, data);
     if (err == 0)
        return 0;
     else
        return -errno;
 }
 
-int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
 {
-    int error = do_privcmd(xc_handle,
+    int error = do_privcmd(xch,
                       IOCTL_PRIVCMD_HYPERCALL,
                       (unsigned long)hypercall);
     if (error)
@@ -254,7 +254,7 @@ int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
 }
 
 /* Optionally flush file to disk and discard page cache */
-void discard_file_cache(int fd, int flush) 
+void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
 
     if ( flush && (fsync(fd) < 0) )
@@ -264,13 +264,13 @@ void discard_file_cache(int fd, int flush)
 }
 
 grant_entry_v1_t *xc_gnttab_map_table_v1(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
 
 grant_entry_v2_t *xc_gnttab_map_table_v2(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
index 5c90e16..b54c672 100644
--- a/tools/libxc/xc_offline_page.c
+++ b/tools/libxc/xc_offline_page.c
@@ -48,7 +48,7 @@ struct pte_backup
 static struct domain_info_context _dinfo;
 static struct domain_info_context *dinfo = &_dinfo;
 
-int xc_mark_page_online(int xc, unsigned long start,
+int xc_mark_page_online(xc_interface *xch, unsigned long start,
                         unsigned long end, uint32_t *status)
 {
     DECLARE_SYSCTL;
@@ -68,14 +68,14 @@ int xc_mark_page_online(int xc, unsigned long start,
     sysctl.u.page_offline.cmd = sysctl_page_online;
     sysctl.u.page_offline.end = end;
     set_xen_guest_handle(sysctl.u.page_offline.status, status);
-    ret = xc_sysctl(xc, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     unlock_pages(status, sizeof(uint32_t)*(end - start + 1));
 
     return ret;
 }
 
-int xc_mark_page_offline(int xc, unsigned long start,
+int xc_mark_page_offline(xc_interface *xch, unsigned long start,
                           unsigned long end, uint32_t *status)
 {
     DECLARE_SYSCTL;
@@ -95,14 +95,14 @@ int xc_mark_page_offline(int xc, unsigned long start,
     sysctl.u.page_offline.cmd = sysctl_page_offline;
     sysctl.u.page_offline.end = end;
     set_xen_guest_handle(sysctl.u.page_offline.status, status);
-    ret = xc_sysctl(xc, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     unlock_pages(status, sizeof(uint32_t)*(end - start + 1));
 
     return ret;
 }
 
-int xc_query_page_offline_status(int xc, unsigned long start,
+int xc_query_page_offline_status(xc_interface *xch, unsigned long start,
                                  unsigned long end, uint32_t *status)
 {
     DECLARE_SYSCTL;
@@ -122,7 +122,7 @@ int xc_query_page_offline_status(int xc, unsigned long 
start,
     sysctl.u.page_offline.cmd = sysctl_query_page_offline;
     sysctl.u.page_offline.end = end;
     set_xen_guest_handle(sysctl.u.page_offline.status, status);
-    ret = xc_sysctl(xc, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     unlock_pages(status, sizeof(uint32_t)*(end - start + 1));
 
@@ -132,7 +132,7 @@ int xc_query_page_offline_status(int xc, unsigned long 
start,
  /*
   * There should no update to the grant when domain paused
   */
-static int xc_is_page_granted_v1(int xc_handle, xen_pfn_t gpfn,
+static int xc_is_page_granted_v1(xc_interface *xch, xen_pfn_t gpfn,
                                  grant_entry_v1_t *gnttab, int gnt_num)
 {
     int i = 0;
@@ -148,7 +148,7 @@ static int xc_is_page_granted_v1(int xc_handle, xen_pfn_t 
gpfn,
    return (i != gnt_num);
 }
 
-static int xc_is_page_granted_v2(int xc_handle, xen_pfn_t gpfn,
+static int xc_is_page_granted_v2(xc_interface *xch, xen_pfn_t gpfn,
                                  grant_entry_v2_t *gnttab, int gnt_num)
 {
     int i = 0;
@@ -173,21 +173,21 @@ static xen_pfn_t pfn_to_mfn(xen_pfn_t pfn, xen_pfn_t 
*p2m, int gwidth)
                             (((uint32_t *)p2m)[(pfn)]))));
 }
 
-static int get_pt_level(int xc_handle, uint32_t domid,
+static int get_pt_level(xc_interface *xch, uint32_t domid,
                         unsigned int *pt_level,
                         unsigned int *gwidth)
 {
     DECLARE_DOMCTL;
     xen_capabilities_info_t xen_caps = "";
 
-    if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
+    if (xc_version(xch, XENVER_capabilities, &xen_caps) != 0)
         return -1;
 
     memset(&domctl, 0, sizeof(domctl));
     domctl.domain = domid;
     domctl.cmd = XEN_DOMCTL_get_address_size;
 
-    if ( do_domctl(xc_handle, &domctl) != 0 )
+    if ( do_domctl(xch, &domctl) != 0 )
         return -1;
 
     *gwidth = domctl.u.address_size.size / 8;
@@ -205,7 +205,7 @@ static int get_pt_level(int xc_handle, uint32_t domid,
     return 0;
 }
 
-static int close_mem_info(int xc_handle, struct domain_mem_info *minfo)
+static int close_mem_info(xc_interface *xch, struct domain_mem_info *minfo)
 {
     if (minfo->pfn_type)
         free(minfo->pfn_type);
@@ -216,7 +216,7 @@ static int close_mem_info(int xc_handle, struct 
domain_mem_info *minfo)
     return 0;
 }
 
-static int init_mem_info(int xc_handle, int domid,
+static int init_mem_info(xc_interface *xch, int domid,
                  struct domain_mem_info *minfo,
                  xc_dominfo_t *info)
 {
@@ -228,7 +228,7 @@ static int init_mem_info(int xc_handle, int domid,
     if (minfo->pfn_type || minfo->m2p_table || minfo->p2m_table)
         return -EINVAL;
 
-    if ( get_pt_level(xc_handle, domid, &minfo->pt_level,
+    if ( get_pt_level(xch, domid, &minfo->pt_level,
                       &minfo->guest_width) )
     {
         ERROR("Unable to get PT level info.");
@@ -238,7 +238,7 @@ static int init_mem_info(int xc_handle, int domid,
 
     shared_info_frame = info->shared_info_frame;
 
-    live_shinfo = xc_map_foreign_range(xc_handle, domid,
+    live_shinfo = xc_map_foreign_range(xch, domid,
                      PAGE_SIZE, PROT_READ, shared_info_frame);
     if ( !live_shinfo )
     {
@@ -246,7 +246,7 @@ static int init_mem_info(int xc_handle, int domid,
         return -EFAULT;
     }
 
-    if ( (rc = xc_core_arch_map_p2m_writable(xc_handle, minfo->guest_width,
+    if ( (rc = xc_core_arch_map_p2m_writable(xch, minfo->guest_width,
               info, live_shinfo, &minfo->p2m_table,  &minfo->p2m_size)) )
     {
         ERROR("Couldn't map p2m table %x\n", rc);
@@ -257,9 +257,9 @@ static int init_mem_info(int xc_handle, int domid,
 
     dinfo->p2m_size = minfo->p2m_size;
 
-    minfo->max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL);
+    minfo->max_mfn = xc_memory_op(xch, XENMEM_maximum_ram_page, NULL);
     if ( !(minfo->m2p_table =
-        xc_map_m2p(xc_handle, minfo->max_mfn, PROT_READ, NULL)) )
+        xc_map_m2p(xch, minfo->max_mfn, PROT_READ, NULL)) )
     {
         ERROR("Failed to map live M2P table");
         goto failed;
@@ -286,7 +286,7 @@ static int init_mem_info(int xc_handle, int domid,
     for (i = 0; i < minfo->p2m_size ; i+=1024)
     {
         int count = ((dinfo->p2m_size - i ) > 1024 ) ? 1024: (dinfo->p2m_size 
- i);
-        if ( ( rc = xc_get_pfn_type_batch(xc_handle, domid, count,
+        if ( ( rc = xc_get_pfn_type_batch(xch, domid, count,
                   minfo->pfn_type + i)) )
         {
             ERROR("Failed to get pfn_type %x\n", rc);
@@ -340,12 +340,14 @@ static int backup_ptes(xen_pfn_t table_mfn, int offset,
  * 0 when no changes
  * <0 when error happen
  */
-typedef int (*pte_func)(uint64_t pte, uint64_t *new_pte,
+typedef int (*pte_func)(xc_interface *xch,
+                       uint64_t pte, uint64_t *new_pte,
                        unsigned long table_mfn, int table_offset,
                        struct pte_backup *backup,
                        unsigned long no_use);
 
-static int __clear_pte(uint64_t pte, uint64_t *new_pte,
+static int __clear_pte(xc_interface *xch,
+                       uint64_t pte, uint64_t *new_pte,
                        unsigned long table_mfn, int table_offset,
                        struct pte_backup *backup,
                        unsigned long mfn)
@@ -369,7 +371,8 @@ static int __clear_pte(uint64_t pte, uint64_t *new_pte,
     return 0;
 }
 
-static int __update_pte(uint64_t pte, uint64_t *new_pte,
+static int __update_pte(xc_interface *xch,
+                      uint64_t pte, uint64_t *new_pte,
                       unsigned long table_mfn, int table_offset,
                       struct pte_backup *backup,
                       unsigned long new_mfn)
@@ -397,7 +400,7 @@ static int __update_pte(uint64_t pte, uint64_t *new_pte,
     return 0;
 }
 
-static int change_pte(int xc_handle, int domid,
+static int change_pte(xc_interface *xch, int domid,
                      struct domain_mem_info *minfo,
                      struct pte_backup *backup,
                      struct xc_mmu *mmu,
@@ -424,7 +427,7 @@ static int change_pte(int xc_handle, int domid,
 
         if ( minfo->pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK )
         {
-            content = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+            content = xc_map_foreign_range(xch, domid, PAGE_SIZE,
                                             PROT_READ, table_mfn);
             if (!content)
                 goto failed;
@@ -436,12 +439,12 @@ static int change_pte(int xc_handle, int domid,
                 else
                     pte = ((const uint64_t*)content)[j];
 
-                rc = func(pte, &new_pte, table_mfn, j, backup, data);
+                rc = func(xch, pte, &new_pte, table_mfn, j, backup, data);
 
                 switch (rc)
                 {
                     case 1:
-                    if ( xc_add_mmu_update(xc_handle, mmu,
+                    if ( xc_add_mmu_update(xch, mmu,
                           table_mfn << PAGE_SHIFT |
                           j * ( (minfo->pt_level == 2) ?
                               sizeof(uint32_t): sizeof(uint64_t)) |
@@ -463,7 +466,7 @@ static int change_pte(int xc_handle, int domid,
         content = NULL;
     }
 
-    if ( xc_flush_mmu_updates(xc_handle, mmu) )
+    if ( xc_flush_mmu_updates(xch, mmu) )
         goto failed;
 
     return 0;
@@ -475,27 +478,27 @@ failed:
     return -1;
 }
 
-static int update_pte(int xc_handle, int domid,
+static int update_pte(xc_interface *xch, int domid,
                      struct domain_mem_info *minfo,
                      struct pte_backup *backup,
                      struct xc_mmu *mmu,
                      unsigned long new_mfn)
 {
-    return change_pte(xc_handle, domid,  minfo, backup, mmu,
+    return change_pte(xch, domid,  minfo, backup, mmu,
                       __update_pte, new_mfn);
 }
 
-static int clear_pte(int xc_handle, int domid,
+static int clear_pte(xc_interface *xch, int domid,
                      struct domain_mem_info *minfo,
                      struct pte_backup *backup,
                      struct xc_mmu *mmu,
                      xen_pfn_t mfn)
 {
-    return change_pte(xc_handle, domid, minfo, backup, mmu,
+    return change_pte(xch, domid, minfo, backup, mmu,
                       __clear_pte, mfn);
 }
 
-static int exchange_page(int xc_handle, xen_pfn_t mfn,
+static int exchange_page(xc_interface *xch, xen_pfn_t mfn,
                      xen_pfn_t *new_mfn, int domid)
 {
     int rc;
@@ -516,7 +519,7 @@ static int exchange_page(int xc_handle, xen_pfn_t mfn,
     set_xen_guest_handle(exchange.in.extent_start, &mfn);
     set_xen_guest_handle(exchange.out.extent_start, &out_mfn);
 
-    rc = xc_memory_op(xc_handle, XENMEM_exchange, &exchange);
+    rc = xc_memory_op(xch, XENMEM_exchange, &exchange);
 
     if (!rc)
         *new_mfn = out_mfn;
@@ -528,7 +531,7 @@ static int exchange_page(int xc_handle, xen_pfn_t mfn,
  * Check if a page can be exchanged successfully
  */
 
-static int is_page_exchangable(int xc_handle, int domid, xen_pfn_t mfn,
+static int is_page_exchangable(xc_interface *xch, int domid, xen_pfn_t mfn,
                                xc_dominfo_t *info)
 {
     uint32_t status;
@@ -547,7 +550,7 @@ static int is_page_exchangable(int xc_handle, int domid, 
xen_pfn_t mfn,
     }
 
     /* Check if pages are offline pending or not */
-    rc = xc_query_page_offline_status(xc_handle, mfn, mfn, &status);
+    rc = xc_query_page_offline_status(xch, mfn, mfn, &status);
 
     if ( rc || !(status & PG_OFFLINE_STATUS_OFFLINE_PENDING) )
     {
@@ -560,7 +563,7 @@ static int is_page_exchangable(int xc_handle, int domid, 
xen_pfn_t mfn,
 }
 
 /* The domain should be suspended when called here */
-int xc_exchange_page(int xc_handle, int domid, xen_pfn_t mfn)
+int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
 {
     xc_dominfo_t info;
     struct domain_mem_info minfo;
@@ -575,7 +578,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     uint32_t status;
     xen_pfn_t new_mfn, gpfn;
 
-    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
     {
         ERROR("Could not get domain info");
         return -EFAULT;
@@ -587,7 +590,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
         return -EINVAL;
     }
 
-    if (!is_page_exchangable(xc_handle, domid, mfn, &info))
+    if (!is_page_exchangable(xch, domid, mfn, &info))
     {
         ERROR("Could not exchange page\n");
         return -EINVAL;
@@ -595,7 +598,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
 
     /* Get domain's memory information */
     memset(&minfo, 0, sizeof(minfo));
-    init_mem_info(xc_handle, domid, &minfo, &info);
+    init_mem_info(xch, domid, &minfo, &info);
     gpfn = minfo.m2p_table[mfn];
 
     /* Don't exchange CR3 for PAE guest in PAE host environment */
@@ -606,10 +609,10 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
             goto failed;
     }
 
-    gnttab_v2 = xc_gnttab_map_table_v2(xc_handle, domid, &gnt_num);
+    gnttab_v2 = xc_gnttab_map_table_v2(xch, domid, &gnt_num);
     if (!gnttab_v2)
     {
-        gnttab_v1 = xc_gnttab_map_table_v1(xc_handle, domid, &gnt_num);
+        gnttab_v1 = xc_gnttab_map_table_v1(xch, domid, &gnt_num);
         if (!gnttab_v1)
         {
             ERROR("Failed to map grant table\n");
@@ -618,8 +621,8 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     }
 
     if (gnttab_v1
-        ? xc_is_page_granted_v1(xc_handle, mfn, gnttab_v1, gnt_num)
-        : xc_is_page_granted_v2(xc_handle, mfn, gnttab_v2, gnt_num))
+        ? xc_is_page_granted_v1(xch, mfn, gnttab_v1, gnt_num)
+        : xc_is_page_granted_v2(xch, mfn, gnttab_v2, gnt_num))
     {
         ERROR("Page %lx is granted now\n", mfn);
         goto failed;
@@ -650,7 +653,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
         mops.cmd = MMUEXT_UNPIN_TABLE;
         mops.arg1.mfn = mfn;
 
-        if ( xc_mmuext_op(xc_handle, &mops, 1, domid) < 0 )
+        if ( xc_mmuext_op(xch, &mops, 1, domid) < 0 )
         {
             ERROR("Failed to unpin page %lx", mfn);
             goto failed;
@@ -660,7 +663,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     }
 
     /* backup the content */
-    old_p = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    old_p = xc_map_foreign_range(xch, domid, PAGE_SIZE,
       PROT_READ, mfn);
     if (!old_p)
     {
@@ -671,7 +674,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     memcpy(backup, old_p, PAGE_SIZE);
     munmap(old_p, PAGE_SIZE);
 
-    mmu = xc_alloc_mmu_updates(xc_handle, domid);
+    mmu = xc_alloc_mmu_updates(xch, domid);
     if ( mmu == NULL )
     {
         ERROR("%s: failed at %d\n", __FUNCTION__, __LINE__);
@@ -679,7 +682,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     }
 
     /* Firstly update all pte to be invalid to remove the reference */
-    rc = clear_pte(xc_handle, domid,  &minfo, &old_ptes, mmu, mfn);
+    rc = clear_pte(xch, domid,  &minfo, &old_ptes, mmu, mfn);
 
     if (rc)
     {
@@ -687,19 +690,19 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
         goto failed;
     }
 
-    rc = exchange_page(xc_handle, mfn, &new_mfn, domid);
+    rc = exchange_page(xch, mfn, &new_mfn, domid);
 
     if (rc)
     {
         ERROR("Exchange the page failed\n");
         /* Exchange fail means there are refere to the page still */
-        rc = update_pte(xc_handle, domid, &minfo, &old_ptes, mmu, mfn);
+        rc = update_pte(xch, domid, &minfo, &old_ptes, mmu, mfn);
         if (rc)
             result = -2;
         goto failed;
     }
 
-    rc = update_pte(xc_handle, domid, &minfo, &old_ptes, mmu, new_mfn);
+    rc = update_pte(xch, domid, &minfo, &old_ptes, mmu, new_mfn);
 
     if (rc)
     {
@@ -710,7 +713,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
     }
 
     /* Check if pages are offlined already */
-    rc = xc_query_page_offline_status(xc_handle, mfn, mfn,
+    rc = xc_query_page_offline_status(xch, mfn, mfn,
                             &status);
 
     if (rc)
@@ -728,7 +731,7 @@ int xc_exchange_page(int xc_handle, int domid, xen_pfn_t 
mfn)
         /* Update the p2m table */
         minfo.p2m_table[gpfn] = new_mfn;
 
-        new_p = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+        new_p = xc_map_foreign_range(xch, domid, PAGE_SIZE,
                                      PROT_READ|PROT_WRITE, new_mfn);
         memcpy(new_p, backup, PAGE_SIZE);
         munmap(new_p, PAGE_SIZE);
@@ -763,7 +766,7 @@ failed:
                 break;
         }
 
-        if ( xc_mmuext_op(xc_handle, &mops, 1, domid) < 0 )
+        if ( xc_mmuext_op(xch, &mops, 1, domid) < 0 )
         {
             ERROR("failed to pin the mfn again\n");
             result = -2;
@@ -784,7 +787,7 @@ failed:
     if (gnttab_v2)
         munmap(gnttab_v2, gnt_num / (PAGE_SIZE/sizeof(grant_entry_v2_t)));
 
-    close_mem_info(xc_handle, &minfo);
+    close_mem_info(xch, &minfo);
 
     return result;
 }
diff --git a/tools/libxc/xc_pagetab.c b/tools/libxc/xc_pagetab.c
index 1a4a3d0..615285b 100644
--- a/tools/libxc/xc_pagetab.c
+++ b/tools/libxc/xc_pagetab.c
@@ -12,7 +12,7 @@
 #define EFER_LMA 0x400
 
 
-unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
+unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
                                            int vcpu, unsigned long long virt)
 {
     xc_dominfo_t dominfo;
@@ -20,14 +20,14 @@ unsigned long xc_translate_foreign_address(int xc_handle, 
uint32_t dom,
     int size, level, pt_levels = 2;
     void *map;
 
-    if (xc_domain_getinfo(xc_handle, dom, 1, &dominfo) != 1 
+    if (xc_domain_getinfo(xch, dom, 1, &dominfo) != 1 
         || dominfo.domid != dom)
         return 0;
 
     /* What kind of paging are we dealing with? */
     if (dominfo.hvm) {
         struct hvm_hw_cpu ctx;
-        if (xc_domain_hvm_getcontext_partial(xc_handle, dom,
+        if (xc_domain_hvm_getcontext_partial(xch, dom,
                                              HVM_SAVE_CODE(CPU), vcpu,
                                              &ctx, sizeof ctx) != 0)
             return 0;
@@ -38,11 +38,11 @@ unsigned long xc_translate_foreign_address(int xc_handle, 
uint32_t dom,
     } else {
         DECLARE_DOMCTL;
         vcpu_guest_context_any_t ctx;
-        if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0)
+        if (xc_vcpu_getcontext(xch, dom, vcpu, &ctx) != 0)
             return 0;
         domctl.domain = dom;
         domctl.cmd = XEN_DOMCTL_get_address_size;
-        if ( do_domctl(xc_handle, &domctl) != 0 )
+        if ( do_domctl(xch, &domctl) != 0 )
             return 0;
         if (domctl.u.address_size.size == 64) {
             pt_levels = 4;
@@ -69,7 +69,7 @@ unsigned long xc_translate_foreign_address(int xc_handle, 
uint32_t dom,
     /* Walk the pagetables */
     for (level = pt_levels; level > 0; level--) {
         paddr += ((virt & mask) >> (xc_ffs64(mask) - 1)) * size;
-        map = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ, 
+        map = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_READ, 
                                    paddr >>PAGE_SHIFT);
         if (!map) 
             return 0;
diff --git a/tools/libxc/xc_physdev.c b/tools/libxc/xc_physdev.c
index dd484a1..b412c7b 100644
--- a/tools/libxc/xc_physdev.c
+++ b/tools/libxc/xc_physdev.c
@@ -9,7 +9,7 @@
 
 #include "xc_private.h"
 
-int xc_physdev_pci_access_modify(int xc_handle,
+int xc_physdev_pci_access_modify(xc_interface *xch,
                                  uint32_t domid,
                                  int bus,
                                  int dev,
@@ -20,7 +20,7 @@ int xc_physdev_pci_access_modify(int xc_handle,
     return -1;
 }
 
-int xc_physdev_map_pirq(int xc_handle,
+int xc_physdev_map_pirq(xc_interface *xch,
                         int domid,
                         int index,
                         int *pirq)
@@ -37,7 +37,7 @@ int xc_physdev_map_pirq(int xc_handle,
     map.index = index;
     map.pirq = *pirq;
 
-    rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map, sizeof(map));
+    rc = do_physdev_op(xch, PHYSDEVOP_map_pirq, &map, sizeof(map));
 
     if ( !rc )
         *pirq = map.pirq;
@@ -45,7 +45,7 @@ int xc_physdev_map_pirq(int xc_handle,
     return rc;
 }
 
-int xc_physdev_map_pirq_msi(int xc_handle,
+int xc_physdev_map_pirq_msi(xc_interface *xch,
                             int domid,
                             int index,
                             int *pirq,
@@ -70,7 +70,7 @@ int xc_physdev_map_pirq_msi(int xc_handle,
     map.entry_nr = entry_nr;
     map.table_base = table_base;
 
-    rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map, sizeof(map));
+    rc = do_physdev_op(xch, PHYSDEVOP_map_pirq, &map, sizeof(map));
 
     if ( !rc )
         *pirq = map.pirq;
@@ -78,7 +78,7 @@ int xc_physdev_map_pirq_msi(int xc_handle,
     return rc;
 }
 
-int xc_physdev_unmap_pirq(int xc_handle,
+int xc_physdev_unmap_pirq(xc_interface *xch,
                           int domid,
                           int pirq)
 {
@@ -89,7 +89,7 @@ int xc_physdev_unmap_pirq(int xc_handle,
     unmap.domid = domid;
     unmap.pirq = pirq;
 
-    rc = do_physdev_op(xc_handle, PHYSDEVOP_unmap_pirq, &unmap, sizeof(unmap));
+    rc = do_physdev_op(xch, PHYSDEVOP_unmap_pirq, &unmap, sizeof(unmap));
 
     return rc;
 }
diff --git a/tools/libxc/xc_pm.c b/tools/libxc/xc_pm.c
index e979ba1..4d32934 100644
--- a/tools/libxc/xc_pm.c
+++ b/tools/libxc/xc_pm.c
@@ -30,7 +30,7 @@
 /*
  * Get PM statistic info
  */
-int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px)
+int xc_pm_get_max_px(xc_interface *xch, int cpuid, int *max_px)
 {
     DECLARE_SYSCTL;
     int ret;
@@ -38,7 +38,7 @@ int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px)
     sysctl.cmd = XEN_SYSCTL_get_pmstat;
     sysctl.u.get_pmstat.type = PMSTAT_get_max_px;
     sysctl.u.get_pmstat.cpuid = cpuid;
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
     if ( ret )
         return ret;
 
@@ -46,7 +46,7 @@ int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px)
     return ret;
 }
 
-int xc_pm_get_pxstat(int xc_handle, int cpuid, struct xc_px_stat *pxpt)
+int xc_pm_get_pxstat(xc_interface *xch, int cpuid, struct xc_px_stat *pxpt)
 {
     DECLARE_SYSCTL;
     int max_px, ret;
@@ -54,7 +54,7 @@ int xc_pm_get_pxstat(int xc_handle, int cpuid, struct 
xc_px_stat *pxpt)
     if ( !pxpt || !(pxpt->trans_pt) || !(pxpt->pt) )
         return -EINVAL;
 
-    if ( (ret = xc_pm_get_max_px(xc_handle, cpuid, &max_px)) != 0)
+    if ( (ret = xc_pm_get_max_px(xch, cpuid, &max_px)) != 0)
         return ret;
 
     if ( (ret = lock_pages(pxpt->trans_pt, 
@@ -76,7 +76,7 @@ int xc_pm_get_pxstat(int xc_handle, int cpuid, struct 
xc_px_stat *pxpt)
     set_xen_guest_handle(sysctl.u.get_pmstat.u.getpx.pt, 
                         (pm_px_val_t *)pxpt->pt);
 
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
     if ( ret )
     {
         unlock_pages(pxpt->trans_pt, max_px * max_px * sizeof(uint64_t));
@@ -95,7 +95,7 @@ int xc_pm_get_pxstat(int xc_handle, int cpuid, struct 
xc_px_stat *pxpt)
     return ret;
 }
 
-int xc_pm_reset_pxstat(int xc_handle, int cpuid)
+int xc_pm_reset_pxstat(xc_interface *xch, int cpuid)
 {
     DECLARE_SYSCTL;
 
@@ -103,10 +103,10 @@ int xc_pm_reset_pxstat(int xc_handle, int cpuid)
     sysctl.u.get_pmstat.type = PMSTAT_reset_pxstat;
     sysctl.u.get_pmstat.cpuid = cpuid;
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
-int xc_pm_get_max_cx(int xc_handle, int cpuid, int *max_cx)
+int xc_pm_get_max_cx(xc_interface *xch, int cpuid, int *max_cx)
 {
     DECLARE_SYSCTL;
     int ret = 0;
@@ -114,14 +114,14 @@ int xc_pm_get_max_cx(int xc_handle, int cpuid, int 
*max_cx)
     sysctl.cmd = XEN_SYSCTL_get_pmstat;
     sysctl.u.get_pmstat.type = PMSTAT_get_max_cx;
     sysctl.u.get_pmstat.cpuid = cpuid;
-    if ( (ret = xc_sysctl(xc_handle, &sysctl)) != 0 )
+    if ( (ret = xc_sysctl(xch, &sysctl)) != 0 )
         return ret;
 
     *max_cx = sysctl.u.get_pmstat.u.getcx.nr;
     return ret;
 }
 
-int xc_pm_get_cxstat(int xc_handle, int cpuid, struct xc_cx_stat *cxpt)
+int xc_pm_get_cxstat(xc_interface *xch, int cpuid, struct xc_cx_stat *cxpt)
 {
     DECLARE_SYSCTL;
     int max_cx, ret;
@@ -129,7 +129,7 @@ int xc_pm_get_cxstat(int xc_handle, int cpuid, struct 
xc_cx_stat *cxpt)
     if( !cxpt || !(cxpt->triggers) || !(cxpt->residencies) )
         return -EINVAL;
 
-    if ( (ret = xc_pm_get_max_cx(xc_handle, cpuid, &max_cx)) )
+    if ( (ret = xc_pm_get_max_cx(xch, cpuid, &max_cx)) )
         goto unlock_0;
 
     if ( (ret = lock_pages(cxpt, sizeof(struct xc_cx_stat))) )
@@ -146,7 +146,7 @@ int xc_pm_get_cxstat(int xc_handle, int cpuid, struct 
xc_cx_stat *cxpt)
     set_xen_guest_handle(sysctl.u.get_pmstat.u.getcx.residencies, 
                          cxpt->residencies);
 
-    if ( (ret = xc_sysctl(xc_handle, &sysctl)) )
+    if ( (ret = xc_sysctl(xch, &sysctl)) )
         goto unlock_3;
 
     cxpt->nr = sysctl.u.get_pmstat.u.getcx.nr;
@@ -163,7 +163,7 @@ unlock_0:
     return ret;
 }
 
-int xc_pm_reset_cxstat(int xc_handle, int cpuid)
+int xc_pm_reset_cxstat(xc_interface *xch, int cpuid)
 {
     DECLARE_SYSCTL;
 
@@ -171,7 +171,7 @@ int xc_pm_reset_cxstat(int xc_handle, int cpuid)
     sysctl.u.get_pmstat.type = PMSTAT_reset_cxstat;
     sysctl.u.get_pmstat.cpuid = cpuid;
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
 
@@ -179,7 +179,7 @@ int xc_pm_reset_cxstat(int xc_handle, int cpuid)
  * 1. Get PM parameter
  * 2. Provide user PM control
  */
-int xc_get_cpufreq_para(int xc_handle, int cpuid,
+int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
                         struct xc_get_cpufreq_para *user_para)
 {
     DECLARE_SYSCTL;
@@ -189,7 +189,7 @@ int xc_get_cpufreq_para(int xc_handle, int cpuid,
                      user_para->freq_num &&
                      user_para->gov_num;
 
-    if ( (xc_handle < 0) || !user_para )
+    if ( (xch < 0) || !user_para )
         return -EINVAL;
 
     if ( has_num )
@@ -224,7 +224,7 @@ int xc_get_cpufreq_para(int xc_handle, int cpuid,
     sys_para->freq_num = user_para->freq_num;
     sys_para->gov_num  = user_para->gov_num;
 
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
     if ( ret )
     {
         if ( errno == EAGAIN )
@@ -274,12 +274,12 @@ unlock_1:
     return ret;
 }
 
-int xc_set_cpufreq_gov(int xc_handle, int cpuid, char *govname)
+int xc_set_cpufreq_gov(xc_interface *xch, int cpuid, char *govname)
 {
     DECLARE_SYSCTL;
     char *scaling_governor = sysctl.u.pm_op.u.set_gov.scaling_governor;
 
-    if ( (xc_handle < 0) || (!govname) )
+    if ( (xch < 0) || (!govname) )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
@@ -288,15 +288,15 @@ int xc_set_cpufreq_gov(int xc_handle, int cpuid, char 
*govname)
     strncpy(scaling_governor, govname, CPUFREQ_NAME_LEN);
     scaling_governor[CPUFREQ_NAME_LEN - 1] = '\0';
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
-int xc_set_cpufreq_para(int xc_handle, int cpuid, 
+int xc_set_cpufreq_para(xc_interface *xch, int cpuid, 
                         int ctrl_type, int ctrl_value)
 {
     DECLARE_SYSCTL;
 
-    if ( xc_handle < 0 )
+    if ( xch < 0 )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
@@ -305,21 +305,21 @@ int xc_set_cpufreq_para(int xc_handle, int cpuid,
     sysctl.u.pm_op.u.set_para.ctrl_type = ctrl_type;
     sysctl.u.pm_op.u.set_para.ctrl_value = ctrl_value;
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
-int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq)
+int xc_get_cpufreq_avgfreq(xc_interface *xch, int cpuid, int *avg_freq)
 {
     int ret = 0;
     DECLARE_SYSCTL;
 
-    if ( (xc_handle < 0) || (!avg_freq) )
+    if ( (xch < 0) || (!avg_freq) )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
     sysctl.u.pm_op.cmd = GET_CPUFREQ_AVGFREQ;
     sysctl.u.pm_op.cpuid = cpuid;
-    ret = xc_sysctl(xc_handle, &sysctl);
+    ret = xc_sysctl(xch, &sysctl);
 
     *avg_freq = sysctl.u.pm_op.u.get_avgfreq;
 
@@ -329,7 +329,7 @@ int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int 
*avg_freq)
 /* value:   0 - disable sched_smt_power_savings 
             1 - enable sched_smt_power_savings
  */
-int xc_set_sched_opt_smt(int xc_handle, uint32_t value)
+int xc_set_sched_opt_smt(xc_interface *xch, uint32_t value)
 {
    int rc;
    DECLARE_SYSCTL;
@@ -338,12 +338,12 @@ int xc_set_sched_opt_smt(int xc_handle, uint32_t value)
    sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_sched_opt_smt;
    sysctl.u.pm_op.cpuid = 0;
    sysctl.u.pm_op.u.set_sched_opt_smt = value;
-   rc = do_sysctl(xc_handle, &sysctl);
+   rc = do_sysctl(xch, &sysctl);
 
    return rc;
 }
 
-int xc_set_vcpu_migration_delay(int xc_handle, uint32_t value)
+int xc_set_vcpu_migration_delay(xc_interface *xch, uint32_t value)
 {
    int rc;
    DECLARE_SYSCTL;
@@ -352,12 +352,12 @@ int xc_set_vcpu_migration_delay(int xc_handle, uint32_t 
value)
    sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_vcpu_migration_delay;
    sysctl.u.pm_op.cpuid = 0;
    sysctl.u.pm_op.u.set_vcpu_migration_delay = value;
-   rc = do_sysctl(xc_handle, &sysctl);
+   rc = do_sysctl(xch, &sysctl);
 
    return rc;
 }
 
-int xc_get_vcpu_migration_delay(int xc_handle, uint32_t *value)
+int xc_get_vcpu_migration_delay(xc_interface *xch, uint32_t *value)
 {
    int rc;
    DECLARE_SYSCTL;
@@ -365,7 +365,7 @@ int xc_get_vcpu_migration_delay(int xc_handle, uint32_t 
*value)
    sysctl.cmd = XEN_SYSCTL_pm_op;
    sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_vcpu_migration_delay;
    sysctl.u.pm_op.cpuid = 0;
-   rc = do_sysctl(xc_handle, &sysctl);
+   rc = do_sysctl(xch, &sysctl);
 
    if (!rc && value)
        *value = sysctl.u.pm_op.u.get_vcpu_migration_delay;
@@ -373,29 +373,29 @@ int xc_get_vcpu_migration_delay(int xc_handle, uint32_t 
*value)
    return rc;
 }
 
-int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value)
+int xc_get_cpuidle_max_cstate(xc_interface *xch, uint32_t *value)
 {
     int rc;
     DECLARE_SYSCTL;
 
-    if ( xc_handle < 0 || !value )
+    if ( xch < 0 || !value )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
     sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_max_cstate;
     sysctl.u.pm_op.cpuid = 0;
     sysctl.u.pm_op.u.get_max_cstate = 0;
-    rc = do_sysctl(xc_handle, &sysctl);
+    rc = do_sysctl(xch, &sysctl);
     *value = sysctl.u.pm_op.u.get_max_cstate;
 
     return rc;
 }
 
-int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value)
+int xc_set_cpuidle_max_cstate(xc_interface *xch, uint32_t value)
 {
     DECLARE_SYSCTL;
 
-    if ( xc_handle < 0 )
+    if ( xch < 0 )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
@@ -403,31 +403,31 @@ int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t 
value)
     sysctl.u.pm_op.cpuid = 0;
     sysctl.u.pm_op.u.set_max_cstate = value;
 
-    return do_sysctl(xc_handle, &sysctl);
+    return do_sysctl(xch, &sysctl);
 }
 
-int xc_enable_turbo(int xc_handle, int cpuid)
+int xc_enable_turbo(xc_interface *xch, int cpuid)
 {
     DECLARE_SYSCTL;
 
-    if ( xc_handle < 0 )
+    if ( xch < 0 )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
     sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_enable_turbo;
     sysctl.u.pm_op.cpuid = cpuid;
-    return do_sysctl(xc_handle, &sysctl);
+    return do_sysctl(xch, &sysctl);
 }
 
-int xc_disable_turbo(int xc_handle, int cpuid)
+int xc_disable_turbo(xc_interface *xch, int cpuid)
 {
     DECLARE_SYSCTL;
 
-    if ( xc_handle < 0 )
+    if ( xch < 0 )
         return -EINVAL;
 
     sysctl.cmd = XEN_SYSCTL_pm_op;
     sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_disable_turbo;
     sysctl.u.pm_op.cpuid = cpuid;
-    return do_sysctl(xc_handle, &sysctl);
+    return do_sysctl(xch, &sysctl);
 }
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index aaa1a39..9bcf175 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -7,70 +7,83 @@
 #include <inttypes.h>
 #include "xc_private.h"
 #include "xg_private.h"
+#include "xc_dom.h"
 #include <stdarg.h>
 #include <stdlib.h>
 #include <malloc.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <assert.h>
+
+xc_interface *xc_interface_open(xentoollog_logger *logger,
+                                xentoollog_logger *dombuild_logger,
+                                unsigned open_flags) {
+    xc_interface xch_buf, *xch = &xch_buf;
+
+    xch->fd = -1;
+    xch->dombuild_logger_file = 0;
+    xc_clear_last_error(xch);
+
+    xch->error_handler   = logger;           xch->error_handler_tofree   = 0;
+    xch->dombuild_logger = dombuild_logger;  xch->dombuild_logger_tofree = 0;
+
+    if (!xch->error_handler) {
+        xch->error_handler = xch->error_handler_tofree =
+            (xentoollog_logger*)
+            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+        if (!xch->error_handler)
+            goto err;
+    }
 
-static pthread_key_t last_error_pkey;
-static pthread_once_t last_error_pkey_once = PTHREAD_ONCE_INIT;
-
-static pthread_key_t errbuf_pkey;
-static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT;
-
-#if DEBUG
-static xc_error_handler error_handler = xc_default_error_handler;
-#else
-static xc_error_handler error_handler = NULL;
-#endif
+    xch = malloc(sizeof(*xch));
+    if (!xch) {
+        xch = &xch_buf;
+        PERROR("Could not allocate new xc_interface struct");
+        goto err;
+    }
+    *xch = xch_buf;
 
-void xc_default_error_handler(const xc_error *err)
-{
-    const char *desc = xc_error_code_to_desc(err->code);
-    fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
-}
+    if (!(open_flags & XC_OPENFLAG_DUMMY)) {
+        xch->fd = xc_interface_open_core(xch);
+        if (xch->fd < 0)
+            goto err;
+    }
 
-static void
-_xc_clean_last_error(void *m)
-{
-    free(m);
-    pthread_setspecific(last_error_pkey, NULL);
-}
+    return xch;
 
-static void
-_xc_init_last_error(void)
-{
-    pthread_key_create(&last_error_pkey, _xc_clean_last_error);
+ err:
+    if (xch) xtl_logger_destroy(xch->error_handler);
+    if (xch != &xch_buf) free(xch);
+    return 0;
 }
 
-static xc_error *
-_xc_get_last_error(void)
+int xc_interface_close(xc_interface *xch)
 {
-    xc_error *last_error;
+    int rc = 0;
 
-    pthread_once(&last_error_pkey_once, _xc_init_last_error);
+    xtl_logger_destroy(xch->dombuild_logger_tofree);
+    xtl_logger_destroy(xch->error_handler_tofree);
 
-    last_error = pthread_getspecific(last_error_pkey);
-    if (last_error == NULL) {
-        last_error = malloc(sizeof(xc_error));
-        pthread_setspecific(last_error_pkey, last_error);
-        xc_clear_last_error();
+    if (xch->fd >= 0) {
+        rc = xc_interface_close_core(xch, xch->fd);
+        if (rc) PERROR("Could not close hypervisor interface");
     }
-
-    return last_error;
+    free(xch);
+    return rc;
 }
 
-const xc_error *xc_get_last_error(void)
+static pthread_key_t errbuf_pkey;
+static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT;
+
+const xc_error *xc_get_last_error(xc_interface *xch)
 {
-    return _xc_get_last_error();
+    return &xch->last_error;
 }
 
-void xc_clear_last_error(void)
+void xc_clear_last_error(xc_interface *xch)
 {
-    xc_error *last_error = _xc_get_last_error();
-    last_error->code = XC_ERROR_NONE;
-    last_error->message[0] = '\0';
+    xch->last_error.code = XC_ERROR_NONE;
+    xch->last_error.message[0] = '\0';
 }
 
 const char *xc_error_code_to_desc(int code)
@@ -93,40 +106,70 @@ const char *xc_error_code_to_desc(int code)
     return "Unknown error code";
 }
 
-xc_error_handler xc_set_error_handler(xc_error_handler handler)
-{
-    xc_error_handler old = error_handler;
-    error_handler = handler;
-    return old;
+void xc_reportv(xc_interface *xch, xentoollog_logger *lg,
+                xentoollog_level level, int code,
+                const char *fmt, va_list args) {
+    int saved_errno = errno;
+    char msgbuf[XC_MAX_ERROR_MSG_LEN];
+    char *msg;
+
+    /* Strip newlines from messages.
+     * XXX really the messages themselves should have the newlines removed.
+     */
+    char fmt_nonewline[512];
+    int fmt_l;
+
+    fmt_l = strlen(fmt);
+    if (fmt_l && fmt[fmt_l-1]=='\n' && fmt_l < sizeof(fmt_nonewline)) {
+        memcpy(fmt_nonewline, fmt, fmt_l-1);
+        fmt_nonewline[fmt_l-1] = 0;
+        fmt = fmt_nonewline;
+    }
+
+    if ( level >= XTL_ERROR ) {
+        msg = xch->last_error.message;
+        xch->last_error.code = code;
+    } else {
+        msg = msgbuf;
+    }
+    vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
+    msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+
+    xtl_log(lg, level, -1, "xc",
+            "%s" "%s%s", msg,
+            code?": ":"", code ? xc_error_code_to_desc(code) : "");
+
+    errno = saved_errno;
 }
 
-static void _xc_set_error(int code, const char *msg)
-{
-    xc_error *last_error = _xc_get_last_error();
-    last_error->code = code;
-    strncpy(last_error->message, msg, XC_MAX_ERROR_MSG_LEN - 1);
-    last_error->message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+void xc_report(xc_interface *xch, xentoollog_logger *lg,
+               xentoollog_level level, int code, const char *fmt, ...) {
+    va_list args;
+    va_start(args,fmt);
+    xc_reportv(xch,lg,level,code,fmt,args);
+    va_end(args);
 }
 
-void xc_set_error(int code, const char *fmt, ...)
+void xc_report_error(xc_interface *xch, int code, const char *fmt, ...)
 {
-    int saved_errno = errno;
-    char msg[XC_MAX_ERROR_MSG_LEN];
     va_list args;
-
     va_start(args, fmt);
-    vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
-    msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+    xc_reportv(xch, xch->error_handler, XTL_ERROR, code, fmt, args);
     va_end(args);
+}
 
-    _xc_set_error(code, msg);
-
-    errno = saved_errno;
+void xc_report_progress_start(xc_interface *xch, const char *doing,
+                              unsigned long total) {
+    xch->currently_progress_reporting = doing;
+    xtl_progress(xch->error_handler, "xc", xch->currently_progress_reporting,
+                 0, total);
+}
 
-    if ( error_handler != NULL ) {
-        xc_error *last_error = _xc_get_last_error();
-        error_handler(last_error);
-    }
+void xc_report_progress_step(xc_interface *xch,
+                             unsigned long done, unsigned long total) {
+    assert(xch->currently_progress_reporting);
+    xtl_progress(xch->error_handler, "xc", xch->currently_progress_reporting,
+                 done, total);
 }
 
 #ifdef __sun__
@@ -244,7 +287,7 @@ void hcall_buf_release(void **addr, size_t len)
 #endif
 
 /* NB: arr must be locked */
-int xc_get_pfn_type_batch(int xc_handle, uint32_t dom,
+int xc_get_pfn_type_batch(xc_interface *xch, uint32_t dom,
                           unsigned int num, xen_pfn_t *arr)
 {
     DECLARE_DOMCTL;
@@ -252,11 +295,11 @@ int xc_get_pfn_type_batch(int xc_handle, uint32_t dom,
     domctl.domain = (domid_t)dom;
     domctl.u.getpageframeinfo3.num = num;
     set_xen_guest_handle(domctl.u.getpageframeinfo3.array, arr);
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_mmuext_op(
-    int xc_handle,
+    xc_interface *xch,
     struct mmuext_op *op,
     unsigned int nr_ops,
     domid_t dom)
@@ -276,7 +319,7 @@ int xc_mmuext_op(
     hypercall.arg[2] = (unsigned long)0;
     hypercall.arg[3] = (unsigned long)dom;
 
-    ret = do_xen_hypercall(xc_handle, &hypercall);
+    ret = do_xen_hypercall(xch, &hypercall);
 
     hcall_buf_release((void **)&op, nr_ops*sizeof(*op));
 
@@ -284,7 +327,7 @@ int xc_mmuext_op(
     return ret;
 }
 
-static int flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
+static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
 {
     int err = 0;
     DECLARE_HYPERCALL;
@@ -305,7 +348,7 @@ static int flush_mmu_updates(int xc_handle, struct xc_mmu 
*mmu)
         goto out;
     }
 
-    if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
+    if ( do_xen_hypercall(xch, &hypercall) < 0 )
     {
         ERROR("Failure when submitting mmu updates");
         err = 1;
@@ -319,7 +362,7 @@ static int flush_mmu_updates(int xc_handle, struct xc_mmu 
*mmu)
     return err;
 }
 
-struct xc_mmu *xc_alloc_mmu_updates(int xc_handle, domid_t dom)
+struct xc_mmu *xc_alloc_mmu_updates(xc_interface *xch, domid_t dom)
 {
     struct xc_mmu *mmu = malloc(sizeof(*mmu));
     if ( mmu == NULL )
@@ -329,24 +372,24 @@ struct xc_mmu *xc_alloc_mmu_updates(int xc_handle, 
domid_t dom)
     return mmu;
 }
 
-int xc_add_mmu_update(int xc_handle, struct xc_mmu *mmu,
+int xc_add_mmu_update(xc_interface *xch, struct xc_mmu *mmu,
                       unsigned long long ptr, unsigned long long val)
 {
     mmu->updates[mmu->idx].ptr = ptr;
     mmu->updates[mmu->idx].val = val;
 
     if ( ++mmu->idx == MAX_MMU_UPDATES )
-        return flush_mmu_updates(xc_handle, mmu);
+        return flush_mmu_updates(xch, mmu);
 
     return 0;
 }
 
-int xc_flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
+int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
 {
-    return flush_mmu_updates(xc_handle, mmu);
+    return flush_mmu_updates(xch, mmu);
 }
 
-int xc_memory_op(int xc_handle,
+int xc_memory_op(xc_interface *xch,
                  int cmd,
                  void *arg)
 {
@@ -421,7 +464,7 @@ int xc_memory_op(int xc_handle,
         break;
     }
 
-    ret = do_xen_hypercall(xc_handle, &hypercall);
+    ret = do_xen_hypercall(xch, &hypercall);
 
     switch ( cmd )
     {
@@ -459,14 +502,14 @@ int xc_memory_op(int xc_handle,
 }
 
 
-long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
+long long xc_domain_get_cpu_usage( xc_interface *xch, domid_t domid, int vcpu )
 {
     DECLARE_DOMCTL;
 
     domctl.cmd = XEN_DOMCTL_getvcpuinfo;
     domctl.domain = (domid_t)domid;
     domctl.u.getvcpuinfo.vcpu   = (uint16_t)vcpu;
-    if ( (do_domctl(xc_handle, &domctl) < 0) )
+    if ( (do_domctl(xch, &domctl) < 0) )
     {
         PERROR("Could not get info on domain");
         return -1;
@@ -476,7 +519,7 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t 
domid, int vcpu )
 
 
 #ifndef __ia64__
-int xc_get_pfn_list(int xc_handle,
+int xc_get_pfn_list(xc_interface *xch,
                     uint32_t domid,
                     uint64_t *pfn_buf,
                     unsigned long max_pfns)
@@ -498,7 +541,7 @@ int xc_get_pfn_list(int xc_handle,
         return -1;
     }
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     unlock_pages(pfn_buf, max_pfns * sizeof(*pfn_buf));
 
@@ -506,22 +549,22 @@ int xc_get_pfn_list(int xc_handle,
 }
 #endif
 
-long xc_get_tot_pages(int xc_handle, uint32_t domid)
+long xc_get_tot_pages(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     domctl.cmd = XEN_DOMCTL_getdomaininfo;
     domctl.domain = (domid_t)domid;
-    return (do_domctl(xc_handle, &domctl) < 0) ?
+    return (do_domctl(xch, &domctl) < 0) ?
         -1 : domctl.u.getdomaininfo.tot_pages;
 }
 
-int xc_copy_to_domain_page(int xc_handle,
+int xc_copy_to_domain_page(xc_interface *xch,
                            uint32_t domid,
                            unsigned long dst_pfn,
                            const char *src_page)
 {
     void *vaddr = xc_map_foreign_range(
-        xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
+        xch, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
     if ( vaddr == NULL )
         return -1;
     memcpy(vaddr, src_page, PAGE_SIZE);
@@ -529,12 +572,12 @@ int xc_copy_to_domain_page(int xc_handle,
     return 0;
 }
 
-int xc_clear_domain_page(int xc_handle,
+int xc_clear_domain_page(xc_interface *xch,
                          uint32_t domid,
                          unsigned long dst_pfn)
 {
     void *vaddr = xc_map_foreign_range(
-        xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
+        xch, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
     if ( vaddr == NULL )
         return -1;
     memset(vaddr, 0, PAGE_SIZE);
@@ -542,17 +585,17 @@ int xc_clear_domain_page(int xc_handle,
     return 0;
 }
 
-int xc_domctl(int xc_handle, struct xen_domctl *domctl)
+int xc_domctl(xc_interface *xch, struct xen_domctl *domctl)
 {
-    return do_domctl(xc_handle, domctl);
+    return do_domctl(xch, domctl);
 }
 
-int xc_sysctl(int xc_handle, struct xen_sysctl *sysctl)
+int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
 {
-    return do_sysctl(xc_handle, sysctl);
+    return do_sysctl(xch, sysctl);
 }
 
-int xc_version(int xc_handle, int cmd, void *arg)
+int xc_version(xc_interface *xch, int cmd, void *arg)
 {
     int rc, argsize = 0;
 
@@ -586,7 +629,7 @@ int xc_version(int xc_handle, int cmd, void *arg)
         memset(arg, 0, argsize);
 #endif
 
-    rc = do_xen_version(xc_handle, cmd, arg);
+    rc = do_xen_version(xch, cmd, arg);
 
     if ( argsize != 0 )
         unlock_pages(arg, argsize);
@@ -595,20 +638,20 @@ int xc_version(int xc_handle, int cmd, void *arg)
 }
 
 unsigned long xc_make_page_below_4G(
-    int xc_handle, uint32_t domid, unsigned long mfn)
+    xc_interface *xch, uint32_t domid, unsigned long mfn)
 {
     xen_pfn_t old_mfn = mfn;
     xen_pfn_t new_mfn;
 
     if ( xc_domain_memory_decrease_reservation(
-        xc_handle, domid, 1, 0, &old_mfn) != 0 )
+        xch, domid, 1, 0, &old_mfn) != 0 )
     {
         DPRINTF("xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
         return 0;
     }
 
     if ( xc_domain_memory_increase_reservation(
-        xc_handle, domid, 1, 0, XENMEMF_address_bits(32), &new_mfn) != 0 )
+        xch, domid, 1, 0, XENMEMF_address_bits(32), &new_mfn) != 0 )
     {
         DPRINTF("xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
         return 0;
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index fba384c..19de3ba 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -3,6 +3,7 @@
 #define XC_PRIVATE_H
 
 #include <unistd.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -39,10 +40,6 @@
 #define PAGE_SIZE               (1UL << PAGE_SHIFT)
 #define PAGE_MASK               (~(PAGE_SIZE-1))
 
-#define DEBUG    1
-#define INFO     1
-#define PROGRESS 0
-
 /* Force a compilation error if condition is true */
 #define XC_BUILD_BUG_ON(p) ((void)sizeof(struct { int:-!!(p); }))
 
@@ -53,30 +50,37 @@
 */
 #define MAX_PAGECACHE_USAGE (4*1024)
 
-#if INFO
-#define IPRINTF(_f, _a...) printf(_f , ## _a)
-#else
-#define IPRINTF(_f, _a...) ((void)0)
-#endif
+struct xc_interface {
+    int fd;
+    xentoollog_logger *error_handler,   *error_handler_tofree;
+    xentoollog_logger *dombuild_logger, *dombuild_logger_tofree;
+    struct xc_error last_error; /* for xc_get_last_error */
+    FILE *dombuild_logger_file;
+    const char *currently_progress_reporting;
+};
 
-#if DEBUG
-#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
-#else
-#define DPRINTF(_f, _a...) ((void)0)
-#endif
+char *safe_strerror(int errcode);
+void xc_report_error(xc_interface *xch, int code, const char *fmt, ...);
+void xc_reportv(xc_interface *xch, xentoollog_logger *lg, xentoollog_level,
+                int code, const char *fmt, va_list args)
+     __attribute__((format(printf,5,0)));
+void xc_report(xc_interface *xch, xentoollog_logger *lg, xentoollog_level,
+               int code, const char *fmt, ...)
+     __attribute__((format(printf,5,6)));
 
-#if PROGRESS
-#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
-#else
-#define PPRINTF(_f, _a...)
-#endif
+void xc_report_progress_start(xc_interface *xch, const char *doing,
+                              unsigned long total);
+void xc_report_progress_step(xc_interface *xch,
+                             unsigned long done, unsigned long total);
 
-char *safe_strerror(int errcode);
-void xc_set_error(int code, const char *fmt, ...);
+/* anamorphic macros:  struct xc_interface *xch  must be in scope */
 
-#define ERROR(_m, _a...)  xc_set_error(XC_INTERNAL_ERROR, _m , ## _a )
-#define PERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m " (%d = %s)", \
-                                       ## _a , errno, safe_strerror(errno))
+#define IPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_INFO,0, _f , 
## _a)
+#define DPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DETAIL,0, _f 
, ## _a)
+
+#define ERROR(_m, _a...)  xc_report_error(xch,XC_INTERNAL_ERROR,_m , ## _a )
+#define PERROR(_m, _a...) xc_report_error(xch,XC_INTERNAL_ERROR,_m \
+                  " (%d = %s)", ## _a , errno, safe_strerror(errno))
 
 void *xc_memalign(size_t alignment, size_t size);
 
@@ -93,9 +97,9 @@ static inline void safe_munlock(const void *addr, size_t len)
     errno = saved_errno;
 }
 
-int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall);
+int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall);
 
-static inline int do_xen_version(int xc_handle, int cmd, void *dest)
+static inline int do_xen_version(xc_interface *xch, int cmd, void *dest)
 {
     DECLARE_HYPERCALL;
 
@@ -103,10 +107,10 @@ static inline int do_xen_version(int xc_handle, int cmd, 
void *dest)
     hypercall.arg[0] = (unsigned long) cmd;
     hypercall.arg[1] = (unsigned long) dest;
 
-    return do_xen_hypercall(xc_handle, &hypercall);
+    return do_xen_hypercall(xch, &hypercall);
 }
 
-static inline int do_physdev_op(int xc_handle, int cmd, void *op, size_t len)
+static inline int do_physdev_op(xc_interface *xch, int cmd, void *op, size_t 
len)
 {
     int ret = -1;
 
@@ -122,7 +126,7 @@ static inline int do_physdev_op(int xc_handle, int cmd, 
void *op, size_t len)
     hypercall.arg[0] = (unsigned long) cmd;
     hypercall.arg[1] = (unsigned long) op;
 
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("physdev operation failed -- need to"
@@ -135,7 +139,7 @@ out1:
     return ret;
 }
 
-static inline int do_domctl(int xc_handle, struct xen_domctl *domctl)
+static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
 {
     int ret = -1;
     DECLARE_HYPERCALL;
@@ -151,7 +155,7 @@ static inline int do_domctl(int xc_handle, struct 
xen_domctl *domctl)
     hypercall.op     = __HYPERVISOR_domctl;
     hypercall.arg[0] = (unsigned long)domctl;
 
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("domctl operation failed -- need to"
@@ -164,7 +168,7 @@ static inline int do_domctl(int xc_handle, struct 
xen_domctl *domctl)
     return ret;
 }
 
-static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl)
+static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
 {
     int ret = -1;
     DECLARE_HYPERCALL;
@@ -180,7 +184,7 @@ static inline int do_sysctl(int xc_handle, struct 
xen_sysctl *sysctl)
     hypercall.op     = __HYPERVISOR_sysctl;
     hypercall.arg[0] = (unsigned long)sysctl;
 
-    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
+    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("sysctl operation failed -- need to"
@@ -193,18 +197,21 @@ static inline int do_sysctl(int xc_handle, struct 
xen_sysctl *sysctl)
     return ret;
 }
 
-void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+int xc_interface_open_core(xc_interface *xch); /* returns fd, logs errors */
+int xc_interface_close_core(xc_interface *xch, int fd); /* no logging */
+
+void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries);
 
-int xc_get_pfn_type_batch(int xc_handle, uint32_t dom,
+int xc_get_pfn_type_batch(xc_interface *xch, uint32_t dom,
                           unsigned int num, xen_pfn_t *);
 
 void bitmap_64_to_byte(uint8_t *bp, const uint64_t *lp, int nbits);
 void bitmap_byte_to_64(uint64_t *lp, const uint8_t *bp, int nbits);
 
 /* Optionally flush file to disk and discard page cache */
-void discard_file_cache(int fd, int flush);
+void discard_file_cache(xc_interface *xch, int fd, int flush);
 
 #define MAX_MMU_UPDATES 1024
 struct xc_mmu {
@@ -213,10 +220,10 @@ struct xc_mmu {
     domid_t      subject;
 };
 /* Structure returned by xc_alloc_mmu_updates must be free()'ed by caller. */
-struct xc_mmu *xc_alloc_mmu_updates(int xc_handle, domid_t dom);
-int xc_add_mmu_update(int xc_handle, struct xc_mmu *mmu,
+struct xc_mmu *xc_alloc_mmu_updates(xc_interface *xch, domid_t dom);
+int xc_add_mmu_update(xc_interface *xch, struct xc_mmu *mmu,
                    unsigned long long ptr, unsigned long long val);
-int xc_flush_mmu_updates(int xc_handle, struct xc_mmu *mmu);
+int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu);
 
 /* Return 0 on success; -1 on error. */
 int read_exact(int fd, void *data, size_t size);
@@ -227,4 +234,7 @@ int xc_ffs16(uint16_t x);
 int xc_ffs32(uint32_t x);
 int xc_ffs64(uint64_t x);
 
+#define DOMPRINTF(fmt, args...) xc_dom_printf(dom->xch, fmt, ## args)
+#define DOMPRINTF_CALLED(xch) xc_dom_printf((xch), "%s: called", __FUNCTION__)
+
 #endif /* __XC_PRIVATE_H__ */
diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c
index e91ac56..c85ab48 100644
--- a/tools/libxc/xc_ptrace.c
+++ b/tools/libxc/xc_ptrace.c
@@ -48,7 +48,7 @@ static vcpu_guest_context_any_t        *ctxt;
 #define FOREACH_CPU(cpumap, i)  for ( cpumap = online_cpumap; (i = 
xc_ffs64(cpumap)); cpumap &= ~(1 << (index - 1)) )
 
 static int
-fetch_regs(int xc_handle, int cpu, int *online)
+fetch_regs(xc_interface *xch, int cpu, int *online)
 {
     xc_vcpuinfo_t info;
     int retval = 0;
@@ -57,7 +57,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
         *online = 0;
     if ( !(regs_valid & (1 << cpu)) )
     {
-        retval = xc_vcpu_getcontext(xc_handle, current_domid,
+        retval = xc_vcpu_getcontext(xch, current_domid,
                 cpu, &ctxt[cpu]);
         if ( retval )
             goto done;
@@ -67,7 +67,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
     if ( online == NULL )
         goto done;
 
-    retval = xc_vcpu_getinfo(xc_handle, current_domid, cpu, &info);
+    retval = xc_vcpu_getinfo(xch, current_domid, cpu, &info);
     *online = info.online;
 
  done:
@@ -102,7 +102,8 @@ paging_enabled(vcpu_guest_context_any_t *v)
     return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
 }
 
-vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(unsigned int nr_cpus)
+vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(xc_interface *xch,
+                              unsigned int nr_cpus)
 {
     if (nr_cpus > nr_vcpu_ids) {
         vcpu_guest_context_any_t *new;
@@ -124,17 +125,17 @@ vcpu_guest_context_any_t 
*xc_ptrace_get_vcpu_ctxt(unsigned int nr_cpus)
  */
 
 static int
-get_online_cpumap(int xc_handle, struct xen_domctl_getdomaininfo *d,
+get_online_cpumap(xc_interface *xch, struct xen_domctl_getdomaininfo *d,
                   uint64_t *cpumap)
 {
     int i, online;
 
-    if (!xc_ptrace_get_vcpu_ctxt(d->max_vcpu_id + 1))
+    if (!xc_ptrace_get_vcpu_ctxt(xch, d->max_vcpu_id + 1))
         return -ENOMEM;
 
     *cpumap = 0;
     for (i = 0; i <= d->max_vcpu_id; i++) {
-        fetch_regs(xc_handle, i, &online);
+        fetch_regs(xch, i, &online);
         if (online)
             *cpumap |= (1 << i);
     }
@@ -149,7 +150,7 @@ get_online_cpumap(int xc_handle, struct 
xen_domctl_getdomaininfo *d,
  */
 
 static void
-online_vcpus_changed(uint64_t cpumap)
+online_vcpus_changed(xc_interface *xch, uint64_t cpumap)
 {
     uint64_t changed_cpumap = cpumap ^ online_cpumap;
     int index;
@@ -171,7 +172,7 @@ online_vcpus_changed(uint64_t cpumap)
 
 static void *
 map_domain_va(
-    int xc_handle,
+    xc_interface *xch,
     int cpu,
     void *guest_va,
     int perm)
@@ -184,11 +185,11 @@ map_domain_va(
     if ( (va & ~PAGE_MASK) + sizeof(long) > PAGE_SIZE )
         return NULL;
 
-    mfn = xc_translate_foreign_address(xc_handle, current_domid, cpu, va);
+    mfn = xc_translate_foreign_address(xch, current_domid, cpu, va);
     if ( mfn == 0 )
         return NULL;
 
-    map = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, 
+    map = xc_map_foreign_range(xch, current_domid, PAGE_SIZE, 
                                perm, mfn);
     if (map == NULL)
         return NULL;
@@ -213,7 +214,7 @@ int control_c_pressed_flag = 0;
 
 static int
 __xc_waitdomain(
-    int xc_handle,
+    xc_interface *xch,
     int domain,
     int *status,
     int options)
@@ -230,7 +231,7 @@ __xc_waitdomain(
     domctl.domain = domain;
 
  retry:
-    retval = do_domctl(xc_handle, &domctl);
+    retval = do_domctl(xch, &domctl);
     if ( retval || (domctl.domain != domain) )
     {
         IPRINTF("getdomaininfo failed\n");
@@ -242,7 +243,7 @@ __xc_waitdomain(
         goto done;
 
     if (control_c_pressed_flag) {
-        xc_domain_pause(xc_handle, domain);
+        xc_domain_pause(xch, domain);
         control_c_pressed_flag = 0;
         goto done;
     }
@@ -253,10 +254,10 @@ __xc_waitdomain(
         goto retry;
     }
  done:
-    if (get_online_cpumap(xc_handle, &domctl.u.getdomaininfo, &cpumap))
+    if (get_online_cpumap(xch, &domctl.u.getdomaininfo, &cpumap))
         IPRINTF("get_online_cpumap failed\n");
     if (online_cpumap != cpumap)
-        online_vcpus_changed(cpumap);
+        online_vcpus_changed(xch, cpumap);
     return retval;
 
 }
@@ -264,7 +265,7 @@ __xc_waitdomain(
 
 long
 xc_ptrace(
-    int xc_handle,
+    xc_interface *xch,
     enum __ptrace_request request,
     uint32_t domid_tid,
     long eaddr,
@@ -287,10 +288,10 @@ xc_ptrace(
     case PTRACE_PEEKDATA:
         if (current_isfile)
             guest_va = (unsigned long *)map_domain_va_core(
-                current_domid, cpu, addr);
+                xch, current_domid, cpu, addr);
         else
             guest_va = (unsigned long *)map_domain_va(
-                xc_handle, cpu, addr, PROT_READ);
+                xch, cpu, addr, PROT_READ);
         if ( guest_va == NULL )
             goto out_error;
         retval = *guest_va;
@@ -303,10 +304,10 @@ xc_ptrace(
         /* XXX assume that all CPUs have the same address space */
         if (current_isfile)
             guest_va = (unsigned long *)map_domain_va_core(
-                current_domid, cpu, addr);
+                xch, current_domid, cpu, addr);
         else
             guest_va = (unsigned long *)map_domain_va(
-                xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
+                xch, cpu, addr, PROT_READ|PROT_WRITE);
         if ( guest_va == NULL )
             goto out_error;
         *guest_va = edata;
@@ -315,20 +316,20 @@ xc_ptrace(
         break;
 
     case PTRACE_GETREGS:
-        if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
+        if (!current_isfile && fetch_regs(xch, cpu, NULL))
             goto out_error;
         SET_PT_REGS(pt, ctxt[cpu].c.user_regs);
         memcpy(data, &pt, sizeof(struct gdb_regs));
         break;
 
     case PTRACE_GETFPREGS:
-        if (!current_isfile && fetch_regs(xc_handle, cpu, NULL)) 
+        if (!current_isfile && fetch_regs(xch, cpu, NULL)) 
                 goto out_error;
         memcpy(data, &ctxt[cpu].c.fpu_ctxt, sizeof (elf_fpregset_t));
         break;
 
     case PTRACE_GETFPXREGS:
-        if (!current_isfile && fetch_regs(xc_handle, cpu, NULL))
+        if (!current_isfile && fetch_regs(xch, cpu, NULL))
                 goto out_error;
         memcpy(data, &ctxt[cpu].c.fpu_ctxt, sizeof(ctxt[cpu].c.fpu_ctxt));
         break;
@@ -337,7 +338,7 @@ xc_ptrace(
         if (current_isfile)
                 goto out_unsupported; /* XXX not yet supported */
         SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].c.user_regs);
-        if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
+        if ((retval = xc_vcpu_setcontext(xch, current_domid, cpu,
                                 &ctxt[cpu])))
             goto out_error_domctl;
         break;
@@ -352,13 +353,13 @@ xc_ptrace(
          * if no MTF support
          */
         if ( !current_is_hvm ||
-             xc_domain_debug_control(xc_handle,
+             xc_domain_debug_control(xch,
                                      current_domid,
                                      XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_ON,
                                      cpu) )
         {
             ctxt[cpu].c.user_regs.eflags |= PSL_T;
-            if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu,
+            if ((retval = xc_vcpu_setcontext(xch, current_domid, cpu,
                                     &ctxt[cpu])))
                 goto out_error_domctl;
         }
@@ -373,18 +374,18 @@ xc_ptrace(
             FOREACH_CPU(cpumap, index) {
                 cpu = index - 1;
                 if ( !current_is_hvm ||
-                      xc_domain_debug_control(xc_handle,
+                      xc_domain_debug_control(xch,
                                               current_domid,
                                               
XEN_DOMCTL_DEBUG_OP_SINGLE_STEP_OFF,
                                               cpu) )
                 {
-                    if (fetch_regs(xc_handle, cpu, NULL))
+                    if (fetch_regs(xch, cpu, NULL))
                         goto out_error;
                     /* Clear trace flag */
                     if ( ctxt[cpu].c.user_regs.eflags & PSL_T )
                     {
                         ctxt[cpu].c.user_regs.eflags &= ~PSL_T;
-                        if ((retval = xc_vcpu_setcontext(xc_handle, 
current_domid,
+                        if ((retval = xc_vcpu_setcontext(xch, current_domid,
                                         cpu, &ctxt[cpu])))
                             goto out_error_domctl;
                     }
@@ -393,11 +394,11 @@ xc_ptrace(
         }
         if ( request == PTRACE_DETACH )
         {
-            if ((retval = xc_domain_setdebugging(xc_handle, current_domid, 0)))
+            if ((retval = xc_domain_setdebugging(xch, current_domid, 0)))
                 goto out_error_domctl;
         }
         regs_valid = 0;
-        if ((retval = xc_domain_unpause(xc_handle, current_domid > 0 ?
+        if ((retval = xc_domain_unpause(xch, current_domid > 0 ?
                                 current_domid : -current_domid)))
             goto out_error_domctl;
         break;
@@ -409,21 +410,21 @@ xc_ptrace(
             break;
         domctl.cmd = XEN_DOMCTL_getdomaininfo;
         domctl.domain = current_domid;
-        retval = do_domctl(xc_handle, &domctl);
+        retval = do_domctl(xch, &domctl);
         if ( retval || (domctl.domain != current_domid) )
             goto out_error_domctl;
         if ( domctl.u.getdomaininfo.flags & XEN_DOMINF_paused )
             IPRINTF("domain currently paused\n");
-        else if ((retval = xc_domain_pause(xc_handle, current_domid)))
+        else if ((retval = xc_domain_pause(xch, current_domid)))
             goto out_error_domctl;
         current_is_hvm = !!(domctl.u.getdomaininfo.flags&XEN_DOMINF_hvm_guest);
-        if ((retval = xc_domain_setdebugging(xc_handle, current_domid, 1)))
+        if ((retval = xc_domain_setdebugging(xch, current_domid, 1)))
             goto out_error_domctl;
 
-        if (get_online_cpumap(xc_handle, &domctl.u.getdomaininfo, &cpumap))
+        if (get_online_cpumap(xch, &domctl.u.getdomaininfo, &cpumap))
             IPRINTF("get_online_cpumap failed\n");
         if (online_cpumap != cpumap)
-            online_vcpus_changed(cpumap);
+            online_vcpus_changed(xch, cpumap);
         break;
 
     case PTRACE_TRACEME:
@@ -437,7 +438,7 @@ xc_ptrace(
     return retval;
 
  out_error_domctl:
-    perror("domctl failed");
+    PERROR("domctl failed");
  out_error:
     errno = EINVAL;
     return retval;
@@ -453,14 +454,14 @@ xc_ptrace(
 
 int
 xc_waitdomain(
-    int xc_handle,
+    xc_interface *xch,
     int domain,
     int *status,
     int options)
 {
     if (current_isfile)
-        return xc_waitdomain_core(xc_handle, domain, status, options);
-    return __xc_waitdomain(xc_handle, domain, status, options);
+        return xc_waitdomain_core(xch, domain, status, options);
+    return __xc_waitdomain(xch, domain, status, options);
 }
 
 /*
diff --git a/tools/libxc/xc_ptrace.h b/tools/libxc/xc_ptrace.h
index c8ba404..7116ba0 100644
--- a/tools/libxc/xc_ptrace.h
+++ b/tools/libxc/xc_ptrace.h
@@ -157,9 +157,12 @@ struct gdb_regs {
 }
 #endif
 
-void *map_domain_va_core(unsigned long domfd, int cpu, void *guest_va);
-int xc_waitdomain_core(int xc_handle, int domain, int *status, int options);
-vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(unsigned int nr_cpus);
+void *map_domain_va_core(xc_interface *xch,
+                         unsigned long domfd, int cpu, void *guest_va);
+int xc_waitdomain_core(xc_interface *xch,
+                       int domain, int *status, int options);
+vcpu_guest_context_any_t *xc_ptrace_get_vcpu_ctxt(xc_interface *xch,
+                              unsigned int nr_cpus);
 
 
 #endif /* XC_PTRACE */
diff --git a/tools/libxc/xc_ptrace_core.c b/tools/libxc/xc_ptrace_core.c
index b6a5eb9..09b70a7 100644
--- a/tools/libxc/xc_ptrace_core.c
+++ b/tools/libxc/xc_ptrace_core.c
@@ -22,7 +22,7 @@ static unsigned long  *page_phys;
 static unsigned long **page_virt;
 
 static vcpu_guest_context_t *
-ptrace_core_get_vcpu_ctxt(unsigned int nr_vcpus)
+ptrace_core_get_vcpu_ctxt(xc_interface *xch, unsigned int nr_vcpus)
 {
     if (nr_vcpus > max_nr_vcpus) {
         void *new;
@@ -47,7 +47,7 @@ ptrace_core_get_vcpu_ctxt(unsigned int nr_vcpus)
         max_nr_vcpus = nr_vcpus;
     }
 
-    return &xc_ptrace_get_vcpu_ctxt(nr_vcpus)->c;
+    return &xc_ptrace_get_vcpu_ctxt(xch, nr_vcpus)->c;
 }
 
 /* Leave the code for the old format as is. */
@@ -71,7 +71,8 @@ map_mtop_offset_compat(unsigned long ma)
 
 
 static void *
-map_domain_va_core_compat(unsigned long domfd, int cpu, void *guest_va)
+map_domain_va_core_compat(xc_interface *xch,
+                          unsigned long domfd, int cpu, void *guest_va)
 {
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
@@ -87,7 +88,7 @@ map_domain_va_core_compat(unsigned long domfd, int cpu, void 
*guest_va)
             map_mtop_offset_compat(xen_cr3_to_pfn(cr3_phys[cpu])));
         if (v == MAP_FAILED)
         {
-            perror("mmap failed");
+            PERROR("mmap failed");
             return NULL;
         }
         cr3_virt[cpu] = v;
@@ -133,7 +134,7 @@ map_domain_va_core_compat(unsigned long domfd, int cpu, 
void *guest_va)
 
 static int
 xc_waitdomain_core_compat(
-    int xc_handle,
+    xc_interface *xch,
     int domfd,
     int *status,
     int options)
@@ -161,7 +162,7 @@ xc_waitdomain_core_compat(
         nr_vcpus = header.xch_nr_vcpus;
         pages_offset_compat = header.xch_pages_offset;
 
-        if ((ctxt = ptrace_core_get_vcpu_ctxt(nr_vcpus)) == NULL)
+        if ((ctxt = ptrace_core_get_vcpu_ctxt(xch, nr_vcpus)) == NULL)
         {
             IPRINTF("Could not allocate vcpu context array\n");
             return -1;
@@ -447,7 +448,8 @@ map_gmfn_to_offset_elf(unsigned long gmfn)
 }
 
 static void *
-map_domain_va_core_elf(unsigned long domfd, int cpu, void *guest_va)
+map_domain_va_core_elf(xc_interface *xch,
+                       unsigned long domfd, int cpu, void *guest_va)
 {
     unsigned long pde, page;
     unsigned long va = (unsigned long)guest_va;
@@ -468,7 +470,7 @@ map_domain_va_core_elf(unsigned long domfd, int cpu, void 
*guest_va)
         v = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, domfd, offset);
         if (v == MAP_FAILED)
         {
-            perror("mmap failed");
+            PERROR("mmap failed");
             return NULL;
         }
         cr3_phys[cpu] = cr3[cpu];
@@ -521,7 +523,7 @@ map_domain_va_core_elf(unsigned long domfd, int cpu, void 
*guest_va)
 
 static int
 xc_waitdomain_core_elf(
-    int xc_handle,
+    xc_interface *xch,
     int domfd,
     int *status,
     int options)
@@ -586,7 +588,7 @@ xc_waitdomain_core_elf(
                 format_version->format_version.version);
     }
 
-    if ((ctxt = ptrace_core_get_vcpu_ctxt(header->header.xch_nr_vcpus)) == 
NULL)
+    if ((ctxt = ptrace_core_get_vcpu_ctxt(xch, header->header.xch_nr_vcpus)) 
== NULL)
         goto out;
 
     /* .xen_prstatus: read vcpu_guest_context_t*/
@@ -646,11 +648,12 @@ out:
 
 /* --- interface ----------------------------------------------------------- */
 
-typedef int (*xc_waitdomain_core_t)(int xc_handle,
+typedef int (*xc_waitdomain_core_t)(xc_interface *xch,
                                     int domfd,
                                     int *status,
                                     int options);
-typedef void *(*map_domain_va_core_t)(unsigned long domfd,
+typedef void *(*map_domain_va_core_t)(xc_interface *xch,
+                                      unsigned long domfd,
                                       int cpu,
                                       void *guest_va);
 struct xc_core_format_type {
@@ -668,21 +671,22 @@ static const struct xc_core_format_type format_type[] = {
 static const struct xc_core_format_type* current_format_type = NULL;
 
 void *
-map_domain_va_core(unsigned long domfd, int cpu, void *guest_va)
+map_domain_va_core(xc_interface *xch,
+                   unsigned long domfd, int cpu, void *guest_va)
 {
     if (current_format_type == NULL)
         return NULL;
-    return (current_format_type->map_domain_va_core)(domfd, cpu, guest_va);
+    return (current_format_type->map_domain_va_core)(xch, domfd, cpu, 
guest_va);
 }
 
 int
-xc_waitdomain_core(int xc_handle, int domfd, int *status, int options)
+xc_waitdomain_core(xc_interface *xch, int domfd, int *status, int options)
 {
     int ret;
     int i;
 
     for (i = 0; i < NR_FORMAT_TYPE; i++) {
-        ret = (format_type[i].waitdomain_core)(xc_handle, domfd, status,
+        ret = (format_type[i].waitdomain_core)(xch, domfd, status,
                                                options);
         if (ret == 0) {
             current_format_type = &format_type[i];
diff --git a/tools/libxc/xc_resume.c b/tools/libxc/xc_resume.c
index c17ae26..de93f41 100644
--- a/tools/libxc/xc_resume.c
+++ b/tools/libxc/xc_resume.c
@@ -8,12 +8,12 @@
 #include <xen/foreign/x86_64.h>
 #include <xen/hvm/params.h>
 
-static int pv_guest_width(int xc_handle, uint32_t domid)
+static int pv_guest_width(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     domctl.domain = domid;
     domctl.cmd = XEN_DOMCTL_get_address_size;
-    if ( xc_domctl(xc_handle, &domctl) != 0 )
+    if ( xc_domctl(xch, &domctl) != 0 )
     {
         PERROR("Could not get guest address size");
         return -1;
@@ -21,7 +21,7 @@ static int pv_guest_width(int xc_handle, uint32_t domid)
     return domctl.u.address_size.size / 8;
 }
 
-static int modify_returncode(int xc_handle, uint32_t domid)
+static int modify_returncode(xc_interface *xch, uint32_t domid)
 {
     vcpu_guest_context_any_t ctxt;
     xc_dominfo_t info;
@@ -30,7 +30,7 @@ static int modify_returncode(int xc_handle, uint32_t domid)
     struct domain_info_context *dinfo = &_dinfo;
     int rc;
 
-    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
     {
         PERROR("Could not get domain info");
         return -1;
@@ -40,12 +40,12 @@ static int modify_returncode(int xc_handle, uint32_t domid)
     {
         /* HVM guests without PV drivers have no return code to modify. */
         unsigned long irq = 0;
-        xc_get_hvm_param(xc_handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
+        xc_get_hvm_param(xch, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
         if ( !irq )
             return 0;
 
         /* HVM guests have host address width. */
-        if ( xc_version(xc_handle, XENVER_capabilities, &caps) != 0 )
+        if ( xc_version(xch, XENVER_capabilities, &caps) != 0 )
         {
             PERROR("Could not get Xen capabilities\n");
             return -1;
@@ -55,17 +55,17 @@ static int modify_returncode(int xc_handle, uint32_t domid)
     else
     {
         /* Probe PV guest address width. */
-        dinfo->guest_width = pv_guest_width(xc_handle, domid);
+        dinfo->guest_width = pv_guest_width(xch, domid);
         if ( dinfo->guest_width < 0 )
             return -1;
     }
 
-    if ( (rc = xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+    if ( (rc = xc_vcpu_getcontext(xch, domid, 0, &ctxt)) != 0 )
         return rc;
 
     SET_FIELD(&ctxt, user_regs.eax, 1);
 
-    if ( (rc = xc_vcpu_setcontext(xc_handle, domid, 0, &ctxt)) != 0 )
+    if ( (rc = xc_vcpu_setcontext(xch, domid, 0, &ctxt)) != 0 )
         return rc;
 
     return 0;
@@ -73,7 +73,7 @@ static int modify_returncode(int xc_handle, uint32_t domid)
 
 #else
 
-static int modify_returncode(int xc_handle, uint32_t domid)
+static int modify_returncode(xc_interface *xch, uint32_t domid)
 {
     return 0;
 
@@ -81,7 +81,7 @@ static int modify_returncode(int xc_handle, uint32_t domid)
 
 #endif
 
-static int xc_domain_resume_cooperative(int xc_handle, uint32_t domid)
+static int xc_domain_resume_cooperative(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     int rc;
@@ -90,15 +90,15 @@ static int xc_domain_resume_cooperative(int xc_handle, 
uint32_t domid)
      * Set hypercall return code to indicate that suspend is cancelled
      * (rather than resuming in a new domain context).
      */
-    if ( (rc = modify_returncode(xc_handle, domid)) != 0 )
+    if ( (rc = modify_returncode(xch, domid)) != 0 )
         return rc;
 
     domctl.cmd = XEN_DOMCTL_resumedomain;
     domctl.domain = domid;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
-static int xc_domain_resume_any(int xc_handle, uint32_t domid)
+static int xc_domain_resume_any(xc_interface *xch, uint32_t domid)
 {
     DECLARE_DOMCTL;
     xc_dominfo_t info;
@@ -115,7 +115,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
     xen_pfn_t *p2m = NULL;
 #endif
 
-    if ( xc_domain_getinfo(xc_handle, domid, 1, &info) != 1 )
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
     {
         PERROR("Could not get domain info");
         return rc;
@@ -131,7 +131,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
         return rc;
     }
 
-    dinfo->guest_width = pv_guest_width(xc_handle, domid);
+    dinfo->guest_width = pv_guest_width(xch, domid);
     if ( dinfo->guest_width != sizeof(long) )
     {
         ERROR("Cannot resume uncooperative cross-address-size guests");
@@ -139,7 +139,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
     }
 
     /* Map the shared info frame */
-    shinfo = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    shinfo = xc_map_foreign_range(xch, domid, PAGE_SIZE,
                                   PROT_READ, info.shared_info_frame);
     if ( shinfo == NULL )
     {
@@ -150,7 +150,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
     dinfo->p2m_size = shinfo->arch.max_pfn;
 
     p2m_frame_list_list =
-        xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ,
+        xc_map_foreign_range(xch, domid, PAGE_SIZE, PROT_READ,
                              shinfo->arch.pfn_to_mfn_frame_list_list);
     if ( p2m_frame_list_list == NULL )
     {
@@ -158,7 +158,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
         goto out;
     }
 
-    p2m_frame_list = xc_map_foreign_pages(xc_handle, domid, PROT_READ,
+    p2m_frame_list = xc_map_foreign_pages(xch, domid, PROT_READ,
                                           p2m_frame_list_list,
                                           P2M_FLL_ENTRIES);
     if ( p2m_frame_list == NULL )
@@ -171,7 +171,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
        the guest must not change which frames are used for this purpose.
        (its not clear why it would want to change them, and we'll be OK
        from a safety POV anyhow. */
-    p2m = xc_map_foreign_pages(xc_handle, domid, PROT_READ,
+    p2m = xc_map_foreign_pages(xch, domid, PROT_READ,
                                p2m_frame_list,
                                P2M_FL_ENTRIES);
     if ( p2m == NULL )
@@ -186,7 +186,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
         goto out;
     }
 
-    if ( xc_vcpu_getcontext(xc_handle, domid, 0, &ctxt) )
+    if ( xc_vcpu_getcontext(xch, domid, 0, &ctxt) )
     {
         ERROR("Could not get vcpu context");
         goto out;
@@ -194,7 +194,7 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
 
     mfn = GET_FIELD(&ctxt, user_regs.edx);
 
-    start_info = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    start_info = xc_map_foreign_range(xch, domid, PAGE_SIZE,
                                       PROT_READ | PROT_WRITE, mfn);
     if ( start_info == NULL )
     {
@@ -210,12 +210,12 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
 
     /* Reset all secondary CPU states. */
     for ( i = 1; i <= info.max_vcpu_id; i++ )
-        xc_vcpu_setcontext(xc_handle, domid, i, NULL);
+        xc_vcpu_setcontext(xch, domid, i, NULL);
 
     /* Ready to resume domain execution now. */
     domctl.cmd = XEN_DOMCTL_resumedomain;
     domctl.domain = domid;
-    rc = do_domctl(xc_handle, &domctl);
+    rc = do_domctl(xch, &domctl);
 
 #if defined(__i386__) || defined(__x86_64__)
  out:
@@ -242,9 +242,9 @@ static int xc_domain_resume_any(int xc_handle, uint32_t 
domid)
  * (2) should be used only for guests which cannot handle the special
  * new return code. (1) is always safe (but slower).
  */
-int xc_domain_resume(int xc_handle, uint32_t domid, int fast)
+int xc_domain_resume(xc_interface *xch, uint32_t domid, int fast)
 {
     return (fast
-            ? xc_domain_resume_cooperative(xc_handle, domid)
-            : xc_domain_resume_any(xc_handle, domid));
+            ? xc_domain_resume_cooperative(xch, domid)
+            : xc_domain_resume_any(xch, domid));
 }
diff --git a/tools/libxc/xc_sedf.c b/tools/libxc/xc_sedf.c
index 20cffa5..c046f38 100644
--- a/tools/libxc/xc_sedf.c
+++ b/tools/libxc/xc_sedf.c
@@ -11,7 +11,7 @@
 #include "xc_private.h"
 
 int xc_sedf_domain_set(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint64_t period,
     uint64_t slice,
@@ -32,11 +32,11 @@ int xc_sedf_domain_set(
     p->latency   = latency;
     p->extratime = extratime;
     p->weight    = weight;
-    return do_domctl(xc_handle, &domctl);
+    return do_domctl(xch, &domctl);
 }
 
 int xc_sedf_domain_get(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint64_t *period,
     uint64_t *slice,
@@ -53,7 +53,7 @@ int xc_sedf_domain_get(
     domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_SEDF;
     domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
 
-    ret = do_domctl(xc_handle, &domctl);
+    ret = do_domctl(xch, &domctl);
 
     *period    = p->period;
     *slice     = p->slice;
diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c
index 99a51ca..b4830de 100644
--- a/tools/libxc/xc_solaris.c
+++ b/tools/libxc/xc_solaris.c
@@ -16,7 +16,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-int xc_interface_open(void)
+int xc_interface_open_core(xc_interface *xch)
 {
     int flags, saved_errno;
     int fd = open("/dev/xen/privcmd", O_RDWR);
@@ -52,17 +52,17 @@ int xc_interface_open(void)
     return -1;
 }
 
-int xc_interface_close(int xc_handle)
+int xc_interface_close(xc_interface *xch, int fd)
 {
-    return close(xc_handle);
+    return close(fd);
 }
 
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
                            xen_pfn_t *arr, int num)
 {
     privcmd_mmapbatch_t ioctlx;
     void *addr;
-    addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xc_handle, 0);
+    addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_SHARED, xch->fd, 0);
     if ( addr == MAP_FAILED )
         return NULL;
 
@@ -70,10 +70,10 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
     ioctlx.dom=dom;
     ioctlx.addr=(unsigned long)addr;
     ioctlx.arr=arr;
-    if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
+    if ( ioctl(xch->fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
     {
         int saved_errno = errno;
-        perror("XXXXXXXX");
+        PERROR("XXXXXXXX");
         (void)munmap(addr, num*PAGE_SIZE);
         errno = saved_errno;
         return NULL;
@@ -82,14 +82,14 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
 
 }
 
-void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+void *xc_map_foreign_range(xc_interface *xch, uint32_t dom,
                            int size, int prot,
                            unsigned long mfn)
 {
     privcmd_mmap_t ioctlx;
     privcmd_mmap_entry_t entry;
     void *addr;
-    addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
+    addr = mmap(NULL, size, prot, MAP_SHARED, xch->fd, 0);
     if ( addr == MAP_FAILED )
         return NULL;
 
@@ -99,7 +99,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     entry.va=(unsigned long) addr;
     entry.mfn=mfn;
     entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
-    if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
+    if ( ioctl(xch->fd, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
     {
         int saved_errno = errno;
         (void)munmap(addr, size);
@@ -109,7 +109,7 @@ void *xc_map_foreign_range(int xc_handle, uint32_t dom,
     return addr;
 }
 
-void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+void *xc_map_foreign_ranges(xc_interface *xch, uint32_t dom,
                             size_t size, int prot, size_t chunksize,
                             privcmd_mmap_entry_t entries[], int nentries)
 {
@@ -117,7 +117,7 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
     int i, rc;
     void *addr;
 
-    addr = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
+    addr = mmap(NULL, size, prot, MAP_SHARED, xch->fd, 0);
     if (addr == MAP_FAILED)
         goto mmap_failed;
 
@@ -130,7 +130,7 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
     ioctlx.dom   = dom;
     ioctlx.entry = entries;
 
-    rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
+    rc = ioctl(xch->fd, IOCTL_PRIVCMD_MMAP, &ioctlx);
     if (rc)
         goto ioctl_failed;
 
@@ -139,21 +139,21 @@ void *xc_map_foreign_ranges(int xc_handle, uint32_t dom,
 ioctl_failed:
     rc = munmap(addr, size);
     if (rc == -1)
-        ERROR("%s: error in error path\n", __FUNCTION__);
+        PERROR("%s: error in error path\n", __FUNCTION__);
 
 mmap_failed:
     return NULL;
 }
 
 
-static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
+static int do_privcmd(xc_interface *xch, unsigned int cmd, unsigned long data)
 {
-    return ioctl(xc_handle, cmd, data);
+    return ioctl(xch->fd, cmd, data);
 }
 
-int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
 {
-    return do_privcmd(xc_handle,
+    return do_privcmd(xch,
                       IOCTL_PRIVCMD_HYPERCALL,
                       (unsigned long)hypercall);
 }
@@ -248,19 +248,19 @@ int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
 }
 
 /* Optionally flush file to disk and discard page cache */
-void discard_file_cache(int fd, int flush) 
+void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
     // TODO: Implement for Solaris!
 }
 
 grant_entry_v1_t *xc_gnttab_map_table_v1(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
 
 grant_entry_v2_t *xc_gnttab_map_table_v2(
-    int xc_handle, int domid, int *gnt_num)
+    xc_interface *xch, int domid, int *gnt_num)
 {
     return NULL;
 }
diff --git a/tools/libxc/xc_suspend.c b/tools/libxc/xc_suspend.c
index a334e82..90958f9 100644
--- a/tools/libxc/xc_suspend.c
+++ b/tools/libxc/xc_suspend.c
@@ -8,7 +8,7 @@
 #include "xenguest.h"
 
 #define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn"
-static int lock_suspend_event(int domid)
+static int lock_suspend_event(xc_interface *xch, int domid)
 {
     int fd, rc;
     mode_t mask;
@@ -34,7 +34,7 @@ static int lock_suspend_event(int domid)
     return rc;
 }
 
-static int unlock_suspend_event(int domid)
+static int unlock_suspend_event(xc_interface *xch, int domid)
 {
     int fd, pid, n;
     char buf[128];
@@ -65,7 +65,7 @@ static int unlock_suspend_event(int domid)
     return -EPERM;
 }
 
-int xc_await_suspend(int xce, int suspend_evtchn)
+int xc_await_suspend(xc_interface *xch, int xce, int suspend_evtchn)
 {
     int rc;
 
@@ -84,19 +84,19 @@ int xc_await_suspend(int xce, int suspend_evtchn)
     return 0;
 }
 
-int xc_suspend_evtchn_release(int xce, int domid, int suspend_evtchn)
+int xc_suspend_evtchn_release(xc_interface *xch, int xce, int domid, int 
suspend_evtchn)
 {
     if (suspend_evtchn >= 0)
         xc_evtchn_unbind(xce, suspend_evtchn);
 
-    return unlock_suspend_event(domid);
+    return unlock_suspend_event(xch, domid);
 }
 
-int xc_suspend_evtchn_init(int xc, int xce, int domid, int port)
+int xc_suspend_evtchn_init(xc_interface *xch, int xce, int domid, int port)
 {
     int rc, suspend_evtchn = -1;
 
-    if (lock_suspend_event(domid))
+    if (lock_suspend_event(xch, domid))
         return -EINVAL;
 
     suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port);
@@ -105,20 +105,20 @@ int xc_suspend_evtchn_init(int xc, int xce, int domid, 
int port)
         goto cleanup;
     }
 
-    rc = xc_domain_subscribe_for_suspend(xc, domid, port);
+    rc = xc_domain_subscribe_for_suspend(xch, domid, port);
     if (rc < 0) {
         ERROR("failed to subscribe to domain: %d", rc);
         goto cleanup;
     }
 
     /* event channel is pending immediately after binding */
-    xc_await_suspend(xce, suspend_evtchn);
+    xc_await_suspend(xch, xce, suspend_evtchn);
 
     return suspend_evtchn;
 
 cleanup:
     if (suspend_evtchn != -1)
-        xc_suspend_evtchn_release(xce, domid, suspend_evtchn);
+        xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
 
     return -1;
 }
diff --git a/tools/libxc/xc_tbuf.c b/tools/libxc/xc_tbuf.c
index aa21d84..6e77ac8 100644
--- a/tools/libxc/xc_tbuf.c
+++ b/tools/libxc/xc_tbuf.c
@@ -17,7 +17,7 @@
 #include "xc_private.h"
 #include <xen/trace.h>
 
-static int tbuf_enable(int xc_handle, int enable)
+static int tbuf_enable(xc_interface *xch, int enable)
 {
     DECLARE_SYSCTL;
 
@@ -28,10 +28,10 @@ static int tbuf_enable(int xc_handle, int enable)
     else
         sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_disable;
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
-int xc_tbuf_set_size(int xc_handle, unsigned long size)
+int xc_tbuf_set_size(xc_interface *xch, unsigned long size)
 {
     DECLARE_SYSCTL;
 
@@ -40,10 +40,10 @@ int xc_tbuf_set_size(int xc_handle, unsigned long size)
     sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_set_size;
     sysctl.u.tbuf_op.size = size;
 
-    return xc_sysctl(xc_handle, &sysctl);
+    return xc_sysctl(xch, &sysctl);
 }
 
-int xc_tbuf_get_size(int xc_handle, unsigned long *size)
+int xc_tbuf_get_size(xc_interface *xch, unsigned long *size)
 {
     struct t_info *t_info;
     int rc;
@@ -53,11 +53,11 @@ int xc_tbuf_get_size(int xc_handle, unsigned long *size)
     sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION;
     sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_get_info;
 
-    rc = xc_sysctl(xc_handle, &sysctl);
+    rc = xc_sysctl(xch, &sysctl);
     if ( rc != 0 )
         return rc;
 
-    t_info = xc_map_foreign_range(xc_handle, DOMID_XEN,
+    t_info = xc_map_foreign_range(xch, DOMID_XEN,
                     sysctl.u.tbuf_op.size, PROT_READ | PROT_WRITE,
                     sysctl.u.tbuf_op.buffer_mfn);
 
@@ -69,7 +69,7 @@ int xc_tbuf_get_size(int xc_handle, unsigned long *size)
     return 0;
 }
 
-int xc_tbuf_enable(int xc_handle, unsigned long pages, unsigned long *mfn,
+int xc_tbuf_enable(xc_interface *xch, unsigned long pages, unsigned long *mfn,
                    unsigned long *size)
 {
     DECLARE_SYSCTL;
@@ -80,16 +80,16 @@ int xc_tbuf_enable(int xc_handle, unsigned long pages, 
unsigned long *mfn,
      * set (since trace buffers cannot be reallocated). If we really have no
      * buffers at all then tbuf_enable() will fail, so this is safe.
      */
-    (void)xc_tbuf_set_size(xc_handle, pages);
+    (void)xc_tbuf_set_size(xch, pages);
 
-    if ( tbuf_enable(xc_handle, 1) != 0 )
+    if ( tbuf_enable(xch, 1) != 0 )
         return -1;
 
     sysctl.cmd = XEN_SYSCTL_tbuf_op;
     sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION;
     sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_get_info;
 
-    rc = xc_sysctl(xc_handle, &sysctl);
+    rc = xc_sysctl(xch, &sysctl);
     if ( rc == 0 )
     {
         *size = sysctl.u.tbuf_op.size;
@@ -99,12 +99,12 @@ int xc_tbuf_enable(int xc_handle, unsigned long pages, 
unsigned long *mfn,
     return 0;
 }
 
-int xc_tbuf_disable(int xc_handle)
+int xc_tbuf_disable(xc_interface *xch)
 {
-    return tbuf_enable(xc_handle, 0);
+    return tbuf_enable(xch, 0);
 }
 
-int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask)
+int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t mask)
 {
     DECLARE_SYSCTL;
     int ret = -1;
@@ -126,7 +126,7 @@ int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask)
         goto out;
     }
 
-    ret = do_sysctl(xc_handle, &sysctl);
+    ret = do_sysctl(xch, &sysctl);
 
     unlock_pages(&bytemap, sizeof(bytemap));
 
@@ -134,7 +134,7 @@ int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask)
     return ret;
 }
 
-int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask)
+int xc_tbuf_set_evt_mask(xc_interface *xch, uint32_t mask)
 {
     DECLARE_SYSCTL;
 
@@ -143,6 +143,6 @@ int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask)
     sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_set_evt_mask;
     sysctl.u.tbuf_op.evt_mask = mask;
 
-    return do_sysctl(xc_handle, &sysctl);
+    return do_sysctl(xch, &sysctl);
 }
 
diff --git a/tools/libxc/xc_tmem.c b/tools/libxc/xc_tmem.c
index 926f848..bccf782 100644
--- a/tools/libxc/xc_tmem.c
+++ b/tools/libxc/xc_tmem.c
@@ -7,7 +7,7 @@
 #include "xc_private.h"
 #include <xen/tmem.h>
 
-static int do_tmem_op(int xc, tmem_op_t *op)
+static int do_tmem_op(xc_interface *xch, tmem_op_t *op)
 {
     int ret;
     DECLARE_HYPERCALL;
@@ -19,7 +19,7 @@ static int do_tmem_op(int xc, tmem_op_t *op)
         PERROR("Could not lock memory for Xen hypercall");
         return -EFAULT;
     }
-    if ((ret = do_xen_hypercall(xc, &hypercall)) < 0)
+    if ((ret = do_xen_hypercall(xch, &hypercall)) < 0)
     {
         if ( errno == EACCES )
             DPRINTF("tmem operation failed -- need to"
@@ -30,7 +30,7 @@ static int do_tmem_op(int xc, tmem_op_t *op)
     return ret;
 }
 
-int xc_tmem_control(int xc,
+int xc_tmem_control(xc_interface *xch,
                     int32_t pool_id,
                     uint32_t subop,
                     uint32_t cli_id,
@@ -64,7 +64,7 @@ int xc_tmem_control(int xc,
         memset(buf, 0, arg1);
 #endif
 
-    rc = do_tmem_op(xc, &op);
+    rc = do_tmem_op(xch, &op);
 
     if (subop == TMEMC_LIST) {
         if (arg1 != 0)
@@ -106,7 +106,7 @@ static int xc_tmem_uuid_parse(char *uuid_str, uint64_t 
*uuid_lo, uint64_t *uuid_
     return 0;
 }
 
-int xc_tmem_auth(int xc,
+int xc_tmem_auth(xc_interface *xch,
                  int cli_id,
                  char *uuid_str,
                  int arg1)
@@ -124,7 +124,7 @@ int xc_tmem_auth(int xc,
         return -1;
     }
 
-    return do_tmem_op(xc, &op);
+    return do_tmem_op(xch, &op);
 }
 
 /* Save/restore/live migrate */
@@ -143,7 +143,8 @@ int xc_tmem_auth(int xc,
  */
 
 /* returns 0 if nothing to save, -1 if error saving, 1 if saved successfully */
-int xc_tmem_save(int xc, int dom, int io_fd, int live, int field_marker)
+int xc_tmem_save(xc_interface *xch,
+                 int dom, int io_fd, int live, int field_marker)
 {
     int marker = field_marker;
     int i, j;
@@ -153,28 +154,28 @@ int xc_tmem_save(int xc, int dom, int io_fd, int live, 
int field_marker)
     uint32_t minusone = -1;
     struct tmem_handle *h;
 
-    if ( xc_tmem_control(xc,0,TMEMC_SAVE_BEGIN,dom,live,0,0,NULL) <= 0 )
+    if ( xc_tmem_control(xch,0,TMEMC_SAVE_BEGIN,dom,live,0,0,NULL) <= 0 )
         return 0;
 
     if ( write_exact(io_fd, &marker, sizeof(marker)) )
         return -1;
-    version = xc_tmem_control(xc,0,TMEMC_SAVE_GET_VERSION,0,0,0,0,NULL);
+    version = xc_tmem_control(xch,0,TMEMC_SAVE_GET_VERSION,0,0,0,0,NULL);
     if ( write_exact(io_fd, &version, sizeof(version)) )
         return -1;
-    max_pools = xc_tmem_control(xc,0,TMEMC_SAVE_GET_MAXPOOLS,0,0,0,0,NULL);
+    max_pools = xc_tmem_control(xch,0,TMEMC_SAVE_GET_MAXPOOLS,0,0,0,0,NULL);
     if ( write_exact(io_fd, &max_pools, sizeof(max_pools)) )
         return -1;
     if ( version == -1 || max_pools == -1 )
         return -1;
     if ( write_exact(io_fd, &minusone, sizeof(minusone)) )
         return -1;
-    flags = xc_tmem_control(xc,0,TMEMC_SAVE_GET_CLIENT_FLAGS,dom,0,0,0,NULL);
+    flags = xc_tmem_control(xch,0,TMEMC_SAVE_GET_CLIENT_FLAGS,dom,0,0,0,NULL);
     if ( write_exact(io_fd, &flags, sizeof(flags)) )
         return -1;
-    weight = xc_tmem_control(xc,0,TMEMC_SAVE_GET_CLIENT_WEIGHT,dom,0,0,0,NULL);
+    weight = 
xc_tmem_control(xch,0,TMEMC_SAVE_GET_CLIENT_WEIGHT,dom,0,0,0,NULL);
     if ( write_exact(io_fd, &weight, sizeof(weight)) )
         return -1;
-    cap = xc_tmem_control(xc,0,TMEMC_SAVE_GET_CLIENT_CAP,dom,0,0,0,NULL);
+    cap = xc_tmem_control(xch,0,TMEMC_SAVE_GET_CLIENT_CAP,dom,0,0,0,NULL);
     if ( write_exact(io_fd, &cap, sizeof(cap)) )
         return -1;
     if ( flags == -1 || weight == -1 || cap == -1 )
@@ -191,14 +192,14 @@ int xc_tmem_save(int xc, int dom, int io_fd, int live, 
int field_marker)
         int checksum = 0;
 
         /* get pool id, flags, pagesize, n_pages, uuid */
-        flags = xc_tmem_control(xc,i,TMEMC_SAVE_GET_POOL_FLAGS,dom,0,0,0,NULL);
+        flags = 
xc_tmem_control(xch,i,TMEMC_SAVE_GET_POOL_FLAGS,dom,0,0,0,NULL);
         if ( flags != -1 )
         {
             pool_id = i;
-            n_pages = 
xc_tmem_control(xc,i,TMEMC_SAVE_GET_POOL_NPAGES,dom,0,0,0,NULL);
+            n_pages = 
xc_tmem_control(xch,i,TMEMC_SAVE_GET_POOL_NPAGES,dom,0,0,0,NULL);
             if ( !(flags & TMEM_POOL_PERSIST) )
                 n_pages = 0;
-            
(void)xc_tmem_control(xc,i,TMEMC_SAVE_GET_POOL_UUID,dom,sizeof(uuid),0,0,&uuid);
+            
(void)xc_tmem_control(xch,i,TMEMC_SAVE_GET_POOL_UUID,dom,sizeof(uuid),0,0,&uuid);
             if ( write_exact(io_fd, &pool_id, sizeof(pool_id)) )
                 return -1;
             if ( write_exact(io_fd, &flags, sizeof(flags)) )
@@ -221,7 +222,7 @@ int xc_tmem_save(int xc, int dom, int io_fd, int live, int 
field_marker)
             for ( j = n_pages; j > 0; j-- )
             {
                 int ret;
-                if ( (ret = xc_tmem_control(xc, pool_id,
+                if ( (ret = xc_tmem_control(xch, pool_id,
                                             TMEMC_SAVE_GET_NEXT_PAGE, dom,
                                             bufsize, 0, 0, buf)) > 0 )
                 {
@@ -258,7 +259,7 @@ int xc_tmem_save(int xc, int dom, int io_fd, int live, int 
field_marker)
 }
 
 /* only called for live migration */
-int xc_tmem_save_extra(int xc, int dom, int io_fd, int field_marker)
+int xc_tmem_save_extra(xc_interface *xch, int dom, int io_fd, int field_marker)
 {
     struct tmem_handle handle;
     int marker = field_marker;
@@ -267,7 +268,7 @@ int xc_tmem_save_extra(int xc, int dom, int io_fd, int 
field_marker)
 
     if ( write_exact(io_fd, &marker, sizeof(marker)) )
         return -1;
-    while ( xc_tmem_control(xc, 0, TMEMC_SAVE_GET_NEXT_INV, dom,
+    while ( xc_tmem_control(xch, 0, TMEMC_SAVE_GET_NEXT_INV, dom,
                             sizeof(handle),0,0,&handle) > 0 ) {
         if ( write_exact(io_fd, &handle.pool_id, sizeof(handle.pool_id)) )
             return -1;
@@ -287,15 +288,15 @@ int xc_tmem_save_extra(int xc, int dom, int io_fd, int 
field_marker)
 }
 
 /* only called for live migration */
-void xc_tmem_save_done(int xc, int dom)
+void xc_tmem_save_done(xc_interface *xch, int dom)
 {
-    xc_tmem_control(xc,0,TMEMC_SAVE_END,dom,0,0,0,NULL);
+    xc_tmem_control(xch,0,TMEMC_SAVE_END,dom,0,0,0,NULL);
 }
 
 /* restore routines */
 
 static int xc_tmem_restore_new_pool(
-                    int xc,
+                    xc_interface *xch,
                     int cli_id,
                     uint32_t pool_id,
                     uint32_t flags,
@@ -311,10 +312,10 @@ static int xc_tmem_restore_new_pool(
     op.u.new.uuid[0] = uuid_lo;
     op.u.new.uuid[1] = uuid_hi;
 
-    return do_tmem_op(xc, &op);
+    return do_tmem_op(xch, &op);
 }
 
-int xc_tmem_restore(int xc, int dom, int io_fd)
+int xc_tmem_restore(xc_interface *xch, int dom, int io_fd)
 {
     uint32_t save_max_pools, save_version;
     uint32_t this_max_pools, this_version;
@@ -323,10 +324,10 @@ int xc_tmem_restore(int xc, int dom, int io_fd)
     uint32_t weight, cap, flags;
     int checksum = 0;
 
-    save_version = xc_tmem_control(xc,0,TMEMC_SAVE_GET_VERSION,dom,0,0,0,NULL);
+    save_version = 
xc_tmem_control(xch,0,TMEMC_SAVE_GET_VERSION,dom,0,0,0,NULL);
     if ( save_version == -1 )
         return -1; /* domain doesn't exist */
-    save_max_pools = 
xc_tmem_control(xc,0,TMEMC_SAVE_GET_MAXPOOLS,0,0,0,0,NULL);
+    save_max_pools = 
xc_tmem_control(xch,0,TMEMC_SAVE_GET_MAXPOOLS,0,0,0,0,NULL);
     if ( read_exact(io_fd, &this_version, sizeof(this_version)) )
         return -1;
     if ( read_exact(io_fd, &this_max_pools, sizeof(this_max_pools)) )
@@ -336,23 +337,23 @@ int xc_tmem_restore(int xc, int dom, int io_fd)
         return -1;
     if ( minusone != -1 )
         return -1;
-    if ( xc_tmem_control(xc,0,TMEMC_RESTORE_BEGIN,dom,0,0,0,NULL) < 0 )
+    if ( xc_tmem_control(xch,0,TMEMC_RESTORE_BEGIN,dom,0,0,0,NULL) < 0 )
         return -1;
     if ( read_exact(io_fd, &flags, sizeof(flags)) )
         return -1;
     if ( flags & TMEM_CLIENT_COMPRESS )
-        if ( xc_tmem_control(xc,0,TMEMC_SET_COMPRESS,dom,1,0,0,NULL) < 0 )
+        if ( xc_tmem_control(xch,0,TMEMC_SET_COMPRESS,dom,1,0,0,NULL) < 0 )
             return -1;
     if ( flags & TMEM_CLIENT_FROZEN )
-        if ( xc_tmem_control(xc,0,TMEMC_FREEZE,dom,0,0,0,NULL) < 0 )
+        if ( xc_tmem_control(xch,0,TMEMC_FREEZE,dom,0,0,0,NULL) < 0 )
             return -1;
     if ( read_exact(io_fd, &weight, sizeof(weight)) )
         return -1;
-    if ( xc_tmem_control(xc,0,TMEMC_SET_WEIGHT,dom,0,0,0,NULL) < 0 )
+    if ( xc_tmem_control(xch,0,TMEMC_SET_WEIGHT,dom,0,0,0,NULL) < 0 )
         return -1;
     if ( read_exact(io_fd, &cap, sizeof(cap)) )
         return -1;
-    if ( xc_tmem_control(xc,0,TMEMC_SET_CAP,dom,0,0,0,NULL) < 0 )
+    if ( xc_tmem_control(xch,0,TMEMC_SET_CAP,dom,0,0,0,NULL) < 0 )
         return -1;
     if ( read_exact(io_fd, &minusone, sizeof(minusone)) )
         return -1;
@@ -370,7 +371,7 @@ int xc_tmem_restore(int xc, int dom, int io_fd)
             return -1;
         if ( read_exact(io_fd, &uuid, sizeof(uuid)) )
             return -1;
-        if ( xc_tmem_restore_new_pool(xc, dom, pool_id,
+        if ( xc_tmem_restore_new_pool(xch, dom, pool_id,
                                  flags, uuid[0], uuid[1]) < 0)
             return -1;
         if ( n_pages <= 0 )
@@ -398,7 +399,7 @@ int xc_tmem_restore(int xc, int dom, int io_fd)
             if ( read_exact(io_fd, buf, pagesize) )
                 return -1;
             checksum += *buf;
-            if ( (rc = xc_tmem_control(xc, pool_id, TMEMC_RESTORE_PUT_PAGE,
+            if ( (rc = xc_tmem_control(xch, pool_id, TMEMC_RESTORE_PUT_PAGE,
                                  dom, bufsize, index, oid, buf)) <= 0 )
             {
                 DPRINTF("xc_tmem_restore: putting page failed, rc=%d\n",rc);
@@ -416,7 +417,7 @@ int xc_tmem_restore(int xc, int dom, int io_fd)
 }
 
 /* only called for live migration, must be called after suspend */
-int xc_tmem_restore_extra(int xc, int dom, int io_fd)
+int xc_tmem_restore_extra(xc_interface *xch, int dom, int io_fd)
 {
     uint32_t pool_id;
     uint64_t oid;
@@ -430,7 +431,7 @@ int xc_tmem_restore_extra(int xc, int dom, int io_fd)
             return -1;
         if ( read_exact(io_fd, &index, sizeof(index)) )
             return -1;
-        if ( xc_tmem_control(xc, pool_id, TMEMC_RESTORE_FLUSH_PAGE, dom,
+        if ( xc_tmem_control(xch, pool_id, TMEMC_RESTORE_FLUSH_PAGE, dom,
                              0,index,oid,NULL) <= 0 )
             return -1;
         count++;
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index f63f96d..b171d08 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -35,6 +35,8 @@
 #include <xen/xsm/flask_op.h>
 #include <xen/tmem.h>
 
+#include "xentoollog.h"
+
 #if defined(__i386__) || defined(__x86_64__)
 #include <xen/foreign/x86_32.h>
 #include <xen/foreign/x86_64.h>
@@ -71,6 +73,27 @@
 #error "Define barriers"
 #endif
 
+
+/*
+ *  GENERAL
+ *
+ * Unless otherwise specified, each function here returns zero or a
+ * non-null pointer on success; or in case of failure, sets errno and
+ * returns -1 or a null pointer.
+ *
+ * Unless otherwise specified, errors result in a call to the error
+ * handler function, which by default prints a message to the
+ * FILE* passed as the caller_data, which by default is stderr.
+ * (This is described below as "logging errors".)
+ *
+ * The error handler can safely trash errno, as libxc saves it across
+ * the callback.
+ */
+
+typedef struct xc_interface xc_interface;
+typedef enum xc_error_code xc_error_code;
+
+
 /*
  *  INITIALIZATION FUNCTIONS
  */
@@ -86,20 +109,30 @@
  * This function can fail if the caller does not have superuser permission or
  * if a Xen-enabled kernel is not currently running.
  *
- * @return a handle to the hypervisor interface or -1 on failure
+ * @return a handle to the hypervisor interface
  */
-int xc_interface_open(void);
+xc_interface *xc_interface_open(xentoollog_logger *logger,
+                                xentoollog_logger *dombuild_logger,
+                                unsigned open_flags);
+  /* if logger==NULL, will log to stderr
+   * if dombuild_logger=NULL, will log to a file
+   */
+
+enum xc_open_flags {
+    XC_OPENFLAG_DUMMY =  01, /* do not actually open a xenctrl interface */
+};
 
 /**
  * This function closes an open hypervisor interface.
  *
  * This function can fail if the handle does not represent an open interface or
- * if there were problems closing the interface.
+ * if there were problems closing the interface.  In the latter case
+ * the interface is still closed.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @return 0 on success, -1 otherwise.
  */
-int xc_interface_close(int xc_handle);
+int xc_interface_close(xc_interface *xch);
 
 /*
  * KERNEL INTERFACES
@@ -139,14 +172,14 @@ void xc_register_event_handler(
     td_event_e e);
 
 long xc_ptrace(
-    int xc_handle,
+    xc_interface *xch,
     enum __ptrace_request request,
     uint32_t  domid,
     long addr,
     long data);
 
 int xc_waitdomain(
-    int xc_handle,
+    xc_interface *xch,
     int domain,
     int *status,
     int options);
@@ -205,7 +238,7 @@ typedef union
 } start_info_any_t;
 
 
-int xc_domain_create(int xc_handle,
+int xc_domain_create(xc_interface *xch,
                      uint32_t ssidref,
                      xen_domain_handle_t handle,
                      uint32_t flags,
@@ -217,7 +250,7 @@ int xc_domain_create(int xc_handle,
  *  xc_domain_dumpcore_via_callback - produces a dump, using a specified
  *                                    callback function
  */
-int xc_domain_dumpcore(int xc_handle,
+int xc_domain_dumpcore(xc_interface *xch,
                        uint32_t domid,
                        const char *corename);
 
@@ -227,9 +260,10 @@ int xc_domain_dumpcore(int xc_handle,
  * and passes an opaque object for the use of the function and
  * created by the caller of xc_domain_dumpcore_via_callback.
  */
-typedef int (dumpcore_rtn_t)(void *arg, char *buffer, unsigned int length);
+typedef int (dumpcore_rtn_t)(xc_interface *xch,
+                             void *arg, char *buffer, unsigned int length);
 
-int xc_domain_dumpcore_via_callback(int xc_handle,
+int xc_domain_dumpcore_via_callback(xc_interface *xch,
                                     uint32_t domid,
                                     void *arg,
                                     dumpcore_rtn_t dump_rtn);
@@ -237,12 +271,12 @@ int xc_domain_dumpcore_via_callback(int xc_handle,
 /*
  * This function sets the maximum number of vcpus that a domain may create.
  *
- * @parm xc_handle a handle to an open hypervisor interface.
+ * @parm xch a handle to an open hypervisor interface.
  * @parm domid the domain id in which vcpus are to be created.
  * @parm max the maximum number of vcpus that the domain may create.
  * @return 0 on success, -1 on failure.
  */
-int xc_domain_max_vcpus(int xc_handle,
+int xc_domain_max_vcpus(xc_interface *xch,
                         uint32_t domid,
                         unsigned int max);
 
@@ -250,21 +284,21 @@ int xc_domain_max_vcpus(int xc_handle,
  * This function pauses a domain. A paused domain still exists in memory
  * however it does not receive any timeslices from the hypervisor.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to pause
  * @return 0 on success, -1 on failure.
  */
-int xc_domain_pause(int xc_handle,
+int xc_domain_pause(xc_interface *xch,
                     uint32_t domid);
 /**
  * This function unpauses a domain.  The domain should have been previously
  * paused.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to unpause
  * return 0 on success, -1 on failure
  */
-int xc_domain_unpause(int xc_handle,
+int xc_domain_unpause(xc_interface *xch,
                       uint32_t domid);
 
 /**
@@ -272,11 +306,11 @@ int xc_domain_unpause(int xc_handle,
  * completely from memory.  This function should be called after sending the
  * domain a SHUTDOWN control message to free up the domain resources.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to destroy
  * @return 0 on success, -1 on failure
  */
-int xc_domain_destroy(int xc_handle,
+int xc_domain_destroy(xc_interface *xch,
                       uint32_t domid);
 
 
@@ -284,12 +318,12 @@ int xc_domain_destroy(int xc_handle,
  * This function resumes a suspended domain. The domain should have
  * been previously suspended.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to resume
  * @parm fast use cooperative resume (guest must support this)
  * return 0 on success, -1 on failure
  */
-int xc_domain_resume(int xc_handle,
+int xc_domain_resume(xc_interface *xch,
                     uint32_t domid,
                     int fast);
 
@@ -299,21 +333,21 @@ int xc_domain_resume(int xc_handle,
  * sched_op operations in a paravirtualized domain. The caller is
  * expected to give the reason for the shutdown.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to destroy
  * @parm reason is the reason (SHUTDOWN_xxx) for the shutdown
  * @return 0 on success, -1 on failure
  */
-int xc_domain_shutdown(int xc_handle,
+int xc_domain_shutdown(xc_interface *xch,
                        uint32_t domid,
                        int reason);
 
-int xc_vcpu_setaffinity(int xc_handle,
+int xc_vcpu_setaffinity(xc_interface *xch,
                         uint32_t domid,
                         int vcpu,
                         uint64_t *cpumap,
                         int cpusize);
-int xc_vcpu_getaffinity(int xc_handle,
+int xc_vcpu_getaffinity(xc_interface *xch,
                         uint32_t domid,
                         int vcpu,
                         uint64_t *cpumap,
@@ -326,7 +360,7 @@ int xc_vcpu_getaffinity(int xc_handle,
  * one exists. It is, therefore, important in this case to make sure the
  * domain requested was the one returned.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm first_domid the first domain to enumerate information from.  Domains
  *                   are currently enumerate in order of creation.
  * @parm max_doms the number of elements in info
@@ -334,7 +368,7 @@ int xc_vcpu_getaffinity(int xc_handle,
  *            the enumerated domains.
  * @return the number of domains enumerated or -1 on error
  */
-int xc_domain_getinfo(int xc_handle,
+int xc_domain_getinfo(xc_interface *xch,
                       uint32_t first_domid,
                       unsigned int max_doms,
                       xc_dominfo_t *info);
@@ -343,13 +377,13 @@ int xc_domain_getinfo(int xc_handle,
 /**
  * This function will set the execution context for the specified vcpu.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to set the vcpu context for
  * @parm vcpu the vcpu number for the context
  * @parm ctxt pointer to the the cpu context with the values to set
  * @return the number of domains enumerated or -1 on error
  */
-int xc_vcpu_setcontext(int xc_handle,
+int xc_vcpu_setcontext(xc_interface *xch,
                        uint32_t domid,
                        uint32_t vcpu,
                        vcpu_guest_context_any_t *ctxt);
@@ -358,7 +392,7 @@ int xc_vcpu_setcontext(int xc_handle,
  * single hypercall.  The domain information will be stored into the supplied
  * array of xc_domaininfo_t structures.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm first_domain the first domain to enumerate information from.
  *                    Domains are currently enumerate in order of creation.
  * @parm max_domains the number of elements in info
@@ -366,21 +400,21 @@ int xc_vcpu_setcontext(int xc_handle,
  *            the enumerated domains.
  * @return the number of domains enumerated or -1 on error
  */
-int xc_domain_getinfolist(int xc_handle,
+int xc_domain_getinfolist(xc_interface *xch,
                           uint32_t first_domain,
                           unsigned int max_domains,
                           xc_domaininfo_t *info);
 
 /**
  * This function returns information about the context of a hvm domain
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
  * @parm ctxt_buf a pointer to a structure to store the execution context of
  *            the hvm domain
  * @parm size the size of ctxt_buf in bytes
  * @return 0 on success, -1 on failure
  */
-int xc_domain_hvm_getcontext(int xc_handle,
+int xc_domain_hvm_getcontext(xc_interface *xch,
                              uint32_t domid,
                              uint8_t *ctxt_buf,
                              uint32_t size);
@@ -388,7 +422,7 @@ int xc_domain_hvm_getcontext(int xc_handle,
 
 /**
  * This function returns one element of the context of a hvm domain
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
  * @parm typecode which type of elemnt required 
  * @parm instance which instance of the type
@@ -397,7 +431,7 @@ int xc_domain_hvm_getcontext(int xc_handle,
  * @parm size the size of ctxt_buf (must be >= HVM_SAVE_LENGTH(typecode))
  * @return 0 on success, -1 on failure
  */
-int xc_domain_hvm_getcontext_partial(int xc_handle,
+int xc_domain_hvm_getcontext_partial(xc_interface *xch,
                                      uint32_t domid,
                                      uint16_t typecode,
                                      uint16_t instance,
@@ -407,13 +441,13 @@ int xc_domain_hvm_getcontext_partial(int xc_handle,
 /**
  * This function will set the context for hvm domain
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to set the hvm domain context for
  * @parm hvm_ctxt pointer to the the hvm context with the values to set
  * @parm size the size of hvm_ctxt in bytes
  * @return 0 on success, -1 on failure
  */
-int xc_domain_hvm_setcontext(int xc_handle,
+int xc_domain_hvm_setcontext(xc_interface *xch,
                              uint32_t domid,
                              uint8_t *hvm_ctxt,
                              uint32_t size);
@@ -422,33 +456,33 @@ int xc_domain_hvm_setcontext(int xc_handle,
  * This function returns information about the execution context of a
  * particular vcpu of a domain.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to get information from
  * @parm vcpu the vcpu number
  * @parm ctxt a pointer to a structure to store the execution context of the
  *            domain
  * @return 0 on success, -1 on failure
  */
-int xc_vcpu_getcontext(int xc_handle,
+int xc_vcpu_getcontext(xc_interface *xch,
                        uint32_t domid,
                        uint32_t vcpu,
                        vcpu_guest_context_any_t *ctxt);
 
 typedef xen_domctl_getvcpuinfo_t xc_vcpuinfo_t;
-int xc_vcpu_getinfo(int xc_handle,
+int xc_vcpu_getinfo(xc_interface *xch,
                     uint32_t domid,
                     uint32_t vcpu,
                     xc_vcpuinfo_t *info);
 
-long long xc_domain_get_cpu_usage(int xc_handle,
+long long xc_domain_get_cpu_usage(xc_interface *xch,
                                   domid_t domid,
                                   int vcpu);
 
-int xc_domain_sethandle(int xc_handle, uint32_t domid,
+int xc_domain_sethandle(xc_interface *xch, uint32_t domid,
                         xen_domain_handle_t handle);
 
 typedef xen_domctl_shadow_op_stats_t xc_shadow_op_stats_t;
-int xc_shadow_control(int xc_handle,
+int xc_shadow_control(xc_interface *xch,
                       uint32_t domid,
                       unsigned int sop,
                       unsigned long *dirty_bitmap,
@@ -457,44 +491,44 @@ int xc_shadow_control(int xc_handle,
                       uint32_t mode,
                       xc_shadow_op_stats_t *stats);
 
-int xc_sedf_domain_set(int xc_handle,
+int xc_sedf_domain_set(xc_interface *xch,
                        uint32_t domid,
                        uint64_t period, uint64_t slice,
                        uint64_t latency, uint16_t extratime,
                        uint16_t weight);
 
-int xc_sedf_domain_get(int xc_handle,
+int xc_sedf_domain_get(xc_interface *xch,
                        uint32_t domid,
                        uint64_t* period, uint64_t *slice,
                        uint64_t *latency, uint16_t *extratime,
                        uint16_t *weight);
 
-int xc_sched_credit_domain_set(int xc_handle,
+int xc_sched_credit_domain_set(xc_interface *xch,
                                uint32_t domid,
                                struct xen_domctl_sched_credit *sdom);
 
-int xc_sched_credit_domain_get(int xc_handle,
+int xc_sched_credit_domain_get(xc_interface *xch,
                                uint32_t domid,
                                struct xen_domctl_sched_credit *sdom);
 
-int xc_sched_credit2_domain_set(int xc_handle,
+int xc_sched_credit2_domain_set(xc_interface *xch,
                                uint32_t domid,
                                struct xen_domctl_sched_credit2 *sdom);
 
-int xc_sched_credit2_domain_get(int xc_handle,
+int xc_sched_credit2_domain_get(xc_interface *xch,
                                uint32_t domid,
                                struct xen_domctl_sched_credit2 *sdom);
 
 /**
  * This function sends a trigger to a domain.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to send trigger
  * @parm trigger the trigger type
  * @parm vcpu the vcpu number to send trigger 
  * return 0 on success, -1 on failure
  */
-int xc_domain_send_trigger(int xc_handle,
+int xc_domain_send_trigger(xc_interface *xch,
                            uint32_t domid,
                            uint32_t trigger,
                            uint32_t vcpu);
@@ -502,12 +536,12 @@ int xc_domain_send_trigger(int xc_handle,
 /**
  * This function enables or disable debugging of a domain.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain id to send trigger
  * @parm enable true to enable debugging
  * return 0 on success, -1 on failure
  */
-int xc_domain_setdebugging(int xc_handle,
+int xc_domain_setdebugging(xc_interface *xch,
                            uint32_t domid,
                            unsigned int enable);
 
@@ -530,7 +564,7 @@ typedef struct xc_cpupoolinfo {
  * @parm sched_id id of scheduler to use for pool
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_create(int xc_handle,
+int xc_cpupool_create(xc_interface *xch,
                       uint32_t *ppoolid,
                       uint32_t sched_id);
 
@@ -541,7 +575,7 @@ int xc_cpupool_create(int xc_handle,
  * @parm poolid id of the cpupool to destroy
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_destroy(int xc_handle,
+int xc_cpupool_destroy(xc_interface *xch,
                        uint32_t poolid);
 
 /**
@@ -553,7 +587,7 @@ int xc_cpupool_destroy(int xc_handle,
  * @parm info pointer to xc_cpupoolinfo_t array
  * return number of cpupool infos
  */
-int xc_cpupool_getinfo(int xc_handle,
+int xc_cpupool_getinfo(xc_interface *xch,
                        uint32_t first_poolid,
                        uint32_t n_max,
                        xc_cpupoolinfo_t *info);
@@ -566,7 +600,7 @@ int xc_cpupool_getinfo(int xc_handle,
  * @parm cpu cpu number to add
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_addcpu(int xc_handle,
+int xc_cpupool_addcpu(xc_interface *xch,
                       uint32_t poolid,
                       int cpu);
 
@@ -578,7 +612,7 @@ int xc_cpupool_addcpu(int xc_handle,
  * @parm cpu cpu number to remove
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_removecpu(int xc_handle,
+int xc_cpupool_removecpu(xc_interface *xch,
                          uint32_t poolid,
                          int cpu);
 
@@ -590,7 +624,7 @@ int xc_cpupool_removecpu(int xc_handle,
  * @parm domid id of the domain to move
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_movedomain(int xc_handle,
+int xc_cpupool_movedomain(xc_interface *xch,
                           uint32_t poolid,
                           uint32_t domid);
 
@@ -601,12 +635,14 @@ int xc_cpupool_movedomain(int xc_handle,
  * @parm cpumap pointer where to store the cpumap
  * return 0 on success, -1 on failure
  */
-int xc_cpupool_freeinfo(int xc_handle,
+int xc_cpupool_freeinfo(xc_interface *xch,
                         uint64_t *cpumap);
 
 
 /*
  * EVENT CHANNEL FUNCTIONS
+ *
+ * None of these do any logging.
  */
 
 /* A port identifier is guaranteed to fit in 31 bits. */
@@ -621,25 +657,27 @@ typedef int evtchn_port_or_error_t;
  * use xc_evtchn_bind_unbound_port(). This function is intended for allocating
  * ports *only* during domain creation.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm dom the ID of the local domain (the 'allocatee')
  * @parm remote_dom the ID of the domain who will later bind
  * @return allocated port (in @dom) on success, -1 on failure
  */
 evtchn_port_or_error_t
-xc_evtchn_alloc_unbound(int xc_handle,
+xc_evtchn_alloc_unbound(xc_interface *xch,
                         uint32_t dom,
                         uint32_t remote_dom);
 
-int xc_evtchn_reset(int xc_handle,
+int xc_evtchn_reset(xc_interface *xch,
                     uint32_t dom);
 
 typedef struct evtchn_status xc_evtchn_status_t;
-int xc_evtchn_status(int xc_handle, xc_evtchn_status_t *status);
+int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status);
 
 /*
  * Return a handle to the event channel driver, or -1 on failure, in which case
  * errno will be set appropriately.
+ *
+ * Before Xen pre-4.1 this function would sometimes report errors with perror.
  */
 int xc_evtchn_open(void);
 
@@ -701,19 +739,19 @@ xc_evtchn_pending(int xce_handle);
  */
 int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
 
-int xc_physdev_pci_access_modify(int xc_handle,
+int xc_physdev_pci_access_modify(xc_interface *xch,
                                  uint32_t domid,
                                  int bus,
                                  int dev,
                                  int func,
                                  int enable);
 
-int xc_readconsolering(int xc_handle,
+int xc_readconsolering(xc_interface *xch,
                        char **pbuffer,
                        unsigned int *pnr_chars,
                        int clear, int incremental, uint32_t *pindex);
 
-int xc_send_debug_keys(int xc_handle, char *keys);
+int xc_send_debug_keys(xc_interface *xch, char *keys);
 
 typedef xen_sysctl_physinfo_t xc_physinfo_t;
 typedef xen_sysctl_topologyinfo_t xc_topologyinfo_t;
@@ -726,109 +764,109 @@ typedef uint64_t xc_node_to_memsize_t;
 typedef uint64_t xc_node_to_memfree_t;
 typedef uint32_t xc_node_to_node_dist_t;
 
-int xc_physinfo(int xc_handle, xc_physinfo_t *info);
-int xc_topologyinfo(int xc_handle, xc_topologyinfo_t *info);
-int xc_numainfo(int xc_handle, xc_numainfo_t *info);
+int xc_physinfo(xc_interface *xch, xc_physinfo_t *info);
+int xc_topologyinfo(xc_interface *xch, xc_topologyinfo_t *info);
+int xc_numainfo(xc_interface *xch, xc_numainfo_t *info);
 
-int xc_sched_id(int xc_handle,
+int xc_sched_id(xc_interface *xch,
                 int *sched_id);
 
 typedef xen_sysctl_cpuinfo_t xc_cpuinfo_t;
-int xc_getcpuinfo(int xc_handle, int max_cpus,
+int xc_getcpuinfo(xc_interface *xch, int max_cpus,
                   xc_cpuinfo_t *info, int *nr_cpus); 
 
-int xc_domain_setmaxmem(int xc_handle,
+int xc_domain_setmaxmem(xc_interface *xch,
                         uint32_t domid,
                         unsigned int max_memkb);
 
-int xc_domain_set_memmap_limit(int xc_handle,
+int xc_domain_set_memmap_limit(xc_interface *xch,
                                uint32_t domid,
                                unsigned long map_limitkb);
 
-int xc_domain_set_time_offset(int xc_handle,
+int xc_domain_set_time_offset(xc_interface *xch,
                               uint32_t domid,
                               int32_t time_offset_seconds);
 
-int xc_domain_set_tsc_info(int xc_handle,
+int xc_domain_set_tsc_info(xc_interface *xch,
                            uint32_t domid,
                            uint32_t tsc_mode,
                            uint64_t elapsed_nsec,
                            uint32_t gtsc_khz,
                            uint32_t incarnation);
 
-int xc_domain_get_tsc_info(int xc_handle,
+int xc_domain_get_tsc_info(xc_interface *xch,
                            uint32_t domid,
                            uint32_t *tsc_mode,
                            uint64_t *elapsed_nsec,
                            uint32_t *gtsc_khz,
                            uint32_t *incarnation);
 
-int xc_domain_disable_migrate(int xc_handle, uint32_t domid);
+int xc_domain_disable_migrate(xc_interface *xch, uint32_t domid);
 
-int xc_domain_memory_increase_reservation(int xc_handle,
+int xc_domain_memory_increase_reservation(xc_interface *xch,
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
                                           unsigned int mem_flags,
                                           xen_pfn_t *extent_start);
 
-int xc_domain_memory_decrease_reservation(int xc_handle,
+int xc_domain_memory_decrease_reservation(xc_interface *xch,
                                           uint32_t domid,
                                           unsigned long nr_extents,
                                           unsigned int extent_order,
                                           xen_pfn_t *extent_start);
 
-int xc_domain_memory_populate_physmap(int xc_handle,
+int xc_domain_memory_populate_physmap(xc_interface *xch,
                                       uint32_t domid,
                                       unsigned long nr_extents,
                                       unsigned int extent_order,
                                       unsigned int mem_flags,
                                       xen_pfn_t *extent_start);
 
-int xc_domain_memory_set_pod_target(int xc_handle,
+int xc_domain_memory_set_pod_target(xc_interface *xch,
                                     uint32_t domid,
                                     uint64_t target_pages,
                                     uint64_t *tot_pages,
                                     uint64_t *pod_cache_pages,
                                     uint64_t *pod_entries);
 
-int xc_domain_memory_get_pod_target(int xc_handle,
+int xc_domain_memory_get_pod_target(xc_interface *xch,
                                     uint32_t domid,
                                     uint64_t *tot_pages,
                                     uint64_t *pod_cache_pages,
                                     uint64_t *pod_entries);
 
-int xc_domain_ioport_permission(int xc_handle,
+int xc_domain_ioport_permission(xc_interface *xch,
                                 uint32_t domid,
                                 uint32_t first_port,
                                 uint32_t nr_ports,
                                 uint32_t allow_access);
 
-int xc_domain_irq_permission(int xc_handle,
+int xc_domain_irq_permission(xc_interface *xch,
                              uint32_t domid,
                              uint8_t pirq,
                              uint8_t allow_access);
 
-int xc_domain_iomem_permission(int xc_handle,
+int xc_domain_iomem_permission(xc_interface *xch,
                                uint32_t domid,
                                unsigned long first_mfn,
                                unsigned long nr_mfns,
                                uint8_t allow_access);
 
-int xc_domain_pin_memory_cacheattr(int xc_handle,
+int xc_domain_pin_memory_cacheattr(xc_interface *xch,
                                    uint32_t domid,
                                    uint64_t start,
                                    uint64_t end,
                                    uint32_t type);
 
-unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
+unsigned long xc_make_page_below_4G(xc_interface *xch, uint32_t domid,
                                     unsigned long mfn);
 
 typedef xen_sysctl_perfc_desc_t xc_perfc_desc_t;
 typedef xen_sysctl_perfc_val_t xc_perfc_val_t;
 /* IMPORTANT: The caller is responsible for mlock()'ing the @desc and @val
    arrays. */
-int xc_perfc_control(int xc_handle,
+int xc_perfc_control(xc_interface *xch,
                      uint32_t op,
                      xc_perfc_desc_t *desc,
                      xc_perfc_val_t *val,
@@ -837,7 +875,7 @@ int xc_perfc_control(int xc_handle,
 
 typedef xen_sysctl_lockprof_data_t xc_lockprof_data_t;
 /* IMPORTANT: The caller is responsible for mlock()'ing the @data array. */
-int xc_lockprof_control(int xc_handle,
+int xc_lockprof_control(xc_interface *xch,
                         uint32_t opcode,
                         uint32_t *n_elems,
                         uint64_t *time,
@@ -852,17 +890,17 @@ int xc_lockprof_control(int xc_handle,
  * the shared_info_frame (from xc_domain_getinfo()) + 2048.  The structure
  * stored there is of type control_if_t.
  *
- * @parm xc_handle a handle on an open hypervisor interface
+ * @parm xch a handle on an open hypervisor interface
  * @parm dom the domain to map memory from
  * @parm size the amount of memory to map (in multiples of page size)
  * @parm prot same flag as in mmap().
  * @parm mfn the frame address to map.
  */
-void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+void *xc_map_foreign_range(xc_interface *xch, uint32_t dom,
                             int size, int prot,
                             unsigned long mfn );
 
-void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_pages(xc_interface *xch, uint32_t dom, int prot,
                            const xen_pfn_t *arr, int num );
 
 /**
@@ -872,7 +910,7 @@ void *xc_map_foreign_pages(int xc_handle, uint32_t dom, int 
prot,
  * When a page cannot be mapped, its PFN in @arr is or'ed with
  * 0xF0000000 to indicate the error.
  */
-void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_batch(xc_interface *xch, uint32_t dom, int prot,
                            xen_pfn_t *arr, int num );
 
 /**
@@ -880,7 +918,7 @@ void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int 
prot,
  * When a page cannot be mapped, its respective field in @err is
  * set to the corresponding errno value.
  */
-void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, int prot,
+void *xc_map_foreign_bulk(xc_interface *xch, uint32_t dom, int prot,
                           const xen_pfn_t *arr, int *err, unsigned int num);
 
 /**
@@ -888,12 +926,12 @@ void *xc_map_foreign_bulk(int xc_handle, uint32_t dom, 
int prot,
  * vcpu returning the GFN containing the address (that is, an MFN for 
  * PV guests, a PFN for HVM guests).  Returns 0 for failure.
  *
- * @parm xc_handle a handle on an open hypervisor interface
+ * @parm xch a handle on an open hypervisor interface
  * @parm dom the domain to perform the translation in
  * @parm vcpu the vcpu to perform the translation on
  * @parm virt the virtual address to translate
  */
-unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
+unsigned long xc_translate_foreign_address(xc_interface *xch, uint32_t dom,
                                            int vcpu, unsigned long long virt);
 
 
@@ -901,33 +939,33 @@ unsigned long xc_translate_foreign_address(int xc_handle, 
uint32_t dom,
  * DEPRECATED.  Avoid using this, as it does not correctly account for PFNs
  * without a backing MFN.
  */
-int xc_get_pfn_list(int xc_handle, uint32_t domid, uint64_t *pfn_buf,
+int xc_get_pfn_list(xc_interface *xch, uint32_t domid, uint64_t *pfn_buf,
                     unsigned long max_pfns);
 
 unsigned long xc_ia64_fpsr_default(void);
 
-int xc_copy_to_domain_page(int xc_handle, uint32_t domid,
+int xc_copy_to_domain_page(xc_interface *xch, uint32_t domid,
                            unsigned long dst_pfn, const char *src_page);
 
-int xc_clear_domain_page(int xc_handle, uint32_t domid,
+int xc_clear_domain_page(xc_interface *xch, uint32_t domid,
                          unsigned long dst_pfn);
 
-long xc_get_max_pages(int xc_handle, uint32_t domid);
+long xc_get_max_pages(xc_interface *xch, uint32_t domid);
 
-int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops,
+int xc_mmuext_op(xc_interface *xch, struct mmuext_op *op, unsigned int nr_ops,
                  domid_t dom);
 
-int xc_memory_op(int xc_handle, int cmd, void *arg);
+int xc_memory_op(xc_interface *xch, int cmd, void *arg);
 
 
 /* Get current total pages allocated to a domain. */
-long xc_get_tot_pages(int xc_handle, uint32_t domid);
+long xc_get_tot_pages(xc_interface *xch, uint32_t domid);
 
 /**
  * This function retrieves the the number of bytes available
  * in the heap in a specific range of address-widths and nodes.
  * 
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the domain to query
  * @parm min_width the smallest address width to query (0 if don't care)
  * @parm max_width the largest address width to query (0 if don't care)
@@ -935,7 +973,7 @@ long xc_get_tot_pages(int xc_handle, uint32_t domid);
  * @parm *bytes caller variable to put total bytes counted
  * @return 0 on success, <0 on failure.
  */
-int xc_availheap(int xc_handle, int min_width, int max_width, int node,
+int xc_availheap(xc_interface *xch, int min_width, int max_width, int node,
                  uint64_t *bytes);
 
 /*
@@ -945,7 +983,7 @@ int xc_availheap(int xc_handle, int min_width, int 
max_width, int node,
 /**
  * xc_tbuf_enable - enable tracing buffers
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm cnt size of tracing buffers to create (in pages)
  * @parm mfn location to store mfn of the trace buffers to
  * @parm size location to store the size (in bytes) of a trace buffer to
@@ -953,13 +991,13 @@ int xc_availheap(int xc_handle, int min_width, int 
max_width, int node,
  * Gets the machine address of the trace pointer area and the size of the
  * per CPU buffers.
  */
-int xc_tbuf_enable(int xc_handle, unsigned long pages,
+int xc_tbuf_enable(xc_interface *xch, unsigned long pages,
                    unsigned long *mfn, unsigned long *size);
 
 /*
  * Disable tracing buffers.
  */
-int xc_tbuf_disable(int xc_handle);
+int xc_tbuf_disable(xc_interface *xch);
 
 /**
  * This function sets the size of the trace buffers. Setting the size
@@ -967,67 +1005,72 @@ int xc_tbuf_disable(int xc_handle);
  * time or via this interface, not both. The buffer size must be set before
  * enabling tracing.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm size the size in pages per cpu for the trace buffers
  * @return 0 on success, -1 on failure.
  */
-int xc_tbuf_set_size(int xc_handle, unsigned long size);
+int xc_tbuf_set_size(xc_interface *xch, unsigned long size);
 
 /**
  * This function retrieves the current size of the trace buffers.
  * Note that the size returned is in terms of bytes, not pages.
 
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm size will contain the size in bytes for the trace buffers
  * @return 0 on success, -1 on failure.
  */
-int xc_tbuf_get_size(int xc_handle, unsigned long *size);
+int xc_tbuf_get_size(xc_interface *xch, unsigned long *size);
 
-int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask);
+int xc_tbuf_set_cpu_mask(xc_interface *xch, uint32_t mask);
 
-int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask);
+int xc_tbuf_set_evt_mask(xc_interface *xch, uint32_t mask);
 
-int xc_domctl(int xc_handle, struct xen_domctl *domctl);
-int xc_sysctl(int xc_handle, struct xen_sysctl *sysctl);
+int xc_domctl(xc_interface *xch, struct xen_domctl *domctl);
+int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl);
 
-int xc_version(int xc_handle, int cmd, void *arg);
+int xc_version(xc_interface *xch, int cmd, void *arg);
 
-int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned long arg_size);
+int xc_acm_op(xc_interface *xch, int cmd, void *arg, unsigned long arg_size);
 
-int xc_flask_op(int xc_handle, flask_op_t *op);
+int xc_flask_op(xc_interface *xch, flask_op_t *op);
 
 /*
  * Subscribe to state changes in a domain via evtchn.
  * Returns -1 on failure, in which case errno will be set appropriately.
  */
 int xc_domain_subscribe_for_suspend(
-    int xc_handle, domid_t domid, evtchn_port_t port);
+    xc_interface *xch, domid_t domid, evtchn_port_t port);
 
 /**************************
  * GRANT TABLE OPERATIONS *
  **************************/
 
 /*
- * Return a handle to the grant table driver, or -1 on failure, in which case
- * errno will be set appropriately.
+ * These functions sometimes log messages as above, but not always.
+ */
+
+/*
+ * Return an fd onto the grant table driver.  Logs errors.
  */
-int xc_gnttab_open(void);
+int xc_gnttab_open(xc_interface *xch);
 
 /*
  * Close a handle previously allocated with xc_gnttab_open().
+ * Never logs errors.
  */
-int xc_gnttab_close(int xcg_handle);
+int xc_gnttab_close(xc_interface *xch, int xcg_handle);
 
 /*
  * Memory maps a grant reference from one domain to a local address range.
- * Mappings should be unmapped with xc_gnttab_munmap.  Returns NULL on failure.
+ * Mappings should be unmapped with xc_gnttab_munmap.  Logs errors.
  *
  * @parm xcg_handle a handle on an open grant table interface
  * @parm domid the domain to map memory from
  * @parm ref the grant reference ID to map
  * @parm prot same flag as in mmap()
  */
-void *xc_gnttab_map_grant_ref(int xcg_handle,
+void *xc_gnttab_map_grant_ref(xc_interface *xch,
+                              int xcg_handle,
                               uint32_t domid,
                               uint32_t ref,
                               int prot);
@@ -1035,7 +1078,7 @@ void *xc_gnttab_map_grant_ref(int xcg_handle,
 /**
  * Memory maps one or more grant references from one or more domains to a
  * contiguous local address range. Mappings should be unmapped with
- * xc_gnttab_munmap.  Returns NULL on failure.
+ * xc_gnttab_munmap.  Logs errors.
  *
  * @parm xcg_handle a handle on an open grant table interface
  * @parm count the number of grant references to be mapped
@@ -1044,7 +1087,8 @@ void *xc_gnttab_map_grant_ref(int xcg_handle,
  * @parm refs an array of @count grant references to be mapped
  * @parm prot same flag as in mmap()
  */
-void *xc_gnttab_map_grant_refs(int xcg_handle,
+void *xc_gnttab_map_grant_refs(xc_interface *xch,
+                               int xcg_handle,
                                uint32_t count,
                                uint32_t *domids,
                                uint32_t *refs,
@@ -1053,7 +1097,7 @@ void *xc_gnttab_map_grant_refs(int xcg_handle,
 /**
  * Memory maps one or more grant references from one domain to a
  * contiguous local address range. Mappings should be unmapped with
- * xc_gnttab_munmap.  Returns NULL on failure.
+ * xc_gnttab_munmap.  Logs errors.
  *
  * @parm xcg_handle a handle on an open grant table interface
  * @parm count the number of grant references to be mapped
@@ -1061,7 +1105,8 @@ void *xc_gnttab_map_grant_refs(int xcg_handle,
  * @parm refs an array of @count grant references to be mapped
  * @parm prot same flag as in mmap()
  */
-void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
+void *xc_gnttab_map_domain_grant_refs(xc_interface *xch,
+                                      int xcg_handle,
                                       uint32_t count,
                                       uint32_t domid,
                                       uint32_t *refs,
@@ -1069,16 +1114,16 @@ void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
 
 /*
  * Unmaps the @count pages starting at @start_address, which were mapped by a
- * call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Returns zero
- * on success, otherwise sets errno and returns non-zero.
+ * call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Never logs.
  */
-int xc_gnttab_munmap(int xcg_handle,
+int xc_gnttab_munmap(xc_interface *xch,
+                     int xcg_handle,
                      void *start_address,
                      uint32_t count);
 
 /*
  * Sets the maximum number of grants that may be mapped by the given instance
- * to @count.
+ * to @count.  Never logs.
  *
  * N.B. This function must be called after opening the handle, and before any
  *      other functions are invoked on it.
@@ -1087,22 +1132,25 @@ int xc_gnttab_munmap(int xcg_handle,
  *      and it may not be possible to satisfy requests up to the maximum number
  *      of grants.
  */
-int xc_gnttab_set_max_grants(int xcg_handle,
+int xc_gnttab_set_max_grants(xc_interface *xch,
+                             int xcg_handle,
                             uint32_t count);
 
-int xc_gnttab_op(int xc_handle, int cmd,
+int xc_gnttab_op(xc_interface *xch, int cmd,
                  void * op, int op_size, int count);
+/* Logs iff lock_pages failes, otherwise doesn't. */
 
-int xc_gnttab_get_version(int xc_handle, int domid);
-grant_entry_v1_t *xc_gnttab_map_table_v1(int xc_handle, int domid, int 
*gnt_num);
-grant_entry_v2_t *xc_gnttab_map_table_v2(int xc_handle, int domid, int 
*gnt_num);
+int xc_gnttab_get_version(xc_interface *xch, int domid); /* Never logs */
+grant_entry_v1_t *xc_gnttab_map_table_v1(xc_interface *xch, int domid, int 
*gnt_num);
+grant_entry_v2_t *xc_gnttab_map_table_v2(xc_interface *xch, int domid, int 
*gnt_num);
+/* Sometimes these don't set errno [fixme], and sometimes they don't log. */
 
-int xc_physdev_map_pirq(int xc_handle,
+int xc_physdev_map_pirq(xc_interface *xch,
                         int domid,
                         int index,
                         int *pirq);
 
-int xc_physdev_map_pirq_msi(int xc_handle,
+int xc_physdev_map_pirq_msi(xc_interface *xch,
                             int domid,
                             int index,
                             int *pirq,
@@ -1111,21 +1159,21 @@ int xc_physdev_map_pirq_msi(int xc_handle,
                             int entry_nr,
                             uint64_t table_base);
 
-int xc_physdev_unmap_pirq(int xc_handle,
+int xc_physdev_unmap_pirq(xc_interface *xch,
                           int domid,
                           int pirq);
 
 int xc_hvm_set_pci_intx_level(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
     unsigned int level);
 int xc_hvm_set_isa_irq_level(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint8_t isa_irq,
     unsigned int level);
 
 int xc_hvm_set_pci_link_route(
-    int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
+    xc_interface *xch, domid_t dom, uint8_t link, uint8_t isa_irq);
 
 
 /*
@@ -1140,7 +1188,7 @@ int xc_hvm_set_pci_link_route(
  * last call.
  */
 int xc_hvm_track_dirty_vram(
-    int xc_handle, domid_t dom,
+    xc_interface *xch, domid_t dom,
     uint64_t first_pfn, uint64_t nr,
     unsigned long *bitmap);
 
@@ -1148,99 +1196,98 @@ int xc_hvm_track_dirty_vram(
  * Notify that some pages got modified by the Device Model
  */
 int xc_hvm_modified_memory(
-    int xc_handle, domid_t dom, uint64_t first_pfn, uint64_t nr);
+    xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr);
 
 /*
  * Set a range of memory to a specific type.
  * Allowed types are HVMMEM_ram_rw, HVMMEM_ram_ro, HVMMEM_mmio_dm
  */
 int xc_hvm_set_mem_type(
-    int xc_handle, domid_t dom, hvmmem_type_t memtype, uint64_t first_pfn, 
uint64_t nr);
+    xc_interface *xch, domid_t dom, hvmmem_type_t memtype, uint64_t first_pfn, 
uint64_t nr);
 
 
-typedef enum {
+/*
+ *  LOGGING AND ERROR REPORTING
+ */
+
+
+enum xc_error_code {
   XC_ERROR_NONE = 0,
   XC_INTERNAL_ERROR = 1,
   XC_INVALID_KERNEL = 2,
   XC_INVALID_PARAM = 3,
   XC_OUT_OF_MEMORY = 4,
-} xc_error_code;
+  /* new codes need to be added to xc_error_level_to_desc too */
+};
 
 #define XC_MAX_ERROR_MSG_LEN 1024
-typedef struct {
-  int code;
+typedef struct xc_error {
+  enum xc_error_code code;
   char message[XC_MAX_ERROR_MSG_LEN];
 } xc_error;
 
-/*
- * Return a pointer to the last error. This pointer and the
- * data pointed to are only valid until the next call to
- * libxc.
- */
-const xc_error *xc_get_last_error(void);
 
 /*
- * Clear the last error
+ * Convert an error code or level into a text description.  Return values
+ * are pointers to fixed strings and do not need to be freed.
+ * Do not fail, but return pointers to generic strings if fed bogus input.
  */
-void xc_clear_last_error(void);
+const char *xc_error_code_to_desc(int code);
 
-typedef void (*xc_error_handler)(const xc_error *err);
 
 /*
- * The default error handler which prints to stderr
+ * Return a pointer to the last error with level XC_REPORT_ERROR. This
+ * pointer and the data pointed to are only valid until the next call
+ * to libxc in the same thread.
  */
-void xc_default_error_handler(const xc_error *err);
+const xc_error *xc_get_last_error(xc_interface *handle);
 
 /*
- * Convert an error code into a text description
+ * Clear the last error
  */
-const char *xc_error_code_to_desc(int code);
+void xc_clear_last_error(xc_interface *xch);
 
-/*
- * Registers a callback to handle errors
- */
-xc_error_handler xc_set_error_handler(xc_error_handler handler);
 
-int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value);
-int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value);
+int xc_set_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned 
long value);
+int xc_get_hvm_param(xc_interface *handle, domid_t dom, int param, unsigned 
long *value);
 
 /* IA64 specific, nvram save */
-int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom);
+int xc_ia64_save_to_nvram(xc_interface *xch, uint32_t dom);
 
 /* IA64 specific, nvram init */
-int xc_ia64_nvram_init(int xc_handle, char *dom_name, uint32_t dom);
+int xc_ia64_nvram_init(xc_interface *xch, char *dom_name, uint32_t dom);
 
 /* IA64 specific, set guest OS type optimizations */
-int xc_ia64_set_os_type(int xc_handle, char *guest_os_type, uint32_t dom);
+int xc_ia64_set_os_type(xc_interface *xch, char *guest_os_type, uint32_t dom);
 
 /* HVM guest pass-through */
-int xc_assign_device(int xc_handle,
+int xc_assign_device(xc_interface *xch,
                      uint32_t domid,
                      uint32_t machine_bdf);
 
-int xc_get_device_group(int xc_handle,
+int xc_get_device_group(xc_interface *xch,
                      uint32_t domid,
                      uint32_t machine_bdf,
                      uint32_t max_sdevs,
                      uint32_t *num_sdevs,
                      uint32_t *sdev_array);
 
-int xc_test_assign_device(int xc_handle,
+int xc_test_assign_device(xc_interface *xch,
                           uint32_t domid,
                           uint32_t machine_bdf);
 
-int xc_deassign_device(int xc_handle,
+int xc_deassign_device(xc_interface *xch,
                      uint32_t domid,
                      uint32_t machine_bdf);
 
-int xc_domain_memory_mapping(int xc_handle,
+int xc_domain_memory_mapping(xc_interface *xch,
                              uint32_t domid,
                              unsigned long first_gfn,
                              unsigned long first_mfn,
                              unsigned long nr_mfns,
                              uint32_t add_mapping);
 
-int xc_domain_ioport_mapping(int xc_handle,
+int xc_domain_ioport_mapping(xc_interface *xch,
                              uint32_t domid,
                              uint32_t first_gport,
                              uint32_t first_mport,
@@ -1248,20 +1295,20 @@ int xc_domain_ioport_mapping(int xc_handle,
                              uint32_t add_mapping);
 
 int xc_domain_update_msi_irq(
-    int xc_handle,
+    xc_interface *xch,
     uint32_t domid,
     uint32_t gvec,
     uint32_t pirq,
     uint32_t gflags,
     uint64_t gtable);
 
-int xc_domain_unbind_msi_irq(int xc_handle,
+int xc_domain_unbind_msi_irq(xc_interface *xch,
                              uint32_t domid,
                              uint32_t gvec,
                              uint32_t pirq,
                              uint32_t gflags);
 
-int xc_domain_bind_pt_irq(int xc_handle,
+int xc_domain_bind_pt_irq(xc_interface *xch,
                           uint32_t domid,
                           uint8_t machine_irq,
                           uint8_t irq_type,
@@ -1270,7 +1317,7 @@ int xc_domain_bind_pt_irq(int xc_handle,
                           uint8_t intx,
                           uint8_t isa_irq);
 
-int xc_domain_unbind_pt_irq(int xc_handle,
+int xc_domain_unbind_pt_irq(xc_interface *xch,
                           uint32_t domid,
                           uint8_t machine_irq,
                           uint8_t irq_type,
@@ -1279,52 +1326,52 @@ int xc_domain_unbind_pt_irq(int xc_handle,
                           uint8_t intx,
                           uint8_t isa_irq);
 
-int xc_domain_bind_pt_pci_irq(int xc_handle,
+int xc_domain_bind_pt_pci_irq(xc_interface *xch,
                               uint32_t domid,
                               uint8_t machine_irq,
                               uint8_t bus,
                               uint8_t device,
                               uint8_t intx);
 
-int xc_domain_bind_pt_isa_irq(int xc_handle,
+int xc_domain_bind_pt_isa_irq(xc_interface *xch,
                               uint32_t domid,
                               uint8_t machine_irq);
 
-int xc_domain_set_machine_address_size(int handle,
+int xc_domain_set_machine_address_size(xc_interface *xch,
                                       uint32_t domid,
                                       unsigned int width);
-int xc_domain_get_machine_address_size(int handle,
+int xc_domain_get_machine_address_size(xc_interface *xch,
                                       uint32_t domid);
 
-int xc_domain_suppress_spurious_page_faults(int handle,
+int xc_domain_suppress_spurious_page_faults(xc_interface *xch,
                                          uint32_t domid);
 
 /* Set the target domain */
-int xc_domain_set_target(int xc_handle,
+int xc_domain_set_target(xc_interface *xch,
                          uint32_t domid,
                          uint32_t target);
 
 /* Control the domain for debug */
-int xc_domain_debug_control(int xc_handle,
+int xc_domain_debug_control(xc_interface *xch,
                             uint32_t domid,
                             uint32_t sop,
                             uint32_t vcpu);
 
 #if defined(__i386__) || defined(__x86_64__)
-int xc_cpuid_check(int xc,
+int xc_cpuid_check(xc_interface *xch,
                    const unsigned int *input,
                    const char **config,
                    char **config_transformed);
-int xc_cpuid_set(int xc,
+int xc_cpuid_set(xc_interface *xch,
                  domid_t domid,
                  const unsigned int *input,
                  const char **config,
                  char **config_transformed);
-int xc_cpuid_apply_policy(int xc,
+int xc_cpuid_apply_policy(xc_interface *xch,
                           domid_t domid);
 void xc_cpuid_to_str(const unsigned int *regs,
                      char **strs);
-int xc_mca_op(int xc_handle, struct xen_mc *mc);
+int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
 #endif
 
 struct xc_px_val {
@@ -1342,9 +1389,9 @@ struct xc_px_stat {
     struct xc_px_val *pt;
 };
 
-int xc_pm_get_max_px(int xc_handle, int cpuid, int *max_px);
-int xc_pm_get_pxstat(int xc_handle, int cpuid, struct xc_px_stat *pxpt);
-int xc_pm_reset_pxstat(int xc_handle, int cpuid);
+int xc_pm_get_max_px(xc_interface *xch, int cpuid, int *max_px);
+int xc_pm_get_pxstat(xc_interface *xch, int cpuid, struct xc_px_stat *pxpt);
+int xc_pm_reset_pxstat(xc_interface *xch, int cpuid);
 
 struct xc_cx_stat {
     uint32_t nr;    /* entry nr in triggers & residencies, including C0 */
@@ -1355,12 +1402,12 @@ struct xc_cx_stat {
 };
 typedef struct xc_cx_stat xc_cx_stat_t;
 
-int xc_pm_get_max_cx(int xc_handle, int cpuid, int *max_cx);
-int xc_pm_get_cxstat(int xc_handle, int cpuid, struct xc_cx_stat *cxpt);
-int xc_pm_reset_cxstat(int xc_handle, int cpuid);
+int xc_pm_get_max_cx(xc_interface *xch, int cpuid, int *max_cx);
+int xc_pm_get_cxstat(xc_interface *xch, int cpuid, struct xc_cx_stat *cxpt);
+int xc_pm_reset_cxstat(xc_interface *xch, int cpuid);
 
-int xc_cpu_online(int xc_handle, int cpu);
-int xc_cpu_offline(int xc_handle, int cpu);
+int xc_cpu_online(xc_interface *xch, int cpu);
+int xc_cpu_offline(xc_interface *xch, int cpu);
 
 /* 
  * cpufreq para name of this structure named 
@@ -1400,83 +1447,85 @@ struct xc_get_cpufreq_para {
     int32_t turbo_enabled;
 };
 
-int xc_get_cpufreq_para(int xc_handle, int cpuid,
+int xc_get_cpufreq_para(xc_interface *xch, int cpuid,
                         struct xc_get_cpufreq_para *user_para);
-int xc_set_cpufreq_gov(int xc_handle, int cpuid, char *govname);
-int xc_set_cpufreq_para(int xc_handle, int cpuid,
+int xc_set_cpufreq_gov(xc_interface *xch, int cpuid, char *govname);
+int xc_set_cpufreq_para(xc_interface *xch, int cpuid,
                         int ctrl_type, int ctrl_value);
-int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq);
+int xc_get_cpufreq_avgfreq(xc_interface *xch, int cpuid, int *avg_freq);
 
-int xc_set_sched_opt_smt(int xc_handle, uint32_t value);
-int xc_set_vcpu_migration_delay(int xc_handle, uint32_t value);
-int xc_get_vcpu_migration_delay(int xc_handle, uint32_t *value);
+int xc_set_sched_opt_smt(xc_interface *xch, uint32_t value);
+int xc_set_vcpu_migration_delay(xc_interface *xch, uint32_t value);
+int xc_get_vcpu_migration_delay(xc_interface *xch, uint32_t *value);
 
-int xc_get_cpuidle_max_cstate(int xc_handle, uint32_t *value);
-int xc_set_cpuidle_max_cstate(int xc_handle, uint32_t value);
+int xc_get_cpuidle_max_cstate(xc_interface *xch, uint32_t *value);
+int xc_set_cpuidle_max_cstate(xc_interface *xch, uint32_t value);
 
-int xc_enable_turbo(int xc_handle, int cpuid);
-int xc_disable_turbo(int xc_handle, int cpuid);
+int xc_enable_turbo(xc_interface *xch, int cpuid);
+int xc_disable_turbo(xc_interface *xch, int cpuid);
 /**
  * tmem operations
  */
-int xc_tmem_control(int xc, int32_t pool_id, uint32_t subop, uint32_t cli_id,
+int xc_tmem_control(xc_interface *xch,
+                    int32_t pool_id, uint32_t subop, uint32_t cli_id,
                     uint32_t arg1, uint32_t arg2, uint64_t arg3, void *buf);
-int xc_tmem_auth(int xc_handle, int cli_id, char *uuid_str, int arg1);
-int xc_tmem_save(int xc_handle, int dom, int live, int fd, int field_marker);
-int xc_tmem_save_extra(int xc_handle, int dom, int fd, int field_marker);
-void xc_tmem_save_done(int xc_handle, int dom);
-int xc_tmem_restore(int xc_handle, int dom, int fd);
-int xc_tmem_restore_extra(int xc_handle, int dom, int fd);
+int xc_tmem_auth(xc_interface *xch, int cli_id, char *uuid_str, int arg1);
+int xc_tmem_save(xc_interface *xch, int dom, int live, int fd, int 
field_marker);
+int xc_tmem_save_extra(xc_interface *xch, int dom, int fd, int field_marker);
+void xc_tmem_save_done(xc_interface *xch, int dom);
+int xc_tmem_restore(xc_interface *xch, int dom, int fd);
+int xc_tmem_restore_extra(xc_interface *xch, int dom, int fd);
 
 /**
  * mem_event operations
  */
-int xc_mem_event_control(int xc_handle, domid_t domain_id, unsigned int op,
+int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op,
                          unsigned int mode, void *shared_page,
                           void *ring_page, unsigned long gfn);
 
-int xc_mem_event_enable(int xc_handle, domid_t domain_id,
+int xc_mem_event_enable(xc_interface *xch, domid_t domain_id,
                         void *shared_page, void *ring_page);
-int xc_mem_event_disable(int xc_handle, domid_t domain_id);
+int xc_mem_event_disable(xc_interface *xch, domid_t domain_id);
 
-int xc_mem_paging_nominate(int xc_handle, domid_t domain_id,
+int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id,
                            unsigned long gfn);
-int xc_mem_paging_evict(int xc_handle, domid_t domain_id, unsigned long gfn);
-int xc_mem_paging_prep(int xc_handle, domid_t domain_id, unsigned long gfn);
-int xc_mem_paging_resume(int xc_handle, domid_t domain_id,
+int xc_mem_paging_evict(xc_interface *xch, domid_t domain_id, unsigned long 
gfn);
+int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long 
gfn);
+int xc_mem_paging_resume(xc_interface *xch, domid_t domain_id,
                          unsigned long gfn);
 
 /**
  * memshr operations
  */
-int xc_memshr_control(int xc_handle,
+int xc_memshr_control(xc_interface *xch,
                       uint32_t domid,
                       int enable);
-int xc_memshr_nominate_gfn(int xc_handle,
+int xc_memshr_nominate_gfn(xc_interface *xch,
                            uint32_t domid,
                            unsigned long gfn,
                            uint64_t *handle);
-int xc_memshr_nominate_gref(int xc_handle,
+int xc_memshr_nominate_gref(xc_interface *xch,
                             uint32_t domid,
                             grant_ref_t gref,
                             uint64_t *handle);
-int xc_memshr_share(int xc_handle,
+int xc_memshr_share(xc_interface *xch,
                     uint64_t source_handle,
                     uint64_t client_handle);
-int xc_memshr_domain_resume(int xc_handle,
+int xc_memshr_domain_resume(xc_interface *xch,
                             uint32_t domid);
-int xc_memshr_debug_gfn(int xc_handle,
+int xc_memshr_debug_gfn(xc_interface *xch,
                         uint32_t domid,
                         unsigned long gfn);
-int xc_memshr_debug_mfn(int xc_handle,
+int xc_memshr_debug_mfn(xc_interface *xch,
                         uint32_t domid,
                         unsigned long mfn);
-int xc_memshr_debug_gref(int xc_handle,
+int xc_memshr_debug_gref(xc_interface *xch,
                          uint32_t domid,
                          grant_ref_t gref);
 
 struct elf_binary;
-void xc_elf_set_logfile(struct elf_binary *elf, FILE *f, int verbose);
+void xc_elf_set_logfile(struct xc_interface *xch, struct elf_binary *elf,
+                        int verbose);
 /* Useful for callers who also use libelf. */
 
 #endif /* XENCTRL_H */
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index d1d86b2..3c4a1c7 100644
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -33,12 +33,12 @@ struct save_callbacks {
 /**
  * This function will save a running domain.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm fd the file descriptor to save a domain to
  * @parm dom the id of the domain
  * @return 0 on success, -1 on failure
  */
-int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
+int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t 
max_iters,
                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
                    struct save_callbacks* callbacks,
                    int hvm, void (*switch_qemu_logdirty)(int, unsigned)); /* 
HVM only */
@@ -47,7 +47,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
 /**
  * This function will restore a saved domain.
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm fd the file descriptor to restore a domain from
  * @parm dom the id of the domain
  * @parm store_evtchn the store event channel for this domain to use
@@ -57,7 +57,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, 
uint32_t max_iters,
  * @parm superpages non-zero to allocate guest memory with superpages
  * @return 0 on success, -1 on failure
  */
-int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
+int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
                       unsigned int hvm, unsigned int pae, int superpages);
@@ -66,7 +66,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
  * This function will create a domain for a paravirtualized Linux
  * using file names pointing to kernel and ramdisk
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the id of the domain
  * @parm mem_mb memory size in megabytes
  * @parm image_name name of the kernel image file
@@ -79,7 +79,7 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
  * @parm conole_mfn returned with the mfn of the console page
  * @return 0 on success, -1 on failure
  */
-int xc_linux_build(int xc_handle,
+int xc_linux_build(xc_interface *xch,
                    uint32_t domid,
                    unsigned int mem_mb,
                    const char *image_name,
@@ -94,7 +94,7 @@ int xc_linux_build(int xc_handle,
 
 /** The same interface, but the dom structure is managed by the caller */
 struct xc_dom_image;
-int xc_dom_linux_build(int xc_handle,
+int xc_dom_linux_build(xc_interface *xch,
                       struct xc_dom_image *dom,
                       uint32_t domid,
                       unsigned int mem_mb,
@@ -110,7 +110,7 @@ int xc_dom_linux_build(int xc_handle,
  * This function will create a domain for a paravirtualized Linux
  * using buffers for kernel and initrd
  *
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm domid the id of the domain
  * @parm mem_mb memory size in megabytes
  * @parm image_buffer buffer containing kernel image
@@ -125,7 +125,7 @@ int xc_dom_linux_build(int xc_handle,
  * @parm conole_mfn returned with the mfn of the console page
  * @return 0 on success, -1 on failure
  */
-int xc_linux_build_mem(int xc_handle,
+int xc_linux_build_mem(xc_interface *xch,
                        uint32_t domid,
                        unsigned int mem_mb,
                        const char *image_buffer,
@@ -140,53 +140,54 @@ int xc_linux_build_mem(int xc_handle,
                        unsigned int console_evtchn,
                        unsigned long *console_mfn);
 
-int xc_hvm_build(int xc_handle,
+int xc_hvm_build(xc_interface *xch,
                  uint32_t domid,
                  int memsize,
                  const char *image_name);
 
-int xc_hvm_build_target_mem(int xc_handle,
+int xc_hvm_build_target_mem(xc_interface *xch,
                             uint32_t domid,
                             int memsize,
                             int target,
                             const char *image_name);
 
-int xc_hvm_build_mem(int xc_handle,
+int xc_hvm_build_mem(xc_interface *xch,
                      uint32_t domid,
                      int memsize,
                      const char *image_buffer,
                      unsigned long image_size);
 
-int xc_suspend_evtchn_release(int xce, int domid, int suspend_evtchn);
+int xc_suspend_evtchn_release(xc_interface *xch, int xce, int domid, int 
suspend_evtchn);
 
-int xc_suspend_evtchn_init(int xc, int xce, int domid, int port);
+int xc_suspend_evtchn_init(xc_interface *xch, int xce, int domid, int port);
 
-int xc_await_suspend(int xce, int suspend_evtchn);
+int xc_await_suspend(xc_interface *xch, int xce, int suspend_evtchn);
 
-int xc_get_bit_size(const char *image_name, const char *cmdline,
-                      const char *features, int *type);
+int xc_get_bit_size(xc_interface *xch,
+                    const char *image_name, const char *cmdline,
+                    const char *features, int *type);
 
-int xc_mark_page_online(int xc, unsigned long start,
+int xc_mark_page_online(xc_interface *xch, unsigned long start,
                         unsigned long end, uint32_t *status);
 
-int xc_mark_page_offline(int xc, unsigned long start,
+int xc_mark_page_offline(xc_interface *xch, unsigned long start,
                           unsigned long end, uint32_t *status);
 
-int xc_query_page_offline_status(int xc, unsigned long start,
+int xc_query_page_offline_status(xc_interface *xch, unsigned long start,
                                  unsigned long end, uint32_t *status);
 
-int xc_exchange_page(int xc_handle, int domid, xen_pfn_t mfn);
+int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn);
 
 
 /**
  * This function map m2p table
- * @parm xc_handle a handle to an open hypervisor interface
+ * @parm xch a handle to an open hypervisor interface
  * @parm max_mfn the max pfn
  * @parm prot the flags to map, such as read/write etc
  * @parm mfn0 return the first mfn, can be NULL
  * @return mapped m2p table on success, NULL on failure
  */
-xen_pfn_t *xc_map_m2p(int xc_handle,
+xen_pfn_t *xc_map_m2p(xc_interface *xch,
                       unsigned long max_mfn,
                       int prot,
                       unsigned long *mfn0);
diff --git a/tools/libxc/xg_private.c b/tools/libxc/xg_private.c
index 457001c..98098db 100644
--- a/tools/libxc/xg_private.c
+++ b/tools/libxc/xg_private.c
@@ -11,7 +11,8 @@
 
 #include "xg_private.h"
 
-char *xc_read_image(const char *filename, unsigned long *size)
+char *xc_read_image(xc_interface *xch,
+                    const char *filename, unsigned long *size)
 {
     int kernel_fd = -1;
     gzFile kernel_gfd = NULL;
@@ -86,7 +87,8 @@ char *xc_read_image(const char *filename, unsigned long *size)
     return image;
 }
 
-char *xc_inflate_buffer(const char *in_buf, unsigned long in_size,
+char *xc_inflate_buffer(xc_interface *xch,
+                        const char *in_buf, unsigned long in_size,
                         unsigned long *out_size)
 {
     int           sts;
@@ -147,14 +149,14 @@ char *xc_inflate_buffer(const char *in_buf, unsigned long 
in_size,
 /*******************/
 
 int pin_table(
-    int xc_handle, unsigned int type, unsigned long mfn, domid_t dom)
+    xc_interface *xch, unsigned int type, unsigned long mfn, domid_t dom)
 {
     struct mmuext_op op;
 
     op.cmd = type;
     op.arg1.mfn = mfn;
 
-    if ( xc_mmuext_op(xc_handle, &op, 1, dom) < 0 )
+    if ( xc_mmuext_op(xch, &op, 1, dom) < 0 )
         return 1;
 
     return 0;
@@ -174,7 +176,7 @@ unsigned long csum_page(void *page)
 }
 
 __attribute__((weak)) 
-    int xc_hvm_build(int xc_handle,
+    int xc_hvm_build(xc_interface *xch,
                      uint32_t domid,
                      int memsize,
                      const char *image_name)
diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h
index a15dd91..5f67d8c 100644
--- a/tools/libxc/xg_private.h
+++ b/tools/libxc/xg_private.h
@@ -27,8 +27,10 @@
 #endif
 #endif
 
-char *xc_read_image(const char *filename, unsigned long *size);
-char *xc_inflate_buffer(const char *in_buf,
+char *xc_read_image(xc_interface *xch,
+                    const char *filename, unsigned long *size);
+char *xc_inflate_buffer(xc_interface *xch,
+                        const char *in_buf,
                         unsigned long in_size,
                         unsigned long *out_size);
 
@@ -174,7 +176,7 @@ struct domain_info_context {
 #define PAEKERN_extended_cr3 2
 #define PAEKERN_bimodal      3
 
-int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
+int pin_table(xc_interface *xch, unsigned int type, unsigned long mfn,
               domid_t dom);
 
 #endif /* XG_PRIVATE_H */
diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h
index 9c2b67a..5df5f0c 100644
--- a/tools/libxc/xg_save_restore.h
+++ b/tools/libxc/xg_save_restore.h
@@ -39,7 +39,7 @@
 **
 ** Returns 1 on success, 0 on failure.
 */
-static inline int get_platform_info(int xc_handle, uint32_t dom,
+static inline int get_platform_info(xc_interface *xch, uint32_t dom,
                                     /* OUT */ unsigned long *max_mfn,
                                     /* OUT */ unsigned long *hvirt_start,
                                     /* OUT */ unsigned int *pt_levels,
@@ -49,13 +49,13 @@ static inline int get_platform_info(int xc_handle, uint32_t 
dom,
     xen_platform_parameters_t xen_params;
     DECLARE_DOMCTL;
 
-    if (xc_version(xc_handle, XENVER_platform_parameters, &xen_params) != 0)
+    if (xc_version(xch, XENVER_platform_parameters, &xen_params) != 0)
         return 0;
 
-    if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
+    if (xc_version(xch, XENVER_capabilities, &xen_caps) != 0)
         return 0;
 
-    *max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL);
+    *max_mfn = xc_memory_op(xch, XENMEM_maximum_ram_page, NULL);
 
     *hvirt_start = xen_params.virt_start;
 
@@ -63,7 +63,7 @@ static inline int get_platform_info(int xc_handle, uint32_t 
dom,
     domctl.domain = dom;
     domctl.cmd = XEN_DOMCTL_get_address_size;
 
-    if ( do_domctl(xc_handle, &domctl) != 0 )
+    if ( do_domctl(xch, &domctl) != 0 )
         return 0; 
 
     *guest_width = domctl.u.address_size.size / 8;
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index f988833..8fd4481 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -47,8 +47,8 @@ int libxl_ctx_init(struct libxl_ctx *ctx, int version)
         return ERROR_NOMEM;
     memset(&ctx->version_info, 0, sizeof(libxl_version_info));
 
-    ctx->xch = xc_interface_open();
-    if (ctx->xch == -1) {
+    ctx->xch = xc_interface_open(0,0,0);
+    if (!ctx->xch) {
         free(ctx->alloc_ptrs);
         return ERROR_FAIL;
     }
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index a6092ff..1c4750e 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -61,7 +61,7 @@ typedef struct {
 } libxl_version_info;
 
 struct libxl_ctx {
-    int xch;
+    xc_interface *xch;
     struct xs_handle *xsh;
     /* errors/debug buf */
     void *log_userdata;
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index f809f4a..483a928 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -148,7 +148,7 @@ int build_pv(struct libxl_ctx *ctx, uint32_t domid,
     int ret;
     int flags = 0;
 
-    dom = xc_dom_allocate(info->u.pv.cmdline, info->u.pv.features);
+    dom = xc_dom_allocate(ctx->xch, info->u.pv.cmdline, info->u.pv.features);
     if (!dom) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xc_dom_allocate failed");
         return -1;
@@ -247,7 +247,7 @@ static int core_suspend_callback(void *data)
             XL_LOG(si->ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", 
ret);
             return 0;
         }
-        ret = xc_await_suspend(si->xce, si->suspend_eventchn);
+        ret = xc_await_suspend(si->ctx->xch, si->xce, si->suspend_eventchn);
         if (ret < 0) {
             XL_LOG(si->ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", 
ret);
             return 0;
@@ -332,7 +332,7 @@ int core_suspend(struct libxl_ctx *ctx, uint32_t domid, int 
fd,
                    &core_suspend_switch_qemu_logdirty);
 
     if (si.suspend_eventchn > 0)
-        xc_suspend_evtchn_release(si.xce, domid, si.suspend_eventchn);
+        xc_suspend_evtchn_release(si.ctx->xch, si.xce, domid, 
si.suspend_eventchn);
     if (si.xce > 0)
         xc_evtchn_close(si.xce);
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index d75a250..2f1f591 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -154,7 +154,7 @@ int libxl_device_pci_flr(struct libxl_ctx *ctx, unsigned 
int domain, unsigned in
                          unsigned int dev, unsigned int func);
 
 /* from xenguest (helper */
-int hvm_build_set_params(int handle, uint32_t domid,
+int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          int apic, int acpi, int pae, int nx, int viridian,
                          int vcpus, int store_evtchn, unsigned long 
*store_mfn);
 
diff --git a/tools/libxl/xenguest.c b/tools/libxl/xenguest.c
index b30744d..11f737b 100644
--- a/tools/libxl/xenguest.c
+++ b/tools/libxl/xenguest.c
@@ -18,7 +18,7 @@
 #include <sys/mman.h>
 #include <xen/hvm/hvm_info_table.h>
 
-int hvm_build_set_params(int handle, uint32_t domid,
+int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          int apic, int acpi, int pae, int nx, int viridian,
                          int vcpus, int store_evtchn, unsigned long *store_mfn)
 {
diff --git a/tools/memshr/interface.c b/tools/memshr/interface.c
index de8fa27..a61715a 100644
--- a/tools/memshr/interface.c
+++ b/tools/memshr/interface.c
@@ -28,7 +28,7 @@
 typedef struct {
     int     enabled;
     domid_t domid;
-    int     xc_handle;
+    xc_interface *xc_handle;
 } memshr_vbd_info_t;
 
 memshr_vbd_info_t vbd_info = {0, DOMID_INVALID};
@@ -82,7 +82,7 @@ void memshr_daemon_initialize(void)
 
 void memshr_vbd_initialize(void)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
 
     memset(&memshr, 0, sizeof(private_memshr_info_t));
 
@@ -113,7 +113,7 @@ void memshr_vbd_initialize(void)
     if(vbd_info.domid == DOMID_INVALID)
         return;
 
-    if((xc_handle = xc_interface_open()) < 0)
+    if((xc_handle = xc_interface_open(0,0,0)) == 0)
     {
         DPRINTF("Failed to open XC interface.\n");
         return;
diff --git a/tools/misc/xen-hptool.c b/tools/misc/xen-hptool.c
index 7c2bf4a..cc4d673 100644
--- a/tools/misc/xen-hptool.c
+++ b/tools/misc/xen-hptool.c
@@ -5,7 +5,7 @@
 
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
 
-static int xc_fd;
+static xc_interface *xch;
 
 void show_help(void)
 {
@@ -44,7 +44,7 @@ static int hp_mem_online_func(int argc, char *argv[])
     sscanf(argv[0], "%lx", &mfn);
     printf("Prepare to online MEMORY mfn %lx\n", mfn);
 
-    ret = xc_mark_page_online(xc_fd, mfn, mfn, &status);
+    ret = xc_mark_page_online(xch, mfn, mfn, &status);
 
     if (ret < 0)
         fprintf(stderr, "Onlining page mfn %lx failed, error %x", mfn, ret);
@@ -75,7 +75,7 @@ static int hp_mem_query_func(int argc, char *argv[])
 
     sscanf(argv[0], "%lx", &mfn);
     printf("Querying MEMORY mfn %lx status\n", mfn);
-    ret = xc_query_page_offline_status(xc_fd, mfn, mfn, &status);
+    ret = xc_query_page_offline_status(xch, mfn, mfn, &status);
 
     if (ret < 0)
         fprintf(stderr, "Querying page mfn %lx failed, error %x", mfn, ret);
@@ -98,7 +98,7 @@ static int hp_mem_query_func(int argc, char *argv[])
 
 extern int xs_suspend_evtchn_port(int domid);
 
-static int suspend_guest(int xc_handle, int xce, int domid, int *evtchn)
+static int suspend_guest(xc_interface *xch, int xce, int domid, int *evtchn)
 {
     int port, rc, suspend_evtchn = -1;
 
@@ -111,7 +111,7 @@ static int suspend_guest(int xc_handle, int xce, int domid, 
int *evtchn)
         fprintf(stderr, "DOM%d: No suspend port, try live migration\n", domid);
         goto failed;
     }
-    suspend_evtchn = xc_suspend_evtchn_init(xc_handle, xce, domid, port);
+    suspend_evtchn = xc_suspend_evtchn_init(xch, xce, domid, port);
     if (suspend_evtchn < 0)
     {
         fprintf(stderr, "Suspend evtchn initialization failed\n");
@@ -125,7 +125,7 @@ static int suspend_guest(int xc_handle, int xce, int domid, 
int *evtchn)
         fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc);
         goto failed;
     }
-    if (xc_await_suspend(xce, suspend_evtchn) < 0)
+    if (xc_await_suspend(xch, xce, suspend_evtchn) < 0)
     {
         fprintf(stderr, "Suspend Failed\n");
         goto failed;
@@ -134,7 +134,7 @@ static int suspend_guest(int xc_handle, int xce, int domid, 
int *evtchn)
 
 failed:
     if (suspend_evtchn != -1)
-        xc_suspend_evtchn_release(xce, domid, suspend_evtchn);
+        xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
 
     return -1;
 }
@@ -153,7 +153,7 @@ static int hp_mem_offline_func(int argc, char *argv[])
 
     sscanf(argv[0], "%lx", &mfn);
     printf("Prepare to offline MEMORY mfn %lx\n", mfn);
-    ret = xc_mark_page_offline(xc_fd, mfn, mfn, &status);
+    ret = xc_mark_page_offline(xch, mfn, mfn, &status);
     if (ret < 0) {
         fprintf(stderr, "Offlining page mfn %lx failed, error %x\n", mfn, ret);
         if (status & (PG_OFFLINE_XENPAGE | PG_OFFLINE_FAILED))
@@ -203,7 +203,7 @@ static int hp_mem_offline_func(int argc, char *argv[])
                     }
 
                     domid = status >> PG_OFFLINE_OWNER_SHIFT;
-                    if (suspend_guest(xc_fd, xce, domid, &suspend_evtchn))
+                    if (suspend_guest(xch, xce, domid, &suspend_evtchn))
                     {
                         fprintf(stderr, "Failed to suspend guest %d for"
                                 " mfn %lx\n", domid, mfn);
@@ -211,7 +211,7 @@ static int hp_mem_offline_func(int argc, char *argv[])
                         return -1;
                     }
 
-                    result = xc_exchange_page(xc_fd, domid, mfn);
+                    result = xc_exchange_page(xch, domid, mfn);
 
                     /* Exchange page successfully */
                     if (result == 0)
@@ -228,8 +228,8 @@ static int hp_mem_offline_func(int argc, char *argv[])
                                 "[PG_OFFLINE_PENDING, PG_OFFLINE_OWNED]\n",
                                 mfn, domid);
                     }
-                    xc_domain_resume(xc_fd, domid, 1);
-                    xc_suspend_evtchn_release(xce, domid, suspend_evtchn);
+                    xc_domain_resume(xch, domid, 1);
+                    xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
                     xc_evtchn_close(xce);
                 }
                 break;
@@ -253,7 +253,7 @@ static int hp_cpu_online_func(int argc, char *argv[])
 
     cpu = atoi(argv[0]);
     printf("Prepare to online CPU %d\n", cpu);
-    ret = xc_cpu_online(xc_fd, cpu);
+    ret = xc_cpu_online(xch, cpu);
     if (ret < 0)
         fprintf(stderr, "CPU %d online failed (error %d: %s)\n",
                 cpu, errno, strerror(errno));
@@ -274,7 +274,7 @@ static int hp_cpu_offline_func(int argc, char *argv[])
     }
     cpu = atoi(argv[0]);
     printf("Prepare to offline CPU %d\n", cpu);
-    ret = xc_cpu_offline(xc_fd, cpu);
+    ret = xc_cpu_offline(xch, cpu);
     if (ret < 0)
         fprintf(stderr, "CPU %d offline failed (error %d: %s)\n",
                 cpu, errno, strerror(errno));
@@ -307,8 +307,8 @@ int main(int argc, char *argv[])
         return 0;
     }
 
-    xc_fd = xc_interface_open();
-    if ( xc_fd < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
     {
         fprintf(stderr, "failed to get the handler\n");
         return 0;
@@ -326,7 +326,7 @@ int main(int argc, char *argv[])
 
     ret = main_options[i].function(argc -2, argv + 2);
 
-    xc_interface_close(xc_fd);
+    xc_interface_close(xch);
 
     return !!ret;
 }
diff --git a/tools/misc/xen-hvmctx.c b/tools/misc/xen-hvmctx.c
index 060ec7a..38ee945 100644
--- a/tools/misc/xen-hvmctx.c
+++ b/tools/misc/xen-hvmctx.c
@@ -377,7 +377,8 @@ static void dump_viridian(void)
 
 int main(int argc, char **argv)
 {
-    int entry, domid, xch;
+    int entry, domid;
+    xc_interface *xch;
 
     struct hvm_save_descriptor desc;
 
@@ -387,8 +388,8 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-    xch = xc_interface_open();
-    if ( xch < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
     {
         fprintf(stderr, "Error: can't open libxc handle\n");
         exit(1);
diff --git a/tools/misc/xenlockprof.c b/tools/misc/xenlockprof.c
index 3e22e94..e30fbaa 100644
--- a/tools/misc/xenlockprof.c
+++ b/tools/misc/xenlockprof.c
@@ -36,7 +36,7 @@ static void unlock_pages(void *addr, size_t len)
 
 int main(int argc, char *argv[])
 {
-    int                xc_handle;
+    xc_interface      *xc_handle;
     uint32_t           i, j, n;
     uint64_t           time;
     double             l, b, sl, sb;
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
         return 1;
     }
 
-    if ( (xc_handle = xc_interface_open()) == -1 )
+    if ( (xc_handle = xc_interface_open(0,0,0)) == 0 )
     {
         fprintf(stderr, "Error opening xc interface: %d (%s)\n",
                 errno, strerror(errno));
diff --git a/tools/misc/xenperf.c b/tools/misc/xenperf.c
index 36d1f1d..3730efd 100644
--- a/tools/misc/xenperf.c
+++ b/tools/misc/xenperf.c
@@ -86,7 +86,8 @@ static void unlock_pages(void *addr, size_t len)
 
 int main(int argc, char *argv[])
 {
-    int              i, j, xc_handle;
+    int              i, j;
+    xc_interface    *xc_handle;
     xc_perfc_desc_t *pcd;
     xc_perfc_val_t  *pcv;
     xc_perfc_val_t  *val;
@@ -127,7 +128,7 @@ int main(int argc, char *argv[])
         }
     }   
 
-    if ( (xc_handle = xc_interface_open()) == -1 )
+    if ( (xc_handle = xc_interface_open(0,0,0)) == 0 )
     {
         fprintf(stderr, "Error opening xc interface: %d (%s)\n",
                 errno, strerror(errno));
diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index d92ff2a..679b1f3 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -34,7 +34,7 @@
 #define CPUFREQ_TURBO_UNSUPPORTED   0
 #define CPUFREQ_TURBO_ENABLED       1
 
-static int xc_fd;
+static xc_interface *xc_handle;
 static int max_cpu_nr;
 
 /* help message */
@@ -95,12 +95,12 @@ static void print_cxstat(int cpuid, struct xc_cx_stat 
*cxstat)
 }
 
 /* show cpu idle information on CPU cpuid */
-static int get_cxstat_by_cpuid(int xc_fd, int cpuid, struct xc_cx_stat *cxstat)
+static int get_cxstat_by_cpuid(xc_interface *xc_handle, int cpuid, struct 
xc_cx_stat *cxstat)
 {
     int ret = 0;
     int max_cx_num = 0;
 
-    ret = xc_pm_get_max_cx(xc_fd, cpuid, &max_cx_num);
+    ret = xc_pm_get_max_cx(xc_handle, cpuid, &max_cx_num);
     if ( ret )
         return errno;
 
@@ -117,7 +117,7 @@ static int get_cxstat_by_cpuid(int xc_fd, int cpuid, struct 
xc_cx_stat *cxstat)
         return -ENOMEM;
     }
 
-    ret = xc_pm_get_cxstat(xc_fd, cpuid, cxstat);
+    ret = xc_pm_get_cxstat(xc_handle, cpuid, cxstat);
     if( ret )
     {
         int temp = errno;
@@ -131,24 +131,24 @@ static int get_cxstat_by_cpuid(int xc_fd, int cpuid, 
struct xc_cx_stat *cxstat)
     return 0;
 }
 
-static int show_max_cstate(int xc_fd)
+static int show_max_cstate(xc_interface *xc_handle)
 {
     int ret = 0;
     uint32_t value;
 
-    if ( (ret = xc_get_cpuidle_max_cstate(xc_fd, &value)) )
+    if ( (ret = xc_get_cpuidle_max_cstate(xc_handle, &value)) )
         return ret;
 
     printf("Max C-state: C%d\n\n", value);
     return 0;
 }
 
-static int show_cxstat_by_cpuid(int xc_fd, int cpuid)
+static int show_cxstat_by_cpuid(xc_interface *xc_handle, int cpuid)
 {
     int ret = 0;
     struct xc_cx_stat cxstatinfo;
 
-    ret = get_cxstat_by_cpuid(xc_fd, cpuid, &cxstatinfo);
+    ret = get_cxstat_by_cpuid(xc_handle, cpuid, &cxstatinfo);
     if ( ret )
         return ret;
 
@@ -169,18 +169,18 @@ void cxstat_func(int argc, char *argv[])
     if ( cpuid >= max_cpu_nr )
         cpuid = -1;
 
-    show_max_cstate(xc_fd);
+    show_max_cstate(xc_handle);
 
     if ( cpuid < 0 )
     {
         /* show cxstates on all cpus */
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( show_cxstat_by_cpuid(xc_fd, i) == -ENODEV )
+            if ( show_cxstat_by_cpuid(xc_handle, i) == -ENODEV )
                 break;
     }
     else
-        show_cxstat_by_cpuid(xc_fd, cpuid);
+        show_cxstat_by_cpuid(xc_handle, cpuid);
 }
 
 static void print_pxstat(int cpuid, struct xc_px_stat *pxstat)
@@ -209,12 +209,12 @@ static void print_pxstat(int cpuid, struct xc_px_stat 
*pxstat)
 }
 
 /* show cpu frequency information on CPU cpuid */
-static int get_pxstat_by_cpuid(int xc_fd, int cpuid, struct xc_px_stat *pxstat)
+static int get_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid, struct 
xc_px_stat *pxstat)
 {
     int ret = 0;
     int max_px_num = 0;
 
-    ret = xc_pm_get_max_px(xc_fd, cpuid, &max_px_num);
+    ret = xc_pm_get_max_px(xc_handle, cpuid, &max_px_num);
     if ( ret )
         return errno;
 
@@ -232,7 +232,7 @@ static int get_pxstat_by_cpuid(int xc_fd, int cpuid, struct 
xc_px_stat *pxstat)
         return -ENOMEM;
     }
 
-    ret = xc_pm_get_pxstat(xc_fd, cpuid, pxstat);
+    ret = xc_pm_get_pxstat(xc_handle, cpuid, pxstat);
     if( ret )
     {
         int temp = errno;
@@ -247,11 +247,11 @@ static int get_pxstat_by_cpuid(int xc_fd, int cpuid, 
struct xc_px_stat *pxstat)
 }
 
 /* show cpu actual average freq information on CPU cpuid */
-static int get_avgfreq_by_cpuid(int xc_fd, int cpuid, int *avgfreq)
+static int get_avgfreq_by_cpuid(xc_interface *xc_handle, int cpuid, int 
*avgfreq)
 {
     int ret = 0;
 
-    ret = xc_get_cpufreq_avgfreq(xc_fd, cpuid, avgfreq);
+    ret = xc_get_cpufreq_avgfreq(xc_handle, cpuid, avgfreq);
     if ( ret )
     {
         return errno;
@@ -260,12 +260,12 @@ static int get_avgfreq_by_cpuid(int xc_fd, int cpuid, int 
*avgfreq)
     return 0;
 }
 
-static int show_pxstat_by_cpuid(int xc_fd, int cpuid)
+static int show_pxstat_by_cpuid(xc_interface *xc_handle, int cpuid)
 {
     int ret = 0;
     struct xc_px_stat pxstatinfo;
 
-    ret = get_pxstat_by_cpuid(xc_fd, cpuid, &pxstatinfo);
+    ret = get_pxstat_by_cpuid(xc_handle, cpuid, &pxstatinfo);
     if ( ret )
         return ret;
 
@@ -291,11 +291,11 @@ void pxstat_func(int argc, char *argv[])
         /* show pxstates on all cpus */
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( show_pxstat_by_cpuid(xc_fd, i) == -ENODEV )
+            if ( show_pxstat_by_cpuid(xc_handle, i) == -ENODEV )
                 break;
     }
     else
-        show_pxstat_by_cpuid(xc_fd, cpuid);
+        show_pxstat_by_cpuid(xc_handle, cpuid);
 }
 
 static uint64_t usec_start, usec_end;
@@ -317,28 +317,28 @@ static void signal_int_handler(int signo)
     }
     usec_end = tv.tv_sec * 1000000UL + tv.tv_usec;
 
-    if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
+    if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV )
     {
         cx_cap = 1;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( !get_cxstat_by_cpuid(xc_fd, i, &cxstat_end[i]) )
+            if ( !get_cxstat_by_cpuid(xc_handle, i, &cxstat_end[i]) )
                 for ( j = 0; j < cxstat_end[i].nr; j++ )
                     sum_cx[i] += cxstat_end[i].residencies[j] -
                                  cxstat_start[i].residencies[j];
     }
 
-    if ( get_pxstat_by_cpuid(xc_fd, 0, NULL) != -ENODEV )
+    if ( get_pxstat_by_cpuid(xc_handle, 0, NULL) != -ENODEV )
     {
         px_cap = 1;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( !get_pxstat_by_cpuid(xc_fd, i , &pxstat_end[i]) )
+            if ( !get_pxstat_by_cpuid(xc_handle, i , &pxstat_end[i]) )
                 for ( j = 0; j < pxstat_end[i].total; j++ )
                     sum_px[i] += pxstat_end[i].pt[j].residency -
                                  pxstat_start[i].pt[j].residency;
     }
 
     for ( i = 0; i < max_cpu_nr; i++ )
-        get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]);
+        get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]);
 
     printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL);
     for ( i = 0; i < max_cpu_nr; i++ )
@@ -386,7 +386,7 @@ static void signal_int_handler(int signo)
     free(pxstat);
     free(sum);
     free(avgfreq);
-    xc_interface_close(xc_fd);
+    xc_interface_close(xc_handle);
     exit(0);
 }
 
@@ -447,8 +447,8 @@ void start_gather_func(int argc, char *argv[])
     pxstat_start = pxstat;
     pxstat_end = pxstat + max_cpu_nr;
 
-    if ( get_cxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV &&
-         get_pxstat_by_cpuid(xc_fd, 0, NULL) == -ENODEV )
+    if ( get_cxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV &&
+         get_pxstat_by_cpuid(xc_handle, 0, NULL) == -ENODEV )
     {
         fprintf(stderr, "Xen cpu idle and frequency is disabled!\n");
         return ;
@@ -456,9 +456,9 @@ void start_gather_func(int argc, char *argv[])
 
     for ( i = 0; i < max_cpu_nr; i++ )
     {
-        get_cxstat_by_cpuid(xc_fd, i, &cxstat_start[i]);
-        get_pxstat_by_cpuid(xc_fd, i, &pxstat_start[i]);
-        get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]);
+        get_cxstat_by_cpuid(xc_handle, i, &cxstat_start[i]);
+        get_pxstat_by_cpuid(xc_handle, i, &pxstat_start[i]);
+        get_avgfreq_by_cpuid(xc_handle, i, &avgfreq[i]);
     }
 
     if (signal(SIGINT, signal_int_handler) == SIG_ERR)
@@ -556,7 +556,7 @@ static void print_cpufreq_para(int cpuid, struct 
xc_get_cpufreq_para *p_cpufreq)
 }
 
 /* show cpu frequency parameters information on CPU cpuid */
-static int show_cpufreq_para_by_cpuid(int xc_fd, int cpuid)
+static int show_cpufreq_para_by_cpuid(xc_interface *xc_handle, int cpuid)
 {
     int ret = 0;
     struct xc_get_cpufreq_para cpufreq_para, *p_cpufreq = &cpufreq_para;
@@ -607,7 +607,7 @@ static int show_cpufreq_para_by_cpuid(int xc_fd, int cpuid)
             goto out;
         }
 
-        ret = xc_get_cpufreq_para(xc_fd, cpuid, p_cpufreq);
+        ret = xc_get_cpufreq_para(xc_handle, cpuid, p_cpufreq);
     } while ( ret && errno == EAGAIN );
 
     if ( ret == 0 )
@@ -645,11 +645,11 @@ void cpufreq_para_func(int argc, char *argv[])
         /* show cpu freqency information on all cpus */
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( show_cpufreq_para_by_cpuid(xc_fd, i) == -ENODEV )
+            if ( show_cpufreq_para_by_cpuid(xc_handle, i) == -ENODEV )
                 break;
     }
     else
-        show_cpufreq_para_by_cpuid(xc_fd, cpuid);
+        show_cpufreq_para_by_cpuid(xc_handle, cpuid);
 }
 
 void scaling_max_freq_func(int argc, char *argv[])
@@ -669,12 +669,12 @@ void scaling_max_freq_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MAX_FREQ, freq) )
+            if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MAX_FREQ, freq) )
                 fprintf(stderr, "[CPU%d] failed to set scaling max freq\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MAX_FREQ, freq) )
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MAX_FREQ, freq) )
             fprintf(stderr, "failed to set scaling max freq\n");
     }
 }
@@ -696,12 +696,12 @@ void scaling_min_freq_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_MIN_FREQ, freq) )
+            if ( xc_set_cpufreq_para(xc_handle, i, SCALING_MIN_FREQ, freq) )
                 fprintf(stderr, "[CPU%d] failed to set scaling min freq\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_MIN_FREQ, freq) )
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_MIN_FREQ, freq) )
             fprintf(stderr, "failed to set scaling min freq\n");
     }
 }
@@ -723,12 +723,12 @@ void scaling_speed_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_para(xc_fd, i, SCALING_SETSPEED, speed) )
+            if ( xc_set_cpufreq_para(xc_handle, i, SCALING_SETSPEED, speed) )
                 fprintf(stderr, "[CPU%d] failed to set scaling speed\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_para(xc_fd, cpuid, SCALING_SETSPEED, speed) )
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SCALING_SETSPEED, speed) )
             fprintf(stderr, "failed to set scaling speed\n");
     }
 }
@@ -750,13 +750,13 @@ void scaling_sampling_rate_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_para(xc_fd, i, SAMPLING_RATE, rate) )
+            if ( xc_set_cpufreq_para(xc_handle, i, SAMPLING_RATE, rate) )
                 fprintf(stderr,
                         "[CPU%d] failed to set scaling sampling rate\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_para(xc_fd, cpuid, SAMPLING_RATE, rate) )
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, SAMPLING_RATE, rate) )
             fprintf(stderr, "failed to set scaling sampling rate\n");
     }
 }
@@ -778,13 +778,13 @@ void scaling_up_threshold_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_para(xc_fd, i, UP_THRESHOLD, threshold) )
+            if ( xc_set_cpufreq_para(xc_handle, i, UP_THRESHOLD, threshold) )
                 fprintf(stderr,
                         "[CPU%d] failed to set up scaling threshold\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_para(xc_fd, cpuid, UP_THRESHOLD, threshold) )
+        if ( xc_set_cpufreq_para(xc_handle, cpuid, UP_THRESHOLD, threshold) )
             fprintf(stderr, "failed to set up scaling threshold\n");
     }
 }
@@ -818,12 +818,12 @@ void scaling_governor_func(int argc, char *argv[])
     {
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            if ( xc_set_cpufreq_gov(xc_fd, i, name) )
+            if ( xc_set_cpufreq_gov(xc_handle, i, name) )
                 fprintf(stderr, "[CPU%d] failed to set governor name\n", i);
     }
     else
     {
-        if ( xc_set_cpufreq_gov(xc_fd, cpuid, name) )
+        if ( xc_set_cpufreq_gov(xc_handle, cpuid, name) )
             fprintf(stderr, "failed to set governor name\n");
     }
 
@@ -848,7 +848,7 @@ void cpu_topology_func(int argc, char *argv[])
     set_xen_guest_handle(info.cpu_to_node, cpu_to_node);
     info.max_cpu_index = MAX_NR_CPU-1;
 
-    if ( xc_topologyinfo(xc_fd, &info) )
+    if ( xc_topologyinfo(xc_handle, &info) )
     {
         printf("Can not get Xen CPU topology: %d\n", errno);
         return;
@@ -890,7 +890,7 @@ void set_sched_smt_func(int argc, char *argv[])
         exit(-1);
     }
 
-    rc = xc_set_sched_opt_smt(xc_fd, value);
+    rc = xc_set_sched_opt_smt(xc_handle, value);
     printf("%s sched_smt_power_savings %s\n", argv[0],
                     rc? "failed":"succeeded" );
 
@@ -915,7 +915,7 @@ void set_vcpu_migration_delay_func(int argc, char *argv[])
         exit(-1);
     }
 
-    rc = xc_set_vcpu_migration_delay(xc_fd, value);
+    rc = xc_set_vcpu_migration_delay(xc_handle, value);
     printf("%s to set vcpu migration delay to %d us\n",
                     rc? "Fail":"Succeed", value );
 
@@ -932,7 +932,7 @@ void get_vcpu_migration_delay_func(int argc, char *argv[])
         exit(-1);
     }
 
-    rc = xc_get_vcpu_migration_delay(xc_fd, &value);
+    rc = xc_get_vcpu_migration_delay(xc_handle, &value);
     if (!rc)
     {
         printf("Schduler vcpu migration delay is %d us\n", value);
@@ -955,7 +955,7 @@ void set_max_cstate_func(int argc, char *argv[])
         exit(-1);
     }
 
-    rc = xc_set_cpuidle_max_cstate(xc_fd, (uint32_t)value);
+    rc = xc_set_cpuidle_max_cstate(xc_handle, (uint32_t)value);
     printf("set max_cstate to C%d %s\n", value,
                     rc? "failed":"succeeded" );
 
@@ -978,10 +978,10 @@ void enable_turbo_mode(int argc, char *argv[])
          * only make effects on dbs governor */
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            xc_enable_turbo(xc_fd, i);
+            xc_enable_turbo(xc_handle, i);
     }
     else
-        xc_enable_turbo(xc_fd, cpuid);
+        xc_enable_turbo(xc_handle, cpuid);
 }
 
 void disable_turbo_mode(int argc, char *argv[])
@@ -1000,10 +1000,10 @@ void disable_turbo_mode(int argc, char *argv[])
          * only make effects on dbs governor */
         int i;
         for ( i = 0; i < max_cpu_nr; i++ )
-            xc_disable_turbo(xc_fd, i);
+            xc_disable_turbo(xc_handle, i);
     }
     else
-        xc_disable_turbo(xc_fd, cpuid);
+        xc_disable_turbo(xc_handle, cpuid);
 }
 
 struct {
@@ -1043,18 +1043,18 @@ int main(int argc, char *argv[])
         return 0;
     }
 
-    xc_fd = xc_interface_open();
-    if ( xc_fd < 0 )
+    xc_handle = xc_interface_open(0,0,0);
+    if ( !xc_handle )
     {
         fprintf(stderr, "failed to get the handler\n");
         return 0;
     }
 
-    ret = xc_physinfo(xc_fd, &physinfo);
+    ret = xc_physinfo(xc_handle, &physinfo);
     if ( ret )
     {
         fprintf(stderr, "failed to get the processor information\n");
-        xc_interface_close(xc_fd);
+        xc_interface_close(xc_handle);
         return 0;
     }
     max_cpu_nr = physinfo.nr_cpus;
@@ -1077,7 +1077,7 @@ int main(int argc, char *argv[])
     else
         show_help();
 
-    xc_interface_close(xc_fd);
+    xc_interface_close(xc_handle);
     return 0;
 }
 
diff --git a/tools/python/xen/lowlevel/acm/acm.c 
b/tools/python/xen/lowlevel/acm/acm.c
index 662c7f7..7b0b508 100644
--- a/tools/python/xen/lowlevel/acm/acm.c
+++ b/tools/python/xen/lowlevel/acm/acm.c
@@ -43,11 +43,11 @@ static PyObject *acm_error_obj;
 static void *__getssid(int domid, uint32_t *buflen)
 {
     struct acm_getssid getssid;
-    int xc_handle;
+    xc_interface *xc_handle;
     #define SSID_BUFFER_SIZE    4096
     void *buf = NULL;
 
-    if ((xc_handle = xc_interface_open()) < 0) {
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0) {
         goto out1;
     }
     if ((buf = malloc(SSID_BUFFER_SIZE)) == NULL) {
@@ -148,7 +148,8 @@ static PyObject *getdecision(PyObject * self, PyObject * 
args)
 {
     char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
     struct acm_getdecision getdecision;
-    int xc_handle, rc;
+    xc_interface *xc_handle;
+    int rc;
     uint32_t hooktype;
 
     if (!PyArg_ParseTuple(args, "ssssi", &arg1_name,
@@ -156,8 +157,8 @@ static PyObject *getdecision(PyObject * self, PyObject * 
args)
         return NULL;
     }
 
-    if ((xc_handle = xc_interface_open()) <= 0) {
-        PERROR("Could not open xen privcmd device!\n");
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0) {
+        perror("Could not open xen privcmd device!\n");
         return NULL;
     }
 
@@ -209,7 +210,8 @@ const char hv_op_err[] = "Error from hypervisor operation.";
 static PyObject *chgpolicy(PyObject *self, PyObject *args)
 {
     struct acm_change_policy chgpolicy;
-    int xc_handle, rc;
+    xc_interface *xc_handle;
+    int rc;
     char *bin_pol = NULL, *del_arr = NULL, *chg_arr = NULL;
     int bin_pol_len = 0, del_arr_len = 0, chg_arr_len = 0;
     uint errarray_mbrs = 20 * 2;
@@ -236,7 +238,7 @@ static PyObject *chgpolicy(PyObject *self, PyObject *args)
     set_xen_guest_handle(chgpolicy.chg_array, chg_arr);
     set_xen_guest_handle(chgpolicy.err_array, error_array);
 
-    if ((xc_handle = xc_interface_open()) <= 0) {
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0) {
         PyErr_SetString(PyExc_IOError, ctrlif_op);
         return NULL;
     }
@@ -261,7 +263,8 @@ static PyObject *chgpolicy(PyObject *self, PyObject *args)
 static PyObject *getpolicy(PyObject *self, PyObject *args)
 {
     struct acm_getpolicy getpolicy;
-    int xc_handle, rc;
+    xc_interface *xc_handle;
+    int rc;
     uint8_t pull_buffer[8192];
     PyObject *result;
     uint32_t len = sizeof(pull_buffer);
@@ -270,7 +273,7 @@ static PyObject *getpolicy(PyObject *self, PyObject *args)
     set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
     getpolicy.pullcache_size = sizeof(pull_buffer);
 
-    if ((xc_handle = xc_interface_open()) <= 0) {
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0) {
         PyErr_SetString(PyExc_IOError, ctrlif_op);
         return NULL;
     }
@@ -296,7 +299,8 @@ static PyObject *getpolicy(PyObject *self, PyObject *args)
 static PyObject *relabel_domains(PyObject *self, PyObject *args)
 {
     struct acm_relabel_doms reldoms;
-    int xc_handle, rc;
+    xc_interface *xc_handle;
+    int rc;
     char *relabel_rules = NULL;
     int rel_rules_len = 0;
     uint errarray_mbrs = 20 * 2;
@@ -317,7 +321,7 @@ static PyObject *relabel_domains(PyObject *self, PyObject 
*args)
     set_xen_guest_handle(reldoms.relabel_map, relabel_rules);
     set_xen_guest_handle(reldoms.err_array, error_array);
 
-    if ((xc_handle = xc_interface_open()) <= 0) {
+    if ((xc_handle = xc_interface_open(0,0,0)) == 0) {
         PyErr_SetString(PyExc_IOError, ctrlif_op);
         return NULL;
     }
diff --git a/tools/python/xen/lowlevel/checkpoint/checkpoint.h 
b/tools/python/xen/lowlevel/checkpoint/checkpoint.h
index 3627a11..24db54f 100644
--- a/tools/python/xen/lowlevel/checkpoint/checkpoint.h
+++ b/tools/python/xen/lowlevel/checkpoint/checkpoint.h
@@ -18,7 +18,7 @@ typedef enum {
 } checkpoint_domtype;
 
 typedef struct {
-    int xch;               /* xc handle */
+    xc_interface *xch;
     int xce;               /* event channel handle */
     struct xs_handle* xsh; /* xenstore handle */
     int watching_shutdown; /* state of watch on @releaseDomain */
diff --git a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c 
b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
index d84fa83..4c4cb4f 100644
--- a/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
+++ b/tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -47,7 +47,7 @@ char* checkpoint_error(checkpoint_state* s)
 
 void checkpoint_init(checkpoint_state* s)
 {
-    s->xch = -1;
+    s->xch = NULL;
     s->xce = -1;
     s->xsh = NULL;
     s->watching_shutdown = 0;
@@ -74,8 +74,8 @@ int checkpoint_open(checkpoint_state* s, unsigned int domid)
 
     s->domid = domid;
 
-    s->xch = xc_interface_open();
-    if (s->xch < 0) {
+    s->xch = xc_interface_open(0,0,0);
+    if (!s->xch) {
        s->errstr = "could not open control interface (are you root?)";
 
        return -1;
@@ -145,9 +145,9 @@ void checkpoint_close(checkpoint_state* s)
   release_shutdown_watch(s);
   release_suspend_evtchn(s);
 
-  if (s->xch >= 0) {
+  if (s->xch) {
     xc_interface_close(s->xch);
-    s->xch = -1;
+    s->xch = NULL;
   }
   if (s->xce >= 0) {
     xc_evtchn_close(s->xce);
@@ -360,7 +360,7 @@ static void release_suspend_evtchn(checkpoint_state *s)
 {
   /* TODO: teach xen to clean up if port is unbound */
   if (s->xce >= 0 && s->suspend_evtchn >= 0) {
-    xc_suspend_evtchn_release(s->xce, s->domid, s->suspend_evtchn);
+    xc_suspend_evtchn_release(s->xch, s->xce, s->domid, s->suspend_evtchn);
     s->suspend_evtchn = -1;
   }
 }
diff --git a/tools/python/xen/lowlevel/flask/flask.c 
b/tools/python/xen/lowlevel/flask/flask.c
index 858d8d3..64e8d63 100644
--- a/tools/python/xen/lowlevel/flask/flask.c
+++ b/tools/python/xen/lowlevel/flask/flask.c
@@ -23,13 +23,13 @@ static PyObject *xc_error_obj;
 
 typedef struct {
     PyObject_HEAD;
-    int xc_handle;
+    xc_interface *xc_handle;
 } XcObject;
 
 static PyObject *pyflask_context_to_sid(PyObject *self, PyObject *args,
                                                                  PyObject 
*kwds)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     char *ctx;
     char *buf;
     uint32_t len;
@@ -52,9 +52,8 @@ static PyObject *pyflask_context_to_sid(PyObject *self, 
PyObject *args,
     
     memcpy(buf, ctx, len);
     
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         free(buf);
         return PyErr_SetFromErrno(xc_error_obj);
     }
@@ -76,7 +75,7 @@ static PyObject *pyflask_context_to_sid(PyObject *self, 
PyObject *args,
 static PyObject *pyflask_sid_to_context(PyObject *self, PyObject *args,
                                                                  PyObject 
*kwds)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     uint32_t sid;
     char ctx[CTX_LEN];
     uint32_t ctx_len = CTX_LEN;
@@ -88,9 +87,8 @@ static PyObject *pyflask_sid_to_context(PyObject *self, 
PyObject *args,
                                       &sid) )
         return NULL;
 
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         return PyErr_SetFromErrno(xc_error_obj);
     }
     
@@ -108,7 +106,7 @@ static PyObject *pyflask_sid_to_context(PyObject *self, 
PyObject *args,
 
 static PyObject *pyflask_load(PyObject *self, PyObject *args, PyObject *kwds)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     char *policy;
     uint32_t len;
     int ret;
@@ -118,9 +116,8 @@ static PyObject *pyflask_load(PyObject *self, PyObject 
*args, PyObject *kwds)
     if( !PyArg_ParseTupleAndKeywords(args, kwds, "s#", kwd_list, &policy, 
&len) )
         return NULL;
 
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         return PyErr_SetFromErrno(xc_error_obj);
     }
 
@@ -138,12 +135,11 @@ static PyObject *pyflask_load(PyObject *self, PyObject 
*args, PyObject *kwds)
 
 static PyObject *pyflask_getenforce(PyObject *self)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     int ret;
 
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         return PyErr_SetFromErrno(xc_error_obj);
     }
     
@@ -162,7 +158,7 @@ static PyObject *pyflask_getenforce(PyObject *self)
 static PyObject *pyflask_setenforce(PyObject *self, PyObject *args,
                                                             PyObject *kwds)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     int mode;
     int ret;
 
@@ -172,9 +168,8 @@ static PyObject *pyflask_setenforce(PyObject *self, 
PyObject *args,
                                       &mode) )
         return NULL;
 
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         return PyErr_SetFromErrno(xc_error_obj);
     }
     
@@ -193,7 +188,7 @@ static PyObject *pyflask_setenforce(PyObject *self, 
PyObject *args,
 static PyObject *pyflask_access(PyObject *self, PyObject *args,
                                                        PyObject *kwds)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     char *tcon, *scon;
     uint16_t tclass;
     uint32_t req, allowed, decided, auditallow, auditdeny, seqno;
@@ -209,9 +204,8 @@ static PyObject *pyflask_access(PyObject *self, PyObject 
*args,
                                       &auditallow, &auditdeny, &seqno) )
         return NULL;
 
-    xc_handle = xc_interface_open();
-    if (xc_handle < 0) {
-        errno = xc_handle;
+    xc_handle = xc_interface_open(0,0,0);
+    if (!xc_handle) {
         return PyErr_SetFromErrno(xc_error_obj);
     }
     
diff --git a/tools/python/xen/lowlevel/xc/xc.c 
b/tools/python/xen/lowlevel/xc/xc.c
index 39864b4..7330191 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -38,18 +38,32 @@ static PyObject *xc_error_obj, *zero;
 
 typedef struct {
     PyObject_HEAD;
-    int xc_handle;
+    xc_interface *xc_handle;
 } XcObject;
 
 
 static PyObject *dom_op(XcObject *self, PyObject *args,
-                        int (*fn)(int, uint32_t));
+                        int (*fn)(xc_interface *, uint32_t));
 
-static PyObject *pyxc_error_to_exception(void)
+static PyObject *pyxc_error_to_exception(xc_interface *xch)
 {
     PyObject *pyerr;
-    const xc_error *err = xc_get_last_error();
-    const char *desc = xc_error_code_to_desc(err->code);
+    static xc_error err_buf;
+    const char *desc;
+    const xc_error *err;
+
+    if (xch) {
+        err = xc_get_last_error(xch);
+    } else {
+        snprintf(err_buf.message, sizeof(err_buf.message),
+                 "xc_interface_open failed: %s",
+                 strerror(errno));
+        err_buf.message[sizeof(err_buf)-1] = 0;
+        err_buf.code = XC_INTERNAL_ERROR;
+        err = &err_buf;
+    }
+
+    desc = xc_error_code_to_desc(err->code);
 
     if ( err->code == XC_ERROR_NONE )
         return PyErr_SetFromErrno(xc_error_obj);
@@ -59,7 +73,7 @@ static PyObject *pyxc_error_to_exception(void)
     else
         pyerr = Py_BuildValue("(is)", err->code, desc);
 
-    xc_clear_last_error();
+    xc_clear_last_error(xch);
 
     if ( pyerr != NULL )
     {
@@ -82,17 +96,12 @@ static PyObject *pyxc_domain_dumpcore(XcObject *self, 
PyObject *args)
         return NULL;
 
     if ( xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
 }
 
-static PyObject *pyxc_handle(XcObject *self)
-{
-    return PyInt_FromLong(self->xc_handle);
-}
-
 static PyObject *pyxc_domain_create(XcObject *self,
                                     PyObject *args,
                                     PyObject *kwds)
@@ -126,11 +135,11 @@ static PyObject *pyxc_domain_create(XcObject *self,
 
     if ( (ret = xc_domain_create(self->xc_handle, ssidref,
                                  handle, flags, &dom)) < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( target )
         if ( (ret = xc_domain_set_target(self->xc_handle, dom, target)) < 0 )
-            return pyxc_error_to_exception();
+            return pyxc_error_to_exception(self->xc_handle);
 
 
     return PyInt_FromLong(dom);
@@ -149,7 +158,7 @@ static PyObject *pyxc_domain_max_vcpus(XcObject *self, 
PyObject *args)
       return NULL;
 
     if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -188,7 +197,7 @@ static PyObject *pyxc_domain_shutdown(XcObject *self, 
PyObject *args)
       return NULL;
 
     if ( xc_domain_shutdown(self->xc_handle, dom, reason) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -203,7 +212,7 @@ static PyObject *pyxc_domain_resume(XcObject *self, 
PyObject *args)
         return NULL;
 
     if ( xc_domain_resume(self->xc_handle, dom, fast) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -228,14 +237,14 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
         return NULL;
 
     if ( xc_physinfo(self->xc_handle, &info) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
   
     nr_cpus = info.nr_cpus;
 
     size = (nr_cpus + cpumap_size * 8 - 1)/ (cpumap_size * 8);
     cpumap = malloc(cpumap_size * size);
     if(cpumap == NULL)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( (cpulist != NULL) && PyList_Check(cpulist) )
     {
@@ -253,7 +262,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
     if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap, size * 
cpumap_size) != 0 )
     {
         free(cpumap);
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     }
     Py_INCREF(zero);
     free(cpumap); 
@@ -285,7 +294,7 @@ static PyObject *pyxc_domain_sethandle(XcObject *self, 
PyObject *args)
     }
 
     if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -321,7 +330,7 @@ static PyObject *pyxc_domain_getinfo(XcObject *self,
     if (nr_doms < 0)
     {
         free(info);
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     }
 
     list = PyList_New(nr_doms);
@@ -388,23 +397,23 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,
         return NULL;
 
     if ( xc_physinfo(self->xc_handle, &pinfo) != 0 ) 
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     nr_cpus = pinfo.nr_cpus;
 
     rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
     if ( rc < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     size = (nr_cpus + cpumap_size * 8 - 1)/ (cpumap_size * 8); 
     if((cpumap = malloc(cpumap_size * size)) == NULL)
-        return pyxc_error_to_exception(); 
+        return pyxc_error_to_exception(self->xc_handle); 
     memset(cpumap, 0, cpumap_size * size);
 
     rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, cpumap, cpumap_size * 
size);
     if ( rc < 0 )
     {
         free(cpumap);
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     }
 
     info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
@@ -440,9 +449,10 @@ static PyObject *pyxc_getBitSize(XcObject *self,
     if ( !PyArg_ParseTupleAndKeywords(args, kwds, "sss", kwd_list,
                                       &image, &cmdline, &features) )
         return NULL;
-    xc_get_bit_size(image, cmdline, features, &type);
+
+    xc_get_bit_size(self->xc_handle, image, cmdline, features, &type);
     if (type < 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     info_type = Py_BuildValue("{s:i}",
                               "type", type);
     return info_type;
@@ -481,9 +491,9 @@ static PyObject *pyxc_linux_build(XcObject *self,
                                       &features, &vhpt, &superpages) )
         return NULL;
 
-    xc_dom_loginit();
-    if (!(dom = xc_dom_allocate(cmdline, features)))
-        return pyxc_error_to_exception();
+    xc_dom_loginit(self->xc_handle);
+    if (!(dom = xc_dom_allocate(self->xc_handle, cmdline, features)))
+        return pyxc_error_to_exception(self->xc_handle);
 
     /* for IA64 */
     dom->vhpt_size_log2 = vhpt;
@@ -537,7 +547,7 @@ static PyObject *pyxc_linux_build(XcObject *self,
 
   out:
     xc_dom_release(dom);
-    return pyxc_error_to_exception();
+    return pyxc_error_to_exception(self->xc_handle);
 }
 
 static PyObject *pyxc_get_hvm_param(XcObject *self,
@@ -554,7 +564,7 @@ static PyObject *pyxc_get_hvm_param(XcObject *self,
         return NULL;
 
     if ( xc_get_hvm_param(self->xc_handle, dom, param, &value) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return PyLong_FromUnsignedLong(value);
 
@@ -574,7 +584,7 @@ static PyObject *pyxc_set_hvm_param(XcObject *self,
         return NULL;
 
     if ( xc_set_hvm_param(self->xc_handle, dom, param, value) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -734,7 +744,7 @@ static PyObject *pyxc_get_device_group(XcObject *self,
     if ( rc < 0 )
     {
         free(sdev_array); 
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     }
 
     if ( !num_sdevs )
@@ -855,7 +865,7 @@ static PyObject *pyxc_dom_check_cpuid(XcObject *self,
 
     if ( xc_cpuid_check(self->xc_handle, input,
                         (const char **)regs, regs_transform) )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return pyxc_create_cpuid_dict(regs_transform);
 }
@@ -869,7 +879,7 @@ static PyObject *pyxc_dom_set_policy_cpuid(XcObject *self,
         return NULL;
 
     if ( xc_cpuid_apply_policy(self->xc_handle, domid) )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -895,7 +905,7 @@ static PyObject *pyxc_dom_set_cpuid(XcObject *self,
 
     if ( xc_cpuid_set(self->xc_handle, domid, input, (const char **)regs,
                       regs_transform) )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return pyxc_create_cpuid_dict(regs_transform);
 }
@@ -910,7 +920,7 @@ static PyObject *pyxc_dom_set_machine_address_size(XcObject 
*self,
        return NULL;
 
     if (xc_domain_set_machine_address_size(self->xc_handle, dom, width) != 0)
-       return pyxc_error_to_exception();
+       return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -926,7 +936,7 @@ static PyObject 
*pyxc_dom_suppress_spurious_page_faults(XcObject *self,
        return NULL;
 
     if (xc_domain_suppress_spurious_page_faults(self->xc_handle, dom) != 0)
-       return pyxc_error_to_exception();
+       return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -986,7 +996,7 @@ static PyObject *pyxc_hvm_build(XcObject *self,
 
     if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
                                  target, image) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
 #if !defined(__ia64__)
     /* Fix up the HVM info table. */
@@ -1023,7 +1033,7 @@ static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
         return NULL;
 
     if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 
0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return PyInt_FromLong(port);
 }
@@ -1040,7 +1050,7 @@ static PyObject *pyxc_evtchn_reset(XcObject *self,
         return NULL;
 
     if ( xc_evtchn_reset(self->xc_handle, dom) < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1061,7 +1071,7 @@ static PyObject *pyxc_physdev_map_pirq(PyObject *self,
         return NULL;
     ret = xc_physdev_map_pirq(xc->xc_handle, dom, index, &pirq);
     if ( ret != 0 )
-          return pyxc_error_to_exception();
+          return pyxc_error_to_exception(xc->xc_handle);
     return PyLong_FromUnsignedLong(pirq);
 }
 
@@ -1081,7 +1091,7 @@ static PyObject *pyxc_physdev_pci_access_modify(XcObject 
*self,
     ret = xc_physdev_pci_access_modify(
         self->xc_handle, dom, bus, dev, func, enable);
     if ( ret != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1107,7 +1117,7 @@ static PyObject *pyxc_readconsolering(XcObject *self,
     ret = xc_readconsolering(self->xc_handle, &str, &count, clear,
                              incremental, &index);
     if ( ret < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     while ( !incremental && count == size )
     {
@@ -1160,7 +1170,7 @@ static PyObject *pyxc_physinfo(XcObject *self)
     const char *virtcap_names[] = { "hvm", "hvm_directio" };
 
     if ( xc_physinfo(self->xc_handle, &pinfo) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     p = cpu_cap;
     *p = '\0';
@@ -1206,7 +1216,7 @@ static PyObject *pyxc_topologyinfo(XcObject *self)
     tinfo.max_cpu_index = MAX_CPU_INDEX;
 
     if ( xc_topologyinfo(self->xc_handle, &tinfo) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     max_cpu_index = tinfo.max_cpu_index;
     if ( max_cpu_index > MAX_CPU_INDEX )
@@ -1286,7 +1296,7 @@ static PyObject *pyxc_numainfo(XcObject *self)
     ninfo.max_node_index = MAX_NODE_INDEX;
 
     if ( xc_numainfo(self->xc_handle, &ninfo) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     max_node_index = ninfo.max_node_index;
     if ( max_node_index > MAX_NODE_INDEX )
@@ -1371,28 +1381,28 @@ static PyObject *pyxc_xeninfo(XcObject *self)
     xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
 
     if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 
0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     if ( xc_version(self->xc_handle, XENVER_commandline, &xen_commandline) != 
0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     snprintf(str, sizeof(str), "virt_start=0x%lx", p_parms.virt_start);
 
     xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
     if (xen_pagesize < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s,s:s}",
                          "xen_major", xen_version >> 16,
@@ -1426,7 +1436,7 @@ static PyObject *pyxc_sedf_domain_set(XcObject *self,
         return NULL;
    if ( xc_sedf_domain_set(self->xc_handle, domid, period,
                            slice, latency, extratime,weight) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1443,7 +1453,7 @@ static PyObject *pyxc_sedf_domain_get(XcObject *self, 
PyObject *args)
     
     if (xc_sedf_domain_get(self->xc_handle, domid, &period,
                            &slice,&latency,&extratime,&weight))
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
                          "domid",    domid,
@@ -1471,7 +1481,7 @@ static PyObject *pyxc_shadow_control(PyObject *self,
     
     if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL) 
          < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(xc->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -1501,7 +1511,7 @@ static PyObject *pyxc_shadow_mem_control(PyObject *self,
         op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
     }
     if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(xc->xc_handle);
     
     mbarg = mb;
     return Py_BuildValue("i", mbarg);
@@ -1537,7 +1547,7 @@ static PyObject *pyxc_sched_credit_domain_set(XcObject 
*self,
     sdom.cap = cap;
 
     if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1552,7 +1562,7 @@ static PyObject *pyxc_sched_credit_domain_get(XcObject 
*self, PyObject *args)
         return NULL;
     
     if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return Py_BuildValue("{s:H,s:H}",
                          "weight",  sdom.weight,
@@ -1577,7 +1587,7 @@ static PyObject *pyxc_sched_credit2_domain_set(XcObject 
*self,
     sdom.weight = weight;
 
     if ( xc_sched_credit2_domain_set(self->xc_handle, domid, &sdom) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1592,7 +1602,7 @@ static PyObject *pyxc_sched_credit2_domain_get(XcObject 
*self, PyObject *args)
         return NULL;
 
     if ( xc_sched_credit2_domain_get(self->xc_handle, domid, &sdom) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return Py_BuildValue("{s:H}",
                          "weight",  sdom.weight);
@@ -1607,7 +1617,7 @@ static PyObject *pyxc_domain_setmaxmem(XcObject *self, 
PyObject *args)
         return NULL;
 
     if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -1625,7 +1635,7 @@ static PyObject *pyxc_domain_set_target_mem(XcObject 
*self, PyObject *args)
 
     if (xc_domain_memory_set_pod_target(self->xc_handle, dom, mem_pages,
                                         NULL, NULL, NULL) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -1640,7 +1650,7 @@ static PyObject *pyxc_domain_set_memmap_limit(XcObject 
*self, PyObject *args)
         return NULL;
 
     if ( xc_domain_set_memmap_limit(self->xc_handle, dom, maplimit_kb) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -1662,7 +1672,7 @@ static PyObject *pyxc_domain_ioport_permission(XcObject 
*self,
     ret = xc_domain_ioport_permission(
         self->xc_handle, dom, first_port, nr_ports, allow_access);
     if ( ret != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1685,7 +1695,7 @@ static PyObject *pyxc_domain_irq_permission(PyObject 
*self,
     ret = xc_domain_irq_permission(
         xc->xc_handle, dom, pirq, allow_access);
     if ( ret != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(xc->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1708,7 +1718,7 @@ static PyObject *pyxc_domain_iomem_permission(PyObject 
*self,
     ret = xc_domain_iomem_permission(
         xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
     if ( ret != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(xc->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1723,7 +1733,7 @@ static PyObject *pyxc_domain_set_time_offset(XcObject 
*self, PyObject *args)
         return NULL;
 
     if (xc_domain_set_time_offset(self->xc_handle, dom, offset) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1737,7 +1747,7 @@ static PyObject *pyxc_domain_set_tsc_info(XcObject *self, 
PyObject *args)
         return NULL;
 
     if (xc_domain_set_tsc_info(self->xc_handle, dom, tsc_mode, 0, 0, 0) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1751,7 +1761,7 @@ static PyObject *pyxc_domain_disable_migrate(XcObject 
*self, PyObject *args)
         return NULL;
 
     if (xc_domain_disable_migrate(self->xc_handle, dom) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1771,7 +1781,7 @@ static PyObject *pyxc_domain_send_trigger(XcObject *self,
         return NULL;
 
     if (xc_domain_send_trigger(self->xc_handle, dom, trigger, vcpu) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1789,14 +1799,14 @@ static PyObject *pyxc_send_debug_keys(XcObject *self,
         return NULL;
 
     if ( xc_send_debug_keys(self->xc_handle, keys) != 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
 }
 
 static PyObject *dom_op(XcObject *self, PyObject *args,
-                        int (*fn)(int, uint32_t))
+                        int (*fn)(xc_interface*, uint32_t))
 {
     uint32_t dom;
 
@@ -1804,7 +1814,7 @@ static PyObject *dom_op(XcObject *self, PyObject *args,
         return NULL;
 
     if (fn(self->xc_handle, dom) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1888,7 +1898,7 @@ static PyObject *pyxc_dom_set_memshr(XcObject *self, 
PyObject *args)
         return NULL;
 
     if (xc_memshr_control(self->xc_handle, dom, enable) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     
     Py_INCREF(zero);
     return zero;
@@ -1927,7 +1937,7 @@ static PyObject *pyxc_cpupool_create(XcObject *self,
         return NULL;
 
     if ( xc_cpupool_create(self->xc_handle, &cpupool, sched) < 0 )
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return PyInt_FromLong(cpupool);
 }
@@ -1941,7 +1951,7 @@ static PyObject *pyxc_cpupool_destroy(XcObject *self,
         return NULL;
 
     if (xc_cpupool_destroy(self->xc_handle, cpupool) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -1972,7 +1982,7 @@ static PyObject *pyxc_cpupool_getinfo(XcObject *self,
     if (nr_pools < 0)
     {
         free(info);
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
     }
 
     list = PyList_New(nr_pools);
@@ -2013,7 +2023,7 @@ static PyObject *pyxc_cpupool_addcpu(XcObject *self,
         return NULL;
 
     if (xc_cpupool_addcpu(self->xc_handle, cpupool, cpu) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -2033,7 +2043,7 @@ static PyObject *pyxc_cpupool_removecpu(XcObject *self,
         return NULL;
 
     if (xc_cpupool_removecpu(self->xc_handle, cpupool, cpu) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -2052,7 +2062,7 @@ static PyObject *pyxc_cpupool_movedomain(XcObject *self,
         return NULL;
 
     if (xc_cpupool_movedomain(self->xc_handle, cpupool, domid) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     Py_INCREF(zero);
     return zero;
@@ -2063,18 +2073,12 @@ static PyObject *pyxc_cpupool_freeinfo(XcObject *self)
     uint64_t cpumap;
 
     if (xc_cpupool_freeinfo(self->xc_handle, &cpumap) != 0)
-        return pyxc_error_to_exception();
+        return pyxc_error_to_exception(self->xc_handle);
 
     return cpumap_to_cpulist(cpumap);
 }
 
 static PyMethodDef pyxc_methods[] = {
-    { "handle",
-      (PyCFunction)pyxc_handle,
-      METH_NOARGS, "\n"
-      "Query the xc control interface file descriptor.\n\n"
-      "Returns: [int] file descriptor\n" },
-
     { "domain_create", 
       (PyCFunction)pyxc_domain_create, 
       METH_VARARGS | METH_KEYWORDS, "\n"
@@ -2689,7 +2693,7 @@ static PyObject *PyXc_new(PyTypeObject *type, PyObject 
*args, PyObject *kwds)
     if (self == NULL)
         return NULL;
 
-    self->xc_handle = -1;
+    self->xc_handle = NULL;
 
     return (PyObject *)self;
 }
@@ -2697,8 +2701,8 @@ static PyObject *PyXc_new(PyTypeObject *type, PyObject 
*args, PyObject *kwds)
 static int
 PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
 {
-    if ((self->xc_handle = xc_interface_open()) == -1) {
-        pyxc_error_to_exception();
+    if ((self->xc_handle = xc_interface_open(0,0,0)) == 0) {
+        pyxc_error_to_exception(0);
         return -1;
     }
 
@@ -2707,9 +2711,9 @@ PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
 
 static void PyXc_dealloc(XcObject *self)
 {
-    if (self->xc_handle != -1) {
+    if (self->xc_handle) {
         xc_interface_close(self->xc_handle);
-        self->xc_handle = -1;
+        self->xc_handle = NULL;
     }
 
     self->ob_type->tp_free((PyObject *)self);
diff --git a/tools/security/secpol_tool.c b/tools/security/secpol_tool.c
index e9da8e4..fa7eafd 100644
--- a/tools/security/secpol_tool.c
+++ b/tools/security/secpol_tool.c
@@ -238,7 +238,7 @@ void acm_dump_policy_buffer(void *buf, int buflen,
 }
 
 /************************** get dom0 ssidref *****************************/
-int acm_get_ssidref(int xc_handle, int domid, uint16_t *chwall_ref,
+int acm_get_ssidref(xc_interface *xc_handle, int domid, uint16_t *chwall_ref,
                     uint16_t *ste_ref)
 {
     int ret;
@@ -262,7 +262,7 @@ int acm_get_ssidref(int xc_handle, int domid, uint16_t 
*chwall_ref,
 #define PULL_CACHE_SIZE                8192
 uint8_t pull_buffer[PULL_CACHE_SIZE];
 
-int acm_domain_getpolicy(int xc_handle)
+int acm_domain_getpolicy(xc_interface *xc_handle)
 {
     struct acm_getpolicy getpolicy;
     int ret;
@@ -349,7 +349,7 @@ static int acm_domain_dumppolicy(const char *filename, 
uint32_t ssidref)
 
 /************************ load binary policy ******************************/
 
-int acm_domain_loadpolicy(int xc_handle, const char *filename)
+int acm_domain_loadpolicy(xc_interface *xc_handle, const char *filename)
 {
     int ret;
     off_t len;
@@ -403,7 +403,7 @@ void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats)
 }
 
 #define PULL_STATS_SIZE                8192
-int acm_domain_dumpstats(int xc_handle)
+int acm_domain_dumpstats(xc_interface *xc_handle)
 {
     uint8_t stats_buffer[PULL_STATS_SIZE];
     struct acm_dumpstats dumpstats;
@@ -472,7 +472,7 @@ int acm_domain_dumpstats(int xc_handle)
 int main(int argc, char **argv)
 {
 
-    int xc_handle, ret = 0;
+    xc_interface *xc_handle, ret = 0;
 
     if (argc < 2)
         usage(argv[0]);
@@ -482,7 +482,7 @@ int main(int argc, char **argv)
         if (argc != 2)
             usage(argv[0]);
 
-        if ((xc_handle = xc_interface_open()) <= 0) {
+        if ((xc_handle = xc_interface_open()) == 0) {
             printf("ERROR: Could not open xen privcmd device!\n");
             exit(-1);
         }
@@ -494,7 +494,7 @@ int main(int argc, char **argv)
         if (argc != 3)
             usage(argv[0]);
 
-        if ((xc_handle = xc_interface_open()) <= 0) {
+        if ((xc_handle = xc_interface_open()) == 0) {
             printf("ERROR: Could not open xen privcmd device!\n");
             exit(-1);
         }
@@ -506,7 +506,7 @@ int main(int argc, char **argv)
         if (argc != 2)
             usage(argv[0]);
 
-        if ((xc_handle = xc_interface_open()) <= 0) {
+        if ((xc_handle = xc_interface_open()) == 0) {
             printf("ERROR: Could not open xen privcmd device!\n");
             exit(-1);
         }
diff --git a/tools/xcutils/lsevtchn.c b/tools/xcutils/lsevtchn.c
index 7e7bcbe..e79fe09 100644
--- a/tools/xcutils/lsevtchn.c
+++ b/tools/xcutils/lsevtchn.c
@@ -10,20 +10,21 @@
 
 int main(int argc, char **argv)
 {
-    int xc_fd, domid, port, rc;
+    xc_interface *xch;
+    int domid, port, rc;
     xc_evtchn_status_t status;
 
     domid = (argc > 1) ? strtol(argv[1], NULL, 10) : 0;
 
-    xc_fd = xc_interface_open();
-    if ( xc_fd < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
         errx(1, "failed to open control interface");
 
     for ( port = 0; ; port++ )
     {
         status.dom = domid;
         status.port = port;
-        rc = xc_evtchn_status(xc_fd, &status);
+        rc = xc_evtchn_status(xch, &status);
         if ( rc < 0 )
             break;
 
@@ -59,7 +60,7 @@ int main(int argc, char **argv)
         printf("\n");
     }
 
-    xc_interface_close(xc_fd);
+    xc_interface_close(xch);
 
     return 0;
 }
diff --git a/tools/xcutils/readnotes.c b/tools/xcutils/readnotes.c
index 270c48b..2637685 100644
--- a/tools/xcutils/readnotes.c
+++ b/tools/xcutils/readnotes.c
@@ -5,6 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <stdarg.h>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -15,6 +16,8 @@
 
 #include <xen/libelf/libelf.h>
 
+static xc_interface *xch;
+
 static void print_string_note(const char *prefix, struct elf_binary *elf,
                              const elf_note *note)
 {
@@ -135,6 +138,8 @@ int main(int argc, char **argv)
        }
        f = argv[1];
 
+        xch = xc_interface_open(0,0,XC_OPENFLAG_DUMMY);
+
        fd = open(f, O_RDONLY);
        if (fd == -1)
        {
@@ -156,11 +161,11 @@ int main(int argc, char **argv)
        }
        size = st.st_size;
 
-       usize = xc_dom_check_gzip(image, st.st_size);
+       usize = xc_dom_check_gzip(xch, image, st.st_size);
        if (usize)
        {
                tmp = malloc(usize);
-               xc_dom_do_gunzip(image, st.st_size, tmp, usize);
+               xc_dom_do_gunzip(xch, image, st.st_size, tmp, usize);
                image = tmp;
                size = usize;
        }
@@ -170,7 +175,7 @@ int main(int argc, char **argv)
                fprintf(stderr, "File %s is not an ELF image\n", f);
                return 1;
        }
-       xc_elf_set_logfile(&elf, stderr, 0);
+       xc_elf_set_logfile(xch, &elf, 0);
 
        count = elf_phdr_count(&elf);
        for ( h=0; h < count; h++)
diff --git a/tools/xcutils/xc_restore.c b/tools/xcutils/xc_restore.c
index da4aa98..ea069ac 100644
--- a/tools/xcutils/xc_restore.c
+++ b/tools/xcutils/xc_restore.c
@@ -20,7 +20,8 @@ main(int argc, char **argv)
 {
     unsigned int domid, store_evtchn, console_evtchn;
     unsigned int hvm, pae, apic;
-    int xc_fd, io_fd, ret;
+    xc_interface *xch;
+    int io_fd, ret;
     int superpages;
     unsigned long store_mfn, console_mfn;
 
@@ -28,8 +29,8 @@ main(int argc, char **argv)
         errx(1, "usage: %s iofd domid store_evtchn "
              "console_evtchn hvm pae apic [superpages]", argv[0]);
 
-    xc_fd = xc_interface_open();
-    if ( xc_fd < 0 )
+    xch = xc_interface_open(0,0,0);
+    if ( !xch )
         errx(1, "failed to open control interface");
 
     io_fd = atoi(argv[1]);
@@ -44,7 +45,7 @@ main(int argc, char **argv)
     else
            superpages = 0;
 
-    ret = xc_domain_restore(xc_fd, io_fd, domid, store_evtchn, &store_mfn,
+    ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
                             console_evtchn, &console_mfn, hvm, pae, 
superpages);
 
     if ( ret == 0 )
@@ -55,7 +56,7 @@ main(int argc, char **argv)
        fflush(stdout);
     }
 
-    xc_interface_close(xc_fd);
+    xc_interface_close(xch);
 
     return ret;
 }
diff --git a/tools/xcutils/xc_save.c b/tools/xcutils/xc_save.c
index 02570bd..cdf62af 100644
--- a/tools/xcutils/xc_save.c
+++ b/tools/xcutils/xc_save.c
@@ -24,7 +24,7 @@
 #include <xenguest.h>
 
 static struct suspendinfo {
-    int xc_fd; /* libxc handle */
+    xc_interface *xch;
     int xce; /* event channel handle */
     int suspend_evtchn;
     int domid;
@@ -59,7 +59,7 @@ static int evtchn_suspend(void)
         return 0;
     }
 
-    if (xc_await_suspend(si.xce, si.suspend_evtchn) < 0) {
+    if (xc_await_suspend(si.xch, si.xce, si.suspend_evtchn) < 0) {
         warnx("suspend failed");
         return 0;
     }
@@ -77,7 +77,7 @@ static int suspend(void* data)
 
     /* Cannot notify guest to shut itself down if it's in ACPI sleep state. */
     if (si.flags & XCFLAGS_HVM)
-        xc_get_hvm_param(si.xc_fd, si.domid,
+        xc_get_hvm_param(si.xch, si.domid,
                          HVM_PARAM_ACPI_S_STATE, &sx_state);
 
     if ((sx_state == 0) && (si.suspend_evtchn >= 0))
@@ -171,8 +171,8 @@ main(int argc, char **argv)
     if (argc != 6)
         errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
 
-    si.xc_fd = xc_interface_open();
-    if (si.xc_fd < 0)
+    si.xch = xc_interface_open(0,0,0);
+    if (!si.xch)
         errx(1, "failed to open control interface");
 
     io_fd = atoi(argv[1]);
@@ -196,7 +196,7 @@ main(int argc, char **argv)
         else
         {
             si.suspend_evtchn =
-              xc_suspend_evtchn_init(si.xc_fd, si.xce, si.domid, port);
+              xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port);
 
             if (si.suspend_evtchn < 0)
                 warnx("suspend event channel initialization failed"
@@ -205,17 +205,17 @@ main(int argc, char **argv)
     }
     memset(&callbacks, 0, sizeof(callbacks));
     callbacks.suspend = suspend;
-    ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, 
+    ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, 
                          &callbacks, !!(si.flags & XCFLAGS_HVM),
                          &switch_qemu_logdirty);
 
     if (si.suspend_evtchn > 0)
-        xc_suspend_evtchn_release(si.xce, si.domid, si.suspend_evtchn);
+        xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn);
 
     if (si.xce > 0)
         xc_evtchn_close(si.xce);
 
-    xc_interface_close(si.xc_fd);
+    xc_interface_close(si.xch);
 
     return ret;
 }
diff --git a/tools/xenmon/setmask.c b/tools/xenmon/setmask.c
index 676dd6d..2cc20d5 100644
--- a/tools/xenmon/setmask.c
+++ b/tools/xenmon/setmask.c
@@ -43,7 +43,7 @@ int main(int argc, char * argv[])
     struct xen_sysctl sysctl;
     int ret;
 
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
     sysctl.cmd = XEN_SYSCTL_tbuf_op;
     sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION;
     sysctl.u.tbuf_op.cmd  = XEN_SYSCTL_TBUFOP_get_info;
diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c
index 33860f8..f44a3e8 100644
--- a/tools/xenmon/xenbaked.c
+++ b/tools/xenmon/xenbaked.c
@@ -328,10 +328,10 @@ static void wait_for_event(void)
 
 static void get_tbufs(unsigned long *mfn, unsigned long *size)
 {
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
     int ret;
 
-    if ( xc_handle < 0 ) 
+    if ( !xc_handle ) 
     {
         exit(EXIT_FAILURE);
     }
@@ -349,7 +349,7 @@ static void get_tbufs(unsigned long *mfn, unsigned long 
*size)
 
 static void disable_tracing(void)
 {
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
     xc_tbuf_disable(xc_handle);  
     xc_interface_close(xc_handle);
 }
@@ -365,12 +365,12 @@ static void disable_tracing(void)
 static struct t_struct *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
                                   unsigned long tinfo_size)
 {
-    int xc_handle;
+    xc_interface *xc_handle;
     static struct t_struct tbufs = { 0 };
     int i;
 
-    xc_handle = xc_interface_open();
-    if ( xc_handle < 0 ) 
+    xc_handle = xc_interface_open(0,0,0);
+    if ( !xc_handle ) 
     {
         exit(EXIT_FAILURE);
     }
@@ -434,7 +434,7 @@ static struct t_struct *map_tbufs(unsigned long tbufs_mfn, 
unsigned int num,
 static unsigned int get_num_cpus(void)
 {
     xc_physinfo_t physinfo = { 0 };
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
     int ret;
 
     ret = xc_physinfo(xc_handle, &physinfo);
@@ -773,7 +773,8 @@ static int indexof(int domid)
 {
     int idx;
     xc_dominfo_t dominfo[NDOMAINS];
-    int xc_handle, ndomains;
+    xc_interface *xc_handle;
+    int ndomains;
   
     if (domid < 0) {   // shouldn't happen
         printf("bad domain id: %d\r\n", domid);
@@ -792,7 +793,7 @@ static int indexof(int domid)
         }
 
     // call domaininfo hypercall to try and garbage collect unused entries
-    xc_handle = xc_interface_open();
+    xc_handle = xc_interface_open(0,0,0);
     ndomains = xc_domain_getinfo(xc_handle, 0, NDOMAINS, dominfo);
     xc_interface_close(xc_handle);
 
diff --git a/tools/xenpaging/file_ops.c b/tools/xenpaging/file_ops.c
index 2d52827..772d222 100644
--- a/tools/xenpaging/file_ops.c
+++ b/tools/xenpaging/file_ops.c
@@ -22,6 +22,7 @@
 
 
 #include <unistd.h>
+#include <stdarg.h>
 #include <xc_private.h>
 
 
diff --git a/tools/xenpaging/policy.h b/tools/xenpaging/policy.h
index 5d7ed6c..0b8fa6c 100644
--- a/tools/xenpaging/policy.h
+++ b/tools/xenpaging/policy.h
@@ -29,7 +29,8 @@
 
 
 int policy_init(xenpaging_t *paging);
-int policy_choose_victim(xenpaging_t *paging, domid_t domain_id,
+int policy_choose_victim(xc_interface *xch,
+                         xenpaging_t *paging, domid_t domain_id,
                          xenpaging_victim_t *victim);
 void policy_notify_paged_out(domid_t domain_id, unsigned long gfn);
 void policy_notify_paged_in(domid_t domain_id, unsigned long gfn);
diff --git a/tools/xenpaging/policy_default.c b/tools/xenpaging/policy_default.c
index 599472e..1bb89e0 100644
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -57,7 +57,8 @@ int policy_init(xenpaging_t *paging)
     return rc;
 }
 
-int policy_choose_victim(xenpaging_t *paging, domid_t domain_id,
+int policy_choose_victim(xc_interface *xch,
+                         xenpaging_t *paging, domid_t domain_id,
                          xenpaging_victim_t *victim)
 {
     ASSERT(victim != NULL);
diff --git a/tools/xenpaging/xc.c b/tools/xenpaging/xc.c
index a5a396b..3b9c836 100644
--- a/tools/xenpaging/xc.c
+++ b/tools/xenpaging/xc.c
@@ -23,6 +23,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <stdarg.h>
 #include <sys/poll.h>
 #include <xc_private.h>
 #include <xg_save_restore.h>
@@ -64,7 +65,7 @@ int xc_mem_paging_flush_ioemu_cache(domid_t domain_id)
     return rc;
 }
 
-int xc_wait_for_event_or_timeout(int xce_handle, unsigned long ms)
+int xc_wait_for_event_or_timeout(xc_interface *xch, int xce_handle, unsigned 
long ms)
 {
     struct pollfd fd = { .fd = xce_handle, .events = POLLIN | POLLERR };
     int port;
@@ -105,12 +106,12 @@ int xc_wait_for_event_or_timeout(int xce_handle, unsigned 
long ms)
     return -errno;
 }
 
-int xc_wait_for_event(int xce_handle)
+int xc_wait_for_event(xc_interface *xch, int xce_handle)
 {
-    return xc_wait_for_event_or_timeout(xce_handle, -1);
+    return xc_wait_for_event_or_timeout(xch, xce_handle, -1);
 }
 
-int xc_get_platform_info(int xc_handle, domid_t domain_id,
+int xc_get_platform_info(xc_interface *xc_handle, domid_t domain_id,
                          xc_platform_info_t *platform_info)
 {
     return get_platform_info(xc_handle, domain_id,
diff --git a/tools/xenpaging/xc.h b/tools/xenpaging/xc.h
index 19da107..5febb89 100644
--- a/tools/xenpaging/xc.h
+++ b/tools/xenpaging/xc.h
@@ -25,6 +25,7 @@
 #define __XC_H__
 
 
+#include <stdarg.h>
 #include <xc_private.h>
 #include <xen/mem_event.h>
 
@@ -52,10 +53,10 @@ typedef struct xc_platform_info {
 int alloc_bitmap(unsigned long **bitmap, unsigned long bitmap_size);
 
 int xc_mem_paging_flush_ioemu_cache(domid_t domain_id);
-int xc_wait_for_event(int xce_handle);
-int xc_wait_for_event_or_timeout(int xce_handle, unsigned long ms);
+int xc_wait_for_event(xc_interface *xch, int xce_handle);
+int xc_wait_for_event_or_timeout(xc_interface *xch, int xce_handle, unsigned 
long ms);
 
-int xc_get_platform_info(int xc_handle, domid_t domain_id,
+int xc_get_platform_info(xc_interface *xc_handle, domid_t domain_id,
                          xc_platform_info_t *platform_info);
 
 
diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c
index 1c91ba8..25ad5c4 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -22,6 +22,7 @@
 
 #include <inttypes.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <xc_private.h>
 
 #include <xen/mem_event.h>
@@ -66,24 +67,24 @@ static void *init_page(void)
     return NULL;
 }
 
-xenpaging_t *xenpaging_init(domid_t domain_id)
+xenpaging_t *xenpaging_init(xc_interface **xch_r, domid_t domain_id)
 {
     xenpaging_t *paging;
+    xc_interface *xch;
     int rc;
 
+    xch = xc_interface_open(0,0,0);
+    if ( !xch ) return NULL;
+
     DPRINTF("xenpaging init\n");
+    *xch_r = xch;
 
     /* Allocate memory */
     paging = malloc(sizeof(xenpaging_t));
     memset(paging, 0, sizeof(xenpaging_t));
 
     /* Open connection to xen */
-    paging->xc_handle = xc_interface_open();
-    if ( paging->xc_handle < 0 )
-    {
-        ERROR("Failed to open connection to Xen");
-        goto err;
-    }
+    paging->xc_handle = xch;
 
     /* Set domain id */
     paging->mem_event.domain_id = domain_id;
@@ -208,7 +209,7 @@ xenpaging_t *xenpaging_init(domid_t domain_id)
     return NULL;
 }
 
-int xenpaging_teardown(xenpaging_t *paging)
+int xenpaging_teardown(xc_interface *xch, xenpaging_t *paging)
 {
     int rc;
 
@@ -248,7 +249,7 @@ int xenpaging_teardown(xenpaging_t *paging)
         ERROR("Error closing connection to xen");
         goto err;
     }
-    paging->xc_handle = -1;
+    paging->xc_handle = NULL;
 
     return 0;
 
@@ -302,7 +303,8 @@ static int put_response(mem_event_t *mem_event, 
mem_event_response_t *rsp)
     return 0;
 }
 
-int xenpaging_evict_page(xenpaging_t *paging, xenpaging_victim_t *victim, int 
fd, int i)
+int xenpaging_evict_page(xc_interface *xch, xenpaging_t *paging,
+                         xenpaging_victim_t *victim, int fd, int i)
 {
     void *page;
     unsigned long gfn;
@@ -373,7 +375,8 @@ int xenpaging_resume_page(xenpaging_t *paging, 
mem_event_response_t *rsp)
     return ret;
 }
 
-int xenpaging_populate_page(xenpaging_t *paging, unsigned long *gfn, int fd, 
int i)
+int xenpaging_populate_page(xc_interface *xch, xenpaging_t *paging,
+                            unsigned long *gfn, int fd, int i)
 {
     void *page;
     int ret;
@@ -411,7 +414,7 @@ int xenpaging_populate_page(xenpaging_t *paging, unsigned 
long *gfn, int fd, int
     return ret;
 }
 
-static int evict_victim(xenpaging_t *paging, domid_t domain_id,
+static int evict_victim(xc_interface *xch, xenpaging_t *paging, domid_t 
domain_id,
                         xenpaging_victim_t *victim, int fd, int i)
 {
     int j = 0;
@@ -419,7 +422,7 @@ static int evict_victim(xenpaging_t *paging, domid_t 
domain_id,
 
     do
     {
-        ret = policy_choose_victim(paging, domain_id, victim);
+        ret = policy_choose_victim(xch, paging, domain_id, victim);
         if ( ret != 0 )
         {
             ERROR("Error choosing victim");
@@ -429,7 +432,7 @@ static int evict_victim(xenpaging_t *paging, domid_t 
domain_id,
         ret = xc_mem_paging_nominate(paging->xc_handle,
                                      paging->mem_event.domain_id, victim->gfn);
         if ( ret == 0 )
-            ret = xenpaging_evict_page(paging, victim, fd, i);
+            ret = xenpaging_evict_page(xch, paging, victim, fd, i);
         else
         {
             if ( j++ % 1000 == 0 )
@@ -459,6 +462,7 @@ int main(int argc, char *argv[])
     int i;
     int rc = -1;
     int rc1;
+    xc_interface *xch;
 
     int open_flags = O_CREAT | O_TRUNC | O_RDWR;
     mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | 
S_IWOTH;
@@ -489,7 +493,7 @@ int main(int argc, char *argv[])
     srand(time(NULL));
 
     /* Initialise domain paging */
-    paging = xenpaging_init(domain_id);
+    paging = xenpaging_init(&xch, domain_id);
     if ( paging == NULL )
     {
         ERROR("Error initialising paging");
@@ -500,7 +504,7 @@ int main(int argc, char *argv[])
     memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
     for ( i = 0; i < num_pages; i++ )
     {
-        evict_victim(paging, domain_id, &victims[i], fd, i);
+        evict_victim(xch, paging, domain_id, &victims[i], fd, i);
         if ( i % 100 == 0 )
             DPRINTF("%d pages evicted\n", i);
     }
@@ -511,7 +515,7 @@ int main(int argc, char *argv[])
     while ( 1 )
     {
         /* Wait for Xen to signal that a page needs paged in */
-        rc = xc_wait_for_event_or_timeout(paging->mem_event.xce_handle, 100);
+        rc = xc_wait_for_event_or_timeout(xch, paging->mem_event.xce_handle, 
100);
         if ( rc < -1 )
         {
             ERROR("Error getting event");
@@ -549,7 +553,7 @@ int main(int argc, char *argv[])
                 }
                 
                 /* Populate the page */
-                rc = xenpaging_populate_page(paging, &req.gfn, fd, i);
+                rc = xenpaging_populate_page(xch, paging, &req.gfn, fd, i);
                 if ( rc != 0 )
                 {
                     ERROR("Error populating page");
@@ -570,7 +574,7 @@ int main(int argc, char *argv[])
                 }
 
                 /* Evict a new page to replace the one we just paged in */
-                evict_victim(paging, domain_id, &victims[i], fd, i);
+                evict_victim(xch, paging, domain_id, &victims[i], fd, i);
             }
             else
             {
@@ -604,7 +608,7 @@ int main(int argc, char *argv[])
     free(victims);
 
     /* Tear down domain paging */
-    rc1 = xenpaging_teardown(paging);
+    rc1 = xenpaging_teardown(xch, paging);
     if ( rc1 != 0 )
         ERROR("Error tearing down paging");
 
diff --git a/tools/xenpaging/xenpaging.h b/tools/xenpaging/xenpaging.h
index 3c897ca..d845193 100644
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -36,7 +36,7 @@
 
 
 typedef struct xenpaging {
-    int xc_handle;
+    xc_interface *xc_handle;
 
     xc_platform_info_t *platform_info;
     xc_domaininfo_t    *domain_info;
diff --git a/tools/xenstat/libxenstat/src/xenstat.c 
b/tools/xenstat/libxenstat/src/xenstat.c
index 60b1a50..2791cc1 100644
--- a/tools/xenstat/libxenstat/src/xenstat.c
+++ b/tools/xenstat/libxenstat/src/xenstat.c
@@ -100,8 +100,8 @@ xenstat_handle *xenstat_init(void)
        }
 #endif
 
-       handle->xc_handle = xc_interface_open();
-       if (handle->xc_handle == -1) {
+       handle->xc_handle = xc_interface_open(0,0,0);
+       if (!handle->xc_handle) {
                perror("xc_interface_open");
                free(handle);
                return NULL;
diff --git a/tools/xenstat/libxenstat/src/xenstat_priv.h 
b/tools/xenstat/libxenstat/src/xenstat_priv.h
index 81beec1..fdd70ed 100644
--- a/tools/xenstat/libxenstat/src/xenstat_priv.h
+++ b/tools/xenstat/libxenstat/src/xenstat_priv.h
@@ -33,7 +33,7 @@
 #define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
 
 struct xenstat_handle {
-       int xc_handle;
+       xc_interface *xc_handle;
        struct xs_handle *xshandle; /* xenstore handle */
        int page_size;
        void *priv;
diff --git a/tools/xenstore/xenstored_domain.c 
b/tools/xenstore/xenstored_domain.c
index d1d59f9..53fb68f 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -22,6 +22,7 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <xenctrl.h>
 
 #include "utils.h"
 #include "talloc.h"
@@ -32,7 +33,7 @@
 
 #include <xenctrl.h>
 
-static int *xc_handle;
+static xc_interface **xc_handle;
 static evtchn_port_t virq_port;
 
 int xce_handle = -1; 
@@ -538,7 +539,7 @@ void do_is_domain_introduced(struct connection *conn, const 
char *domid_str)
 
 static int close_xc_handle(void *_handle)
 {
-       xc_interface_close(*(int *)_handle);
+       xc_interface_close(*(xc_interface**)_handle);
        return 0;
 }
 
@@ -584,12 +585,12 @@ int domain_init(void)
 {
        int rc;
 
-       xc_handle = talloc(talloc_autofree_context(), int);
+       xc_handle = talloc(talloc_autofree_context(), xc_interface*);
        if (!xc_handle)
                barf_perror("Failed to allocate domain handle");
 
-       *xc_handle = xc_interface_open();
-       if (*xc_handle < 0)
+       *xc_handle = xc_interface_open(0,0,0);
+       if (!*xc_handle)
                barf_perror("Failed to open connection to hypervisor");
 
        talloc_set_destructor(xc_handle, close_xc_handle);
diff --git a/tools/xentrace/setsize.c b/tools/xentrace/setsize.c
index fcb1fcb..ad87915 100644
--- a/tools/xentrace/setsize.c
+++ b/tools/xentrace/setsize.c
@@ -6,7 +6,7 @@
 int main(int argc, char * argv[])
 {
     unsigned long size;
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
   
     if ( xc_tbuf_get_size(xc_handle, &size) != 0 )
     {
diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c
index 0797c52..b16b5c4 100644
--- a/tools/xentrace/xenctx.c
+++ b/tools/xentrace/xenctx.c
@@ -28,7 +28,7 @@
 #include <xen/foreign/x86_64.h>
 #include <xen/hvm/save.h>
 
-int xc_handle = 0;
+xc_interface *xc_handle = 0;
 int domid = 0;
 int frame_ptrs = 0;
 int stack_trace = 0;
@@ -823,7 +823,7 @@ static void dump_ctx(int vcpu)
     vcpu_guest_context_any_t ctx;
     xc_dominfo_t dominfo;
 
-    xc_handle = xc_interface_open(); /* for accessing control interface */
+    xc_handle = xc_interface_open(0,0,0); /* for accessing control interface */
 
     ret = xc_domain_getinfo(xc_handle, domid, 1, &dominfo);
     if (ret < 0) {
@@ -890,7 +890,7 @@ static void dump_ctx(int vcpu)
         }
     }
 
-    xc_interface_close(xc_handle);
+    ret = xc_interface_close(xc_handle);
     if (ret < 0) {
         perror("xc_interface_close");
         exit(-1);
diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c
index dd5471a..6291cde 100644
--- a/tools/xentrace/xentrace.c
+++ b/tools/xentrace/xentrace.c
@@ -72,7 +72,7 @@ settings_t opts;
 
 int interrupted = 0; /* gets set if we get a SIGHUP */
 
-static int xc_handle = -1;
+static xc_interface *xc_handle;
 static int event_fd = -1;
 static int virq_port = -1;
 static int outfd = 1;
@@ -424,10 +424,10 @@ fail:
 
 static void disable_tbufs(void)
 {
-    int xc_handle = xc_interface_open();
+    xc_interface *xc_handle = xc_interface_open(0,0,0);
     int ret;
 
-    if ( xc_handle < 0 ) 
+    if ( !xc_handle ) 
     {
         perror("Couldn't open xc handle to disable tbufs.");
         goto out;
@@ -578,7 +578,7 @@ static void event_init(void)
 
     rc = xc_evtchn_open();
     if (rc < 0) {
-        perror(xc_get_last_error()->message);
+        perror("event channel open");
         exit(EXIT_FAILURE);
     }
     event_fd = rc;
@@ -1014,10 +1014,10 @@ int main(int argc, char **argv)
 
     parse_args(argc, argv);
 
-    xc_handle = xc_interface_open();
-    if ( xc_handle < 0 ) 
+    xc_handle = xc_interface_open(0,0,0);
+    if ( !xc_handle ) 
     {
-        perror(xc_get_last_error()->message);
+        perror("xenctrl interface open");
         exit(EXIT_FAILURE);
     }
 
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.