xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
Subject: [PATCH 02/10] add ocaml XC bindings.
Date: Tue, 9 Mar 2010 14:41:07 +0000	[thread overview]
Message-ID: <1268145675-10375-3-git-send-email-vincent.hanquez@eu.citrix.com> (raw)
In-Reply-To: <1268145675-10375-1-git-send-email-vincent.hanquez@eu.citrix.com>

[-- Attachment #1: Type: text/plain, Size: 1246 bytes --]


this include a small and simpler reimplementation of libxc.

Signed-off-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
---
 tools/ocaml/libs/xc/META.in         |    4 +
 tools/ocaml/libs/xc/Makefile        |   28 +
 tools/ocaml/libs/xc/xc.h            |  191 +++++
 tools/ocaml/libs/xc/xc.ml           |  340 ++++++++
 tools/ocaml/libs/xc/xc.mli          |  196 +++++
 tools/ocaml/libs/xc/xc_cpufeature.h |  116 +++
 tools/ocaml/libs/xc/xc_cpuid.h      |  285 +++++++
 tools/ocaml/libs/xc/xc_e820.h       |   20 +
 tools/ocaml/libs/xc/xc_lib.c        | 1502 +++++++++++++++++++++++++++++++++++
 tools/ocaml/libs/xc/xc_stubs.c      | 1170 +++++++++++++++++++++++++++
 10 files changed, 3852 insertions(+), 0 deletions(-)
 create mode 100644 tools/ocaml/libs/xc/META.in
 create mode 100644 tools/ocaml/libs/xc/Makefile
 create mode 100644 tools/ocaml/libs/xc/xc.h
 create mode 100644 tools/ocaml/libs/xc/xc.ml
 create mode 100644 tools/ocaml/libs/xc/xc.mli
 create mode 100644 tools/ocaml/libs/xc/xc_cpufeature.h
 create mode 100644 tools/ocaml/libs/xc/xc_cpuid.h
 create mode 100644 tools/ocaml/libs/xc/xc_e820.h
 create mode 100644 tools/ocaml/libs/xc/xc_lib.c
 create mode 100644 tools/ocaml/libs/xc/xc_stubs.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-add-ocaml-XC-bindings.patch --]
[-- Type: text/x-patch; name="0002-add-ocaml-XC-bindings.patch", Size: 121587 bytes --]

