@@ -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
@@ -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
@@ -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;
}
@@ -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;
@@ -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 */
@@ -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)
@@ -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);
}
@@ -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:
@@ -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;
@@ -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