diff mbox

[V9,04/16] xen: Support new libxc calls from xen unstable.

Message ID 1295965760-31508-5-git-send-email-anthony.perard@citrix.com
State New
Headers show

Commit Message

Anthony PERARD Jan. 25, 2011, 2:29 p.m. UTC
From: Anthony PERARD <anthony.perard@citrix.com>

Update the libxenctrl calls in Qemu to use the new interface, otherwise
Qemu wouldn't be able to build against new versions of the library.

We also check libxenctrl version in configure, from Xen 3.3.0 to Xen
unstable.

Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
---
 Makefile.target      |    3 +
 configure            |   62 +++++++++++++++++++++++++++++-
 hw/xen_backend.c     |   21 +++++-----
 hw/xen_backend.h     |    7 ++-
 hw/xen_common.h      |   36 ++++++++++-------
 hw/xen_disk.c        |    4 +-
 hw/xen_domainbuild.c |    2 +-
 hw/xen_interfaces.c  |  103 +++++++++++++++++++++++++++++++++++++++++++++-----
 hw/xen_interfaces.h  |   76 +++++++++++++++++++++++++------------
 hw/xen_redirect.h    |   32 ++++++++-------
 10 files changed, 264 insertions(+), 82 deletions(-)

Comments

Anthony Liguori Jan. 26, 2011, 10:53 p.m. UTC | #1
On 01/25/2011 08:29 AM, anthony.perard@citrix.com wrote:
> From: Anthony PERARD<anthony.perard@citrix.com>
>
> Update the libxenctrl calls in Qemu to use the new interface, otherwise
> Qemu wouldn't be able to build against new versions of the library.
>
> We also check libxenctrl version in configure, from Xen 3.3.0 to Xen
> unstable.
>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> ---
>   Makefile.target      |    3 +
>   configure            |   62 +++++++++++++++++++++++++++++-
>   hw/xen_backend.c     |   21 +++++-----
>   hw/xen_backend.h     |    7 ++-
>   hw/xen_common.h      |   36 ++++++++++-------
>   hw/xen_disk.c        |    4 +-
>   hw/xen_domainbuild.c |    2 +-
>   hw/xen_interfaces.c  |  103 +++++++++++++++++++++++++++++++++++++++++++++-----
>   hw/xen_interfaces.h  |   76 +++++++++++++++++++++++++------------
>   hw/xen_redirect.h    |   32 ++++++++-------
>   10 files changed, 264 insertions(+), 82 deletions(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index db29e96..d09719f 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -205,6 +205,9 @@ QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
>   QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
>   QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
>
> +# xen support
> +obj-$(CONFIG_XEN) += xen_interfaces.o
> +
>   # xen backend driver support
>   obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
>   obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
> diff --git a/configure b/configure
> index 5a9121d..fde9bad 100755
> --- a/configure
> +++ b/configure
> @@ -126,6 +126,7 @@ vnc_jpeg=""
>   vnc_png=""
>   vnc_thread="no"
>   xen=""
> +xen_ctrl_version=""
>   linux_aio=""
>   attr=""
>   vhost_net=""
> @@ -1144,13 +1145,71 @@ fi
>
>   if test "$xen" != "no" ; then
>     xen_libs="-lxenstore -lxenctrl -lxenguest"
> +
> +  # Xen unstable
>     cat>  $TMPC<<EOF
>   #include<xenctrl.h>
>   #include<xs.h>
> -int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
> +#include<stdint.h>
> +#include<xen/hvm/hvm_info_table.h>
> +#if !defined(HVM_MAX_VCPUS)
> +# error HVM_MAX_VCPUS not defined
> +#endif
> +int main(void) {
> +  xc_interface *xc;
> +  xs_daemon_open();
> +  xc = xc_interface_open(0, 0, 0);
> +  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
> +  xc_gnttab_open(NULL, 0);
> +  return 0;
> +}
>   EOF
>     if compile_prog "" "$xen_libs" ; then
> +    xen_ctrl_version=410
> +    xen=yes
> +
> +  # Xen 4.0.0
> +  elif (
> +      cat>  $TMPC<<EOF
> +#include<xenctrl.h>
> +#include<xs.h>
> +#include<stdint.h>
> +#include<xen/hvm/hvm_info_table.h>
> +#if !defined(HVM_MAX_VCPUS)
> +# error HVM_MAX_VCPUS not defined
> +#endif
> +int main(void) {
> +  xs_daemon_open();
> +  xc_interface_open();
> +  xc_gnttab_open();
> +  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
> +  return 0;
> +}
>    

Really?  There's no VERSION #define?  Can please fix this upstream so we 
don't have to do this forever.

> diff --git a/hw/xen_backend.c b/hw/xen_backend.c
> index 860b038..7e78546 100644
> --- a/hw/xen_backend.c
> +++ b/hw/xen_backend.c
> @@ -43,7 +43,8 @@
>   /* ------------------------------------------------------------- */
>
>   /* public */
> -int xen_xc;
> +qemu_xc_interface xen_xc = XC_HANDLER_INITIAL_VALUE;
> +qemu_xc_gnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
>    

Where ever qemu_xc_interface comes from, the typename needs to change.
> +/* Xen unstable */
> +#if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
> +typedef int qemu_xc_interface;
>    

Ah, right here :-)

Regards,

Anthony Liguori
Stefano Stabellini Jan. 27, 2011, 12:03 p.m. UTC | #2
On Wed, 26 Jan 2011, Anthony Liguori wrote:
> > +    xen_ctrl_version=410
> > +    xen=yes
> > +
> > +  # Xen 4.0.0
> > +  elif (
> > +      cat>  $TMPC<<EOF
> > +#include<xenctrl.h>
> > +#include<xs.h>
> > +#include<stdint.h>
> > +#include<xen/hvm/hvm_info_table.h>
> > +#if !defined(HVM_MAX_VCPUS)
> > +# error HVM_MAX_VCPUS not defined
> > +#endif
> > +int main(void) {
> > +  xs_daemon_open();
> > +  xc_interface_open();
> > +  xc_gnttab_open();
> > +  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
> > +  return 0;
> > +}
> >    
> 
> Really?  There's no VERSION #define?  Can please fix this upstream so we 
> don't have to do this forever.
 
Yeah, it is a bit of a shame but there isn't an #define VERSION in
xenctrl.h.
If we introduce it now, the first Xen release to have it is going to be
4.1.
Keir Fraser Jan. 27, 2011, 12:16 p.m. UTC | #3
On 27/01/2011 12:03, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
wrote:

>> Really?  There's no VERSION #define?  Can please fix this upstream so we
>> don't have to do this forever.
>  
> Yeah, it is a bit of a shame but there isn't an #define VERSION in
> xenctrl.h.
> If we introduce it now, the first Xen release to have it is going to be
> 4.1.

We can add it for 4.1.0 and 4.0.2. Really that covers everyone who'll want
to build newly upstreamed qemu bits. Gracefully failing to configure in the
absence of the new define would be quite acceptable imo.

 -- Keir
Stefano Stabellini Jan. 27, 2011, 12:21 p.m. UTC | #4
On Thu, 27 Jan 2011, Keir Fraser wrote:
> On 27/01/2011 12:03, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
> wrote:
> 
> >> Really?  There's no VERSION #define?  Can please fix this upstream so we
> >> don't have to do this forever.
> >  
> > Yeah, it is a bit of a shame but there isn't an #define VERSION in
> > xenctrl.h.
> > If we introduce it now, the first Xen release to have it is going to be
> > 4.1.
> 
> We can add it for 4.1.0 and 4.0.2. Really that covers everyone who'll want
> to build newly upstreamed qemu bits. Gracefully failing to configure in the
> absence of the new define would be quite acceptable imo.

People might want to use qemu just as Xen PV backends provider, as it
works now, so removing Xen support in the absence of the new define
would be a regression in that case.
Anthony PERARD Jan. 27, 2011, 5:24 p.m. UTC | #5
On Wed, 26 Jan 2011, Anthony Liguori wrote:

> On 01/25/2011 08:29 AM, anthony.perard@citrix.com wrote:
> > From: Anthony PERARD<anthony.perard@citrix.com>
> >
> > Update the libxenctrl calls in Qemu to use the new interface, otherwise
> > Qemu wouldn't be able to build against new versions of the library.
> >
> > We also check libxenctrl version in configure, from Xen 3.3.0 to Xen
> > unstable.
> >
> > Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> > Signed-off-by: Stefano Stabellini<stefano.stabellini@eu.citrix.com>
> > ---


> > diff --git a/hw/xen_backend.c b/hw/xen_backend.c
> > index 860b038..7e78546 100644
> > --- a/hw/xen_backend.c
> > +++ b/hw/xen_backend.c
> > @@ -43,7 +43,8 @@
> >   /* ------------------------------------------------------------- */
> >
> >   /* public */
> > -int xen_xc;
> > +qemu_xc_interface xen_xc = XC_HANDLER_INITIAL_VALUE;
> > +qemu_xc_gnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
> >
>
> Where ever qemu_xc_interface comes from, the typename needs to change.

I can call it XCInterface, even if is not always a struct. Same for
qemu_xc_gnttab and xc_evtchn.

> > +/* Xen unstable */
> > +#if CONFIG_XEN_CTRL_INTERFACE_VERSION<  410
> > +typedef int qemu_xc_interface;
> >
>
> Ah, right here :-)
>
> Regards,

Thanks,
diff mbox

Patch

diff --git a/Makefile.target b/Makefile.target
index db29e96..d09719f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -205,6 +205,9 @@  QEMU_CFLAGS += $(VNC_SASL_CFLAGS)
 QEMU_CFLAGS += $(VNC_JPEG_CFLAGS)
 QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 
+# xen support
+obj-$(CONFIG_XEN) += xen_interfaces.o
+
 # xen backend driver support
 obj-$(CONFIG_XEN) += xen_backend.o xen_devconfig.o
 obj-$(CONFIG_XEN) += xen_console.o xenfb.o xen_disk.o xen_nic.o
diff --git a/configure b/configure
index 5a9121d..fde9bad 100755
--- a/configure
+++ b/configure
@@ -126,6 +126,7 @@  vnc_jpeg=""
 vnc_png=""
 vnc_thread="no"
 xen=""
+xen_ctrl_version=""
 linux_aio=""
 attr=""
 vhost_net=""
@@ -1144,13 +1145,71 @@  fi
 
 if test "$xen" != "no" ; then
   xen_libs="-lxenstore -lxenctrl -lxenguest"
+
+  # Xen unstable
   cat > $TMPC <<EOF
 #include <xenctrl.h>
 #include <xs.h>
-int main(void) { xs_daemon_open(); xc_interface_open(); return 0; }
+#include <stdint.h>
+#include <xen/hvm/hvm_info_table.h>
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xc_interface *xc;
+  xs_daemon_open();
+  xc = xc_interface_open(0, 0, 0);
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_gnttab_open(NULL, 0);
+  return 0;
+}
 EOF
   if compile_prog "" "$xen_libs" ; then