diff --git a/tools/ocaml/libs/xc/META.in b/tools/ocaml/libs/xc/META.in
new file mode 100644
index 0000000..e46d7dd
--- /dev/null
+++ b/tools/ocaml/libs/xc/META.in
@@ -0,0 +1,4 @@
+version = "@VERSION@"
+description = "Xen Control Interface"
+archive(byte) = "xc.cma"
+archive(native) = "xc.cmxa"
diff --git a/tools/ocaml/libs/xc/Makefile b/tools/ocaml/libs/xc/Makefile
new file mode 100644
index 0000000..9e361b5
--- /dev/null
+++ b/tools/ocaml/libs/xc/Makefile
@@ -0,0 +1,28 @@
+TOPLEVEL=../..
+include $(TOPLEVEL)/common.make
+
+CFLAGS += -I../mmap -I./
+OCAMLINCLUDE += -I ../mmap -I ../uuid
+
+OBJS = xc
+INTF = xc.cmi
+LIBS = xc.cma xc.cmxa
+
+xc_OBJS = $(OBJS)
+xc_C_OBJS = xc_lib xc_stubs
+
+OCAML_LIBRARY = xc
+
+all: $(INTF) $(LIBS)
+
+libs: $(LIBS)
+
+.PHONY: install
+install: $(LIBS) META
+	ocamlfind install -destdir $(DESTDIR)$(shell ocamlfind printconf destdir) -ldconf ignore xc META $(INTF) $(LIBS) *.a *.so *.cmx
+
+.PHONY: uninstall
+uninstall:
+	ocamlfind remove xc
+
+include $(TOPLEVEL)/Makefile.rules
diff --git a/tools/ocaml/libs/xc/xc.h b/tools/ocaml/libs/xc/xc.h
new file mode 100644
index 0000000..8ef7009
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#define __XEN_TOOLS__
+
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xen/sysctl.h>
+#include <xen/domctl.h>
+#include <xen/sched.h>
+#include <xen/sysctl.h>
+#if XEN_SYSCTL_INTERFACE_VERSION < 4
+#include <xen/linux/privcmd.h>
+#else
+#include <xen/sys/privcmd.h>
+#endif
+#include <xen/version.h>
+#include <xen/foreign/x86_32.h>
+#include <xen/foreign/x86_64.h>
+#include <xen/hvm/params.h>
+#include "xc_e820.h"
+
+typedef xen_domctl_getdomaininfo_t xc_domaininfo_t;
+typedef xen_domctl_getvcpuinfo_t xc_vcpuinfo_t;
+typedef xen_sysctl_physinfo_t xc_physinfo_t;
+
+struct xc_core_header {
+	unsigned int xch_magic;
+	unsigned int xch_nr_vcpus;
+	unsigned int xch_nr_pages;
+	unsigned int xch_ctxt_offset;
+	unsigned int xch_index_offset;
+	unsigned int xch_pages_offset;
+};
+
+typedef union {
+#if defined(__i386__) || defined(__x86_64__)
+	vcpu_guest_context_x86_64_t x64;
+	vcpu_guest_context_x86_32_t x32;
+#endif
+	vcpu_guest_context_t c;
+} vcpu_guest_context_any_t;
+
+char * xc_error_get(void);
+void xc_error_clear(void);
+
+int xc_using_injection(void);
+
+int xc_interface_open(void);
+int xc_interface_close(int handle);
+
+int xc_domain_create(int handle, unsigned int ssidref,
+                     xen_domain_handle_t dhandle,
+                     unsigned int flags, unsigned int *pdomid);
+int xc_domain_pause(int handle, unsigned int domid);
+int xc_domain_unpause(int handle, unsigned int domid);
+int xc_domain_resume_fast(int handle, unsigned int domid);
+int xc_domain_destroy(int handle, unsigned int domid);
+int xc_domain_shutdown(int handle, int domid, int reason);
+
+int xc_vcpu_setaffinity(int handle, unsigned int domid, int vcpu,
+                        uint64_t cpumap);
+int xc_vcpu_getaffinity(int handle, unsigned int domid, int vcpu,
+                        uint64_t *cpumap);
+
+int xc_domain_getinfolist(int handle, unsigned int first_domain,
+                          unsigned int max_domains, xc_domaininfo_t *info);
+int xc_domain_getinfo(int handle, unsigned int first_domain,
+                      xc_domaininfo_t *info);
+
+int xc_domain_setmaxmem(int handle, unsigned int domid, unsigned int max_memkb);
+int xc_domain_set_memmap_limit(int handle, unsigned int domid,
+                               unsigned long map_limitkb);
+
+int xc_domain_set_time_offset(int handle, unsigned int domid, int time_offset);
+
+int xc_domain_memory_increase_reservation(int handle, unsigned int domid,
+                                          unsigned long nr_extents,
+                                          unsigned int extent_order,
+                                          unsigned int address_bits,
+                                          xen_pfn_t *extent_start);
+int xc_domain_memory_decrease_reservation(int handle, unsigned int domid,
+                                          unsigned long nr_extents,
+                                          unsigned int extent_order,
+                                          unsigned int address_bits,
+                                          xen_pfn_t *extent_start);
+int xc_domain_memory_populate_physmap(int handle, unsigned int domid,
+                                      unsigned long nr_extents,
+                                      unsigned int extent_order,
+                                      unsigned int address_bits,
+                                      xen_pfn_t *extent_start);
+int xc_domain_setvmxassist(int handle, unsigned int domid, int use_vmxassist);
+int xc_domain_max_vcpus(int handle, unsigned int domid, unsigned int max);
+int xc_domain_sethandle(int handle, unsigned int domid,
+                        xen_domain_handle_t dhandle);
+int xc_vcpu_getinfo(int handle, unsigned int domid, unsigned int vcpu,
+                    xc_vcpuinfo_t *info);
+int xc_domain_ioport_permission(int handle, unsigned int domid,
+                                unsigned int first_port, unsigned int nr_ports,
+                                unsigned int allow_access);
+int xc_vcpu_setcontext(int handle, unsigned int domid,
+                       unsigned int vcpu, vcpu_guest_context_any_t *ctxt);
+int xc_vcpu_getcontext(int handle, unsigned int domid,
+                       unsigned int vcpu, vcpu_guest_context_any_t *ctxt);
+int xc_domain_irq_permission(int handle, unsigned int domid,
+                             unsigned char pirq, unsigned char allow_access);
+int xc_domain_iomem_permission(int handle, unsigned int domid,
+                               unsigned long first_mfn, unsigned long nr_mfns,
+                               unsigned char allow_access);
+long long xc_domain_get_cpu_usage(int handle, unsigned int domid,
+                                  unsigned int vcpu);
+void *xc_map_foreign_range(int handle, unsigned int domid,
+                           int size, int prot, unsigned long mfn);
+int xc_map_foreign_ranges(int handle, unsigned int domid,
+                          privcmd_mmap_entry_t *entries, int nr);
+int xc_readconsolering(int handle, char **pbuffer,
+                       unsigned int *pnr_chars, int clear);
+int xc_send_debug_keys(int handle, char *keys);
+int xc_physinfo(int handle, xc_physinfo_t *put_info);
+int xc_pcpu_info(int handle, int max_cpus, uint64_t *info, int *nr_cpus);
+int xc_sched_id(int handle, int *sched_id);
+int xc_version(int handle, int cmd, void *arg);
+int xc_evtchn_alloc_unbound(int handle, unsigned int domid,
+                            unsigned int remote_domid);
+int xc_evtchn_reset(int handle, unsigned int domid);
+
+int xc_sched_credit_domain_set(int handle, unsigned int domid,
+                               struct xen_domctl_sched_credit *sdom);
+int xc_sched_credit_domain_get(int handle, unsigned int domid,
+                               struct xen_domctl_sched_credit *sdom);
+int xc_shadow_allocation_get(int handle, unsigned int domid,
+			     uint32_t *mb);
+int xc_shadow_allocation_set(int handle, unsigned int domid,
+			     uint32_t mb);
+int xc_domain_get_pfn_list(int handle, unsigned int domid,
+                           xen_pfn_t *pfn_array, unsigned long max_pfns);
+int xc_hvm_check_pvdriver(int handle, unsigned int domid);
+
+int xc_domain_assign_device(int handle, unsigned int domid,
+                            int domain, int bus, int slot, int func);
+int xc_domain_deassign_device(int handle, unsigned int domid,
+                              int domain, int bus, int slot, int func);
+int xc_domain_test_assign_device(int handle, unsigned int domid,
+                                 int domain, int bus, int slot, int func);
+int xc_domain_watchdog(int handle, int id, uint32_t timeout);
+int xc_domain_set_machine_address_size(int xc, uint32_t domid, unsigned int width);
+int xc_domain_get_machine_address_size(int xc, uint32_t domid);
+
+int xc_domain_cpuid_set(int xc, unsigned int domid, int hvm,
+                        uint32_t input, uint32_t oinput,
+                        char *config[4], char *config_out[4]);
+int xc_domain_cpuid_apply(int xc, unsigned int domid, int hvm);
+int xc_cpuid_check(uint32_t input, uint32_t optsubinput,
+                   char *config[4], char *config_out[4]);
+
+int xc_domain_send_s3resume(int handle, unsigned int domid);
+int xc_domain_set_vpt_align(int handle, unsigned int domid, int vpt_align);
+int xc_domain_set_hpet(int handle, unsigned int domid, int hpet);
+int xc_domain_set_timer_mode(int handle, unsigned int domid, int mode);
+int xc_domain_get_acpi_s_state(int handle, unsigned int domid);
+
+#if XEN_SYSCTL_INTERFACE_VERSION >= 6
+#define SAFEDIV(a, b)					(((b) > 0) ? (a) / (b) : (a))
+#define COMPAT_FIELD_physinfo_get_nr_cpus(p)		(p).nr_cpus
+#define COMPAT_FIELD_physinfo_get_sockets_per_node(p)	\
+	SAFEDIV((p).nr_cpus, ((p).threads_per_core * (p).cores_per_socket * (p).nr_nodes))
+#else
+#define COMPAT_FIELD_physinfo_get_nr_cpus(p)		\
+	((p).threads_per_core * (p).sockets_per_node *	\
+	 (p).cores_per_socket * (p).threads_per_core)
+#define COMPAT_FIELD_physinfo_get_sockets_per_node(p)	(p).sockets_per_node
+#endif
+
+#if __XEN_LATEST_INTERFACE_VERSION__ >= 0x00030209
+#define COMPAT_FIELD_ADDRESS_BITS		mem_flags
+#else
+#define COMPAT_FIELD_ADDRESS_BITS		address_bits
+#endif
diff --git a/tools/ocaml/libs/xc/xc.ml b/tools/ocaml/libs/xc/xc.ml
new file mode 100644
index 0000000..b9dd284
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc.ml
@@ -0,0 +1,340 @@
+(*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *)
+
+(** *)
+type domid = int
+
+(* ** xenctrl.h ** *)
+
+type vcpuinfo =
+{
+	online: bool;
+	blocked: bool;
+	running: bool;
+	cputime: int64;
+	cpumap: int32;
+}
+
+type domaininfo =
+{
+	domid             : domid;
+	dying             : bool;
+	shutdown          : bool;
+	paused            : bool;
+	blocked           : bool;
+	running           : bool;
+	hvm_guest         : bool;
+	shutdown_code     : int;
+	total_memory_pages: nativeint;
+	max_memory_pages  : nativeint;
+	shared_info_frame : int64;
+	cpu_time          : int64;
+	nr_online_vcpus   : int;
+	max_vcpu_id       : int;
+	ssidref           : int32;
+	handle            : int array;
+}
+
+type sched_control =
+{
+	weight : int;
+	cap    : int;
+}
+
+type physinfo_cap_flag =
+	| CAP_HVM
+	| CAP_DirectIO
+
+type physinfo =
+{
+	threads_per_core : int;
+	cores_per_socket : int;
+	nr_cpus          : int;
+	max_node_id      : int;
+	cpu_khz          : int;
+	total_pages      : nativeint;
+	free_pages       : nativeint;
+	scrub_pages      : nativeint;
+	(* XXX hw_cap *)
+	capabilities     : physinfo_cap_flag list;
+}
+
+type version =
+{
+	major : int;
+	minor : int;
+	extra : string;
+}
+
+
+type compile_info =
+{
+	compiler : string;
+	compile_by : string;
+	compile_domain : string;
+	compile_date : string;
+}
+
+type shutdown_reason = Poweroff | Reboot | Suspend | Crash | Halt
+
+type domain_create_flag = CDF_HVM | CDF_HAP
+
+exception Error of string
+
+type handle
+
+(* this is only use by coredumping *)
+external sizeof_core_header: unit -> int
+       = "stub_sizeof_core_header"
+external sizeof_vcpu_guest_context: unit -> int
+       = "stub_sizeof_vcpu_guest_context"
+external sizeof_xen_pfn: unit -> int = "stub_sizeof_xen_pfn"
+(* end of use *)
+
+external interface_open: unit -> handle = "stub_xc_interface_open"
+external interface_close: handle -> unit = "stub_xc_interface_close"
+
+external using_injection: unit -> bool = "stub_xc_using_injection"
+
+let with_intf f =
+	let xc = interface_open () in
+	let r = try f xc with exn -> interface_close xc; raise exn in
+	interface_close xc;
+	r
+
+external _domain_create: handle -> int32 -> domain_create_flag list -> int array -> domid
+       = "stub_xc_domain_create"
+
+let domain_create handle n flags uuid =
+	_domain_create handle n flags (Uuid.int_array_of_uuid uuid)
+
+external _domain_sethandle: handle -> domid -> int array -> unit
+                          = "stub_xc_domain_sethandle"
+
+let domain_sethandle handle n uuid =
+	_domain_sethandle handle n (Uuid.int_array_of_uuid uuid)
+
+external domain_setvmxassist: handle -> domid -> bool -> unit
+       = "stub_xc_domain_setvmxassist"
+
+external domain_max_vcpus: handle -> domid -> int -> unit
+       = "stub_xc_domain_max_vcpus"
+
+external domain_pause: handle -> domid -> unit = "stub_xc_domain_pause"
+external domain_unpause: handle -> domid -> unit = "stub_xc_domain_unpause"
+external domain_resume_fast: handle -> domid -> unit = "stub_xc_domain_resume_fast"
+external domain_destroy: handle -> domid -> unit = "stub_xc_domain_destroy"
+
+external domain_shutdown: handle -> domid -> shutdown_reason -> unit
+       = "stub_xc_domain_shutdown"
+
+external _domain_getinfolist: handle -> domid -> int -> domaininfo list
+       = "stub_xc_domain_getinfolist"
+
+let domain_getinfolist handle first_domain =
+	let nb = 2 in
+	let last_domid l = (List.hd l).domid + 1 in
+	let rec __getlist from =
+		let l = _domain_getinfolist handle from nb in
+		(if List.length l = nb then __getlist (last_domid l) else []) @ l
+		in
+	List.rev (__getlist first_domain)
+
+external domain_getinfo: handle -> domid -> domaininfo= "stub_xc_domain_getinfo"
+
+external domain_get_vcpuinfo: handle -> int -> int -> vcpuinfo
+       = "stub_xc_vcpu_getinfo"
+
+external domain_ioport_permission: handle -> domid -> int -> int -> bool -> unit
+       = "stub_xc_domain_ioport_permission"
+external domain_iomem_permission: handle -> domid -> nativeint -> nativeint -> bool -> unit
+       = "stub_xc_domain_iomem_permission"
+external domain_irq_permission: handle -> domid -> int -> bool -> unit
+       = "stub_xc_domain_irq_permission"
+
+external vcpu_affinity_set: handle -> domid -> int -> int64 -> unit
+       = "stub_xc_vcpu_setaffinity"
+external vcpu_affinity_get: handle -> domid -> int -> int64
+       = "stub_xc_vcpu_getaffinity"
+
+external vcpu_context_get: handle -> domid -> int -> string
+       = "stub_xc_vcpu_context_get"
+
+external sched_id: handle -> int = "stub_xc_sched_id"
+
+external sched_credit_domain_set: handle -> domid -> sched_control -> unit
+       = "stub_sched_credit_domain_set"
+external sched_credit_domain_get: handle -> domid -> sched_control
+       = "stub_sched_credit_domain_get"
+
+external shadow_allocation_set: handle -> domid -> int -> unit
+       = "stub_shadow_allocation_set"
+external shadow_allocation_get: handle -> domid -> int
+       = "stub_shadow_allocation_get"
+
+external evtchn_alloc_unbound: handle -> domid -> domid -> int
+       = "stub_xc_evtchn_alloc_unbound"
+external evtchn_reset: handle -> domid -> unit = "stub_xc_evtchn_reset"
+
+external readconsolering: handle -> string = "stub_xc_readconsolering"
+
+external send_debug_keys: handle -> string -> unit = "stub_xc_send_debug_keys"
+external physinfo: handle -> physinfo = "stub_xc_physinfo"
+external pcpu_info: handle -> int -> int64 array = "stub_xc_pcpu_info"
+
+external domain_setmaxmem: handle -> domid -> int64 -> unit
+       = "stub_xc_domain_setmaxmem"
+external domain_set_memmap_limit: handle -> domid -> int64 -> unit
+       = "stub_xc_domain_set_memmap_limit"
+external domain_memory_increase_reservation: handle -> domid -> int64 -> unit
+       = "stub_xc_domain_memory_increase_reservation"
+
+external domain_set_machine_address_size: handle -> domid -> int -> unit
+       = "stub_xc_domain_set_machine_address_size"
+external domain_get_machine_address_size: handle -> domid -> int
+       = "stub_xc_domain_get_machine_address_size"
+
+external domain_cpuid_set: handle -> domid -> bool -> (int64 * (int64 option))
+                        -> string option array
+                        -> string option array
+       = "stub_xc_domain_cpuid_set"
+external domain_cpuid_apply: handle -> domid -> bool -> unit
+       = "stub_xc_domain_cpuid_apply"
+external cpuid_check: (int64 * (int64 option)) -> string option array -> (bool * string option array)
+       = "stub_xc_cpuid_check"
+
+external map_foreign_range: handle -> domid -> int
+                         -> nativeint -> Mmap.mmap_interface
+       = "stub_map_foreign_range"
+
+external domain_get_pfn_list: handle -> domid -> nativeint -> nativeint array
+       = "stub_xc_domain_get_pfn_list"
+
+external domain_assign_device: handle -> domid -> (int * int * int * int) -> unit
+       = "stub_xc_domain_assign_device"
+external domain_deassign_device: handle -> domid -> (int * int * int * int) -> unit
+       = "stub_xc_domain_deassign_device"
+external domain_test_assign_device: handle -> domid -> (int * int * int * int) -> bool
+       = "stub_xc_domain_test_assign_device"
+
+external domain_set_timer_mode: handle -> domid -> int -> unit = "stub_xc_domain_set_timer_mode"
+external domain_set_hpet: handle -> domid -> int -> unit = "stub_xc_domain_set_hpet"
+external domain_set_vpt_align: handle -> domid -> int -> unit = "stub_xc_domain_set_vpt_align"
+
+external domain_send_s3resume: handle -> domid -> unit = "stub_xc_domain_send_s3resume"
+external domain_get_acpi_s_state: handle -> domid -> int = "stub_xc_domain_get_acpi_s_state"
+
+(** check if some hvm domain got pv driver or not *)
+external hvm_check_pvdriver: handle -> domid -> bool
+       = "stub_xc_hvm_check_pvdriver"
+
+external version: handle -> version = "stub_xc_version_version"
+external version_compile_info: handle -> compile_info
+       = "stub_xc_version_compile_info"
+external version_changeset: handle -> string = "stub_xc_version_changeset"
+external version_capabilities: handle -> string =
+  "stub_xc_version_capabilities"
+
+external watchdog : handle -> int -> int32 -> int
+  = "stub_xc_watchdog"
+
+(* core dump structure *)
+type core_magic = Magic_hvm | Magic_pv
+
+type core_header = {
+	xch_magic: core_magic;
+	xch_nr_vcpus: int;
+	xch_nr_pages: nativeint;
+	xch_index_offset: int64;
+	xch_ctxt_offset: int64;
+	xch_pages_offset: int64;
+}
+
+external marshall_core_header: core_header -> string = "stub_marshall_core_header"
+
+(* coredump *)
+let coredump xch domid fd =
+	let dump s =
+		let wd = Unix.write fd s 0 (String.length s) in
+		if wd <> String.length s then
+			failwith "error while writing";
+		in
+
+	let info = domain_getinfo xch domid in
+
+	let nrpages = info.total_memory_pages in
+	let ctxt = Array.make info.max_vcpu_id None in
+	let nr_vcpus = ref 0 in
+	for i = 0 to info.max_vcpu_id - 1
+	do
+		ctxt.(i) <- try
+			let v = vcpu_context_get xch domid i in
+			incr nr_vcpus;
+			Some v
+			with _ -> None
+	done;
+
+	(* FIXME page offset if not rounded to sup *)
+	let page_offset =
+		Int64.add
+			(Int64.of_int (sizeof_core_header () +
+			 (sizeof_vcpu_guest_context () * !nr_vcpus)))
+			(Int64.of_nativeint (
+				Nativeint.mul
+					(Nativeint.of_int (sizeof_xen_pfn ()))
+					nrpages)
+				)
+		in
+
+	let header = {
+		xch_magic = if info.hvm_guest then Magic_hvm else Magic_pv;
+		xch_nr_vcpus = !nr_vcpus;
+		xch_nr_pages = nrpages;
+		xch_ctxt_offset = Int64.of_int (sizeof_core_header ());
+		xch_index_offset = Int64.of_int (sizeof_core_header ()
+					+ sizeof_vcpu_guest_context ());
+		xch_pages_offset = page_offset;
+	} in
+
+	dump (marshall_core_header header);
+	for i = 0 to info.max_vcpu_id - 1
+	do
+		match ctxt.(i) with
+		| None -> ()
+		| Some ctxt_i -> dump ctxt_i
+	done;
+	let pfns = domain_get_pfn_list xch domid nrpages in
+	if Array.length pfns <> Nativeint.to_int nrpages then
+		failwith "could not get the page frame list";
+
+	let page_size = Mmap.getpagesize () in
+	for i = 0 to Nativeint.to_int nrpages - 1
+	do
+		let page = map_foreign_range xch domid page_size pfns.(i) in
+		let data = Mmap.read page 0 page_size in
+		Mmap.unmap page;
+		dump data
+	done
+
+(* ** Misc ** *)
+
+(**
+   Convert the given number of pages to an amount in KiB, rounded up.
+ *)
+external pages_to_kib : int64 -> int64 = "stub_pages_to_kib"
+let pages_to_mib pages = Int64.div (pages_to_kib pages) 1024L
+
+let _ = Callback.register_exception "xc.error" (Error "register_callback")
diff --git a/tools/ocaml/libs/xc/xc.mli b/tools/ocaml/libs/xc/xc.mli
new file mode 100644
index 0000000..dc55b67
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc.mli
@@ -0,0 +1,196 @@
+(*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *)
+
+type domid = int
+type vcpuinfo = {
+  online : bool;
+  blocked : bool;
+  running : bool;
+  cputime : int64;
+  cpumap : int32;
+}
+type domaininfo = {
+  domid : domid;
+  dying : bool;
+  shutdown : bool;
+  paused : bool;
+  blocked : bool;
+  running : bool;
+  hvm_guest : bool;
+  shutdown_code : int;
+  total_memory_pages : nativeint;
+  max_memory_pages : nativeint;
+  shared_info_frame : int64;
+  cpu_time : int64;
+  nr_online_vcpus : int;
+  max_vcpu_id : int;
+  ssidref : int32;
+  handle : int array;
+}
+type sched_control = { weight : int; cap : int; }
+type physinfo_cap_flag = CAP_HVM | CAP_DirectIO
+type physinfo = {
+  threads_per_core : int;
+  cores_per_socket : int;
+  nr_cpus          : int;
+  max_node_id      : int;
+  cpu_khz          : int;
+  total_pages      : nativeint;
+  free_pages       : nativeint;
+  scrub_pages      : nativeint;
+  capabilities     : physinfo_cap_flag list;
+}
+type version = { major : int; minor : int; extra : string; }
+type compile_info = {
+  compiler : string;
+  compile_by : string;
+  compile_domain : string;
+  compile_date : string;
+}
+type shutdown_reason = Poweroff | Reboot | Suspend | Crash | Halt
+
+type domain_create_flag = CDF_HVM | CDF_HAP
+
+exception Error of string
+type handle
+external sizeof_core_header : unit -> int = "stub_sizeof_core_header"
+external sizeof_vcpu_guest_context : unit -> int
+  = "stub_sizeof_vcpu_guest_context"
+external sizeof_xen_pfn : unit -> int = "stub_sizeof_xen_pfn"
+external interface_open : unit -> handle = "stub_xc_interface_open"
+external using_injection : unit -> bool = "stub_xc_using_injection"
+external interface_close : handle -> unit = "stub_xc_interface_close"
+val with_intf : (handle -> 'a) -> 'a
+external _domain_create : handle -> int32 -> domain_create_flag list -> int array -> domid
+  = "stub_xc_domain_create"
+val domain_create : handle -> int32 -> domain_create_flag list -> 'a Uuid.t -> domid
+external _domain_sethandle : handle -> domid -> int array -> unit
+  = "stub_xc_domain_sethandle"
+val domain_sethandle : handle -> domid -> 'a Uuid.t -> unit
+external domain_setvmxassist: handle -> domid -> bool -> unit
+  = "stub_xc_domain_setvmxassist"
+external domain_max_vcpus : handle -> domid -> int -> unit
+  = "stub_xc_domain_max_vcpus"
+external domain_pause : handle -> domid -> unit = "stub_xc_domain_pause"
+external domain_unpause : handle -> domid -> unit = "stub_xc_domain_unpause"
+external domain_resume_fast : handle -> domid -> unit
+  = "stub_xc_domain_resume_fast"
+external domain_destroy : handle -> domid -> unit = "stub_xc_domain_destroy"
+external domain_shutdown : handle -> domid -> shutdown_reason -> unit
+  = "stub_xc_domain_shutdown"
+external _domain_getinfolist : handle -> domid -> int -> domaininfo list
+  = "stub_xc_domain_getinfolist"
+val domain_getinfolist : handle -> domid -> domaininfo list
+external domain_getinfo : handle -> domid -> domaininfo
+  = "stub_xc_domain_getinfo"
+external domain_get_vcpuinfo : handle -> int -> int -> vcpuinfo
+  = "stub_xc_vcpu_getinfo"
+external domain_ioport_permission: handle -> domid -> int -> int -> bool -> unit
+       = "stub_xc_domain_ioport_permission"
+external domain_iomem_permission: handle -> domid -> nativeint -> nativeint -> bool -> unit
+       = "stub_xc_domain_iomem_permission"
+external domain_irq_permission: handle -> domid -> int -> bool -> unit
+       = "stub_xc_domain_irq_permission"
+external vcpu_affinity_set : handle -> domid -> int -> int64 -> unit
+  = "stub_xc_vcpu_setaffinity"
+external vcpu_affinity_get : handle -> domid -> int -> int64
+  = "stub_xc_vcpu_getaffinity"
+external vcpu_context_get : handle -> domid -> int -> string
+  = "stub_xc_vcpu_context_get"
+external sched_id : handle -> int = "stub_xc_sched_id"
+external sched_credit_domain_set : handle -> domid -> sched_control -> unit
+  = "stub_sched_credit_domain_set"
+external sched_credit_domain_get : handle -> domid -> sched_control
+  = "stub_sched_credit_domain_get"
+external shadow_allocation_set : handle -> domid -> int -> unit
+  = "stub_shadow_allocation_set"
+external shadow_allocation_get : handle -> domid -> int
+  = "stub_shadow_allocation_get"
+external evtchn_alloc_unbound : handle -> domid -> domid -> int
+  = "stub_xc_evtchn_alloc_unbound"
+external evtchn_reset : handle -> domid -> unit = "stub_xc_evtchn_reset"
+external readconsolering : handle -> string = "stub_xc_readconsolering"
+external send_debug_keys : handle -> string -> unit = "stub_xc_send_debug_keys"
+external physinfo : handle -> physinfo = "stub_xc_physinfo"
+external pcpu_info: handle -> int -> int64 array = "stub_xc_pcpu_info"
+external domain_setmaxmem : handle -> domid -> int64 -> unit
+  = "stub_xc_domain_setmaxmem"
+external domain_set_memmap_limit : handle -> domid -> int64 -> unit
+  = "stub_xc_domain_set_memmap_limit"
+external domain_memory_increase_reservation :
+  handle -> domid -> int64 -> unit
+  = "stub_xc_domain_memory_increase_reservation"
+external map_foreign_range :
+  handle -> domid -> int -> nativeint -> Mmap.mmap_interface
+  = "stub_map_foreign_range"
+external domain_get_pfn_list :
+  handle -> domid -> nativeint -> nativeint array
+  = "stub_xc_domain_get_pfn_list"
+
+external domain_assign_device: handle -> domid -> (int * int * int * int) -> unit
+       = "stub_xc_domain_assign_device"
+external domain_deassign_device: handle -> domid -> (int * int * int * int) -> unit
+       = "stub_xc_domain_deassign_device"
+external domain_test_assign_device: handle -> domid -> (int * int * int * int) -> bool
+       = "stub_xc_domain_test_assign_device"
+
+external domain_set_timer_mode: handle -> domid -> int -> unit = "stub_xc_domain_set_timer_mode"
+external domain_set_hpet: handle -> domid -> int -> unit = "stub_xc_domain_set_hpet"
+external domain_set_vpt_align: handle -> domid -> int -> unit = "stub_xc_domain_set_vpt_align"
+
+external domain_send_s3resume: handle -> domid -> unit
+  = "stub_xc_domain_send_s3resume"
+external domain_get_acpi_s_state: handle -> domid -> int = "stub_xc_domain_get_acpi_s_state"
+
+external hvm_check_pvdriver : handle -> domid -> bool
+  = "stub_xc_hvm_check_pvdriver"
+external version : handle -> version = "stub_xc_version_version"
+external version_compile_info : handle -> compile_info
+  = "stub_xc_version_compile_info"
+external version_changeset : handle -> string = "stub_xc_version_changeset"
+external version_capabilities : handle -> string
+  = "stub_xc_version_capabilities"
+type core_magic = Magic_hvm | Magic_pv
+type core_header = {
+  xch_magic : core_magic;
+  xch_nr_vcpus : int;
+  xch_nr_pages : nativeint;
+  xch_index_offset : int64;
+  xch_ctxt_offset : int64;
+  xch_pages_offset : int64;
+}
+external marshall_core_header : core_header -> string
+  = "stub_marshall_core_header"
+val coredump : handle -> domid -> Unix.file_descr -> unit
+external pages_to_kib : int64 -> int64 = "stub_pages_to_kib"
+val pages_to_mib : int64 -> int64
+external watchdog : handle -> int -> int32 -> int
+  = "stub_xc_watchdog"
+
+external domain_set_machine_address_size: handle -> domid -> int -> unit
+  = "stub_xc_domain_set_machine_address_size"
+external domain_get_machine_address_size: handle -> domid -> int
+       = "stub_xc_domain_get_machine_address_size"
+
+external domain_cpuid_set: handle -> domid -> bool -> (int64 * (int64 option))
+                        -> string option array
+                        -> string option array
+       = "stub_xc_domain_cpuid_set"
+external domain_cpuid_apply: handle -> domid -> bool -> unit
+       = "stub_xc_domain_cpuid_apply"
+external cpuid_check: (int64 * (int64 option)) -> string option array -> (bool * string option array)
+       = "stub_xc_cpuid_check"
+
diff --git a/tools/ocaml/libs/xc/xc_cpufeature.h b/tools/ocaml/libs/xc/xc_cpufeature.h
new file mode 100644
index 0000000..047a6c9
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc_cpufeature.h
@@ -0,0 +1,116 @@
+#ifndef __LIBXC_CPUFEATURE_H
+#define __LIBXC_CPUFEATURE_H
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
+#define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
+#define X86_FEATURE_VME		(0*32+ 1) /* Virtual Mode Extensions */
+#define X86_FEATURE_DE		(0*32+ 2) /* Debugging Extensions */
+#define X86_FEATURE_PSE 	(0*32+ 3) /* Page Size Extensions */
+#define X86_FEATURE_TSC		(0*32+ 4) /* Time Stamp Counter */
+#define X86_FEATURE_MSR		(0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE		(0*32+ 6) /* Physical Address Extensions */
+#define X86_FEATURE_MCE		(0*32+ 7) /* Machine Check Architecture */
+#define X86_FEATURE_CX8		(0*32+ 8) /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC	(0*32+ 9) /* Onboard APIC */
+#define X86_FEATURE_SEP		(0*32+11) /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR	(0*32+12) /* Memory Type Range Registers */
+#define X86_FEATURE_PGE		(0*32+13) /* Page Global Enable */
+#define X86_FEATURE_MCA		(0*32+14) /* Machine Check Architecture */
+#define X86_FEATURE_CMOV	(0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
+#define X86_FEATURE_PAT		(0*32+16) /* Page Attribute Table */
+#define X86_FEATURE_PSE36	(0*32+17) /* 36-bit PSEs */
+#define X86_FEATURE_PN		(0*32+18) /* Processor serial number */
+#define X86_FEATURE_CLFLSH	(0*32+19) /* Supports the CLFLUSH instruction */
+#define X86_FEATURE_DS		(0*32+21) /* Debug Store */
+#define X86_FEATURE_ACPI	(0*32+22) /* ACPI via MSR */
+#define X86_FEATURE_MMX		(0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR	(0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
+				          /* of FPU context), and CR4.OSFXSR available */
+#define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
+#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
+#define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
+#define X86_FEATURE_PBE		(0*32+31) /* Pending Break Enable */
+
+/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
+/* Don't duplicate feature flags which are redundant with Intel! */
+#define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP		(1*32+19) /* MP Capable. */
+#define X86_FEATURE_NX		(1*32+20) /* Execute Disable */
+#define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_FFXSR       (1*32+25) /* FFXSR instruction optimizations */
+#define X86_FEATURE_PAGE1GB	(1*32+26) /* 1Gb large page support */
+#define X86_FEATURE_RDTSCP	(1*32+27) /* RDTSCP */
+#define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW	(1*32+31) /* 3DNow! */
+
+/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
+#define X86_FEATURE_RECOVERY	(2*32+ 0) /* CPU in recovery mode */
+#define X86_FEATURE_LONGRUN	(2*32+ 1) /* Longrun power control */
+#define X86_FEATURE_LRTI	(2*32+ 3) /* LongRun table interface */
+
+/* Other features, Linux-defined mapping, word 3 */
+/* This range is used for feature bits which conflict or are synthesized */
+#define X86_FEATURE_CXMMX	(3*32+ 0) /* Cyrix MMX extensions */
+#define X86_FEATURE_K6_MTRR	(3*32+ 1) /* AMD K6 nonstandard MTRRs */
+#define X86_FEATURE_CYRIX_ARR	(3*32+ 2) /* Cyrix ARRs (= MTRRs) */
+#define X86_FEATURE_CENTAUR_MCR	(3*32+ 3) /* Centaur MCRs (= MTRRs) */
+/* cpu types for specific tunings: */
+#define X86_FEATURE_K8		(3*32+ 4) /* Opteron, Athlon64 */
+#define X86_FEATURE_K7		(3*32+ 5) /* Athlon */
+#define X86_FEATURE_P3		(3*32+ 6) /* P3 */
+#define X86_FEATURE_P4		(3*32+ 7) /* P4 */
+#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
+
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
+#define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
+#define X86_FEATURE_DTES64	(4*32+ 2) /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT	(4*32+ 3) /* Monitor/Mwait support */
+#define X86_FEATURE_DSCPL	(4*32+ 4) /* CPL Qualified Debug Store */
+#define X86_FEATURE_VMXE	(4*32+ 5) /* Virtual Machine Extensions */
+#define X86_FEATURE_SMXE	(4*32+ 6) /* Safer Mode Extensions */
+#define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3	(4*32+ 9) /* Supplemental Streaming SIMD Extensions-3 */
+#define X86_FEATURE_CID		(4*32+10) /* Context ID */
+#define X86_FEATURE_CX16        (4*32+13) /* CMPXCHG16B */
+#define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM	(4*32+15) /* Perf/Debug Capability MSR */
+#define X86_FEATURE_DCA		(4*32+18) /* Direct Cache Access */
+#define X86_FEATURE_SSE4_1	(4*32+19) /* Streaming SIMD Extensions 4.1 */
+#define X86_FEATURE_SSE4_2	(4*32+20) /* Streaming SIMD Extensions 4.2 */
+#define X86_FEATURE_POPCNT	(4*32+23) /* POPCNT instruction */
+#define X86_FEATURE_HYPERVISOR	(4*32+31) /* Running under some hypervisor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
+#define X86_FEATURE_XSTORE	(5*32+ 2) /* on-CPU RNG present (xstore insn) */
+#define X86_FEATURE_XSTORE_EN	(5*32+ 3) /* on-CPU RNG enabled */
+#define X86_FEATURE_XCRYPT	(5*32+ 6) /* on-CPU crypto (xcrypt insn) */
+#define X86_FEATURE_XCRYPT_EN	(5*32+ 7) /* on-CPU crypto enabled */
+#define X86_FEATURE_ACE2	(5*32+ 8) /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN	(5*32+ 9) /* ACE v2 enabled */
+#define X86_FEATURE_PHE		(5*32+ 10) /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN	(5*32+ 11) /* PHE enabled */
+#define X86_FEATURE_PMM		(5*32+ 12) /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN	(5*32+ 13) /* PMM enabled */
+
+/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
+#define X86_FEATURE_LAHF_LM	(6*32+ 0) /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY	(6*32+ 1) /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVME        (6*32+ 2) /* Secure Virtual Machine */
+#define X86_FEATURE_EXTAPICSPACE (6*32+ 3) /* Extended APIC space */
+#define X86_FEATURE_ALTMOVCR	(6*32+ 4) /* LOCK MOV CR accesses CR+8 */
+#define X86_FEATURE_ABM		(6*32+ 5) /* Advanced Bit Manipulation */
+#define X86_FEATURE_SSE4A	(6*32+ 6) /* AMD Streaming SIMD Extensions-4a */
+#define X86_FEATURE_MISALIGNSSE	(6*32+ 7) /* Misaligned SSE Access */
+#define X86_FEATURE_3DNOWPF	(6*32+ 8) /* 3DNow! Prefetch */
+#define X86_FEATURE_OSVW	(6*32+ 9) /* OS Visible Workaround */
+#define X86_FEATURE_IBS		(6*32+ 10) /* Instruction Based Sampling */
+#define X86_FEATURE_SSE5	(6*32+ 11) /* AMD Streaming SIMD Extensions-5 */
+#define X86_FEATURE_SKINIT	(6*32+ 12) /* SKINIT, STGI/CLGI, DEV */
+#define X86_FEATURE_WDT		(6*32+ 13) /* Watchdog Timer */
+
+#endif /* __LIBXC_CPUFEATURE_H */
diff --git a/tools/ocaml/libs/xc/xc_cpuid.h b/tools/ocaml/libs/xc/xc_cpuid.h
new file mode 100644
index 0000000..43743ef
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc_cpuid.h
@@ -0,0 +1,285 @@
+#ifndef XC_CPUID_H
+#define XC_CPUID_H
+
+#ifdef XEN_DOMCTL_set_cpuid
+
+#include "xc_cpufeature.h"
+
+#define bitmaskof(idx)      (1u << ((idx) & 31))
+#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31)))
+#define set_bit(idx, dst)   ((dst) |= (1u << ((idx) & 31)))
+
+#define DEF_MAX_BASE 0x00000004u
+#define DEF_MAX_EXT  0x80000008u
+
+static void xc_cpuid(uint32_t eax, uint32_t ecx, uint32_t regs[4])
+{
+	unsigned int realecx = (ecx == XEN_CPUID_INPUT_UNUSED) ? 0 : ecx;
+	asm (
+#ifdef __i386__
+	     "push %%ebx; cpuid; mov %%ebx,%1; pop %%ebx"
+#else
+	     "push %%rbx; cpuid; mov %%ebx,%1; pop %%rbx"
+#endif
+	    : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+	    : "0" (eax), "2" (realecx));
+}
+
+enum { CPU_BRAND_INTEL, CPU_BRAND_AMD, CPU_BRAND_UNKNOWN };
+
+static int xc_cpuid_brand_get(void)
+{
+	uint32_t regs[4];
+	char str[13];
+	uint32_t *istr = (uint32_t *) str;
+
+	xc_cpuid(0, 0, regs);
+	istr[0] = regs[1];
+	istr[1] = regs[3];
+	istr[2] = regs[2];
+	str[12] = '\0';
+	if      (strcmp(str, "AuthenticAMD") == 0) {
+		return CPU_BRAND_AMD;
+	} else if (strcmp(str, "GenuineIntel") == 0) {
+		return CPU_BRAND_INTEL;
+	} else
+		return CPU_BRAND_UNKNOWN;
+}
+
+static int hypervisor_is_64bit(int xc)
+{
+	xen_capabilities_info_t xen_caps;
+	return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
+	        (strstr(xen_caps, "x86_64") != NULL));
+}
+
+static void do_hvm_cpuid_policy(int xc, int domid, uint32_t input, uint32_t regs[4])
+{
+	unsigned long is_pae;
+	int brand;
+
+	/* pae ? */
+	xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &is_pae);
+	is_pae = !!is_pae;
+
+	switch (input) {
+	case 0x00000000:
+		if (regs[0] > DEF_MAX_BASE)
+			regs[0] = DEF_MAX_BASE;
+		break;
+	case 0x00000001:
+		regs[2] &= (bitmaskof(X86_FEATURE_XMM3) |
+				bitmaskof(X86_FEATURE_SSSE3) |
+				bitmaskof(X86_FEATURE_CX16) |
+				bitmaskof(X86_FEATURE_SSE4_1) |
+				bitmaskof(X86_FEATURE_SSE4_2) |
+				bitmaskof(X86_FEATURE_POPCNT));
+
+                regs[2] |= bitmaskof(X86_FEATURE_HYPERVISOR);
+
+		regs[3] &= (bitmaskof(X86_FEATURE_FPU) |
+				bitmaskof(X86_FEATURE_VME) |
+				bitmaskof(X86_FEATURE_DE) |
+				bitmaskof(X86_FEATURE_PSE) |
+				bitmaskof(X86_FEATURE_TSC) |
+				bitmaskof(X86_FEATURE_MSR) |
+				bitmaskof(X86_FEATURE_PAE) |
+				bitmaskof(X86_FEATURE_MCE) |
+				bitmaskof(X86_FEATURE_CX8) |
+				bitmaskof(X86_FEATURE_APIC) |
+				bitmaskof(X86_FEATURE_SEP) |
+				bitmaskof(X86_FEATURE_MTRR) |
+				bitmaskof(X86_FEATURE_PGE) |
+				bitmaskof(X86_FEATURE_MCA) |
+				bitmaskof(X86_FEATURE_CMOV) |
+				bitmaskof(X86_FEATURE_PAT) |
+				bitmaskof(X86_FEATURE_CLFLSH) |
+				bitmaskof(X86_FEATURE_MMX) |
+				bitmaskof(X86_FEATURE_FXSR) |
+				bitmaskof(X86_FEATURE_XMM) |
+				bitmaskof(X86_FEATURE_XMM2));
+		/* We always support MTRR MSRs. */
+		regs[3] |= bitmaskof(X86_FEATURE_MTRR);
+
+		if (!is_pae)
+			clear_bit(X86_FEATURE_PAE, regs[3]);
+		break;
+	case 0x80000000:
+		if (regs[0] > DEF_MAX_EXT)
+			regs[0] = DEF_MAX_EXT;
+		break;
+	case 0x80000001:
+		if (!is_pae)
+			clear_bit(X86_FEATURE_NX, regs[3]);
+		break;
+	case 0x80000008:
+		regs[0] &= 0x0000ffffu;
+		regs[1] = regs[2] = regs[3] = 0;
+		break;
+	case 0x00000002: /* Intel cache info (dumped by AMD policy) */
+	case 0x00000004: /* Intel cache info (dumped by AMD policy) */
+	case 0x80000002: /* Processor name string */
+	case 0x80000003: /* ... continued         */
+	case 0x80000004: /* ... continued         */
+	case 0x80000005: /* AMD L1 cache/TLB info (dumped by Intel policy) */
+	case 0x80000006: /* AMD L2/3 cache/TLB info ; Intel L2 cache features */
+		break;
+	default:
+		regs[0] = regs[1] = regs[2] = regs[3] = 0;
+		break;
+	}
+	
+	brand = xc_cpuid_brand_get();
+	if (brand == CPU_BRAND_AMD) {
+		switch (input) {
+		case 0x00000001:
+			/* Mask Intel-only features. */
+			regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) |
+					bitmaskof(X86_FEATURE_SSE4_1) |
+					bitmaskof(X86_FEATURE_SSE4_2));
+			break;
+
+		case 0x00000002:
+		case 0x00000004:
+			regs[0] = regs[1] = regs[2] = 0;
+			break;
+
+		case 0x80000001: {
+			int is_64bit = hypervisor_is_64bit(xc) && is_pae;
+
+			if (!is_pae)
+				 clear_bit(X86_FEATURE_PAE, regs[3]);
+			clear_bit(X86_FEATURE_PSE36, regs[3]);
+
+			/* Filter all other features according to a whitelist. */
+			regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) |
+					 bitmaskof(X86_FEATURE_ALTMOVCR) |
+					 bitmaskof(X86_FEATURE_ABM) |
+					 bitmaskof(X86_FEATURE_SSE4A) |
+					 bitmaskof(X86_FEATURE_MISALIGNSSE) |
+					 bitmaskof(X86_FEATURE_3DNOWPF));
+			regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
+					 (is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
+					 (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
+					 bitmaskof(X86_FEATURE_SYSCALL) |
+					 bitmaskof(X86_FEATURE_MP) |
+					 bitmaskof(X86_FEATURE_MMXEXT) |
+					 bitmaskof(X86_FEATURE_FFXSR) |
+					 bitmaskof(X86_FEATURE_3DNOW) |
+					 bitmaskof(X86_FEATURE_3DNOWEXT));
+			break;
+			}
+		}
+	} else if (brand == CPU_BRAND_INTEL) {
+		switch (input) {
+		case 0x00000001:
+			/* Mask AMD-only features. */
+			regs[2] &= ~(bitmaskof(X86_FEATURE_POPCNT));
+			break;
+
+		case 0x00000004:
+			regs[0] &= 0x3FF;
+			regs[3] &= 0x3FF;
+			break;
+
+		case 0x80000001:
+			{
+			int is_64bit = hypervisor_is_64bit(xc) && is_pae;
+
+			/* Only a few features are advertised in Intel's 0x80000001. */
+			regs[2] &= (is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0);
+			regs[3] &= ((is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
+					(is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
+					(is_64bit ? bitmaskof(X86_FEATURE_SYSCALL) : 0));
+			break;
+			}
+		case 0x80000005:
+			{
+			regs[0] = regs[1] = regs[2] = 0;
+			break;
+			}
+		}
+	}
+}
+
+static void do_pv_cpuid_policy(int xc, int domid, uint32_t input, uint32_t regs[4])
+{
+	int brand;
+	int guest_64_bits, xen_64_bits;
+	int ret;
+	
+	ret = xc_domain_get_machine_address_size(xc, domid);
+	if (ret < 0)
+		return;
+	guest_64_bits = (ret == 64);
+	xen_64_bits = hypervisor_is_64bit(xc);
+	brand = xc_cpuid_brand_get();
+
+	if ((input & 0x7fffffff) == 1) {
+		clear_bit(X86_FEATURE_VME, regs[3]);
+		clear_bit(X86_FEATURE_PSE, regs[3]);
+		clear_bit(X86_FEATURE_PGE, regs[3]);
+		clear_bit(X86_FEATURE_MCE, regs[3]);
+		clear_bit(X86_FEATURE_MCA, regs[3]);
+		clear_bit(X86_FEATURE_MTRR, regs[3]);
+		clear_bit(X86_FEATURE_PSE36, regs[3]);
+	}
+
+	switch (input) {
+	case 1:
+		if (!xen_64_bits || brand == CPU_BRAND_AMD)
+			clear_bit(X86_FEATURE_SEP, regs[3]);
+		clear_bit(X86_FEATURE_DS, regs[3]);
+		clear_bit(X86_FEATURE_ACC, regs[3]);
+		clear_bit(X86_FEATURE_PBE, regs[3]);
+
+		clear_bit(X86_FEATURE_DTES64, regs[2]);
+		clear_bit(X86_FEATURE_MWAIT, regs[2]);
+		clear_bit(X86_FEATURE_DSCPL, regs[2]);
+		clear_bit(X86_FEATURE_VMXE, regs[2]);
+		clear_bit(X86_FEATURE_SMXE, regs[2]);
+		clear_bit(X86_FEATURE_EST, regs[2]);
+		clear_bit(X86_FEATURE_TM2, regs[2]);
+		if (!guest_64_bits)
+			clear_bit(X86_FEATURE_CX16, regs[2]);
+		clear_bit(X86_FEATURE_XTPR, regs[2]);
+		clear_bit(X86_FEATURE_PDCM, regs[2]);
+		clear_bit(X86_FEATURE_DCA, regs[2]);
+		break;
+	case 0x80000001:
+		if (!guest_64_bits) {
+			clear_bit(X86_FEATURE_LM, regs[3]);
+			clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
+			if (brand != CPU_BRAND_AMD)
+				clear_bit(X86_FEATURE_SYSCALL, regs[3]);
+		} else
+			set_bit(X86_FEATURE_SYSCALL, regs[3]);
+		clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
+		clear_bit(X86_FEATURE_RDTSCP, regs[3]);
+
+		clear_bit(X86_FEATURE_SVME, regs[2]);
+		clear_bit(X86_FEATURE_OSVW, regs[2]);
+		clear_bit(X86_FEATURE_IBS, regs[2]);
+		clear_bit(X86_FEATURE_SKINIT, regs[2]);
+		clear_bit(X86_FEATURE_WDT, regs[2]);
+		break;
+	case 5: /* MONITOR/MWAIT */
+	case 0xa: /* Architectural Performance Monitor Features */
+	case 0x8000000a: /* SVM revision and features */
+	case 0x8000001b: /* Instruction Based Sampling */
+		regs[0] = regs[1] = regs[2] = regs[3] = 0;
+		break;
+	}
+}
+
+static void do_cpuid_policy(int xc, int domid, int hvm, uint32_t input, uint32_t regs[4])
+{
+	if (hvm)
+		do_hvm_cpuid_policy(xc, domid, input, regs);
+	else
+		do_pv_cpuid_policy(xc, domid, input, regs);
+}
+
+#endif
+
+#endif
diff --git a/tools/ocaml/libs/xc/xc_e820.h b/tools/ocaml/libs/xc/xc_e820.h
new file mode 100644
index 0000000..52bbb0f
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc_e820.h
@@ -0,0 +1,20 @@
+#ifndef __XC_E820_H__
+#define __XC_E820_H__
+
+#include <xen/hvm/e820.h>
+
+/*
+ * PC BIOS standard E820 types and structure.
+ */
+#define E820_RAM          1
+#define E820_RESERVED     2
+#define E820_ACPI         3
+#define E820_NVS          4
+
+struct e820entry {
+    uint64_t addr;
+    uint64_t size;
+    uint32_t type;
+} __attribute__((packed));
+
+#endif /* __XC_E820_H__ */
diff --git a/tools/ocaml/libs/xc/xc_lib.c b/tools/ocaml/libs/xc/xc_lib.c
new file mode 100644
index 0000000..7fffc43
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc_lib.c
@@ -0,0 +1,1502 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "xc.h"
+
+#define PAGE_SHIFT		12
+#define PAGE_SIZE               (1UL << PAGE_SHIFT)
+#define PAGE_MASK               (~(PAGE_SIZE-1))
+
+#define MIN(a, b) 		(((a) < (b)) ? (a) : (b))
+
+#define DECLARE_DOMCTL(_cmd, _domain)	\
+	struct xen_domctl domctl = {    \
+		.cmd = _cmd,		\
+		.domain = _domain,	\
+		.interface_version = XEN_DOMCTL_INTERFACE_VERSION, \
+	}
+
+#define DECLARE_SYSCTL(_cmd)		\
+	struct xen_sysctl sysctl = {	\
+		.cmd = _cmd,		\
+		.interface_version = XEN_SYSCTL_INTERFACE_VERSION, \
+	}
+
+#define DECLARE_HYPERCALL2(_cmd, _arg0, _arg1)	\
+	privcmd_hypercall_t hypercall = {	\
+		.op = _cmd,			\
+		.arg[0] = (unsigned long) _arg0,\
+		.arg[1] = (unsigned long) _arg1,\
+	}
+#define DECLARE_HYPERCALL0(_cmd)	DECLARE_HYPERCALL2(_cmd, 0, 0);
+#define DECLARE_HYPERCALL1(_cmd, _arg0)	DECLARE_HYPERCALL2(_cmd, _arg0, 0);
+
+/*---- Errors handlings ----*/
+#ifndef WITHOUT_GOOD_ERROR
+#define ERROR_STRLEN 256
+
+static char __error_str[ERROR_STRLEN];
+
+char * xc_error_get(void)
+{
+	return __error_str;
+}
+
+static void xc_error_set(const char *fmt, ...)
+{
+	va_list ap;
+	char __errordup[ERROR_STRLEN];
+
+	va_start(ap, fmt);
+	vsnprintf(__errordup, ERROR_STRLEN, fmt, ap);
+	va_end(ap);
+	memcpy(__error_str, __errordup, ERROR_STRLEN);
+}
+
+static void xc_error_dom_set(unsigned int domid, const char *fmt, ...)
+{
+	va_list ap;
+	char __errordup[ERROR_STRLEN];
+	int i;
+
+	i = snprintf(__errordup, ERROR_STRLEN, "domain %u - ", domid);
+	va_start(ap, fmt);
+	i += vsnprintf(__errordup + i, ERROR_STRLEN - i, fmt, ap);
+	va_end(ap);
+	snprintf(__errordup + i, ERROR_STRLEN - i,
+	         " failed: %s", xc_error_get());
+	memcpy(__error_str, __errordup, ERROR_STRLEN);
+}
+
+void xc_error_clear(void)
+{
+	memset(__error_str, '\0', ERROR_STRLEN);
+}
+#else
+char * xc_error_get(void)
+{
+	return "";
+}
+#define xc_error_set(fmt, ...) do {} while (0)
+#define xc_error_dom_set(id, fmt, ...) do {} while (0)
+#define xc_error_clear() do {} while (0)
+#endif
+
+#define xc_error_hypercall(_h, _r) \
+	xc_error_set("hypercall %lld fail: %d: %s (ret %d)", _h.op, errno, errno ? strerror(errno) : strerror(-_r), _r)
+
+int xc_using_injection(void)
+{
+	return 0;
+}
+
+/*---- Trivia ----*/
+int xc_interface_open(void)
+{
+	int fd, ret;
+
+	fd = open("/proc/xen/privcmd", O_RDWR);
+	if (fd == -1) {
+		xc_error_set("open /proc/xen/privcmd failed: %s",
+		             strerror(errno));
+		return -1;
+	}
+
+	ret = fcntl(fd, F_GETFD);
+	if (ret < 0) {
+		xc_error_set("cannot get handle flags: %s",
+		             strerror(errno));
+		goto out;
+	}
+
+	ret = fcntl(fd, F_SETFD, ret | FD_CLOEXEC);
+	if (ret < 0) {
+		xc_error_set("cannot set handle flags: %s",
+		             strerror(errno));
+		goto out;
+	}
+
+	return fd;
+out:
+	close(fd);
+	return -1;
+}
+
+int xc_interface_close(int handle)
+{
+	int ret;
+
+	ret = close(handle);
+	if (ret != 0)
+		xc_error_set("close xc failed: %s", strerror(errno));
+	return ret;
+}
+
+/*---- Low private operations ----*/
+static int do_xen_hypercall(int handle, privcmd_hypercall_t *hypercall)
+{
+	return ioctl(handle, IOCTL_PRIVCMD_HYPERCALL, (unsigned long) hypercall);
+}
+
+static int do_domctl(int handle, struct xen_domctl *domctl)
+{
+	int ret;
+	DECLARE_HYPERCALL1(__HYPERVISOR_domctl, domctl);
+
+	if (mlock(domctl, sizeof(*domctl)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret < 0)
+		xc_error_hypercall(hypercall, ret);
+
+	munlock(domctl, sizeof(*domctl));
+	return ret;
+}
+
+static int do_sysctl(int handle, struct xen_sysctl *sysctl)
+{
+	int ret;
+	DECLARE_HYPERCALL1(__HYPERVISOR_sysctl, sysctl);
+
+	if (mlock(sysctl, sizeof(*sysctl)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret < 0)
+		xc_error_hypercall(hypercall, ret);
+
+	munlock(sysctl, sizeof(*sysctl));
+	return ret;
+}
+
+static int do_evtchnctl(int handle, int cmd, void *arg, size_t arg_size)
+{
+	DECLARE_HYPERCALL2(__HYPERVISOR_event_channel_op, cmd, arg);
+	int ret;
+
+	if (mlock(arg, arg_size) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret < 0)
+		xc_error_hypercall(hypercall, ret);
+	munlock(arg, arg_size);
+	return ret;
+}
+
+static int do_memctl_reservation(int handle, int cmd,
+                                 struct xen_memory_reservation *reservation)
+{
+	int ret;
+	DECLARE_HYPERCALL2(__HYPERVISOR_memory_op, cmd, reservation);
+	xen_pfn_t *extent_start;
+
+	if (cmd != XENMEM_increase_reservation &&
+	    cmd != XENMEM_decrease_reservation &&
+	    cmd != XENMEM_populate_physmap) {
+		xc_error_set("do_memctl_reservation: unknown cmd %d", cmd);
+		return -EINVAL;
+	}
+
+	if (mlock(reservation, sizeof(*reservation)) == -1) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -ENOMEM;
+	}
+	get_xen_guest_handle(extent_start, reservation->extent_start);
+	if (extent_start && mlock(extent_start, reservation->nr_extents
+	                                      * sizeof(xen_pfn_t)) == -1) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		munlock(reservation, sizeof(*reservation));
+		return -3;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret)
+		xc_error_hypercall(hypercall, ret);
+	munlock(extent_start, reservation->nr_extents * sizeof(xen_pfn_t));
+	get_xen_guest_handle(extent_start, reservation->extent_start);
+	munlock(reservation, sizeof(*reservation));
+	return ret;
+}
+
+static int do_ioctl(int handle, int cmd, void *arg)
+{
+	return ioctl(handle, cmd, arg);
+}
+
+static void * do_mmap(void *start, size_t length, int prot, int flags,
+                      int fd, off_t offset)
+{
+	return mmap(start, length, prot, flags, fd, offset);
+}
+
+int xc_get_hvm_param(int handle, unsigned int domid,
+                     int param, unsigned long *value)
+{
+	struct xen_hvm_param arg = {
+		.domid = domid,
+		.index = param,
+	};
+	DECLARE_HYPERCALL2(__HYPERVISOR_hvm_op, HVMOP_get_param,
+	                   (unsigned long) &arg);
+	int ret;
+
+	if (mlock(&arg, sizeof(arg)) == -1) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret)
+		xc_error_hypercall(hypercall, ret);
+	*value = arg.value;
+	munlock(&arg, sizeof(arg));
+	return ret;
+}
+
+static int xc_set_hvm_param(int handle, unsigned int domid,
+                            int param, unsigned long value)
+{
+	struct xen_hvm_param arg = {
+		.domid = domid,
+		.index = param,
+		.value = value,
+	};
+	DECLARE_HYPERCALL2(__HYPERVISOR_hvm_op, HVMOP_set_param, (unsigned long) &arg);
+	int ret;
+
+	if (mlock(&arg, sizeof(arg)) == -1) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret)
+		xc_error_hypercall(hypercall, ret);
+	munlock(&arg, sizeof(arg));
+	return ret;
+}
+
+
+/*---- XC API ----*/
+int xc_domain_create(int handle, unsigned int ssidref,
+                     xen_domain_handle_t dhandle,
+                     unsigned int flags, unsigned int *pdomid)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_createdomain, *pdomid);
+	domctl.u.createdomain.ssidref = ssidref;
+	domctl.u.createdomain.flags = flags;
+	memcpy(domctl.u.createdomain.handle, dhandle, sizeof(xen_domain_handle_t));
+
+	ret = do_domctl(handle, &domctl);
+	if (ret != 0) {
+		xc_error_set("creating domain failed: %s", xc_error_get());
+		return ret;
+	}
+	*pdomid = domctl.domain;
+	return 0;
+}
+
+int xc_domain_pause(int handle, unsigned int domid)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_pausedomain, domid);
+
+	ret = do_domctl(handle, &domctl);
+	if (ret != 0)
+		xc_error_dom_set(domid, "pause");
+	return ret;
+}
+
+int xc_domain_unpause(int handle, unsigned int domid)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_unpausedomain, domid);
+
+	ret = do_domctl(handle, &domctl);
+	if (ret != 0)
+		xc_error_dom_set(domid, "unpause");
+	return ret;
+}
+
+/* return 1 if hvm domain got pv driver, 0 if not. -1 is error occurs */
+int xc_hvm_check_pvdriver(int handle, unsigned int domid)
+{
+	int ret;
+	unsigned long irq = 0;
+	xc_domaininfo_t info;
+
+	ret = xc_domain_getinfolist(handle, domid, 1, &info);
+	if (ret != 1) {
+		xc_error_set("domain getinfo failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "hvm_check_pvdriver");
+		return -1;
+	}
+
+	if (!(info.flags & XEN_DOMINF_hvm_guest)) {
+		xc_error_set("domain is not hvm");
+		xc_error_dom_set(domid, "hvm_check_pvdriver");
+		return -1;
+	}
+	xc_get_hvm_param(handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
+	return irq;
+}
+
+static int modify_returncode_register(int handle, unsigned int domid)
+{
+	int ret;
+	xc_domaininfo_t info;
+	xen_capabilities_info_t caps;
+	vcpu_guest_context_any_t context;
+
+	ret = xc_domain_getinfolist(handle, domid, 1, &info);
+	if (ret != 1) {
+		xc_error_set("domain getinfo failed: %s", strerror(errno));
+		return -1;
+	}
+
+	/* HVM guests without PV drivers do not have a return code to modify */
+	if (info.flags & XEN_DOMINF_hvm_guest) {
+		unsigned long irq = 0;
+		xc_get_hvm_param(handle, domid, HVM_PARAM_CALLBACK_IRQ, &irq);
+		if (!irq)
+			return 0;
+	}
+
+	ret = xc_version(handle, XENVER_capabilities, &caps);
+	if (ret) {
+		xc_error_set("could not get Xen capabilities");
+		return ret;
+	}
+
+	ret = xc_vcpu_getcontext(handle, domid, 0, &context);
+	if (ret) {
+		xc_error_set("could not get vcpu 0 context");
+		return ret;
+	}
+
+	if (!(info.flags & XEN_DOMINF_hvm_guest))
+		context.c.user_regs.eax = 1;
+	else if (strstr(caps, "x86_64"))
+		context.x64.user_regs.eax = 1;
+	else
+		context.x32.user_regs.eax = 1;
+
+	ret = xc_vcpu_setcontext(handle, domid, 0, &context);
+	if (ret) {
+		xc_error_set("could not set vcpu 0 context");
+		return ret;
+	}
+	return 0;
+}
+
+int xc_domain_resume_fast(int handle, unsigned int domid)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_resumedomain, domid);
+
+	ret = modify_returncode_register(handle, domid);
+	if (ret != 0) {
+		xc_error_dom_set(domid, "resume_fast");
+		return ret;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret != 0)
+		xc_error_dom_set(domid, "resume_fast");
+	return ret;
+}
+
+int xc_domain_destroy(int handle, unsigned int domid)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_destroydomain, domid);
+
+	do {
+		ret = do_domctl(handle, &domctl);
+	} while (ret && (errno == EAGAIN));
+	if (ret != 0)
+		xc_error_dom_set(domid, "destroy");
+	return ret;
+}
+
+int xc_domain_shutdown(int handle, int domid, int reason)
+{
+	sched_remote_shutdown_t arg = {
+		.domain_id = domid,
+		.reason = reason,
+	};
+	DECLARE_HYPERCALL2(__HYPERVISOR_sched_op, SCHEDOP_remote_shutdown, &arg);
+	int ret;
+
+	if (mlock(&arg, sizeof(arg)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "shutdown %d", reason);
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret < 0) {
+		xc_error_hypercall(hypercall, ret);
+		xc_error_dom_set(domid, "shutdown %d", reason);
+	}
+	munlock(&arg, sizeof(arg));
+	return ret;
+}
+
+int xc_vcpu_setaffinity(int handle, unsigned int domid, int vcpu,
+                        uint64_t cpumap)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_setvcpuaffinity, domid);
+	domctl.u.vcpuaffinity.vcpu = vcpu;
+	domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8;
+
+	set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, (uint8_t *) &cpumap);
+
+	if (mlock(&cpumap, sizeof(cpumap)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "vcpu %d set affinity", vcpu);
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "vcpu %d set affinity", vcpu);
+	munlock(&cpumap, sizeof(cpumap));
+	return ret;
+}
+
+int xc_vcpu_getaffinity(int handle, unsigned int domid, int vcpu,
+                        uint64_t *cpumap)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_getvcpuaffinity, domid);
+	domctl.u.vcpuaffinity.vcpu = vcpu;
+	domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(*cpumap) * 8;
+
+	set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, cpumap);
+
+	if (mlock(cpumap, sizeof(*cpumap)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "vcpu %d get affinity", vcpu);
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "vcpu %d get affinity", vcpu);
+	munlock(cpumap, sizeof(*cpumap));
+	return ret;
+}
+
+int xc_vcpu_context_get(int handle, unsigned int domid, unsigned short vcpu,
+                        struct vcpu_guest_context *ctxt)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_getvcpucontext, domid);
+	domctl.u.vcpucontext.vcpu = vcpu;
+
+	set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
+
+	if (mlock(ctxt, sizeof(struct vcpu_guest_context)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "vcpu %d get context", vcpu);
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "vcpu %d get context", vcpu);
+	munlock(ctxt, sizeof(struct vcpu_guest_context));
+
+	return ret;
+}
+
+int xc_domain_getinfolist(int handle, unsigned int first_domain,
+                          unsigned int max_domains, xc_domaininfo_t *info)
+{
+	int ret;
+	DECLARE_SYSCTL(XEN_SYSCTL_getdomaininfolist);
+	sysctl.u.getdomaininfolist.first_domain = first_domain;
+	sysctl.u.getdomaininfolist.max_domains = max_domains;
+	set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info);
+
+	if (mlock(info, max_domains * sizeof(xc_domaininfo_t)) != 0) {
+		xc_error_set("getinfolist(%d, %u, %u, %x (%d)) failed: mlock failed: %s",
+			     handle, first_domain, max_domains, info, sizeof(xc_domaininfo_t),
+		             strerror(errno));
+		return -1;
+	}
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret < 0)
+		xc_error_set("getinfolist(%d, %u, %u, %x (%d)) failed: %s", 
+			     handle, first_domain, max_domains, info, sizeof(xc_domaininfo_t),
+			     xc_error_get());
+	else
+		ret = sysctl.u.getdomaininfolist.num_domains;
+
+	munlock(info, max_domains * sizeof(xc_domaininfo_t));
+	return ret;
+}
+
+int xc_domain_getinfo(int handle, unsigned int domid, xc_domaininfo_t *info)
+{
+	int ret;
+	ret = xc_domain_getinfolist(handle, domid, 1, info);
+	if (ret != 1) {
+		xc_error_set("getinfo failed: domain %d: %s", domid, xc_error_get());
+		return -1;
+	}
+
+	/* If the requested domain didn't exist but there exists one with a 
+	   higher domain ID, this will be returned. We consider this an error since
+	   we only wanted info about a specific domain. */
+	if (info->domain != domid) {
+		xc_error_set("getinfo failed: domain %d nolonger exists", domid);
+		return -1;
+	}
+
+	return 0;
+}
+
+int xc_domain_setmaxmem(int handle, unsigned int domid, unsigned int max_memkb)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_max_mem, domid);
+	domctl.u.max_mem.max_memkb = max_memkb;
+	int ret;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "set max memory to %u", max_memkb);
+	return ret;
+}
+
+int xc_domain_set_memmap_limit(int handle, unsigned int domid,
+                               unsigned long map_limitkb)
+{
+	int ret;
+	struct xen_foreign_memory_map fmap = {
+		.domid = domid,
+		.map = { .nr_entries = 1 }
+	};
+	struct e820entry e820 = {
+		.addr = 0,
+		.size = (uint64_t)map_limitkb << 10,
+		.type = E820_RAM
+	};
+	DECLARE_HYPERCALL2(__HYPERVISOR_memory_op, XENMEM_set_memory_map, &fmap);
+
+	set_xen_guest_handle(fmap.map.buffer, &e820);
+
+	if (mlock(&fmap, sizeof(fmap)) != 0) {
+		xc_error_set("set_memmap_limit failed: mlock failed: %s",
+		             strerror(errno));
+		return -1;
+	}
+
+	if (mlock(&e820, sizeof(e820)) != 0) {
+		xc_error_set("set_memmap_limit failed: mlock failed: %s",
+		             strerror(errno));
+		munlock(&fmap, sizeof(fmap));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret)
+		xc_error_hypercall(hypercall, ret);
+
+	munlock(&e820, sizeof(e820));
+	munlock(&fmap, sizeof(fmap));
+	return ret;
+}
+
+int xc_domain_set_time_offset(int handle, unsigned int domid, int time_offset)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_settimeoffset, domid);
+	domctl.u.settimeoffset.time_offset_seconds = time_offset;
+	int ret;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "set time offset %d", time_offset);
+	return ret;
+}
+
+int xc_domain_memory_increase_reservation(int handle, unsigned int domid,
+                                          unsigned long nr_extents,
+                                          unsigned int extent_order,
+                                          unsigned int address_bits,
+                                          xen_pfn_t *extent_start)
+{
+	int ret;
+	struct xen_memory_reservation reservation = {
+		.nr_extents   = nr_extents,
+		.extent_order = extent_order,
+		.COMPAT_FIELD_ADDRESS_BITS = address_bits,
+		.domid        = domid
+	};
+
+	set_xen_guest_handle(reservation.extent_start, extent_start);
+
+	ret = do_memctl_reservation(handle, XENMEM_increase_reservation,
+	                            &reservation);
+	if (ret != nr_extents) {
+		xc_error_dom_set(domid, "increase reservation to %lu",
+		                 nr_extents);
+		return (ret >= 0) ? -1 : ret;
+	}
+	return 0;
+}
+
+int xc_domain_memory_decrease_reservation(int handle, unsigned int domid,
+                                          unsigned long nr_extents,
+                                          unsigned int extent_order,
+                                          unsigned int address_bits,
+                                          xen_pfn_t *extent_start)
+{
+	int ret;
+	struct xen_memory_reservation reservation = {
+		.nr_extents   = nr_extents,
+		.extent_order = extent_order,
+		.COMPAT_FIELD_ADDRESS_BITS = 0,
+		.domid        = domid
+	};
+
+	set_xen_guest_handle(reservation.extent_start, extent_start);
+	if (!extent_start) {
+		xc_error_set("decrease reservation: extent start is NULL");
+		return -EINVAL;
+	}
+
+	ret = do_memctl_reservation(handle, XENMEM_decrease_reservation,
+	                            &reservation);
+	if (ret < nr_extents) {
+		xc_error_dom_set(domid, "decrease reservation to %lu",
+		                 nr_extents);
+		return (ret >= 0) ? -1 : ret;
+	}
+	return 0;
+}
+
+int xc_domain_memory_populate_physmap(int handle, unsigned int domid,
+                                      unsigned long nr_extents,
+                                      unsigned int extent_order,
+                                      unsigned int address_bits,
+                                      xen_pfn_t *extent_start)
+{
+	int ret;
+	struct xen_memory_reservation reservation = {
+		.nr_extents   = nr_extents,
+		.extent_order = extent_order,
+		.COMPAT_FIELD_ADDRESS_BITS = address_bits,
+		.domid        = domid
+	};
+
+	set_xen_guest_handle(reservation.extent_start, extent_start);
+	ret = do_memctl_reservation(handle, XENMEM_populate_physmap,
+	                            &reservation);
+	if (ret < nr_extents) {
+		xc_error_dom_set(domid, "populate physmap");
+		return (ret >= 0) ? -1 : ret;
+	}
+	return 0;
+}
+
+int xc_domain_setvmxassist(int handle, unsigned int domid, int use_vmxassist)
+{
+	int ret = 0;
+#ifdef XEN_DOMCTL_setvmxassist
+	DECLARE_DOMCTL(XEN_DOMCTL_setvmxassist, domid);
+	domctl.u.setvmxassist.use_vmxassist = use_vmxassist;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "setting vmxassist to %d",
+				 use_vmxassist);
+#endif
+	return ret;
+}
+
+int xc_domain_max_vcpus(int handle, unsigned int domid, unsigned int max)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_max_vcpus, domid);
+	domctl.u.max_vcpus.max = max;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "setting max vcpus to %d", max);
+	return ret;
+}
+
+int xc_domain_sethandle(int handle, unsigned int domid,
+                        xen_domain_handle_t dhandle)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_setdomainhandle, domid);
+	memcpy(domctl.u.setdomainhandle.handle, dhandle, sizeof(xen_domain_handle_t));
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "set handle");
+	return ret;
+}
+
+int xc_vcpu_getinfo(int handle, unsigned int domid, unsigned int vcpu,
+                    xc_vcpuinfo_t *info)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_getvcpuinfo, domid);
+	domctl.u.getvcpuinfo.vcpu = vcpu;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0) {
+		xc_error_dom_set(domid, "vcpu %u getinfo", vcpu);
+		return ret;
+	}
+	memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info));
+	return ret;
+}
+
+int xc_domain_ioport_permission(int handle, unsigned int domid,
+                                unsigned int first_port, unsigned int nr_ports,
+                                unsigned int allow_access)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_ioport_permission, domid);
+	domctl.u.ioport_permission.first_port = first_port;
+	domctl.u.ioport_permission.nr_ports = nr_ports;
+	domctl.u.ioport_permission.allow_access = allow_access;
+
+	return do_domctl(handle, &domctl);
+}
+
+int xc_vcpu_getcontext(int handle, unsigned int domid,
+                       unsigned int vcpu, vcpu_guest_context_any_t *ctxt)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_getvcpucontext, domid);
+	domctl.u.vcpucontext.vcpu = vcpu;
+	set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
+
+	if (mlock(ctxt, sizeof(*ctxt)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "vcpu %u getcontext", vcpu);
+	munlock(ctxt, sizeof(*ctxt));
+	return ret;
+}
+
+int xc_vcpu_setcontext(int handle, unsigned int domid,
+                       unsigned int vcpu, vcpu_guest_context_any_t *ctxt)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_setvcpucontext, domid);
+	domctl.u.vcpucontext.vcpu = vcpu;
+	set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
+
+	if (mlock(ctxt, sizeof(*ctxt)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "vcpu %u setcontext", vcpu);
+
+	munlock(ctxt, sizeof(*ctxt));
+	return ret;
+}
+
+int xc_domain_irq_permission(int handle, unsigned int domid,
+                             unsigned char pirq, unsigned char allow_access)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_irq_permission, domid);
+	domctl.u.irq_permission.pirq = pirq;
+	domctl.u.irq_permission.allow_access = allow_access;
+	int ret;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "irq permission %u to %u",
+		                 pirq, allow_access);
+	return ret;
+}
+
+int xc_domain_iomem_permission(int handle, unsigned int domid,
+                               unsigned long first_mfn, unsigned long nr_mfns,
+                               unsigned char allow_access)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_iomem_permission, domid);
+	domctl.u.iomem_permission.first_mfn = first_mfn;
+	domctl.u.iomem_permission.nr_mfns = nr_mfns;
+	domctl.u.iomem_permission.allow_access = allow_access;
+	int ret;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret)
+		xc_error_dom_set(domid, "iomem permission [%lu, %lu] to %u",
+		                 first_mfn, first_mfn + nr_mfns, allow_access);
+	return ret;
+}
+
+long long xc_domain_get_cpu_usage(int handle, unsigned int domid,
+                                  unsigned int vcpu)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_getvcpuinfo, domid);
+	domctl.u.getvcpuinfo.vcpu = vcpu;
+
+	if (do_domctl(handle, &domctl) < 0) {
+		xc_error_dom_set(domid, "get cpu %d usage", vcpu);
+		return -1;
+	}
+	return domctl.u.getvcpuinfo.cpu_time;
+}
+
+void *xc_map_foreign_range(int handle, unsigned int domid,
+                           int size, int prot, unsigned long mfn)
+{
+	privcmd_mmap_entry_t entry = {
+		.mfn = mfn,
+		.npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT,
+	};
+	privcmd_mmap_t ioctlx = {
+		.num = 1,
+		.dom = domid,
+		.entry = &entry,
+	};
+	void *addr;
+
+	addr = do_mmap(NULL, size, prot, MAP_SHARED, handle, 0);
+	if (addr == MAP_FAILED) {
+		xc_error_set("mmap failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "map foreign range [%lx,%lx] prot %u",
+		                 mfn, mfn + size, prot);
+		return NULL;
+	}
+	entry.va = (unsigned long) addr;
+	if (do_ioctl(handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0) {
+		xc_error_set("ioctl failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "map foreign range [%lx,%lx] prot %u",
+		                 mfn, mfn + size, prot);
+		munmap(addr, size);
+		return NULL;
+	}
+	return addr;
+}
+
+int xc_map_foreign_ranges(int handle, unsigned int domid,
+                          privcmd_mmap_entry_t *entries, int nr)
+{
+	privcmd_mmap_t ioctlx = {
+		.num = nr,
+		.dom = domid,
+		.entry = entries,
+	};
+	int ret;
+
+	ret = do_ioctl(handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
+	if (ret < 0) {
+		xc_error_set("ioctl failed: %s", strerror(errno));
+		xc_error_dom_set(domid, "map foreign ranges");
+		return -1;
+	}
+	return ret;
+}
+
+int xc_readconsolering(int handle, char **pbuffer,
+                       unsigned int *pnr_chars, int clear)
+{
+	int ret;
+	DECLARE_SYSCTL(XEN_SYSCTL_readconsole);
+	char *buffer = *pbuffer;
+	unsigned int nr_chars = *pnr_chars;
+
+	set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer);
+	sysctl.u.readconsole.count = nr_chars;
+	sysctl.u.readconsole.clear = clear;
+
+	if (mlock(buffer, nr_chars) != 0) {
+		xc_error_set("read console ring: mlock failed: %s",
+		             strerror(errno));
+		return -1;
+	}
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret != 0)
+		xc_error_set("read console ring failed: %s", xc_error_get());
+	else
+		*pnr_chars = sysctl.u.readconsole.count;
+
+	munlock(buffer, nr_chars);
+	return ret;
+}
+
+int xc_send_debug_keys(int handle, char *keys)
+{
+	int ret;
+	DECLARE_SYSCTL(XEN_SYSCTL_debug_keys);
+
+	set_xen_guest_handle(sysctl.u.debug_keys.keys, keys);
+	sysctl.u.debug_keys.nr_keys = strlen(keys);
+
+	if (mlock(keys, sysctl.u.debug_keys.nr_keys) != 0) {
+		xc_error_set("send debug keys: mlock failed: %s",
+		             strerror(errno));
+		return -1;
+	}
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret != 0)
+		xc_error_set("send debug keys: %s", xc_error_get());
+
+	munlock(keys, sysctl.u.debug_keys.nr_keys);
+	return ret;
+}
+
+int xc_physinfo(int handle, xc_physinfo_t *put_info)
+{
+	DECLARE_SYSCTL(XEN_SYSCTL_physinfo);
+	int ret;
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret) {
+		xc_error_set("physinfo failed: %s", xc_error_get());
+		return ret;
+	}
+	memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info));
+	return 0;
+}
+
+int xc_pcpu_info(int handle, int max_cpus, uint64_t *info, int *nr_cpus)
+{
+	DECLARE_SYSCTL(XEN_SYSCTL_getcpuinfo);
+	int ret;
+
+	sysctl.u.getcpuinfo.max_cpus = max_cpus;
+	set_xen_guest_handle(sysctl.u.getcpuinfo.info, info);
+
+	if (mlock(info, sizeof(*info) * max_cpus) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret)
+		xc_error_set("pcpu info failed: %s", xc_error_get());
+	else if (ret == 0 && nr_cpus)
+		*nr_cpus = sysctl.u.getcpuinfo.nr_cpus;
+	munlock(info, sizeof(*info) * max_cpus);
+	return ret;
+}
+
+int xc_sched_id(int handle, int *sched_id)
+{
+	DECLARE_SYSCTL(XEN_SYSCTL_sched_id);
+	int ret;
+
+	ret = do_sysctl(handle, &sysctl);
+	if (ret) {
+		xc_error_set("sched id failed: %s", xc_error_get());
+		return ret;
+	}
+	*sched_id = sysctl.u.sched_id.sched_id;
+	return 0;
+}
+
+int xc_version(int handle, int cmd, void *arg)
+{
+	int argsize;
+	int ret;
+	DECLARE_HYPERCALL2(__HYPERVISOR_xen_version, cmd, arg);
+
+	switch (cmd) {
+	case XENVER_extraversion:
+		argsize = sizeof(xen_extraversion_t); break;
+	case XENVER_compile_info:
+		argsize = sizeof(xen_compile_info_t); break;
+	case XENVER_capabilities:
+		argsize = sizeof(xen_capabilities_info_t); break;
+	case XENVER_changeset:
+		argsize = sizeof(xen_changeset_info_t); break;
+	case XENVER_platform_parameters:
+		argsize = sizeof(xen_platform_parameters_t); break;
+	case XENVER_version:
+		argsize = 0; break;
+	default:
+		xc_error_set("version: unknown command");
+		return -1;
+	}
+	if (argsize && mlock(arg, argsize) == -1) {
+		xc_error_set("version: mlock failed: %s", strerror(errno));
+		return -ENOMEM;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret)
+		xc_error_hypercall(hypercall, ret);
+
+	if (argsize)
+		munlock(arg, argsize);
+	return ret;
+}
+
+int xc_evtchn_alloc_unbound(int handle, unsigned int domid,
+                            unsigned int remote_domid)
+{
+	struct evtchn_alloc_unbound arg = {
+		.dom = domid,
+		.remote_dom = remote_domid,
+	};
+	int ret;
+
+	ret = do_evtchnctl(handle, EVTCHNOP_alloc_unbound, &arg, sizeof(arg));
+	if (ret) {
+		xc_error_dom_set(domid, "alloc unbound evtchn to %d",
+		                 remote_domid);
+		return ret;
+	}
+	return arg.port;
+}
+
+int xc_evtchn_reset(int handle, unsigned int domid)
+{
+	struct evtchn_reset arg = {
+		.dom = domid,
+	};
+	int ret;
+
+	ret = do_evtchnctl(handle, EVTCHNOP_reset, &arg, sizeof(arg));
+	if (ret)
+		xc_error_dom_set(domid, "reset evtchn of %d", domid);
+	return ret;
+}
+
+int xc_sched_credit_domain_set(int handle, unsigned int domid,
+                               struct xen_domctl_sched_credit *sdom)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_scheduler_op, domid);
+	domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT;
+	domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo;
+	domctl.u.scheduler_op.u.credit = *sdom;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "credit scheduler domain set");
+	return ret;
+}
+
+int xc_sched_credit_domain_get(int handle, unsigned int domid,
+                               struct xen_domctl_sched_credit *sdom)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_scheduler_op, domid);
+
+	domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT;
+	domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "credit scheduler domain get");
+	else
+		*sdom = domctl.u.scheduler_op.u.credit;
+	return ret;
+}
+
+int xc_shadow_allocation_get(int handle, unsigned int domid, uint32_t *mb)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_shadow_op, domid);
+
+	domctl.u.shadow_op.op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "shadow allocation get");
+	else
+		*mb = domctl.u.shadow_op.mb;
+	return ret;
+}
+
+int xc_shadow_allocation_set(int handle, unsigned int domid, uint32_t mb)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_shadow_op, domid);
+
+	domctl.u.shadow_op.op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
+	domctl.u.shadow_op.mb = mb;
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "shadow allocation set");
+	return ret;
+}
+
+int xc_domain_get_pfn_list(int handle, unsigned int domid,
+                           xen_pfn_t *pfn_array, unsigned long max_pfns)
+{
+	int ret;
+	DECLARE_DOMCTL(XEN_DOMCTL_getmemlist, domid);
+
+	domctl.u.getmemlist.max_pfns = max_pfns;
+	set_xen_guest_handle(domctl.u.getmemlist.buffer, pfn_array);
+
+	if (mlock(pfn_array, max_pfns * sizeof(xen_pfn_t)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "get pfn list");
+
+	munlock(pfn_array, max_pfns * sizeof(xen_pfn_t));
+	return (ret < 0) ? ret : domctl.u.getmemlist.num_pfns;
+}
+
+#define MARSHALL_BDF(d,b,s,f) \
+	(((b) & 0xff) << 16 | ((s) & 0x1f) << 11 | ((f) & 0x7) << 8)
+
+int xc_domain_assign_device(int handle, unsigned int domid,
+                            int domain, int bus, int slot, int func)
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_assign_device
+	DECLARE_DOMCTL(XEN_DOMCTL_assign_device, domid);
+
+	domctl.u.assign_device.machine_bdf = MARSHALL_BDF(domain, bus, slot, func);
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "assign device");
+#endif
+	return ret;
+}
+
+int xc_domain_deassign_device(int handle, unsigned int domid,
+                              int domain, int bus, int slot, int func)
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_deassign_device
+	DECLARE_DOMCTL(XEN_DOMCTL_deassign_device, domid);
+
+	domctl.u.assign_device.machine_bdf = MARSHALL_BDF(domain, bus, slot, func);
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "deassign device");
+#endif
+	return ret;
+}
+
+int xc_domain_test_assign_device(int handle, unsigned int domid,
+                                 int domain, int bus, int slot, int func)
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_test_assign_device
+	DECLARE_DOMCTL(XEN_DOMCTL_test_assign_device, domid);
+	domctl.u.assign_device.machine_bdf = MARSHALL_BDF(domain, bus, slot, func);
+
+	ret = do_domctl(handle, &domctl);
+	if (ret < 0)
+		xc_error_dom_set(domid, "test assign device");
+#endif
+	return ret;
+}
+
+int xc_domain_watchdog(int handle, int id, uint32_t timeout)
+{
+	int ret = -EBADF;
+#ifdef SCHEDOP_watchdog
+	sched_watchdog_t arg = {
+		.id = (uint32_t) id,
+		.timeout = timeout,
+	};
+	DECLARE_HYPERCALL2(__HYPERVISOR_sched_op, SCHEDOP_watchdog, &arg);
+
+	if (mlock(&arg, sizeof(arg)) != 0) {
+		xc_error_set("mlock failed: %s", strerror(errno));
+		return -1;
+	}
+
+	ret = do_xen_hypercall(handle, &hypercall);
+	if (ret < 0) {
+		xc_error_hypercall(hypercall, ret);
+	}
+	munlock(&arg, sizeof(arg));
+#endif
+	return ret;
+}
+
+int xc_domain_set_machine_address_size(int xc, uint32_t domid, unsigned int width)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_set_machine_address_size, domid);
+	int rc;
+
+	domctl.u.address_size.size = width;
+	rc = do_domctl(xc, &domctl);
+	if (rc != 0)
+		xc_error_dom_set(domid, "set machine address size");
+
+	return rc;
+}
+
+int xc_domain_get_machine_address_size(int xc, uint32_t domid)
+{
+	DECLARE_DOMCTL(XEN_DOMCTL_get_machine_address_size, domid);
+	int rc;
+
+	rc = do_domctl(xc, &domctl);
+	if (rc != 0)
+		xc_error_dom_set(domid, "get machine address size");
+	return rc == 0 ? domctl.u.address_size.size : rc;
+}
+
+#include "xc_cpuid.h"
+int xc_domain_cpuid_set(int xc, unsigned int domid, int hvm,
+                        uint32_t input, uint32_t oinput,
+                        char *config[4], char *config_out[4])
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_set_cpuid
+	DECLARE_DOMCTL(XEN_DOMCTL_set_cpuid, domid);
+	uint32_t regs[4], polregs[4];
+	int i, j;
+
+	xc_cpuid(input, oinput, regs);
+	memcpy(polregs, regs, sizeof(regs));
+	do_cpuid_policy(xc, domid, hvm, input, polregs);
+
+	for (i = 0; i < 4; i++) {
+		if (!config[i]) {
+			regs[i] = polregs[i];
+			continue;
+		}
+		
+		for (j = 0; j < 32; j++) {
+			unsigned char val, polval;
+
+			val = !!((regs[i] & (1U << (31 - j))));
+			polval = !!((regs[i] & (1U << (31 - j))));
+
+			switch (config[i][j]) {
+			case '1': val = 1; break; /* force to true */
+			case '0': val = 0; break; /* force to false */
+			case 'x': val = polval; break;
+			case 'k': case 's': break;
+			default:
+				xc_error_dom_set(domid, "domain cpuid set: invalid config");
+				ret = -EINVAL;
+				goto out;
+			}
+
+			if (val)
+				set_bit(31 - j, regs[i]);
+			else
+				clear_bit(31 - j, regs[i]);
+
+			if (config_out && config_out[i]) {
+				config_out[i][j] = (config[i][j] == 's')
+				                   ? '0' + val
+						   : config[i][j];
+			}
+		}
+	}
+
+	domctl.u.cpuid.input[0] = input;
+	domctl.u.cpuid.input[1] = oinput;
+	domctl.u.cpuid.eax = regs[0];
+	domctl.u.cpuid.ebx = regs[1];
+	domctl.u.cpuid.ecx = regs[2];
+	domctl.u.cpuid.edx = regs[3];
+	ret = do_domctl(xc, &domctl);
+	if (ret) {
+		xc_error_dom_set(domid, "cpuid set");
+		goto out;
+	}
+out:
+#endif
+	return ret;
+}
+
+int xc_domain_cpuid_apply(int xc, unsigned int domid, int hvm)
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_set_cpuid
+	uint32_t regs[4], base_max, ext_max, eax, ecx;
+
+	/* determinate cpuid range */
+	xc_cpuid(0, 0, regs);
+	base_max = MIN(regs[0], DEF_MAX_BASE);
+	xc_cpuid(0x80000000, 0, regs);
+	ext_max = MIN(regs[0], DEF_MAX_EXT);
+
+	eax = ecx = 0;
+	while (!(eax & 0x80000000) || (eax <= ext_max)) {
+		xc_cpuid(eax, ecx, regs);
+
+		do_cpuid_policy(xc, domid, hvm, eax, regs);
+		
+		if (regs[0] || regs[1] || regs[2] || regs[3]) {
+			DECLARE_DOMCTL(XEN_DOMCTL_set_cpuid, domid);
+			
+			domctl.u.cpuid.input[0] = eax;
+			domctl.u.cpuid.input[1] = (eax == 4) ? ecx : XEN_CPUID_INPUT_UNUSED;
+			domctl.u.cpuid.eax = regs[0];
+			domctl.u.cpuid.ebx = regs[1];
+			domctl.u.cpuid.ecx = regs[2];
+			domctl.u.cpuid.edx = regs[3];
+
+			ret = do_domctl(xc, &domctl);
+			if (ret) {
+				xc_error_dom_set(domid, "cpuid apply");
+				goto out;
+			}
+
+			/* we repeat when doing node 4 (cache descriptor leaves) increasing ecx 
+			 * until the cpuid eax value masked is 0 */
+			if (eax == 4) {
+				ecx++;
+				if ((regs[0] & 0x1f) != 0)
+					continue;
+				ecx = 0;
+			}
+		}
+
+		eax++;
+		if (!(eax & 0x80000000) && (eax > base_max))
+			eax = 0x80000000;
+	}
+	ret = 0;
+out:
+#endif
+	return ret;
+}
+
+/*
+ * return 1 on checking success 
+ *        0 on checking failure
+ *        -EINVAL if the config contains unknown character
+ */
+int xc_cpuid_check(uint32_t input, uint32_t optsubinput,
+                   char *config[4], char *config_out[4])
+{
+	int ret = -EBADF;
+#ifdef XEN_DOMCTL_set_cpuid
+	uint32_t regs[4];
+	int i, j;
+
+	xc_cpuid(input, optsubinput, regs);
+
+	ret = 1;
+	for (i = 0; i < 4; i++) {
+		if (!config[i])
+			continue;
+		for (j = 0; j < 32; j++) {
+			unsigned char val;
+
+			val = !!((regs[i] & (1U << (31 - j))));
+
+			switch (config[i][j]) {
+			case '1': if (!val) { ret = 0; goto out; }; break;
+			case '0': if (val) { ret = 0; goto out; }; break;
+			case 'x': case 's': break;
+			default:
+				xc_error_set("cpuid check: invalid config");
+				ret = -EINVAL;
+				goto out;
+			}
+
+			if (config_out && config_out[i]) {
+				config_out[i][j] = (config[i][j] == 's')
+				                   ? '0' + val
+						   : config[i][j];
+			}
+		}
+	} 
+out:
+#endif
+	return ret;
+}
+
+#ifndef HVM_PARAM_HPET_ENABLED
+#define HVM_PARAM_HPET_ENABLED 11
+#endif
+
+#ifndef HVM_PARAM_ACPI_S_STATE
+#define HVM_PARAM_ACPI_S_STATE 14
+#endif
+
+#ifndef HVM_PARAM_VPT_ALIGN
+#define HVM_PARAM_VPT_ALIGN 16
+#endif
+
+int xc_domain_send_s3resume(int handle, unsigned int domid)
+{
+	return xc_set_hvm_param(handle, domid, HVM_PARAM_ACPI_S_STATE, 0);
+}
+
+int xc_domain_set_timer_mode(int handle, unsigned int domid, int mode)
+{
+	return xc_set_hvm_param(handle, domid,
+	                        HVM_PARAM_TIMER_MODE, (unsigned long) mode);
+}
+
+int xc_domain_set_hpet(int handle, unsigned int domid, int hpet)
+{
+	return xc_set_hvm_param(handle, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) hpet);
+}
+
+int xc_domain_set_vpt_align(int handle, unsigned int domid, int vpt_align)
+{
+	return xc_set_hvm_param(handle, domid, HVM_PARAM_HPET_ENABLED, (unsigned long) vpt_align);
+}
+
+int xc_domain_get_acpi_s_state(int handle, unsigned int domid)
+{
+	int ret;
+	unsigned long value;
+
+	ret = xc_get_hvm_param(handle, domid, HVM_PARAM_ACPI_S_STATE, &value);
+	if (ret != 0)
+		xc_error_dom_set(domid, "get acpi s-state");
+	return value;
+}
diff --git a/tools/ocaml/libs/xc/xc_stubs.c b/tools/ocaml/libs/xc/xc_stubs.c
new file mode 100644
index 0000000..b43a750
--- /dev/null
+++ b/tools/ocaml/libs/xc/xc_stubs.c
@@ -0,0 +1,1170 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#define _XOPEN_SOURCE 600
+#include <stdlib.h>
+
+#define CAML_NAME_SPACE
+#include <caml/alloc.h>
+#include <caml/memory.h>
+#include <caml/signals.h>
+#include <caml/fail.h>
+#include <caml/callback.h>
+
+#include <sys/mman.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "xc.h"
+
+#include "mmap_stubs.h"
+
+#define PAGE_SHIFT		12
+#define PAGE_SIZE               (1UL << PAGE_SHIFT)
+#define PAGE_MASK               (~(PAGE_SIZE-1))
+
+#define _H(__h) (Int_val(__h))
+#define _D(__d) ((uint32_t)Int_val(__d))
+
+#define Val_none (Val_int(0))
+
+#define string_of_option_array(array, index) \
+	((Field(array, index) == Val_none) ? NULL : String_val(Field(Field(array, index), 0)))
+
+/* maybe here we should check the range of the input instead of blindly
+ * casting it to uint32 */
+#define cpuid_input_of_val(i1, i2, input) \
+	i1 = (uint32_t) Int64_val(Field(input, 0)); \
+	i2 = ((Field(input, 1) == Val_none) ? 0xffffffff : (uint32_t) Int64_val(Field(Field(input, 1), 0)));
+
+/**
+ * Convert the given number of pages to an amount in MiB, rounded up.
+ */
+void failwith_xc(void)
+{
+	caml_raise_with_string(*caml_named_value("xc.error"), xc_error_get());
+}
+
+CAMLprim value stub_sizeof_core_header(value unit)
+{
+	CAMLparam1(unit);
+	CAMLreturn(Val_int(sizeof(struct xc_core_header)));
+}
+
+CAMLprim value stub_sizeof_vcpu_guest_context(value unit)
+{
+	CAMLparam1(unit);
+	CAMLreturn(Val_int(sizeof(struct vcpu_guest_context)));
+}
+
+CAMLprim value stub_sizeof_xen_pfn(value unit)
+{
+	CAMLparam1(unit);
+	CAMLreturn(Val_int(sizeof(xen_pfn_t)));
+}
+
+#define XC_CORE_MAGIC     0xF00FEBED
+#define XC_CORE_MAGIC_HVM 0xF00FEBEE
+
+CAMLprim value stub_marshall_core_header(value header)
+{
+	CAMLparam1(header);
+	CAMLlocal1(s);
+	struct xc_core_header c_header;
+
+	c_header.xch_magic = (Field(header, 0))
+		? XC_CORE_MAGIC
+		: XC_CORE_MAGIC_HVM;
+	c_header.xch_nr_vcpus = Int_val(Field(header, 1));
+	c_header.xch_nr_pages = Nativeint_val(Field(header, 2));
+	c_header.xch_ctxt_offset = Int64_val(Field(header, 3));
+	c_header.xch_index_offset = Int64_val(Field(header, 4));
+	c_header.xch_pages_offset = Int64_val(Field(header, 5));
+
+	s = caml_alloc_string(sizeof(c_header));
+	memcpy(String_val(s), (char *) &c_header, sizeof(c_header));
+	CAMLreturn(s);
+}
+
+CAMLprim value stub_xc_interface_open()
+{
+        int handle;
+        handle = xc_interface_open();
+        if (handle == -1)
+		failwith_xc();
+        return Val_int(handle);
+}
+
+
+CAMLprim value stub_xc_interface_open_fake()
+{
+	return Val_int(-1);
+}
+
+CAMLprim value stub_xc_using_injection()
+{
+	if (xc_using_injection ()){
+		return Val_int(1);
+	} else {
+		return Val_int(0);
+	}
+}
+
+CAMLprim value stub_xc_interface_close(value xc_handle)
+{
+	CAMLparam1(xc_handle);
+
+	int handle = _H(xc_handle);
+	// caml_enter_blocking_section();
+	xc_interface_close(handle);
+	// caml_leave_blocking_section();
+
+	CAMLreturn(Val_unit);
+}
+
+static int domain_create_flag_table[] = {
+	XEN_DOMCTL_CDF_hvm_guest,
+	XEN_DOMCTL_CDF_hap,
+};
+
+CAMLprim value stub_xc_domain_create(value xc_handle, value ssidref,
+                                     value flags, value handle)
+{
+	CAMLparam4(xc_handle, ssidref, flags, handle);
+
+	uint32_t domid = 0;
+	xen_domain_handle_t h = { 0 };
+	int result;
+	int i;
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_ssidref = Int32_val(ssidref);
+	unsigned int c_flags = 0;
+	value l;
+
+        if (Wosize_val(handle) != 16)
+		caml_invalid_argument("Handle not a 16-integer array");
+
+	for (i = 0; i < sizeof(h); i++) {
+		h[i] = Int_val(Field(handle, i)) & 0xff;
+	}
+
+	for (l = flags; l != Val_none; l = Field(l, 1)) {
+		int v = Int_val(Field(l, 0));
+		c_flags |= domain_create_flag_table[v];
+	}
+
+	// caml_enter_blocking_section();
+	result = xc_domain_create(c_xc_handle, c_ssidref, h, c_flags, &domid);
+	// caml_leave_blocking_section();
+
+	if (result < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_int(domid));
+}
+
+CAMLprim value stub_xc_domain_setvmxassist(value xc_handle, value domid,
+					    value use_vmxassist)
+{
+	CAMLparam3(xc_handle, domid, use_vmxassist);
+	int r;
+
+	r = xc_domain_setvmxassist(_H(xc_handle), _D(domid),
+				   Bool_val(use_vmxassist));
+	if (r)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_max_vcpus(value xc_handle, value domid,
+                                        value max_vcpus)
+{
+	CAMLparam3(xc_handle, domid, max_vcpus);
+	int r;
+
+	r = xc_domain_max_vcpus(_H(xc_handle), _D(domid), Int_val(max_vcpus));
+	if (r)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+
+value stub_xc_domain_sethandle(value xc_handle, value domid, value handle)
+{
+	CAMLparam3(xc_handle, domid, handle);
+	xen_domain_handle_t h = { 0 };
+	int i;
+
+        if (Wosize_val(handle) != 16)
+		caml_invalid_argument("Handle not a 16-integer array");
+
+	for (i = 0; i < sizeof(h); i++) {
+		h[i] = Int_val(Field(handle, i)) & 0xff;
+	}
+
+	i = xc_domain_sethandle(_H(xc_handle), _D(domid), h);
+	if (i)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+static value dom_op(value xc_handle, value domid, int (*fn)(int, uint32_t))
+{
+	CAMLparam2(xc_handle, domid);
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_domid = _D(domid);
+
+	// caml_enter_blocking_section();
+	int result = fn(c_xc_handle, c_domid);
+	// caml_leave_blocking_section();
+        if (result)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_pause(value xc_handle, value domid)
+{
+	return dom_op(xc_handle, domid, xc_domain_pause);
+}
+
+
+CAMLprim value stub_xc_domain_unpause(value xc_handle, value domid)
+{
+	return dom_op(xc_handle, domid, xc_domain_unpause);
+}
+
+CAMLprim value stub_xc_domain_destroy(value xc_handle, value domid)
+{
+	return dom_op(xc_handle, domid, xc_domain_destroy);
+}
+
+CAMLprim value stub_xc_domain_resume_fast(value xc_handle, value domid)
+{
+	return dom_op(xc_handle, domid, xc_domain_resume_fast);
+}
+
+CAMLprim value stub_xc_domain_shutdown(value handle, value domid, value reason)
+{
+	CAMLparam3(handle, domid, reason);
+	int ret;
+
+	ret = xc_domain_shutdown(_H(handle), _D(domid), Int_val(reason));
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+static value alloc_domaininfo(xc_domaininfo_t * info)
+{
+	CAMLparam0();
+	CAMLlocal2(result, tmp);
+	int i;
+
+	result = caml_alloc_tuple(16);
+
+	Store_field(result,  0, Val_int(info->domain));
+	Store_field(result,  1, Val_bool(info->flags & XEN_DOMINF_dying));
+	Store_field(result,  2, Val_bool(info->flags & XEN_DOMINF_shutdown));
+	Store_field(result,  3, Val_bool(info->flags & XEN_DOMINF_paused));
+	Store_field(result,  4, Val_bool(info->flags & XEN_DOMINF_blocked));
+	Store_field(result,  5, Val_bool(info->flags & XEN_DOMINF_running));
+	Store_field(result,  6, Val_bool(info->flags & XEN_DOMINF_hvm_guest));
+	Store_field(result,  7, Val_int((info->flags >> XEN_DOMINF_shutdownshift)
+	                                 & XEN_DOMINF_shutdownmask));
+	Store_field(result,  8, caml_copy_nativeint(info->tot_pages));
+	Store_field(result,  9, caml_copy_nativeint(info->max_pages));
+	Store_field(result, 10, caml_copy_int64(info->shared_info_frame));
+	Store_field(result, 11, caml_copy_int64(info->cpu_time));
+	Store_field(result, 12, Val_int(info->nr_online_vcpus));
+	Store_field(result, 13, Val_int(info->max_vcpu_id));
+	Store_field(result, 14, caml_copy_int32(info->ssidref));
+
+        tmp = caml_alloc_small(16, 0);
+	for (i = 0; i < 16; i++) {
+		Field(tmp, i) = Val_int(info->handle[i]);
+	}
+
+	Store_field(result, 15, tmp);
+
+	CAMLreturn(result);
+}
+
+CAMLprim value stub_xc_domain_getinfolist(value xc_handle, value first_domain, value nb)
+{
+	CAMLparam3(xc_handle, first_domain, nb);
+	CAMLlocal2(result, temp);
+	xc_domaininfo_t * info;
+	int i, ret, toalloc;
+
+	/* get the minimum number of allocate byte we need and bump it up to page boundary */
+	toalloc = (sizeof(xc_domaininfo_t) * Int_val(nb)) | 0xfff;
+	ret = posix_memalign((void **) ((void *) &info), 4096, toalloc);
+	if (ret)
+		caml_raise_out_of_memory();
+
+	result = temp = Val_emptylist;
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_first_domain = _D(first_domain);
+	unsigned int c_max_domains = Int_val(nb);
+	// caml_enter_blocking_section();
+	int retval = xc_domain_getinfolist(c_xc_handle, c_first_domain,
+					   c_max_domains, info);
+	// caml_leave_blocking_section();
+
+	if (retval < 0) {
+		free(info);
+		failwith_xc();
+	}
+	for (i = 0; i < retval; i++) {
+		result = caml_alloc_small(2, Tag_cons);
+		Field(result, 0) = Val_int(0);
+		Field(result, 1) = temp;
+		temp = result;
+
+		Store_field(result, 0, alloc_domaininfo(info + i));
+	}
+
+	free(info);
+	CAMLreturn(result);
+}
+
+CAMLprim value stub_xc_domain_getinfo(value xc_handle, value domid)
+{
+	CAMLparam2(xc_handle, domid);
+	CAMLlocal1(result);
+	xc_domaininfo_t info;
+	int ret;
+
+	ret = xc_domain_getinfo(_H(xc_handle), _D(domid), &info);
+	if (ret != 0)
+		failwith_xc();
+
+	result = alloc_domaininfo(&info);
+	CAMLreturn(result);
+}
+
+CAMLprim value stub_xc_vcpu_getinfo(value xc_handle, value domid, value vcpu)
+{
+	CAMLparam3(xc_handle, domid, vcpu);
+	CAMLlocal1(result);
+	xc_vcpuinfo_t info;
+	int retval;
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_domid = _D(domid);
+	uint32_t c_vcpu = Int_val(vcpu);
+	// caml_enter_blocking_section();
+	retval = xc_vcpu_getinfo(c_xc_handle, c_domid,
+	                         c_vcpu, &info);
+	// caml_leave_blocking_section();
+	if (retval < 0)
+		failwith_xc();
+
+	result = caml_alloc_tuple(5);
+	Store_field(result, 0, Val_bool(info.online));
+	Store_field(result, 1, Val_bool(info.blocked));
+	Store_field(result, 2, Val_bool(info.running));
+	Store_field(result, 3, caml_copy_int64(info.cpu_time));
+	Store_field(result, 4, caml_copy_int32(info.cpu));
+
+	CAMLreturn(result);
+}
+
+CAMLprim value stub_xc_vcpu_context_get(value xc_handle, value domid,
+                                        value cpu)
+{
+	CAMLparam3(xc_handle, domid, cpu);
+	CAMLlocal1(context);
+	int ret;
+	struct vcpu_guest_context ctxt;
+
+	ret = xc_vcpu_getcontext(_H(xc_handle), _D(domid), Int_val(cpu), &ctxt);
+
+	context = caml_alloc_string(sizeof(ctxt));
+	memcpy(String_val(context), (char *) &ctxt, sizeof(ctxt));
+
+	CAMLreturn(context);
+}
+
+CAMLprim value stub_xc_vcpu_setaffinity(value xc_handle, value domid,
+                                        value vcpu, value cpumap)
+{
+	CAMLparam4(xc_handle, domid, vcpu, cpumap);
+	uint64_t c_cpumap;
+	int retval;
+
+	c_cpumap = Int64_val(cpumap);
+	retval = xc_vcpu_setaffinity(_H(xc_handle), _D(domid),
+	                             Int_val(vcpu), c_cpumap);
+	if (retval < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_vcpu_getaffinity(value xc_handle, value domid,
+                                        value vcpu)
+{
+	CAMLparam3(xc_handle, domid, vcpu);
+	CAMLlocal1(ret);
+	uint64_t cpumap;
+	int retval;
+
+	retval = xc_vcpu_getaffinity(_H(xc_handle), _D(domid),
+	                             Int_val(vcpu), &cpumap);
+	if (retval < 0)
+		failwith_xc();
+	ret = caml_copy_int64(cpumap);
+	CAMLreturn(ret);
+}
+
+CAMLprim value stub_xc_sched_id(value xc_handle)
+{
+	CAMLparam1(xc_handle);
+	int sched_id;
+
+	if (xc_sched_id(_H(xc_handle), &sched_id))
+		failwith_xc();
+	CAMLreturn(Val_int(sched_id));
+}
+
+CAMLprim value stub_xc_evtchn_alloc_unbound(value xc_handle,
+                                            value local_domid,
+                                            value remote_domid)
+{
+	CAMLparam3(xc_handle, local_domid, remote_domid);
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_local_domid = _D(local_domid);
+	uint32_t c_remote_domid = _D(remote_domid);
+
+	// caml_enter_blocking_section();
+	int result = xc_evtchn_alloc_unbound(c_xc_handle, c_local_domid,
+	                                     c_remote_domid);
+	// caml_leave_blocking_section();
+
+	if (result < 0)
+		failwith_xc();
+	CAMLreturn(Val_int(result));
+}
+
+CAMLprim value stub_xc_evtchn_reset(value handle, value domid)
+{
+	CAMLparam2(handle, domid);
+	int r;
+
+	r = xc_evtchn_reset(_H(handle), _D(domid));
+	if (r < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+
+#define RING_SIZE 32768
+static char ring[RING_SIZE];
+
+CAMLprim value stub_xc_readconsolering(value xc_handle)
+{
+	unsigned int size = RING_SIZE;
+	char *ring_ptr = ring;
+
+	CAMLparam1(xc_handle);
+	int c_xc_handle = _H(xc_handle);
+
+	// caml_enter_blocking_section();
+	int retval = xc_readconsolering(c_xc_handle, &ring_ptr, &size, 0);
+	// caml_leave_blocking_section();
+
+	if (retval)
+		failwith_xc();
+	ring[size] = '\0';
+	CAMLreturn(caml_copy_string(ring));
+}
+
+CAMLprim value stub_xc_send_debug_keys(value xc_handle, value keys)
+{
+	CAMLparam2(xc_handle, keys);
+	int r;
+
+	r = xc_send_debug_keys(_H(xc_handle), String_val(keys));
+	if (r)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_physinfo(value xc_handle)
+{
+	CAMLparam1(xc_handle);
+	CAMLlocal3(physinfo, cap_list, tmp);
+	xc_physinfo_t c_physinfo;
+	int r;
+
+	// caml_enter_blocking_section();
+	r = xc_physinfo(_H(xc_handle), &c_physinfo);
+	// caml_leave_blocking_section();
+
+	if (r)
+		failwith_xc();
+
+	tmp = cap_list = Val_emptylist;
+	for (r = 0; r < 2; r++) {
+		if ((c_physinfo.capabilities >> r) & 1) {
+			tmp = caml_alloc_small(2, Tag_cons);
+			Field(tmp, 0) = Val_int(r);
+			Field(tmp, 1) = cap_list;
+			cap_list = tmp;
+		}
+	}
+
+	physinfo = caml_alloc_tuple(9);
+	Store_field(physinfo, 0, Val_int(c_physinfo.threads_per_core));
+	Store_field(physinfo, 1, Val_int(c_physinfo.cores_per_socket));
+	Store_field(physinfo, 2, Val_int(c_physinfo.nr_cpus));
+	Store_field(physinfo, 3, Val_int(c_physinfo.max_node_id));
+	Store_field(physinfo, 4, Val_int(c_physinfo.cpu_khz));
+	Store_field(physinfo, 5, caml_copy_nativeint(c_physinfo.total_pages));
+	Store_field(physinfo, 6, caml_copy_nativeint(c_physinfo.free_pages));
+	Store_field(physinfo, 7, caml_copy_nativeint(c_physinfo.scrub_pages));
+	Store_field(physinfo, 8, cap_list);
+
+	CAMLreturn(physinfo);
+}
+
+CAMLprim value stub_xc_pcpu_info(value xc_handle, value nr_cpus)
+{
+	CAMLparam2(xc_handle, nr_cpus);
+	CAMLlocal2(pcpus, v);
+	uint64_t *info;
+	int r, size;
+
+	if (Int_val(nr_cpus) < 1)
+		caml_invalid_argument("nr_cpus");
+	
+	info = calloc(Int_val(nr_cpus) + 1, sizeof(uint64_t));
+	if (!info)
+		caml_raise_out_of_memory();
+
+	// caml_enter_blocking_section();
+	r = xc_pcpu_info(_H(xc_handle), Int_val(nr_cpus), info, &size);
+	// caml_leave_blocking_section();
+
+	if (r) {
+		free(info);
+		failwith_xc();
+	}
+
+	if (size > 0) {
+		int i;
+		pcpus = caml_alloc(size, 0);
+		for (i = 0; i < size; i++) {
+			v = caml_copy_int64(info[i]);
+			caml_modify(&Field(pcpus, i), v);
+		}
+	} else
+		pcpus = Atom(0);
+	free(info);
+	CAMLreturn(pcpus);
+}
+
+CAMLprim value stub_xc_domain_setmaxmem(value xc_handle, value domid,
+                                        value max_memkb)
+{
+	CAMLparam3(xc_handle, domid, max_memkb);
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_domid = _D(domid);
+	unsigned int c_max_memkb = Int64_val(max_memkb);
+	// caml_enter_blocking_section();
+	int retval = xc_domain_setmaxmem(c_xc_handle, c_domid,
+	                                 c_max_memkb);
+	// caml_leave_blocking_section();
+	if (retval)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_set_memmap_limit(value xc_handle, value domid,
+                                               value map_limitkb)
+{
+	CAMLparam3(xc_handle, domid, map_limitkb);
+	unsigned long v;
+	int retval;
+
+	v = Int64_val(map_limitkb);
+	retval = xc_domain_set_memmap_limit(_H(xc_handle), _D(domid), v);
+	if (retval)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_memory_increase_reservation(value xc_handle,
+                                                          value domid,
+                                                          value mem_kb)
+{
+	CAMLparam3(xc_handle, domid, mem_kb);
+
+	unsigned long nr_extents = ((unsigned long)(Int64_val(mem_kb))) >> (PAGE_SHIFT - 10);
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_domid = _D(domid);
+	// caml_enter_blocking_section();
+	int retval = xc_domain_memory_increase_reservation(c_xc_handle, c_domid,
+	                                                   nr_extents, 0, 0, NULL);
+	// caml_leave_blocking_section();
+
+	if (retval)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_set_machine_address_size(value xc_handle,
+						       value domid,
+						       value width)
+{
+	CAMLparam3(xc_handle, domid, width);
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_domid = _D(domid);
+	int c_width = Int_val(width);
+
+	int retval = xc_domain_set_machine_address_size(c_xc_handle, c_domid, c_width);
+	if (retval)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_get_machine_address_size(value xc_handle,
+                                                       value domid)
+{
+	CAMLparam2(xc_handle, domid);
+	int retval;
+
+	retval = xc_domain_get_machine_address_size(_H(xc_handle), _D(domid));
+	if (retval < 0)
+		failwith_xc();
+	CAMLreturn(Val_int(retval));
+}
+
+CAMLprim value stub_xc_domain_cpuid_set(value xc_handle, value domid,
+                                        value is_hvm, value input,
+                                        value config)
+{
+	CAMLparam5(xc_handle, domid, is_hvm, input, config);
+	CAMLlocal2(array, tmp);
+	int r;
+	char *c_config[4], *out_config[4];
+	uint32_t c_input, c_oinput;
+
+	c_config[0] = string_of_option_array(config, 0);
+	c_config[1] = string_of_option_array(config, 1);
+	c_config[2] = string_of_option_array(config, 2);
+	c_config[3] = string_of_option_array(config, 3);
+
+	cpuid_input_of_val(c_input, c_oinput, input);
+
+	array = caml_alloc(4, 0);
+	for (r = 0; r < 4; r++) {
+		tmp = Val_none;
+		if (c_config[r]) {
+			tmp = caml_alloc_small(1, 0);
+			Field(tmp, 0) = caml_alloc_string(32);
+		}
+		Store_field(array, r, tmp);
+	}
+
+	for (r = 0; r < 4; r++)
+		out_config[r] = (c_config[r]) ? String_val(Field(Field(array, r), 0)) : NULL;
+
+	r = xc_domain_cpuid_set(_H(xc_handle), _D(domid), Bool_val(is_hvm),
+	                        c_input, c_oinput, c_config, out_config);
+	if (r < 0)
+		failwith_xc();
+	CAMLreturn(array);
+}
+
+CAMLprim value stub_xc_domain_cpuid_apply(value xc_handle, value domid, value is_hvm)
+{
+	CAMLparam3(xc_handle, domid, is_hvm);
+	int r;
+	r = xc_domain_cpuid_apply(_H(xc_handle), _D(domid), Bool_val(is_hvm));
+	if (r < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_cpuid_check(value input, value config)
+{
+	CAMLparam2(input, config);
+	CAMLlocal3(ret, array, tmp);
+	int r;
+	uint32_t c_input, c_oinput;
+	char *c_config[4], *out_config[4];
+
+	c_config[0] = string_of_option_array(config, 0);
+	c_config[1] = string_of_option_array(config, 1);
+	c_config[2] = string_of_option_array(config, 2);
+	c_config[3] = string_of_option_array(config, 3);
+
+	cpuid_input_of_val(c_input, c_oinput, input);
+
+	array = caml_alloc(4, 0);
+	for (r = 0; r < 4; r++) {
+		tmp = Val_none;
+		if (c_config[r]) {
+			tmp = caml_alloc_small(1, 0);
+			Field(tmp, 0) = caml_alloc_string(32);
+		}
+		Store_field(array, r, tmp);
+	}
+
+	for (r = 0; r < 4; r++)
+		out_config[r] = (c_config[r]) ? String_val(Field(Field(array, r), 0)) : NULL;
+
+	r = xc_cpuid_check(c_input, c_oinput, c_config, out_config);
+	if (r < 0)
+		failwith_xc();
+
+	ret = caml_alloc_tuple(2);
+	Store_field(ret, 0, Val_bool(r));
+	Store_field(ret, 1, array);
+
+	CAMLreturn(ret);
+}
+
+CAMLprim value stub_xc_version_version(value xc_handle)
+{
+	CAMLparam1(xc_handle);
+	CAMLlocal1(result);
+	xen_extraversion_t extra;
+	long packed;
+	int retval;
+
+	int c_xc_handle = _H(xc_handle);
+	// caml_enter_blocking_section();
+	packed = xc_version(c_xc_handle, XENVER_version, NULL);
+	retval = xc_version(c_xc_handle, XENVER_extraversion, &extra);
+	// caml_leave_blocking_section();
+
+	if (retval)
+		failwith_xc();
+
+	result = caml_alloc_tuple(3);
+
+	Store_field(result, 0, Val_int(packed >> 16));
+	Store_field(result, 1, Val_int(packed & 0xffff));
+	Store_field(result, 2, caml_copy_string(extra));
+
+	CAMLreturn(result);
+}
+
+
+CAMLprim value stub_xc_version_compile_info(value xc_handle)
+{
+	CAMLparam1(xc_handle);
+	CAMLlocal1(result);
+	xen_compile_info_t ci;
+	int retval;
+
+	int c_xc_handle = _H(xc_handle);
+	// caml_enter_blocking_section();
+	retval = xc_version(c_xc_handle, XENVER_compile_info, &ci);
+	// caml_leave_blocking_section();
+
+	if (retval)
+		failwith_xc();
+
+	result = caml_alloc_tuple(4);
+
+	Store_field(result, 0, caml_copy_string(ci.compiler));
+	Store_field(result, 1, caml_copy_string(ci.compile_by));
+	Store_field(result, 2, caml_copy_string(ci.compile_domain));
+	Store_field(result, 3, caml_copy_string(ci.compile_date));
+
+	CAMLreturn(result);
+}
+
+
+static value xc_version_single_string(value xc_handle, int code, void *info)
+{
+	CAMLparam1(xc_handle);
+	int retval;
+
+	int c_xc_handle = _H(xc_handle);
+	// caml_enter_blocking_section();
+	retval = xc_version(c_xc_handle, code, info);
+	// caml_leave_blocking_section();
+
+	if (retval)
+		failwith_xc();
+
+	CAMLreturn(caml_copy_string((char *)info));
+}
+
+
+CAMLprim value stub_xc_version_changeset(value xc_handle)
+{
+	xen_changeset_info_t ci;
+
+	return xc_version_single_string(xc_handle, XENVER_changeset, &ci);
+}
+
+
+CAMLprim value stub_xc_version_capabilities(value xc_handle)
+{
+	xen_capabilities_info_t ci;
+
+	return xc_version_single_string(xc_handle, XENVER_capabilities, &ci);
+}
+
+
+CAMLprim value stub_pages_to_kib(value pages)
+{
+	CAMLparam1(pages);
+
+	CAMLreturn(caml_copy_int64(Int64_val(pages) << (PAGE_SHIFT - 10)));
+}
+
+
+CAMLprim value stub_map_foreign_range(value xc_handle, value dom,
+                                      value size, value mfn)
+{
+	CAMLparam4(xc_handle, dom, size, mfn);
+	CAMLlocal1(result);
+	struct mmap_interface *intf;
+
+	result = caml_alloc(sizeof(struct mmap_interface), Abstract_tag);
+	intf = (struct mmap_interface *) result;
+
+	intf->len = Int_val(size);
+
+	int c_xc_handle = _H(xc_handle);
+	uint32_t c_dom = _D(dom);
+	unsigned long c_mfn = Nativeint_val(mfn);
+	// caml_enter_blocking_section();
+	intf->addr = xc_map_foreign_range(c_xc_handle, c_dom,
+	                                  intf->len, PROT_READ|PROT_WRITE,
+	                                  c_mfn);
+	// caml_leave_blocking_section();
+	if (!intf->addr)
+		caml_failwith("xc_map_foreign_range error");
+	CAMLreturn(result);
+}
+
+CAMLprim value stub_sched_credit_domain_get(value xc_handle, value domid)
+{
+	CAMLparam2(xc_handle, domid);
+	CAMLlocal1(sdom);
+	struct xen_domctl_sched_credit c_sdom;
+	int ret;
+
+	// caml_enter_blocking_section();
+	ret = xc_sched_credit_domain_get(_H(xc_handle), _D(domid), &c_sdom);
+	// caml_leave_blocking_section();
+	if (ret != 0)
+		failwith_xc();
+
+	sdom = caml_alloc_tuple(2);
+	Store_field(sdom, 0, Val_int(c_sdom.weight));
+	Store_field(sdom, 1, Val_int(c_sdom.cap));
+
+	CAMLreturn(sdom);
+}
+
+CAMLprim value stub_sched_credit_domain_set(value xc_handle, value domid,
+                                            value sdom)
+{
+	CAMLparam3(xc_handle, domid, sdom);
+	struct xen_domctl_sched_credit c_sdom;
+	int ret;
+
+	c_sdom.weight = Int_val(Field(sdom, 0));
+	c_sdom.cap = Int_val(Field(sdom, 1));
+	// caml_enter_blocking_section();
+	ret = xc_sched_credit_domain_set(_H(xc_handle), _D(domid), &c_sdom);
+	// caml_leave_blocking_section();
+	if (ret != 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_shadow_allocation_get(value xc_handle, value domid)
+{
+	CAMLparam2(xc_handle, domid);
+	CAMLlocal1(mb);
+	uint32_t c_mb;
+	int ret;
+
+	// caml_enter_blocking_section();
+	ret = xc_shadow_allocation_get(_H(xc_handle), _D(domid), &c_mb);
+	// caml_leave_blocking_section();
+	if (ret != 0)
+		failwith_xc();
+
+	mb = Val_int(c_mb);
+	CAMLreturn(mb);
+}
+
+CAMLprim value stub_shadow_allocation_set(value xc_handle, value domid,
+					  value mb)
+{
+	CAMLparam3(xc_handle, domid, mb);
+	uint32_t c_mb;
+	int ret;
+
+	c_mb = Int_val(mb);
+	// caml_enter_blocking_section();
+	ret = xc_shadow_allocation_set(_H(xc_handle), _D(domid), c_mb);
+	// caml_leave_blocking_section();
+	if (ret != 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_get_pfn_list(value xc_handle, value domid,
+                                           value nr_pfns)
+{
+	CAMLparam3(xc_handle, domid, nr_pfns);
+	CAMLlocal2(array, v);
+	unsigned long c_nr_pfns;
+	long ret, i;
+	xen_pfn_t *c_array;
+
+	c_nr_pfns = Nativeint_val(nr_pfns);
+
+	c_array = malloc(sizeof(xen_pfn_t) * c_nr_pfns);
+	if (!c_array)
+		caml_raise_out_of_memory();
+
+	ret = xc_domain_get_pfn_list(_H(xc_handle), _D(domid),
+	                             c_array, c_nr_pfns);
+	if (ret < 0) {
+		free(c_array);
+		failwith_xc();
+	}
+
+	array = caml_alloc(ret, 0);
+	for (i = 0; i < ret; i++) {
+		v = caml_copy_nativeint(c_array[i]);
+		Store_field(array, i, v);
+	}
+	free(c_array);
+
+	CAMLreturn(array);
+}
+
+CAMLprim value stub_xc_domain_ioport_permission(value xc_handle, value domid,
+					       value start_port, value nr_ports,
+					       value allow)
+{
+	CAMLparam5(xc_handle, domid, start_port, nr_ports, allow);
+	uint32_t c_start_port, c_nr_ports;
+	uint8_t c_allow;
+	int ret;
+
+	c_start_port = Int_val(start_port);
+	c_nr_ports = Int_val(nr_ports);
+	c_allow = Bool_val(allow);
+
+	ret = xc_domain_ioport_permission(_H(xc_handle), _D(domid),
+					 c_start_port, c_nr_ports, c_allow);
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_iomem_permission(value xc_handle, value domid,
+					       value start_pfn, value nr_pfns,
+					       value allow)
+{
+	CAMLparam5(xc_handle, domid, start_pfn, nr_pfns, allow);
+	unsigned long c_start_pfn, c_nr_pfns;
+	uint8_t c_allow;
+	int ret;
+
+	c_start_pfn = Nativeint_val(start_pfn);
+	c_nr_pfns = Nativeint_val(nr_pfns);
+	c_allow = Bool_val(allow);
+
+	ret = xc_domain_iomem_permission(_H(xc_handle), _D(domid),
+					 c_start_pfn, c_nr_pfns, c_allow);
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_irq_permission(value xc_handle, value domid,
+					     value pirq, value allow)
+{
+	CAMLparam4(xc_handle, domid, pirq, allow);
+	uint8_t c_pirq;
+	uint8_t c_allow;
+	int ret;
+
+	c_pirq = Int_val(pirq);
+	c_allow = Bool_val(allow);
+
+	ret = xc_domain_irq_permission(_H(xc_handle), _D(domid),
+				       c_pirq, c_allow);
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_hvm_check_pvdriver(value xc_handle, value domid)
+{
+	CAMLparam2(xc_handle, domid);
+	int ret;
+
+	ret = xc_hvm_check_pvdriver(_H(xc_handle), _D(domid));
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_bool(ret));
+}
+
+CAMLprim value stub_xc_domain_test_assign_device(value xc_handle, value domid, value desc)
+{
+	CAMLparam3(xc_handle, domid, desc);
+	int ret;
+	int domain, bus, slot, func;
+
+	domain = Int_val(Field(desc, 0));
+	bus = Int_val(Field(desc, 1));
+	slot = Int_val(Field(desc, 2));
+	func = Int_val(Field(desc, 3));
+
+	ret = xc_domain_test_assign_device(_H(xc_handle), _D(domid),
+	                                   domain, bus, slot, func);
+	CAMLreturn(Val_bool(ret == 0));
+}
+
+CAMLprim value stub_xc_domain_assign_device(value xc_handle, value domid, value desc)
+{
+	CAMLparam3(xc_handle, domid, desc);
+	int ret;
+	int domain, bus, slot, func;
+
+	domain = Int_val(Field(desc, 0));
+	bus = Int_val(Field(desc, 1));
+	slot = Int_val(Field(desc, 2));
+	func = Int_val(Field(desc, 3));
+
+	ret = xc_domain_assign_device(_H(xc_handle), _D(domid),
+	                              domain, bus, slot, func);
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_deassign_device(value xc_handle, value domid, value desc)
+{
+	CAMLparam3(xc_handle, domid, desc);
+	int ret;
+	int domain, bus, slot, func;
+
+	domain = Int_val(Field(desc, 0));
+	bus = Int_val(Field(desc, 1));
+	slot = Int_val(Field(desc, 2));
+	func = Int_val(Field(desc, 3));
+
+	ret = xc_domain_deassign_device(_H(xc_handle), _D(domid),
+	                                domain, bus, slot, func);
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_set_timer_mode(value handle, value id, value mode)
+{
+	CAMLparam3(handle, id, mode);
+	int ret;
+
+	ret = xc_domain_set_timer_mode(_H(handle), _D(id), Int_val(mode));
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_set_hpet(value handle, value id, value mode)
+{
+	CAMLparam3(handle, id, mode);
+	int ret;
+
+	ret = xc_domain_set_hpet(_H(handle), _D(id), Int_val(mode));
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_set_vpt_align(value handle, value id, value mode)
+{
+	CAMLparam3(handle, id, mode);
+	int ret;
+
+	ret = xc_domain_set_vpt_align(_H(handle), _D(id), Int_val(mode));
+	if (ret < 0)
+		failwith_xc();
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_watchdog(value handle, value domid, value timeout)
+{
+	CAMLparam3(handle, domid, timeout);
+	int ret;
+	unsigned int c_timeout = Int32_val(timeout);
+
+	ret = xc_domain_watchdog(_H(handle), _D(domid), c_timeout);
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_int(ret));
+}
+
+CAMLprim value stub_xc_domain_send_s3resume(value handle, value domid)
+{
+	CAMLparam2(handle, domid);
+	xc_domain_send_s3resume(_H(handle), _D(domid));
+	CAMLreturn(Val_unit);
+}
+
+CAMLprim value stub_xc_domain_get_acpi_s_state(value handle, value domid)
+{
+	CAMLparam2(handle, domid);
+	int ret;
+
+	ret = xc_domain_get_acpi_s_state(_H(handle), _D(domid));
+	if (ret < 0)
+		failwith_xc();
+
+	CAMLreturn(Val_int(ret));
+}
+
+/*
+ * Local variables:
+ *  indent-tabs-mode: t
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

  parent reply	other threads:[~2010-03-09 14:41 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-09 14:41 [PATCH 00/10][RFC][v2] merge ocaml xenstored and dependencies Vincent Hanquez
2010-03-09 14:41 ` [PATCH 01/10] add ocaml mmap bindings implementation Vincent Hanquez
2010-03-09 14:41 ` Vincent Hanquez [this message]
2010-03-09 14:41 ` [PATCH 03/10] add XS ocaml bindings Vincent Hanquez
2010-03-09 14:41 ` [PATCH 04/10] add uuid " Vincent Hanquez
2010-03-09 14:41 ` [PATCH 05/10] add logs " Vincent Hanquez
2010-03-09 14:41 ` [PATCH 06/10] add ocaml xenstored Vincent Hanquez
2010-03-09 14:41 ` [PATCH 07/10] add compilation makefile to ocaml directory Vincent Hanquez
2010-03-09 14:41 ` [PATCH 08/10] remove hook from external ocaml repository Vincent Hanquez
2010-03-09 14:41 ` [PATCH 09/10] add ocaml tools to build if defined. default to n Vincent Hanquez
2010-03-09 14:41 ` [PATCH 10/10] default ocaml tools config variable to y Vincent Hanquez
  -- strict thread matches above, loose matches on Subject: below --
2010-04-23 14:31 [PATCH 00/10][RFC][v2] merge ocaml xenstored and dependencies Vincent Hanquez
2010-04-23 14:31 ` [PATCH 02/10] add ocaml XC bindings Vincent Hanquez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1268145675-10375-3-git-send-email-vincent.hanquez@eu.citrix.com \
    --to=vincent.hanquez@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).