if (str != NULL) {
/* move to qemu-allocated memory to make sure
* callers can savely qemu_free() stuff. */
@@ -197,7 +198,7 @@ static struct XenDevice *xen_be_get_xendev(const char
*type, int dom, int dev,
xendev->dev = dev;
xendev->ops = ops;
- dom0 = xs_get_domain_path(xenstore, 0);
+ dom0 = xs_ops.get_domain_path(xenstore, 0);
snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
dom0, xendev->type, xendev->dom, xendev->dev);
snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
@@ -207,24 +208,24 @@ 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_ops.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;
}
- fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
+ fcntl(xc_evtchn_ops.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_ops.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);
+ xc_evtchn_ops.close(xendev->evtchndev);
qemu_free(xendev);
return NULL;
}
} else {
- xendev->gnttabdev = -1;
+ xendev->gnttabdev = XC_HANDLER_INITIAL_VALUE;
}
QTAILQ_INSERT_TAIL(&xendevs, xendev, next);
@@ -262,14 +263,16 @@ static struct XenDevice *xen_be_del_xendev(int dom, int
dev)
if (xendev->fe) {
char token[XEN_BUFSIZE];
snprintf(token, sizeof(token), "fe:%p", xendev);
- xs_unwatch(xenstore, xendev->fe, token);
+ xs_ops.unwatch(xenstore, xendev->fe, token);
qemu_free(xendev->fe);
}
- if (xendev->evtchndev>= 0)
- xc_evtchn_close(xendev->evtchndev);
- if (xendev->gnttabdev>= 0)
- xc_gnttab_close(xendev->gnttabdev);
+ if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) {
+ xc_evtchn_ops.close(xendev->evtchndev);
+ }
+ if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) {
+ xc_gnttab_ops.close(xendev->gnttabdev);
+ }
QTAILQ_REMOVE(&xendevs, xendev, next);
qemu_free(xendev);
@@ -358,7 +361,7 @@ static int xen_be_try_setup(struct XenDevice *xendev)
/* setup frontend watch */
snprintf(token, sizeof(token), "fe:%p", xendev);
- if (!xs_watch(xenstore, xendev->fe, token)) {
+ if (!xs_ops.watch(xenstore, xendev->fe, token)) {
xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n",
xendev->fe);
return -1;
@@ -506,17 +509,17 @@ static int xenstore_scan(const char *type, int dom,
struct XenDevOps *ops)
unsigned int cdev, j;
/* setup watch */
- dom0 = xs_get_domain_path(xenstore, 0);
+ dom0 = xs_ops.get_domain_path(xenstore, 0);
snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
free(dom0);
- if (!xs_watch(xenstore, path, token)) {
+ if (!xs_ops.watch(xenstore, path, token)) {
xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n",
path);
return -1;
}
/* look for backends */
- dev = xs_directory(xenstore, 0, path,&cdev);
+ dev = xs_ops.directory(xenstore, 0, path,&cdev);
if (!dev)
return 0;
for (j = 0; j< cdev; j++) {
@@ -536,7 +539,7 @@ static void xenstore_update_be(char *watch, char *type, int
dom,
char path[XEN_BUFSIZE], *dom0;
unsigned int len, dev;
- dom0 = xs_get_domain_path(xenstore, 0);
+ dom0 = xs_ops.get_domain_path(xenstore, 0);
len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
free(dom0);
if (strncmp(path, watch, len) != 0)
@@ -583,7 +586,7 @@ static void xenstore_update(void *unused)
intptr_t type, ops, ptr;
unsigned int dom, count;
- vec = xs_read_watch(xenstore,&count);
+ vec = xs_ops.read_watch(xenstore,&count);
if (vec == NULL)
goto cleanup;
@@ -602,13 +605,13 @@ static void xen_be_evtchn_event(void *opaque)
struct XenDevice *xendev = opaque;
evtchn_port_t port;
- port = xc_evtchn_pending(xendev->evtchndev);
+ port = xc_evtchn_ops.pending(xendev->evtchndev);
if (port != xendev->local_port) {
xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected
%d)\n",
port, xendev->local_port);
return;
}
- xc_evtchn_unmask(xendev->evtchndev, port);
+ xc_evtchn_ops.unmask(xendev->evtchndev, port);
if (xendev->ops->event)
xendev->ops->event(xendev);
@@ -618,25 +621,26 @@ static void xen_be_evtchn_event(void *opaque)
int xen_be_init(void)
{
- xenstore = xs_daemon_open();
+ xenstore = xs_ops.daemon_open();
if (!xenstore) {
xen_be_printf(NULL, 0, "can't connect to xenstored\n");
return -1;
}
- if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL)<
0)
+ if (qemu_set_fd_handler(xs_ops.fileno(xenstore), xenstore_update, NULL,
NULL)< 0) {
goto err;
+ }
- xen_xc = xc_interface_open();
- if (xen_xc == -1) {
+ xen_xc = xc_ops.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;
}
return 0;
err:
- qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
- xs_daemon_close(xenstore);
+ qemu_set_fd_handler(xs_ops.fileno(xenstore), NULL, NULL, NULL);
+ xs_ops.daemon_close(xenstore);
xenstore = NULL;
return -1;
@@ -651,14 +655,14 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
{
if (xendev->local_port != -1)
return 0;
- xendev->local_port = xc_evtchn_bind_interdomain
+ xendev->local_port = xc_evtchn_ops.bind_interdomain
(xendev->evtchndev, xendev->dom, xendev->remote_port);
if (xendev->local_port == -1) {
xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n");
return -1;
}
xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
- qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev),
+ qemu_set_fd_handler(xc_evtchn_ops.fd(xendev->evtchndev),
xen_be_evtchn_event, NULL, xendev);
return 0;
}
@@ -667,15 +671,15 @@ void xen_be_unbind_evtchn(struct XenDevice *xendev)
{
if (xendev->local_port == -1)
return;
- qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
- xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
+ qemu_set_fd_handler(xc_evtchn_ops.fd(xendev->evtchndev), NULL, NULL, NULL);
+ xc_evtchn_ops.unbind(xendev->evtchndev, xendev->local_port);
xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
xendev->local_port = -1;
}
int xen_be_send_notify(struct XenDevice *xendev)
{
- return xc_evtchn_notify(xendev->evtchndev, xendev->local_port);
+ return xc_evtchn_ops.notify(xendev->evtchndev, xendev->local_port);
}
/*
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index 1b428e3..5af09b8 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_interfaces.h"
#include "sysemu.h"
#include "net.h"
@@ -45,8 +46,8 @@ struct XenDevice {
int remote_port;
int local_port;
- int evtchndev;
- int gnttabdev;
+ XenEvtchn evtchndev;
+ XenGnttab gnttabdev;
struct XenDevOps *ops;
QTAILQ_ENTRY(XenDevice) next;
@@ -55,7 +56,7 @@ struct XenDevice {
/* ------------------------------------------------------------- */
/* variables */
-extern int xen_xc;
+extern XenXC 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..3a08f6a 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,28 @@
#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 XenXC;
+# define XC_INTERFACE_FMT "%i"
+# define XC_HANDLER_INITIAL_VALUE -1
+static inline int xc_fd(int xen_xc)
+{
+ return xen_xc;
+}
+#else
+typedef xc_interface *XenXC;
+# define XC_INTERFACE_FMT "%p"
+# 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_console.c b/hw/xen_console.c
index d2261f4..7f79df9 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -183,7 +183,7 @@ static int con_init(struct XenDevice *xendev)
char *type, *dom;
/* setup */
- dom = xs_get_domain_path(xenstore, con->xendev.dom);
+ dom = xs_ops.get_domain_path(xenstore, con->xendev.dom);
snprintf(con->console, sizeof(con->console), "%s/console", dom);
free(dom);
@@ -214,10 +214,10 @@ static int con_connect(struct XenDevice *xendev)
if (xenstore_read_int(con->console, "limit",&limit) == 0)
con->buffer.max_capacity = limit;
- con->sring = xc_map_foreign_range(xen_xc, con->xendev.dom,
- XC_PAGE_SIZE,
- PROT_READ|PROT_WRITE,
- con->ring_ref);
+ con->sring = xc_ops.map_foreign_range(xen_xc, con->xendev.dom,
+ XC_PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ con->ring_ref);
if (!con->sring)
return -1;
diff --git a/hw/xen_devconfig.c b/hw/xen_devconfig.c
index 8d50216..b79c444 100644
--- a/hw/xen_devconfig.c
+++ b/hw/xen_devconfig.c
@@ -24,7 +24,7 @@ void xen_config_cleanup(void)
struct xs_dirs *d;
QTAILQ_FOREACH(d,&xs_cleanup, list) {
- xs_rm(xenstore, 0, d->xs_dir);
+ xs_ops.rm(xenstore, 0, d->xs_dir);
}
}
@@ -39,13 +39,13 @@ static int xen_config_dev_mkdir(char *dev, int p)
.perms = p,
}};
- if (!xs_mkdir(xenstore, 0, dev)) {
+ if (!xs_ops.mkdir(xenstore, 0, dev)) {
xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
return -1;
}
xen_config_cleanup_dir(qemu_strdup(dev));
- if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
+ if (!xs_ops.set_permissions(xenstore, 0, dev, perms, 2)) {
xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
return -1;
}
@@ -57,11 +57,11 @@ static int xen_config_dev_dirs(const char *ftype, const
char *btype, int vdev,
{
char *dom;
- dom = xs_get_domain_path(xenstore, xen_domid);
+ dom = xs_ops.get_domain_path(xenstore, xen_domid);
snprintf(fe, len, "%s/device/%s/%d", dom, ftype, vdev);
free(dom);
- dom = xs_get_domain_path(xenstore, 0);
+ dom = xs_ops.get_domain_path(xenstore, 0);
snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
free(dom);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 7f6aaca..7fe7d56 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;
+ XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
int i;
if (ioreq->v.niov == 0)
@@ -247,18 +247,20 @@ static void ioreq_unmap(struct ioreq *ioreq)
if (batch_maps) {
if (!ioreq->pages)
return;
- if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0)
- xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed:
%s\n",
+ if (xc_gnttab_ops.munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) {
+ xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_ops.munmap failed:
%s\n",
strerror(errno));
+ }
ioreq->blkdev->cnt_map -= ioreq->v.niov;
ioreq->pages = NULL;
} else {
for (i = 0; i< ioreq->v.niov; i++) {
if (!ioreq->page[i])
continue;
- if (xc_gnttab_munmap(gnt, ioreq->page[i], 1) != 0)
- xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed:
%s\n",
+ if (xc_gnttab_ops.munmap(gnt, ioreq->page[i], 1) != 0) {
+ xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_ops.munmap
failed: %s\n",
strerror(errno));
+ }
ioreq->blkdev->cnt_map--;
ioreq->page[i] = NULL;
}
@@ -267,13 +269,13 @@ static void ioreq_unmap(struct ioreq *ioreq)
static int ioreq_map(struct ioreq *ioreq)
{
- int gnt = ioreq->blkdev->xendev.gnttabdev;
+ XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
int i;
if (ioreq->v.niov == 0)
return 0;
if (batch_maps) {
- ioreq->pages = xc_gnttab_map_grant_refs
+ ioreq->pages = xc_gnttab_ops.map_grant_refs
(gnt, ioreq->v.niov, ioreq->domids, ioreq->refs, ioreq->prot);
if (ioreq->pages == NULL) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
@@ -287,7 +289,7 @@ static int ioreq_map(struct ioreq *ioreq)
ioreq->blkdev->cnt_map += ioreq->v.niov;
} else {
for (i = 0; i< ioreq->v.niov; i++) {
- ioreq->page[i] = xc_gnttab_map_grant_ref
+ ioreq->page[i] = xc_gnttab_ops.map_grant_ref
(gnt, ioreq->domids[i], ioreq->refs[i], ioreq->prot);
if (ioreq->page[i] == NULL) {
xen_be_printf(&ioreq->blkdev->xendev, 0,
@@ -687,10 +689,10 @@ static int blk_connect(struct XenDevice *xendev)
blkdev->protocol = BLKIF_PROTOCOL_X86_64;
}
- blkdev->sring = xc_gnttab_map_grant_ref(blkdev->xendev.gnttabdev,
- blkdev->xendev.dom,
- blkdev->ring_ref,
- PROT_READ | PROT_WRITE);
+ blkdev->sring = xc_gnttab_ops.map_grant_ref(blkdev->xendev.gnttabdev,
+ blkdev->xendev.dom,
+ blkdev->ring_ref,
+ PROT_READ | PROT_WRITE);
if (!blkdev->sring)
return -1;
blkdev->cnt_map++;
@@ -742,7 +744,7 @@ static void blk_disconnect(struct XenDevice *xendev)
xen_be_unbind_evtchn(&blkdev->xendev);
if (blkdev->sring) {
- xc_gnttab_munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
+ xc_gnttab_ops.munmap(blkdev->xendev.gnttabdev, blkdev->sring, 1);
blkdev->cnt_map--;
blkdev->sring = NULL;
}
diff --git a/hw/xen_domainbuild.c b/hw/xen_domainbuild.c
index 7f1fd66..ae241fa 100644
--- a/hw/xen_domainbuild.c
+++ b/hw/xen_domainbuild.c
@@ -25,22 +25,22 @@ static int xenstore_domain_mkdir(char *path)
char subpath[256];
int i;
- if (!xs_mkdir(xenstore, 0, path)) {
+ if (!xs_ops.mkdir(xenstore, 0, path)) {
fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__, path);
return -1;
}
- if (!xs_set_permissions(xenstore, 0, path, perms_ro, 2)) {
+ if (!xs_ops.set_permissions(xenstore, 0, path, perms_ro, 2)) {
fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
return -1;
}
for (i = 0; writable[i]; i++) {
snprintf(subpath, sizeof(subpath), "%s/%s", path, writable[i]);
- if (!xs_mkdir(xenstore, 0, subpath)) {
+ if (!xs_ops.mkdir(xenstore, 0, subpath)) {
fprintf(stderr, "%s: xs_mkdir %s: failed\n", __FUNCTION__,
subpath);
return -1;
}
- if (!xs_set_permissions(xenstore, 0, subpath, perms_rw, 2)) {
+ if (!xs_ops.set_permissions(xenstore, 0, subpath, perms_rw, 2)) {
fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
return -1;
}
@@ -59,7 +59,7 @@ int xenstore_domain_init1(const char *kernel, const char
*ramdisk,
qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],
qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11],
qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]);
- dom = xs_get_domain_path(xenstore, xen_domid);
+ dom = xs_ops.get_domain_path(xenstore, xen_domid);
snprintf(vm, sizeof(vm), "/vm/%s", uuid_string);
xenstore_domain_mkdir(dom);
@@ -104,13 +104,13 @@ int xenstore_domain_init2(int xenstore_port, int
xenstore_mfn,
{
char *dom;
- dom = xs_get_domain_path(xenstore, xen_domid);
+ dom = xs_ops.get_domain_path(xenstore, xen_domid);
/* signal new domain */
- xs_introduce_domain(xenstore,
- xen_domid,
- xenstore_mfn,
- xenstore_port);
+ xs_ops.introduce_domain(xenstore,
+ xen_domid,
+ xenstore_mfn,
+ xenstore_port);
/* xenstore */
xenstore_write_int(dom, "store/ring-ref", xenstore_mfn);
@@ -176,8 +176,9 @@ 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);
}
@@ -216,12 +217,12 @@ static void xen_domain_cleanup(void)
{
char *dom;
- dom = xs_get_domain_path(xenstore, xen_domid);
+ dom = xs_ops.get_domain_path(xenstore, xen_domid);
if (dom) {
- xs_rm(xenstore, 0, dom);
+ xs_ops.rm(xenstore, 0, dom);
free(dom);
}
- xs_release_domain(xenstore, xen_domid);
+ xs_ops.release_domain(xenstore, xen_domid);
}
int xen_domain_build_pv(const char *kernel, const char *ramdisk,
diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
new file mode 100644
index 0000000..96f33fe
--- /dev/null
+++ b/hw/xen_interfaces.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2011 Citrix Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#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
+
+# if CONFIG_XEN_CTRL_INTERFACE_VERSION< 410
+static int evtchn_open(xentoollog_logger *logger, unsigned open_flags)
+{
+ return xc_evtchn_open();
+}
+
+static 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 XenEvtOps xc_evtchn_xen = {
+ .open = xc_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,
+};
+# endif
+
+static int xs_domid(struct xs_handle *h, int domid)
+{
+ return -1;
+}
+
+static XenStoreOps xs_xen = {
+ .daemon_open = xs_daemon_open,
+ .domain_open = xs_domain_open,
+ .daemon_open_readonly = xs_daemon_open_readonly,
+ .domid = xs_domid,
+ .daemon_close = xs_daemon_close,
+ .directory = xs_directory,
+ .read = xs_read,
+ .write = xs_write,
+ .mkdir = xs_mkdir,
+ .rm = xs_rm,
+ .get_permissions = xs_get_permissions,
+ .set_permissions = xs_set_permissions,
+ .watch = xs_watch,
+ .fileno = xs_fileno,
+ .read_watch = xs_read_watch,
+ .unwatch = xs_unwatch,
+ .transaction_start = xs_transaction_start,
+ .transaction_end = xs_transaction_end,
+ .introduce_domain = xs_introduce_domain,
+ .resume_domain = xs_resume_domain,
+ .release_domain = xs_release_domain,
+ .get_domain_path = xs_get_domain_path,
+ .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 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 XenGnttabOps xc_gnttab_xen = {
+ .open = xc_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,
+};
+# endif
+
+/* ------------------------------------------------------------- */
+/* xen hypercall interface */
+
+# if CONFIG_XEN_CTRL_INTERFACE_VERSION< 400
+static XenXC 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 XenXC 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 /* CONFIG_XEN */
+
+XenEvtOps xc_evtchn_ops;
+XenGnttabOps xc_gnttab_ops;
+XenIfOps xc_ops;
+XenStoreOps xs_ops;
+
+void xen_interfaces_init(void)
+{
+ switch (xen_mode) {
+#ifdef CONFIG_XEN
+ case XEN_ATTACH:
+ case XEN_CREATE:
+ xc_evtchn_ops = xc_evtchn_xen;
+ xc_gnttab_ops = xc_gnttab_xen;
+ xc_ops = xc_xen;
+ xs_ops = xs_xen;
+ break;
+#endif
+ default:
+ fprintf(stderr, "ERROR: Compiled without %s support, sorry.\n",
+ xen_mode == XEN_EMULATE ? "xenner" : "Xen");
+ exit(1);
+ }
+}
diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
new file mode 100644
index 0000000..ec0ab68
--- /dev/null
+++ b/hw/xen_interfaces.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2011 Citrix Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_HW_XEN_INTERFACES_H
+#define QEMU_HW_XEN_INTERFACES_H 1
+
+#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 XenEvtchn;
+#else
+typedef xc_evtchn *XenEvtchn;
+#endif
+
+typedef XenEvtchn (*xc_evtchn_open_fn)
+ (xentoollog_logger *logger, unsigned open_flags);
+typedef int (*xc_evtchn_close_fn)(XenEvtchn xce);
+typedef int (*xc_evtchn_fd_fn)(XenEvtchn xce);
+typedef int (*xc_evtchn_notify_fn)(XenEvtchn xce, evtchn_port_t port);
+typedef evtchn_port_or_error_t (*xc_evtchn_bind_unbound_port_fn)
+ (XenEvtchn xce, int domid);
+typedef evtchn_port_or_error_t (*xc_evtchn_bind_interdomain_fn)
+ (XenEvtchn xce, int domid, evtchn_port_t remote_port);
+typedef evtchn_port_or_error_t (*xc_evtchn_bind_virq_fn)
+ (XenEvtchn xce, unsigned int virq);
+typedef int (*xc_evtchn_unbind_fn) (XenEvtchn xce, evtchn_port_t port);
+typedef evtchn_port_or_error_t (*xc_evtchn_pending_fn)(XenEvtchn xce);
+typedef int (*xc_evtchn_unmask_fn)(XenEvtchn xce, evtchn_port_t port);
+
+struct XenEvtOps {
+ xc_evtchn_open_fn open;
+ xc_evtchn_close_fn close;
+ xc_evtchn_fd_fn fd;
+ xc_evtchn_notify_fn notify;
+ xc_evtchn_bind_unbound_port_fn bind_unbound_port;
+ xc_evtchn_bind_interdomain_fn bind_interdomain;
+ xc_evtchn_bind_virq_fn bind_virq;
+ xc_evtchn_unbind_fn unbind;
+ xc_evtchn_pending_fn pending;
+ xc_evtchn_unmask_fn unmask;
+};
+typedef struct XenEvtOps XenEvtOps;
+extern XenEvtOps xc_evtchn_ops;
+
+/* ------------------------------------------------------------- */
+/* xenstore interface */
+
+struct xs_handle;
+
+typedef struct xs_handle *(*xenstore_daemon_open_fn)(void);
+typedef struct xs_handle *(*xenstore_domain_open_fn)(void);
+typedef struct xs_handle *(*xenstore_daemon_open_readonly_fn)(void);
+typedef int (*xenstore_domid_fn)(struct xs_handle *h, int domid);
+typedef void (*xenstore_daemon_close_fn)(struct xs_handle *);
+typedef char **(*xenstore_directory_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path, unsigned int
*num);
+typedef void *(*xenstore_read_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path, unsigned int
*len);
+typedef bool (*xenstore_write_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path,
+ const void *data, unsigned int len);
+typedef bool (*xenstore_mkdir_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path);
+typedef bool (*xenstore_rm_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path);
+typedef struct xs_permissions *(*xenstore_get_permissions_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path, unsigned int
*num);
+typedef bool (*xenstore_set_permissions_fn)
+ (struct xs_handle *h, xs_transaction_t t, const char *path,
+ struct xs_permissions *perms, unsigned int num_perms);
+typedef bool (*xenstore_watch_fn)
+ (struct xs_handle *h, const char *path, const char *token);
+typedef int (*xenstore_fileno_fn)(struct xs_handle *h);
+typedef char **(*xenstore_read_watch_fn)(struct xs_handle *h, unsigned int
*num);
+typedef bool (*xenstore_unwatch_fn)
+ (struct xs_handle *h, const char *path, const char *token);
+typedef xs_transaction_t (*xenstore_transaction_start_fn)(struct xs_handle *h);
+typedef bool (*xenstore_transaction_end_fn)
+ (struct xs_handle *h, xs_transaction_t t, bool abort);
+typedef bool (*xenstore_introduce_domain_fn)
+ (struct xs_handle *h, unsigned int domid, unsigned long mfn,
+ unsigned int eventchn);
+typedef bool (*xenstore_resume_domain_fn)
+ (struct xs_handle *h, unsigned int domid);
+typedef bool (*xenstore_release_domain_fn)
+ (struct xs_handle *h, unsigned int domid);
+typedef char *(*xenstore_get_domain_path_fn)
+ (struct xs_handle *h, unsigned int domid);
+typedef bool (*xenstore_is_domain_introduced_fn)
+ (struct xs_handle *h, unsigned int domid);
+
+struct XenStoreOps {
+ xenstore_daemon_open_fn daemon_open;
+ xenstore_domain_open_fn domain_open;
+ xenstore_daemon_open_readonly_fn daemon_open_readonly;
+ xenstore_domid_fn domid;
+ xenstore_daemon_close_fn daemon_close;
+ xenstore_directory_fn directory;
+ xenstore_read_fn read;
+ xenstore_write_fn write;
+ xenstore_mkdir_fn mkdir;
+ xenstore_rm_fn rm;
+ xenstore_get_permissions_fn get_permissions;
+ xenstore_set_permissions_fn set_permissions;
+ xenstore_watch_fn watch;
+ xenstore_fileno_fn fileno;
+ xenstore_read_watch_fn read_watch;
+ xenstore_unwatch_fn unwatch;
+ xenstore_transaction_start_fn transaction_start;
+ xenstore_transaction_end_fn transaction_end;
+ xenstore_introduce_domain_fn introduce_domain;
+ xenstore_resume_domain_fn resume_domain;
+ xenstore_release_domain_fn release_domain;
+ xenstore_get_domain_path_fn get_domain_path;
+ xenstore_is_domain_introduced_fn is_domain_introduced;
+};
+typedef struct XenStoreOps XenStoreOps;
+extern XenStoreOps xs_ops;
+
+/* ------------------------------------------------------------- */
+/* xen grant table interface */
+
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION< 410
+typedef int XenGnttab;
+#else
+typedef xc_gnttab *XenGnttab;
+#endif
+
+typedef XenGnttab (*xc_gnttab_open_fn)
+ (xentoollog_logger *logger, unsigned open_flags);
+typedef int (*xc_gnttab_close_fn)(XenGnttab xcg);
+typedef void *(*xc_gnttab_map_grant_ref_fn)
+ (XenGnttab xcg, uint32_t domid, uint32_t ref, int prot);
+typedef void *(*xc_gnttab_map_grant_refs_fn)
+ (XenGnttab xcg, uint32_t count, uint32_t *domids, uint32_t *refs, int
prot);
+typedef int (*xc_gnttab_munmap_fn)
+ (XenGnttab xcg, void *start_address, uint32_t count);
+
+struct XenGnttabOps {
+ xc_gnttab_open_fn open;
+ xc_gnttab_close_fn close;
+ xc_gnttab_map_grant_ref_fn map_grant_ref;
+ xc_gnttab_map_grant_refs_fn map_grant_refs;
+ xc_gnttab_munmap_fn munmap;
+};
+typedef struct XenGnttabOps XenGnttabOps;
+extern XenGnttabOps xc_gnttab_ops;
+
+/* ------------------------------------------------------------- */
+/* xen hypercall interface */
+
+typedef XenXC (*xc_interface_open_fn)
+ (xentoollog_logger *logger, xentoollog_logger *dombuild_logger,
+ unsigned open_flags);
+typedef int (*xc_interface_close_fn)(XenXC xc_handle);
+typedef void *(*xc_map_foreign_range_fn)
+ (XenXC xc_handle, uint32_t dom, int size, int prot, unsigned long mfn);
+typedef void *(*xc_map_foreign_pages_fn)
+ (XenXC xc_handle, uint32_t dom, int prot, const xen_pfn_t *arr, int num);
+typedef void *(*xc_map_foreign_bulk_fn)
+ (XenXC xc_handle, uint32_t dom, int prot, const xen_pfn_t *arr, int *err,
+ unsigned int num);
+typedef int (*xc_domain_populate_physmap_exact_fn)
+ (XenXC xc_handle, uint32_t domid, unsigned long nr_extents,
+ unsigned int extent_order, unsigned int mem_flags, xen_pfn_t
*extent_start);
+
+struct XenIfOps {
+ xc_interface_open_fn interface_open;
+ xc_interface_close_fn interface_close;
+ xc_map_foreign_range_fn map_foreign_range;
+ xc_map_foreign_pages_fn map_foreign_pages;
+ xc_map_foreign_bulk_fn map_foreign_bulk;
+ xc_domain_populate_physmap_exact_fn domain_populate_physmap_exact;
+};
+typedef struct XenIfOps XenIfOps;
+extern XenIfOps xc_ops;
+
+/* ------------------------------------------------------------- */
+
+void xen_interfaces_init(void);
+
+#endif /* QEMU_HW_XEN_INTERFACES_H */
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 8fcf856..6cb6fc4 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -166,9 +166,9 @@ static void net_tx_packets(struct XenNetDev *netdev)
(txreq.flags& NETTXF_more_data) ? " more_data" :
"",
(txreq.flags& NETTXF_extra_info) ? " extra_info" :
"");
- page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
- netdev->xendev.dom,
- txreq.gref, PROT_READ);
+ page = xc_gnttab_ops.map_grant_ref(netdev->xendev.gnttabdev,
+ netdev->xendev.dom,
+ txreq.gref, PROT_READ);
if (page == NULL) {
xen_be_printf(&netdev->xendev, 0, "error: tx gref dereference
failed (%d)\n",
txreq.gref);
@@ -185,7 +185,7 @@ static void net_tx_packets(struct XenNetDev *netdev)
} else {
qemu_send_packet(&netdev->nic->nc, page + txreq.offset,
txreq.size);
}
- xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
+ xc_gnttab_ops.munmap(netdev->xendev.gnttabdev, page, 1);
net_tx_response(netdev,&txreq, NETIF_RSP_OKAY);
}
if (!netdev->tx_work)
@@ -272,9 +272,9 @@ static ssize_t net_rx_packet(VLANClientState *nc, const
uint8_t *buf, size_t siz
memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
netdev->rx_ring.req_cons = ++rc;
- page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
- netdev->xendev.dom,
- rxreq.gref, PROT_WRITE);
+ page = xc_gnttab_ops.map_grant_ref(netdev->xendev.gnttabdev,
+ netdev->xendev.dom,
+ rxreq.gref, PROT_WRITE);
if (page == NULL) {
xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed
(%d)\n",
rxreq.gref);
@@ -282,7 +282,7 @@ static ssize_t net_rx_packet(VLANClientState *nc, const
uint8_t *buf, size_t siz
return -1;
}
memcpy(page + NET_IP_ALIGN, buf, size);
- xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);
+ xc_gnttab_ops.munmap(netdev->xendev.gnttabdev, page, 1);
net_rx_response(netdev,&rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
return size;
@@ -350,14 +350,14 @@ static int net_connect(struct XenDevice *xendev)
return -1;
}
- netdev->txs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
- netdev->xendev.dom,
- netdev->tx_ring_ref,
- PROT_READ | PROT_WRITE);
- netdev->rxs = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,
- netdev->xendev.dom,
- netdev->rx_ring_ref,
- PROT_READ | PROT_WRITE);
+ netdev->txs = xc_gnttab_ops.map_grant_ref(netdev->xendev.gnttabdev,
+ netdev->xendev.dom,
+ netdev->tx_ring_ref,
+ PROT_READ | PROT_WRITE);
+ netdev->rxs = xc_gnttab_ops.map_grant_ref(netdev->xendev.gnttabdev,
+ netdev->xendev.dom,
+ netdev->rx_ring_ref,
+ PROT_READ | PROT_WRITE);
if (!netdev->txs || !netdev->rxs)
return -1;
BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XC_PAGE_SIZE);
@@ -381,11 +381,11 @@ static void net_disconnect(struct XenDevice *xendev)
xen_be_unbind_evtchn(&netdev->xendev);
if (netdev->txs) {
- xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
+ xc_gnttab_ops.munmap(netdev->xendev.gnttabdev, netdev->txs, 1);
netdev->txs = NULL;
}
if (netdev->rxs) {
- xc_gnttab_munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
+ xc_gnttab_ops.munmap(netdev->xendev.gnttabdev, netdev->rxs, 1);
netdev->rxs = NULL;
}
if (netdev->nic) {
diff --git a/hw/xenfb.c b/hw/xenfb.c
index da5297b..7ff7885 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -105,9 +105,9 @@ static int common_bind(struct common *c)
if (xenstore_read_fe_int(&c->xendev,
"event-channel",&c->xendev.remote_port) == -1)
return -1;
- c->page = xc_map_foreign_range(xen_xc, c->xendev.dom,
- XC_PAGE_SIZE,
- PROT_READ | PROT_WRITE, mfn);
+ c->page = xc_ops.map_foreign_range(xen_xc, c->xendev.dom,
+ XC_PAGE_SIZE,
+ PROT_READ | PROT_WRITE, mfn);
if (c->page == NULL)
return -1;
@@ -483,15 +483,15 @@ static int xenfb_map_fb(struct XenFB *xenfb)
fbmfns = qemu_mallocz(sizeof(unsigned long) * xenfb->fbpages);
xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
- map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
- PROT_READ, pgmfns, n_fbdirs);
+ map = xc_ops.map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
+ PROT_READ, pgmfns, n_fbdirs);
if (map == NULL)
goto out;
xenfb_copy_mfns(mode, xenfb->fbpages, fbmfns, map);
munmap(map, n_fbdirs * XC_PAGE_SIZE);
- xenfb->pixels = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
- PROT_READ | PROT_WRITE, fbmfns,
xenfb->fbpages);
+ xenfb->pixels = xc_ops.map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
+ PROT_READ | PROT_WRITE, fbmfns,
xenfb->fbpages);
if (xenfb->pixels == NULL)
goto out;