+    xen_ctrl_version=410
+    xen=yes
+
+  # Xen 4.0.0
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
+#include <stdint.h>
+#include <xen/hvm/hvm_info_table.h>
+#if !defined(HVM_MAX_VCPUS)
+# error HVM_MAX_VCPUS not defined
+#endif
+int main(void) {
+  xs_daemon_open();
+  xc_interface_open();
+  xc_gnttab_open();
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  return 0;
+}
+EOF
+      compile_prog "" "$xen_libs"
+    ) ; then
+    xen_ctrl_version=400
+    xen=yes
+
+  # Xen 3.3.0, 3.4.0
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
+int main(void) {
+  xs_daemon_open();
+  xc_interface_open();
+  xc_gnttab_open();
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  return 0;
+}
+EOF
+      compile_prog "" "$xen_libs"
+    ) ; then
+    xen_ctrl_version=330
     xen=yes
+
+  # Xen not found or unsupported
   else
     if test "$xen" = "yes" ; then
       feature_not_found "xen"
@@ -3009,6 +3068,7 @@  case "$target_arch2" in
     if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
       echo "CONFIG_XEN=y" >> $config_target_mak
       echo "LIBS+=$xen_libs" >> $config_target_mak
+      echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_target_mak
     fi
 esac
 case "$target_arch2" in
diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index 860b038..7e78546 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -43,7 +43,8 @@ 
 /* ------------------------------------------------------------- */
 
 /* public */
-int xen_xc;
+qemu_xc_interface xen_xc = XC_HANDLER_INITIAL_VALUE;
+qemu_xc_gnttab xen_xcg = XC_HANDLER_INITIAL_VALUE;
 struct xs_handle *xenstore = NULL;
 const char *xen_protocol;
 
@@ -207,8 +208,8 @@  static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
     xendev->debug      = debug;
     xendev->local_port = -1;
 
-    xendev->evtchndev = xc_evtchn_open();
-    if (xendev->evtchndev < 0) {
+    xendev->evtchndev = xc_evtchn_open(NULL, 0);
+    if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) {
         xen_be_printf(NULL, 0, "can't open evtchn device\n");
         qemu_free(xendev);
         return NULL;
@@ -216,15 +217,15 @@  static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
     fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
 
     if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
-        xendev->gnttabdev = xc_gnttab_open();
-        if (xendev->gnttabdev < 0) {
+        xendev->gnttabdev = xc_gnttab_open(NULL, 0);
+        if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) {
             xen_be_printf(NULL, 0, "can't open gnttab device\n");
             xc_evtchn_close(xendev->evtchndev);
             qemu_free(xendev);
             return NULL;
         }
     } else {
-        xendev->gnttabdev = -1;
+        xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE;
     }
 
     QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
