WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] libxc: eliminate static variables, use xentoollog; API change, Ian Jackson <=