WARNING - OLD ARCHIVES

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

xen-changelog

[Xen-changelog] [xen-unstable] ocaml: Add XC bindings.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] ocaml: Add XC bindings.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 06 May 2010 04:10:26 -0700
Delivery-date: Thu, 06 May 2010 04:17:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1273140138 -3600
# Node ID 08aa6b3afaf24662e654aaeb77562c39a691a6cd
# Parent  f8a3979d05522b47a5cc733ae0bf6f62397ea89e
ocaml: Add XC bindings.

This include a small and simpler reimplementation of libxc.

Signed-off-by: Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
---
 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(+)

diff -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/META.in
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/META.in       Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,4 @@
+version = "@VERSION@"
+description = "Xen Control Interface"
+archive(byte) = "xc.cma"
+archive(native) = "xc.cmxa"
diff -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/Makefile      Thu May 06 11:02:18 2010 +0100
@@ -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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc.h  Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ *
+ * 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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc.ml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc.ml Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,340 @@
+(*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ *
+ * 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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc.mli
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc.mli        Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,196 @@
+(*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ *
+ * 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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc_cpufeature.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc_cpufeature.h       Thu May 06 11:02:18 2010 +0100
@@ -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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc_cpuid.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc_cpuid.h    Thu May 06 11:02:18 2010 +0100
@@ -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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc_e820.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc_e820.h     Thu May 06 11:02:18 2010 +0100
@@ -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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc_lib.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc_lib.c      Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,1502 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ *
+ * 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 -r f8a3979d0552 -r 08aa6b3afaf2 tools/ocaml/libs/xc/xc_stubs.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ocaml/libs/xc/xc_stubs.c    Thu May 06 11:02:18 2010 +0100
@@ -0,0 +1,1170 @@
+/*
+ * Copyright (C) 2006-2007 XenSource Ltd.
+ * Copyright (C) 2008      Citrix Ltd.
+ * Author Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>
+ *
+ * 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:
+ */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] ocaml: Add XC bindings., Xen patchbot-unstable <=