@@ -266,9 +267,9 @@  static struct XenDevice *xen_be_del_xendev(int dom, int dev)
             qemu_free(xendev->fe);
         }
 
-        if (xendev->evtchndev >= 0)
+        if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE)
             xc_evtchn_close(xendev->evtchndev);
-        if (xendev->gnttabdev >= 0)
+        if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE)
             xc_gnttab_close(xendev->gnttabdev);
 
         QTAILQ_REMOVE(&xendevs, xendev, next);
@@ -627,8 +628,8 @@  int xen_be_init(void)
     if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0)
         goto err;
 
-    xen_xc = xc_interface_open();
-    if (xen_xc == -1) {
+    xen_xc = xc_interface_open(0, 0, 0);
+    if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
         xen_be_printf(NULL, 0, "can't open xen interface\n");
         goto err;
     }
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index 1b428e3..24f69d4 100644
--- a/hw/xen_backend.h
+++ b/hw/xen_backend.h
@@ -2,6 +2,7 @@ 
 #define QEMU_HW_XEN_BACKEND_H 1
 
 #include "xen_common.h"
+#include "xen_redirect.h"
 #include "sysemu.h"
 #include "net.h"
 
@@ -45,8 +46,8 @@  struct XenDevice {
     int                remote_port;
     int                local_port;
 
-    int                evtchndev;
-    int                gnttabdev;
+    qemu_xc_evtchn     evtchndev;
+    qemu_xc_gnttab     gnttabdev;
 
     struct XenDevOps   *ops;
     QTAILQ_ENTRY(XenDevice) next;
@@ -55,7 +56,7 @@  struct XenDevice {
 /* ------------------------------------------------------------- */
 
 /* variables */
-extern int xen_xc;
+extern qemu_xc_interface xen_xc;
 extern struct xs_handle *xenstore;
 extern const char *xen_protocol;
 
diff --git a/hw/xen_common.h b/hw/xen_common.h
index 8a55b44..33df207 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -1,6 +1,8 @@ 
 #ifndef QEMU_HW_XEN_COMMON_H
 #define QEMU_HW_XEN_COMMON_H 1
 
+#include "config-target.h"
+
 #include <stddef.h>
 #include <inttypes.h>
 
@@ -13,22 +15,26 @@ 
 #include "qemu-queue.h"
 
 /*
- * tweaks needed to build with different xen versions
- *  0x00030205 -> 3.1.0
- *  0x00030207 -> 3.2.0
- *  0x00030208 -> unstable
+ * We don't support Xen prior to 3.3.0.
  */
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030205
-# define evtchn_port_or_error_t int
-#endif
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030207
-# define xc_map_foreign_pages xc_map_foreign_batch
-#endif
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00030208
-# define xen_mb()  mb()
-# define xen_rmb() rmb()
-# define xen_wmb() wmb()
+
+/* Xen unstable */
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+typedef int qemu_xc_interface;
+#  define XC_HANDLER_INITIAL_VALUE    -1
+static inline int xc_fd(int xen_xc)
+{
+    return xen_xc;
+}
+#else
+typedef xc_interface *qemu_xc_interface;
+#  define XC_HANDLER_INITIAL_VALUE    NULL
+/* FIXME The fd of xen_xc is now xen_xc->fd */
+/* fd is the first field, so this works */
+static inline int xc_fd(xc_interface *xen_xc)
+{
+    return *(int*)xen_xc;
+}
 #endif
 
 #endif /* QEMU_HW_XEN_COMMON_H */
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 7f6aaca..454086a 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -239,7 +239,7 @@  err:
 
 static void ioreq_unmap(struct ioreq *ioreq)
 {
-    int gnt = ioreq->blkdev->xendev.gnttabdev;
+    qemu_xc_gnttab gnt = ioreq->blkdev->xendev.gnttabdev;
     int i;
 
     if (ioreq->v.niov == 0)
@@ -267,7 +267,7 @@  static void ioreq_unmap(struct ioreq *ioreq)
 
 static int ioreq_map(struct ioreq *ioreq)
 {
-    int gnt = ioreq->blkdev->xendev.gnttabdev;
+    qemu_xc_gnttab gnt = ioreq->blkdev->xendev.gnttabdev;
     int i;
 
     if (ioreq->v.niov == 0)
diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c
index 7f1fd66..232a456 100644
--- a/hw/xen_domainbuild.c
+++ b/hw/xen_domainbuild.c
@@ -176,7 +176,7 @@  static int xen_domain_watcher(void)
     for (i = 3; i < n; i++) {
         if (i == fd[0])
             continue;
-        if (i == xen_xc)
+        if (i == xc_fd(xen_xc))
             continue;
         close(i);
     }
diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
index 09f40e0..1fee58f 100644
--- a/hw/xen_interfaces.c
+++ b/hw/xen_interfaces.c
@@ -1,20 +1,37 @@ 
+#include "config-host.h"
+
 #include <xenctrl.h>
 #include <xs.h>
 
 #include "hw.h"
 #include "xen.h"
+#include "xen_common.h"
 #include "xen_interfaces.h"
 
 #ifdef CONFIG_XEN
 
-static int xc_evtchn_domid(int handle, int domid)
+#  if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+static int evtchn_open(xentoollog_logger *logger, unsigned open_flags)
 {
-    return -1;
+    return xc_evtchn_open();
 }
 
 static struct XenEvtOps xc_evtchn_xen = {
+    .open               = evtchn_open,
+    .close              = xc_evtchn_close,
+    .fd                 = xc_evtchn_fd,
+    .notify             = xc_evtchn_notify,
+    .bind_unbound_port  = xc_evtchn_bind_unbound_port,
+    .bind_interdomain   = xc_evtchn_bind_interdomain,
+    .bind_virq          = xc_evtchn_bind_virq,
+    .unbind             = xc_evtchn_unbind,
+    .pending            = xc_evtchn_pending,
+    .unmask             = xc_evtchn_unmask,
+};
+
+#  else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 410 */
+static struct XenEvtOps xc_evtchn_xen = {
     .open               = xc_evtchn_open,
-    .domid              = xc_evtchn_domid,
     .close              = xc_evtchn_close,
     .fd                 = xc_evtchn_fd,
     .notify             = xc_evtchn_notify,
@@ -25,6 +42,7 @@  static struct XenEvtOps xc_evtchn_xen = {
     .pending            = xc_evtchn_pending,
     .unmask             = xc_evtchn_unmask,
 };
+#  endif
 
 static int xs_domid(struct xs_handle *h, int domid)
 {
@@ -57,6 +75,24 @@  static struct XenStoreOps xs_xen = {
     .is_domain_introduced  = xs_is_domain_introduced,
 };
 
+/* ------------------------------------------------------------- */
+/* xen grant table interface                                     */
+
+#  if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+static int gnttab_open(xentoollog_logger *logger, unsigned open_flags)
+{
+    return xc_gnttab_open();
+}
+
+static struct XenGnttabOps xc_gnttab_xen = {
+    .open            = gnttab_open,
+    .close           = xc_gnttab_close,
+    .map_grant_ref   = xc_gnttab_map_grant_ref,
+    .map_grant_refs  = xc_gnttab_map_grant_refs,
+    .munmap          = xc_gnttab_munmap,
+};
+
+#  else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 410 */
 static struct XenGnttabOps xc_gnttab_xen = {
     .open            = xc_gnttab_open,
     .close           = xc_gnttab_close,
@@ -64,19 +100,66 @@  static struct XenGnttabOps xc_gnttab_xen = {
     .map_grant_refs  = xc_gnttab_map_grant_refs,
     .munmap          = xc_gnttab_munmap,
 };
+#  endif
 
+/* ------------------------------------------------------------- */
+/* xen hypercall interface                                       */
+
+#  if CONFIG_XEN_CTRL_INTERFACE_VERSION < 400
+static qemu_xc_interface interface_open(xentoollog_logger *logger,
+                                        xentoollog_logger *dombuild_logger,
+                                        unsigned open_flags)
+{
+    return xc_interface_open();
+}
+
+static void *map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+                               const xen_pfn_t *arr, int *err, unsigned int num)
+{
+    return xc_map_foreign_batch(xc_handle, dom, prot, (xen_pfn_t*)arr, num);
+}
+
+struct XenIfOps xc_xen = {
+    .interface_open                 = interface_open,
+    .interface_close                = xc_interface_close,
+    .map_foreign_range              = xc_map_foreign_range,
+    .map_foreign_pages              = xc_map_foreign_pages,
+    .map_foreign_bulk               = map_foreign_batch,
+    .domain_populate_physmap_exact  = xc_domain_memory_populate_physmap,
+};
+
+#  elif CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+static qemu_xc_interface interface_open(xentoollog_logger *logger,
+                                        xentoollog_logger *dombuild_logger,
+                                        unsigned open_flags)
+{
+    return xc_interface_open();
+}
+
+struct XenIfOps xc_xen = {
+    .interface_open                 = interface_open,
+    .interface_close                = xc_interface_close,
+    .map_foreign_range              = xc_map_foreign_range,
+    .map_foreign_pages              = xc_map_foreign_pages,
+    .map_foreign_bulk               = xc_map_foreign_bulk,
+    .domain_populate_physmap_exact  = xc_domain_memory_populate_physmap,
+};
+
+#  else /* CONFIG_XEN_CTRL_INTERFACE_VERSION >= 410 */
 struct XenIfOps xc_xen = {
     .interface_open                 = xc_interface_open,
     .interface_close                = xc_interface_close,
     .map_foreign_range              = xc_map_foreign_range,
     .map_foreign_pages              = xc_map_foreign_pages,
     .map_foreign_bulk               = xc_map_foreign_bulk,
+    .domain_populate_physmap_exact  = xc_domain_populate_physmap_exact,
 };
+#  endif
 
-#endif
+#endif /* CONFIG_XEN */
 
-struct XenEvtOps xc_evtchn;
-struct XenGnttabOps xc_gnttab;
+struct XenEvtOps xc_evtchn_ops;
+struct XenGnttabOps xc_gnttab_ops;
 struct XenIfOps xc;
 struct XenStoreOps xs;
 
@@ -86,10 +169,10 @@  void xen_interfaces_init(void)
 #ifdef CONFIG_XEN
     case XEN_ATTACH:
     case XEN_CREATE:
-        xc_evtchn = xc_evtchn_xen;
-        xc_gnttab = xc_gnttab_xen;
-        xc        = xc_xen;
-        xs        = xs_xen;
+        xc_evtchn_ops = xc_evtchn_xen;
+        xc_gnttab_ops = xc_gnttab_xen;
+        xc            = xc_xen;
+        xs            = xs_xen;
         break;
 #endif
     default:
diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
index 1086850..2afc0b3 100644
--- a/hw/xen_interfaces.h
+++ b/hw/xen_interfaces.h
@@ -4,24 +4,36 @@ 
 #include <xenctrl.h>
 #include <xs.h>
 
+#include "hw/xen_common.h"
+
+
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+typedef struct xentoollog_logger xentoollog_logger;
+#endif
+
 /* ------------------------------------------------------------- */
 /* xen event channel interface                                   */
 
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+typedef int qemu_xc_evtchn;
+#else
+typedef xc_evtchn *qemu_xc_evtchn;
+#endif
+
 struct XenEvtOps {
-    int (*open)(void);
-    int (*domid)(int xce_handle, int domid);
-    int (*close)(int xce_handle);
-    int (*fd)(int xce_handle);
-    int (*notify)(int xce_handle, evtchn_port_t port);
-    evtchn_port_or_error_t (*bind_unbound_port)(int xce_handle, int domid);
-    evtchn_port_or_error_t (*bind_interdomain)(int xce_handle, int domid,
+    qemu_xc_evtchn (*open)(xentoollog_logger *logger, unsigned open_flags);
+    int (*close)(qemu_xc_evtchn xce);
+    int (*fd)(qemu_xc_evtchn xce);
+    int (*notify)(qemu_xc_evtchn xce, evtchn_port_t port);
+    evtchn_port_or_error_t (*bind_unbound_port)(qemu_xc_evtchn xce, int domid);
+    evtchn_port_or_error_t (*bind_interdomain)(qemu_xc_evtchn xce, int domid,
                                                evtchn_port_t remote_port);
-    evtchn_port_or_error_t (*bind_virq)(int xce_handle, unsigned int virq);
-    int (*unbind)(int xce_handle, evtchn_port_t port);
-    evtchn_port_or_error_t (*pending)(int xce_handle);
-    int (*unmask)(int xce_handle, evtchn_port_t port);
+    evtchn_port_or_error_t (*bind_virq)(qemu_xc_evtchn xce, unsigned int virq);
+    int (*unbind)(qemu_xc_evtchn xce, evtchn_port_t port);
+    evtchn_port_or_error_t (*pending)(qemu_xc_evtchn xce);
+    int (*unmask)(qemu_xc_evtchn xce, evtchn_port_t port);
 };
-extern struct XenEvtOps xc_evtchn;
+extern struct XenEvtOps xc_evtchn_ops;
 
 /* ------------------------------------------------------------- */
 /* xenstore interface                                            */
@@ -70,30 +82,44 @@  extern struct XenStoreOps xs;
 /* ------------------------------------------------------------- */
 /* xen grant table interface                                     */
 
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 410
+typedef int qemu_xc_gnttab;
+#else
+typedef xc_gnttab *qemu_xc_gnttab;
+#endif
+
 struct XenGnttabOps {
-    int (*open)(void);
-    int (*close)(int xcg_handle);
-    void *(*map_grant_ref)(int xcg_handle, uint32_t domid,
-                          uint32_t ref, int prot);
-    void *(*map_grant_refs)(int xcg_handle, uint32_t count,
+    qemu_xc_gnttab (*open)(xentoollog_logger *logger, unsigned open_flags);
+    int (*close)(qemu_xc_gnttab xcg);
+    void *(*map_grant_ref)(qemu_xc_gnttab xcg, uint32_t domid,
+                           uint32_t ref, int prot);
+    void *(*map_grant_refs)(qemu_xc_gnttab xcg, uint32_t count,
                             uint32_t *domids, uint32_t *refs, int prot);
-    int (*munmap)(int xcg_handle, void *start_address, uint32_t count);
+    int (*munmap)(qemu_xc_gnttab xcg, void *start_address, uint32_t count);
 };
-extern struct XenGnttabOps xc_gnttab;
+extern struct XenGnttabOps xc_gnttab_ops;
 
 /* ------------------------------------------------------------- */
 /* xen hypercall interface                                       */
 
 struct XenIfOps {
-    int (*interface_open)(void);
-    int (*interface_close)(int xc_handle);
-    void *(*map_foreign_range)(int xc_handle, uint32_t dom,
+    qemu_xc_interface (*interface_open)(xentoollog_logger *logger,
+                                        xentoollog_logger *dombuild_logger,
+                                        unsigned open_flags);
+    int (*interface_close)(qemu_xc_interface xc_handle);
+    void *(*map_foreign_range)(qemu_xc_interface xc_handle, uint32_t dom,
                                int size, int prot,
                                unsigned long mfn);
-    void *(*map_foreign_pages)(int xc_handle, uint32_t dom, int prot,
+    void *(*map_foreign_pages)(qemu_xc_interface xc_handle, uint32_t dom, int prot,
                                const xen_pfn_t *arr, int num);
-    void *(*map_foreign_bulk)(int xc_handle, uint32_t dom, int prot,
-                              xen_pfn_t *arr, int num);
+    void *(*map_foreign_bulk)(qemu_xc_interface xc_handle, uint32_t dom, int prot,
+                              const xen_pfn_t *arr, int *err, unsigned int num);
+    int (*domain_populate_physmap_exact)(qemu_xc_interface xc_handle,
+                                         uint32_t domid,
+                                         unsigned long nr_extents,
+                                         unsigned int extent_order,
+                                         unsigned int mem_flags,
+                                         xen_pfn_t *extent_start);
 };
 extern struct XenIfOps xc;
 
diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h
index 6ddecf3..c0cb1ab 100644
--- a/hw/xen_redirect.h
+++ b/hw/xen_redirect.h
@@ -4,23 +4,23 @@ 
 #include "xen_interfaces.h"
 
 /* xen event channel interface */
-#define xc_evtchn_open              xc_evtchn.open
-#define xc_evtchn_close             xc_evtchn.close
-#define xc_evtchn_fd                xc_evtchn.fd
-#define xc_evtchn_notify            xc_evtchn.notify
-#define xc_evtchn_bind_unbound_port xc_evtchn.bind_unbound_port
-#define xc_evtchn_bind_interdomain  xc_evtchn.bind_interdomain
-#define xc_evtchn_bind_virq         xc_evtchn.bind_virq
-#define xc_evtchn_unbind            xc_evtchn.unbind
-#define xc_evtchn_pending           xc_evtchn.pending
-#define xc_evtchn_unmask            xc_evtchn.unmask
+#define xc_evtchn_open              xc_evtchn_ops.open
+#define xc_evtchn_close             xc_evtchn_ops.close
+#define xc_evtchn_fd                xc_evtchn_ops.fd
+#define xc_evtchn_notify            xc_evtchn_ops.notify
+#define xc_evtchn_bind_unbound_port xc_evtchn_ops.bind_unbound_port
+#define xc_evtchn_bind_interdomain  xc_evtchn_ops.bind_interdomain
+#define xc_evtchn_bind_virq         xc_evtchn_ops.bind_virq
+#define xc_evtchn_unbind            xc_evtchn_ops.unbind
+#define xc_evtchn_pending           xc_evtchn_ops.pending
+#define xc_evtchn_unmask            xc_evtchn_ops.unmask
 
 /* grant table interface */
-#define xc_gnttab_open              xc_gnttab.open
-#define xc_gnttab_close             xc_gnttab.close
-#define xc_gnttab_map_grant_ref     xc_gnttab.map_grant_ref
-#define xc_gnttab_map_grant_refs    xc_gnttab.map_grant_refs
-#define xc_gnttab_munmap            xc_gnttab.munmap
+#define xc_gnttab_open              xc_gnttab_ops.open
+#define xc_gnttab_close             xc_gnttab_ops.close
+#define xc_gnttab_map_grant_ref     xc_gnttab_ops.map_grant_ref
+#define xc_gnttab_map_grant_refs    xc_gnttab_ops.map_grant_refs
+#define xc_gnttab_munmap            xc_gnttab_ops.munmap
 
 /* xen hypercall interface */
 #define xc_interface_open           xc.interface_open
@@ -28,6 +28,8 @@ 
 #define xc_map_foreign_range        xc.map_foreign_range
 #define xc_map_foreign_pages        xc.map_foreign_pages
 #define xc_map_foreign_bulk         xc.map_foreign_bulk
+#define xc_domain_populate_physmap_exact \
+                                    xc.domain_populate_physmap_exact
 
 /* xenstore interface */
 #define xs_daemon_open              xs.daemon_open